1
1
mirror of https://github.com/OpenDiablo2/OpenDiablo2 synced 2024-11-19 02:46:35 -05:00

Merge branch 'master' into data-encoder-dat

This commit is contained in:
gucio321 2021-02-08 18:43:58 +01:00 committed by GitHub
commit b74bc3d0b6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 107 additions and 45 deletions

View File

@ -107,6 +107,10 @@ func (v *StreamReader) Size() uint64 {
// ReadBytes reads multiple bytes // ReadBytes reads multiple bytes
func (v *StreamReader) ReadBytes(count int) ([]byte, error) { func (v *StreamReader) ReadBytes(count int) ([]byte, error) {
if count <= 0 {
return nil, nil
}
size := v.Size() size := v.Size()
if v.position >= size || v.position+uint64(count) > size { if v.position >= size || v.position+uint64(count) > size {
return nil, io.EOF return nil, io.EOF

View File

@ -8,9 +8,10 @@ import (
) )
const ( const (
unknownByteCount = 21 numUnknownHeaderBytes = 21
numHeaderBytes = 4 + unknownByteCount numUnknownBodyBytes = 3
numLayerBytes = 9 numHeaderBytes = 4 + numUnknownHeaderBytes
numLayerBytes = 9
) )
const ( const (
@ -33,12 +34,41 @@ const (
badCharacter = string(byte(0)) badCharacter = string(byte(0))
) )
// New creates a new COF
func New() *COF {
return &COF{
unknownHeaderBytes: make([]byte, numUnknownHeaderBytes),
unknownBodyBytes: make([]byte, numUnknownBodyBytes),
NumberOfDirections: 0,
FramesPerDirection: 0,
NumberOfLayers: 0,
Speed: 0,
CofLayers: make([]CofLayer, 0),
CompositeLayers: make(map[d2enum.CompositeType]int),
AnimationFrames: make([]d2enum.AnimationFrame, 0),
Priority: make([][][]d2enum.CompositeType, 0),
}
}
// Marshal a COF to a new byte slice
func Marshal(c *COF) []byte {
return c.Marshal()
}
// Unmarshal a byte slice to a new COF
func Unmarshal(data []byte) (*COF, error) {
c := New()
err := c.Unmarshal(data)
return c, err
}
// COF is a structure that represents a COF file. // COF is a structure that represents a COF file.
type COF struct { type COF struct {
// unknown bytes for header // unknown bytes for header
unknownHeaderBytes []byte unknownHeaderBytes []byte
// unknown bytes (first "body's" bytes) // unknown bytes (first "body's" bytes)
unknown1 []byte unknownBodyBytes []byte
NumberOfDirections int NumberOfDirections int
FramesPerDirection int FramesPerDirection int
NumberOfLayers int NumberOfLayers int
@ -49,10 +79,9 @@ type COF struct {
Priority [][][]d2enum.CompositeType Priority [][][]d2enum.CompositeType
} }
// Load loads a COF file. // Unmarshal a byte slice to this COF
// nolint:funlen // no need to change // nolint:funlen // no need to change
func Load(fileData []byte) (*COF, error) { func (c *COF) Unmarshal(fileData []byte) error {
result := &COF{}
streamReader := d2datautils.CreateStreamReader(fileData) streamReader := d2datautils.CreateStreamReader(fileData)
var b []byte var b []byte
@ -61,35 +90,29 @@ func Load(fileData []byte) (*COF, error) {
b, err = streamReader.ReadBytes(numHeaderBytes) b, err = streamReader.ReadBytes(numHeaderBytes)
if err != nil { if err != nil {
return nil, err return err
} }
result.NumberOfLayers = int(b[headerNumLayers]) c.NumberOfLayers = int(b[headerNumLayers])
result.FramesPerDirection = int(b[headerFramesPerDir]) c.FramesPerDirection = int(b[headerFramesPerDir])
result.NumberOfDirections = int(b[headerNumDirs]) c.NumberOfDirections = int(b[headerNumDirs])
result.unknownHeaderBytes = b[headerNumDirs+1 : headerSpeed] c.unknownHeaderBytes = b[headerNumDirs+1 : headerSpeed]
result.Speed = int(b[headerSpeed]) c.Speed = int(b[headerSpeed])
// read unknown bytes c.unknownBodyBytes, err = streamReader.ReadBytes(numUnknownBodyBytes)
// previous streamReader.SkipBytes(3) if err != nil {
for i := 0; i < 3; i++ { return err
b, errSR := streamReader.ReadByte()
if errSR != nil {
return nil, errSR
}
result.unknown1 = append(result.unknown1, b)
} }
result.CofLayers = make([]CofLayer, result.NumberOfLayers) c.CofLayers = make([]CofLayer, c.NumberOfLayers)
result.CompositeLayers = make(map[d2enum.CompositeType]int) c.CompositeLayers = make(map[d2enum.CompositeType]int)
for i := 0; i < result.NumberOfLayers; i++ { for i := 0; i < c.NumberOfLayers; i++ {
layer := CofLayer{} layer := CofLayer{}
b, err = streamReader.ReadBytes(numLayerBytes) b, err = streamReader.ReadBytes(numLayerBytes)
if err != nil { if err != nil {
return nil, err return err
} }
layer.Type = d2enum.CompositeType(b[layerType]) layer.Type = d2enum.CompositeType(b[layerType])
@ -102,46 +125,46 @@ func Load(fileData []byte) (*COF, error) {
layer.WeaponClass = d2enum.WeaponClassFromString(strings.TrimSpace(strings.ReplaceAll( layer.WeaponClass = d2enum.WeaponClassFromString(strings.TrimSpace(strings.ReplaceAll(
string(b[layerWeaponClass:]), badCharacter, ""))) string(b[layerWeaponClass:]), badCharacter, "")))
result.CofLayers[i] = layer c.CofLayers[i] = layer
result.CompositeLayers[layer.Type] = i c.CompositeLayers[layer.Type] = i
} }
b, err = streamReader.ReadBytes(result.FramesPerDirection) b, err = streamReader.ReadBytes(c.FramesPerDirection)
if err != nil { if err != nil {
return nil, err return err
} }
result.AnimationFrames = make([]d2enum.AnimationFrame, result.FramesPerDirection) c.AnimationFrames = make([]d2enum.AnimationFrame, c.FramesPerDirection)
for i := range b { for i := range b {
result.AnimationFrames[i] = d2enum.AnimationFrame(b[i]) c.AnimationFrames[i] = d2enum.AnimationFrame(b[i])
} }
priorityLen := result.FramesPerDirection * result.NumberOfDirections * result.NumberOfLayers priorityLen := c.FramesPerDirection * c.NumberOfDirections * c.NumberOfLayers
result.Priority = make([][][]d2enum.CompositeType, result.NumberOfDirections) c.Priority = make([][][]d2enum.CompositeType, c.NumberOfDirections)
priorityBytes, err := streamReader.ReadBytes(priorityLen) priorityBytes, err := streamReader.ReadBytes(priorityLen)
if err != nil { if err != nil {
return nil, err return err
} }
priorityIndex := 0 priorityIndex := 0
for direction := 0; direction < result.NumberOfDirections; direction++ { for direction := 0; direction < c.NumberOfDirections; direction++ {
result.Priority[direction] = make([][]d2enum.CompositeType, result.FramesPerDirection) c.Priority[direction] = make([][]d2enum.CompositeType, c.FramesPerDirection)
for frame := 0; frame < result.FramesPerDirection; frame++ { for frame := 0; frame < c.FramesPerDirection; frame++ {
result.Priority[direction][frame] = make([]d2enum.CompositeType, result.NumberOfLayers) c.Priority[direction][frame] = make([]d2enum.CompositeType, c.NumberOfLayers)
for i := 0; i < result.NumberOfLayers; i++ { for i := 0; i < c.NumberOfLayers; i++ {
result.Priority[direction][frame][i] = d2enum.CompositeType(priorityBytes[priorityIndex]) c.Priority[direction][frame][i] = d2enum.CompositeType(priorityBytes[priorityIndex])
priorityIndex++ priorityIndex++
} }
} }
} }
return result, nil return nil
} }
// Marshal encodes COF back into byte slince // Marshal this COF to a byte slice
func (c *COF) Marshal() []byte { func (c *COF) Marshal() []byte {
sw := d2datautils.CreateStreamWriter() sw := d2datautils.CreateStreamWriter()
@ -150,7 +173,7 @@ func (c *COF) Marshal() []byte {
sw.PushBytes(byte(c.NumberOfDirections)) sw.PushBytes(byte(c.NumberOfDirections))
sw.PushBytes(c.unknownHeaderBytes...) sw.PushBytes(c.unknownHeaderBytes...)
sw.PushBytes(byte(c.Speed)) sw.PushBytes(byte(c.Speed))
sw.PushBytes(c.unknown1...) sw.PushBytes(c.unknownBodyBytes...)
for i := range c.CofLayers { for i := range c.CofLayers {
sw.PushBytes(byte(c.CofLayers[i].Type.Int())) sw.PushBytes(byte(c.CofLayers[i].Type.Int()))

View File

@ -0,0 +1,35 @@
package d2cof
import "testing"
func TestCOF_New(t *testing.T) {
c := New()
if c == nil {
t.Error("method New created nil instance")
}
}
func TestCOF_Marshal_Unmarshal(t *testing.T) {
cof1 := New()
cof2 := New()
var err error
err = cof1.Unmarshal(make([]byte, 1000))
if err != nil {
t.Error(err)
}
cof1.Speed = 255
data1 := cof1.Marshal()
err = cof2.Unmarshal(data1)
if err != nil {
t.Error(err)
}
if cof2.Speed != cof1.Speed {
t.Error("marshaled data does not match unmarshaled data")
}
}

View File

@ -543,7 +543,7 @@ func (am *AssetManager) LoadCOF(cofPath string) (*d2cof.COF, error) {
return nil, err return nil, err
} }
cof, err := d2cof.Load(fileData) cof, err := d2cof.Unmarshal(fileData)
if err != nil { if err != nil {
return nil, err return nil, err
} }