Skip to content

Instantly share code, notes, and snippets.

@t1nky

t1nky/main.go Secret

Last active July 31, 2023 15:33
Show Gist options
  • Save t1nky/19790793842c3c00304626c3106076c2 to your computer and use it in GitHub Desktop.
Save t1nky/19790793842c3c00304626c3106076c2 to your computer and use it in GitHub Desktop.
Extract real and internal/raw names
package main
import (
"bytes"
"encoding/binary"
"encoding/json"
"fmt"
"io"
"log"
"os"
)
const (
sequenceLength = 32
copyLength = 512
searchStringPrefix = "/Game/World_"
)
func isValidCharacter(c byte) bool {
return (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9')
}
func findSequences(input []byte) [][]byte {
var sequences [][]byte
for i := 0; i <= len(input)-sequenceLength; i++ {
isValidSequence := true
for j := i; j < i+sequenceLength; j++ {
if !isValidCharacter(input[j]) {
isValidSequence = false
break
}
}
if isValidSequence {
end := i + sequenceLength + copyLength
if end > len(input) {
end = len(input)
}
sequences = append(sequences, input[i:end])
}
}
return sequences
}
func reverseBytes(input []byte) []byte {
if len(input) == 0 {
return input
}
return append(reverseBytes(input[1:]), input[0])
}
func extractNameAndPath(sequence []byte) (name, path string) {
sizeBytes := make([]byte, 4)
copy(sizeBytes, sequence[33:37])
reversedBytes := reverseBytes(sizeBytes)
size := binary.BigEndian.Uint32(reversedBytes)
strEnd := int(37 + size)
nameStr := sequence[37 : strEnd-1]
strStart := bytes.Index(sequence[strEnd:], []byte(searchStringPrefix))
strSize := bytes.IndexByte(sequence[strEnd+strStart:], byte(0))
if strStart == -1 || strSize == -1 {
return "", ""
}
pathStr := sequence[strEnd+strStart : strEnd+strStart+strSize]
if pathStr[0] != '/' {
return "", ""
}
return string(nameStr), string(pathStr)
}
func main() {
inputFilename := "save_0.txt"
inputFile, err := os.Open(inputFilename)
if err != nil {
fmt.Println("Error opening input file:", err)
return
}
defer inputFile.Close()
inputData, err := io.ReadAll(inputFile)
if err != nil {
log.Println("Error reading input file:", err)
return
}
sequences := findSequences(inputData)
result := make(map[string]string)
for _, seq := range sequences {
if !bytes.Contains(seq, []byte(searchStringPrefix)) {
continue
}
if bytes.Contains(seq, []byte("/SpawnTables/")) || bytes.Contains(seq, []byte("/TileSet/")) {
continue
}
name, path := extractNameAndPath(seq)
if name == "" || path == "" {
continue
}
if _, ok := result[name]; !ok {
result[name] = path
}
}
jsonData, err := json.MarshalIndent(result, "", " ")
if err != nil {
log.Println("Error converting result to json:", err)
return
}
log.Println(string(jsonData))
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment