Convert to templates

Signed-off-by: jolheiser <john.olheiser@gmail.com>
This commit is contained in:
jolheiser
2021-08-06 14:05:10 -05:00
parent ba26dc6adc
commit 782f70ba21
10 changed files with 21461 additions and 4677 deletions

File diff suppressed because it is too large Load Diff

View File

@ -6,147 +6,17 @@ package main
import ( import (
"encoding/json" "encoding/json"
"fmt" "fmt"
"go/ast"
"go/format"
"go/token"
"net/http" "net/http"
"os" "os"
"reflect" "text/template"
"strconv"
"github.com/iancoleman/strcase" "github.com/iancoleman/strcase"
) )
const ( const (
infoURL = "https://raw.githubusercontent.com/PrismarineJS/minecraft-data/master/data/pc/1.17/blocks.json" infoURL = "https://raw.githubusercontent.com/PrismarineJS/minecraft-data/master/data/pc/1.17/blocks.json"
) //language=gohtml
blockTmpl = `// Code generated by gen_block.go; DO NOT EDIT.
type Block struct {
ID uint32 `json:"id"`
DisplayName string `json:"displayName"`
Name string `json:"name"`
Hardness float64 `json:"hardness"`
Diggable bool `json:"diggable"`
DropIDs []uint32 `json:"drops"`
NeedsTools map[uint32]bool `json:"harvestTools"`
MinStateID uint32 `json:"minStateId"`
MaxStateID uint32 `json:"maxStateId"`
Transparent bool `json:"transparent"`
FilterLightLevel int `json:"filterLight"`
EmitLightLevel int `json:"emitLight"`
}
func downloadInfo() ([]Block, error) {
resp, err := http.Get(infoURL)
if err != nil {
return nil, err
}
defer resp.Body.Close()
var data []Block
if err := json.NewDecoder(resp.Body).Decode(&data); err != nil {
return nil, err
}
return data, nil
}
func makeBlockDeclaration(blocks []Block) *ast.DeclStmt {
out := &ast.DeclStmt{Decl: &ast.GenDecl{Tok: token.VAR}}
for _, b := range blocks {
t := reflect.TypeOf(b)
fields := make([]ast.Expr, t.NumField())
for i := 0; i < t.NumField(); i++ {
ft := t.Field(i)
var val ast.Expr
switch ft.Type.Kind() {
case reflect.Uint32, reflect.Int:
val = &ast.BasicLit{Kind: token.INT, Value: fmt.Sprint(reflect.ValueOf(b).Field(i))}
case reflect.Float64:
val = &ast.BasicLit{Kind: token.FLOAT, Value: fmt.Sprint(reflect.ValueOf(b).Field(i))}
case reflect.String:
val = &ast.BasicLit{Kind: token.STRING, Value: strconv.Quote(reflect.ValueOf(b).Field(i).String())}
case reflect.Bool:
val = &ast.BasicLit{Kind: token.IDENT, Value: fmt.Sprint(reflect.ValueOf(b).Field(i).Bool())}
case reflect.Slice:
val = &ast.CompositeLit{
Type: &ast.ArrayType{
Elt: &ast.BasicLit{Kind: token.IDENT, Value: ft.Type.Elem().Name()},
},
}
v := reflect.ValueOf(b).Field(i)
switch ft.Type.Elem().Kind() {
case reflect.Uint32, reflect.Int:
for x := 0; x < v.Len(); x++ {
val.(*ast.CompositeLit).Elts = append(val.(*ast.CompositeLit).Elts, &ast.BasicLit{
Kind: token.INT,
Value: fmt.Sprint(v.Index(x)),
})
}
}
case reflect.Map:
// Must be the NeedsTools map of type map[uint32]bool.
m := &ast.CompositeLit{
Type: &ast.MapType{
Key: &ast.BasicLit{Kind: token.IDENT, Value: ft.Type.Key().Name()},
Value: &ast.BasicLit{Kind: token.IDENT, Value: ft.Type.Elem().Name()},
},
}
iter := reflect.ValueOf(b).Field(i).MapRange()
for iter.Next() {
m.Elts = append(m.Elts, &ast.KeyValueExpr{
Key: &ast.BasicLit{Kind: token.INT, Value: fmt.Sprint(iter.Key().Uint())},
Value: &ast.BasicLit{Kind: token.IDENT, Value: fmt.Sprint(iter.Value().Bool())},
})
}
val = m
}
fields[i] = &ast.KeyValueExpr{
Key: &ast.Ident{Name: ft.Name},
Value: val,
}
}
out.Decl.(*ast.GenDecl).Specs = append(out.Decl.(*ast.GenDecl).Specs, &ast.ValueSpec{
Names: []*ast.Ident{{Name: strcase.ToCamel(b.Name)}},
Values: []ast.Expr{
&ast.CompositeLit{
Type: &ast.Ident{Name: reflect.TypeOf(b).Name()},
Elts: fields,
},
},
})
}
return out
}
//go:generate go run $GOFILE
//go:generate go fmt block.go
func main() {
blocks, err := downloadInfo()
if err != nil {
fmt.Fprintf(os.Stderr, "Error: %v\n", err)
os.Exit(1)
}
f, err := os.Create("block.go")
if err != nil {
fmt.Fprintf(os.Stderr, "Error: %v\n", err)
os.Exit(1)
}
defer f.Close()
fmt.Fprintln(f, `// Code generated by gen_blocks.go; DO NOT EDIT.
// Package block stores information about blocks in Minecraft. // Package block stores information about blocks in Minecraft.
package block package block
@ -181,29 +51,100 @@ type Block struct {
EmitLightLevel int EmitLightLevel int
} }
`) var (
format.Node(f, token.NewFileSet(), makeBlockDeclaration(blocks)) {{- range .}}
{{.CamelName}} = Block{
ID: {{.ID}},
DisplayName: "{{.DisplayName}}",
Name: "{{.Name}}",
Hardness: {{.Hardness}},
Diggable: {{.Diggable}},
DropIDs: []uint32{ {{- range .DropIDs}}{{.}},{{end -}} },
NeedsTools: map[uint32]bool{ {{- range $key, $val := .NeedsTools}}{{$key}}: {{$val}},{{end -}} },
MinStateID: {{.MinStateID}},
MaxStateID: {{.MaxStateID}},
Transparent: {{.Transparent}},
FilterLightLevel: {{.FilterLightLevel}},
EmitLightLevel: {{.EmitLightLevel}},
}{{end}}
)
fmt.Fprintln(f) // ByID is an index of minecraft blocks by their ID.
fmt.Fprintln(f) var ByID = map[ID]*Block{ {{range .}}
fmt.Fprintln(f, "// ByID is an index of minecraft blocks by their ID.") {{.ID}}: &{{.CamelName}},{{end}}
fmt.Fprintln(f, "var ByID = map[ID]*Block{") }
for _, b := range blocks {
fmt.Fprintf(f, " %d: &%s,\n", b.ID, strcase.ToCamel(b.Name)) // StateID maps all possible state IDs to a corresponding block ID.
} var StateID = map[uint32]ID{ {{range $block := .}}
fmt.Fprintln(f, "}") {{- range .States}}
{{.}}: {{$block.ID}},
fmt.Fprintln(f) {{- end}}{{end}}
fmt.Fprintln(f, "// StateID maps all possible state IDs to a corresponding block ID.") }`
fmt.Fprintln(f, "var StateID = map[uint32]ID{") )
for _, b := range blocks {
if b.MinStateID == b.MaxStateID { type Block struct {
fmt.Fprintf(f, " %d: %d,\n", b.MinStateID, b.ID) ID uint32 `json:"id"`
} else { CamelName string `json:"-"`
for i := b.MinStateID; i <= b.MaxStateID; i++ { DisplayName string `json:"displayName"`
fmt.Fprintf(f, " %d: %d,\n", i, b.ID) Name string `json:"name"`
}
} Hardness float64 `json:"hardness"`
} Diggable bool `json:"diggable"`
fmt.Fprintln(f, "}") DropIDs []uint32 `json:"drops"`
NeedsTools map[uint32]bool `json:"harvestTools"`
MinStateID uint32 `json:"minStateId"`
MaxStateID uint32 `json:"maxStateId"`
Transparent bool `json:"transparent"`
FilterLightLevel int `json:"filterLight"`
EmitLightLevel int `json:"emitLight"`
}
func (b Block) States() []uint32 {
if b.MinStateID == b.MaxStateID {
return []uint32{b.MinStateID}
}
states := make([]uint32, 0)
for i := b.MinStateID; i <= b.MaxStateID; i++ {
states = append(states, i)
}
return states
}
func downloadInfo() ([]*Block, error) {
resp, err := http.Get(infoURL)
if err != nil {
return nil, err
}
defer resp.Body.Close()
var data []*Block
if err := json.NewDecoder(resp.Body).Decode(&data); err != nil {
return nil, err
}
for _, d := range data {
d.CamelName = strcase.ToCamel(d.Name)
}
return data, nil
}
//go:generate go run $GOFILE
//go:generate go fmt block.go
func main() {
fmt.Println("generating block.go")
blocks, err := downloadInfo()
if err != nil {
panic(err)
}
f, err := os.Create("block.go")
if err != nil {
panic(err)
}
defer f.Close()
if err := template.Must(template.New("").Parse(blockTmpl)).Execute(f, blocks); err != nil {
panic(err)
}
} }

File diff suppressed because it is too large Load Diff

View File

@ -6,24 +6,56 @@ package main
import ( import (
"encoding/json" "encoding/json"
"fmt" "fmt"
"go/ast"
"go/format"
"go/token"
"net/http" "net/http"
"os" "os"
"reflect" "text/template"
"strconv"
"github.com/iancoleman/strcase" "github.com/iancoleman/strcase"
) )
const ( const (
infoURL = "https://raw.githubusercontent.com/PrismarineJS/minecraft-data/master/data/pc/1.17/entities.json" infoURL = "https://raw.githubusercontent.com/PrismarineJS/minecraft-data/master/data/pc/1.17/entities.json"
//language=gohtml
entityTmpl = `// Code generated by gen_entity.go DO NOT EDIT.
// Package entity stores information about entities in Minecraft.
package entity
// ID describes the numeric ID of an entity.
type ID uint32
// Entity describes information about a type of entity.
type Entity struct {
ID ID
InternalID uint32
DisplayName string
Name string
Width float64
Height float64
Type string
}
var (
{{- range .}}
{{.CamelName}} = Entity{
ID: {{.ID}},
InternalID: {{.InternalID}},
DisplayName: "{{.DisplayName}}",
Name: "{{.Name}}",
Width: {{.Width}},
Height: {{.Height}},
Type: "{{.Type}}",
}{{end}}
)
// ByID is an index of minecraft entities by their ID.
var ByID = map[ID]*Entity{ {{range .}}
{{.ID}}: &{{.CamelName}},{{end}}
}`
) )
type Entity struct { type Entity struct {
ID uint32 `json:"id"` ID uint32 `json:"id"`
InternalID uint32 `json:"internalId"` InternalID uint32 `json:"internalId"`
CamelName string `json:"-"`
DisplayName string `json:"displayName"` DisplayName string `json:"displayName"`
Name string `json:"name"` Name string `json:"name"`
@ -33,121 +65,39 @@ type Entity struct {
Type string `json:"type"` Type string `json:"type"`
} }
func downloadInfo() ([]Entity, error) { func downloadInfo() ([]*Entity, error) {
resp, err := http.Get(infoURL) resp, err := http.Get(infoURL)
if err != nil { if err != nil {
return nil, err return nil, err
} }
defer resp.Body.Close() defer resp.Body.Close()
var data []Entity var data []*Entity
if err := json.NewDecoder(resp.Body).Decode(&data); err != nil { if err := json.NewDecoder(resp.Body).Decode(&data); err != nil {
return nil, err return nil, err
} }
for _, d := range data {
d.CamelName = strcase.ToCamel(d.Name)
}
return data, nil return data, nil
} }
func makeEntityDeclaration(entities []Entity) *ast.DeclStmt {
out := &ast.DeclStmt{Decl: &ast.GenDecl{Tok: token.VAR}}
for _, e := range entities {
t := reflect.TypeOf(e)
fields := make([]ast.Expr, t.NumField())
for i := 0; i < t.NumField(); i++ {
ft := t.Field(i)
var val ast.Expr
switch ft.Type.Kind() {
case reflect.Uint32, reflect.Int:
val = &ast.BasicLit{Kind: token.INT, Value: fmt.Sprint(reflect.ValueOf(e).Field(i))}
case reflect.Float64:
val = &ast.BasicLit{Kind: token.FLOAT, Value: fmt.Sprint(reflect.ValueOf(e).Field(i))}
case reflect.String:
val = &ast.BasicLit{Kind: token.STRING, Value: strconv.Quote(reflect.ValueOf(e).Field(i).String())}
case reflect.Bool:
val = &ast.BasicLit{Kind: token.IDENT, Value: fmt.Sprint(reflect.ValueOf(e).Field(i).Bool())}
case reflect.Slice:
val = &ast.CompositeLit{
Type: &ast.ArrayType{
Elt: &ast.BasicLit{Kind: token.IDENT, Value: ft.Type.Elem().Name()},
},
}
v := reflect.ValueOf(e).Field(i)
switch ft.Type.Elem().Kind() {
case reflect.Uint32, reflect.Int:
for x := 0; x < v.Len(); x++ {
val.(*ast.CompositeLit).Elts = append(val.(*ast.CompositeLit).Elts, &ast.BasicLit{
Kind: token.INT,
Value: fmt.Sprint(v.Index(x)),
})
}
}
}
fields[i] = &ast.KeyValueExpr{
Key: &ast.Ident{Name: ft.Name},
Value: val,
}
}
out.Decl.(*ast.GenDecl).Specs = append(out.Decl.(*ast.GenDecl).Specs, &ast.ValueSpec{
Names: []*ast.Ident{{Name: strcase.ToCamel(e.Name)}},
Values: []ast.Expr{
&ast.CompositeLit{
Type: &ast.Ident{Name: reflect.TypeOf(e).Name()},
Elts: fields,
},
},
})
}
return out
}
//go:generate go run $GOFILE //go:generate go run $GOFILE
//go:generate go fmt entity.go //go:generate go fmt entity.go
func main() { func main() {
fmt.Println("generating entity.go")
entities, err := downloadInfo() entities, err := downloadInfo()
if err != nil { if err != nil {
fmt.Fprintf(os.Stderr, "Error: %v\n", err) panic(err)
os.Exit(1)
} }
f, err := os.Create("entity.go") f, err := os.Create("entity.go")
if err != nil { if err != nil {
fmt.Fprintf(os.Stderr, "Error: %v\n", err) panic(err)
os.Exit(1)
} }
defer f.Close() defer f.Close()
fmt.Fprintln(f, `// Code generated by gen_entity.go DO NOT EDIT. if err := template.Must(template.New("").Parse(entityTmpl)).Execute(f, entities); err != nil {
// Package entity stores information about entities in Minecraft. panic(err)
package entity
// ID describes the numeric ID of an entity.
type ID uint32
// Entity describes information about a type of entity.
type Entity struct {
ID ID
InternalID uint32
DisplayName string
Name string
Width float64
Height float64
Type string
}`)
format.Node(f, token.NewFileSet(), makeEntityDeclaration(entities))
fmt.Fprintln(f)
fmt.Fprintln(f)
fmt.Fprintln(f, "// ByID is an index of minecraft entities by their ID.")
fmt.Fprintln(f, "var ByID = map[ID]*Entity{")
for _, e := range entities {
fmt.Fprintf(f, " %d: &%s,\n", e.ID, strcase.ToCamel(e.Name))
} }
fmt.Fprintln(f, "}")
fmt.Fprintln(f)
} }

View File

@ -6,136 +6,18 @@ package main
import ( import (
"encoding/json" "encoding/json"
"fmt" "fmt"
"go/ast"
"go/format"
"go/token"
"net/http" "net/http"
"os" "os"
"reflect" "text/template"
"strconv"
"github.com/iancoleman/strcase" "github.com/iancoleman/strcase"
) )
const ( const (
infoURL = "https://raw.githubusercontent.com/PrismarineJS/minecraft-data/master/data/pc/1.17/items.json" infoURL = "https://raw.githubusercontent.com/PrismarineJS/minecraft-data/master/data/pc/1.17/items.json"
) //language=gohtml
itemTmpl = `// Code generated by gen_item.go DO NOT EDIT.
type Item struct { // Package item stores information about items in Minecraft.
ID uint32 `json:"id"`
DisplayName string `json:"displayName"`
Name string `json:"name"`
StackSize uint `json:"stackSize"`
}
func downloadInfo() ([]Item, error) {
resp, err := http.Get(infoURL)
if err != nil {
return nil, err
}
defer resp.Body.Close()
var data []Item
if err := json.NewDecoder(resp.Body).Decode(&data); err != nil {
return nil, err
}
return data, nil
}
func makeItemDeclaration(blocks []Item) *ast.DeclStmt {
out := &ast.DeclStmt{Decl: &ast.GenDecl{Tok: token.VAR}}
for _, b := range blocks {
t := reflect.TypeOf(b)
fields := make([]ast.Expr, t.NumField())
for i := 0; i < t.NumField(); i++ {
ft := t.Field(i)
var val ast.Expr
switch ft.Type.Kind() {
case reflect.Uint32, reflect.Int, reflect.Uint:
val = &ast.BasicLit{Kind: token.INT, Value: fmt.Sprint(reflect.ValueOf(b).Field(i))}
case reflect.Float64:
val = &ast.BasicLit{Kind: token.FLOAT, Value: fmt.Sprint(reflect.ValueOf(b).Field(i))}
case reflect.String:
val = &ast.BasicLit{Kind: token.STRING, Value: strconv.Quote(reflect.ValueOf(b).Field(i).String())}
case reflect.Bool:
val = &ast.BasicLit{Kind: token.IDENT, Value: fmt.Sprint(reflect.ValueOf(b).Field(i).Bool())}
case reflect.Slice:
val = &ast.CompositeLit{
Type: &ast.ArrayType{
Elt: &ast.BasicLit{Kind: token.IDENT, Value: ft.Type.Elem().Name()},
},
}
v := reflect.ValueOf(b).Field(i)
switch ft.Type.Elem().Kind() {
case reflect.Uint32, reflect.Int:
for x := 0; x < v.Len(); x++ {
val.(*ast.CompositeLit).Elts = append(val.(*ast.CompositeLit).Elts, &ast.BasicLit{
Kind: token.INT,
Value: fmt.Sprint(v.Index(x)),
})
}
}
case reflect.Map:
// Must be the NeedsTools map of type map[uint32]bool.
m := &ast.CompositeLit{
Type: &ast.MapType{
Key: &ast.BasicLit{Kind: token.IDENT, Value: ft.Type.Key().Name()},
Value: &ast.BasicLit{Kind: token.IDENT, Value: ft.Type.Elem().Name()},
},
}
iter := reflect.ValueOf(b).Field(i).MapRange()
for iter.Next() {
m.Elts = append(m.Elts, &ast.KeyValueExpr{
Key: &ast.BasicLit{Kind: token.INT, Value: fmt.Sprint(iter.Key().Uint())},
Value: &ast.BasicLit{Kind: token.IDENT, Value: fmt.Sprint(iter.Value().Bool())},
})
}
val = m
}
fields[i] = &ast.KeyValueExpr{
Key: &ast.Ident{Name: ft.Name},
Value: val,
}
}
out.Decl.(*ast.GenDecl).Specs = append(out.Decl.(*ast.GenDecl).Specs, &ast.ValueSpec{
Names: []*ast.Ident{{Name: strcase.ToCamel(b.Name)}},
Values: []ast.Expr{
&ast.CompositeLit{
Type: &ast.Ident{Name: reflect.TypeOf(b).Name()},
Elts: fields,
},
},
})
}
return out
}
//go:generate go run $GOFILE
//go:generate go fmt item.go
func main() {
items, err := downloadInfo()
if err != nil {
fmt.Fprintf(os.Stderr, "Error: %v\n", err)
os.Exit(1)
}
f, err := os.Create("item.go")
if err != nil {
fmt.Fprintf(os.Stderr, "Error: %v\n", err)
os.Exit(1)
}
defer f.Close()
fmt.Fprintln(f, `// Package item stores information about items in Minecraft.
package item package item
// ID describes the numeric ID of an item. // ID describes the numeric ID of an item.
@ -149,24 +31,65 @@ type Item struct {
StackSize uint StackSize uint
} }
`) var (
format.Node(f, token.NewFileSet(), makeItemDeclaration(items)) {{- range .}}
{{.CamelName}} = Item{
ID: {{.ID}},
DisplayName: "{{.DisplayName}}",
Name: "{{.Name}}",
StackSize: {{.StackSize}},
}{{end}}
)
fmt.Fprintln(f) // ByID is an index of minecraft items by their ID.
fmt.Fprintln(f) var ByID = map[ID]*Item{ {{range .}}
fmt.Fprintln(f, "// ByID is an index of minecraft items by their ID.") {{.ID}}: &{{.CamelName}},{{end}}
fmt.Fprintln(f, "var ByID = map[ID]*Item{") }`
for _, i := range items { )
fmt.Fprintf(f, " %d: &%s,\n", i.ID, strcase.ToCamel(i.Name))
}
fmt.Fprintln(f, "}")
fmt.Fprintln(f)
fmt.Fprintln(f, "// ByName is an index of minecraft items by their name.") type Item struct {
fmt.Fprintln(f, "var ByName = map[string]*Item{") ID uint32 `json:"id"`
for _, i := range items { CamelName string `json:"-"`
fmt.Fprintf(f, " %q: &%s,\n", i.Name, strcase.ToCamel(i.Name)) DisplayName string `json:"displayName"`
} Name string `json:"name"`
fmt.Fprintln(f, "}") StackSize uint `json:"stackSize"`
fmt.Fprintln(f) }
func downloadInfo() ([]*Item, error) {
resp, err := http.Get(infoURL)
if err != nil {
return nil, err
}
defer resp.Body.Close()
var data []*Item
if err := json.NewDecoder(resp.Body).Decode(&data); err != nil {
return nil, err
}
for _, d := range data {
d.CamelName = strcase.ToCamel(d.Name)
}
return data, nil
}
//go:generate go run $GOFILE
//go:generate go fmt item.go
func main() {
fmt.Println("generating item.go")
items, err := downloadInfo()
if err != nil {
fmt.Fprintf(os.Stderr, "Error: %v\n", err)
os.Exit(1)
}
f, err := os.Create("item.go")
if err != nil {
fmt.Fprintf(os.Stderr, "Error: %v\n", err)
os.Exit(1)
}
defer f.Close()
if err := template.Must(template.New("").Parse(itemTmpl)).Execute(f, items); err != nil {
panic(err)
}
} }

File diff suppressed because it is too large Load Diff

View File

@ -8,7 +8,6 @@ import (
"errors" "errors"
"fmt" "fmt"
"io" "io"
"log"
"net/http" "net/http"
"os" "os"
"path/filepath" "path/filepath"
@ -18,9 +17,23 @@ import (
"text/template" "text/template"
) )
var (
//language=gohtml
langTmpl = `// Code generated by downloader.go; DO NOT EDIT.
package {{.Name}}
{{if ne .Name "en_us"}}
import "github.com/Tnze/go-mc/chat"
func init() { chat.SetLanguage(Map) }
{{end}}
var Map = {{.LangMap | printf "%#v"}}
`
)
//go:generate go run $GOFILE //go:generate go run $GOFILE
//go:generate go fmt ./... //go:generate go fmt ./...
func main() { func main() {
fmt.Println("generating langs")
if len(os.Args) == 2 { if len(os.Args) == 2 {
f, err := os.Open(os.Args[1]) f, err := os.Open(os.Args[1])
if err != nil { if err != nil {
@ -33,13 +46,12 @@ func main() {
versionURL, err := assetIndexURL() versionURL, err := assetIndexURL()
if err != nil { if err != nil {
log.Fatal(err) panic(err)
} }
log.Print("start generating lang packages")
resp, err := http.Get(versionURL) resp, err := http.Get(versionURL)
if err != nil { if err != nil {
log.Fatal(err) panic(err)
} }
defer resp.Body.Close() defer resp.Body.Close()
@ -52,7 +64,7 @@ func main() {
err = json.NewDecoder(resp.Body).Decode(&list) err = json.NewDecoder(resp.Body).Decode(&list)
if err != nil { if err != nil {
log.Fatal(err) panic(err)
} }
tasks := make(chan string) tasks := make(chan string)
@ -78,13 +90,11 @@ func main() {
} }
func lang(name, hash string) { func lang(name, hash string) {
log.Print("generating ", name, " package")
//download language //download language
LangURL := "http://resources.download.minecraft.net/" + hash[:2] + "/" + hash LangURL := "http://resources.download.minecraft.net/" + hash[:2] + "/" + hash
resp, err := http.Get(LangURL) resp, err := http.Get(LangURL)
if err != nil { if err != nil {
log.Fatal(err) panic(err)
} }
defer resp.Body.Close() defer resp.Body.Close()
readLang(name, resp.Body) readLang(name, resp.Body)
@ -95,7 +105,7 @@ func readLang(name string, r io.Reader) {
var LangMap map[string]string var LangMap map[string]string
err := json.NewDecoder(r).Decode(&LangMap) err := json.NewDecoder(r).Decode(&LangMap)
if err != nil { if err != nil {
log.Fatal("unmarshal json fail: ", err) panic(err)
} }
trans(LangMap) trans(LangMap)
@ -104,12 +114,12 @@ func readLang(name string, r io.Reader) {
// mkdir // mkdir
err = os.Mkdir(pName, 0777) err = os.Mkdir(pName, 0777)
if err != nil && !os.IsExist(err) { if err != nil && !os.IsExist(err) {
log.Fatal(err) panic(err)
} }
f, err := os.OpenFile(filepath.Join(pName, name+".go"), os.O_CREATE|os.O_RDWR|os.O_TRUNC, 0666) f, err := os.OpenFile(filepath.Join(pName, name+".go"), os.O_CREATE|os.O_RDWR|os.O_TRUNC, 0666)
if err != nil { if err != nil {
log.Fatal(err) panic(err)
} }
defer f.Close() defer f.Close()
@ -123,18 +133,9 @@ func readLang(name string, r io.Reader) {
LangMap: LangMap, LangMap: LangMap,
} }
tmpl := template.Must(template.New("code_template").Parse( tmpl := template.Must(template.New("").Parse(langTmpl))
`// Code generated by downloader.go; DO NOT EDIT.
package {{.Name}}
{{if ne .Name "en_us"}}
import "github.com/Tnze/go-mc/chat"
func init() { chat.SetLanguage(Map) }
{{end}}
var Map = {{.LangMap | printf "%#v"}}
`))
if err := tmpl.Execute(f, genData); err != nil { if err := tmpl.Execute(f, genData); err != nil {
log.Fatal(err) panic(err)
} }
} }
@ -150,7 +151,7 @@ func trans(m map[string]string) {
var index int var index int
_, err := fmt.Sscanf(s, "%%%d$s", &index) _, err := fmt.Sscanf(s, "%%%d$s", &index)
if err != nil { if err != nil {
log.Fatal(err) panic(err)
} }
return fmt.Sprintf("%%[%d]s", index) return fmt.Sprintf("%%[%d]s", index)
}) })

View File

@ -16,6 +16,7 @@ import (
const ( const (
protocolURL = "https://raw.githubusercontent.com/PrismarineJS/minecraft-data/master/data/pc/1.17.1/protocol.json" protocolURL = "https://raw.githubusercontent.com/PrismarineJS/minecraft-data/master/data/pc/1.17.1/protocol.json"
//language=gohtml
packetidTmpl = `// This file is automatically generated by gen_packetIDs.go. DO NOT EDIT. packetidTmpl = `// This file is automatically generated by gen_packetIDs.go. DO NOT EDIT.
package packetid package packetid
@ -165,22 +166,20 @@ func downloadInfo() (*protocolIDs, error) {
//go:generate go run $GOFILE //go:generate go run $GOFILE
//go:generate go fmt packetid.go //go:generate go fmt packetid.go
func main() { func main() {
fmt.Println("generating packetid.go")
pIDs, err := downloadInfo() pIDs, err := downloadInfo()
if err != nil { if err != nil {
fmt.Fprintf(os.Stderr, "Error: %v\n", err) panic(err)
os.Exit(1)
} }
f, err := os.Create("packetid.go") f, err := os.Create("packetid.go")
if err != nil { if err != nil {
fmt.Fprintf(os.Stderr, "Error: %v\n", err) panic(err)
os.Exit(1)
} }
defer f.Close() defer f.Close()
tmpl := template.Must(template.New("packetIDs").Parse(packetidTmpl)) tmpl := template.Must(template.New("packetIDs").Parse(packetidTmpl))
if err := tmpl.Execute(f, pIDs); err != nil { if err := tmpl.Execute(f, pIDs); err != nil {
fmt.Fprintf(os.Stderr, "Error: %v\n", err) panic(err)
os.Exit(1)
} }
} }

View File

@ -9,19 +9,39 @@ import (
"net/http" "net/http"
"os" "os"
"sort" "sort"
"text/template"
) )
const ( const (
protocolURL = "https://pokechu22.github.io/Burger/1.17.1.json" protocolURL = "https://pokechu22.github.io/Burger/1.17.1.json"
//language=gohtml
soundTmpl = `// Code generated by gen_soundid.go. DO NOT EDIT.
package soundid
// SoundID represents a sound ID used in the minecraft protocol.
type SoundID int32
// SoundNames - map of ids to names for sounds.
var SoundNames = map[SoundID]string{ {{range .}}
{{.ID}}: "{{.Name}}",{{end}}
}
// GetSoundNameByID helper method
func GetSoundNameByID(id SoundID) (string, bool) {
name, ok := SoundNames[id]
return name, ok
}`
) )
type sound struct { type Sound struct {
ID int64 ID int64
Name string Name string
} }
//go:generate go run $GOFILE //go:generate go run $GOFILE
func main() { func main() {
fmt.Println("generating soundid.go")
sounds, err := downloadSoundInfo() sounds, err := downloadSoundInfo()
if err != nil { if err != nil {
fmt.Fprintf(os.Stderr, "Error: %v\n", err) fmt.Fprintf(os.Stderr, "Error: %v\n", err)
@ -35,56 +55,35 @@ func main() {
} }
defer f.Close() defer f.Close()
fmt.Fprintln(f, "// Code generated by gen_soundIDs.go. DO NOT EDIT.") if err := template.Must(template.New("").Parse(soundTmpl)).Execute(f, sounds); err != nil {
fmt.Fprintln(f) panic(err)
fmt.Fprintln(f, "package soundid")
fmt.Fprintln(f)
fmt.Fprintln(f, "// SoundID represents a sound ID used in the minecraft protocol.")
fmt.Fprintln(f, "type SoundID int32")
fmt.Fprintln(f)
fmt.Fprintln(f, "// SoundNames - map of ids to names for sounds.")
fmt.Fprintln(f, "var SoundNames map[SoundID]string = map[SoundID]string{")
for _, v := range sounds {
fmt.Fprintf(f, ` %d: "%s",`, v.ID, v.Name)
fmt.Fprintln(f)
} }
fmt.Fprintln(f, "}")
fmt.Fprintln(f)
fmt.Fprintln(f, "// GetSoundNameByID helper method")
fmt.Fprintln(f, "func GetSoundNameByID(id SoundID) (string,bool) {")
fmt.Fprintln(f, " name, ok := SoundNames[id]")
fmt.Fprintln(f, " return name, ok")
fmt.Fprintln(f, "}")
} }
func downloadSoundInfo() ([]sound, error) { func downloadSoundInfo() ([]*Sound, error) {
resp, err := http.Get(protocolURL) resp, err := http.Get(protocolURL)
if err != nil { if err != nil {
return nil, err return nil, err
} }
defer resp.Body.Close() defer resp.Body.Close()
x := []map[string]interface{}{} // I'm not sure why the response returns a list, it appears to ever only have a single object...
var data []struct {
Sounds map[string]Sound `json:"sounds"`
}
// if err := json.Unmarshal([]byte(data), &x); err != nil { if err := json.NewDecoder(resp.Body).Decode(&data); err != nil {
if err := json.NewDecoder(resp.Body).Decode(&x); err != nil {
return nil, err return nil, err
} }
out := []sound{} out := make([]*Sound, 0)
for i := range x { for _, d := range data {
if sounds, ok := x[i]["sounds"]; ok { if has := len(d.Sounds); has > 0 {
// fmt.Fprintf("sounds: %#v\n", sounds) for _, val := range d.Sounds {
for _, value := range sounds.(map[string]interface{}) { out = append(out, &Sound{ID: val.ID, Name: val.Name})
// fmt.Fprintf("%d: %s\n", int64(value.(map[string]interface{})["id"].(float64)), value.(map[string]interface{})["name"])
out = append(out, sound{ID: int64(value.(map[string]interface{})["id"].(float64)), Name: value.(map[string]interface{})["name"].(string)})
} }
} else { } else {
// fmt.Fprintf("NO SOUNDS FOUND IN DATA!") return nil, fmt.Errorf("no sounds found in data from %s", protocolURL)
return nil, fmt.Errorf("No sounds found in data from %s", protocolURL)
} }
} }

View File

@ -1,4 +1,4 @@
// Code generated by gen_soundIDs.go. DO NOT EDIT. // Code generated by gen_soundid.go. DO NOT EDIT.
package soundid package soundid
@ -6,7 +6,7 @@ package soundid
type SoundID int32 type SoundID int32
// SoundNames - map of ids to names for sounds. // SoundNames - map of ids to names for sounds.
var SoundNames map[SoundID]string = map[SoundID]string{ var SoundNames = map[SoundID]string{
0: "ambient.cave", 0: "ambient.cave",
1: "ambient.basalt_deltas.additions", 1: "ambient.basalt_deltas.additions",
2: "ambient.basalt_deltas.loop", 2: "ambient.basalt_deltas.loop",