コード例 #1
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,
	)))
}
コード例 #2
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
			}()
		})
	}
}
コード例 #3
0
ファイル: maps.go プロジェクト: MJKWoolnough/minewebgen
func rangeWatch(r *dom.HTMLInputElement) dom.Element {
	s := xdom.Span()
	xjs.SetInnerText(s, r.Value)
	r.AddEventListener("input", false, func(dom.Event) {
		xjs.SetInnerText(s, r.Value)
	})
	return s
}
コード例 #4
0
ファイル: generators.go プロジェクト: MJKWoolnough/minewebgen
func GeneratorsTab(c dom.Element) {
	go func() {
		xjs.RemoveChildren(c)
		gs, err := RPC.Generators()
		if err != nil {
			xjs.Alert("Error getting generator list: %s", err)
			return
		}
		ng := xdom.Button()
		xjs.SetInnerText(ng, "New Generator")
		ng.AddEventListener("click", false, func(dom.Event) {
			d := xdom.Div()
			o := overlay.New(d)
			o.OnClose(func() {
				GeneratorsTab(c)
			})
			d.AppendChild(transferFile("Map", "Upload/Download", 3, o))
			xjs.Body().AppendChild(o)
		})
		table := xjs.AppendChildren(xdom.Table(), xjs.AppendChildren(xdom.Tr(), xjs.SetInnerText(xdom.Th(), "Generator")))
		if len(gs) == 0 {
			table.AppendChild(xjs.AppendChildren(xdom.Tr(), xjs.SetInnerText(xdom.Td(), "No Generators")))
		} else {
			for _, g := range gs {
				td := xdom.Td()
				td.AddEventListener("click", false, func(g data.Generator) func(dom.Event) {
					return func(dom.Event) {
						d := xdom.Div()
						o := overlay.New(d)
						o.OnClose(func() {
							GeneratorsTab(c)
						})
						d.AppendChild(tabs.New([]tabs.Tab{
							{"Profile", generatorProfile(g.ID)},
							{"Misc", misc("generator", g.ID, o, RPC.RemoveGenerator)},
						}))
						xjs.Body().AppendChild(o)
					}
				}(g))
				table.AppendChild(xjs.AppendChildren(xdom.Tr(), xjs.SetInnerText(td, g.Name)))
			}
		}
		xjs.AppendChildren(c,
			xjs.SetInnerText(xdom.H2(), "Generators"),
			ng,
			table,
		)
	}()
}
コード例 #5
0
ファイル: main.go プロジェクト: MJKWoolnough/minewebgen
func SetTitle(title string) {
	title += " Server"
	xjs.SetInnerText(dom.GetWindow().Document().(dom.HTMLDocument).Body().ChildNodes()[0], title)
	tDoc, ok := dom.GetWindow().Document().(dom.HTMLDocument)
	if ok {
		tDoc.SetTitle(title)
	}
}
コード例 #6
0
ファイル: style.go プロジェクト: MJKWoolnough/gopherjs
// Add adds the given CSS string to the DOM
func Add(css string) dom.Element {
	h := dom.GetWindow().Document().GetElementsByTagName("head")
	if len(h) == 0 {
		return nil
	}
	s := xdom.Style()
	h[0].AppendChild(xjs.SetInnerText(s, css))
	return s
}
コード例 #7
0
ファイル: utils.go プロジェクト: MJKWoolnough/minewebgen
func misc(mType string, id int, o *overlay.Overlay, deleteFunc func(int) error) func(dom.Element) {
	return func(c dom.Element) {
		download := xdom.A()
		download.Href = "http://" + js.Global.Get("location").Get("host").String() + "/download/" + mType + "/" + strconv.Itoa(id) + ".zip"
		download.Target = "_blank"
		del := xdom.Button()
		del.AddEventListener("click", false, func(dom.Event) {
			del.Disabled = true
			if dom.GetWindow().Confirm("Are you sure?") {
				go func() {
					err := deleteFunc(id)
					if err != nil {
						del.Disabled = false
						xjs.Alert("Error while deleting %s: %s", mType, err)
					} else {
						o.Close()
					}
				}()
			}
		})
		xjs.AppendChildren(c,
			xjs.AppendChildren(xdom.Fieldset(),
				xjs.SetInnerText(xdom.Legend(), "Download"),
				xjs.SetInnerText(xdom.Div(), "Click the following link to download the "+mType+" as a zip file."),
				xjs.SetInnerText(download, download.Href),
			),
			xjs.AppendChildren(xdom.Fieldset(),
				xjs.SetInnerText(xdom.Legend(), "Delete"),
				xjs.SetInnerText(xdom.Div(), "The following button will permanently delete the "+mType+" (this cannot be undone)."),
				xjs.SetInnerText(del, "Delete "+mType),
			),
		)
	}
}
コード例 #8
0
ファイル: rpc.go プロジェクト: MJKWoolnough/minewebgen
func rpcInit() error {
	conn, err := websocket.Dial("ws://" + js.Global.Get("location").Get("host").String() + "/rpc")
	if err != nil {
		return err
	}
	conn.WebSocket.Call("addEventListener", "close", func(*js.Object) {
		xjs.RemoveChildren(xdom.Body()).AppendChild(xjs.SetInnerText(xdom.H1(), "Connection Lost"))
	}, false)
	dom.GetWindow().AddEventListener("beforeunload", false, func(dom.Event) {
		switch conn.ReadyState {
		case websocket.Connecting, websocket.Open:
			conn.Close()
		}
	})
	RPC = jRPC{jsonrpc.NewClient(conn)}
	return nil
}
コード例 #9
0
ファイル: tabs.go プロジェクト: MJKWoolnough/gopherjs
// New takes a list of tabs and generates a tabbed interface, which is return as a document fragment
func New(t []Tab) dom.Node {
	f := xdom.DocumentFragment()
	if len(t) < 0 {
		return f
	}
	tabsDiv := xdom.Div()
	contents := xdom.Div()
	tabsDiv.Class().SetString("tabs")
	contents.Class().SetString("content")
	tabs := make([]dom.Element, len(t))
	for n := range t {
		tabs[n] = xjs.SetInnerText(xdom.Div(), t[n].Name).(dom.Element)
		tabs[n].AddEventListener("click", false, func() func(dom.Event) {
			i := n
			return func(e dom.Event) {
				if tabs[i].Class().String() == "selected" {
					return
				}
				for _, tab := range tabs {
					tab.Class().Remove("selected")
				}
				newContents := contents.CloneNode(false).(*dom.HTMLDivElement)
				contents.ParentNode().ReplaceChild(newContents, contents)
				contents = newContents
				tabs[i].Class().Add("selected")
				go t[i].Func(contents)
			}
		}())
		tabsDiv.AppendChild(tabs[n])
	}
	go t[0].Func(contents)
	tabs[0].Class().Add("selected")
	f.AppendChild(tabsDiv)
	f.AppendChild(contents)
	return f
}
コード例 #10
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
}
コード例 #11
0
ファイル: utils.go プロジェクト: MJKWoolnough/minewebgen
func editProperties(c dom.Element, name string, id int, rpcGet func(int) (map[string]string, error), rpcSet func(id int, properties map[string]string) error) {
	sp, err := rpcGet(id)
	if err != nil {
		c.AppendChild(xjs.SetInnerText(xdom.Div(), "Failed to get properties: "+err.Error()))
		return
	}
	props := make(PropertyList, 0, len(sp))
	for k, v := range sp {
		props = append(props, [2]string{k, v})
	}
	sort.Sort(props)
	propE := make([][2]*dom.HTMLSpanElement, len(props))
	df := xjs.DocumentFragment()

	toggleFunc := func(k, v *dom.HTMLSpanElement, toggle *dom.HTMLInputElement) func(dom.Event) {
		return func(dom.Event) {
			if toggle.Value == "-" {
				k.SetContentEditable("false")
				v.SetContentEditable("false")
				k.Style().SetProperty("background-color", "#888", "")
				v.Style().SetProperty("background-color", "#888", "")
				toggle.Value = "+"
			} else {
				k.SetContentEditable("true")
				v.SetContentEditable("true")
				k.Style().RemoveProperty("background-color")
				v.Style().RemoveProperty("background-color")
				toggle.Value = "-"
			}
		}
	}

	for i, prop := range props {
		k := xform.InputSizeable("", prop[0])
		v := xform.InputSizeable("", prop[1])
		toggle := xform.InputButton("", "-")
		toggle.AddEventListener("click", false, toggleFunc(k, v, toggle))
		propE[i][0] = k
		propE[i][1] = v
		xjs.AppendChildren(df,
			toggle,
			k,
			xjs.SetInnerText(xdom.Span(), "="),
			v,
			xdom.Br(),
		)
	}

	add := xform.InputButton("", "Add")
	submit := xform.InputButton("", "Save")
	fs := xjs.AppendChildren(xdom.Fieldset(),
		xjs.SetInnerText(xdom.Legend(), name+" Properties"),
		df,
		add,
		submit,
	)

	add.AddEventListener("click", false, func(dom.Event) {
		k := xform.InputSizeable("", "")
		v := xform.InputSizeable("", "")
		toggle := xform.InputButton("", "-")
		toggle.AddEventListener("click", false, toggleFunc(k, v, toggle))
		propE = append(propE, [2]*dom.HTMLSpanElement{k, v})
		fs.InsertBefore(toggle, add)
		fs.InsertBefore(k, add)
		fs.InsertBefore(xjs.SetInnerText(xdom.Span(), "="), add)
		fs.InsertBefore(v, add)
		fs.InsertBefore(xdom.Br(), add)
	})

	submit.AddEventListener("click", false, func(dom.Event) {
		submit.Disabled = true
		props := make(map[string]string, len(propE))
		for _, spans := range propE {
			if spans[0].IsContentEditable() {
				props[spans[0].TextContent()] = spans[1].TextContent()
			}
		}
		go func() {
			err := rpcSet(id, props)
			if err != nil {
				xjs.Alert("Error setting "+name+" properties: %s", err)
				return
			}
			span := xdom.Span()
			span.Style().Set("color", "#f00")
			fs.AppendChild(xjs.SetInnerText(span, "Saved!"))
			time.Sleep(5 * time.Second)
			fs.RemoveChild(span)
			submit.Disabled = false
		}()
	})

	xjs.AppendChildren(c, xjs.AppendChildren(xdom.Form(), fs))
}
コード例 #12
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"))
				}
			}
		}()
	}
}
コード例 #13
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,
			))
		}()
	}
}
コード例 #14
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,
			))
		}()
	}
}
コード例 #15
0
ファイル: maps.go プロジェクト: MJKWoolnough/minewebgen
func MapsTab() func(dom.Element) {
	forceUpdate := make(chan struct{})
	nm := xdom.Button()
	nm.AddEventListener("click", false, func(dom.Event) {
		d := xdom.Div()
		o := overlay.New(d)
		o.OnClose(func() {
			go func() {
				forceUpdate <- struct{}{}
			}()
		})
		xjs.AppendChildren(d,
			xjs.SetInnerText(xdom.H1(), "New Map"),
			tabs.New([]tabs.Tab{
				{"Create", createMap(o)},
				{"Upload/Download", func(c dom.Element) {
					c.AppendChild(transferFile("Map", "Upload/Download", 1, o))
				}},
				{"Generate", func(c dom.Element) {
					c.AppendChild(transferFile("Map", "Generate", 2, o))
				}},
			}),
		)
		xjs.Body().AppendChild(o)
	})
	noneTd := xdom.Td()
	noneTd.ColSpan = 2
	none := xjs.AppendChildren(xdom.Tr(), xjs.SetInnerText(noneTd, "No Maps Found"))
	mapList := xjs.AppendChildren(xdom.Table(),
		xjs.AppendChildren(xdom.Thead(), xjs.AppendChildren(xdom.Tr(),
			xjs.SetInnerText(xdom.Th(), "Map Name"),
			xjs.SetInnerText(xdom.Th(), "Status"),
		)),
		none,
	)
	nodes := xjs.AppendChildren(xdom.Div(),
		xjs.SetInnerText(xdom.H2(), "Maps"),
		xjs.SetInnerText(nm, "New Map"),
		mapList,
	)

	maps := make(map[int]*Map)
	return func(c dom.Element) {
		c.AppendChild(nodes)
		updateStop := make(chan struct{})
		registerUpdateStopper(c, updateStop)
		for {
			mps, err := RPC.MapList()
			if err != nil {
				xjs.Alert("Error getting map list: %s", err)
				return
			}

			if none.ParentNode() != nil {
				mapList.RemoveChild(none)
			}

			for _, m := range maps {
				m.ID = -1
			}

			for _, m := range mps {
				om, ok := maps[m.ID]
				if ok {
					om.Map = m
				} else {
					name := xdom.Td()
					status := xdom.Td()
					om = &Map{
						Map: m,
						row: xjs.AppendChildren(xdom.Tr(),
							name,
							status,
						),
						name:   name,
						status: status,
					}
					maps[m.ID] = om
					mapList.AppendChild(om.row)
					name.Class().SetString("mapName")
					name.AddEventListener("click", false, func() func(dom.Event) {
						m := om
						return func(dom.Event) {
							div := xdom.Div()
							o := overlay.New(div)
							div.AppendChild(tabs.New([]tabs.Tab{
								{"General", mapGeneral(m.Map)},
								{"Properties", mapProperties(m.Map)},
								{"Misc.", misc("map", m.Map.ID, o, RPC.RemoveMap)},
							}))
							o.OnClose(func() {
								go func() {
									forceUpdate <- struct{}{}
								}()
							})
							xjs.Body().AppendChild(o)
						}
					}())
				}
				switch om.Server {
				case -2:
					xjs.SetInnerText(om.status, "Busy")
					om.status.Style().SetProperty("color", "#f00", "")
				case -1:
					xjs.SetInnerText(om.status, "Unassigned")
					om.status.Style().SetProperty("color", "#00f", "")
				default:
					serv, err := RPC.Server(om.Server)
					if err == nil {
						xjs.SetInnerText(om.status, "Assigned")
					} else {
						xjs.SetInnerText(om.status, "Assigned - "+serv.Name)
					}
					om.status.Style().SetProperty("color", "#000", "")
				}
				xjs.SetInnerText(om.name, om.Name)
			}

			for id, m := range maps {
				if m.ID == -1 {
					delete(maps, id)
					mapList.RemoveChild(m.row)
				}
			}

			if len(maps) == 0 {
				mapList.AppendChild(none)
			}

			// Sleep until update
			if !updateSleep(forceUpdate, updateStop) {
				return
			}
		}
	}
}
コード例 #16
0
ファイル: maps.go プロジェクト: MJKWoolnough/minewebgen
func createMap(o *overlay.Overlay) func(dom.Element) {
	return func(c dom.Element) {
		name := xform.InputText("name", "")
		name.Required = true
		gmOpts := make([]xform.Option, len(gameModes))
		for i, m := range gameModes {
			gmOpts[i] = xform.Option{
				Label: m,
				Value: strconv.Itoa(i),
			}
		}
		gameMode := xform.SelectBox("gamemode", gmOpts...)
		seed := xform.InputText("seed", "")
		structures := xform.InputCheckbox("structures", true)
		cheats := xform.InputCheckbox("cheats", false)
		fs := xdom.Fieldset()
		fs.AppendChild(xjs.SetInnerText(xdom.Legend(), "Create Map"))
		c.AppendChild(xjs.AppendChildren(xdom.Form(), fs))
		dataParser := func(mode int) func() (data.DefaultMap, error) {
			return func() (data.DefaultMap, error) {
				data := data.DefaultMap{
					Mode: mode,
				}
				var err error
				data.Name = name.Value
				si := gameMode.SelectedIndex
				if si < 0 || si >= len(gameModes) {
					return data, errors.New("invalid gamemode")
				}
				if seed.Value == "" {
					seed.Value = "0"
				}
				data.Seed, err = strconv.ParseInt(seed.Value, 10, 64)
				if err != nil {
					return data, err
				}
				data.Structures = structures.Checked
				data.Cheats = cheats.Checked
				return data, nil
			}
		}
		xjs.AppendChildren(fs,
			xform.Label("Name", "name"),
			name,
			xdom.Br(),
			xform.Label("Game Mode", "gamemode"),
			gameMode,
			xdom.Br(),
			xform.Label("Level Seed", "seed"),
			seed,
			xdom.Br(),
			xform.Label("Structures", "structures"),
			structures,
			xdom.Br(),
			xform.Label("Cheats", "cheats"),
			cheats,
			xdom.Br(),
			tabs.New([]tabs.Tab{
				{"Default", createMapMode(0, o, dataParser(0))},
				{"Super Flat", createSuperFlatMap(o, dataParser(1))},
				{"Large Biomes", createMapMode(2, o, dataParser(2))},
				{"Amplified", createMapMode(3, o, dataParser(3))},
				{"Customised", createCustomisedMap(o, dataParser(4))},
			}),
		)
	}
}
コード例 #17
0
ファイル: generators.go プロジェクト: MJKWoolnough/minewebgen
func generatorProfile(id int) func(dom.Element) {
	var d dom.Node
	return func(c dom.Element) {
		if d == nil {
			g, err := RPC.Generator(id)
			if err != nil {
				xjs.Alert("Error while getting generator settings: %s", err)
				return
			}
			tTable := xjs.AppendChildren(xdom.Table(), xjs.AppendChildren(xdom.Thead(), xjs.AppendChildren(xdom.Tr(),
				xjs.SetInnerText(xdom.Th(), "Colour"),
				xjs.SetInnerText(xdom.Th(), "Colour Code"),
				xjs.SetInnerText(xdom.Th(), "Name"),
			)))
			for _, t := range g.Terrain {
				colour := xdom.Td()
				cc := fmt.Sprintf("rgb(%d, %d, %d)", t.Colour.R, t.Colour.G, t.Colour.B)
				colour.Style().SetProperty("background-color", cc, "")
				colour.Style().SetProperty("border", "1px solid #000", "")
				tTable.AppendChild(xjs.AppendChildren(xdom.Tr(),
					colour,
					xjs.SetInnerText(xdom.Td(), cc),
					xjs.SetInnerText(xdom.Td(), t.Name),
				))
			}
			bTable := xjs.AppendChildren(xdom.Table(), xjs.AppendChildren(xdom.Thead(), xjs.AppendChildren(xdom.Tr(),
				xjs.SetInnerText(xdom.Th(), "Colour"),
				xjs.SetInnerText(xdom.Th(), "Colour Code"),
				xjs.SetInnerText(xdom.Th(), "Name"),
			)))
			for _, b := range g.Biomes {
				colour := xdom.Td()
				cc := fmt.Sprintf("rgb(%d, %d, %d)", b.Colour.R, b.Colour.G, b.Colour.B)
				colour.Style().SetProperty("background-color", cc, "")
				colour.Style().SetProperty("border", "1px solid #000", "")
				bTable.AppendChild(xjs.AppendChildren(xdom.Tr(),
					colour,
					xjs.SetInnerText(xdom.Td(), cc),
					xjs.SetInnerText(xdom.Td(), b.Name),
				))
			}
			pTable := xjs.AppendChildren(xdom.Table(), xjs.AppendChildren(xdom.Thead(), xjs.AppendChildren(xdom.Tr(),
				xjs.SetInnerText(xdom.Th(), "Colour"),
				xjs.SetInnerText(xdom.Th(), "Colour Code"),
				xjs.SetInnerText(xdom.Th(), "Name"),
			)))
			for _, p := range g.Plants {
				colour := xdom.Td()
				cc := fmt.Sprintf("rgb(%d, %d, %d)", p.Colour.R, p.Colour.G, p.Colour.B)
				colour.Style().SetProperty("background-color", cc, "")
				colour.Style().SetProperty("border", "1px solid #000", "")
				pTable.AppendChild(xjs.AppendChildren(xdom.Tr(),
					colour,
					xjs.SetInnerText(xdom.Td(), cc),
					xjs.SetInnerText(xdom.Td(), p.Name),
				))
			}
			d = xjs.AppendChildren(xdom.Div(),
				xjs.SetInnerText(xdom.H2(), "Terrain"),
				tTable,
				xjs.SetInnerText(xdom.H2(), "Biomes"),
				bTable,
				xjs.SetInnerText(xdom.H2(), "Plants"),
				pTable,
			)
		}
		c.AppendChild(d)
	}
}
コード例 #18
0
ファイル: servers.go プロジェクト: MJKWoolnough/minewebgen
func ServersTab() func(dom.Element) {
	forceUpdate := make(chan struct{})
	ns := xdom.Button()
	ns.AddEventListener("click", false, func(dom.Event) {
		d := xdom.Div()
		o := overlay.New(d)
		d.AppendChild(transferFile("Server", "Upload/Download", 0, o))
		o.OnClose(func() {
			go func() {
				forceUpdate <- struct{}{}
			}()
		})
		xjs.Body().AppendChild(o)
	})
	noneTd := xdom.Td()
	noneTd.ColSpan = 3
	none := xjs.AppendChildren(xdom.Tr(), xjs.SetInnerText(noneTd, "No Servers Found"))
	serverList := xjs.AppendChildren(xdom.Table(),
		xjs.AppendChildren(xdom.Thead(), xjs.AppendChildren(xdom.Tr(),
			xjs.SetInnerText(xdom.Th(), "Server Name"),
			xjs.SetInnerText(xdom.Th(), "Status"),
			xjs.SetInnerText(xdom.Th(), "Controls"),
		)),
		none,
	)
	nodes := xjs.AppendChildren(xdom.Div(),
		xjs.SetInnerText(xdom.H2(), "Servers"),
		xjs.SetInnerText(ns, "New Server"),
		serverList,
	)
	servers := make(map[int]*Server)

	return func(c dom.Element) {
		c.AppendChild(nodes)
		updateStop := make(chan struct{})
		registerUpdateStopper(c, updateStop)
		for {
			servs, err := RPC.ServerList()
			if err != nil {
				xjs.Alert("Error getting server list: %s", err)
				return
			}

			if none.ParentNode() != nil {
				serverList.RemoveChild(none)
			}

			for _, s := range servers {
				s.ID = -1
			}

			for _, s := range servs {
				os, ok := servers[s.ID]
				if ok {
					os.Server = s
				} else {
					name := xdom.Td()
					status := xdom.Td()
					startStop := xdom.Button()
					os = &Server{
						Server: s,
						row: xjs.AppendChildren(xdom.Tr(),
							name,
							status,
							xjs.AppendChildren(xdom.Td(), startStop),
						),
						name:   name,
						status: status,
						button: startStop,
					}
					servers[s.ID] = os
					serverList.AppendChild(os.row)
					name.Class().SetString("serverName")
					name.AddEventListener("click", false, func() func(dom.Event) {
						s := os
						return func(dom.Event) {
							go func() {
								d, err := RPC.ServerEULA(s.ID)
								if err != nil {
									d = ""
								}
								t := []tabs.Tab{
									{"General", serverGeneral(s.Server)},
									{"Properties", serverProperties(s.Server)},
									{"Console", serverConsole(s.Server)},
								}
								if d != "" {
									t = append(t, tabs.Tab{"EULA", serverEULA(s.Server, d)})
								}
								div := xdom.Div()
								o := overlay.New(div)
								t = append(t, tabs.Tab{"Misc.", misc("server", s.Server.ID, o, RPC.RemoveServer)})
								div.AppendChild(tabs.New(t))
								o.OnClose(func() {
									go func() {
										forceUpdate <- struct{}{}
									}()
								})
								xjs.Body().AppendChild(o)
							}()

						}
					}())
					startStop.AddEventListener("click", false, func() func(dom.Event) {
						b := startStop
						s := os
						return func(dom.Event) {
							go func() {
								b.Disabled = true
								switch s.State {
								case data.StateStopped:
									err := RPC.StartServer(s.ID)
									if err != nil {
										xjs.Alert("Error starting server: %s", err)
										return
									}
								case data.StateRunning:
									err := RPC.StopServer(s.ID)
									if err != nil {
										xjs.Alert("Error stopping server: %s", err)
										return
									}
								default:
									return
								}
								go func() {
									forceUpdate <- struct{}{}
								}()
							}()
						}
					}())
				}
				if os.Map >= 0 {
					xjs.SetInnerText(os.status, os.State.String())
					switch os.State {
					case data.StateStopped:
						xjs.SetInnerText(os.button, "Start")
						os.button.Disabled = false
					case data.StateRunning:
						xjs.SetInnerText(os.button, "Stop")
						os.button.Disabled = false
					default:
						xjs.SetInnerText(os.button, "N/A")
						os.button.Disabled = true
					}
				} else {
					xjs.SetInnerText(os.status, "No Map")
					os.button.Disabled = true
					xjs.SetInnerText(os.button, "N/A")
				}
				xjs.SetInnerText(os.name, os.Name)
			}

			for id, s := range servers {
				if s.ID == -1 {
					delete(servers, id)
					serverList.RemoveChild(s.row)
				}
			}

			if len(servers) == 0 {
				serverList.AppendChild(none)
			}

			// Sleep until update
			if !updateSleep(forceUpdate, updateStop) {
				return
			}
		}
	}
}