-
Notifications
You must be signed in to change notification settings - Fork 9
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Refactor, Add binary data processing
- Loading branch information
Showing
10 changed files
with
1,085 additions
and
892 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
package parser | ||
|
||
import ( | ||
log "github.com/sirupsen/logrus" | ||
"strings" | ||
) | ||
|
||
type ClassResolver func(parser *PakParser, export *FObjectExport, size int32, uAsset *FPackageFileSummary) interface{} | ||
|
||
var classResolvers = map[string]ClassResolver{ | ||
"DataTable": func(parser *PakParser, export *FObjectExport, size int32, uAsset *FPackageFileSummary) interface{} { | ||
return parser.ReadUDataTable(uAsset) | ||
}, | ||
"ObjectProperty": func(parser *PakParser, export *FObjectExport, size int32, uAsset *FPackageFileSummary) interface{} { | ||
// TODO Figure out | ||
parser.Read(24) | ||
return parser.ReadFPackageIndex(uAsset.Imports, uAsset.Exports) | ||
}, | ||
"BoolProperty": func(parser *PakParser, export *FObjectExport, size int32, uAsset *FPackageFileSummary) interface{} { | ||
// TODO Figure out | ||
parser.Read(25) | ||
return parser.Read(1)[0] != 0 | ||
}, | ||
"StructProperty": func(parser *PakParser, export *FObjectExport, size int32, uAsset *FPackageFileSummary) interface{} { | ||
// TODO Figure out | ||
parser.Read(24) | ||
return parser.ReadFPackageIndex(uAsset.Imports, uAsset.Exports) | ||
}, | ||
"DelegateProperty": func(parser *PakParser, export *FObjectExport, size int32, uAsset *FPackageFileSummary) interface{} { | ||
// TODO Figure out | ||
parser.Read(24) | ||
return parser.ReadFPackageIndex(uAsset.Imports, uAsset.Exports) | ||
}, | ||
} | ||
|
||
type ClassType struct { | ||
Type string `json:"type"` | ||
Value interface{} `json:"value"` | ||
} | ||
|
||
func (parser *PakParser) ReadClass(export *FObjectExport, size int32, uAsset *FPackageFileSummary) (interface{}, bool) { | ||
var className string | ||
|
||
if classNameTemp := export.TemplateIndex.ClassName(); classNameTemp != nil { | ||
className = *classNameTemp | ||
} else { | ||
return nil, false | ||
} | ||
|
||
trimmedType := strings.Trim(className, "\x00") | ||
|
||
resolver, ok := classResolvers[trimmedType] | ||
|
||
if !ok { | ||
return nil, false | ||
} | ||
|
||
if resolver != nil { | ||
value := resolver(parser, export, size, uAsset) | ||
|
||
if value != nil { | ||
return value, true | ||
} | ||
} | ||
|
||
// TODO Read types correctly | ||
log.Warningf("Unread Class Type [%d]: %s", size, trimmedType) | ||
// fmt.Println(utils.HexDump(data[offset:])) | ||
if size > 0 { | ||
parser.Read(size) | ||
} | ||
|
||
return nil, true | ||
} | ||
|
||
func RegisterClassResolver(classType string, resolver ClassResolver) { | ||
classResolvers[classType] = resolver | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
package parser | ||
|
||
// https://github.com/SatisfactoryModdingUE/UnrealEngine/blob/4.22-CSS/Engine/Source/Runtime/Engine/Classes/Engine/DataTable.h#L56 | ||
type UDataTable struct { | ||
Values map[string][]*FPropertyTag `json:"values"` | ||
} | ||
|
||
func (parser *PakParser) ReadUDataTable(uAsset *FPackageFileSummary) *UDataTable { | ||
// Unknown | ||
parser.Read(4) | ||
|
||
count := parser.ReadUint32() | ||
|
||
values := make(map[string][]*FPropertyTag) | ||
|
||
for i := uint32(0); i < count; i++ { | ||
name := parser.ReadFName(uAsset.Names) | ||
values[name] = parser.ReadFPropertyTagLoop(uAsset) | ||
} | ||
|
||
return &UDataTable{ | ||
Values: values, | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,102 @@ | ||
package parser | ||
|
||
import ( | ||
"fmt" | ||
"github.com/spf13/viper" | ||
) | ||
|
||
type PakParser struct { | ||
reader PakReader | ||
tracker *readTracker | ||
preload []byte | ||
} | ||
|
||
type readTracker struct { | ||
child *readTracker | ||
bytesRead int32 | ||
} | ||
|
||
func (tracker *readTracker) Increment(n int32) { | ||
tracker.bytesRead += n | ||
|
||
if tracker.child != nil { | ||
tracker.child.Increment(n) | ||
} | ||
} | ||
|
||
func NewParser(reader PakReader) *PakParser { | ||
return &PakParser{ | ||
reader: reader, | ||
} | ||
} | ||
|
||
func (parser *PakParser) TrackRead() *readTracker { | ||
parser.tracker = &readTracker{ | ||
child: parser.tracker, | ||
} | ||
|
||
return parser.tracker | ||
} | ||
|
||
func (parser *PakParser) UnTrackRead() { | ||
if parser.tracker != nil { | ||
parser.tracker = parser.tracker.child | ||
} | ||
} | ||
|
||
func (parser *PakParser) Seek(offset int64, whence int) (ret int64, err error) { | ||
parser.preload = nil | ||
return parser.reader.Seek(offset, whence) | ||
} | ||
|
||
func (parser *PakParser) Preload(n int32) { | ||
if viper.GetBool("NoPreload") { | ||
return | ||
} | ||
|
||
buffer := make([]byte, n) | ||
read, err := parser.reader.Read(buffer) | ||
|
||
if err != nil { | ||
panic(err) | ||
} | ||
|
||
if int32(read) < n { | ||
panic(fmt.Sprintf("End of stream: %d < %d", read, n)) | ||
} | ||
|
||
if parser.preload != nil && len(parser.preload) > 0 { | ||
parser.preload = append(parser.preload, buffer...) | ||
} else { | ||
parser.preload = buffer | ||
} | ||
} | ||
|
||
func (parser *PakParser) Read(n int32) []byte { | ||
toRead := n | ||
buffer := make([]byte, toRead) | ||
|
||
if parser.preload != nil && len(parser.preload) > 0 { | ||
copied := copy(buffer, parser.preload) | ||
parser.preload = parser.preload[copied:] | ||
toRead = toRead - int32(copied) | ||
} | ||
|
||
if toRead > 0 { | ||
read, err := parser.reader.Read(buffer[n-toRead:]) | ||
|
||
if err != nil { | ||
panic(err) | ||
} | ||
|
||
if int32(read) < toRead { | ||
panic(fmt.Sprintf("End of stream: %d < %d", read, toRead)) | ||
} | ||
} | ||
|
||
if parser.tracker != nil { | ||
parser.tracker.Increment(n) | ||
} | ||
|
||
return buffer | ||
} |
Oops, something went wrong.