Compare commits
2 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
1523c67ee8 | ||
|
f56ee42b79 |
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
lsconvert
|
||||||
|
*.sublime-workspace
|
@ -108,7 +108,6 @@ func (v Vec) MarshalXML(e *xml.Encoder, start xml.StartElement) error {
|
|||||||
switch i {
|
switch i {
|
||||||
case 0:
|
case 0:
|
||||||
name.Local = "x"
|
name.Local = "x"
|
||||||
// start.Name = "float1"
|
|
||||||
case 1:
|
case 1:
|
||||||
name.Local = "y"
|
name.Local = "y"
|
||||||
start.Name.Local = "float2"
|
start.Name.Local = "float2"
|
||||||
|
14
binutils.go
14
binutils.go
@ -85,21 +85,18 @@ func MakeCompressionFlags(method CompressionMethod, level CompressionLevel) int
|
|||||||
func Decompress(compressed io.Reader, uncompressedSize int, compressionFlags byte, chunked bool) io.ReadSeeker {
|
func Decompress(compressed io.Reader, uncompressedSize int, compressionFlags byte, chunked bool) io.ReadSeeker {
|
||||||
switch CompressionMethod(compressionFlags & 0x0f) {
|
switch CompressionMethod(compressionFlags & 0x0f) {
|
||||||
case CMNone:
|
case CMNone:
|
||||||
// logger.Println("No compression")
|
|
||||||
if v, ok := compressed.(io.ReadSeeker); ok {
|
if v, ok := compressed.(io.ReadSeeker); ok {
|
||||||
return v
|
return v
|
||||||
}
|
}
|
||||||
panic(errors.New("compressed must be an io.ReadSeeker if there is no compression"))
|
panic(errors.New("compressed must be an io.ReadSeeker if there is no compression"))
|
||||||
|
|
||||||
case CMZlib:
|
case CMZlib:
|
||||||
// logger.Println("zlib compression")
|
|
||||||
zr, _ := zlib.NewReader(compressed)
|
zr, _ := zlib.NewReader(compressed)
|
||||||
v, _ := ioutil.ReadAll(zr)
|
v, _ := ioutil.ReadAll(zr)
|
||||||
return bytes.NewReader(v)
|
return bytes.NewReader(v)
|
||||||
|
|
||||||
case CMLZ4:
|
case CMLZ4:
|
||||||
if chunked {
|
if chunked {
|
||||||
// logger.Println("lz4 stream compressed")
|
|
||||||
zr := lz4.NewReader(compressed)
|
zr := lz4.NewReader(compressed)
|
||||||
p := make([]byte, uncompressedSize)
|
p := make([]byte, uncompressedSize)
|
||||||
_, err := zr.Read(p)
|
_, err := zr.Read(p)
|
||||||
@ -108,10 +105,7 @@ func Decompress(compressed io.Reader, uncompressedSize int, compressionFlags byt
|
|||||||
}
|
}
|
||||||
return bytes.NewReader(p)
|
return bytes.NewReader(p)
|
||||||
}
|
}
|
||||||
// logger.Println("lz4 block compressed")
|
|
||||||
// panic(errors.New("not implemented"))
|
|
||||||
src, _ := ioutil.ReadAll(compressed)
|
src, _ := ioutil.ReadAll(compressed)
|
||||||
// logger.Println(len(src))
|
|
||||||
dst := make([]byte, uncompressedSize*2)
|
dst := make([]byte, uncompressedSize*2)
|
||||||
_, err := lz4.UncompressBlock(src, dst)
|
_, err := lz4.UncompressBlock(src, dst)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -147,7 +141,7 @@ func ReadAttribute(r io.ReadSeeker, name string, DT DataType, length uint, l log
|
|||||||
pos int64
|
pos int64
|
||||||
n int
|
n int
|
||||||
)
|
)
|
||||||
pos, err = r.Seek(0, io.SeekCurrent)
|
pos, _ = r.Seek(0, io.SeekCurrent)
|
||||||
|
|
||||||
switch DT {
|
switch DT {
|
||||||
case DTNone:
|
case DTNone:
|
||||||
@ -414,7 +408,6 @@ func ReadTranslatedString(r io.ReadSeeker, version FileVersion, engineVersion ui
|
|||||||
)
|
)
|
||||||
|
|
||||||
if version >= VerBG3 || engineVersion == 0x4000001d {
|
if version >= VerBG3 || engineVersion == 0x4000001d {
|
||||||
// logger.Println("decoding bg3 data")
|
|
||||||
var version uint16
|
var version uint16
|
||||||
err = binary.Read(r, binary.LittleEndian, &version)
|
err = binary.Read(r, binary.LittleEndian, &version)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -432,7 +425,7 @@ func ReadTranslatedString(r io.ReadSeeker, version FileVersion, engineVersion ui
|
|||||||
}
|
}
|
||||||
str.Version = 0
|
str.Version = 0
|
||||||
} else {
|
} else {
|
||||||
_, err = r.Seek(-2, io.SeekCurrent)
|
_, _ = r.Seek(-2, io.SeekCurrent)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
str.Version = 0
|
str.Version = 0
|
||||||
@ -464,11 +457,10 @@ func ReadTranslatedString(r io.ReadSeeker, version FileVersion, engineVersion ui
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return str, err
|
return str, err
|
||||||
}
|
}
|
||||||
// logger.Printf("handle %s; %v", str.Handle, err)
|
|
||||||
return str, nil
|
return str, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func ReadTranslatedFSString(r io.ReadSeeker, version FileVersion) (TranslatedFSString, error) {
|
func ReadTranslatedFSString(r io.Reader, version FileVersion) (TranslatedFSString, error) {
|
||||||
var (
|
var (
|
||||||
str = TranslatedFSString{}
|
str = TranslatedFSString{}
|
||||||
err error
|
err error
|
||||||
|
@ -11,7 +11,6 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
|
||||||
|
|
||||||
"git.narnian.us/lordwelch/lsgo"
|
"git.narnian.us/lordwelch/lsgo"
|
||||||
_ "git.narnian.us/lordwelch/lsgo/lsb"
|
_ "git.narnian.us/lordwelch/lsgo/lsb"
|
||||||
@ -40,7 +39,6 @@ func init() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
|
|
||||||
for _, v := range flag.Args() {
|
for _, v := range flag.Args() {
|
||||||
fi, err := os.Stat(v)
|
fi, err := os.Stat(v)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -48,7 +46,6 @@ func main() {
|
|||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
switch {
|
switch {
|
||||||
|
|
||||||
case !fi.IsDir():
|
case !fi.IsDir():
|
||||||
err = openLSF(v)
|
err = openLSF(v)
|
||||||
if err != nil && !errors.As(err, &lsgo.HeaderError{}) {
|
if err != nil && !errors.As(err, &lsgo.HeaderError{}) {
|
||||||
@ -131,14 +128,14 @@ func readLSF(filename string) (*lsgo.Resource, error) {
|
|||||||
err error
|
err error
|
||||||
)
|
)
|
||||||
switch filepath.Ext(filename) {
|
switch filepath.Ext(filename) {
|
||||||
|
|
||||||
case ".lsf", ".lsb":
|
case ".lsf", ".lsb":
|
||||||
var b []byte
|
var b []byte
|
||||||
fi, err = os.Stat(filename)
|
fi, err = os.Stat(filename)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
// Arbitrary size, no lsf file should reach 100 MB (I haven't found one over 90 KB) and if you don't have 100 MB of ram free you shouldn't be using this
|
// Arbitrary size, no lsf file should reach 100 MB (I haven't found one over 90 KB)
|
||||||
|
// and if you don't have 100 MB of ram free you shouldn't be using this
|
||||||
if fi.Size() <= 100*1024*1024 {
|
if fi.Size() <= 100*1024*1024 {
|
||||||
b, err = ioutil.ReadFile(filename)
|
b, err = ioutil.ReadFile(filename)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
4
const.go
4
const.go
@ -48,10 +48,10 @@ var (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type HeaderError struct {
|
type HeaderError struct {
|
||||||
Expected []byte
|
Expected string
|
||||||
Got []byte
|
Got []byte
|
||||||
}
|
}
|
||||||
|
|
||||||
func (he HeaderError) Error() string {
|
func (he HeaderError) Error() string {
|
||||||
return fmt.Sprintf("Invalid LSF signature; expected %v, got %v", he.Expected, he.Got)
|
return fmt.Sprintf("Invalid LSF signature; expected % X, got % X", he.Expected, he.Got)
|
||||||
}
|
}
|
||||||
|
@ -64,7 +64,7 @@ func sniff(r io.ReadSeeker) format {
|
|||||||
b = make([]byte, len(f.magic))
|
b = make([]byte, len(f.magic))
|
||||||
}
|
}
|
||||||
_, err = r.Read(b)
|
_, err = r.Read(b)
|
||||||
r.Seek(0, io.SeekStart)
|
_, _ = r.Seek(0, io.SeekStart)
|
||||||
if err == nil && match(f.magic, b) {
|
if err == nil && match(f.magic, b) {
|
||||||
return f
|
return f
|
||||||
}
|
}
|
||||||
|
2
go.mod
2
go.mod
@ -2,7 +2,7 @@ module git.narnian.us/lordwelch/lsgo
|
|||||||
|
|
||||||
go 1.15
|
go 1.15
|
||||||
|
|
||||||
replace github.com/pierrec/lz4/v4 v4.1.3 => ./lz4
|
replace github.com/pierrec/lz4/v4 v4.1.3 => ./third_party/lz4
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/go-kit/kit v0.10.0
|
github.com/go-kit/kit v0.10.0
|
||||||
|
76
lsb/lsb.go
76
lsb/lsb.go
@ -12,7 +12,12 @@ import (
|
|||||||
"github.com/go-kit/kit/log"
|
"github.com/go-kit/kit/log"
|
||||||
)
|
)
|
||||||
|
|
||||||
type LSBHeader struct {
|
const (
|
||||||
|
Signature = "LSFM"
|
||||||
|
PreBG3Signature = "\x00\x00\x00\x40"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Header struct {
|
||||||
Signature [4]byte
|
Signature [4]byte
|
||||||
Size uint32
|
Size uint32
|
||||||
Endianness uint32
|
Endianness uint32
|
||||||
@ -20,7 +25,7 @@ type LSBHeader struct {
|
|||||||
Version lsgo.LSMetadata
|
Version lsgo.LSMetadata
|
||||||
}
|
}
|
||||||
|
|
||||||
func (lsbh *LSBHeader) Read(r io.ReadSeeker) error {
|
func (h *Header) Read(r io.ReadSeeker) error {
|
||||||
var (
|
var (
|
||||||
l log.Logger
|
l log.Logger
|
||||||
pos int64
|
pos int64
|
||||||
@ -28,75 +33,75 @@ func (lsbh *LSBHeader) Read(r io.ReadSeeker) error {
|
|||||||
err error
|
err error
|
||||||
)
|
)
|
||||||
l = log.With(lsgo.Logger, "component", "LS converter", "file type", "lsb", "part", "header")
|
l = log.With(lsgo.Logger, "component", "LS converter", "file type", "lsb", "part", "header")
|
||||||
pos, err = r.Seek(0, io.SeekCurrent)
|
pos, _ = r.Seek(0, io.SeekCurrent)
|
||||||
|
|
||||||
n, err = r.Read(lsbh.Signature[:])
|
n, err = r.Read(h.Signature[:])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
l.Log("member", "Signature", "read", n, "start position", pos, "value", fmt.Sprintf("%#x", lsbh.Signature[:]))
|
l.Log("member", "Signature", "read", n, "start position", pos, "value", fmt.Sprintf("%#x", h.Signature[:]))
|
||||||
pos += int64(n)
|
pos += int64(n)
|
||||||
err = binary.Read(r, binary.LittleEndian, &lsbh.Size)
|
err = binary.Read(r, binary.LittleEndian, &h.Size)
|
||||||
n = 4
|
n = 4
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
l.Log("member", "Size", "read", n, "start position", pos, "value", lsbh.Size)
|
l.Log("member", "Size", "read", n, "start position", pos, "value", h.Size)
|
||||||
pos += int64(n)
|
pos += int64(n)
|
||||||
|
|
||||||
err = binary.Read(r, binary.LittleEndian, &lsbh.Endianness)
|
err = binary.Read(r, binary.LittleEndian, &h.Endianness)
|
||||||
n = 4
|
n = 4
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
l.Log("member", "Endianness", "read", n, "start position", pos, "value", lsbh.Endianness)
|
l.Log("member", "Endianness", "read", n, "start position", pos, "value", h.Endianness)
|
||||||
pos += int64(n)
|
pos += int64(n)
|
||||||
|
|
||||||
err = binary.Read(r, binary.LittleEndian, &lsbh.Unknown)
|
err = binary.Read(r, binary.LittleEndian, &h.Unknown)
|
||||||
n = 4
|
n = 4
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
l.Log("member", "Unknown", "read", n, "start position", pos, "value", lsbh.Unknown)
|
l.Log("member", "Unknown", "read", n, "start position", pos, "value", h.Unknown)
|
||||||
pos += int64(n)
|
pos += int64(n)
|
||||||
|
|
||||||
err = binary.Read(r, binary.LittleEndian, &lsbh.Version.Timestamp)
|
err = binary.Read(r, binary.LittleEndian, &h.Version.Timestamp)
|
||||||
n = 4
|
n = 4
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
l.Log("member", "Version.Timestamp", "read", n, "start position", pos, "value", lsbh.Version.Timestamp)
|
l.Log("member", "Version.Timestamp", "read", n, "start position", pos, "value", h.Version.Timestamp)
|
||||||
pos += int64(n)
|
pos += int64(n)
|
||||||
|
|
||||||
err = binary.Read(r, binary.LittleEndian, &lsbh.Version.Major)
|
err = binary.Read(r, binary.LittleEndian, &h.Version.Major)
|
||||||
n = 4
|
n = 4
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
l.Log("member", "Version.Major", "read", n, "start position", pos, "value", lsbh.Version.Major)
|
l.Log("member", "Version.Major", "read", n, "start position", pos, "value", h.Version.Major)
|
||||||
pos += int64(n)
|
pos += int64(n)
|
||||||
|
|
||||||
err = binary.Read(r, binary.LittleEndian, &lsbh.Version.Minor)
|
err = binary.Read(r, binary.LittleEndian, &h.Version.Minor)
|
||||||
n = 4
|
n = 4
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
l.Log("member", "Version.Minor", "read", n, "start position", pos, "value", lsbh.Version.Minor)
|
l.Log("member", "Version.Minor", "read", n, "start position", pos, "value", h.Version.Minor)
|
||||||
pos += int64(n)
|
pos += int64(n)
|
||||||
|
|
||||||
err = binary.Read(r, binary.LittleEndian, &lsbh.Version.Revision)
|
err = binary.Read(r, binary.LittleEndian, &h.Version.Revision)
|
||||||
n = 4
|
n = 4
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
l.Log("member", "Version.Revision", "read", n, "start position", pos, "value", lsbh.Version.Revision)
|
l.Log("member", "Version.Revision", "read", n, "start position", pos, "value", h.Version.Revision)
|
||||||
|
|
||||||
err = binary.Read(r, binary.LittleEndian, &lsbh.Version.Build)
|
err = binary.Read(r, binary.LittleEndian, &h.Version.Build)
|
||||||
n = 4
|
n = 4
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
l.Log("member", "Version.Build", "read", n, "start position", pos, "value", lsbh.Version.Build)
|
l.Log("member", "Version.Build", "read", n, "start position", pos, "value", h.Version.Build)
|
||||||
pos += int64(n)
|
pos += int64(n)
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
@ -104,10 +109,9 @@ func (lsbh *LSBHeader) Read(r io.ReadSeeker) error {
|
|||||||
|
|
||||||
type IdentifierDictionary map[int]string
|
type IdentifierDictionary map[int]string
|
||||||
|
|
||||||
func ReadLSB(r io.ReadSeeker) (lsgo.Resource, error) {
|
func Read(r io.ReadSeeker) (lsgo.Resource, error) {
|
||||||
var (
|
var (
|
||||||
hdr = &LSBHeader{}
|
hdr = &Header{}
|
||||||
h = [4]byte{0x00, 0x00, 0x00, 0x40}
|
|
||||||
err error
|
err error
|
||||||
d IdentifierDictionary
|
d IdentifierDictionary
|
||||||
res lsgo.Resource
|
res lsgo.Resource
|
||||||
@ -116,28 +120,28 @@ func ReadLSB(r io.ReadSeeker) (lsgo.Resource, error) {
|
|||||||
pos int64
|
pos int64
|
||||||
)
|
)
|
||||||
l = log.With(lsgo.Logger, "component", "LS converter", "file type", "lsb", "part", "file")
|
l = log.With(lsgo.Logger, "component", "LS converter", "file type", "lsb", "part", "file")
|
||||||
pos, err = r.Seek(0, io.SeekCurrent)
|
pos, _ = r.Seek(0, io.SeekCurrent)
|
||||||
l.Log("member", "header", "start position", pos)
|
l.Log("member", "header", "start position", pos)
|
||||||
|
|
||||||
err = hdr.Read(r)
|
err = hdr.Read(r)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return lsgo.Resource{}, err
|
return lsgo.Resource{}, err
|
||||||
}
|
}
|
||||||
if !(hdr.Signature == [4]byte{'L', 'S', 'F', 'M'} || hdr.Signature == h) {
|
if !(string(hdr.Signature[:]) == Signature || string(hdr.Signature[:]) == PreBG3Signature) {
|
||||||
return lsgo.Resource{}, lsgo.HeaderError{
|
return lsgo.Resource{}, lsgo.HeaderError{
|
||||||
Expected: []byte("LSFM"),
|
Expected: Signature,
|
||||||
Got: hdr.Signature[:],
|
Got: hdr.Signature[:],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pos, err = r.Seek(0, io.SeekCurrent)
|
pos, _ = r.Seek(0, io.SeekCurrent)
|
||||||
l.Log("member", "string dictionary", "start position", pos)
|
l.Log("member", "string dictionary", "start position", pos)
|
||||||
d, err = ReadLSBDictionary(r, binary.LittleEndian)
|
d, err = ReadLSBDictionary(r, binary.LittleEndian)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return lsgo.Resource{}, err
|
return lsgo.Resource{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
pos, err = r.Seek(0, io.SeekCurrent)
|
pos, _ = r.Seek(0, io.SeekCurrent)
|
||||||
l.Log("member", "Regions", "start position", pos)
|
l.Log("member", "Regions", "start position", pos)
|
||||||
|
|
||||||
res, err = ReadLSBRegions(r, d, binary.LittleEndian, lsgo.FileVersion(hdr.Version.Major))
|
res, err = ReadLSBRegions(r, d, binary.LittleEndian, lsgo.FileVersion(hdr.Version.Major))
|
||||||
@ -156,7 +160,7 @@ func ReadLSBDictionary(r io.ReadSeeker, endianness binary.ByteOrder) (Identifier
|
|||||||
n int
|
n int
|
||||||
)
|
)
|
||||||
l = log.With(lsgo.Logger, "component", "LS converter", "file type", "lsb", "part", "dictionary")
|
l = log.With(lsgo.Logger, "component", "LS converter", "file type", "lsb", "part", "dictionary")
|
||||||
pos, err = r.Seek(0, io.SeekCurrent)
|
pos, _ = r.Seek(0, io.SeekCurrent)
|
||||||
|
|
||||||
err = binary.Read(r, endianness, &length)
|
err = binary.Read(r, endianness, &length)
|
||||||
n = 4
|
n = 4
|
||||||
@ -215,7 +219,7 @@ func ReadLSBRegions(r io.ReadSeeker, d IdentifierDictionary, endianness binary.B
|
|||||||
n int
|
n int
|
||||||
)
|
)
|
||||||
l = log.With(lsgo.Logger, "component", "LS converter", "file type", "lsb", "part", "region")
|
l = log.With(lsgo.Logger, "component", "LS converter", "file type", "lsb", "part", "region")
|
||||||
pos, err = r.Seek(0, io.SeekCurrent)
|
pos, _ = r.Seek(0, io.SeekCurrent)
|
||||||
|
|
||||||
err = binary.Read(r, endianness, ®ionCount)
|
err = binary.Read(r, endianness, ®ionCount)
|
||||||
n = 4
|
n = 4
|
||||||
@ -284,7 +288,7 @@ func readLSBNode(r io.ReadSeeker, d IdentifierDictionary, endianness binary.Byte
|
|||||||
n int
|
n int
|
||||||
)
|
)
|
||||||
l = log.With(lsgo.Logger, "component", "LS converter", "file type", "lsb", "part", "node")
|
l = log.With(lsgo.Logger, "component", "LS converter", "file type", "lsb", "part", "node")
|
||||||
pos, err = r.Seek(0, io.SeekCurrent)
|
pos, _ = r.Seek(0, io.SeekCurrent)
|
||||||
|
|
||||||
if pos != int64(offset) && offset != 0 {
|
if pos != int64(offset) && offset != 0 {
|
||||||
panic("shit")
|
panic("shit")
|
||||||
@ -375,10 +379,10 @@ func ReadLSBAttr(r io.ReadSeeker, name string, dt lsgo.DataType, endianness bina
|
|||||||
pos int64
|
pos int64
|
||||||
)
|
)
|
||||||
l = log.With(lsgo.Logger, "component", "LS converter", "file type", "lsb", "part", "attribute")
|
l = log.With(lsgo.Logger, "component", "LS converter", "file type", "lsb", "part", "attribute")
|
||||||
pos, err = r.Seek(0, io.SeekCurrent)
|
pos, _ = r.Seek(0, io.SeekCurrent)
|
||||||
|
|
||||||
switch dt {
|
switch dt {
|
||||||
case lsgo.DTString, lsgo.DTPath, lsgo.DTFixedString, lsgo.DTLSString: //, DTLSWString:
|
case lsgo.DTString, lsgo.DTPath, lsgo.DTFixedString, lsgo.DTLSString: // DTLSWString:
|
||||||
var v string
|
var v string
|
||||||
err = binary.Read(r, endianness, &length)
|
err = binary.Read(r, endianness, &length)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -430,6 +434,6 @@ func ReadLSBAttr(r io.ReadSeeker, name string, dt lsgo.DataType, endianness bina
|
|||||||
}
|
}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
lsgo.RegisterFormat("lsb", "LSFM", ReadLSB)
|
lsgo.RegisterFormat("lsb", Signature, Read)
|
||||||
lsgo.RegisterFormat("lsb", "\x00\x00\x00\x40", ReadLSB)
|
lsgo.RegisterFormat("lsb", PreBG3Signature, Read)
|
||||||
}
|
}
|
||||||
|
166
lsf/lsf.go
166
lsf/lsf.go
@ -11,9 +11,9 @@ import (
|
|||||||
"github.com/go-kit/kit/log"
|
"github.com/go-kit/kit/log"
|
||||||
)
|
)
|
||||||
|
|
||||||
var LSFSignature = [4]byte{0x4C, 0x53, 0x4F, 0x46}
|
const Signature = "LSOF"
|
||||||
|
|
||||||
type LSFHeader struct {
|
type Header struct {
|
||||||
// LSOF file signature
|
// LSOF file signature
|
||||||
Signature [4]byte
|
Signature [4]byte
|
||||||
|
|
||||||
@ -46,7 +46,6 @@ type LSFHeader struct {
|
|||||||
|
|
||||||
// Compressed size of the raw value buffer
|
// Compressed size of the raw value buffer
|
||||||
ValuesSizeOnDisk uint32
|
ValuesSizeOnDisk uint32
|
||||||
// summary
|
|
||||||
|
|
||||||
// Uses the same format as packages (see BinUtils.MakeCompressionFlags)
|
// Uses the same format as packages (see BinUtils.MakeCompressionFlags)
|
||||||
CompressionFlags byte
|
CompressionFlags byte
|
||||||
@ -59,7 +58,7 @@ type LSFHeader struct {
|
|||||||
Extended uint32
|
Extended uint32
|
||||||
}
|
}
|
||||||
|
|
||||||
func (lsfh *LSFHeader) Read(r io.ReadSeeker) error {
|
func (h *Header) Read(r io.ReadSeeker) error {
|
||||||
var (
|
var (
|
||||||
l log.Logger
|
l log.Logger
|
||||||
pos int64
|
pos int64
|
||||||
@ -67,158 +66,150 @@ func (lsfh *LSFHeader) Read(r io.ReadSeeker) error {
|
|||||||
err error
|
err error
|
||||||
)
|
)
|
||||||
l = log.With(lsgo.Logger, "component", "LS converter", "file type", "lsf", "part", "header")
|
l = log.With(lsgo.Logger, "component", "LS converter", "file type", "lsf", "part", "header")
|
||||||
pos, err = r.Seek(0, io.SeekCurrent)
|
pos, _ = r.Seek(0, io.SeekCurrent)
|
||||||
n, err = r.Read(lsfh.Signature[:])
|
n, err = r.Read(h.Signature[:])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
l.Log("member", "Signature", "read", n, "start position", pos, "value", string(lsfh.Signature[:]))
|
l.Log("member", "Signature", "read", n, "start position", pos, "value", string(h.Signature[:]))
|
||||||
pos += int64(n)
|
pos += int64(n)
|
||||||
err = binary.Read(r, binary.LittleEndian, &lsfh.Version)
|
err = binary.Read(r, binary.LittleEndian, &h.Version)
|
||||||
n = 4
|
n = 4
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
l.Log("member", "Version", "read", n, "start position", pos, "value", lsfh.Version)
|
l.Log("member", "Version", "read", n, "start position", pos, "value", h.Version)
|
||||||
pos += int64(n)
|
pos += int64(n)
|
||||||
|
|
||||||
err = binary.Read(r, binary.LittleEndian, &lsfh.EngineVersion)
|
err = binary.Read(r, binary.LittleEndian, &h.EngineVersion)
|
||||||
n = 4
|
n = 4
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
l.Log("member", "EngineVersion", "read", n, "start position", pos, "value", fmt.Sprintf("%d.%d.%d.%d", (lsfh.EngineVersion&0xf0000000)>>28, (lsfh.EngineVersion&0xf000000)>>24, (lsfh.EngineVersion&0xff0000)>>16, (lsfh.EngineVersion&0xffff)))
|
l.Log("member", "EngineVersion", "read", n, "start position", pos, "value", fmt.Sprintf("%d.%d.%d.%d", (h.EngineVersion&0xf0000000)>>28, (h.EngineVersion&0xf000000)>>24, (h.EngineVersion&0xff0000)>>16, (h.EngineVersion&0xffff)))
|
||||||
pos += int64(n)
|
pos += int64(n)
|
||||||
|
|
||||||
err = binary.Read(r, binary.LittleEndian, &lsfh.StringsUncompressedSize)
|
err = binary.Read(r, binary.LittleEndian, &h.StringsUncompressedSize)
|
||||||
n = 4
|
n = 4
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
l.Log("member", "StringsUncompressedSize", "read", n, "start position", pos, "value", lsfh.StringsUncompressedSize)
|
l.Log("member", "StringsUncompressedSize", "read", n, "start position", pos, "value", h.StringsUncompressedSize)
|
||||||
pos += int64(n)
|
pos += int64(n)
|
||||||
|
|
||||||
err = binary.Read(r, binary.LittleEndian, &lsfh.StringsSizeOnDisk)
|
err = binary.Read(r, binary.LittleEndian, &h.StringsSizeOnDisk)
|
||||||
n = 4
|
n = 4
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
l.Log("member", "StringsSizeOnDisk", "read", n, "start position", pos, "value", lsfh.StringsSizeOnDisk)
|
l.Log("member", "StringsSizeOnDisk", "read", n, "start position", pos, "value", h.StringsSizeOnDisk)
|
||||||
pos += int64(n)
|
pos += int64(n)
|
||||||
|
|
||||||
err = binary.Read(r, binary.LittleEndian, &lsfh.NodesUncompressedSize)
|
err = binary.Read(r, binary.LittleEndian, &h.NodesUncompressedSize)
|
||||||
n = 4
|
n = 4
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
l.Log("member", "NodesUncompressedSize", "read", n, "start position", pos, "value", lsfh.NodesUncompressedSize)
|
l.Log("member", "NodesUncompressedSize", "read", n, "start position", pos, "value", h.NodesUncompressedSize)
|
||||||
pos += int64(n)
|
pos += int64(n)
|
||||||
|
|
||||||
err = binary.Read(r, binary.LittleEndian, &lsfh.NodesSizeOnDisk)
|
err = binary.Read(r, binary.LittleEndian, &h.NodesSizeOnDisk)
|
||||||
n = 4
|
n = 4
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
l.Log("member", "NodesSizeOnDisk", "read", n, "start position", pos, "value", lsfh.NodesSizeOnDisk)
|
l.Log("member", "NodesSizeOnDisk", "read", n, "start position", pos, "value", h.NodesSizeOnDisk)
|
||||||
pos += int64(n)
|
pos += int64(n)
|
||||||
|
|
||||||
err = binary.Read(r, binary.LittleEndian, &lsfh.AttributesUncompressedSize)
|
err = binary.Read(r, binary.LittleEndian, &h.AttributesUncompressedSize)
|
||||||
n = 4
|
n = 4
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
l.Log("member", "AttributesUncompressedSize", "read", n, "start position", pos, "value", lsfh.AttributesUncompressedSize)
|
l.Log("member", "AttributesUncompressedSize", "read", n, "start position", pos, "value", h.AttributesUncompressedSize)
|
||||||
pos += int64(n)
|
pos += int64(n)
|
||||||
|
|
||||||
err = binary.Read(r, binary.LittleEndian, &lsfh.AttributesSizeOnDisk)
|
err = binary.Read(r, binary.LittleEndian, &h.AttributesSizeOnDisk)
|
||||||
n = 4
|
n = 4
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
l.Log("member", "AttributesSizeOnDisk", "read", n, "start position", pos, "value", lsfh.AttributesSizeOnDisk)
|
l.Log("member", "AttributesSizeOnDisk", "read", n, "start position", pos, "value", h.AttributesSizeOnDisk)
|
||||||
pos += int64(n)
|
pos += int64(n)
|
||||||
|
|
||||||
err = binary.Read(r, binary.LittleEndian, &lsfh.ValuesUncompressedSize)
|
err = binary.Read(r, binary.LittleEndian, &h.ValuesUncompressedSize)
|
||||||
n = 4
|
n = 4
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
l.Log("member", "ValuesUncompressedSize", "read", n, "start position", pos, "value", lsfh.ValuesUncompressedSize)
|
l.Log("member", "ValuesUncompressedSize", "read", n, "start position", pos, "value", h.ValuesUncompressedSize)
|
||||||
pos += int64(n)
|
pos += int64(n)
|
||||||
|
|
||||||
err = binary.Read(r, binary.LittleEndian, &lsfh.ValuesSizeOnDisk)
|
err = binary.Read(r, binary.LittleEndian, &h.ValuesSizeOnDisk)
|
||||||
n = 4
|
n = 4
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
l.Log("member", "ValuesSizeOnDisk", "read", n, "start position", pos, "value", lsfh.ValuesSizeOnDisk)
|
l.Log("member", "ValuesSizeOnDisk", "read", n, "start position", pos, "value", h.ValuesSizeOnDisk)
|
||||||
pos += int64(n)
|
pos += int64(n)
|
||||||
|
|
||||||
err = binary.Read(r, binary.LittleEndian, &lsfh.CompressionFlags)
|
err = binary.Read(r, binary.LittleEndian, &h.CompressionFlags)
|
||||||
n = 1
|
n = 1
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
l.Log("member", "CompressionFlags", "read", n, "start position", pos, "value", lsfh.CompressionFlags)
|
l.Log("member", "CompressionFlags", "read", n, "start position", pos, "value", h.CompressionFlags)
|
||||||
pos += int64(n)
|
pos += int64(n)
|
||||||
|
|
||||||
err = binary.Read(r, binary.LittleEndian, &lsfh.Unknown2)
|
err = binary.Read(r, binary.LittleEndian, &h.Unknown2)
|
||||||
n = 1
|
n = 1
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
l.Log("member", "Unknown2", "read", n, "start position", pos, "value", lsfh.Unknown2)
|
l.Log("member", "Unknown2", "read", n, "start position", pos, "value", h.Unknown2)
|
||||||
pos += int64(n)
|
pos += int64(n)
|
||||||
|
|
||||||
err = binary.Read(r, binary.LittleEndian, &lsfh.Unknown3)
|
err = binary.Read(r, binary.LittleEndian, &h.Unknown3)
|
||||||
n = 2
|
n = 2
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
l.Log("member", "Unknown3", "read", n, "start position", pos, "value", lsfh.Unknown3)
|
l.Log("member", "Unknown3", "read", n, "start position", pos, "value", h.Unknown3)
|
||||||
pos += int64(n)
|
pos += int64(n)
|
||||||
|
|
||||||
err = binary.Read(r, binary.LittleEndian, &lsfh.Extended)
|
err = binary.Read(r, binary.LittleEndian, &h.Extended)
|
||||||
n = 4
|
n = 4
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
l.Log("member", "Extended", "read", n, "start position", pos, "value", lsfh.Extended)
|
l.Log("member", "Extended", "read", n, "start position", pos, "value", h.Extended)
|
||||||
pos += int64(n)
|
pos += int64(n)
|
||||||
|
|
||||||
if !lsfh.IsCompressed() {
|
if !h.IsCompressed() {
|
||||||
lsfh.NodesSizeOnDisk = lsfh.NodesUncompressedSize
|
h.NodesSizeOnDisk = h.NodesUncompressedSize
|
||||||
lsfh.AttributesSizeOnDisk = lsfh.AttributesUncompressedSize
|
h.AttributesSizeOnDisk = h.AttributesUncompressedSize
|
||||||
lsfh.StringsSizeOnDisk = lsfh.StringsUncompressedSize
|
h.StringsSizeOnDisk = h.StringsUncompressedSize
|
||||||
lsfh.ValuesSizeOnDisk = lsfh.ValuesUncompressedSize
|
h.ValuesSizeOnDisk = h.ValuesUncompressedSize
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (lsfh LSFHeader) IsCompressed() bool {
|
func (h Header) IsCompressed() bool {
|
||||||
return lsgo.CompressionFlagsToMethod(lsfh.CompressionFlags) != lsgo.CMNone && lsgo.CompressionFlagsToMethod(lsfh.CompressionFlags) != lsgo.CMInvalid
|
return lsgo.CompressionFlagsToMethod(h.CompressionFlags) != lsgo.CMNone && lsgo.CompressionFlagsToMethod(h.CompressionFlags) != lsgo.CMInvalid
|
||||||
}
|
}
|
||||||
|
|
||||||
type NodeEntry struct {
|
type NodeEntry struct {
|
||||||
Long bool
|
Long bool
|
||||||
|
|
||||||
// summary
|
|
||||||
|
|
||||||
// (16-bit MSB: index into name hash table, 16-bit LSB: offset in hash chain)
|
// (16-bit MSB: index into name hash table, 16-bit LSB: offset in hash chain)
|
||||||
NameHashTableIndex uint32
|
NameHashTableIndex uint32
|
||||||
|
|
||||||
// summary
|
|
||||||
|
|
||||||
// (-1: node has no attributes)
|
// (-1: node has no attributes)
|
||||||
FirstAttributeIndex int32
|
FirstAttributeIndex int32
|
||||||
|
|
||||||
// summary
|
|
||||||
|
|
||||||
// (-1: this node is a root region)
|
// (-1: this node is a root region)
|
||||||
ParentIndex int32
|
ParentIndex int32
|
||||||
|
|
||||||
// summary
|
|
||||||
|
|
||||||
// (-1: this is the last node)
|
// (-1: this is the last node)
|
||||||
NextSiblingIndex int32
|
NextSiblingIndex int32
|
||||||
}
|
}
|
||||||
@ -238,11 +229,10 @@ func (ne *NodeEntry) readShort(r io.ReadSeeker) error {
|
|||||||
n int
|
n int
|
||||||
)
|
)
|
||||||
l = log.With(lsgo.Logger, "component", "LS converter", "file type", "lsf", "part", "short node")
|
l = log.With(lsgo.Logger, "component", "LS converter", "file type", "lsf", "part", "short node")
|
||||||
pos, err = r.Seek(0, io.SeekCurrent)
|
pos, _ = r.Seek(0, io.SeekCurrent)
|
||||||
err = binary.Read(r, binary.LittleEndian, &ne.NameHashTableIndex)
|
err = binary.Read(r, binary.LittleEndian, &ne.NameHashTableIndex)
|
||||||
n = 4
|
n = 4
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// logger.Println(err, "ne.NameHashTableIndex", ne.NameHashTableIndex)
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
l.Log("member", "NameHashTableIndex", "read", n, "start position", pos, "value", strconv.Itoa(ne.NameIndex())+" "+strconv.Itoa(ne.NameOffset()))
|
l.Log("member", "NameHashTableIndex", "read", n, "start position", pos, "value", strconv.Itoa(ne.NameIndex())+" "+strconv.Itoa(ne.NameOffset()))
|
||||||
@ -251,7 +241,6 @@ func (ne *NodeEntry) readShort(r io.ReadSeeker) error {
|
|||||||
err = binary.Read(r, binary.LittleEndian, &ne.FirstAttributeIndex)
|
err = binary.Read(r, binary.LittleEndian, &ne.FirstAttributeIndex)
|
||||||
n = 4
|
n = 4
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// logger.Println(err, "ne.FirstAttributeIndex", ne.FirstAttributeIndex)
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
l.Log("member", "NameHashTableIndex", "read", n, "start position", pos, "value", ne.FirstAttributeIndex)
|
l.Log("member", "NameHashTableIndex", "read", n, "start position", pos, "value", ne.FirstAttributeIndex)
|
||||||
@ -260,7 +249,6 @@ func (ne *NodeEntry) readShort(r io.ReadSeeker) error {
|
|||||||
err = binary.Read(r, binary.LittleEndian, &ne.ParentIndex)
|
err = binary.Read(r, binary.LittleEndian, &ne.ParentIndex)
|
||||||
n = 4
|
n = 4
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// logger.Println(err, "ne.ParentIndex", ne.ParentIndex)
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
l.Log("member", "NameHashTableIndex", "read", n, "start position", pos, "value", ne.ParentIndex)
|
l.Log("member", "NameHashTableIndex", "read", n, "start position", pos, "value", ne.ParentIndex)
|
||||||
@ -276,7 +264,7 @@ func (ne *NodeEntry) readLong(r io.ReadSeeker) error {
|
|||||||
n int
|
n int
|
||||||
)
|
)
|
||||||
l = log.With(lsgo.Logger, "component", "LS converter", "file type", "lsf", "part", "long node")
|
l = log.With(lsgo.Logger, "component", "LS converter", "file type", "lsf", "part", "long node")
|
||||||
pos, err = r.Seek(0, io.SeekCurrent)
|
pos, _ = r.Seek(0, io.SeekCurrent)
|
||||||
err = binary.Read(r, binary.LittleEndian, &ne.NameHashTableIndex)
|
err = binary.Read(r, binary.LittleEndian, &ne.NameHashTableIndex)
|
||||||
n = 4
|
n = 4
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -322,7 +310,6 @@ func (ne NodeEntry) NameOffset() int {
|
|||||||
|
|
||||||
// Processed node information for a node in the LSF file
|
// Processed node information for a node in the LSF file
|
||||||
type NodeInfo struct {
|
type NodeInfo struct {
|
||||||
// summary
|
|
||||||
|
|
||||||
// (-1: this node is a root region)
|
// (-1: this node is a root region)
|
||||||
ParentIndex int
|
ParentIndex int
|
||||||
@ -333,8 +320,6 @@ type NodeInfo struct {
|
|||||||
// Offset in hash chain
|
// Offset in hash chain
|
||||||
NameOffset int
|
NameOffset int
|
||||||
|
|
||||||
// summary
|
|
||||||
|
|
||||||
// (-1: node has no attributes)
|
// (-1: node has no attributes)
|
||||||
FirstAttributeIndex int
|
FirstAttributeIndex int
|
||||||
}
|
}
|
||||||
@ -342,23 +327,16 @@ type NodeInfo struct {
|
|||||||
// attribute extension in the LSF file
|
// attribute extension in the LSF file
|
||||||
type AttributeEntry struct {
|
type AttributeEntry struct {
|
||||||
Long bool
|
Long bool
|
||||||
// summary
|
|
||||||
|
|
||||||
// (16-bit MSB: index into name hash table, 16-bit LSB: offset in hash chain)
|
// (16-bit MSB: index into name hash table, 16-bit LSB: offset in hash chain)
|
||||||
NameHashTableIndex uint32
|
NameHashTableIndex uint32
|
||||||
|
|
||||||
// summary
|
|
||||||
|
|
||||||
// 26-bit MSB: Length of this attribute
|
// 26-bit MSB: Length of this attribute
|
||||||
TypeAndLength uint32
|
TypeAndLength uint32
|
||||||
|
|
||||||
// summary
|
|
||||||
|
|
||||||
// Note: These indexes are assigned seemingly arbitrarily, and are not necessarily indices into the node list
|
// Note: These indexes are assigned seemingly arbitrarily, and are not necessarily indices into the node list
|
||||||
NodeIndex int32
|
NodeIndex int32
|
||||||
|
|
||||||
// summary
|
|
||||||
|
|
||||||
// Note: These indexes are assigned seemingly arbitrarily, and are not necessarily indices into the node list
|
// Note: These indexes are assigned seemingly arbitrarily, and are not necessarily indices into the node list
|
||||||
NextAttributeIndex int32
|
NextAttributeIndex int32
|
||||||
|
|
||||||
@ -381,7 +359,7 @@ func (ae *AttributeEntry) readShort(r io.ReadSeeker) error {
|
|||||||
n int
|
n int
|
||||||
)
|
)
|
||||||
l = log.With(lsgo.Logger, "component", "LS converter", "file type", "lsf", "part", "short attribute")
|
l = log.With(lsgo.Logger, "component", "LS converter", "file type", "lsf", "part", "short attribute")
|
||||||
pos, err = r.Seek(0, io.SeekCurrent)
|
pos, _ = r.Seek(0, io.SeekCurrent)
|
||||||
|
|
||||||
err = binary.Read(r, binary.LittleEndian, &ae.NameHashTableIndex)
|
err = binary.Read(r, binary.LittleEndian, &ae.NameHashTableIndex)
|
||||||
n = 4
|
n = 4
|
||||||
@ -418,7 +396,7 @@ func (ae *AttributeEntry) readLong(r io.ReadSeeker) error {
|
|||||||
n int
|
n int
|
||||||
)
|
)
|
||||||
l = log.With(lsgo.Logger, "component", "LS converter", "file type", "lsf", "part", "long attribute")
|
l = log.With(lsgo.Logger, "component", "LS converter", "file type", "lsf", "part", "long attribute")
|
||||||
pos, err = r.Seek(0, io.SeekCurrent)
|
pos, _ = r.Seek(0, io.SeekCurrent)
|
||||||
|
|
||||||
err = binary.Read(r, binary.LittleEndian, &ae.NameHashTableIndex)
|
err = binary.Read(r, binary.LittleEndian, &ae.NameHashTableIndex)
|
||||||
n = 4
|
n = 4
|
||||||
@ -492,7 +470,6 @@ type AttributeInfo struct {
|
|||||||
|
|
||||||
// Absolute position of attribute data in the values section
|
// Absolute position of attribute data in the values section
|
||||||
DataOffset uint
|
DataOffset uint
|
||||||
// summary
|
|
||||||
|
|
||||||
// (-1: this is the last attribute)
|
// (-1: this is the last attribute)
|
||||||
NextAttributeIndex int
|
NextAttributeIndex int
|
||||||
@ -510,7 +487,7 @@ func ReadNames(r io.ReadSeeker) ([][]string, error) {
|
|||||||
n int
|
n int
|
||||||
)
|
)
|
||||||
l = log.With(lsgo.Logger, "component", "LS converter", "file type", "lsf", "part", "names")
|
l = log.With(lsgo.Logger, "component", "LS converter", "file type", "lsf", "part", "names")
|
||||||
pos, err = r.Seek(0, io.SeekCurrent)
|
pos, _ = r.Seek(0, io.SeekCurrent)
|
||||||
|
|
||||||
err = binary.Read(r, binary.LittleEndian, &numHashEntries)
|
err = binary.Read(r, binary.LittleEndian, &numHashEntries)
|
||||||
n = 4
|
n = 4
|
||||||
@ -522,11 +499,13 @@ func ReadNames(r io.ReadSeeker) ([][]string, error) {
|
|||||||
|
|
||||||
names = make([][]string, int(numHashEntries))
|
names = make([][]string, int(numHashEntries))
|
||||||
for i := range names {
|
for i := range names {
|
||||||
|
|
||||||
var numStrings uint16
|
var numStrings uint16
|
||||||
|
|
||||||
err = binary.Read(r, binary.LittleEndian, &numStrings)
|
err = binary.Read(r, binary.LittleEndian, &numStrings)
|
||||||
n = 4
|
n = 4
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
l.Log("member", "numStrings", "read", n, "start position", pos, "value", numStrings)
|
l.Log("member", "numStrings", "read", n, "start position", pos, "value", numStrings)
|
||||||
pos += int64(n)
|
pos += int64(n)
|
||||||
|
|
||||||
@ -554,16 +533,13 @@ func ReadNames(r io.ReadSeeker) ([][]string, error) {
|
|||||||
pos += int64(n)
|
pos += int64(n)
|
||||||
|
|
||||||
hash[x] = string(name)
|
hash[x] = string(name)
|
||||||
|
|
||||||
}
|
}
|
||||||
names[i] = hash
|
names[i] = hash
|
||||||
|
|
||||||
}
|
}
|
||||||
return names, nil
|
return names, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func readNodeInfo(r io.ReadSeeker, longNodes bool) ([]NodeInfo, error) {
|
func readNodeInfo(r io.ReadSeeker, longNodes bool) ([]NodeInfo, error) {
|
||||||
// Console.WriteLine(" ----- DUMP OF NODE TABLE -----");
|
|
||||||
var (
|
var (
|
||||||
nodes []NodeInfo
|
nodes []NodeInfo
|
||||||
err error
|
err error
|
||||||
@ -572,7 +548,6 @@ func readNodeInfo(r io.ReadSeeker, longNodes bool) ([]NodeInfo, error) {
|
|||||||
|
|
||||||
for err == nil {
|
for err == nil {
|
||||||
var node NodeInfo
|
var node NodeInfo
|
||||||
// var pos = lsfr.Position;
|
|
||||||
|
|
||||||
item := &NodeEntry{Long: longNodes}
|
item := &NodeEntry{Long: longNodes}
|
||||||
err = item.Read(r)
|
err = item.Read(r)
|
||||||
@ -581,11 +556,6 @@ func readNodeInfo(r io.ReadSeeker, longNodes bool) ([]NodeInfo, error) {
|
|||||||
node.NameIndex = item.NameIndex()
|
node.NameIndex = item.NameIndex()
|
||||||
node.NameOffset = item.NameOffset()
|
node.NameOffset = item.NameOffset()
|
||||||
node.ParentIndex = int(item.ParentIndex)
|
node.ParentIndex = int(item.ParentIndex)
|
||||||
// Console.WriteLine(String.Format(
|
|
||||||
// "{0}: {1} @ {2:X} (parent {3}, firstAttribute {4})",
|
|
||||||
// index, Names[node.NameIndex][node.NameOffset], pos, node.ParentIndex,
|
|
||||||
// node.FirstAttributeIndex
|
|
||||||
// ));
|
|
||||||
|
|
||||||
nodes = append(nodes, node)
|
nodes = append(nodes, node)
|
||||||
index++
|
index++
|
||||||
@ -613,7 +583,6 @@ func readAttributeInfo(r io.ReadSeeker, long bool) []AttributeInfo {
|
|||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
// pretty.Log( attribute)
|
|
||||||
if long {
|
if long {
|
||||||
dataOffset = uint(attribute.Offset)
|
dataOffset = uint(attribute.Offset)
|
||||||
nextAttrIndex = int(attribute.NextAttributeIndex)
|
nextAttrIndex = int(attribute.NextAttributeIndex)
|
||||||
@ -630,7 +599,6 @@ func readAttributeInfo(r io.ReadSeeker, long bool) []AttributeInfo {
|
|||||||
|
|
||||||
if !long {
|
if !long {
|
||||||
// get index of previous attribute for node
|
// get index of previous attribute for node
|
||||||
|
|
||||||
if indexOfLastAttr, ok := prevAttributeRefs[int(attribute.NodeIndex)]; ok { // previous attribute exists for current node set the next attribute index for the previous node to this attribute
|
if indexOfLastAttr, ok := prevAttributeRefs[int(attribute.NodeIndex)]; ok { // previous attribute exists for current node set the next attribute index for the previous node to this attribute
|
||||||
attributes[indexOfLastAttr].NextAttributeIndex = index
|
attributes[indexOfLastAttr].NextAttributeIndex = index
|
||||||
}
|
}
|
||||||
@ -667,7 +635,7 @@ func readAttributeInfo(r io.ReadSeeker, long bool) []AttributeInfo {
|
|||||||
// }
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
func ReadLSF(r io.ReadSeeker) (lsgo.Resource, error) {
|
func Read(r io.ReadSeeker) (lsgo.Resource, error) {
|
||||||
var (
|
var (
|
||||||
err error
|
err error
|
||||||
|
|
||||||
@ -689,13 +657,13 @@ func ReadLSF(r io.ReadSeeker) (lsgo.Resource, error) {
|
|||||||
// n int
|
// n int
|
||||||
)
|
)
|
||||||
l = log.With(lsgo.Logger, "component", "LS converter", "file type", "lsf", "part", "file")
|
l = log.With(lsgo.Logger, "component", "LS converter", "file type", "lsf", "part", "file")
|
||||||
pos, err = r.Seek(0, io.SeekCurrent)
|
pos, _ = r.Seek(0, io.SeekCurrent)
|
||||||
l.Log("member", "header", "start position", pos)
|
l.Log("member", "header", "start position", pos)
|
||||||
|
|
||||||
hdr := &LSFHeader{}
|
hdr := &Header{}
|
||||||
err = hdr.Read(r)
|
err = hdr.Read(r)
|
||||||
if err != nil || (hdr.Signature != LSFSignature) {
|
if err != nil || (string(hdr.Signature[:]) != Signature) {
|
||||||
return lsgo.Resource{}, lsgo.HeaderError{Expected: LSFSignature[:], Got: hdr.Signature[:]}
|
return lsgo.Resource{}, lsgo.HeaderError{Expected: Signature, Got: hdr.Signature[:]}
|
||||||
}
|
}
|
||||||
|
|
||||||
if hdr.Version < lsgo.VerInitial || hdr.Version > lsgo.MaxVersion {
|
if hdr.Version < lsgo.VerInitial || hdr.Version > lsgo.MaxVersion {
|
||||||
@ -704,7 +672,7 @@ func ReadLSF(r io.ReadSeeker) (lsgo.Resource, error) {
|
|||||||
|
|
||||||
isCompressed := lsgo.CompressionFlagsToMethod(hdr.CompressionFlags) != lsgo.CMNone && lsgo.CompressionFlagsToMethod(hdr.CompressionFlags) != lsgo.CMInvalid
|
isCompressed := lsgo.CompressionFlagsToMethod(hdr.CompressionFlags) != lsgo.CMNone && lsgo.CompressionFlagsToMethod(hdr.CompressionFlags) != lsgo.CMInvalid
|
||||||
|
|
||||||
pos, err = r.Seek(0, io.SeekCurrent)
|
pos, _ = r.Seek(0, io.SeekCurrent)
|
||||||
l.Log("member", "LSF names", "start position", pos)
|
l.Log("member", "LSF names", "start position", pos)
|
||||||
if hdr.StringsSizeOnDisk > 0 || hdr.StringsUncompressedSize > 0 {
|
if hdr.StringsSizeOnDisk > 0 || hdr.StringsUncompressedSize > 0 {
|
||||||
uncompressed := lsgo.LimitReadSeeker(r, int64(hdr.StringsSizeOnDisk))
|
uncompressed := lsgo.LimitReadSeeker(r, int64(hdr.StringsSizeOnDisk))
|
||||||
@ -719,13 +687,12 @@ func ReadLSF(r io.ReadSeeker) (lsgo.Resource, error) {
|
|||||||
// }
|
// }
|
||||||
|
|
||||||
names, err = ReadNames(uncompressed)
|
names, err = ReadNames(uncompressed)
|
||||||
// pretty.Log(len(names), names)
|
|
||||||
if err != nil && err != io.EOF {
|
if err != nil && err != io.EOF {
|
||||||
return lsgo.Resource{}, err
|
return lsgo.Resource{}, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
npos, err = r.Seek(0, io.SeekCurrent)
|
npos, _ = r.Seek(0, io.SeekCurrent)
|
||||||
l.Log("member", "LSF nodes", "start position", npos)
|
l.Log("member", "LSF nodes", "start position", npos)
|
||||||
if npos != pos+int64(hdr.StringsSizeOnDisk) {
|
if npos != pos+int64(hdr.StringsSizeOnDisk) {
|
||||||
l.Log("member", "LSF nodes", "msg", "seeking to correct offset", "current", npos, "wanted", pos+int64(hdr.StringsSizeOnDisk))
|
l.Log("member", "LSF nodes", "msg", "seeking to correct offset", "current", npos, "wanted", pos+int64(hdr.StringsSizeOnDisk))
|
||||||
@ -746,14 +713,12 @@ func ReadLSF(r io.ReadSeeker) (lsgo.Resource, error) {
|
|||||||
|
|
||||||
longNodes := hdr.Version >= lsgo.VerExtendedNodes && hdr.Extended == 1
|
longNodes := hdr.Version >= lsgo.VerExtendedNodes && hdr.Extended == 1
|
||||||
nodeInfo, err = readNodeInfo(uncompressed, longNodes)
|
nodeInfo, err = readNodeInfo(uncompressed, longNodes)
|
||||||
// pretty.Log(err, nodeInfo)
|
|
||||||
// logger.Printf("region 1 name: %v", names[nodeInfo[0].NameIndex])
|
|
||||||
if err != nil && err != io.EOF {
|
if err != nil && err != io.EOF {
|
||||||
return lsgo.Resource{}, err
|
return lsgo.Resource{}, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
npos, err = r.Seek(0, io.SeekCurrent)
|
npos, _ = r.Seek(0, io.SeekCurrent)
|
||||||
l.Log("member", "LSF attributes", "start position", npos)
|
l.Log("member", "LSF attributes", "start position", npos)
|
||||||
if npos != pos+int64(hdr.NodesSizeOnDisk) {
|
if npos != pos+int64(hdr.NodesSizeOnDisk) {
|
||||||
l.Log("msg", "seeking to correct offset", "current", npos, "wanted", pos+int64(hdr.NodesSizeOnDisk))
|
l.Log("msg", "seeking to correct offset", "current", npos, "wanted", pos+int64(hdr.NodesSizeOnDisk))
|
||||||
@ -774,11 +739,9 @@ func ReadLSF(r io.ReadSeeker) (lsgo.Resource, error) {
|
|||||||
|
|
||||||
longAttributes := hdr.Version >= lsgo.VerExtendedNodes && hdr.Extended == 1
|
longAttributes := hdr.Version >= lsgo.VerExtendedNodes && hdr.Extended == 1
|
||||||
attributeInfo = readAttributeInfo(uncompressed, longAttributes)
|
attributeInfo = readAttributeInfo(uncompressed, longAttributes)
|
||||||
// logger.Printf("attribute 1 name: %v", names[attributeInfo[0].NameIndex])
|
|
||||||
// pretty.Log(attributeInfo)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
npos, err = r.Seek(0, io.SeekCurrent)
|
npos, _ = r.Seek(0, io.SeekCurrent)
|
||||||
l.Log("member", "LSF values", "start position", npos)
|
l.Log("member", "LSF values", "start position", npos)
|
||||||
if npos != pos+int64(hdr.AttributesSizeOnDisk) {
|
if npos != pos+int64(hdr.AttributesSizeOnDisk) {
|
||||||
l.Log("msg", "seeking to correct offset", "current", npos, "wanted", pos+int64(hdr.AttributesSizeOnDisk))
|
l.Log("msg", "seeking to correct offset", "current", npos, "wanted", pos+int64(hdr.AttributesSizeOnDisk))
|
||||||
@ -810,7 +773,6 @@ func ReadLSF(r io.ReadSeeker) (lsgo.Resource, error) {
|
|||||||
res.Metadata.Revision = (hdr.EngineVersion & 0xff0000) >> 16
|
res.Metadata.Revision = (hdr.EngineVersion & 0xff0000) >> 16
|
||||||
res.Metadata.Build = (hdr.EngineVersion & 0xffff)
|
res.Metadata.Build = (hdr.EngineVersion & 0xffff)
|
||||||
|
|
||||||
// pretty.Log(res)
|
|
||||||
return res, nil
|
return res, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -820,8 +782,6 @@ func ReadRegions(r io.ReadSeeker, valueStart int64, names [][]string, nodeInfo [
|
|||||||
if nodeInfo.ParentIndex == -1 {
|
if nodeInfo.ParentIndex == -1 {
|
||||||
region, err := ReadNode(r, valueStart, nodeInfo, names, attributeInfo, version, engineVersion)
|
region, err := ReadNode(r, valueStart, nodeInfo, names, attributeInfo, version, engineVersion)
|
||||||
|
|
||||||
// pretty.Log(err, region)
|
|
||||||
|
|
||||||
region.RegionName = region.Name
|
region.RegionName = region.Name
|
||||||
NodeInstances = append(NodeInstances, ®ion)
|
NodeInstances = append(NodeInstances, ®ion)
|
||||||
|
|
||||||
@ -831,8 +791,6 @@ func ReadRegions(r io.ReadSeeker, valueStart int64, names [][]string, nodeInfo [
|
|||||||
} else {
|
} else {
|
||||||
node, err := ReadNode(r, valueStart, nodeInfo, names, attributeInfo, version, engineVersion)
|
node, err := ReadNode(r, valueStart, nodeInfo, names, attributeInfo, version, engineVersion)
|
||||||
|
|
||||||
// pretty.Log(err, node)
|
|
||||||
|
|
||||||
node.Parent = NodeInstances[nodeInfo.ParentIndex]
|
node.Parent = NodeInstances[nodeInfo.ParentIndex]
|
||||||
NodeInstances = append(NodeInstances, &node)
|
NodeInstances = append(NodeInstances, &node)
|
||||||
NodeInstances[nodeInfo.ParentIndex].AppendChild(&node)
|
NodeInstances[nodeInfo.ParentIndex].AppendChild(&node)
|
||||||
@ -855,7 +813,7 @@ func ReadNode(r io.ReadSeeker, valueStart int64, ni NodeInfo, names [][]string,
|
|||||||
pos int64
|
pos int64
|
||||||
)
|
)
|
||||||
l = log.With(lsgo.Logger, "component", "LS converter", "file type", "lsf", "part", "node")
|
l = log.With(lsgo.Logger, "component", "LS converter", "file type", "lsf", "part", "node")
|
||||||
pos, err = r.Seek(0, io.SeekCurrent)
|
pos, _ = r.Seek(0, io.SeekCurrent)
|
||||||
|
|
||||||
node.Name = names[ni.NameIndex][ni.NameOffset]
|
node.Name = names[ni.NameIndex][ni.NameOffset]
|
||||||
|
|
||||||
@ -879,8 +837,6 @@ func ReadNode(r io.ReadSeeker, valueStart int64, ni NodeInfo, names [][]string,
|
|||||||
return node, err
|
return node, err
|
||||||
}
|
}
|
||||||
index = attribute.NextAttributeIndex
|
index = attribute.NextAttributeIndex
|
||||||
|
|
||||||
// Console.WriteLine(String.Format(" {0:X}: {1} ({2})", attribute.DataOffset, names[attribute.NameIndex][attribute.NameOffset], value));
|
|
||||||
}
|
}
|
||||||
return node, nil
|
return node, nil
|
||||||
}
|
}
|
||||||
@ -900,7 +856,7 @@ func ReadLSFAttribute(r io.ReadSeeker, name string, dt lsgo.DataType, length uin
|
|||||||
pos int64
|
pos int64
|
||||||
)
|
)
|
||||||
l = log.With(lsgo.Logger, "component", "LS converter", "file type", "lsf", "part", "attribute")
|
l = log.With(lsgo.Logger, "component", "LS converter", "file type", "lsf", "part", "attribute")
|
||||||
pos, err = r.Seek(0, io.SeekCurrent)
|
pos, _ = r.Seek(0, io.SeekCurrent)
|
||||||
|
|
||||||
switch dt {
|
switch dt {
|
||||||
case lsgo.DTString, lsgo.DTPath, lsgo.DTFixedString, lsgo.DTLSString, lsgo.DTWString, lsgo.DTLSWString:
|
case lsgo.DTString, lsgo.DTPath, lsgo.DTFixedString, lsgo.DTLSString, lsgo.DTWString, lsgo.DTLSWString:
|
||||||
@ -950,5 +906,5 @@ func ReadLSFAttribute(r io.ReadSeeker, name string, dt lsgo.DataType, length uin
|
|||||||
}
|
}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
lsgo.RegisterFormat("lsf", "LSOF", ReadLSF)
|
lsgo.RegisterFormat("lsf", Signature, Read)
|
||||||
}
|
}
|
||||||
|
37
lsgo.sublime-project
Normal file
37
lsgo.sublime-project
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
{
|
||||||
|
"folders":
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"path": "."
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"settings":
|
||||||
|
{
|
||||||
|
"LSP":
|
||||||
|
{
|
||||||
|
"gopls":
|
||||||
|
{
|
||||||
|
"settings":
|
||||||
|
{
|
||||||
|
"gopls":
|
||||||
|
{
|
||||||
|
"usePlaceholders": true,
|
||||||
|
"buildFlags":
|
||||||
|
[
|
||||||
|
"-tags",
|
||||||
|
"noasm"
|
||||||
|
],
|
||||||
|
"directoryFilters":
|
||||||
|
[
|
||||||
|
"third_party"
|
||||||
|
],
|
||||||
|
"analyses": {
|
||||||
|
"shadow": true,
|
||||||
|
"unusedparams": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -37,7 +37,7 @@ type Node struct {
|
|||||||
RegionName string `xml:"-"`
|
RegionName string `xml:"-"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n Node) MarshalXML(e *xml.Encoder, start xml.StartElement) error {
|
func (n *Node) MarshalXML(e *xml.Encoder, start xml.StartElement) error {
|
||||||
R := xml.Name{
|
R := xml.Name{
|
||||||
Local: "region",
|
Local: "region",
|
||||||
}
|
}
|
||||||
|
0
lz4/LICENSE → third_party/lz4/LICENSE
vendored
0
lz4/LICENSE → third_party/lz4/LICENSE
vendored
0
lz4/go.mod → third_party/lz4/go.mod
vendored
0
lz4/go.mod → third_party/lz4/go.mod
vendored
0
lz4/go.sum → third_party/lz4/go.sum
vendored
0
lz4/go.sum → third_party/lz4/go.sum
vendored
0
lz4/lz4.go → third_party/lz4/lz4.go
vendored
0
lz4/lz4.go → third_party/lz4/lz4.go
vendored
0
lz4/state.go → third_party/lz4/state.go
vendored
0
lz4/state.go → third_party/lz4/state.go
vendored
Loading…
x
Reference in New Issue
Block a user