language change
This commit is contained in:
30
language-change/asset-meta/bytehash16.go
Normal file
30
language-change/asset-meta/bytehash16.go
Normal file
@@ -0,0 +1,30 @@
|
||||
package assetMeta
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
)
|
||||
|
||||
type ByteHash16 []byte
|
||||
|
||||
func ByteHash16FromBytes(r io.ReadSeeker) (ByteHash16, error) {
|
||||
fullHash := make([]byte, 16)
|
||||
buf := make([]byte, 4)
|
||||
for i := 0; i < 4; i++ {
|
||||
if _, err := io.ReadFull(r, buf); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for j := 0; j < 4; j++ {
|
||||
fullHash[i*4+j] = buf[3-j]
|
||||
}
|
||||
}
|
||||
return ByteHash16(fullHash), nil
|
||||
}
|
||||
|
||||
func (b ByteHash16) String() string {
|
||||
s := ""
|
||||
for _, v := range b {
|
||||
s += fmt.Sprintf("%02x", v)
|
||||
}
|
||||
return s
|
||||
}
|
||||
28
language-change/asset-meta/dataEntry.go
Normal file
28
language-change/asset-meta/dataEntry.go
Normal file
@@ -0,0 +1,28 @@
|
||||
package assetMeta
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"io"
|
||||
)
|
||||
|
||||
type DataEntry struct {
|
||||
NameHash int32
|
||||
Size uint32
|
||||
Offset uint32
|
||||
}
|
||||
|
||||
func DataEntryFromBytes(r io.Reader) (*DataEntry, error) {
|
||||
var d DataEntry
|
||||
|
||||
if err := binary.Read(r, binary.BigEndian, &d.NameHash); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := binary.Read(r, binary.BigEndian, &d.Size); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := binary.Read(r, binary.BigEndian, &d.Offset); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &d, nil
|
||||
}
|
||||
98
language-change/asset-meta/designIndex.go
Normal file
98
language-change/asset-meta/designIndex.go
Normal file
@@ -0,0 +1,98 @@
|
||||
package assetMeta
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/binary"
|
||||
"encoding/hex"
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
)
|
||||
|
||||
|
||||
type DesignIndex struct {
|
||||
UnkI64 int64
|
||||
FileCount int32
|
||||
DesignDataCount int32
|
||||
FileList []FileEntry
|
||||
}
|
||||
|
||||
|
||||
|
||||
func (d *DesignIndex) FindDataAndFileByTarget(target int32) (DataEntry, FileEntry, error) {
|
||||
for _, file := range d.FileList {
|
||||
for _, entry := range file.DataEntries {
|
||||
if entry.NameHash == target {
|
||||
return entry, file, nil
|
||||
}
|
||||
}
|
||||
}
|
||||
return DataEntry{}, FileEntry{}, errors.New("not found")
|
||||
}
|
||||
|
||||
|
||||
func DesignIndexFromBytes(assetFolder string, indexHash string) (*DesignIndex, error) {
|
||||
path := filepath.Join(assetFolder, fmt.Sprintf("DesignV_%s.bytes", indexHash))
|
||||
data, err := os.ReadFile(path)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
r := bytes.NewReader(data)
|
||||
|
||||
var d DesignIndex
|
||||
|
||||
if err := binary.Read(r, binary.BigEndian, &d.UnkI64); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := binary.Read(r, binary.BigEndian, &d.FileCount); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := binary.Read(r, binary.BigEndian, &d.DesignDataCount); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
d.FileList = make([]FileEntry, 0, d.FileCount)
|
||||
for i := int32(0); i < d.FileCount; i++ {
|
||||
entry, err := FileEntryFromBytes(r)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
d.FileList = append(d.FileList, *entry)
|
||||
}
|
||||
|
||||
return &d, nil
|
||||
}
|
||||
|
||||
|
||||
func GetIndexHash(assetFolder string) (string, error) {
|
||||
path := filepath.Join(assetFolder, "M_DesignV.bytes")
|
||||
|
||||
f, err := os.Open(path)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
_, err = f.Seek(0x1C, 0)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
hash := make([]byte, 0x10)
|
||||
index := 0
|
||||
for i := 0; i < 4; i++ {
|
||||
chunk := make([]byte, 4)
|
||||
_, err := f.Read(chunk)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
for bytePos := 3; bytePos >= 0; bytePos-- {
|
||||
hash[index] = chunk[bytePos]
|
||||
index++
|
||||
}
|
||||
}
|
||||
|
||||
return hex.EncodeToString(hash), nil
|
||||
}
|
||||
63
language-change/asset-meta/fileEntry.go
Normal file
63
language-change/asset-meta/fileEntry.go
Normal file
@@ -0,0 +1,63 @@
|
||||
package assetMeta
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"fmt"
|
||||
"io"
|
||||
)
|
||||
|
||||
type FileEntry struct {
|
||||
NameHash int32
|
||||
FileByteName string
|
||||
Size int64
|
||||
DataCount int32
|
||||
DataEntries []DataEntry
|
||||
Unk uint8
|
||||
}
|
||||
|
||||
func FileEntryFromBytes(r io.Reader) (*FileEntry, error) {
|
||||
var f FileEntry
|
||||
|
||||
if err := binary.Read(r, binary.BigEndian, &f.NameHash); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
buf := make([]byte, 16)
|
||||
if _, err := io.ReadFull(r, buf); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
f.FileByteName = toHex(buf)
|
||||
|
||||
if err := binary.Read(r, binary.BigEndian, &f.Size); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := binary.Read(r, binary.BigEndian, &f.DataCount); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
f.DataEntries = make([]DataEntry, 0, f.DataCount)
|
||||
for i := int32(0); i < f.DataCount; i++ {
|
||||
entry, err := DataEntryFromBytes(r)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
f.DataEntries = append(f.DataEntries, *entry)
|
||||
}
|
||||
|
||||
// read 1 byte
|
||||
b := make([]byte, 1)
|
||||
if _, err := r.Read(b); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
f.Unk = b[0]
|
||||
|
||||
return &f, nil
|
||||
}
|
||||
|
||||
func toHex(buf []byte) string {
|
||||
s := ""
|
||||
for _, b := range buf {
|
||||
s += fmt.Sprintf("%02x", b)
|
||||
}
|
||||
return s
|
||||
}
|
||||
32
language-change/asset-meta/miniAsset.go
Normal file
32
language-change/asset-meta/miniAsset.go
Normal file
@@ -0,0 +1,32 @@
|
||||
package assetMeta
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"io"
|
||||
)
|
||||
|
||||
type MiniAsset struct {
|
||||
RevisionID uint32
|
||||
DesignIndexHash ByteHash16
|
||||
}
|
||||
|
||||
func MiniAssetFromBytes(r io.ReadSeeker) (*MiniAsset, error) {
|
||||
if _, err := r.Seek(6*4, io.SeekCurrent); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var revID uint32
|
||||
if err := binary.Read(r, binary.LittleEndian, &revID); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
hash, err := ByteHash16FromBytes(r)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &MiniAsset{
|
||||
RevisionID: revID,
|
||||
DesignIndexHash: hash,
|
||||
}, nil
|
||||
}
|
||||
Reference in New Issue
Block a user