コード例 #1
0
ファイル: servers.go プロジェクト: MJKWoolnough/minewebgen
func serverEULA(s data.Server, d string) func(dom.Element) {
	return func(c dom.Element) {
		t := xform.TextArea("eula", d)
		submit := xform.InputSubmit("Save")
		c.AppendChild(xjs.AppendChildren(xdom.Form(), xjs.AppendChildren(xdom.Fieldset(),
			xjs.SetInnerText(xdom.Legend(), "End User License Agreement"),
			xform.Label("EULA", "eula"), t, xdom.Br(),
			submit,
		)))
		submit.AddEventListener("click", false, func(e dom.Event) {
			e.PreventDefault()
			submit.Disabled = true
			go func() {
				err := RPC.SetServerEULA(s.ID, t.Value)
				if err != nil {
					xjs.Alert("Error setting server EULA: %s", err)
					return
				}
				d = t.Value
				span := xdom.Span()
				span.Style().Set("color", "#f00")
				c.AppendChild(xjs.SetInnerText(span, "Saved!"))
				time.Sleep(5 * time.Second)
				c.RemoveChild(span)
				submit.Disabled = false
			}()
		})
	}
}
コード例 #2
0
ファイル: maps.go プロジェクト: MJKWoolnough/minewebgen
func createMapMode(mode int, o *overlay.Overlay, dataParser func() (data.DefaultMap, error)) func(dom.Element) {
	submit := xform.InputSubmit("Create Map")
	submit.AddEventListener("click", false, func(e dom.Event) {
		data, err := dataParser()
		if err != nil {
			xjs.Alert("Error parsing values: %s", err)
			return
		}
		e.PreventDefault()
		go func() {
			err = RPC.CreateDefaultMap(data)
			if err != nil {
				xjs.Alert("Error creating map: %s", err)
				return
			}
			o.Close()
		}()
	})
	return func(c dom.Element) {
		xjs.AppendChildren(c,
			xjs.SetPreText(xdom.Div(), worldTypes[mode]),
			xdom.Br(),
			submit,
		)
	}
}
コード例 #3
0
ファイル: settings.go プロジェクト: MJKWoolnough/minewebgen
func settingsTab(c dom.Element) {
	s, err := RPC.Settings()
	if err != nil {
		xjs.Alert("Error reading settings: %s", err)
		return
	}
	sn := xform.InputText("serverName", s.ServerName)
	sn.Required = true
	la := xform.InputText("listenAddr", s.ListenAddr)
	la.Required = true
	sp := xform.InputText("serversPath", s.DirServers)
	sp.Required = true
	mp := xform.InputText("mapsPath", s.DirMaps)
	mp.Required = true
	gp := xform.InputText("gensPath", s.DirGenerators)
	gp.Required = true
	ge := xform.InputText("genExe", s.GeneratorExecutable)
	ge.Required = true
	mm := xform.InputNumber("maxMem", 100, 10000, float64(s.GeneratorMaxMem/1024/1024))
	mm.Required = true
	sb := xform.InputSubmit("Save")
	sb.AddEventListener("click", false, func(e dom.Event) {
		if sn.Value == "" || la.Value == "" || sp.Value == "" || mp.Value == "" || gp.Value == "" || ge.Value == "" || !mm.CheckValidity() {
			return
		}
		e.PreventDefault()
		sb.Disabled = true
		go func() {
			s.ServerName = sn.Value
			s.ListenAddr = la.Value
			s.DirServers = sp.Value
			s.DirMaps = mp.Value
			s.DirGenerators = gp.Value
			s.GeneratorExecutable = ge.Value
			s.GeneratorMaxMem = uint64(mm.ValueAsNumber * 1024 * 1024)
			if err := RPC.SetSettings(s); err != nil {
				xjs.Alert("Error saving settings: %s", err)
				return
			}
			SetTitle(sn.Value)
			span := xdom.Span()
			span.Style().Set("color", "#f00")
			c.AppendChild(xjs.SetInnerText(span, "Saved!"))
			time.Sleep(5 * time.Second)
			c.RemoveChild(span)
			sb.Disabled = false
		}()
	})
	xjs.AppendChildren(c, xjs.AppendChildren(xdom.Form(), xjs.AppendChildren(xdom.Fieldset(),
		xjs.SetInnerText(xdom.Legend(), "Change Settings"),
		xform.Label("Server Name", "serverName"), sn, xdom.Br(),
		xform.Label("Listen Address", "listenAddr"), la, xdom.Br(),
		xform.Label("Servers Path", "serversPath"), sp, xdom.Br(),
		xform.Label("Maps Path", "mapsPath"), mp, xdom.Br(),
		xform.Label("Generators Path", "gensPath"), gp, xdom.Br(),
		xform.Label("Generator Executable", "genExe"), ge, xdom.Br(),
		xform.Label("Generator Memory (MB)", "maxMem"), mm, xdom.Br(),
		sb,
	)))
}
コード例 #4
0
ファイル: maps.go プロジェクト: MJKWoolnough/minewebgen
func createSuperFlatMap(o *overlay.Overlay, dataParser func() (data.DefaultMap, error)) func(dom.Element) {
	// create better UI here
	d := xdom.Div()
	gs := xform.InputText("settings", "0")
	gs.Required = true
	submit := xform.InputSubmit("Create Map")
	xjs.AppendChildren(d,
		xjs.SetPreText(xdom.Div(), worldTypes[1]),
		xform.Label("Generator Settings", "settings"),
		gs,
		xdom.Br(),
		submit,
	)
	submit.AddEventListener("click", false, func(e dom.Event) {
		d, err := dataParser()
		if err != nil {
			xjs.Alert("Error parsing values: %s", err)
			return
		}
		e.PreventDefault()
		go func() {
			err = RPC.CreateSuperflatMap(data.SuperFlatMap{
				DefaultMap:        d,
				GeneratorSettings: gs.Value,
			})
			if err != nil {
				xjs.Alert("Error creating map: %s", err)
				return
			}
			o.Close()

		}()
	})
	return func(c dom.Element) {
		c.AppendChild(d)
	}
}
コード例 #5
0
ファイル: utils.go プロジェクト: MJKWoolnough/minewebgen
func transferFile(typeName, method string, typeID uint8, o *overlay.Overlay) dom.Node {
	name := xform.InputText("name", "")
	url := xform.InputRadio("url", "switch", true)
	upload := xform.InputRadio("upload", "switch", false)
	fileI := xform.InputUpload("")
	urlI := xform.InputURL("", "")
	s := xform.InputSubmit(method)

	name.Required = true

	typeFunc := func(dom.Event) {
		if url.Checked {
			urlI.Style().RemoveProperty("display")
			fileI.Style().SetProperty("display", "none", "")
			urlI.Required = true
			fileI.Required = false
			fileI.SetID("")
			urlI.SetID("file")
		} else {
			fileI.Style().RemoveProperty("display")
			urlI.Style().SetProperty("display", "none", "")
			fileI.Required = true
			urlI.Required = false
			urlI.SetID("")
			fileI.SetID("file")
		}
	}

	typeFunc(nil)

	url.AddEventListener("change", false, typeFunc)
	upload.AddEventListener("change", false, typeFunc)

	f := xjs.AppendChildren(xdom.Form(), xjs.AppendChildren(xdom.Fieldset(),
		xjs.SetInnerText(xdom.Legend(), method+" "+typeName),
		xform.Label(typeName+" Name", "name"),
		name,
		xdom.Br(),

		xform.Label("URL", "url"),
		url,
		xdom.Br(),

		xform.Label("Upload", "upload"),
		upload,
		xdom.Br(),

		xform.Label("File", "file"),

		fileI,
		urlI,

		xdom.Br(),
		s,
	))

	s.AddEventListener("click", false, func(e dom.Event) {
		if name.Value == "" {
			return
		}
		if url.Checked {
			if urlI.Value == "" {
				return
			}
		} else if len(fileI.Files()) != 1 {
			return

		}
		s.Disabled = true
		name.Disabled = true
		url.Disabled = true
		upload.Disabled = true
		fileI.Disabled = true
		urlI.Disabled = true
		e.PreventDefault()
		go func() {
			d := xdom.Div()
			uo := overlay.New(d)
			uo.OnClose(func() {
				o.Close()
			})
			xjs.Body().AppendChild(uo)
			status := xdom.Div()
			d.AppendChild(xjs.SetInnerText(status, "Transferring..."))
			conn, err := websocket.Dial("ws://" + js.Global.Get("location").Get("host").String() + "/transfer")
			if err != nil {
				xjs.SetInnerText(status, err.Error())
				return
			}
			defer conn.Close()
			w := byteio.StickyWriter{Writer: byteio.LittleEndianWriter{Writer: conn}}
			r := byteio.StickyReader{Reader: byteio.LittleEndianReader{Reader: conn}}

			pb := progress.New(color.RGBA{255, 0, 0, 0}, color.RGBA{0, 0, 255, 0}, 400, 50)
			d.AppendChild(pb)

			if url.Checked {
				w.WriteUint8(typeID << 1)
				data.WriteString(&w, urlI.Value)
				length := int(r.ReadInt32())
				total := 0
				for total < length {
					switch v := r.ReadUint8(); v {
					case 1:
						i := int(r.ReadInt32())
						total += i
						pb.Percent(100 * total / length)
					default:
						xjs.SetInnerText(status, ReadError(&r).Error())
						return
					}
				}
			} else {
				f := files.NewFileReader(files.NewFile(fileI.Files()[0]))
				l := f.Len()
				if l == 0 {
					xjs.SetInnerText(status, "Zero-length file")
					return
				}
				w.WriteUint8(typeID<<1 | 1)
				w.WriteInt32(int32(l))
				io.Copy(&w, pb.Reader(f, l))
			}

			d.RemoveChild(pb)
			xjs.SetInnerText(status, "Checking File")

			data.WriteString(&w, name.Value)

			var ctx *dom.CanvasRenderingContext2D

			for {
				switch v := r.ReadUint8(); v {
				case 0:
					if r.Err != nil {
						xjs.SetInnerText(status, r.Err.Error())
					} else {
						xjs.SetInnerText(status, ReadError(&r).Error())
					}
					return
				case 1:
					files := make([]xform.Option, r.ReadInt16())
					for i := range files {
						files[i] = xform.Option{
							Value: strconv.Itoa(i),
							Label: data.ReadString(&r),
						}
					}
					j := xform.SelectBox("files", files...)
					sel := xjs.SetInnerText(xdom.Button(), "Select")
					fo := overlay.New(xjs.AppendChildren(xdom.Div(), xjs.AppendChildren(xdom.Fieldset(),
						xjs.SetInnerText(xdom.Legend(), "Please select the "+typeName+" file"),
						xform.Label("File", "files"),
						j,
						xdom.Br(),
						sel,
					)))
					c := make(chan int16, 0)
					done := false
					fo.OnClose(func() {
						if !done {
							done = true
							c <- -1
						}
					})
					sel.AddEventListener("click", false, func(dom.Event) {
						if !done {
							done = true
							v, err := strconv.Atoi(j.Value)
							if err != nil {
								v = -1
							}
							c <- int16(v)
							fo.Close()
						}
					})
					xjs.Body().AppendChild(fo)
					w.WriteInt16(<-c)
					close(c)
				case 2:
					w := r.ReadInt32()
					h := r.ReadInt32()
					canvas := xdom.Canvas()
					canvas.Width = int(w) * 8
					canvas.Height = int(h) * 8
					d.AppendChild(canvas)
					ctx = canvas.GetContext2d()
					ctx.Scale(8, 8)
				case 3:
					xjs.SetInnerText(status, data.ReadString(&r))
				case 4:
					x := r.ReadInt32()
					y := r.ReadInt32()
					red := r.ReadUint8()
					green := r.ReadUint8()
					blue := r.ReadUint8()
					alpha := r.ReadUint8()
					ctx.FillStyle = "rgba(" + strconv.Itoa(int(red)) + ", " + strconv.Itoa(int(green)) + ", " + strconv.Itoa(int(blue)) + ", " + strconv.FormatFloat(float64(alpha)/255, 'f', -1, 32) + ")"
					ctx.FillRect(int(x), int(y), 1, 1)
				case 255:
					uo.Close()
					return
				}
			}

		}()
	})
	return f
}
コード例 #6
0
ファイル: servers.go プロジェクト: MJKWoolnough/minewebgen
func serverConsole(s data.Server) func(dom.Element) {
	return func(c dom.Element) {
		log := xform.TextArea("log", "")
		log.ReadOnly = true
		command := xform.InputText("command", "")
		command.Required = true
		send := xform.InputSubmit("Send")
		c.AppendChild(xjs.AppendChildren(xdom.Form(), xjs.AppendChildren(xdom.Fieldset(),
			xjs.SetInnerText(xdom.Legend(), "Console"),
			xform.Label("Log", ""), log, xdom.Br(),
			xform.Label("Command", "command"), command, send,
		)))
		if s.State == data.StateStopped {
			send.Disabled = true
			command.Disabled = true
		} else {
			send.AddEventListener("click", false, func(e dom.Event) {
				if command.Value == "" {
					return
				}
				e.PreventDefault()
				send.Disabled = true
				cmd := command.Value
				log.Value += "\n>" + cmd + "\n"
				log.Set("scrollTop", log.Get("scrollHeight"))
				command.Value = ""
				go func() {
					err := RPC.WriteCommand(s.ID, cmd)
					if err != nil {
						xjs.Alert("Error sending command: %s", err)
						return
					}
					send.Disabled = false
				}()
			})
		}
		go func() {
			conn, err := websocket.Dial("ws://" + js.Global.Get("location").Get("host").String() + "/console")
			if err != nil {
				xjs.Alert("Failed to connect to console: %s", err)
				return
			}
			defer conn.Close()
			w := byteio.StickyWriter{Writer: byteio.LittleEndianWriter{Writer: conn}}
			r := byteio.StickyReader{Reader: byteio.LittleEndianReader{Reader: conn}}
			updateStop := make(chan struct{})
			registerUpdateStopper(c, updateStop)
			done := false
			go func() {
				<-updateStop
				done = true
				conn.Close()
			}()
			w.WriteInt32(int32(s.ID))
			for {
				state := r.ReadUint8()
				switch state {
				case 0:
					if !done {
						err := ReadError(&r)
						if r.Err != nil {
							err = r.Err
						}
						log.Value += "\n\nError reading from console: " + err.Error()
						log.Set("scrollTop", log.Get("scrollHeight"))
					}
					return
				case 1:
					log.Value += data.ReadString(&r)
					log.Set("scrollTop", log.Get("scrollHeight"))
				}
			}
		}()
	}
}
コード例 #7
0
ファイル: servers.go プロジェクト: MJKWoolnough/minewebgen
func serverGeneral(s data.Server) func(dom.Element) {
	return func(c dom.Element) {
		go func() {
			maps, err := RPC.MapList()
			if err != nil {
				c.AppendChild(xjs.SetInnerText(xdom.Div(), "Error getting map list: "+err.Error()))
				return
			}
			name := xform.InputText("name", s.Name)
			name.Required = true
			opts := make([]xform.Option, 1, len(maps)+1)
			opts[0] = xform.Option{
				Label:    "-- None -- ",
				Value:    "-1",
				Selected: s.Map == -1,
			}
			for i, m := range maps {
				n := m.Name
				if m.Server != -1 {
					if m.ID == s.Map {
						n = "* - " + n
					} else {
						n = "! - " + n
					}
				} else {
					n = "    " + n
				}
				opts = append(opts, xform.Option{
					Label:    n,
					Value:    strconv.Itoa(i),
					Selected: m.ID == s.Map,
				})
			}
			args := xform.InputSizeableList(s.Args...)
			sel := xform.SelectBox("map", opts...)
			submit := xform.InputSubmit("Set")
			submit.AddEventListener("click", false, func(e dom.Event) {
				if s.State != data.StateStopped {
					xjs.Alert("Cannot modify these settings while the server is running")
					return
				}
				if name.Value == "" {
					return
				}
				sID, err := strconv.Atoi(sel.Value)
				if err != nil || sID < -1 || sID >= len(maps) {
					return
				}
				submit.Disabled = true
				e.PreventDefault()
				if sID >= 0 {
					m := maps[sID]
					sID = m.ID
				}
				go func() {
					err = RPC.SetServerMap(s.ID, sID)
					if err != nil {
						xjs.Alert("Error setting server map: %s", err)
						return
					}
					s.Name = name.Value
					s.Args = args.Values()
					err = RPC.SetServer(s)
					if err != nil {
						xjs.Alert("Error setting server data: %s", err)
						return
					}
					span := xdom.Span()
					span.Style().Set("color", "#f00")
					c.AppendChild(xjs.SetInnerText(span, "Saved!"))
					time.Sleep(5 * time.Second)
					c.RemoveChild(span)
					submit.Disabled = false
				}()
			})
			xjs.AppendChildren(c, xjs.AppendChildren(xdom.Form(),
				xform.Label("Server Name", "name"),
				name,
				xdom.Br(),
				xform.Label("Arguments", "args"),
				args,
				xdom.Br(),
				xform.Label("Map Name", "map"),
				sel,
				xdom.Br(),
				submit,
			))
		}()
	}
}
コード例 #8
0
ファイル: maps.go プロジェクト: MJKWoolnough/minewebgen
func mapGeneral(m data.Map) func(dom.Element) {
	return func(c dom.Element) {
		go func() {
			servers, err := RPC.ServerList()
			if err != nil {
				c.AppendChild(xjs.SetInnerText(xdom.Div(), "Error getting server list: "+err.Error()))
				return
			}
			name := xform.InputText("name", m.Name)
			name.Required = true
			opts := make([]xform.Option, 1, len(servers)+1)
			opts[0] = xform.Option{
				Label:    "-- None --",
				Value:    "-1",
				Selected: m.Server == -1,
			}
			var cs data.Server
			for i, s := range servers {
				n := s.Name
				if s.Map != -1 {
					if s.ID == m.Server {
						cs = s
						n = "* - " + n
					} else {
						n = "! - " + n
					}
				} else {
					n = "    " + n
				}
				opts = append(opts, xform.Option{
					Label:    n,
					Value:    strconv.Itoa(i),
					Selected: s.ID == m.Server,
				})
			}
			sel := xform.SelectBox("server", opts...)
			submit := xform.InputSubmit("Set")
			submit.AddEventListener("click", false, func(e dom.Event) {
				if cs.State != data.StateStopped {
					xjs.Alert("Cannot modify these settings while connected server is running.")
					return
				}
				if name.Value == "" {
					return
				}
				mID, err := strconv.Atoi(sel.Value)
				if err != nil || mID < -1 || mID >= len(servers) {
					return
				}
				submit.Disabled = true
				e.PreventDefault()
				if mID >= 0 {
					s := servers[mID]
					mID = s.ID
				}
				go func() {
					err = RPC.SetServerMap(mID, m.ID)
					if err != nil {
						xjs.Alert("Error setting map server: %s", err)
						return
					}
					m.Name = name.Value
					err = RPC.SetMap(m)
					if err != nil {
						xjs.Alert("Error setting map data: %s", err)
						return
					}
					span := xdom.Span()
					span.Style().Set("color", "#f00")
					c.AppendChild(xjs.SetInnerText(span, "Saved!"))
					time.Sleep(5 * time.Second)
					c.RemoveChild(span)
					submit.Disabled = false
				}()
			})
			xjs.AppendChildren(c, xjs.AppendChildren(xdom.Form(),
				xform.Label("Server Name", "name"),
				name,
				xdom.Br(),
				xform.Label("Server Name", "server"),
				sel,
				xdom.Br(),
				submit,
			))
		}()
	}
}
コード例 #9
0
ファイル: maps.go プロジェクト: MJKWoolnough/minewebgen
func createCustomisedMap(o *overlay.Overlay, dataParser func() (data.DefaultMap, error)) func(dom.Element) {
	d := xdom.Div()
	d.Class().SetString("brClear")
	seaLevel := xform.InputRange("sea", 0, 255, 1, 63)
	caves := xform.InputCheckbox("caves", true)
	strongholds := xform.InputCheckbox("strongholds", true)
	villages := xform.InputCheckbox("villages", true)
	mineshafts := xform.InputCheckbox("mineshafts", true)
	temples := xform.InputCheckbox("templaes", true)
	oceanMonuments := xform.InputCheckbox("oceanMonuments", true)
	ravines := xform.InputCheckbox("ravines", true)
	dungeons := xform.InputCheckbox("dungeons", true)
	dungeonCount := xform.InputRange("dungeonCount", 1, 100, 1, 7)
	waterLakes := xform.InputCheckbox("waterLakes", true)
	waterLakeRarity := xform.InputRange("waterLakeRarity", 1, 100, 1, 4)
	lavaLakes := xform.InputCheckbox("lavaLakes", true)
	lavaLakeRarity := xform.InputRange("lavaLakeRarity", 1, 100, 1, 80)
	biome := xform.SelectBox("biomes", biomes...)
	biomeSize := xform.InputRange("biomeSize", 1, 8, 1, 4)
	riverSize := xform.InputRange("riverSize", 1, 5, 1, 4)

	dirtSpawnSize := xform.InputRange("dirtSpawnSize", 1, 50, 1, 33)
	dirtSpawnTries := xform.InputRange("dirtSpawnTries", 0, 40, 1, 10)
	dirtMinHeight := xform.InputRange("dirtMinHeight", 0, 255, 1, 0)
	dirtMaxHeight := xform.InputRange("dirtMaxHeight", 0, 255, 1, 256)

	gravelSpawnSize := xform.InputRange("gravelSpawnSize", 1, 50, 1, 33)
	gravelSpawnTries := xform.InputRange("gravelSpawnTries", 0, 40, 1, 8)
	gravelMinHeight := xform.InputRange("gravelMinHeight", 0, 255, 1, 0)
	gravelMaxHeight := xform.InputRange("gravelMaxHeight", 0, 255, 1, 256)

	graniteSpawnSize := xform.InputRange("graniteSpawnSize", 1, 50, 1, 33)
	graniteSpawnTries := xform.InputRange("graniteSpawnTries", 0, 40, 1, 10)
	graniteMinHeight := xform.InputRange("graniteMinHeight", 0, 255, 1, 0)
	graniteMaxHeight := xform.InputRange("graniteMaxHeight", 0, 255, 1, 80)

	dioriteSpawnSize := xform.InputRange("dioriteSpawnSize", 1, 50, 1, 33)
	dioriteSpawnTries := xform.InputRange("dioriteSpawnTries", 0, 40, 1, 10)
	dioriteMinHeight := xform.InputRange("dioriteMinHeight", 0, 255, 1, 0)
	dioriteMaxHeight := xform.InputRange("dioriteMaxHeight", 0, 255, 1, 80)

	andesiteSpawnSize := xform.InputRange("andesiteSpawnSize", 1, 50, 1, 33)
	andesiteSpawnTries := xform.InputRange("andesiteSpawnTries", 0, 40, 1, 10)
	andesiteMinHeight := xform.InputRange("andesiteMinHeight", 0, 255, 1, 0)
	andesiteMaxHeight := xform.InputRange("andesiteMaxHeight", 0, 255, 1, 80)

	coalOreSpawnSize := xform.InputRange("coalOreSpawnSize", 1, 50, 1, 17)
	coalOreSpawnTries := xform.InputRange("coalOreSpawnTries", 0, 40, 1, 20)
	coalOreMinHeight := xform.InputRange("coalOreMinHeight", 0, 255, 1, 0)
	coalOreMaxHeight := xform.InputRange("coalOreMaxHeight", 0, 255, 1, 128)

	ironOreSpawnSize := xform.InputRange("ironOreSpawnSize", 1, 50, 1, 9)
	ironOreSpawnTries := xform.InputRange("ironOreSpawnTries", 0, 40, 1, 20)
	ironOreMinHeight := xform.InputRange("ironOreMinHeight", 0, 255, 1, 0)
	ironOreMaxHeight := xform.InputRange("ironOreMaxHeight", 0, 255, 1, 64)

	goldOreSpawnSize := xform.InputRange("goldOreSpawnSize", 1, 50, 1, 9)
	goldOreSpawnTries := xform.InputRange("goldOreSpawnTries", 0, 40, 1, 2)
	goldOreMinHeight := xform.InputRange("goldOreMinHeight", 0, 255, 1, 0)
	goldOreMaxHeight := xform.InputRange("goldOreMaxHeight", 0, 255, 1, 32)

	redstoneOreSpawnSize := xform.InputRange("redstoneOreSpawnSize", 1, 50, 1, 8)
	redstoneOreSpawnTries := xform.InputRange("redstoneOreSpawnTries", 0, 40, 1, 8)
	redstoneOreMinHeight := xform.InputRange("redstoneOreMinHeight", 0, 255, 1, 0)
	redstoneOreMaxHeight := xform.InputRange("redstoneOreMaxHeight", 0, 255, 1, 16)

	diamondOreSpawnSize := xform.InputRange("diamondOreSpawnSize", 1, 50, 1, 8)
	diamondOreSpawnTries := xform.InputRange("diamondOreSpawnTries", 0, 40, 1, 1)
	diamondOreMinHeight := xform.InputRange("diamondOreMinHeight", 0, 255, 1, 0)
	diamondOreMaxHeight := xform.InputRange("diamondOreMaxHeight", 0, 255, 1, 16)

	lapisLazuliOreSpawnSize := xform.InputRange("lapisLazuliOreSpawnSize", 1, 50, 1, 7)
	lapisLazuliOreSpawnTries := xform.InputRange("lapisLazuliOreSpawnTries", 0, 40, 1, 1)
	lapisLazuliOreCentreHeight := xform.InputRange("lapisLazuliOreCentreHeight", 0, 255, 1, 16)
	lapisLazuliOreSpreadHeight := xform.InputRange("lapisLazuliOreSpreadHeight", 0, 255, 1, 16)

	mainNoiseScaleX := xform.InputRange("mainNoiseScaleX", 1, 5000, -1, 80)
	mainNoiseScaleY := xform.InputRange("mainNoiseScaleY", 1, 5000, -1, 160)
	mainNoiseScaleZ := xform.InputRange("mainNoiseScaleZ", 1, 5000, -1, 80)
	depthNoiseScaleX := xform.InputRange("depthNoiseScaleX", 1, 2000, -1, 200)
	depthNoiseScaleZ := xform.InputRange("depthNoiseScaleZ", 1, 2000, -1, 200)
	depthNoiseExponent := xform.InputRange("depthNoiseExponent", 0.01, 20, -1, 0.5)
	depthBaseSize := xform.InputRange("depthBaseSize", 1, 25, -1, 8.5)
	coordinateScale := xform.InputRange("coordinateScale", 1, 6000, -1, 684.412)
	heightScale := xform.InputRange("heightScale", 1, 6000, -1, 684.412)
	heightStretch := xform.InputRange("heightStretch", 0.01, 50, -1, 12)
	upperLimitScale := xform.InputRange("upperLimitScale", 1, 5000, -1, 512)
	lowerLimitScale := xform.InputRange("lowerLimitScale", 1, 5000, -1, 512)
	biomeDepthWeight := xform.InputRange("biomeDepthWeight", 1, 20, -1, 1)
	biomeDepthOffset := xform.InputRange("biomeDepthOffset", 0, 20, -1, 0)
	biomeScaleWeight := xform.InputRange("biomeScaleWeight", 1, 20, -1, 1)
	biomeScaleOffset := xform.InputRange("biomeScaleOffset", 0, 20, -1, 0)

	submit := xform.InputSubmit("Create Map")
	submit.AddEventListener("click", false, func(e dom.Event) {
		d, err := dataParser()
		if err != nil {
			xjs.Alert("Error parsing values: %s", err)
			return
		}
		e.PreventDefault()
		cd := data.CustomMap{
			DefaultMap: d,
		}
		cd.GeneratorSettings.SeaLevel = uint8(seaLevel.ValueAsNumber)
		cd.GeneratorSettings.Caves = caves.Checked
		cd.GeneratorSettings.Strongholds = strongholds.Checked
		cd.GeneratorSettings.Villages = villages.Checked
		cd.GeneratorSettings.Mineshafts = mineshafts.Checked
		cd.GeneratorSettings.Temples = temples.Checked
		cd.GeneratorSettings.OceanMonuments = oceanMonuments.Checked
		cd.GeneratorSettings.Ravines = ravines.Checked
		cd.GeneratorSettings.Dungeons = dungeons.Checked
		cd.GeneratorSettings.DungeonChance = uint8(dungeonCount.ValueAsNumber)
		cd.GeneratorSettings.WaterLake = waterLakes.Checked
		cd.GeneratorSettings.WaterLakeChance = uint8(waterLakeRarity.ValueAsNumber)
		cd.GeneratorSettings.LaveLake = lavaLakes.Checked
		cd.GeneratorSettings.LavaLakeChance = uint8(lavaLakeRarity.ValueAsNumber)
		b, err := strconv.Atoi(biome.Value)
		if err != nil {
			b = -1
		}
		cd.GeneratorSettings.Biome = int16(b)

		cd.GeneratorSettings.BiomeSize = uint8(biomeSize.ValueAsNumber)
		cd.GeneratorSettings.RiverSize = uint8(riverSize.ValueAsNumber)

		cd.GeneratorSettings.DirtSize = uint8(dirtSpawnSize.ValueAsNumber)
		cd.GeneratorSettings.DirtTries = uint8(dirtSpawnTries.ValueAsNumber)
		cd.GeneratorSettings.DirtMinHeight = uint8(dirtMinHeight.ValueAsNumber)
		cd.GeneratorSettings.DirtMaxHeight = uint8(dirtMaxHeight.ValueAsNumber)

		cd.GeneratorSettings.GravelSize = uint8(gravelSpawnSize.ValueAsNumber)
		cd.GeneratorSettings.GravelTries = uint8(gravelSpawnTries.ValueAsNumber)
		cd.GeneratorSettings.GravelMinHeight = uint8(gravelMinHeight.ValueAsNumber)
		cd.GeneratorSettings.GravelMaxHeight = uint8(gravelMaxHeight.ValueAsNumber)

		cd.GeneratorSettings.GraniteSize = uint8(graniteSpawnSize.ValueAsNumber)
		cd.GeneratorSettings.GraniteTries = uint8(graniteSpawnTries.ValueAsNumber)
		cd.GeneratorSettings.GraniteMinHeight = uint8(graniteMinHeight.ValueAsNumber)
		cd.GeneratorSettings.GraniteMaxHeight = uint8(graniteMaxHeight.ValueAsNumber)

		cd.GeneratorSettings.DiortiteSize = uint8(dioriteSpawnSize.ValueAsNumber)
		cd.GeneratorSettings.DiortiteTries = uint8(dioriteSpawnTries.ValueAsNumber)
		cd.GeneratorSettings.DiortiteMinHeight = uint8(dioriteMinHeight.ValueAsNumber)
		cd.GeneratorSettings.DiortiteMaxHeight = uint8(dioriteMaxHeight.ValueAsNumber)

		cd.GeneratorSettings.AndesiteSize = uint8(andesiteSpawnSize.ValueAsNumber)
		cd.GeneratorSettings.AndesiteTries = uint8(andesiteSpawnTries.ValueAsNumber)
		cd.GeneratorSettings.AndesiteMinHeight = uint8(andesiteMinHeight.ValueAsNumber)
		cd.GeneratorSettings.AndesiteMaxHeight = uint8(andesiteMaxHeight.ValueAsNumber)

		cd.GeneratorSettings.CoalSize = uint8(coalOreSpawnSize.ValueAsNumber)
		cd.GeneratorSettings.CoalTries = uint8(coalOreSpawnTries.ValueAsNumber)
		cd.GeneratorSettings.CoalMinHeight = uint8(coalOreMinHeight.ValueAsNumber)
		cd.GeneratorSettings.CoalMaxHeight = uint8(coalOreMaxHeight.ValueAsNumber)

		cd.GeneratorSettings.IronSize = uint8(ironOreSpawnSize.ValueAsNumber)
		cd.GeneratorSettings.IronTries = uint8(ironOreSpawnTries.ValueAsNumber)
		cd.GeneratorSettings.IronMinHeight = uint8(ironOreMinHeight.ValueAsNumber)
		cd.GeneratorSettings.IronMaxHeight = uint8(ironOreMaxHeight.ValueAsNumber)

		cd.GeneratorSettings.GoldSize = uint8(goldOreSpawnSize.ValueAsNumber)
		cd.GeneratorSettings.GoldTries = uint8(goldOreSpawnTries.ValueAsNumber)
		cd.GeneratorSettings.GoldMinHeight = uint8(goldOreMinHeight.ValueAsNumber)
		cd.GeneratorSettings.GoldMaxHeight = uint8(goldOreMaxHeight.ValueAsNumber)

		cd.GeneratorSettings.RedstoneSize = uint8(redstoneOreSpawnSize.ValueAsNumber)
		cd.GeneratorSettings.RedstoneTries = uint8(redstoneOreSpawnTries.ValueAsNumber)
		cd.GeneratorSettings.RedstoneMinHeight = uint8(redstoneOreMinHeight.ValueAsNumber)
		cd.GeneratorSettings.RedstoneMaxHeight = uint8(redstoneOreMaxHeight.ValueAsNumber)

		cd.GeneratorSettings.DiamondSize = uint8(diamondOreSpawnSize.ValueAsNumber)
		cd.GeneratorSettings.DiamondTries = uint8(diamondOreSpawnTries.ValueAsNumber)
		cd.GeneratorSettings.DiamondMinHeight = uint8(diamondOreMinHeight.ValueAsNumber)
		cd.GeneratorSettings.DiamondMaxHeight = uint8(diamondOreMaxHeight.ValueAsNumber)

		cd.GeneratorSettings.LapisSize = uint8(lapisLazuliOreSpawnSize.ValueAsNumber)
		cd.GeneratorSettings.LapisTries = uint8(lapisLazuliOreSpawnTries.ValueAsNumber)
		cd.GeneratorSettings.LapisCenterHeight = uint8(lapisLazuliOreCentreHeight.ValueAsNumber)
		cd.GeneratorSettings.LapisSpread = uint8(lapisLazuliOreSpreadHeight.ValueAsNumber)

		cd.GeneratorSettings.MainNoiseScaleX = mainNoiseScaleX.ValueAsNumber
		cd.GeneratorSettings.MainNoiseScaleY = mainNoiseScaleY.ValueAsNumber
		cd.GeneratorSettings.MainNoiseScaleZ = mainNoiseScaleZ.ValueAsNumber
		cd.GeneratorSettings.DepthNoiseScaleX = depthNoiseScaleX.ValueAsNumber
		cd.GeneratorSettings.DepthNoiseScaleZ = depthNoiseScaleZ.ValueAsNumber
		cd.GeneratorSettings.DepthNoiseScaleExponent = depthNoiseExponent.ValueAsNumber
		cd.GeneratorSettings.BaseSize = depthBaseSize.ValueAsNumber
		cd.GeneratorSettings.CoordinateScale = coordinateScale.ValueAsNumber
		cd.GeneratorSettings.HeightScale = heightScale.ValueAsNumber
		cd.GeneratorSettings.HeightStretch = heightStretch.ValueAsNumber
		cd.GeneratorSettings.UpperLimitScale = upperLimitScale.ValueAsNumber
		cd.GeneratorSettings.LowerLimitScale = lowerLimitScale.ValueAsNumber
		cd.GeneratorSettings.BiomeDepthWeight = biomeDepthWeight.ValueAsNumber
		cd.GeneratorSettings.BiomeDepthOffset = biomeDepthOffset.ValueAsNumber
		cd.GeneratorSettings.BiomeScaleWeight = biomeScaleWeight.ValueAsNumber
		cd.GeneratorSettings.BiomeScaleOffset = biomeScaleOffset.ValueAsNumber
		go func() {
			err = RPC.CreateCustomMap(cd)
			if err != nil {
				xjs.Alert("Error creating map: %s", err)
				return
			}
			o.Close()
		}()
	})

	enabler(dungeons, dungeonCount)
	enabler(waterLakes, waterLakeRarity)
	enabler(lavaLakes, lavaLakeRarity)

	xjs.AppendChildren(d,
		xform.Label("Sea Level", "sea"), seaLevel, rangeWatch(seaLevel), xdom.Br(),
		xform.Label("Caves", "caves"), caves, xdom.Br(),
		xform.Label("Strongholds", "strongholds"), strongholds, xdom.Br(),
		xform.Label("Villages", "villages"), villages, xdom.Br(),
		xform.Label("Mineshafts", "mineshafts"), mineshafts, xdom.Br(),
		xform.Label("Temples", "temples"), temples, xdom.Br(),
		xform.Label("Ocean Monuments", "oceanMonuments"), oceanMonuments, xdom.Br(),
		xform.Label("Ravines", "ravines"), ravines, xdom.Br(),
		xform.Label("Dungeons", "dungeons"), dungeons, xdom.Br(),
		xform.Label("Dungeon Count", "dungeonCount"), dungeonCount, rangeWatch(dungeonCount), xdom.Br(),
		xform.Label("Water Lakes", "waterLakes"), waterLakes, xdom.Br(),
		xform.Label("Water Lake Rarity", "waterLakeRarity"), waterLakeRarity, rangeWatch(waterLakeRarity), xdom.Br(),
		xform.Label("Lava Lakes", "lavaLakes"), lavaLakes, xdom.Br(),
		xform.Label("Lava Lake Rarity", "lavaLakeRarity"), lavaLakeRarity, rangeWatch(lavaLakeRarity), xdom.Br(),
		xform.Label("Biomes", "biomes"), biome, xdom.Br(),
		xform.Label("Biome Size", "biomeSize"), biomeSize, xdom.Br(),
		xform.Label("River Size", "riverSize"), riverSize, xdom.Br(),
		xdom.Br(),
		xjs.AppendChildren(xdom.Table(),
			xjs.AppendChildren(xdom.Tr(),
				xjs.AppendChildren(xdom.Td(),
					xform.Label("Dirt Spawn Size", "dirtSpawnSize"), dirtSpawnSize, rangeWatch(dirtSpawnSize), xdom.Br(),
					xform.Label("Dirt Spawn Tries", "dirtSpawnTries"), dirtSpawnTries, rangeWatch(dirtSpawnTries), xdom.Br(),
					xform.Label("Dirt Spawn Min Height", "dirtMinHeight"), dirtMinHeight, rangeWatch(dirtMinHeight), xdom.Br(),
					xform.Label("Dirt Spawn Max Height", "dirtMaxHeight"), dirtMaxHeight, rangeWatch(dirtMaxHeight), xdom.Br(),
				),
				xjs.AppendChildren(xdom.Td(),
					xform.Label("Gravel Spawn Size", "gravelSpawnSize"), gravelSpawnSize, rangeWatch(gravelSpawnSize), xdom.Br(),
					xform.Label("Gravel Spawn Tries", "gravelSpawnTries"), gravelSpawnTries, rangeWatch(gravelSpawnTries), xdom.Br(),
					xform.Label("Gravel Spawn Min Height", "gravelMinHeight"), gravelMinHeight, rangeWatch(gravelMinHeight), xdom.Br(),
					xform.Label("Gravel Spawn Max Height", "gravelMaxHeight"), gravelMaxHeight, rangeWatch(gravelMaxHeight), xdom.Br(),
				),
			),
			xjs.AppendChildren(xdom.Tr(),
				xjs.AppendChildren(xdom.Td(),
					xform.Label("Granite Spawn Size", "graniteSpawnSize"), graniteSpawnSize, rangeWatch(graniteSpawnSize), xdom.Br(),
					xform.Label("Granite Spawn Tries", "graniteSpawnTries"), graniteSpawnTries, rangeWatch(graniteSpawnTries), xdom.Br(),
					xform.Label("Granite Spawn Min Height", "graniteMinHeight"), graniteMinHeight, rangeWatch(graniteMinHeight), xdom.Br(),
					xform.Label("Granite Spawn Max Height", "graniteMaxHeight"), graniteMaxHeight, rangeWatch(graniteMaxHeight), xdom.Br(),
				),
				xjs.AppendChildren(xdom.Td(),
					xform.Label("Diorite Spawn Size", "dioriteSpawnSize"), dioriteSpawnSize, rangeWatch(dioriteSpawnSize), xdom.Br(),
					xform.Label("Diorite Spawn Tries", "dioriteSpawnTries"), dioriteSpawnTries, rangeWatch(dioriteSpawnTries), xdom.Br(),
					xform.Label("Diorite Spawn Min Height", "dioriteMinHeight"), dioriteMinHeight, rangeWatch(dioriteMinHeight), xdom.Br(),
					xform.Label("Diorite Spawn Max Height", "dioriteMaxHeight"), dioriteMaxHeight, rangeWatch(dioriteMaxHeight), xdom.Br(),
				),
			),
			xjs.AppendChildren(xdom.Tr(),
				xjs.AppendChildren(xdom.Td(),
					xform.Label("Andesite Spawn Size", "andesiteSpawnSize"), andesiteSpawnSize, rangeWatch(andesiteSpawnSize), xdom.Br(),
					xform.Label("Andesite Spawn Tries", "andesiteSpawnTries"), andesiteSpawnTries, rangeWatch(andesiteSpawnTries), xdom.Br(),
					xform.Label("Andesite Spawn Min Height", "andesiteMinHeight"), andesiteMinHeight, rangeWatch(andesiteMinHeight), xdom.Br(),
					xform.Label("Andesite Spawn Max Height", "andesiteMaxHeight"), andesiteMaxHeight, rangeWatch(andesiteMaxHeight), xdom.Br(),
				),
				xjs.AppendChildren(xdom.Td(),
					xform.Label("Coal Ore Spawn Size", "coalOreSpawnSize"), coalOreSpawnSize, rangeWatch(coalOreSpawnSize), xdom.Br(),
					xform.Label("Coal Ore Spawn Tries", "coalOreSpawnTries"), coalOreSpawnTries, rangeWatch(coalOreSpawnTries), xdom.Br(),
					xform.Label("Coal Ore Spawn Min Height", "coalOreMinHeight"), coalOreMinHeight, rangeWatch(coalOreMinHeight), xdom.Br(),
					xform.Label("Coal Ore Spawn Max Height", "coalOreMaxHeight"), coalOreMaxHeight, rangeWatch(coalOreMaxHeight), xdom.Br(),
				),
			),
			xjs.AppendChildren(xdom.Tr(),
				xjs.AppendChildren(xdom.Td(),
					xform.Label("Iron Ore Spawn Size", "ironOreSpawnSize"), ironOreSpawnSize, rangeWatch(ironOreSpawnSize), xdom.Br(),
					xform.Label("Iron Ore Spawn Tries", "ironOreSpawnTries"), ironOreSpawnTries, rangeWatch(ironOreSpawnTries), xdom.Br(),
					xform.Label("Iron Ore Spawn Min Height", "ironOreMinHeight"), ironOreMinHeight, rangeWatch(ironOreMinHeight), xdom.Br(),
					xform.Label("Iron Ore Spawn Max Height", "ironOreMaxHeight"), ironOreMaxHeight, rangeWatch(ironOreMaxHeight), xdom.Br(),
				),
				xjs.AppendChildren(xdom.Td(),
					xform.Label("Gold Ore Spawn Size", "goldOreSpawnSize"), goldOreSpawnSize, rangeWatch(goldOreSpawnSize), xdom.Br(),
					xform.Label("Gold Ore Spawn Tries", "goldOreSpawnTries"), goldOreSpawnTries, rangeWatch(goldOreSpawnTries), xdom.Br(),
					xform.Label("Gold Ore Spawn Min Height", "goldOreMinHeight"), goldOreMinHeight, rangeWatch(goldOreMinHeight), xdom.Br(),
					xform.Label("Gold Ore Spawn Max Height", "goldOreMaxHeight"), goldOreMaxHeight, rangeWatch(goldOreMaxHeight), xdom.Br(),
				),
			),
			xjs.AppendChildren(xdom.Tr(),
				xjs.AppendChildren(xdom.Td(),
					xform.Label("Redstone Ore Spawn Size", "redstoneOreSpawnSize"), redstoneOreSpawnSize, rangeWatch(redstoneOreSpawnSize), xdom.Br(),
					xform.Label("Redstone Ore Spawn Tries", "redstoneOreSpawnTries"), redstoneOreSpawnTries, rangeWatch(redstoneOreSpawnTries), xdom.Br(),
					xform.Label("Redstone Ore Spawn Min Height", "redstoneOreMinHeight"), redstoneOreMinHeight, rangeWatch(redstoneOreMinHeight), xdom.Br(),
					xform.Label("Redstone Ore Spawn Max Height", "redstoneOreMaxHeight"), redstoneOreMaxHeight, rangeWatch(redstoneOreMaxHeight), xdom.Br(),
				),
				xjs.AppendChildren(xdom.Td(),
					xform.Label("Diamond Ore Spawn Size", "diamondOreSpawnSize"), diamondOreSpawnSize, rangeWatch(diamondOreSpawnSize), xdom.Br(),
					xform.Label("Diamond Ore Spawn Tries", "diamondOreSpawnTries"), diamondOreSpawnTries, rangeWatch(diamondOreSpawnTries), xdom.Br(),
					xform.Label("Diamond Ore Spawn Min Height", "diamondOreMinHeight"), diamondOreMinHeight, rangeWatch(diamondOreMinHeight), xdom.Br(),
					xform.Label("Diamond Ore Spawn Max Height", "diamondOreMaxHeight"), diamondOreMaxHeight, rangeWatch(diamondOreMaxHeight), xdom.Br(),
				),
			),
			xjs.AppendChildren(xdom.Tr(),
				xjs.AppendChildren(xdom.Td(),
					xform.Label("Lapis Lazuli Ore Spawn Size", "lapisLazuliOreSpawnSize"), lapisLazuliOreSpawnSize, rangeWatch(lapisLazuliOreSpawnSize), xdom.Br(),
					xform.Label("Lapis Lazuli Ore Spawn Tries", "lapisLazuliOreSpawnTries"), lapisLazuliOreSpawnTries, rangeWatch(lapisLazuliOreSpawnTries), xdom.Br(),
					xform.Label("Lapis Lazuli Ore Centre Height", "lapisLazuliOreCentreHeight"), lapisLazuliOreCentreHeight, rangeWatch(lapisLazuliOreCentreHeight), xdom.Br(),
					xform.Label("Lapis Lazuli Ore Spread Height", "lapisLazuliOreSpreadHeight"), lapisLazuliOreSpreadHeight, rangeWatch(lapisLazuliOreSpreadHeight), xdom.Br(),
				),
			),
		),
		xform.Label("Main Noise Scale X", "mainNoiseScaleX"), mainNoiseScaleX, rangeWatch(mainNoiseScaleX), xdom.Br(),
		xform.Label("Main Noise Scale Y", "mainNoiseScaleY"), mainNoiseScaleY, rangeWatch(mainNoiseScaleY), xdom.Br(),
		xform.Label("Main Noise Scale Z", "mainNoiseScaleZ"), mainNoiseScaleZ, rangeWatch(mainNoiseScaleZ), xdom.Br(),
		xform.Label("Depth Noise Scale X", "depthNoiseScaleX"), depthNoiseScaleX, rangeWatch(depthNoiseScaleX), xdom.Br(),
		xform.Label("Depth Noise Scale Z", "depthNoiseScaleZ"), depthNoiseScaleZ, rangeWatch(depthNoiseScaleZ), xdom.Br(),
		xform.Label("Depth Noise Exponent", "depthNoiseExponent"), depthNoiseExponent, rangeWatch(depthNoiseExponent), xdom.Br(),
		xform.Label("Depth Base Size", "depthBaseSize"), depthBaseSize, rangeWatch(depthBaseSize), xdom.Br(),
		xform.Label("Coordinate Scale", "coordinateScale"), coordinateScale, rangeWatch(coordinateScale), xdom.Br(),
		xform.Label("Height Scale", "heightScale"), heightScale, rangeWatch(heightScale), xdom.Br(),
		xform.Label("Height Stretch", "heightStretch"), heightStretch, rangeWatch(heightStretch), xdom.Br(),
		xform.Label("Upper Limit Scale", "upperLimitScale"), upperLimitScale, rangeWatch(upperLimitScale), xdom.Br(),
		xform.Label("Lower Limit Scale", "lowerLimitScale"), lowerLimitScale, rangeWatch(lowerLimitScale), xdom.Br(),
		xform.Label("Biome Depth Weight", "biomeDepthWeight"), biomeDepthWeight, rangeWatch(biomeDepthWeight), xdom.Br(),
		xform.Label("Biome Depth Offset", "biomeDepthOffset"), biomeDepthOffset, rangeWatch(biomeDepthOffset), xdom.Br(),
		xform.Label("Biome Scale Weight", "biomeDepthWeight"), biomeScaleWeight, rangeWatch(biomeScaleWeight), xdom.Br(),
		xform.Label("Biome Scale Offset", "biomeDepthOffset"), biomeScaleOffset, rangeWatch(biomeScaleOffset), xdom.Br(),
		submit,
	)

	return func(c dom.Element) {
		c.AppendChild(d)
	}
}