mirror of
https://github.com/CosmicStar98/bedrocktool.git
synced 2024-06-16 05:19:46 +00:00
Merge branch 'master' into 1.19.63
This commit is contained in:
commit
5742a6b850
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -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
|
||||||
|
|
|
@ -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)
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
219
utils/encryptor/enc.go
Normal 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
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user