Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 19 additions & 5 deletions bundler/bundler.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"ModCreator/file"
"fmt"
"regexp"
"sort"
"strings"
)

Expand Down Expand Up @@ -59,10 +60,18 @@ end)(nil)`
rootfuncname string = `__root`
)

// IsBundled keeps regex bundling logic to this file
func IsBundled(rawlua string) bool {
anyBundle := regexp.MustCompile(`__bundle_register`)
if len(anyBundle.FindStringSubmatch(rawlua)) > 0 {
return true
}
return false
}

// Unbundle takes luacode and strips it down to the root sub function
func Unbundle(rawlua string) (string, error) {
anyBundle := regexp.MustCompile(`__bundle_register`)
if len(anyBundle.FindStringSubmatch(rawlua)) <= 0 {
if !IsBundled(rawlua) {
return rawlua, nil
}

Expand All @@ -73,11 +82,13 @@ func Unbundle(rawlua string) (string, error) {
return "", fmt.Errorf("could not find root bundle")
}
return matches[1], nil

}

// Bundle grabs all dependencies and creates a single luascript
func Bundle(rawlua string, l file.LuaReader) (string, error) {
if IsBundled(rawlua) {
return rawlua, nil
}
reqs := map[string]string{
rootfuncname: rawlua,
}
Expand All @@ -91,6 +102,9 @@ func Bundle(rawlua string, l file.LuaReader) (string, error) {
if err != nil {
return "", fmt.Errorf("for %s getAllReqValues(%s): %v", fname, scriptToInvestigate, err)
}
sort.Slice(reqsToLoad, func(i int, j int) bool {
return reqsToLoad[i] < reqsToLoad[j]
})
for _, r := range reqsToLoad {
val, err := l.EncodeFromFile(r + ".ttslua")
if err != nil {
Expand All @@ -101,15 +115,15 @@ func Bundle(rawlua string, l file.LuaReader) (string, error) {
todo = append(todo, reqsToLoad...)
}

bundlestr := "\n" + metaprefix + "\n"
bundlestr := metaprefix + "\n"

for k, v := range reqs {
bundlestr += strings.Replace(funcprefix, funcprefixReplace, k, 1) + "\n"
bundlestr += v + "\n"
bundlestr += funcsuffix + "\n"
}

bundlestr += metasuffix + "\n"
bundlestr += metasuffix

return bundlestr, nil
}
Expand Down
33 changes: 26 additions & 7 deletions bundler/bundler_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,14 @@ package bundler

import (
"fmt"
"strings"
"testing"

"github.com/google/go-cmp/cmp"
)

const (
fullrawlua string = `
-- Bundled by luabundle {"version":"1.6.0"}
fullrawlua string = `-- Bundled by luabundle {"version":"1.6.0"}
local __bundle_require, __bundle_loaded, __bundle_register, __bundle_modules = (function(superRequire)
local loadingPlaceholder = {[{}] = true}

Expand Down Expand Up @@ -190,8 +190,7 @@ function keepSample(_obj, _string, value)
end

end)
return __bundle_require("__root")
`
return __bundle_require("__root")`
fullrawlua2 string = "-- Bundled by luabundle {\"version\":\"1.6.0\"}\r\nlocal __bundle_require, __bundle_loaded, __bundle_register, __bundle_modules = (function(superRequire)\r\n\tlocal loadingPlaceholder = {[{}] = true}\r\n\r\n\tlocal register\r\n\tlocal modules = {}\r\n\r\n\tlocal require\r\n\tlocal loaded = {}\r\n\r\n\tregister = function(name, body)\r\n\t\tif not modules[name] then\r\n\t\t\tmodules[name] = body\r\n\t\tend\r\n\tend\r\n\r\n\trequire = function(name)\r\n\t\tlocal loadedModule = loaded[name]\r\n\r\n\t\tif loadedModule then\r\n\t\t\tif loadedModule == loadingPlaceholder then\r\n\t\t\t\treturn nil\r\n\t\t\tend\r\n\t\telse\r\n\t\t\tif not modules[name] then\r\n\t\t\t\tif not superRequire then\r\n\t\t\t\t\tlocal identifier = type(name) == 'string' and '\\\"' .. name .. '\\\"' or tostring(name)\r\n\t\t\t\t\terror('Tried to require ' .. identifier .. ', but no such module has been registered')\r\n\t\t\t\telse\r\n\t\t\t\t\treturn superRequire(name)\r\n\t\t\t\tend\r\n\t\t\tend\r\n\r\n\t\t\tloaded[name] = loadingPlaceholder\r\n\t\t\tloadedModule = modules[name](require, loaded, register, modules)\r\n\t\t\tloaded[name] = loadedModule\r\n\t\tend\r\n\r\n\t\treturn loadedModule\r\n\tend\r\n\r\n\treturn require, loaded, register, modules\r\nend)(nil)\r\n__bundle_register(\"__root\", function(require, _LOADED, __bundle_register, __bundle_modules)\r\nrequire(\"core/DataHelper\")\r\nend)\r\n__bundle_register(\"core/DataHelper\", function(require, _LOADED, __bundle_register, __bundle_modules)\r\n-- set true to enable debug logging\r\nDEBUG = false\r\n\r\nfunction log(message)\r\n if DEBUG then\r\n print(message)\r\n end\r\nend\r\n\r\n--[[\r\nKnown locations and clues. We check this to determine if we should\r\natttempt to spawn clues, first we look for <LOCATION_NAME>_<GUID> and if\r\nwe find nothing we look for <LOCATION_NAME>\r\nformat is [location_guid -> clueCount]\r\n]]\r\nLOCATIONS_DATA_JSON = [[\r\n{\r\n \"Study\": {\"type\": \"perPlayer\", \"value\": 2, \"clueSide\": \"back\"},\r\n \"Study_670914\": {\"type\": \"perPlayer\", \"value\": 1, \"clueSide\": \"back\"},\r\n \"Attic_377b20\": {\"type\": \"perPlayer\", \"value\": 1, \"clueSide\": \"back\"},\r\n \"Attic\": {\"type\": \"perPlayer\", \"value\": 2, \"clueSide\": \"back\"},\r\n \"Cellar_5d3bcc\": {\"type\": \"perPlayer\", \"value\": 1, \"clueSide\": \"back\"},\r\n \"Cellar\": {\"type\": \"perPlayer\", \"value\": 2, \"clueSide\": \"back\"},\r\n \"Bathroom\": {\"type\": \"perPlayer\", \"value\": 1, \"clueSide\": \"back\"},\r\n \"Bedroom\": {\"type\": \"perPlayer\", \"value\": 1, \"clueSide\": \"back\"},\r\n \"Far Above Your House\": {\"type\": \"perPlayer\", \"value\": 1, \"clueSide\": \"back\"},\r\n \"Deep Below Your House\": {\"type\": \"perPlayer\", \"value\": 1, \"clueSide\": \"back\"},\r\n\r\n \"Northside_86faac\": {\"type\": \"perPlayer\", \"value\": 1, \"clueSide\": \"back\"},\r\n \"Northside\": {\"type\" : \"perPlayer\", \"value\": 2, \"clueSide\": \"back\"},\r\n \"Graveyard\": {\"type\": \"perPlayer\", \"value\": 2, \"clueSide\": \"back\"},\r\n \"Miskatonic University_cedb0a\": {\"type\": \"perPlayer\", \"value\": 1, \"clueSide\": \"back\"},\r\n \"Miskatonic University\": {\"type\": \"perPlayer\", \"value\": 2, \"clueSide\": \"back\"},\r\n \"Downtown_1aa7cb\": {\"type\": \"perPlayer\", \"value\": 2, \"clueSide\": \"back\"},\r\n \"Downtown\": {\"type\": \"perPlayer\", \"value\": 1, \"clueSide\": \"back\"},\r\n \"St. Mary's Hospital\": {\"type\": \"perPlayer\", \"value\": 1, \"clueSide\": \"back\"},\r\n \"Easttown_88245c\": {\"type\": \"perPlayer\", \"value\": 2, \"clueSide\": \"back\"},\r\n \"Easttown\": {\"type\": \"perPlayer\", \"value\": 1, \"clueSide\": \"back\"},\r\n \"Southside\": {\"type\": \"perPlayer\", \"value\": 1, \"clueSide\": \"back\"},\r\n \"Rivertown\": {\"type\": \"perPlayer\", \"value\": 1, \"clueSide\": \"back\"},\r\n \"Your House_377b20\": {\"type\": \"perPlayer\", \"value\": 1, \"clueSide\": \"back\"},\r\n \"Your House_b28633\": {\"type\": \"perPlayer\", \"value\": 1, \"clueSide\": \"back\"},\r\n\r\n \"Ritual Site\": {\"type\": \"perPlayer\", \"value\": 2, \"clueSide\": \"back\"},\r\n \"Arkham Woods_e8e04b\": {\"type\": \"perPlayer\", \"value\": 0, \"clueSide\": \"back\"},\r\n \"Arkham Woods\": {\"type\": \"perPlayer\", \"value\": 1, \"clueSide\": \"back\"},\r\n\r\n \"New Orleans_5ab18a\": {\"type\": \"perPlayer\", \"value\": 0, \"clueSide\": \"back\"},\r\n \"New Orleans\": {\"type\": \"perPlayer\", \"value\": 1, \"clueSide\": \"back\"},\r\n \"Riverside_ab9d69\": {\"type\": \"perPlayer\", \"value\": 0, \"clueSide\": \"back\"},\r\n \"Riverside\": {\"type\": \"perPlayer\", \"value\": 1, \"clueSide\": \"back\"},\r\n \"Wilderness_3c5ea8\": {\"type\": \"perPlayer\", \"value\": 0, \"clueSide\": \"back\"},\r\n \"Wilderness\": {\"type\": \"perPlayer\", \"value\": 1, \"clueSide\": \"back\"},\r\n \"Unhallowed Land_552a1d\": {\"type\":', 'p1', '0', '0', '0', 'm1', 'm1', 'm1', 'm2', 'm2', 'skull', 'skull', 'elder', 'red', 'blue' } },\r\n normal = { token = { 'p1', '0', '0', 'm1', 'm1', 'm1', 'm2', 'm2', 'm3', 'm4', 'skull', 'skull', 'elder', 'red', 'blue' } },\r\n hard = { token = { 'p1', '0', 'm1', 'm1', 'm2', 'm2', 'm3', 'm4', 'm5', 'm6', 'skull', 'skull', 'elder', 'red', 'blue' } },\r\n expert = { token = { '0', 'm1', 'm1', 'm2', 'm3', 'm4', 'm5', 'm6', 'm7', 'm8', 'skull', 'skull', 'elder', 'red', 'blue' } }\r\n },\r\n ['Pokemon'] = {\r\n easy = { token = { 'p1', 'p1', '0', '0', '0', 'm1', 'm1', 'm2', 'm3', 'skull', 'skull', 'tablet', 'elder', 'red', 'blue' } },\r\n normal = { token = { 'p1', '0', '0', '0', 'm1', 'm2', 'm2', 'm3', 'm5', 'skull', 'skull', 'tablet', 'elder', 'red', 'blue' } },\r\n hard = { token = { 'p1', '0', '0', 'm1', 'm2', 'm3', 'm3', 'm4', 'm6', 'skull', 'skull', 'tablet', 'elder', 'red', 'blue' } },\r\n expert = { token = { '0', 'm1', 'm2', 'm2', 'm3', 'm3', 'm4', 'm4', 'm6', 'm8', 'skull', 'skull', 'tablet', 'elder', 'red', 'blue' } }\r\n },\r\n ['Safari'] = {\r\n normal = { token = { 'p1', '0', '0', '0', 'm1', 'm2', 'm2', 'm3', 'm5', 'skull', 'skull', 'cultist', 'tablet', 'elder', 'red', 'blue' } },\r\n hard = { token = { 'p1', '0', '0', 'm1', 'm2', 'm3', 'm3', 'm4', 'm6', 'skull', 'skull', 'cultist', 'tablet', 'elder', 'red', 'blue' } },\r\n },\r\n ['Cerulean'] = {\r\n normal = { token = { 'p1', '0', '0', '0', 'm1', 'm2', 'm2', 'm3', 'm5', 'skull', 'skull', 'cultist', 'cultist', 'tablet', 'elder', 'red', 'blue' } },\r\n hard = { token = { 'p1', '0', '0', 'm1', 'm2', 'm3', 'm3', 'm4', 'm6', 'skull', 'skull', 'cultist', 'cultist', 'tablet', 'elder', 'red', 'blue' } },\r\n },\r\n ['Erich Zann'] = {\r\n easy = { token = { 'p1', '0', '0', 'm1', 'm1', 'm2', 'm2', 'm3', 'skull', 'skull', 'cultist', 'tablet', 'elder', 'red', 'blue' } },\r\n normal = { token = { 'p1', '0', 'm1', 'm1', 'm2', 'm3', 'm3', 'm4', 'skull', 'skull', 'cultist', 'tablet', 'elder', 'red', 'blue' } },\r\n hard = { token = { '0', 'm1', 'm2', 'm3', 'm4', 'm4', 'm5', 'm6', 'skull', 'skull', 'cultist', 'tablet', 'elder', 'red', 'blue' } },\r\n expert = { token = { '0', 'm1', 'm2', 'm3', 'm4', 'm5', 'm6', 'm8', 'skull', 'skull', 'cultist', 'tablet', 'elder', 'red', 'blue' } }\r\n },\r\n ['Kaimonogatari'] = {\r\n easy = { token = { 'p1', 'p1', '0', '0', '0', 'm1', 'm1', 'm2', 'm2', 'skull', 'skull', 'cultist', 'red', 'blue' } },\r\n normal = { token = { 'p1', '0', '0', 'm1', 'm2', 'm2', 'm3', 'm3', 'm4', 'skull', 'skull', 'cultist', 'red', 'blue' } },\r\n hard = { token = { '0', '0', '0', 'm1', 'm2', 'm2', 'm3', 'm4', 'm4', 'm5', 'skull', 'skull', 'cultist', 'red', 'blue' } },\r\n expert = { token = { '0', '0', 'm1', 'm1', 'm2', 'm3', 'm4', 'm5', 'm6', 'm6', 'm8', 'skull', 'skull', 'cultist', 'red', 'blue' } }\r\n },\r\n ['Sleepy Hollow'] = {\r\n normal = { token = { 'p1', 'p1', '0', '0', '0', 'm1', 'm1', 'm1', 'm2', 'm2', 'm3', 'm3', 'm4', 'm4', 'm5', 'm6', 'skull', 'skull', 'skull', 'cultist', 'tablet', 'elder', 'red', 'blue' } },\r\n hard = { token = { 'p1', '0', '0', '0', 'm1', 'm1', 'm1', 'm2', 'm2', 'm3', 'm3', 'm4', 'm4', 'm5', 'm6', 'm8', 'skull', 'skull', 'skull', 'cultist', 'tablet', 'elder', 'red', 'blue' } },\r\n },\r\n ['Flesh'] = {\r\n easy = { token = { 'p1', 'p1', '0', '0', '0', 'm1', 'm1', 'm1', 'm2', 'm3', 'skull', 'skull', 'cultist', 'tablet', 'tablet', 'red', 'blue' } },\r\n normal = { token = { 'p1', '0', '0', 'm1', 'm1', 'm1', 'm2', 'm2', 'm3', 'm4', 'skull', 'skull', 'cultist', 'tablet', 'tablet', 'red', 'blue' } },\r\n hard = { token = { '0', '0', 'm1', 'm1', 'm2', 'm3', 'm3', 'm4', 'm4', 'm6', 'skull', 'skull', 'cultist', 'tablet', 'tablet', 'red', 'blue' } },\r\n },\r\n ['Dark Matter'] = {\r\n easy = { token = { 'p1', 'p1', '0', '0', '0', 'm1', 'm1', 'm2', 'm2', 'skull', 'skull', 'cultist', 'cultist', 'red', 'blue' } },\r\n normal = { token = { 'p1', '0', '0', 'm1', 'm1', 'm1', 'm2', 'm2', 'm3', 'm4', 'skull', 'skull', 'cultist', 'cultist', 'red', 'blue' } },\r\n hard = { token = { '0', '0', '0', 'm1', 'm1', 'm2', 'm2', 'm3', 'm3', 'm4', 'm5', 'skull', 'skull', 'cultist', 'cultist', 'red', 'blue' } },\r\n expert = { token = { '0', 'm1', 'm2', 'm2', 'm3', 'm3', 'm4', 'm4', 'm5', 'm6', 'm8', 'skull', 'skull', 'cultist', 'cultist', 'red', 'blue' } }\r\n },\r\n ['Dont Starve'] = {\r\n normal = { token = { 'p1', '0', 'm1', 'm1', 'm2', 'm2', 'm3', 'm3', 'm5', 'skull', 'skull', 'cultist', 'tablet', 'elder', 'red', 'blue' } },\r\n hard = { token = { '0', 'm1', 'm1', 'm2', 'm2', 'm3', 'm3', 'm5', 'm7', 'skull', 'skull', 'cultist', 'tablet', 'elder', 'red', 'blue' } },\r\n },\r\n ['XXXX'] = {\r\n easy = { token = { 'p1', 'p1', '0', '0', '0', 'm1', 'm1', 'm1', 'm2', 'm2', 'skull', 'skull', 'cultist', 'tablet', 'red', 'blue' } },\r\n normal = { token = { 'p1', '0', '0', 'm1', 'm1', 'm1', 'm2', 'm2', 'm3', 'm4', 'skull', 'skull', 'cultist', 'tablet', 'red', 'blue' } },\r\n hard = { token = { '0', '0', '0', 'm1', 'm1', 'm2', 'm2', 'm3', 'm3', 'm4', 'm5', 'skull', 'skull', 'cultist', 'tablet', 'red', 'blue' } },\r\n expert = { token = { '0', 'm1', 'm1', 'm2', 'm2', 'm3', 'm3', 'm4', 'm4', 'm5', 'm6', 'm8', 'skull', 'skull', 'cultist', 'tablet', 'red', 'blue' } }\r\n },\r\n\r\n}\r\n\r\nfunction onSave()\r\n local globalState = JSON.encode(SPAWNED_PLAYER_CARD_GUIDS)\r\n log('saving global state: ' .. globalState)\r\n self.script_state = globalState\r\nend\r\n\r\nfunction onload(save_state)\r\n if save_state ~= '' then\r\n log('loading global state: ' .. save_state)\r\n SPAWNED_PLAYER_CARD_GUIDS = JSON.decode(save_state)\r\n else\r\n SPAWNED_PLAYER_CARD_GUIDS = {}\r\n end\r\nend\r\n\r\nfunction getSpawnedPlayerCardGuid(params)\r\n local guid = params[1]\r\n if SPAWNED_PLAYER_CARD_GUIDS == nil then\r\n return nil\r\n end\r\n return SPAWNED_PLAYER_CARD_GUIDS[guid]\r\nend\r\n\r\nfunction setSpawnedPlayerCardGuid(params)\r\n local guid = params[1]\r\n local value = params[2]\r\n if SPAWNED_PLAYER_CARD_GUIDS ~= nil then\r\n SPAWNED_PLAYER_CARD_GUIDS[guid] = value\r\n return true\r\n end\r\n return false\r\nend\r\n\r\nfunction checkHiddenCard(name)\r\n for _, n in ipairs(HIDDEN_CARD_DATA) do\r\n if name == n then\r\n return true\r\n end\r\n end\r\n return false\r\nend\r\n\r\nfunction updateHiddenCards(args)\r\n local custom_data_helper = getObjectFromGUID(args[1])\r\n local data_hiddenCards = custom_data_helper.getTable(\"HIDDEN_CARD_DATA\")\r\n for k, v in ipairs(data_hiddenCards) do\r\n table.insert(HIDDEN_CARD_DATA, v)\r\n end\r\nend\r\n\r\nend)\r\nreturn __bundle_require(\"__root\")"
)

Expand Down Expand Up @@ -248,9 +247,7 @@ require("core/AgendaDeck")`
}
}

// Disabled because bundler puts together bundles non-deterministically, need
// to sort out either deterministic bundling or a more mature comparator
func DisabledTestSmartBundle(t *testing.T) {
func TestSmartBundle(t *testing.T) {
fr := &fakeLuaReader{
fs: map[string]string{
"core/AgendaDeck.ttslua": `MIN_VALUE = -99
Expand Down Expand Up @@ -401,6 +398,28 @@ end
}
}

func TestBundleNoRequires(t *testing.T) {
fr := &fakeLuaReader{
fs: map[string]string{},
}
input := `var foo = 42`

got, err := Bundle(input, fr)
if err != nil {
t.Errorf("Expected no error, got %v", err)
}
want := strings.Trim(strings.Join(
[]string{metaprefix,
strings.Replace(funcprefix, funcprefixReplace, rootfuncname, 1),
"var foo = 42",
funcsuffix,
metasuffix}, "\n"), "\n\n")

if diff := cmp.Diff(want, got); diff != "" {
t.Errorf("want != got:\n%v\n", diff)
}
}

func TestFailedUnbundle(t *testing.T) {
rawlua := ` __bundle_register("core/AgendaDeck", function(require, _LOADED, __bundle_register, __bundle_modules)
MIN_VALUE = -99
Expand Down
3 changes: 3 additions & 0 deletions mod/generate.go
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,9 @@ func (m *Mod) generate(raw types.J) error {
if err != nil {
return fmt.Errorf("objects.ParseAllObjectStates(%s) : %v", "", err)
}
if allObjs == nil {
allObjs = []map[string]interface{}{}
}
m.Data[ExpectedObjStates] = allObjs
return nil
}
Expand Down
2 changes: 0 additions & 2 deletions mod/reverse.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import (
"encoding/json"
"fmt"
"io/ioutil"
"log"
)

// Reverser holds interfaces and configs for the reversing process
Expand All @@ -27,7 +26,6 @@ func (r *Reverser) Write(raw map[string]interface{}) error {
for _, strKey := range ExpectedStr {
rawVal, ok := raw[strKey]
if !ok {
log.Printf("expected string value in key %s, key not found\n", strKey)
continue
}
strVal, ok := rawVal.(string)
Expand Down
Loading