Merge branch 'master' into 1.19.63

This commit is contained in:
olebeck 2023-03-21 11:22:51 +01:00
commit 5742a6b850
4 changed files with 344 additions and 102 deletions

1
.gitignore vendored
View File

@ -24,6 +24,7 @@ keys.db
/updates/ /updates/
/fyne-cross/ /fyne-cross/
/tmp/ /tmp/
/cmd/test
packets.log.gpg packets.log.gpg
customdata.json customdata.json

View File

@ -18,9 +18,12 @@ type itemContainer struct {
} }
func (w *WorldState) processItemPacketsServer(pk packet.Packet) packet.Packet { func (w *WorldState) processItemPacketsServer(pk packet.Packet) packet.Packet {
if !w.experimentInventory {
return pk
}
switch pk := pk.(type) { switch pk := pk.(type) {
case *packet.ContainerOpen: case *packet.ContainerOpen:
if w.experimentInventory {
// add to open containers // add to open containers
existing, ok := w.openItemContainers[pk.WindowID] existing, ok := w.openItemContainers[pk.WindowID]
if !ok { if !ok {
@ -30,9 +33,8 @@ func (w *WorldState) processItemPacketsServer(pk packet.Packet) packet.Packet {
OpenPacket: pk, OpenPacket: pk,
Content: existing.Content, Content: existing.Content,
} }
}
case *packet.InventoryContent: case *packet.InventoryContent:
if w.experimentInventory {
// save content // save content
existing, ok := w.openItemContainers[byte(pk.WindowID)] existing, ok := w.openItemContainers[byte(pk.WindowID)]
if !ok { if !ok {
@ -44,17 +46,21 @@ func (w *WorldState) processItemPacketsServer(pk packet.Packet) packet.Packet {
break break
} }
existing.Content = pk existing.Content = pk
}
case *packet.ContainerClose: case *packet.ContainerClose:
if w.experimentInventory { // find container info
existing, ok := w.openItemContainers[byte(pk.WindowID)]
switch pk.WindowID { switch pk.WindowID {
case protocol.WindowIDArmour: // todo handle case protocol.WindowIDArmour: // todo handle
case protocol.WindowIDOffHand: // todo handle case protocol.WindowIDOffHand: // todo handle
case protocol.WindowIDUI: case protocol.WindowIDUI:
case protocol.WindowIDInventory: // todo handle case protocol.WindowIDInventory: // todo handle
if !ok {
break
}
default: default:
// find container info
existing, ok := w.openItemContainers[byte(pk.WindowID)]
if !ok { if !ok {
logrus.Warn(locale.Loc("warn_window_closed_not_open", nil)) logrus.Warn(locale.Loc("warn_window_closed_not_open", nil))
break break
@ -80,6 +86,7 @@ func (w *WorldState) processItemPacketsServer(pk packet.Packet) packet.Packet {
NBTPos := protocol.BlockPos{v["x"].(int32), v["y"].(int32), v["z"].(int32)} NBTPos := protocol.BlockPos{v["x"].(int32), v["y"].(int32), v["z"].(int32)}
if NBTPos == pos { if NBTPos == pos {
w.blockNBT[cp][i]["Items"] = nbtconv.InvToNBT(inv) w.blockNBT[cp][i]["Items"] = nbtconv.InvToNBT(inv)
break
} }
} }
@ -88,7 +95,7 @@ func (w *WorldState) processItemPacketsServer(pk packet.Packet) packet.Packet {
// remove it again // remove it again
delete(w.openItemContainers, byte(pk.WindowID)) delete(w.openItemContainers, byte(pk.WindowID))
} }
}
case *packet.ItemComponent: case *packet.ItemComponent:
w.bp.ApplyComponentEntries(pk.Items) w.bp.ApplyComponentEntries(pk.Items)
} }

View File

@ -3,13 +3,13 @@ package worlds
import ( import (
"image" "image"
"image/draw" "image/draw"
"time" "math"
"gioui.org/f32" "gioui.org/f32"
"gioui.org/gesture"
"gioui.org/io/pointer" "gioui.org/io/pointer"
"gioui.org/layout" "gioui.org/layout"
"gioui.org/op" "gioui.org/op"
"gioui.org/op/clip"
"gioui.org/op/paint" "gioui.org/op/paint"
"github.com/bedrock-tool/bedrocktool/ui/messages" "github.com/bedrock-tool/bedrocktool/ui/messages"
"github.com/sandertv/gophertunnel/minecraft/protocol" "github.com/sandertv/gophertunnel/minecraft/protocol"
@ -17,68 +17,83 @@ import (
type Map struct { type Map struct {
click f32.Point click f32.Point
mapPos f32.Point
pos f32.Point
imageOp paint.ImageOp imageOp paint.ImageOp
zoom float32
drag gesture.Drag scaleFactor float32
scroll gesture.Scroll center f32.Point
transform f32.Affine2D
grabbed bool
MapImage *image.RGBA MapImage *image.RGBA
BoundsMin protocol.ChunkPos BoundsMin protocol.ChunkPos
BoundsMax protocol.ChunkPos BoundsMax protocol.ChunkPos
Rotation float32 }
func (m *Map) HandlePointerEvent(e pointer.Event) {
switch e.Type {
case pointer.Press:
m.click = e.Position
m.grabbed = true
case pointer.Drag:
m.transform = m.transform.Offset(e.Position.Sub(m.click))
m.click = e.Position
case pointer.Release:
m.grabbed = false
case pointer.Scroll:
m.HandleScrollEvent(e)
}
}
func (m *Map) HandleScrollEvent(e pointer.Event) {
scaleFactor := float32(math.Pow(1.01, float64(e.Scroll.Y)))
m.transform = m.transform.Scale(e.Position.Sub(m.center), f32.Pt(scaleFactor, scaleFactor))
m.scaleFactor *= scaleFactor
} }
func (m *Map) Layout(gtx layout.Context) layout.Dimensions { func (m *Map) Layout(gtx layout.Context) layout.Dimensions {
// here we loop through all the events associated with this button. // here we loop through all the events associated with this button.
for _, e := range m.drag.Events(gtx.Metric, gtx.Queue, gesture.Both) { for _, e := range gtx.Events(m) {
switch e.Type { if e, ok := e.(pointer.Event); ok {
case pointer.Press: m.HandlePointerEvent(e)
m.click = e.Position
case pointer.Drag:
m.pos = m.mapPos.Sub(m.click).Add(e.Position)
case pointer.Release:
m.mapPos = m.pos
} }
} }
scrollDist := m.scroll.Scroll(gtx.Metric, gtx.Queue, time.Now(), gesture.Vertical)
m.zoom -= float32(scrollDist) / 20
if m.zoom < 0.2 {
m.zoom = 0.2
}
size := gtx.Constraints.Max
if m.MapImage != nil { if m.MapImage != nil {
m.imageOp.Add(gtx.Ops) // Calculate the size of the widget based on the size of the image and the current scale factor.
b := m.MapImage.Bounds() dx := float32(m.MapImage.Bounds().Dx())
sx := float32(b.Dx() / 2) dy := float32(m.MapImage.Bounds().Dy())
sy := float32(b.Dy() / 2) size := f32.Pt(dx*m.scaleFactor, dy*m.scaleFactor)
op.Affine( m.center = f32.Pt(
f32.Affine2D{}. float32(gtx.Constraints.Max.X),
Scale(f32.Pt(sx, sy), f32.Pt(m.zoom, m.zoom)). float32(gtx.Constraints.Max.Y),
Offset(m.pos), ).Div(2)
).Add(gtx.Ops)
// Calculate the offset required to center the image within the widget.
offset := m.center.Sub(size.Div(2))
// Draw the image at the correct position and scale.
defer clip.Rect{Max: gtx.Constraints.Max}.Push(gtx.Ops).Pop()
op.Affine(m.transform.Offset(offset)).Add(gtx.Ops)
m.imageOp.Add(gtx.Ops)
paint.PaintOp{}.Add(gtx.Ops) paint.PaintOp{}.Add(gtx.Ops)
} }
m.drag.Add(gtx.Ops) size := gtx.Constraints.Max
m.scroll.Add(gtx.Ops, image.Rect(-size.X, -size.Y, size.X, size.Y)) pointer.InputOp{
Tag: m,
Grab: m.grabbed,
Types: pointer.Scroll | pointer.Drag | pointer.Press | pointer.Release,
ScrollBounds: image.Rect(-size.X, -size.Y, size.X, size.Y),
}.Add(gtx.Ops)
return layout.Dimensions{ return layout.Dimensions{Size: size}
Size: size,
}
} }
func drawTile(img *image.RGBA, min, pos protocol.ChunkPos, tile *image.RGBA) { func drawTile(img *image.RGBA, min, pos protocol.ChunkPos, tile *image.RGBA) {
px := image.Pt( px := image.Pt(
int((pos.X()-min[0])*16), int((pos.X()-min[0])*16),
int((pos.Z()-min[0])*16), int((pos.Z()-min[1])*16),
) )
draw.Draw(img, image.Rect( draw.Draw(img, image.Rect(
px.X, px.Y, px.X, px.Y,
@ -88,7 +103,7 @@ func drawTile(img *image.RGBA, min, pos protocol.ChunkPos, tile *image.RGBA) {
func (m *Map) Update(u *messages.UpdateMapPayload) { func (m *Map) Update(u *messages.UpdateMapPayload) {
if m.MapImage == nil { if m.MapImage == nil {
m.zoom = 1 m.scaleFactor = 1
} }
needNewImage := false needNewImage := false

219
utils/encryptor/enc.go Normal file
View File

@ -0,0 +1,219 @@
package encryptor
import (
"archive/zip"
"bytes"
"crypto/aes"
"crypto/cipher"
"encoding/binary"
"encoding/hex"
"encoding/json"
"errors"
"io"
"io/fs"
"math/rand"
"path/filepath"
"testing/fstest"
"time"
"github.com/google/uuid"
)
type contentItem struct {
Path string `json:"path"`
Key string `json:"key"`
}
type Content struct {
Content []contentItem `json:"content"`
}
var StaticKey = []byte("s5s5ejuDru4uchuF2drUFuthaspAbepE")
func GenerateKey() (out []byte) {
out = make([]byte, 32)
var vocab = []byte("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789")
for i := 0; i < 32; i++ {
out[i] = vocab[rand.Intn(len(vocab))]
}
return
}
func encryptCfb(data []byte, key []byte) {
b, _ := aes.NewCipher(key)
s := cipher.NewCFBEncrypter(b, key[0:16])
s.XORKeyStream(data, data)
}
func canEncrypt(path string) bool {
if path == "manifest.json" {
return false
}
s := filepath.SplitList(path)
if s[0] == "texts" {
return false
}
if s[len(s)-1] == "contents.json" {
return false
}
return true
}
func enc(fsys fs.FS, fsyso fstest.MapFS, contentsJson *Content, dir string) error {
// get all files in this folder
matches, err := fs.Glob(fsys, dir+"**")
if err != nil {
return err
}
for _, path := range matches {
// create output file
ifo, err := fs.Stat(fsys, path)
if err != nil {
return err
}
fo := &fstest.MapFile{
ModTime: ifo.ModTime(),
Mode: ifo.Mode(),
}
fsyso[path] = fo
// recurse
if ifo.IsDir() {
return enc(fsys, fsyso, contentsJson, path+"/")
}
// read data
var data []byte
data, err = fs.ReadFile(fsys, path)
if err != nil {
return err
}
// encrypt if needed
if canEncrypt(path) {
key := GenerateKey()
it := contentItem{
Path: path,
Key: hex.EncodeToString(key),
}
contentsJson.Content = append(contentsJson.Content, it)
encryptCfb(data, key)
}
// write to output
fo.Data = data
}
return nil
}
func Enc(fsys fs.FS, id *uuid.UUID, ContentKey []byte) (fs.FS, error) {
var manifest map[string]any
// read the manifest
f, err := fsys.Open("manifest.json")
if err == nil {
dec := json.NewDecoder(f)
err = dec.Decode(&manifest)
if err != nil {
return nil, err
}
header, ok := manifest["header"].(map[string]any)
if !ok {
return nil, errors.New("no header")
}
// get id from manifest if not specified, else change it in the manifet
if id == nil {
idstr, ok := header["uuid"].(string)
if !ok {
return nil, errors.New("no id")
}
_id, err := uuid.Parse(idstr)
if err != nil {
return nil, err
}
id = &_id
} else {
header["uuid"] = id.String()
}
} else {
if id != nil {
// create a manifest
} else {
return nil, err
}
}
fsyso := fstest.MapFS{}
// encrypt
var contentsJson Content
err = enc(fsys, fsyso, &contentsJson, "")
if err != nil {
return nil, err
}
// write new manifest
manifestData, _ := json.MarshalIndent(manifest, "", "\t")
fsyso["manifest.json"] = &fstest.MapFile{
Data: manifestData,
}
// write the contents.json encrypted
contentsBuf := bytes.NewBuffer(nil)
binary.Write(contentsBuf, binary.LittleEndian, uint32(0))
binary.Write(contentsBuf, binary.LittleEndian, uint32(0x9bcfb9fc))
binary.Write(contentsBuf, binary.LittleEndian, uint64(0))
contentsBuf.WriteByte(byte(len(id.String())))
contentsBuf.Write([]byte(id.String()))
contentsBuf.Write(make([]byte, 0xff-contentsBuf.Len()))
contentsData, _ := json.Marshal(&contentsJson)
encryptCfb(contentsData, ContentKey)
contentsBuf.Write(contentsData)
fsyso["contents.json"] = &fstest.MapFile{
Data: contentsBuf.Bytes(),
Mode: 0775,
ModTime: time.Now(),
}
return fsyso, nil
}
func fstozip(fsys fs.FS, zw *zip.Writer, dir string) error {
// get files in this folder
matches, err := fs.Glob(fsys, dir+"**")
if err != nil {
return err
}
for _, path := range matches {
// if this path is a folder, recurse
ifo, _ := fs.Stat(fsys, path)
if ifo.IsDir() {
return fstozip(fsys, zw, path+"/")
}
// copy the file to the zip
w, err := zw.CreateHeader(&zip.FileHeader{
Name: ifo.Name(),
Modified: ifo.ModTime(),
})
if err != nil {
return err
}
data, err := fs.ReadFile(fsys, path)
if err != nil {
return err
}
w.Write(data)
}
return nil
}
func FSToZip(fsys fs.FS, w io.Writer) error {
zw := zip.NewWriter(w)
err := fstozip(fsys, zw, "")
if err != nil {
return err
}
zw.Close()
return nil
}