package rbxbuilder import ( "bytes" "encoding/json" "git.itzana.me/itzaname/rbxfile" "git.itzana.me/itzaname/rbxfile/xml" "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 }