Skip to content

Commit

Permalink
initial unpacker
Browse files Browse the repository at this point in the history
  • Loading branch information
Ryex committed Jun 20, 2020
1 parent b36d633 commit dcb53b4
Show file tree
Hide file tree
Showing 6 changed files with 475 additions and 0 deletions.
76 changes: 76 additions & 0 deletions cmd/dungeondraft-unpack/dungeondraft-unpack.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
package main

import (
"flag"
"fmt"
"os"
"path/filepath"
"strings"

log "github.com/sirupsen/logrus"
"gitlab.com/ryexandrite/dungeondraft-gopackager/pkg/unpack"
)

const usageText = `Extracts the contesnts of a .dungeondraft_pack file
Usage:
dungeondraft-unpack [args] <.dungeondraft_pack file> <output folder>
Arguments:
-debug
`

func main() {
flag.Usage = usage
// args go here

debugPtr := flag.Bool("debug", false, "output debug info level log messages?")
flag.BoolVar(debugPtr, "v", false, "output debug info level log messages?")

flag.Parse()

debug := *debugPtr

if flag.NArg() < 1 {
fmt.Println("Error: Must provide a pack file")
usage()
} else if flag.NArg() < 2 {
fmt.Println("Error: Must provide a output folder")
usage()
}

packFilePath, pathErr := filepath.Abs(flag.Arg(0))
if pathErr != nil {
fmt.Println("could not get absolute path for packfile", pathErr)
}

packFileName := filepath.Base(packFilePath)
packName := strings.TrimSuffix(packFileName, filepath.Ext(packFileName))

log.SetOutput(os.Stdout)

// Only log the warning severity or above.
log.SetLevel(log.WarnLevel)
if debug {
log.SetLevel(log.InfoLevel)
}

logger := log.WithFields(log.Fields{
"filename": packFileName,
})

unpacker := unpack.NewUnpacker(logger, packName)

file, fileErr := os.Open(packFilePath)
if fileErr != nil {
log.WithField("path", packFilePath).WithError(fileErr).Fatal("Could not open file for reading.")
}

defer file.Close()

unpacker.ExtractPackage(file, flag.Arg(1))
}

func usage() {
fmt.Print(usageText)
flag.PrintDefaults()
os.Exit(2)
}
5 changes: 5 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
module gitlab.com/ryexandrite/dungeondraft-gopackager

go 1.14

require github.com/sirupsen/logrus v1.6.0
8 changes: 8 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/konsorten/go-windows-terminal-sequences v1.0.3 h1:CE8S1cTafDpPvMhIxNJKvHsGVBgn1xWYf1NbHQhywc8=
github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/sirupsen/logrus v1.6.0 h1:UBcNElsrwanuuMsnGSlYmtmgbb23qDR5dG+6X6Oo89I=
github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
24 changes: 24 additions & 0 deletions internal/structures/structures.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package structures

type PackageHeadersBytes struct {
H1 uint32
H2 uint32
H3 uint32
H4 uint32
H5 uint32
H7 [16]uint32
FileCount uint32
}

type FileInfoBytes struct {
Offset uint64
Size uint64
Md5 [16]byte
}

type FileInfo struct {
Path string
Offset int64
Size int64
Md5 string
}
66 changes: 66 additions & 0 deletions internal/utils/utils.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
package utils

import (
"bytes"
"encoding/binary"
"errors"
"os"
)

// DirExists tests if a Directyory exists
func DirExists(path string) (bool, error) {
_, err := os.Stat(path)
if err == nil {
return true, nil
}
if os.IsNotExist(err) {
return false, nil
}
return false, err
}

// RipTexture detects and pulls image data from texture bytes
func RipTexture(data []byte) (fileExt string, fileData []byte, err error) {

// webp
start := bytes.Index(data, []byte{0x52, 0x49, 0x46, 0x46})
if start >= 0 {
var size int32
err = binary.Read(bytes.NewBuffer(data[start+4:start+8]), binary.LittleEndian, size)
if err != nil {
return
}
fileExt = ".webp"
fileData = data[start : start+8+int(size)]
return
}

// png
start = bytes.Index(data, []byte{0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A})
if start >= 0 {
end := bytes.Index(data, []byte{0x49, 0x45, 0x4E, 0x44, 0xAE, 0x42, 0x60, 0x82})
if end < 0 {
err = errors.New("found PNG start but could not find PNG end tag")
return
}
fileExt = ".png"
fileData = data[start : end+8]
return
}

// jpg
start = bytes.Index(data, []byte{0xFF, 0xD8, 0xFF})
if start >= 0 {
end := bytes.Index(data, []byte{0xFF, 0xD9})
if end < 0 {
err = errors.New("found JPG start but could not find JPG end tag")
return
}
fileExt = ".jpg"
fileData = data[start:end]
return
}

err = errors.New("no valid image data found")
return
}
Loading

0 comments on commit dcb53b4

Please sign in to comment.