summaryrefslogtreecommitdiff
path: root/server
diff options
context:
space:
mode:
authorraven <citrons@mondecitronne.com>2026-03-27 18:21:20 -0500
committerraven <citrons@mondecitronne.com>2026-03-27 18:32:38 -0500
commit0a56a69743bb53b57e090323364d594aa3ba70af (patch)
tree0395c321e9d700398fcea458fe5d15ad376af239 /server
parent214ddf63a19d66b1ea039ea05b0f5a099f682b9d (diff)
it WORKS.
Diffstat (limited to 'server')
-rw-r--r--server/flate.go171
-rw-r--r--server/map.go8
-rw-r--r--server/player.go6
3 files changed, 115 insertions, 70 deletions
diff --git a/server/flate.go b/server/flate.go
index 99517c1..e2d87f4 100644
--- a/server/flate.go
+++ b/server/flate.go
@@ -2,6 +2,7 @@ package server
import (
"io"
+ "math/bits"
"encoding/binary"
)
@@ -12,17 +13,18 @@ import (
// compressor, translate it directly into DEFLATE
func deflateRuns(
wr io.Writer, runs []blockData, changes []blockData,
- levelSize uint32) error {
- var err error
+ levelSize uint32) (length uint32, err error) {
bw := bitsWriter {wr: wr}
- bw.Write(0b01, 2) // fixed huffman
- writeCode(&bw, 0xff & levelSize)
- writeCode(&bw, 0xff & (levelSize >> 8))
+
+ bw.Write(0b011, 3) // BFINAL, fixed huffman
+ writeCode(&bw, 0xff & (levelSize >> 24))
writeCode(&bw, 0xff & (levelSize >> 16))
- err = writeCode(&bw, 0xff & levelSize >> 24)
+ writeCode(&bw, 0xff & (levelSize >> 8))
+ err = writeCode(&bw, 0xff & levelSize)
if err != nil {
- return err
+ return
}
+
for i, data := range runs {
var nextPos uint32
if i < len(runs) - 1 {
@@ -40,74 +42,113 @@ func deflateRuns(
writeRun(&bw, byte(data.Block), ch.Pos - curPos)
err = writeRun(&bw, byte(ch.Block), 1)
if err != nil {
- return err
+ return
}
curPos = ch.Pos + 1
}
if curPos < nextPos {
err = writeRun(&bw, byte(data.Block), nextPos - curPos)
if err != nil {
- return err
+ return
}
}
}
- return writeCode(&bw, 256) // end of block
+ writeCode(&bw, 256)
+ return levelSize + 4, bw.Close()
+}
+
+var lengthExtraBits = [...]uint8{
+ /* 257 */ 0, 0, 0,
+ /* 260 */ 0, 0, 0, 0, 0, 1, 1, 1, 1, 2,
+ /* 270 */ 2, 2, 2, 3, 3, 3, 3, 4, 4, 4,
+ /* 280 */ 4, 5, 5, 5, 5, 0,
+}
+
+var lengthBase = [...]uint32{
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 10,
+ 12, 14, 16, 20, 24, 28, 32, 40, 48, 56,
+ 64, 80, 96, 112, 128, 160, 192, 224, 255,
+}
+
+var lengthCodes = [...]uint32{
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 8,
+ 9, 9, 10, 10, 11, 11, 12, 12, 12, 12,
+ 13, 13, 13, 13, 14, 14, 14, 14, 15, 15,
+ 15, 15, 16, 16, 16, 16, 16, 16, 16, 16,
+ 17, 17, 17, 17, 17, 17, 17, 17, 18, 18,
+ 18, 18, 18, 18, 18, 18, 19, 19, 19, 19,
+ 19, 19, 19, 19, 20, 20, 20, 20, 20, 20,
+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 22, 22, 22, 22,
+ 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
+ 22, 22, 23, 23, 23, 23, 23, 23, 23, 23,
+ 23, 23, 23, 23, 23, 23, 23, 23, 24, 24,
+ 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+ 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+ 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+ 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
+ 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
+ 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
+ 25, 25, 26, 26, 26, 26, 26, 26, 26, 26,
+ 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
+ 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
+ 26, 26, 26, 26, 27, 27, 27, 27, 27, 27,
+ 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
+ 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
+ 27, 27, 27, 27, 27, 28,
}
func writeRun(bw *bitsWriter, value byte, totalLen uint32) error {
var err error
for totalLen > 0 {
len := min(totalLen, 258)
- if len < 3 {
+ if len < 4 {
for i := 0; i < int(len); i++ {
err = writeCode(bw, uint32(value))
}
} else {
writeCode(bw, uint32(value))
- err = writeRunLength(bw, len)
+ writeLength(bw, len - 1)
+ err = bw.Write(0b00000, 5) // distance: 1
}
totalLen -= len
}
return err
}
-func writeRunLength(bw *bitsWriter, length uint32) error {
+func writeLength(bw *bitsWriter, length uint32) error {
length -= 3
- if length < 11 {
- writeCode(bw, 257 + length)
- } else if length < 19 {
- writeCode(bw, 265 + length >> 1)
- bw.Write(length & 0b1, 1)
- } else if length < 35 {
- writeCode(bw, 269 + length >> 2)
- bw.Write(length & 0b11, 2)
- } else if length < 115 {
- writeCode(bw, 273 + length >> 3)
- bw.Write(length & 0b111, 3)
- } else if length < 131 {
- writeCode(bw, 273 + length >> 4)
- bw.Write(length & 0b1111, 4)
- } else if length < 285 {
- writeCode(bw, 281 + length >> 5)
- bw.Write(length & 0b11111, 5)
- } else if length == 258 {
- writeCode(bw, 285)
- } else {
- panic("length out of range")
- }
- return writeCode(bw, 0)
+ code := lengthCodes[length]
+ writeCode(bw, 257 + code)
+ return bw.Write(length - lengthBase[code], lengthExtraBits[code])
}
func writeCode(bw *bitsWriter, v uint32) error {
- if v < 144 {
- return bw.Write(0b00110000 + v, 8)
- } else if v < 256 {
- return bw.Write(0b110010000 + v, 9)
- } else if v < 280 {
- return bw.Write(v, 7)
- } else {
- return bw.Write(0b11000000, 8)
+ var code uint32
+ var size uint8
+ switch {
+ case v < 144:
+ // size 8, 000110000 .. 10111111
+ code = v + 48
+ size = 8
+ case v < 256:
+ // size 9, 110010000 .. 111111111
+ code = v + 400 - 144
+ size = 9
+ case v < 280:
+ // size 7, 0000000 .. 0010111
+ code = v - 256
+ size = 7
+ case v < 288:
+ // size 8, 11000000 .. 11000111
+ code = v + 192 - 280
+ size = 8
+ default:
+ panic("code value out of range")
}
+ code = bits.Reverse32(code << (32 - size))
+ return bw.Write(code, size)
}
type bitsWriter struct {
@@ -115,22 +156,34 @@ type bitsWriter struct {
buf uint64
nbuf byte
}
-func (bw *bitsWriter) Write(bits uint32, n byte) error {
- bw.buf |= uint64(bits & ((1<<n)-1)) << bw.nbuf
- bw.nbuf += n
- if bw.nbuf < 32 {
- return nil
+
+func (bw *bitsWriter) Write(v uint32, n uint8) error {
+ if 64 - bw.nbuf < n {
+ err := bw.writeBuf()
+ if err != nil {
+ return err
+ }
}
+ bw.buf |= uint64(v & ((1<<n)-1)) << bw.nbuf
+ bw.nbuf += n
+ return nil
+}
+
+func (bw *bitsWriter) writeBuf() error {
var bytes [8]byte
binary.LittleEndian.PutUint64(bytes[:], bw.buf)
- _, err := bw.wr.Write(bytes[:bw.nbuf / 8])
- bw.buf >>= bw.nbuf / 8
- bw.nbuf -= bw.nbuf / 8
+ nbytes := bw.nbuf / 8
+ _, err := bw.wr.Write(bytes[:nbytes])
+ bw.buf >>= nbytes * 8
+ bw.nbuf -= nbytes * 8
return err
}
-func (bw *bitsWriter) Flush() error {
- return bw.Write(0, 0)
+func (bw *bitsWriter) Close() error {
+ if bw.nbuf > 0 {
+ bw.Write(0, 8 - (bw.nbuf % 8))
+ }
+ return bw.writeBuf()
}
func writePointlessGzipHeader(wr io.Writer) error {
@@ -147,13 +200,9 @@ func writePointlessGzipHeader(wr io.Writer) error {
}
func writePointlessGzipTrailer(wr io.Writer, length uint32) error {
- var trailer = [8]byte {
- 0, 0, 0, 0,
- byte(length),
- byte(length >> 8),
- byte(length >> 16),
- byte(length >> 24),
- }
+ var trailer [8]byte
+ binary.LittleEndian.PutUint32(trailer[0:], 0xffffffff)
+ binary.LittleEndian.PutUint32(trailer[4:], length)
_, err := wr.Write(trailer[:])
return err
}
diff --git a/server/map.go b/server/map.go
index f210d42..345a62c 100644
--- a/server/map.go
+++ b/server/map.go
@@ -201,14 +201,16 @@ func (v *blockVolume) unsyncBlocksInRange(min, max blockPos) []blockType {
func (v *blockVolume) syncCompressForNetwork(/*highBits bool*/) io.ReadCloser {
rd, wr := io.Pipe()
go func() {
+ defer wr.Close()
v.RLock()
defer v.RUnlock()
bw := bufio.NewWriter(wr)
defer bw.Flush()
+
writePointlessGzipHeader(bw)
- len := uint32(v.size.X*v.size.Y*v.size.Z)
- deflateRuns(wr, v.blockRuns, v.changes, len)
- writePointlessGzipTrailer(bw, len)
+ size := uint32(v.size.X*v.size.Y*v.size.Z)
+ dataLen, _ := deflateRuns(bw, v.blockRuns, v.changes, size)
+ writePointlessGzipTrailer(bw, dataLen)
}()
return rd
}
diff --git a/server/player.go b/server/player.go
index a6219cc..d2c6722 100644
--- a/server/player.go
+++ b/server/player.go
@@ -272,12 +272,6 @@ func (p *player) OnLevelData(from *level, info levelInfo, data io.ReadCloser) {
}
packets := func(yield func(classic.Packet) bool) {
defer data.Close()
- dbg, err := os.OpenFile("./debug.gz", os.O_CREATE | os.O_WRONLY, 0777)
- if err != nil {
- panic(err)
- }
- defer dbg.Close()
- data := io.TeeReader(data, dbg)
for {
var packet classic.LevelDataChunk
n, err := io.ReadFull(data, packet.Data[:])