Skip to content

Commit

Permalink
fix packet compression
Browse files Browse the repository at this point in the history
  • Loading branch information
oq-x committed Aug 20, 2024
1 parent d55259d commit 22ac528
Showing 25 changed files with 2,826 additions and 176 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -17,4 +17,5 @@ zeppelin.exe
/world_old
server.properties
/q
data.qfg
data.qfg
/blockstates
34 changes: 21 additions & 13 deletions main.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
package main

import (
"math/rand"
"os"
"runtime"
"runtime/pprof"
"strconv"
"time"

"github.com/zeppelinmc/zeppelin/core_commands"
@@ -19,16 +21,33 @@ var timeStart = time.Now()

func main() {
log.Infolnf("Zeppelin 1.21 Minecraft server with %s on platform %s-%s", runtime.Version(), runtime.GOOS, runtime.GOARCH)

if util.HasArgument("--cpuprof") {
f, _ := os.Create("zeppelin-cpu-profile")
pprof.StartCPUProfile(f)
log.Infoln("Started CPU profiler (writing to zeppelin-cpu-profile)")

defer func() {
log.Infoln("Stopped CPU profiler")
pprof.StopCPUProfile()
f.Close()
}()
}

if util.HasArgument("--memprof") {
defer func() {
log.InfolnClean("Writing memory profile to zeppelin-mem-profile")
f, _ := os.Create("zeppelin-mem-profile")
pprof.Lookup("allocs").WriteTo(f, 0)
f.Close()
}()
}

cfg := loadConfig()
if cfg.LevelSeed == "" {
cfg.LevelSeed = strconv.FormatInt(rand.Int63(), 10)
}

w, err := world.NewWorld(cfg.LevelName)
w, err := world.NewWorld(cfg)
if err != nil {
log.Errorlnf("Error preparing level: %v", w)
return
@@ -58,15 +77,4 @@ func main() {
go notRawTerminal(srv)
}
srv.Start(timeStart)

if util.HasArgument("--cpuprof") {
log.Infoln("Stopped CPU profiler")
pprof.StopCPUProfile()
}
if util.HasArgument("--memprof") {
log.InfolnClean("Writing memory profile to zeppelin-mem-profile")
f, _ := os.Create("zeppelin-mem-profile")
pprof.Lookup("allocs").WriteTo(f, 0)
f.Close()
}
}
4 changes: 3 additions & 1 deletion net/config.go
Original file line number Diff line number Diff line change
@@ -39,7 +39,9 @@ func (c Config) New() (*Listener, error) {
return true, nil
},
}
lis.privKey, err = rsa.GenerateKey(rand.Reader, 1024)
if c.Encrypt {
lis.privKey, err = rsa.GenerateKey(rand.Reader, 1024)
}

go lis.listen()

18 changes: 14 additions & 4 deletions net/conn.go
Original file line number Diff line number Diff line change
@@ -13,6 +13,7 @@ import (
"github.com/zeppelinmc/zeppelin/net/cfb8"
"github.com/zeppelinmc/zeppelin/net/io"
"github.com/zeppelinmc/zeppelin/net/io/compress"
"github.com/zeppelinmc/zeppelin/net/io/util"
"github.com/zeppelinmc/zeppelin/net/packet"
"github.com/zeppelinmc/zeppelin/net/packet/handshake"
"github.com/zeppelinmc/zeppelin/net/packet/login"
@@ -47,6 +48,7 @@ type Conn struct {

usesForge bool
read_mu sync.Mutex
write_mu sync.Mutex
}

func (conn *Conn) UsesForge() bool {
@@ -85,6 +87,9 @@ var pkpool = sync.Pool{
}

func (conn *Conn) WritePacket(pk packet.Packet) error {
conn.write_mu.Lock()
defer conn.write_mu.Unlock()

var packetBuf = pkpool.Get().(*bytes.Buffer)
packetBuf.Reset()
defer pkpool.Put(packetBuf)
@@ -244,13 +249,18 @@ func (conn *Conn) ReadPacket() (packet.Packet, error) {
rd = io.NewReader(bytes.NewReader(packet), int(length))
}
} else { //packet is compressed
/*length = dataLength
length = dataLength
compressedLength := packetLength - int32(dataLengthSize)

var ilength = int(length)
uncompressedPacket, err := compress.DecompressZlib(conn, int(compressedLength), &ilength)

var packetBuf = pkpool.Get().(*bytes.Buffer)
packetBuf.Reset()
packetBuf.ReadFrom(util.NewReaderMaxxer(conn, int(compressedLength)))
defer pkpool.Put(packetBuf)

uncompressedPacket, err := compress.DecompressZlib(packetBuf.Bytes(), &ilength)
if err != nil {
log.Println(err)
return nil, err
}

@@ -262,7 +272,7 @@ func (conn *Conn) ReadPacket() (packet.Packet, error) {
uncompressedPacket = data
length = int32(len(data))

rd = io.NewReader(bytes.NewReader(uncompressedPacket), int(length))*/
rd = io.NewReader(bytes.NewReader(uncompressedPacket), int(length))
}
}

3 changes: 2 additions & 1 deletion net/io/compress/compress.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package compress

import (
"bytes"
"sync"

"github.com/4kills/go-libdeflate/v2"
@@ -21,5 +22,5 @@ var compressors = sync.Pool{
}

var bufs = sync.Pool{
New: func() any { return make([]byte, 0) },
New: func() any { return new(bytes.Buffer) },
}
30 changes: 8 additions & 22 deletions net/io/compress/lz4.go
Original file line number Diff line number Diff line change
@@ -1,23 +1,20 @@
package compress

import (
"bytes"
"encoding/binary"
"fmt"
"io"

"github.com/pierrec/lz4/v4"
"github.com/zeppelinmc/zeppelin/net/io/buffers"
"github.com/zeppelinmc/zeppelin/net/io/util"
)

// Decompress an lz4-java block. The data returned is only safe to use until the next operation
func DecompressLZ4(data io.Reader) ([]byte, error) {
var header [21]byte
_, err := data.Read(header[:])
if err != nil {
return nil, err
func DecompressLZ4(data []byte) ([]byte, error) {
if len(data) <= 21 {
return nil, fmt.Errorf("missing header")
}
header := data[:21]
data = data[21:]

magicValue := string(header[:8])
if magicValue != magic {
return nil, fmt.Errorf("invalid magic value")
@@ -26,18 +23,7 @@ func DecompressLZ4(data io.Reader) ([]byte, error) {
compressedLength := int(binary.LittleEndian.Uint32(header[9:13]))
decompressedLength := binary.LittleEndian.Uint32(header[13:17])

var compressedBuffer = buffers.Buffers.Get().(*bytes.Buffer)
defer buffers.Buffers.Put(compressedBuffer)
compressedBuffer.Reset()
if compressedBuffer.Len() < compressedLength {
compressedBuffer.Grow(compressedLength)
}

if _, err := compressedBuffer.ReadFrom(util.NewReaderMaxxer(data, compressedLength)); err != nil {
return nil, err
}

compressed := compressedBuffer.Bytes()[:compressedLength]
compressed := data[:compressedLength]

token := header[8]
compressionMethod := token & 0xf0
@@ -49,7 +35,7 @@ func DecompressLZ4(data io.Reader) ([]byte, error) {
}
defer bufs.Put(decompressed)

_, err = lz4.UncompressBlock(compressed, decompressed[:decompressedLength])
_, err := lz4.UncompressBlock(compressed, decompressed[:decompressedLength])

return decompressed[:decompressedLength], err
case methodUncompressed:
22 changes: 14 additions & 8 deletions net/io/compress/zlib.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package compress

import (
"bytes"

"github.com/4kills/go-libdeflate/v2"
)

@@ -11,13 +13,15 @@ func DecompressZlib(compressed []byte, decompressedLength *int) ([]byte, error)
defer decompressors.Put(dc)

if decompressedLength != nil {
dst := bufs.Get().([]byte)
if len(dst) < int(*decompressedLength) {
dst = make([]byte, *decompressedLength)
dst := bufs.Get().(*bytes.Buffer)
if dst.Len() < int(*decompressedLength) {
dst.Grow(*decompressedLength)
}
defer bufs.Put(dst)

_, decompressedResult, err := dc.DecompressZlib(compressed, dst[:*decompressedLength])
c := dst.Bytes()[:*decompressedLength]

_, decompressedResult, err := dc.DecompressZlib(compressed, c)

return decompressedResult, err
} else {
@@ -33,13 +37,15 @@ func CompressZlib(decompressedData []byte, compressedLength *int) (compressed []
defer compressors.Put(c)

if compressedLength != nil {
dst := bufs.Get().([]byte)
if len(dst) < int(*compressedLength) {
dst = make([]byte, *compressedLength)
dst := bufs.Get().(*bytes.Buffer)
if dst.Len() < int(*compressedLength) {
dst.Grow(*compressedLength)
}
defer bufs.Put(dst)

_, compressedResult, err := c.CompressZlib(decompressedData, dst[:*compressedLength])
dc := dst.Bytes()[:*compressedLength]

_, compressedResult, err := c.CompressZlib(decompressedData, dc)

return compressedResult, err
} else {
11 changes: 11 additions & 0 deletions net/io/writer.go
Original file line number Diff line number Diff line change
@@ -193,6 +193,17 @@ func (w Writer) TextComponent(comp text.TextComponent) error {
return w.NBT(comp)
}

func (w Writer) StringTextComponent(text string) error {
if err := w.Byte(8); err != nil {
return err
}
if err := w.Short(int16(len(text))); err != nil {
return err
}

return w.String(text)
}

func (w Writer) NBT(data any) error {
enc := nbt.NewEncoder(w.w)
enc.WriteRootName(false)
4 changes: 2 additions & 2 deletions net/packet/configuration/registryData.go
Original file line number Diff line number Diff line change
@@ -8,10 +8,10 @@ import (
"github.com/zeppelinmc/zeppelin/net/registry"
)

var RegistryPackets = make([]*RegistryData, 0, len(registry.RegistryMap))
var RegistryPackets = make([]*RegistryData, 0, len(registry.Registries))

func init() {
for key, registry := range registry.RegistryMap {
for key, registry := range registry.Registries {
RegistryPackets = append(RegistryPackets, &RegistryData{
RegistryId: key,
Registry: registry,
265 changes: 253 additions & 12 deletions net/registry/embed.go

Large diffs are not rendered by default.

2,182 changes: 2,182 additions & 0 deletions net/registry/embed.go.txt

Large diffs are not rendered by default.

14 changes: 7 additions & 7 deletions net/registry/registry.go
Original file line number Diff line number Diff line change
@@ -2,12 +2,9 @@ package registry

import (
_ "embed"
"reflect"
)

// This packet contains registries that are sent to the client. Because of the way Go maps aren't ordered, sending a registry data packet will set its Indexes field to the order in which its entries were encoded, which can then be used to get registry ids

var RegistryMap = make(map[string]any)
// This packet contains registries that are sent to the client. Because Go maps aren't ordered, sending a registry data packet will set its Indexes field to the order in which its entries were encoded, which can then be used to get registry ids

type ChatType struct {
Chat struct {
@@ -71,7 +68,7 @@ type Dimension struct {
} `nbt:"monster_spawn_light_level"`
}

type registries struct {
/*type registries struct {
BannerPattern map[string]struct {
AssetId string `nbt:"asset_id"`
TranslationKey string `nbt:"translation_key"`
@@ -409,11 +406,14 @@ type registries struct {
HasPrecipitation bool `nbt:"has_precipitation"`
Temperature float32 `nbt:"temperature"`
} `nbt:"minecraft:worldgen/biome"`
}
}*/

func init() {
/*func init() {
v := reflect.ValueOf(Registries)
for i := 0; i < v.NumField(); i++ {
RegistryMap[v.Type().Field(i).Tag.Get("nbt")] = v.Field(i).Interface()
}
os.WriteFile("d.go", fmt.Appendf(nil, "package registry\n\nvar Registries = %#v", RegistryMap), 0755)
}
*/
14 changes: 10 additions & 4 deletions server/world/block/blockstates/dec.go
Original file line number Diff line number Diff line change
@@ -51,7 +51,7 @@ func ReadBlock(f io.ReaderAt, loc BlockLocation) (Block, error) {
blockStates[i].Id = blockStateId
blockStates[i].Properties = make(map[string]string, propertyCount)

for i := 0; i < int(propertyCount); i++ {
for j := 0; j < int(propertyCount); j++ {
propertyName, err := readString(maxxer, stringlen)
if err != nil {
return blockStates, nil
@@ -79,11 +79,14 @@ func ReadHeader(f io.Reader) (map[string]BlockLocation, error) {
return nil, fmt.Errorf("invalid magic header")
}

var blockCount int32
if err := binary.Read(f, binary.BigEndian, &blockCount); err != nil {
var locations_tmp [8]byte

if _, err := f.Read(locations_tmp[:4]); err != nil {
return nil, err
}

blockCount := int32(locations_tmp[0])<<24 | int32(locations_tmp[1])<<16 | int32(locations_tmp[2])<<8 | int32(locations_tmp[3])

var locations = make(map[string]BlockLocation, blockCount)

var strlen = make([]byte, 1)
@@ -94,9 +97,12 @@ func ReadHeader(f io.Reader) (map[string]BlockLocation, error) {
}

var location BlockLocation
if err := binary.Read(f, binary.BigEndian, location); err != nil {

if _, err := f.Read(locations_tmp[:]); err != nil {
return nil, err
}
location.Offset = int32(locations_tmp[0])<<24 | int32(locations_tmp[1])<<16 | int32(locations_tmp[2])<<8 | int32(locations_tmp[3])
location.Size = int32(locations_tmp[4])<<24 | int32(locations_tmp[5])<<16 | int32(locations_tmp[6])<<8 | int32(locations_tmp[7])

locations[name] = location
}
Loading

0 comments on commit 22ac528

Please sign in to comment.