From 401834008cd224c341b742ae1e3de3746ab5d517 Mon Sep 17 00:00:00 2001 From: Andrew Gutekanst Date: Tue, 3 Mar 2020 20:21:41 -0500 Subject: [PATCH] Move null compression to subpackage --- .../compression/nullcomp/nullcomp.go | 93 ++++++++++++++++++ server/channelserver/handlers.go | 98 ++----------------- 2 files changed, 99 insertions(+), 92 deletions(-) create mode 100644 server/channelserver/compression/nullcomp/nullcomp.go diff --git a/server/channelserver/compression/nullcomp/nullcomp.go b/server/channelserver/compression/nullcomp/nullcomp.go new file mode 100644 index 000000000..ed62e99ca --- /dev/null +++ b/server/channelserver/compression/nullcomp/nullcomp.go @@ -0,0 +1,93 @@ +package nullcomp + +import ( + "bytes" + "io" +) + +// Decompress decompresses null-compressesed data. +func Decompress(compData []byte) ([]byte, error) { + r := bytes.NewReader(compData) + + header := make([]byte, 16) + n, err := r.Read(header) + if err != nil { + return nil, err + } else if n != len(header) { + return nil, err + } + + // Just return the data if it doesn't contain the cmp header. + if !bytes.Equal(header, []byte("cmp\x2020110113\x20\x20\x20\x00")) { + return compData, nil + } + + var output []byte + for { + b, err := r.ReadByte() + if err == io.EOF { + break + } else if err != nil { + return nil, err + } + + if b == 0 { + // If it's a null byte, then the next byte is how many nulls to add. + nullCount, err := r.ReadByte() + if err == io.EOF { + break + } else if err != nil { + return nil, err + } + + output = append(output, make([]byte, int(nullCount))...) + } else { + output = append(output, b) + } + } + + return output, nil +} + +// Compress null compresses give given data. +func Compress(rawData []byte) ([]byte, error) { + r := bytes.NewReader(rawData) + var output []byte + output = append(output, []byte("cmp\x2020110113\x20\x20\x20\x00")...) + for { + b, err := r.ReadByte() + if err == io.EOF { + break + } else if err != nil { + return nil, err + } + if b == 0 { + output = append(output, []byte{0x00}...) + // read to get null count + nullCount := 1 + for { + i, err := r.ReadByte() + if err == io.EOF { + output = append(output, []byte{byte(nullCount)}...) + break + } else if i != 0 { + r.UnreadByte() + output = append(output, []byte{byte(nullCount)}...) + break + } else if err != nil { + return nil, err + } + nullCount++ + + // Flush the null-count if it gets to 255, start on the next null count. + if nullCount == 255 { + output = append(output, []byte{0xFF, 0x00}...) + nullCount = 0 + } + } + } else { + output = append(output, b) + } + } + return output, nil +} diff --git a/server/channelserver/handlers.go b/server/channelserver/handlers.go index 19433c21d..bf341b7a4 100644 --- a/server/channelserver/handlers.go +++ b/server/channelserver/handlers.go @@ -6,7 +6,6 @@ import ( "encoding/base64" "encoding/hex" "fmt" - "io" "io/ioutil" "os" "path/filepath" @@ -14,6 +13,7 @@ import ( "time" "github.com/Andoryuuta/Erupe/network/mhfpacket" + "github.com/Andoryuuta/Erupe/server/channelserver/compression/nullcomp" "github.com/Andoryuuta/byteframe" "go.uber.org/zap" "golang.org/x/text/encoding/japanese" @@ -88,92 +88,6 @@ func saveDataDiff(b []byte, save []byte) []byte { return save } -// decompress save data -func saveDecompress(compData []byte) ([]byte, error) { - r := bytes.NewReader(compData) - - header := make([]byte, 16) - n, err := r.Read(header) - if err != nil { - return nil, err - } else if n != len(header) { - return nil, err - } - - if !bytes.Equal(header, []byte("cmp\x2020110113\x20\x20\x20\x00")) { - return nil, err - } - - var output []byte - for { - b, err := r.ReadByte() - if err == io.EOF { - break - } else if err != nil { - return nil, err - } - - if b == 0 { - // If it's a null byte, then the next byte is how many nulls to add. - nullCount, err := r.ReadByte() - if err == io.EOF { - break - } else if err != nil { - return nil, err - } - - output = append(output, make([]byte, int(nullCount))...) - } else { - output = append(output, b) - } - } - - return output, nil -} - -// Null compresses a save -func saveCompress(rawData []byte) ([]byte, error) { - r := bytes.NewReader(rawData) - var output []byte - output = append(output, []byte("cmp\x2020110113\x20\x20\x20\x00")...) - for { - b, err := r.ReadByte() - if err == io.EOF { - break - } else if err != nil { - return nil, err - } - if b == 0 { - output = append(output, []byte{0x00}...) - // read to get null count - nullCount := 1 - for { - i, err := r.ReadByte() - if err == io.EOF { - output = append(output, []byte{byte(nullCount)}...) - break - } else if i != 0 { - r.UnreadByte() - output = append(output, []byte{byte(nullCount)}...) - break - } else if err != nil { - return nil, err - } - nullCount++ - - if nullCount == 255 { - output = append(output, []byte{0xFF, 0x00}...) - nullCount = 0 - } - } - //output = append(output, []byte{byte(nullCount)}...) - } else { - output = append(output, b) - } - } - return output, nil -} - func updateRights(s *Session) { update := &mhfpacket.MsgSysUpdateRight{ Unk0: 0, @@ -1027,7 +941,7 @@ func handleMsgMhfSavedata(s *Session, p mhfpacket.MHFPacket) { // 0x1F715 Weapon Class // 0x1FDF6 HR (small_gr_level) // 0x88 Character Name - saveFile, _ := saveDecompress(pkt.RawDataPayload) + saveFile, _ := nullcomp.Decompress(pkt.RawDataPayload) _, err = s.server.db.Exec("UPDATE characters SET weapon=$1 WHERE id=$2", uint16(saveFile[128789]), s.charID) x := uint16(saveFile[130550])<<8 | uint16(saveFile[130551]) _, err = s.server.db.Exec("UPDATE characters SET small_gr_level=$1 WHERE id=$2", uint16(x), s.charID) @@ -1632,13 +1546,13 @@ func handleMsgMhfSavePlateData(s *Session, p mhfpacket.MHFPacket) { } //decompress fmt.Println("Decompressing...") - data, err = saveDecompress(data) + data, err = nullcomp.Decompress(data) if err != nil { s.logger.Fatal("Failed to decompress platedata from db", zap.Error(err)) } // perform diff and compress it to write back to db fmt.Println("Diffing...") - saveOutput, err := saveCompress(saveDataDiff(pkt.RawDataPayload, data)) + saveOutput, err := nullcomp.Compress(saveDataDiff(pkt.RawDataPayload, data)) if err != nil { s.logger.Fatal("Failed to diff and compress platedata savedata", zap.Error(err)) } @@ -1686,13 +1600,13 @@ func handleMsgMhfSavePlateBox(s *Session, p mhfpacket.MHFPacket) { } //decompress fmt.Println("Decompressing...") - data, err = saveDecompress(data) + data, err = nullcomp.Decompress(data) if err != nil { s.logger.Fatal("Failed to decompress savedata from db", zap.Error(err)) } // perform diff and compress it to write back to db fmt.Println("Diffing...") - saveOutput, err := saveCompress(saveDataDiff(pkt.RawDataPayload, data)) + saveOutput, err := nullcomp.Compress(saveDataDiff(pkt.RawDataPayload, data)) if err != nil { s.logger.Fatal("Failed to diff and compress savedata", zap.Error(err)) }