160 lines
3.2 KiB
Go
160 lines
3.2 KiB
Go
|
package rbxbuilder
|
||
|
|
||
|
import (
|
||
|
"bytes"
|
||
|
"ci.itzana.me/itzaname/rbxfile"
|
||
|
"ci.itzana.me/itzaname/rbxfile/xml"
|
||
|
"encoding/json"
|
||
|
"io/ioutil"
|
||
|
"os"
|
||
|
"path/filepath"
|
||
|
)
|
||
|
|
||
|
type PlaceDumper struct {
|
||
|
Options *DumpSettings
|
||
|
source *rbxfile.Root
|
||
|
template *rbxfile.Root
|
||
|
scripts map[string]string
|
||
|
}
|
||
|
|
||
|
func (d *PlaceDumper) dumpScriptsFromInstance(instance *rbxfile.Instance) error {
|
||
|
for _, child := range instance.Children {
|
||
|
if isScript(child) {
|
||
|
path := getScriptFilePathString(child)
|
||
|
if child.ClassName != "ModuleScript" {
|
||
|
d.scripts[path] = child.ClassName
|
||
|
}
|
||
|
if err := os.MkdirAll(filepath.Dir(d.Options.Output+path), 0755); err != nil {
|
||
|
return err
|
||
|
}
|
||
|
if err := ioutil.WriteFile(d.Options.Output+path, []byte(getSource(child)), 0644); err != nil {
|
||
|
return err
|
||
|
}
|
||
|
}
|
||
|
if err := d.dumpScriptsFromInstance(child); err != nil {
|
||
|
return err
|
||
|
}
|
||
|
}
|
||
|
return nil
|
||
|
}
|
||
|
|
||
|
func (d *PlaceDumper) findInstance(name string) *rbxfile.Instance {
|
||
|
for _, child := range d.template.Instances {
|
||
|
if child.Name() == name {
|
||
|
return child
|
||
|
}
|
||
|
}
|
||
|
return nil
|
||
|
}
|
||
|
|
||
|
func (d *PlaceDumper) removeScripts(instance *rbxfile.Instance) {
|
||
|
var queue []*rbxfile.Instance
|
||
|
for _, child := range instance.Children {
|
||
|
if isScript(child) {
|
||
|
queue = append(queue, child)
|
||
|
continue
|
||
|
}
|
||
|
d.removeScripts(child)
|
||
|
}
|
||
|
|
||
|
for i := 0; i < len(queue); i++ {
|
||
|
instance.RemoveChild(queue[i])
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func (d *PlaceDumper) addAssets() {
|
||
|
for _, parent := range d.source.Instances {
|
||
|
for _, child := range parent.Children {
|
||
|
if !isScript(child) {
|
||
|
if destInst := d.findInstance(parent.Name()); destInst != nil {
|
||
|
newChild := child.Clone()
|
||
|
d.removeScripts(newChild)
|
||
|
destInst.AddChild(newChild)
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func (d *PlaceDumper) createTemplate() {
|
||
|
d.template = rbxfile.NewRoot()
|
||
|
|
||
|
for _, child := range d.source.Instances {
|
||
|
newInst := child.Clone()
|
||
|
newInst.RemoveAll()
|
||
|
d.template.Instances = append(d.template.Instances, newInst)
|
||
|
}
|
||
|
|
||
|
d.addAssets()
|
||
|
}
|
||
|
|
||
|
func (d *PlaceDumper) loadRootFromFile() error {
|
||
|
file, err := os.Open(d.Options.Source)
|
||
|
if err != nil {
|
||
|
return err
|
||
|
}
|
||
|
|
||
|
root, err := xml.Deserialize(file, nil)
|
||
|
if err != nil {
|
||
|
return err
|
||
|
}
|
||
|
d.source = root
|
||
|
|
||
|
return nil
|
||
|
}
|
||
|
|
||
|
func (d *PlaceDumper) dumpScripts() error {
|
||
|
for i := 0; i < len(d.source.Instances); i++ {
|
||
|
if err := d.dumpScriptsFromInstance(d.source.Instances[i]); err != nil {
|
||
|
return err
|
||
|
}
|
||
|
}
|
||
|
return nil
|
||
|
}
|
||
|
|
||
|
func (d PlaceDumper) writeManifest() error {
|
||
|
buffer := &bytes.Buffer{}
|
||
|
if err := xml.Serialize(buffer, nil, d.template); err != nil {
|
||
|
return err
|
||
|
}
|
||
|
|
||
|
manifest := Manifest{
|
||
|
Template: buffer.Bytes(),
|
||
|
}
|
||
|
|
||
|
for path, class := range d.scripts {
|
||
|
manifest.Override = append(manifest.Override, Script{
|
||
|
Path: path,
|
||
|
Class: class,
|
||
|
})
|
||
|
}
|
||
|
|
||
|
file, err := os.OpenFile(d.Options.Output+seperator+"manifest.json", os.O_CREATE|os.O_WRONLY, 0644)
|
||
|
if err != nil {
|
||
|
return err
|
||
|
}
|
||
|
defer file.Close()
|
||
|
|
||
|
encoder := json.NewEncoder(file)
|
||
|
encoder.SetIndent("", "\t")
|
||
|
return encoder.Encode(&manifest)
|
||
|
}
|
||
|
|
||
|
func (d PlaceDumper) Dump() error {
|
||
|
d.scripts = map[string]string{}
|
||
|
if err := d.loadRootFromFile(); err != nil {
|
||
|
return err
|
||
|
}
|
||
|
d.createTemplate()
|
||
|
|
||
|
if err := d.dumpScripts(); err != nil {
|
||
|
return err
|
||
|
}
|
||
|
|
||
|
if err := d.writeManifest(); err != nil {
|
||
|
return err
|
||
|
}
|
||
|
|
||
|
return nil
|
||
|
}
|