minewebgen - transfer_generator.go
1 package main
2
3 import (
4 "archive/zip"
5 "encoding/json"
6 "errors"
7 "os"
8 "path"
9 "strings"
10
11 "vimagination.zapto.org/byteio"
12 "vimagination.zapto.org/minewebgen/internal/data"
13 )
14
15 func (t Transfer) generator(name string, r *byteio.StickyLittleEndianReader, w *byteio.StickyLittleEndianWriter, f *os.File, size int64) error {
16 g := t.c.Generators.New(t.c.Settings().DirGenerators)
17 if g == nil {
18 return errors.New("error creating generator")
19 }
20 g.Name = name
21
22 done := false
23 defer func() {
24 if !done {
25 t.c.RemoveGenerator(g.ID)
26 }
27 go t.c.Save()
28 }()
29
30 zr, err := zip.NewReader(f, size)
31 if err != nil {
32 f.Seek(0, 0)
33 e := json.NewDecoder(f).Decode(new(data.GeneratorData))
34 if e != nil {
35 return err
36 }
37 err = moveFile(f.Name(), path.Join(g.Path, "data.gen"))
38 if err != nil {
39 return err
40 }
41
42 done = true
43 return nil
44 }
45
46 gens := make([]*zip.File, 0, 16)
47 for _, file := range zr.File {
48 if file.Name == "data.gen" {
49 gens = []*zip.File{file}
50 break
51 }
52 if strings.HasSuffix(file.Name, ".gen") || strings.HasSuffix(file.Name, ".json") {
53 gens = append(gens, file)
54 }
55 }
56
57 if len(gens) == 0 {
58 return errors.New("cannot find generator data in zip")
59 }
60 if len(gens) > 1 {
61 w.WriteUint8(1)
62 w.WriteInt16(int16(len(gens)))
63 for _, gen := range gens {
64 data.WriteString(w, gen.Name)
65 }
66 if w.Err != nil {
67 return w.Err
68 }
69 p := r.ReadInt16()
70 if r.Err != nil {
71 return r.Err
72 }
73 if int(p) >= len(gens) || p < 0 {
74 return errors.New("error selecting generator data")
75 }
76 gens[0] = gens[p]
77 }
78
79 gd, err := gens[0].Open()
80 if err != nil {
81 return err
82 }
83
84 err = json.NewDecoder(gd).Decode(new(data.GeneratorData))
85 if err != nil {
86 return err
87 }
88
89 err = unzip(zr, g.Path)
90 if err != nil {
91 return err
92 }
93
94 err = os.Rename(path.Join(g.Path, gens[0].Name), path.Join(g.Path, "data.gen"))
95 if err != nil {
96 return err
97 }
98
99 done = true
100 return nil
101 }