minewebgen - internal/generator/main.go
		
     1  package main // import "vimagination.zapto.org/minewebgen/internal/generator"
     2  
     3  import (
     4  	"encoding/json"
     5  	"image/color"
     6  	"os"
     7  	"path"
     8  
     9  	"vimagination.zapto.org/byteio"
    10  	"vimagination.zapto.org/minecraft"
    11  	"vimagination.zapto.org/minewebgen/internal/data"
    12  	"vimagination.zapto.org/ora"
    13  )
    14  
    15  func LoadGenerator(f *os.File) (*generator, error) {
    16  	g := new(generator)
    17  	err := json.NewDecoder(f).Decode(&g.generator)
    18  	if err != nil {
    19  		return nil, err
    20  	}
    21  	if len(g.generator.Terrain) == 0 {
    22  		g.generator.Terrain = []data.ColourBlocks{{Name: "Empty"}}
    23  	}
    24  	if len(g.generator.Biomes) == 0 {
    25  		g.generator.Biomes = []data.ColourBiome{{Name: "Plains", Biome: 1}}
    26  	}
    27  	if len(g.generator.Plants) == 0 {
    28  		g.generator.Plants = []data.ColourBlocks{{Name: "Empty"}}
    29  	}
    30  
    31  	g.Terrain.Blocks = make([]data.Blocks, len(g.generator.Terrain)+1)
    32  	g.Terrain.Palette = make(color.Palette, len(g.generator.Terrain))
    33  	for i := range g.generator.Terrain {
    34  		g.Terrain.Blocks[i] = g.generator.Terrain[i].Blocks
    35  		g.Terrain.Palette[i] = g.generator.Terrain[i].Colour
    36  	}
    37  	g.Terrain.Blocks[len(g.Terrain.Blocks)-1].Base.ID = 9
    38  
    39  	g.Biomes.Values = make([]minecraft.Biome, len(g.generator.Biomes))
    40  	g.Biomes.Palette = make(color.Palette, len(g.generator.Biomes))
    41  	for i := range g.generator.Biomes {
    42  		g.Biomes.Values[i] = g.generator.Biomes[i].Biome
    43  		g.Biomes.Palette[i] = g.generator.Biomes[i].Colour
    44  	}
    45  
    46  	g.Plants.Blocks = make([]data.Blocks, len(g.generator.Plants))
    47  	g.Plants.Palette = make(color.Palette, len(g.generator.Plants))
    48  	for i := range g.generator.Plants {
    49  		g.Plants.Blocks[i] = g.generator.Plants[i].Blocks
    50  		g.Plants.Palette[i] = g.generator.Plants[i].Colour
    51  	}
    52  	return g, nil
    53  }
    54  
    55  func main() {
    56  	r := byteio.StickyLittleEndianReader{Reader: os.Stdin}
    57  	w := byteio.StickyLittleEndianWriter{Writer: os.Stdout}
    58  	if err := generate(&r, &w, os.NewFile(3, "data.ora")); err != nil {
    59  		w.WriteUint8(0)
    60  		data.WriteString(&w, err.Error())
    61  		os.Exit(1)
    62  	}
    63  }
    64  
    65  func generate(r *byteio.StickyLittleEndianReader, w *byteio.StickyLittleEndianWriter, of *os.File) error {
    66  	memoryLimit := r.ReadUint64()
    67  	size := r.ReadInt64()
    68  	gPath := data.ReadString(r)
    69  	levelName := data.ReadString(r)
    70  	mapPath := data.ReadString(r)
    71  	if r.Err != nil {
    72  		return r.Err
    73  	}
    74  	o, err := ora.Open(of, size)
    75  	if err != nil {
    76  		return err
    77  	}
    78  	f, err := os.Open(path.Join(gPath, "data.gen"))
    79  	if err != nil {
    80  		return err
    81  	}
    82  	g, err := LoadGenerator(f)
    83  	if e := f.Close(); e != nil {
    84  		return e
    85  	}
    86  	if err != nil {
    87  		return err
    88  	}
    89  
    90  	b := o.Bounds()
    91  	w.WriteUint8(2)
    92  	w.WriteInt32(int32(b.Max.X) >> 4)
    93  	w.WriteInt32(int32(b.Max.Y) >> 4)
    94  
    95  	c := make(chan paint, 1024)
    96  	m := make(chan string, 4)
    97  	e := make(chan struct{}, 0)
    98  	go func() {
    99  		defer close(e)
   100  		defer close(m)
   101  		defer close(c)
   102  		for {
   103  			select {
   104  			case message := <-m:
   105  				w.WriteUint8(3)
   106  				data.WriteString(w, message)
   107  			case p := <-c:
   108  				w.WriteUint8(4)
   109  				w.WriteInt32(p.X)
   110  				w.WriteInt32(p.Y)
   111  				r, g, b, a := p.RGBA()
   112  				w.WriteUint8(uint8(r >> 8))
   113  				w.WriteUint8(uint8(g >> 8))
   114  				w.WriteUint8(uint8(b >> 8))
   115  				w.WriteUint8(uint8(a >> 8))
   116  			case <-e:
   117  				return
   118  			}
   119  		}
   120  	}()
   121  
   122  	err = g.Generate(levelName, mapPath, o, c, m, memoryLimit)
   123  
   124  	e <- struct{}{}
   125  	<-e
   126  	return err
   127  }
   128  
   129  type paint struct {
   130  	color.Color
   131  	X, Y int32
   132  }