[
  {
    "path": ".github/dependabot.yml",
    "content": "version: 2\nupdates:\n  - package-ecosystem: \"gomod\"\n    directory: \"/\" # Location of package manifests\n    schedule:\n      interval: \"daily\"\n    assignees:\n      - \"Sxtanna\"\n"
  },
  {
    "path": ".gitignore",
    "content": "# Binaries for programs and plugins\n*.exe\n*.exe~\n*.dll\n*.so\n*.dylib\n\n# Test binary, built with `go test -c`\n*.test\n\n# Output of the go coverage tool, specifically when used with LiteIDE\n*.out\n\n# Dependency directories (remove the comment below to include it)\n# vendor/\n\n# IntelliJ project files\n.idea\n*.iml\nout\ngen\n"
  },
  {
    "path": "LICENSE",
    "content": "MIT License\n\nCopyright (c) 2020 GoLangMc\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
  },
  {
    "path": "README.md",
    "content": "\n<p align=\"center\">\n\n  <a href=\"https://github.com/GoLangMc/minecraft-server\">\n    <img src=\"https://avatars3.githubusercontent.com/u/61735329\" alt=\"logo\" width=\"100\" height=\"100\">\n  </a>\n\n  <h3 align=\"center\">minecraft-server</h3>\n\n  <p align=\"center\">\n    Minecraft Server implementation written in Go\n    <br />\n    <br />\n    <a href=\"https://github.com/GoLangMc/minecraft-server/issues\">Report Bug</a>\n    ·\n    <a href=\"https://github.com/GoLangMc/minecraft-server/issues\">Request Feature</a>\n    ·\n    <a href=\"https://github.com/GoLangMc/minecraft-server/pulls\">Send a Pull Request</a>\n  </p>\n  \n</p>"
  },
  {
    "path": "apis/base/funcs.go",
    "content": "package base\n\nimport (\n\t\"crypto/sha256\"\n\t\"encoding/binary\"\n\t\"fmt\"\n\t\"strings\"\n)\n\nfunc ConvertToString(data ...interface{}) string {\n\tstrs := make([]string, len(data))\n\n\tfor i, str := range data {\n\t\tstrs[i] = fmt.Sprintf(\"%v\", str)\n\t}\n\n\treturn strings.Join(strs, \"\")\n}\n\nfunc Attempt(function func()) (err error) {\n\tdefer func() {\n\t\tif r := recover(); r != nil {\n\t\t\terr = fmt.Errorf(\"caught: %v\", r)\n\t\t}\n\t}()\n\n\tfunction()\n\n\treturn\n}\n\nfunc JavaStringHashCode(value string) int32 {\n\tvar h int32\n\n\tif len(value) > 0 {\n\t\tfor _, r := range value {\n\t\t\th = 31*h + r\n\t\t}\n\t}\n\n\treturn h\n}\n\nfunc JavaSHA256HashLong(value int64) []byte {\n\tbytes := make([]byte, 8)\n\tbinary.LittleEndian.PutUint64(bytes, uint64(value))\n\n\thash := sha256.Sum256(bytes)\n\n\treturn hash[:]\n}\n"
  },
  {
    "path": "apis/base/named.go",
    "content": "package base\n\ntype Named interface {\n\tName() string\n}\n"
  },
  {
    "path": "apis/base/state.go",
    "content": "package base\n\ntype Loads interface {\n\tLoad()\n}\n\ntype Kills interface {\n\tKill()\n}\n\ntype State interface {\n\tLoads\n\tKills\n}\n"
  },
  {
    "path": "apis/base/unique.go",
    "content": "package base\n\nimport \"github.com/golangmc/minecraft-server/apis/uuid\"\n\ntype Unique interface {\n\tUUID() uuid.UUID\n}\n"
  },
  {
    "path": "apis/buff/buffers.go",
    "content": "package buff\n\nimport (\n\t\"github.com/golangmc/minecraft-server/apis/data\"\n\t\"github.com/golangmc/minecraft-server/apis/data/tags\"\n\t\"github.com/golangmc/minecraft-server/apis/uuid\"\n)\n\ntype Buffer interface {\n\tLen() int32\n\n\tSAS() []int8\n\n\tUAS() []byte\n\n\tInI() int32\n\n\tInO() int32\n\n\tSkpAll()\n\n\tSkpLen(delta int32)\n\n\t// pull\n\tPullBit() bool\n\n\tPullByt() byte\n\n\tPullI16() int16\n\n\tPullU16() uint16\n\n\tPullI32() int32\n\n\tPullI64() int64\n\n\tPullU64() uint64\n\n\tPullF32() float32\n\n\tPullF64() float64\n\n\tPullVrI() int32\n\n\tPullVrL() int64\n\n\tPullTxt() string\n\n\tPullUAS() []byte\n\n\tPullSAS() []int8\n\n\tPullUID() uuid.UUID\n\n\tPullPos() data.PositionI\n\n\tPullNbt() *tags.NbtCompound\n\n\t// push\n\tPushBit(data bool)\n\n\tPushByt(data byte)\n\n\tPushI16(data int16)\n\n\tPushI32(data int32)\n\n\tPushI64(data int64)\n\n\tPushF32(data float32)\n\n\tPushF64(data float64)\n\n\tPushVrI(data int32)\n\n\tPushVrL(data int64)\n\n\tPushTxt(data string)\n\n\tPushUAS(data []byte, prefixWithLen bool)\n\n\tPushSAS(data []int8, prefixWithLen bool)\n\n\tPushUID(data uuid.UUID)\n\n\tPushPos(data data.PositionI)\n\n\tPushNbt(data *tags.NbtCompound)\n}\n\ntype BufferPush interface {\n\tPush(writer Buffer)\n}\n\ntype BufferPull interface {\n\tPull(reader Buffer)\n}\n\ntype BufferCodec interface {\n\tBufferPush\n\tBufferPull\n}\n"
  },
  {
    "path": "apis/cmds/command.go",
    "content": "package cmds\n\nimport (\n\t\"github.com/golangmc/minecraft-server/apis/base\"\n\t\"github.com/golangmc/minecraft-server/apis/ents\"\n)\n\ntype Command interface {\n\tbase.Named\n\tbase.State\n\n\tEvaluate(sender ents.Sender, params []string)\n\n\tComplete(sender ents.Sender, params []string, output *[]string)\n}\n"
  },
  {
    "path": "apis/cmds/commandmanager.go",
    "content": "package cmds\n\nimport (\n\t\"strings\"\n\n\t\"github.com/golangmc/minecraft-server/apis/ents\"\n)\n\ntype CommandManager struct {\n\tcommands map[string]*Command\n}\n\nfunc NewCommandManager() *CommandManager {\n\treturn &CommandManager{\n\t\tcommands: make(map[string]*Command),\n\t}\n}\n\nfunc (c *CommandManager) Load() {\n\n}\n\nfunc (c *CommandManager) Kill() {\n\tc.commands = nil\n}\n\nfunc (c *CommandManager) RegisterCommand(command Command) {\n\tc.commands[command.Name()] = &command\n\n\tcommand.Load()\n}\n\nfunc (c *CommandManager) Register(name string, evaluate func(sender ents.Sender, params []string)) {\n\tcommand := simpleCommand{\n\t\tname:     name,\n\t\tevaluate: evaluate,\n\t}\n\n\tc.RegisterCommand(&command)\n}\n\nfunc (c *CommandManager) Search(named string) *Command {\n\tfor name, command := range c.commands {\n\t\tif strings.EqualFold(name, named) {\n\t\t\treturn command\n\t\t}\n\t}\n\n\treturn nil\n}\n\ntype simpleCommand struct {\n\tname string\n\n\tevaluate func(sender ents.Sender, params []string)\n}\n\nfunc (s *simpleCommand) Name() string {\n\treturn s.name\n}\n\nfunc (s *simpleCommand) Load() {\n\n}\n\nfunc (s *simpleCommand) Kill() {\n\n}\n\nfunc (s *simpleCommand) Evaluate(sender ents.Sender, params []string) {\n\ts.evaluate(sender, params)\n}\n\nfunc (s *simpleCommand) Complete(sender ents.Sender, params []string, output *[]string) {\n\n}\n"
  },
  {
    "path": "apis/data/chat/coloring.go",
    "content": "package chat\n\nimport (\n\t\"fmt\"\n\t\"strings\"\n\n\t\"github.com/fatih/color\"\n)\n\ntype ChatColor int\n\ntype ColorCode struct {\n\tChat string\n\tMotd string\n\tJson string\n\n\tDec string\n\tHex string\n}\n\nconst (\n\tDarkRed ChatColor = iota\n\tRed\n\n\tGold\n\tYellow\n\n\tDarkGreen\n\tGreen\n\n\tDarkAqua\n\tAqua\n\n\tDarkBlue\n\tBlue\n\n\tDarkPurple\n\tPurple\n\n\tWhite\n\tBlack\n\n\tDarkGray\n\tGray\n\n\tObfuscated\n\tBold\n\tStrikethrough\n\tUnderline\n\tItalic\n\tReset\n)\n\nconst ColorCChar = '§'\nconst ColorAChar = '&'\n\nvar codeToCode = map[ChatColor]*ColorCode{\n\tDarkRed: {\n\t\tChat: `§4`,\n\t\tMotd: `\\u00A74`,\n\t\tJson: `dark_red`,\n\t\tDec:  `11141120`,\n\t\tHex:  `AA0000`,\n\t},\n\tRed: {\n\t\tChat: `§c`,\n\t\tMotd: `\\u00A7c`,\n\t\tJson: `red`,\n\t\tDec:  `16733525`,\n\t\tHex:  `FF5555`,\n\t},\n\tGold: {\n\t\tChat: `§6`,\n\t\tMotd: `\\u00A76`,\n\t\tJson: `gold`,\n\t\tDec:  `16755200`,\n\t\tHex:  `FFAA00`,\n\t},\n\tYellow: {\n\t\tChat: `§e`,\n\t\tMotd: `\\u00A7e`,\n\t\tJson: `yellow`,\n\t\tDec:  `16777045`,\n\t\tHex:  `FFFF55`,\n\t},\n\tDarkGreen: {\n\t\tChat: `§2`,\n\t\tMotd: `\\u00A72`,\n\t\tJson: `dark_green`,\n\t\tDec:  `43520`,\n\t\tHex:  `00AA00`,\n\t},\n\tGreen: {\n\t\tChat: `§a`,\n\t\tMotd: `\\u00A7a`,\n\t\tDec:  `5635925`,\n\t\tHex:  `55FF55`,\n\t},\n\tDarkAqua: {\n\t\tChat: `§3`,\n\t\tMotd: `\\u00A73`,\n\t\tJson: `dark_aqua`,\n\t\tDec:  `43690`,\n\t\tHex:  `00AAAA`,\n\t},\n\tAqua: {\n\t\tChat: `§b`,\n\t\tMotd: `\\u00A7b`,\n\t\tJson: `aqua`,\n\t\tDec:  `5636095`,\n\t\tHex:  `55FFFF`,\n\t},\n\tDarkBlue: {\n\t\tChat: `§1`,\n\t\tMotd: `\\u00A71`,\n\t\tJson: `dark_blue`,\n\t\tDec:  `170`,\n\t\tHex:  `0000AA`,\n\t},\n\tBlue: {\n\t\tChat: `§9`,\n\t\tMotd: `\\u00A79`,\n\t\tJson: `blue`,\n\t\tDec:  `5592575`,\n\t\tHex:  `5555FF`,\n\t},\n\tDarkPurple: {\n\t\tChat: `§5`,\n\t\tMotd: `\\u00A75`,\n\t\tJson: `dark_purple`,\n\t\tDec:  `11141290`,\n\t\tHex:  `AA00AA`,\n\t},\n\tPurple: {\n\t\tChat: `§d`,\n\t\tMotd: `\\u00A7d`,\n\t\tJson: `light_purple`,\n\t\tDec:  `16733695`,\n\t\tHex:  `FF55FF`,\n\t},\n\tWhite: {\n\t\tChat: `§f`,\n\t\tMotd: `\\u00A7f`,\n\t\tJson: `white`,\n\t\tDec:  `16777215`,\n\t\tHex:  `FFFFFF`,\n\t},\n\tBlack: {\n\t\tChat: `§0`,\n\t\tMotd: `\\u00A70`,\n\t\tJson: `black`,\n\t\tDec:  `0`,\n\t\tHex:  `000000`,\n\t},\n\tDarkGray: {\n\t\tChat: `§8`,\n\t\tMotd: `\\u00A78`,\n\t\tJson: `dark_gray`,\n\t\tDec:  `5592405`,\n\t\tHex:  `555555`,\n\t},\n\tGray: {\n\t\tChat: `§7`,\n\t\tMotd: `\\u00A77`,\n\t\tJson: `gray`,\n\t\tDec:  `11184810`,\n\t\tHex:  `AAAAAA`,\n\t},\n\n\tObfuscated: {\n\t\tChat: `§k`,\n\t\tMotd: `\\u00A7k`,\n\t\tJson: `obfuscated`,\n\t},\n\tBold: {\n\t\tChat: `§l`,\n\t\tMotd: `\\u00A7l`,\n\t\tJson: `bold`,\n\t},\n\tStrikethrough: {\n\t\tChat: `§m`,\n\t\tMotd: `\\u00A7m`,\n\t\tJson: `strikethrough`,\n\t},\n\tUnderline: {\n\t\tChat: `§n`,\n\t\tMotd: `\\u00A7n`,\n\t\tJson: `underline`,\n\t},\n\tItalic: {\n\t\tChat: `§o`,\n\t\tMotd: `\\u00A7o`,\n\t\tJson: `italic`,\n\t},\n\tReset: {\n\t\tChat: `§r`,\n\t\tMotd: `\\u00A7r`,\n\t\tJson: `reset`,\n\t},\n}\nvar codeToForm = map[ChatColor]color.Attribute{\n\tDarkRed:    color.FgHiRed,\n\tRed:        color.FgRed,\n\tGold:       color.FgYellow,\n\tYellow:     color.FgHiYellow,\n\tDarkGreen:  color.FgGreen,\n\tGreen:      color.FgHiGreen,\n\tDarkAqua:   color.FgCyan,\n\tAqua:       color.FgHiCyan,\n\tDarkBlue:   color.FgBlue,\n\tBlue:       color.FgHiBlue,\n\tDarkPurple: color.FgMagenta,\n\tPurple:     color.FgHiMagenta,\n\tWhite:      color.FgHiWhite,\n\tBlack:      color.FgBlack,\n\tDarkGray:   color.FgHiBlack,\n\tGray:       color.FgWhite,\n\n\tReset:         color.Reset,\n\tObfuscated:    color.BlinkRapid,\n\tBold:          color.Bold,\n\tStrikethrough: color.CrossedOut,\n\tUnderline:     color.Underline,\n\tItalic:        color.Italic,\n}\n\nvar charToCode = map[rune]ChatColor{\n\t'4': DarkRed,\n\t'c': Red,\n\t'6': Gold,\n\t'e': Yellow,\n\n\t'2': DarkGreen,\n\t'a': Green,\n\n\t'3': DarkAqua,\n\t'b': Aqua,\n\n\t'1': DarkBlue,\n\t'9': Blue,\n\n\t'5': DarkPurple,\n\t'd': Purple,\n\n\t'f': White,\n\t'0': Black,\n\n\t'8': DarkGray,\n\t'7': Gray,\n\n\t'k': Obfuscated,\n\t'l': Bold,\n\t'm': Strikethrough,\n\t'n': Underline,\n\t'o': Italic,\n\t'r': Reset,\n}\n\nvar jsonToCode = map[string]ChatColor{\n\t`dark_red`: DarkRed,\n\t`red`:      Red,\n\t`gold`:     Gold,\n\t`yellow`:   Yellow,\n\n\t`dark_green`: DarkGreen,\n\t`green`:      Green,\n\n\t`dark_aqua`: DarkAqua,\n\t`aqua`:      Aqua,\n\n\t`dark_blue`: DarkBlue,\n\t`blue`:      Blue,\n\n\t`dark_purple`:  DarkPurple,\n\t`light_purple`: Purple,\n\n\t`white`: White,\n\t`black`: Black,\n\n\t`dark_gray`: DarkGray,\n\t`gray`:      Gray,\n\n\t`obfuscated`:    Obfuscated,\n\t`bold`:          Bold,\n\t`strikethrough`: Strikethrough,\n\t`underline`:     Underline,\n\t`italic`:        Italic,\n\t`reset`:         Reset,\n}\n\nfunc (code ChatColor) String() string {\n\treturn codeToCode[code].Chat\n}\n\nfunc (code *ChatColor) MarshalJSON() ([]byte, error) {\n\treturn []byte(`\"` + codeToCode[*code].Json + `\"`), nil\n}\n\nfunc (code *ChatColor) UnmarshalJSON(bytes []byte) error {\n\t*code = jsonToCode[string(bytes)]\n\treturn nil\n}\n\nfunc (code *ChatColor) On(text string) string {\n\tif len(text) == 0 {\n\t\treturn \"\"\n\t}\n\n\treturn fmt.Sprintf(\"%p%s%v\", code, text, Reset)\n}\n\nfunc Translate(text string) string {\n\n\tbuild := strings.Builder{}\n\tchars := []rune(text)\n\n\tfor i := 0; i < len(chars); i++ {\n\n\t\tr := chars[i]\n\n\t\tif r != ColorAChar || i+1 >= len(chars) {\n\t\t\tbuild.WriteRune(r)\n\t\t} else {\n\t\t\tc := codeToCode[charToCode[chars[i+1]]]\n\n\t\t\tif c == nil {\n\t\t\t\tbuild.WriteRune(r)\n\t\t\t} else {\n\t\t\t\tbuild.WriteString(c.Chat)\n\t\t\t\ti++\n\t\t\t}\n\t\t}\n\t}\n\n\treturn build.String()\n}\n\nfunc TranslateConsole(text string) string {\n\ttext = Translate(text)\n\n\tbuild := strings.Builder{}\n\ttemps := strings.Builder{}\n\n\tchars := []rune(text)\n\tforms := make([]color.Attribute, 0)\n\n\tfor i := 0; i < len(chars); i++ {\n\t\tr := chars[i]\n\t\tif r != ColorCChar || i+1 >= len(chars) {\n\t\t\ttemps.WriteRune(r)\n\t\t\tcontinue\n\t\t}\n\n\t\tf, con := codeToForm[charToCode[chars[i+1]]]\n\t\tif !con {\n\t\t\ttemps.WriteRune(r)\n\t\t\tcontinue\n\t\t}\n\n\t\tif temps.Len() > 0 {\n\t\t\tbuild.WriteString(color.New(forms...).Sprint(temps.String()))\n\t\t\ttemps.Reset()\n\t\t}\n\n\t\ti++\n\t\tif f <= color.CrossedOut {\n\t\t\tforms = append(forms, f)\n\t\t} else {\n\t\t\tforms = make([]color.Attribute, 0)\n\t\t\tforms = append(forms, f)\n\t\t}\n\t}\n\n\tif temps.Len() > 0 {\n\t\tbuild.WriteString(color.New(forms...).Sprint(temps.String()))\n\t}\n\n\treturn build.String()\n}\n"
  },
  {
    "path": "apis/data/location.go",
    "content": "package data\n\ntype Location struct {\n\tPositionF\n\tRotationF\n}\n"
  },
  {
    "path": "apis/data/material.go",
    "content": "package data\n\ntype Material int32\n\nconst (\n\tAIR Material = iota\n\n\tSTONE\n\n\tGRANITE\n\tPOLISHED_GRANITE\n\n\tANDESITE\n\tPOLISHED_ANDESITE\n\n\tDIORITE\n\tPOLISHED_DIORITE\n)\n"
  },
  {
    "path": "apis/data/msgs/messages.go",
    "content": "package msgs\n\nimport (\n\t\"encoding/json\"\n\t\"strings\"\n\n\t\"github.com/golangmc/minecraft-server/apis/data/chat\"\n)\n\ntype MessagePosition byte\n\nconst (\n\tNormalChat MessagePosition = iota\n\tSystemChat\n\tHotBarText\n)\n\ntype Message struct {\n\tText  string          `json:\"text\"`\n\tColor *chat.ChatColor `json:\"color,string,omitempty\"`\n\n\tBold          *bool `json:\"bold,boolean,omitempty\"`\n\tItalic        *bool `json:\"italic,boolean,omitempty\"`\n\tUnderlined    *bool `json:\"underlined,boolean,omitempty\"`\n\tStrikethrough *bool `json:\"strikethrough,boolean,omitempty\"`\n\tObfuscated    *bool `json:\"obfuscated,boolean,omitempty\"`\n\n\tExtra []*Message `json:\"extra,omitempty\"`\n\n\thead *Message\n}\n\nfunc New(text string) *Message {\n\treturn &Message{\n\t\tText: text,\n\t}\n}\n\nfunc (c *Message) SetColor(code chat.ChatColor) *Message {\n\tc.Color = &code\n\treturn c\n}\n\nfunc (c *Message) SetBold(value bool) *Message {\n\tc.Bold = &value\n\treturn c\n}\n\nfunc (c *Message) SetItalic(value bool) *Message {\n\tc.Italic = &value\n\treturn c\n}\n\nfunc (c *Message) SetUnderlined(value bool) *Message {\n\tc.Underlined = &value\n\treturn c\n}\n\nfunc (c *Message) SetStrikethrough(value bool) *Message {\n\tc.Strikethrough = &value\n\treturn c\n}\n\nfunc (c *Message) SetObfuscated(value bool) *Message {\n\tc.Obfuscated = &value\n\treturn c\n}\n\n// creates and returns a new Chat object, and adds it to the caller's extra slice\nfunc (c *Message) Add(text string) *Message {\n\tchat := New(text)\n\tchat.head = c\n\n\tc.Extra = append(c.Extra, chat)\n\n\treturn chat\n}\n\nfunc (c *Message) Reset() *Message {\n\n\tnext := c.Add(\"\").SetColor(chat.Reset)\n\n\tif c.Bold != nil && *c.Bold == true {\n\t\tnext.SetBold(false)\n\t}\n\n\tif c.Italic != nil && *c.Italic == true {\n\t\tnext.SetItalic(false)\n\t}\n\n\tif c.Underlined != nil && *c.Underlined == true {\n\t\tnext.SetUnderlined(false)\n\t}\n\n\tif c.Strikethrough != nil && *c.Strikethrough == true {\n\t\tnext.SetStrikethrough(false)\n\t}\n\n\tif c.Obfuscated != nil && *c.Obfuscated == true {\n\t\tnext.SetObfuscated(false)\n\t}\n\n\treturn next\n}\n\nfunc (c *Message) AsJson() string {\n\n\tchat := c\n\n\tfor chat.head != nil {\n\t\tchat = chat.head\n\t}\n\n\tif text, err := json.Marshal(chat); err != nil {\n\t\tpanic(err)\n\t} else {\n\t\treturn string(text)\n\t}\n}\n\nfunc (c *Message) AsText() string {\n\tbuilder := strings.Builder{}\n\n\tcurr := c\n\n\tfor curr.head != nil {\n\t\tcurr = curr.head\n\t}\n\n\tbuilder.WriteString(curr.asText())\n\n\treturn builder.String()\n}\n\nfunc (c *Message) asText() string {\n\tbuilder := strings.Builder{}\n\n\tif c.Color != nil {\n\t\tbuilder.WriteString(c.Color.String())\n\t}\n\n\tif c.Bold != nil && *c.Bold == true {\n\t\tbuilder.WriteString(chat.Bold.String())\n\t}\n\n\tif c.Italic != nil && *c.Italic == true {\n\t\tbuilder.WriteString(chat.Italic.String())\n\t}\n\n\tif c.Underlined != nil && *c.Underlined == true {\n\t\tbuilder.WriteString(chat.Underline.String())\n\t}\n\n\tif c.Strikethrough != nil && *c.Strikethrough == true {\n\t\tbuilder.WriteString(chat.Strikethrough.String())\n\t}\n\n\tif c.Obfuscated != nil && *c.Obfuscated == true {\n\t\tbuilder.WriteString(chat.Obfuscated.String())\n\t}\n\n\tbuilder.WriteString(c.Text)\n\n\tfor _, extra := range c.Extra {\n\t\tbuilder.WriteString(extra.asText())\n\t}\n\n\treturn builder.String()\n}\n\nfunc (c *Message) String() string {\n\treturn c.AsJson()\n}\n"
  },
  {
    "path": "apis/data/position.go",
    "content": "package data\n\ntype PositionI struct {\n\tX int64\n\tY int64\n\tZ int64\n}\n\ntype PositionF struct {\n\tX float64\n\tY float64\n\tZ float64\n}\n"
  },
  {
    "path": "apis/data/rotation.go",
    "content": "package data\n\ntype RotationF struct {\n\tAxisX float32 // 'yaw'\n\tAxisY float32 // 'pitch'\n}\n"
  },
  {
    "path": "apis/data/tags/nbt.go",
    "content": "package tags\n\ntype Typ byte\n\nconst (\n\tTAG_End Typ = iota\n\tTAG_Byte\n\tTAG_Short\n\tTAG_Int\n\tTAG_Long\n\tTAG_Float\n\tTAG_Double\n\tTAG_Byte_Array\n\tTAG_String\n\tTAG_List\n\tTAG_Compound\n\tTAG_Int_Array\n\tTAG_Long_Array\n)\n\ntype Nbt interface {\n\tType() Typ\n\n\tName() string\n}\n\n// end\ntype NbtEnd struct{}\n\nfunc (n *NbtEnd) Type() Typ {\n\treturn TAG_End\n}\n\nfunc (n *NbtEnd) Name() string {\n\treturn \"TAG_End\"\n}\n\n// byte\ntype NbtByt struct {\n\tValue int8\n}\n\nfunc (n *NbtByt) Type() Typ {\n\treturn TAG_Byte\n}\n\nfunc (n *NbtByt) Name() string {\n\treturn \"TAG_Byte\"\n}\n\n// short\ntype NbtI16 struct {\n\tValue int16\n}\n\nfunc (n *NbtI16) Type() Typ {\n\treturn TAG_Short\n}\n\nfunc (n *NbtI16) Name() string {\n\treturn \"TAG_Short\"\n}\n\n/*func (n *NbtI16) Push(writer buff.Buffer) {\n\twriter.PushI16(n.Value)\n}\n\nfunc (n *NbtI16) Pull(reader buff.Buffer) {\n\tn.Value = reader.PullI16()\n}*/\n\n// int\ntype NbtI32 struct {\n\tValue int32\n}\n\nfunc (n *NbtI32) Type() Typ {\n\treturn TAG_Int\n}\n\nfunc (n *NbtI32) Name() string {\n\treturn \"TAG_Int\"\n}\n\n/*func (n *NbtI32) Push(writer buff.Buffer) {\n\twriter.PushI32(n.Value)\n}\n\nfunc (n *NbtI32) Pull(reader buff.Buffer) {\n\tn.Value = reader.PullI32()\n}*/\n\n// long\ntype NbtI64 struct {\n\tValue int64\n}\n\nfunc (n *NbtI64) Type() Typ {\n\treturn TAG_Long\n}\n\nfunc (n *NbtI64) Name() string {\n\treturn \"TAG_Long\"\n}\n\n/*func (n *NbtI64) Push(writer buff.Buffer) {\n\twriter.PushI64(n.Value)\n}\n\nfunc (n *NbtI64) Pull(reader buff.Buffer) {\n\tn.Value = reader.PullI64()\n}*/\n\n// float\ntype NbtF32 struct {\n\tValue float32\n}\n\nfunc (n *NbtF32) Type() Typ {\n\treturn TAG_Float\n}\n\nfunc (n *NbtF32) Name() string {\n\treturn \"TAG_Float\"\n}\n\n/*func (n *NbtF32) Push(writer buff.Buffer) {\n\twriter.PushF32(n.Value)\n}\n\nfunc (n *NbtF32) Pull(reader buff.Buffer) {\n\tn.Value = reader.PullF32()\n}*/\n\n// double\ntype NbtF64 struct {\n\tValue float64\n}\n\nfunc (n *NbtF64) Type() Typ {\n\treturn TAG_Double\n}\n\nfunc (n *NbtF64) Name() string {\n\treturn \"TAG_Double\"\n}\n\n/*func (n *NbtF64) Push(writer buff.Buffer) {\n\twriter.PushF64(n.Value)\n}\n\nfunc (n *NbtF64) Pull(reader buff.Buffer) {\n\tn.Value = reader.PullF64()\n}*/\n\n// byte array\ntype NbtArrByt struct {\n\tValue []int8\n}\n\nfunc (n *NbtArrByt) Type() Typ {\n\treturn TAG_Byte_Array\n}\n\nfunc (n *NbtArrByt) Name() string {\n\treturn \"TAG_Byte_Array\"\n}\n\n/*func (n *NbtArrByt) Push(writer buff.Buffer) {\n\twriter.PushSAS(n.Value, true)\n}\n\nfunc (n *NbtArrByt) Pull(reader buff.Buffer) {\n\tn.Value = reader.PullSAS()\n}*/\n\n// string\ntype NbtTxt struct {\n\tValue string\n}\n\nfunc (n *NbtTxt) Type() Typ {\n\treturn TAG_String\n}\n\nfunc (n *NbtTxt) Name() string {\n\treturn \"TAG_String\"\n}\n\n/*func (n *NbtTxt) Push(writer buff.Buffer) {\n\twriter.PushTxt(n.Value)\n}\n\nfunc (n *NbtTxt) Pull(reader buff.Buffer) {\n\tn.Value = reader.PullTxt()\n}*/\n\n// typed list\ntype NbtArrAny struct {\n\tNType Typ\n\tValue []Nbt\n}\n\nfunc (n *NbtArrAny) Type() Typ {\n\treturn TAG_List\n}\n\nfunc (n *NbtArrAny) Name() string {\n\treturn \"TAG_List\"\n}\n\n/*func (n *NbtArrAny) Push(writer buff.Buffer) {\n\tif len(n.Value) == 0 {\n\t\twriter.PushByt(0)\n\t} else {\n\t\twriter.PushByt(byte(n.NType))\n\t}\n\n\twriter.PushI32(int32(len(n.Value)))\n\n\tfor _, nbt := range n.Value {\n\t\tnbt.Push(writer)\n\t}\n}\n\nfunc (n *NbtArrAny) Pull(reader buff.Buffer) {\n\tnType := Typ(reader.PullByt()) // this can probably fail...\n\n\tsize := reader.PullI32()\n\tvalue := make([]Nbt, size, size)\n\n\tfor i := int32(0); i < size; i++ {\n\t\tinst := typeToInst[nType]()\n\t\tinst.Pull(reader)\n\n\t\tvalue[i] = inst\n\t}\n}*/\n\n// compound (map)\ntype NbtCompound struct {\n\tNamed string\n\tValue map[string]Nbt\n}\n\nfunc (n *NbtCompound) Type() Typ {\n\treturn TAG_Compound\n}\n\nfunc (n *NbtCompound) Name() string {\n\treturn \"TAG_Compound\"\n}\n\nfunc (n *NbtCompound) Set(name string, data Nbt) {\n\tn.Value[name] = data\n}\n\nfunc (n *NbtCompound) Get(name string) (nbt Nbt, con bool) {\n\tnbt, con = n.Value[name]\n\treturn\n}\n\n// int list\ntype NbtArrI32 struct {\n\tValue []int32\n}\n\nfunc (n *NbtArrI32) Type() Typ {\n\treturn TAG_Int_Array\n}\n\nfunc (n *NbtArrI32) Name() string {\n\treturn \"TAG_Int_Array\"\n}\n\n/*func (n *NbtArrI32) Push(writer buff.Buffer) {\n\twriter.PushI32(int32(len(n.Value)))\n\n\tfor _, value := range n.Value {\n\t\twriter.PushI32(value)\n\t}\n}\n\nfunc (n *NbtArrI32) Pull(reader buff.Buffer) {\n\tvalue := make([]int32, reader.PullI32())\n\n\tfor i := 0; i < len(value); i++ {\n\t\tvalue[i] = reader.PullI32()\n\t}\n}*/\n\n// long list\ntype NbtArrI64 struct {\n\tValue []int64\n}\n\nfunc (n *NbtArrI64) Type() Typ {\n\treturn TAG_Long_Array\n}\n\nfunc (n *NbtArrI64) Name() string {\n\treturn \"TAG_Long_Array\"\n}\n"
  },
  {
    "path": "apis/data/versions.go",
    "content": "package data\n\ntype MinecraftVersion int\n\nconst (\n\tMC1_12_2 MinecraftVersion = iota\n\tMC1_13_2\n\tMC1_14_4\n\tMC1_15_2\n)\n\nvar CurrentProtocol = MC1_15_2\n\nvar protocolVersion = map[MinecraftVersion]int{\n\tMC1_12_2: 340,\n\tMC1_13_2: 404,\n\tMC1_14_4: 498,\n\tMC1_15_2: 578,\n}\n\nfunc (m MinecraftVersion) Protocol() int {\n\treturn protocolVersion[m]\n}\n\nfunc (m MinecraftVersion) String() string {\n\tswitch m {\n\tcase MC1_12_2:\n\t\treturn \"1.12.2\"\n\tcase MC1_13_2:\n\t\treturn \"1.13.2\"\n\tcase MC1_14_4:\n\t\treturn \"1.14.4\"\n\tcase MC1_15_2:\n\t\treturn \"1.15.2\"\n\tdefault:\n\t\treturn \"Unknown\"\n\t}\n}\n"
  },
  {
    "path": "apis/ents/entity.go",
    "content": "package ents\n\nimport \"github.com/golangmc/minecraft-server/apis/base\"\n\ntype Entity interface {\n\tSender\n\tbase.Unique\n\n\tEntityUUID() int64\n}\n"
  },
  {
    "path": "apis/ents/living.go",
    "content": "package ents\n\ntype EntityLiving interface {\n\tEntity\n\n\tGetHealth() float64\n\tSetHealth(health float64)\n}\n"
  },
  {
    "path": "apis/ents/player.go",
    "content": "package ents\n\nimport \"github.com/golangmc/minecraft-server/apis/game\"\n\ntype Player interface {\n\tEntityLiving\n\n\tGetGameMode() game.GameMode\n\tSetGameMode(mode game.GameMode)\n\n\tGetIsOnline() bool\n\tSetIsOnline(state bool)\n\n\tGetProfile() *game.Profile\n}\n"
  },
  {
    "path": "apis/ents/sender.go",
    "content": "package ents\n\nimport (\n\t\"github.com/golangmc/minecraft-server/apis/base\"\n)\n\ntype Sender interface {\n\tbase.Named\n\n\tSendMessage(message ...interface{})\n}\n"
  },
  {
    "path": "apis/game/difficulty.go",
    "content": "package game\n\nimport \"fmt\"\n\ntype Difficulty byte\n\nconst (\n\tPEACEFUL Difficulty = iota\n\tEASY\n\tNORMAL\n\tHARD\n)\n\nfunc (d Difficulty) String() string {\n\tswitch d {\n\tcase PEACEFUL:\n\t\treturn \"Peaceful\"\n\tcase EASY:\n\t\treturn \"Easy\"\n\tcase NORMAL:\n\t\treturn \"Normal\"\n\tcase HARD:\n\t\treturn \"Hard\"\n\tdefault:\n\t\tpanic(fmt.Errorf(\"no difficulty for id %d\", byte(d)))\n\t}\n}\n\nfunc ValueOfDifficulty(d Difficulty) byte {\n\treturn byte(d)\n}\n\nfunc DifficultyValueOf(id byte) Difficulty {\n\tswitch id {\n\tcase 0:\n\t\treturn PEACEFUL\n\tcase 1:\n\t\treturn EASY\n\tcase 2:\n\t\treturn NORMAL\n\tcase 3:\n\t\treturn HARD\n\tdefault:\n\t\tpanic(fmt.Errorf(\"no difficulty for id %d\", id))\n\t}\n}\n"
  },
  {
    "path": "apis/game/dimension.go",
    "content": "package game\n\ntype Dimension int\n\nconst (\n\tNETHER    = -1\n\tOVERWORLD = 0\n\tTHE_END   = 1\n)\n"
  },
  {
    "path": "apis/game/event/block.go",
    "content": "package event\n\nimport (\n\t\"github.com/golangmc/minecraft-server/apis/game/level\"\n)\n\ntype BlockEvent struct {\n\tlevel.Block\n}\n\ntype BlockBreakEvent struct {\n\tBlockEvent\n\tPlayerEvent\n\tCancellable\n}\n"
  },
  {
    "path": "apis/game/event/cancel.go",
    "content": "package event\n\ntype Cancellable struct {\n\tcancelled bool\n}\n\nfunc (c *Cancellable) GetCancelled() bool {\n\treturn c.cancelled\n}\n\nfunc (c *Cancellable) SetCancelled(cancelled bool) {\n\tc.cancelled = cancelled\n}\n"
  },
  {
    "path": "apis/game/event/player.go",
    "content": "package event\n\nimport \"github.com/golangmc/minecraft-server/apis/ents\"\n\ntype PlayerEvent struct {\n\tents.Player\n}\n\ntype PlayerJoinEvent struct {\n\tPlayerEvent\n}\n\ntype PlayerQuitEvent struct {\n\tPlayerEvent\n}\n"
  },
  {
    "path": "apis/game/gamemode.go",
    "content": "package game\n\ntype GameMode int\n\nconst (\n\tSURVIVAL GameMode = iota\n\tCREATIVE\n\tADVENTURE\n\tSPECTATOR\n)\n\nfunc (g GameMode) Encoded(hardcore bool) byte {\n\n\tbit := 0\n\tif hardcore {\n\t\tbit = 0x8\n\t}\n\n\treturn byte(g) | byte(bit)\n}\n"
  },
  {
    "path": "apis/game/level/block.go",
    "content": "package level\n\ntype Block interface {\n\tX() int\n\tY() int\n\tZ() int\n\n\tChunk() Chunk\n\tLevel() Level\n\n\tGetBlockType() int\n\tSetBlockType(value int)\n}\n"
  },
  {
    "path": "apis/game/level/chunk.go",
    "content": "package level\n\nimport (\n\t\"github.com/golangmc/minecraft-server/apis/buff\"\n\t\"github.com/golangmc/minecraft-server/apis/data/tags\"\n)\n\ntype Chunk interface {\n\tbuff.BufferPush\n\n\tChunkX() int\n\tChunkZ() int\n\n\tSlices() []Slice\n\n\tLevel() Level\n\n\t// supports values y:[0:15]\n\tGetSlice(y int) Slice\n\n\t// supports values x:[0:15] y:[0:255] z: [0:15]\n\tGetBlock(x, y, z int) Block\n\n\tHeightMapNbtCompound() *tags.NbtCompound\n}\n"
  },
  {
    "path": "apis/game/level/level.go",
    "content": "package level\n\nimport \"github.com/golangmc/minecraft-server/apis/base\"\n\ntype Level interface {\n\tbase.Named\n\tbase.Unique\n\n\tChunks() []Chunk\n\n\tGetChunk(x, z int) Chunk\n\n\tGetChunkIfLoaded(x, z int) Chunk\n\n\tGetBlock(x, y, z int) Block\n}\n"
  },
  {
    "path": "apis/game/level/slice.go",
    "content": "package level\n\nimport (\n\t\"github.com/golangmc/minecraft-server/apis/buff\"\n)\n\ntype Slice interface {\n\tbuff.BufferPush\n\n\tIndex() int\n\n\tChunk() Chunk\n\tLevel() Level\n\n\t// supports values x:[0:15] y:[0:15] z: [0:15]\n\tGetBlock(x, y, z int) Block\n}\n"
  },
  {
    "path": "apis/game/level/value.go",
    "content": "package level\n\nconst (\n\tChunkW = 16\n\tChunkH = 256\n\tChunkL = 16\n\n\tSliceC = 16\n\tSliceH = ChunkH / SliceC\n\n\tSliceS = ChunkW * ChunkL * SliceH\n\n\tBitsPerBlock = 14\n\tMaxPaletteID = (1 << BitsPerBlock) - 1\n)\n"
  },
  {
    "path": "apis/game/leveltype.go",
    "content": "package game\n\ntype LevelType int\n\nconst (\n\tDEFAULT LevelType = iota\n\tFLAT\n\tLARGEBIOMES\n\tAMPLIFIED\n\tCUSTOMIZED\n\tBUFFET\n\tDEFAULT11\n)\n\nvar typeToName = map[LevelType]string{\n\tDEFAULT:     \"default\",\n\tFLAT:        \"flat\",\n\tLARGEBIOMES: \"largeBiomes\",\n\tAMPLIFIED:   \"amplified\",\n\tCUSTOMIZED:  \"customized\",\n\tBUFFET:      \"buffet\",\n\tDEFAULT11:   \"default_1_1\",\n}\n\nfunc (l LevelType) String() string {\n\treturn typeToName[l]\n}\n"
  },
  {
    "path": "apis/game/profile.go",
    "content": "package game\n\nimport \"github.com/golangmc/minecraft-server/apis/uuid\"\n\ntype Profile struct {\n\tUUID uuid.UUID\n\tName string\n\n\tProperties []*ProfileProperty\n}\n\ntype ProfileProperty struct {\n\tName      string\n\tValue     string\n\tSignature *string\n}\n"
  },
  {
    "path": "apis/logs/logging.go",
    "content": "package logs\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"os\"\n\t\"time\"\n\n\t\"github.com/fatih/color\"\n\n\t\"github.com/golangmc/minecraft-server/apis/base\"\n\t\"github.com/golangmc/minecraft-server/apis/data/chat\"\n)\n\ntype LogLevel int\n\nconst (\n\tInfo LogLevel = iota\n\tWarn\n\tFail\n\tData\n)\n\nvar BasicLevel = []LogLevel{Info, Warn, Fail}\nvar EveryLevel = []LogLevel{Info, Warn, Fail, Data}\n\ntype Logging struct {\n\tname   string\n\twriter io.Writer\n\tshow   []LogLevel\n}\n\nfunc (log *Logging) Name() string {\n\treturn log.name\n}\n\nfunc (log *Logging) Show() []LogLevel {\n\treturn log.show\n}\n\nfunc (log *Logging) formatPrint(level, message string) {\n\t_, _ = fmt.Fprint(log.writer, fmt.Sprintf(\"[%s] [%s] [%s] %s\\n\", color.HiGreenString(currentTimeAsText()), level, color.WhiteString(log.Name()), chat.TranslateConsole(message)))\n}\n\nfunc (log *Logging) info(message string) {\n\tlog.formatPrint(color.CyanString(\"INFO\"), message)\n}\n\nfunc (log *Logging) warn(message string) {\n\tlog.formatPrint(color.YellowString(\"WARN\"), message)\n}\n\nfunc (log *Logging) fail(message string) {\n\tlog.formatPrint(color.RedString(\"FAIL\"), message)\n}\n\nfunc (log *Logging) data(message string) {\n\tlog.formatPrint(color.MagentaString(\"DATA\"), message)\n}\n\nfunc (log *Logging) Info(message ...interface{}) {\n\tif !checkIfLevelShows(log, Info) {\n\t\treturn\n\t}\n\n\tlog.info(base.ConvertToString(message...))\n}\n\nfunc (log *Logging) Warn(message ...interface{}) {\n\tif !checkIfLevelShows(log, Warn) {\n\t\treturn\n\t}\n\n\tlog.warn(base.ConvertToString(message...))\n}\n\nfunc (log *Logging) Fail(message ...interface{}) {\n\tif !checkIfLevelShows(log, Fail) {\n\t\treturn\n\t}\n\n\tlog.fail(base.ConvertToString(message...))\n}\n\nfunc (log *Logging) Data(message ...interface{}) {\n\tif !checkIfLevelShows(log, Data) {\n\t\treturn\n\t}\n\n\tlog.data(base.ConvertToString(message...))\n}\n\nfunc (log *Logging) InfoF(format string, a ...interface{}) {\n\tif !checkIfLevelShows(log, Info) {\n\t\treturn\n\t}\n\n\tlog.info(fmt.Sprintf(format, a...))\n}\n\nfunc (log *Logging) WarnF(format string, a ...interface{}) {\n\tif !checkIfLevelShows(log, Warn) {\n\t\treturn\n\t}\n\n\tlog.warn(fmt.Sprintf(format, a...))\n}\n\nfunc (log *Logging) FailF(format string, a ...interface{}) {\n\tif !checkIfLevelShows(log, Fail) {\n\t\treturn\n\t}\n\n\tlog.fail(fmt.Sprintf(format, a...))\n}\n\nfunc (log *Logging) DataF(format string, a ...interface{}) {\n\tif !checkIfLevelShows(log, Data) {\n\t\treturn\n\t}\n\n\tlog.data(fmt.Sprintf(format, a...))\n}\n\nfunc NewLogging(name string, show ...LogLevel) *Logging {\n\treturn NewLoggingWith(name, os.Stdout, show...)\n}\n\nfunc NewLoggingWith(name string, writer io.Writer, show ...LogLevel) *Logging {\n\treturn &Logging{name: name, writer: writer, show: show}\n}\n\nfunc currentTimeAsText() string {\n\th, m, s := time.Now().Clock()\n\treturn fmt.Sprintf(\"%02d:%02d:%02d\", h, m, s)\n}\n\nfunc checkIfLevelShows(log *Logging, lvl LogLevel) bool {\n\tfor _, a := range log.Show() {\n\t\tif a == lvl {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n"
  },
  {
    "path": "apis/math/vector.go",
    "content": "package math\n\ntype Vector2F struct {\n\tX float64\n\tZ float64\n}\n\ntype Vector3F struct {\n\tVector2F\n\tY float64\n}\n"
  },
  {
    "path": "apis/rand/random.go",
    "content": "package rand\n\nimport \"crypto/rand\"\n\nfunc RandomByteArray(len int) []byte {\n\tarray := make([]byte, 4)\n\t_, _ = rand.Read(array)\n\n\treturn array\n}\n"
  },
  {
    "path": "apis/server.go",
    "content": "package apis\n\nimport (\n\t\"sync\"\n\n\t\"github.com/golangmc/minecraft-server/apis/cmds\"\n\t\"github.com/golangmc/minecraft-server/apis/ents\"\n\t\"github.com/golangmc/minecraft-server/apis/logs\"\n\t\"github.com/golangmc/minecraft-server/apis/task\"\n\t\"github.com/golangmc/minecraft-server/apis/util\"\n\t\"github.com/golangmc/minecraft-server/apis/uuid\"\n\n\tapis_base \"github.com/golangmc/minecraft-server/apis/base\"\n\timpl_base \"github.com/golangmc/minecraft-server/impl/base\"\n)\n\ntype Server interface {\n\tapis_base.State\n\n\tLogging() *logs.Logging\n\n\tCommand() *cmds.CommandManager\n\n\tTasking() *task.Tasking\n\n\tWatcher() util.Watcher\n\n\tPlayers() []ents.Player\n\n\tConnByUUID(uuid uuid.UUID) impl_base.Connection\n\n\tPlayerByUUID(uuid uuid.UUID) ents.Player\n\n\tPlayerByConn(conn impl_base.Connection) ents.Player\n\n\tServerVersion() string\n\n\tBroadcast(message string)\n}\n\nvar instance *Server\nvar syncOnce sync.Once\n\nfunc MinecraftServer() Server {\n\tif instance == nil {\n\t\tpanic(\"server is unavailable\")\n\t}\n\n\treturn *instance\n}\n\nfunc SetMinecraftServer(server Server) {\n\tsyncOnce.Do(func() {\n\t\tinstance = &server\n\t})\n}\n"
  },
  {
    "path": "apis/task/tasking.go",
    "content": "package task\n\nimport (\n\t\"fmt\"\n\t\"sync/atomic\"\n\t\"time\"\n\n\t\"github.com/golangmc/minecraft-server/apis/base\"\n)\n\ntype Task struct {\n\tuuid int64\n\texec *func(task *Task)\n\n\tcancel bool\n\tperiod int64\n\tpaused int64\n\ttasker *Tasking\n}\n\ntype Tasking struct {\n\t// milliseconds per tick\n\tmpt int64\n\n\t// uuid -> task\n\ttasks map[int64]*Task\n\n\t// task -> last ran\n\tticks map[*Task]int64\n\t// time -> tasks\n\tqueue map[int64][]*Task\n\n\tnext uint64\n\tdone bool\n\tkill chan bool\n}\n\nfunc NewTasking(mpt int64) *Tasking {\n\treturn &Tasking{\n\t\tmpt: mpt,\n\n\t\ttasks: make(map[int64]*Task),\n\t\tticks: make(map[*Task]int64),\n\t\tqueue: make(map[int64][]*Task),\n\t}\n}\n\nfunc (t *Tasking) Load() {\n\tt.done = false\n\tt.kill = make(chan bool, 1)\n\n\tgo t.tick()\n}\n\nfunc (t *Tasking) Kill() {\n\tif t.done {\n\t\treturn\n\t}\n\n\tt.done = true\n\tt.kill <- true\n\n\tfor k := range t.ticks {\n\t\tdelete(t.ticks, k)\n\t}\n\n\tfor k := range t.queue {\n\t\tdelete(t.queue, k)\n\t}\n\n\tfor k, v := range t.tasks {\n\t\tdelete(t.tasks, k)\n\t\tv.Cancel()\n\t}\n\n\tclose(t.kill)\n}\n\nfunc (t *Tasking) tick() {\n\ttick := time.NewTicker(time.Millisecond)\n\tdefer tick.Stop()\n\n\tfor {\n\t\tselect {\n\t\tcase <-t.kill:\n\t\t\treturn\n\t\tcase curr := <-tick.C:\n\t\t\tt.tickQueue(curr)\n\t\t\tt.tickTasks(curr)\n\t\t}\n\t}\n}\n\nfunc (t *Tasking) tickTasks(curr time.Time) {\n\tunix := curr.UnixNano() / 1e6\n\n\tfor task, last := range t.ticks {\n\t\tif unix-last < task.period {\n\t\t\tcontinue // not ready to be executed\n\t\t}\n\n\t\tif err := task.attemptExec(); err != nil {\n\t\t\ttask.cancel = true\n\t\t\tfmt.Printf(\"%v\", err)\n\t\t}\n\n\t\tif task.cancel || task.period <= 0 {\n\t\t\tdelete(t.ticks, task)\n\t\t} else {\n\t\t\tt.ticks[task] = unix\n\t\t}\n\t}\n}\n\nfunc (t *Tasking) tickQueue(curr time.Time) {\n\t// this is for handling the delayed tasks\n\t// delay gets counted down, and then the tasks are added to the queue used for tickTasks\n\n\tunix := curr.UnixNano() / 1e6\n\n\tfor when, tasks := range t.queue {\n\t\tif unix < when {\n\t\t\tcontinue // not ready to be executed\n\t\t}\n\n\t\tdelete(t.queue, when)\n\n\t\tfor _, task := range tasks {\n\t\t\tt.ticks[task] = 0\n\t\t}\n\t}\n}\n\nfunc (t *Tasking) nextTaskU() int64 {\n\treturn int64(atomic.AddUint64(&t.next, 1))\n}\n\nfunc (t *Tasking) repeats(period int64, function func(task *Task)) {\n\ttask := t.newTask(period, 0, &function)\n\n\tt.ticks[task] = 0\n\tt.tasks[task.uuid] = task\n}\n\nfunc (t *Tasking) delayed(paused int64, function func(task *Task)) {\n\ttask := t.newTask(0, paused, &function)\n\n\tunix := time.Now().UnixNano() / 1e6\n\twhen := unix + paused\n\n\tqueue, exists := t.queue[when]\n\n\tif !exists {\n\t\tqueue = make([]*Task, 0)\n\t}\n\n\tqueue = append(queue, task)\n\n\tt.queue[when] = queue\n\tt.tasks[task.uuid] = task\n}\n\n// repeats the function every period, in ticks\nfunc (t *Tasking) Every(period int64, function func(task *Task)) {\n\tt.repeats(period*t.mpt, function)\n}\n\n// executes the function after paused, in ticks\nfunc (t *Tasking) After(paused int64, function func(task *Task)) {\n\tt.delayed(paused*t.mpt, function)\n}\n\nfunc (t *Tasking) EveryTime(period int64, duration time.Duration, function func(task *Task)) {\n\tt.repeats(period*duration.Milliseconds(), function)\n}\n\nfunc (t *Tasking) AfterTime(paused int64, duration time.Duration, function func(task *Task)) {\n\tt.delayed(paused*duration.Milliseconds(), function)\n}\n\nfunc (t *Tasking) newTask(period int64, paused int64, function *func(task *Task)) *Task {\n\treturn &Task{\n\t\ttasker: t,\n\t\tuuid:   t.nextTaskU(),\n\t\texec:   function,\n\t\tperiod: period,\n\t\tpaused: paused,\n\t}\n}\n\nfunc (t *Task) attemptExec() (error error) {\n\treturn base.Attempt(func() { (*t.exec)(t) })\n}\n\nfunc (t *Task) Cancel() {\n\tt.cancel = true\n}\n\nfunc (t *Task) Tasker() *Tasking {\n\treturn t.tasker\n}\n"
  },
  {
    "path": "apis/task/tasking_test.go",
    "content": "package task\n\nimport (\n\t\"fmt\"\n\t\"testing\"\n)\n\nfunc TestTasker_Load(t *testing.T) {\n\n\ttasker := NewTasking(1_000 / 20)\n\ttasker.Load()\n\n\ttasker.Every(20, printCurrentTask)\n\n\tdone := <-tasker.kill\n\tfmt.Printf(\"Tasker done: %t\\n\", done)\n}\n\nvar count = 0\n\nfunc printCurrentTask(_ *Task) {\n\tfmt.Printf(\"Running print task %d\\n\", count)\n\n\tif count++; count >= 2 {\n\t\tpanic(\"hi\")\n\t}\n}\n"
  },
  {
    "path": "apis/urls/urls.go",
    "content": "package urls\n\nimport (\n\t\"io/ioutil\"\n\t\"net/http\"\n)\n\nfunc GetByte(url string) (res []byte, err error) {\n\t// get\n\tout, err := http.Get(url)\n\tif err != nil {\n\t\treturn\n\t}\n\n\t// read body\n\tbdy, err := ioutil.ReadAll(out.Body)\n\tif err != nil {\n\t\treturn\n\t}\n\n\t// assign response\n\tres = bdy\n\n\treturn\n}\n\nfunc GetText(url string) (res string, err error) {\n\tarr, err := GetByte(url)\n\tif err != nil {\n\t\treturn\n\t}\n\n\tres = string(arr)\n\n\treturn\n}\n"
  },
  {
    "path": "apis/util/formats.go",
    "content": "package util\n\nimport (\n\t\"time\"\n\n\t\"github.com/hako/durafmt\"\n)\n\nfunc FormatTime(durationInSeconds int64) string {\n\treturn durafmt.Parse(time.Second * time.Duration(durationInSeconds)).String()\n}\n"
  },
  {
    "path": "apis/util/watcher.go",
    "content": "package util\n\nimport (\n\t\"fmt\"\n\t\"reflect\"\n\t\"sync\"\n)\n\ntype Watcher interface {\n\tHas(topic string) bool\n\n\tPub(topic string, args ...interface{})\n\n\tPubAs(topicValue ...interface{})\n\n\tPubTo(topicType reflect.Type, args ...interface{})\n\n\tSub(topic string, function interface{}) Handler\n\n\tSubAs(function interface{}) Handler\n\n\tSubTo(topicType reflect.Type, function interface{}) Handler\n}\n\ntype Handler interface {\n\tUnSub()\n}\n\nfunc NewWatcher() Watcher {\n\treturn &watcher{\n\t\tlocker: sync.Mutex{},\n\t\ttopics: make(map[string][]*handler),\n\t}\n}\n\ntype watcher struct {\n\tlocker sync.Mutex\n\ttopics map[string][]*handler\n}\n\nfunc (w *watcher) Has(topic string) bool {\n\thandlers, contains := w.topics[topic]\n\n\treturn contains && len(handlers) > 0\n}\n\nfunc (w *watcher) Pub(topic string, args ...interface{}) {\n\tif handlers, contains := w.topics[topic]; contains && len(handlers) > 0 {\n\n\t\tcallArgs := make([]reflect.Value, 0)\n\t\tfor _, arg := range args {\n\t\t\tcallArgs = append(callArgs, reflect.ValueOf(arg))\n\t\t}\n\n\t\tfor _, handler := range handlers {\n\t\t\tif handler.function.Type().NumIn() != len(callArgs) {\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\thandler.function.Call(callArgs)\n\t\t}\n\t}\n}\n\nfunc (w *watcher) PubAs(topicValue ...interface{}) {\n\tw.PubTo(reflect.TypeOf(topicValue[0]), topicValue...)\n}\n\nfunc (w *watcher) PubTo(topicType reflect.Type, args ...interface{}) {\n\tw.Pub(topicType.String(), args...)\n}\n\nfunc (w *watcher) Sub(topic string, function interface{}) Handler {\n\tw.locker.Lock()\n\tdefer w.locker.Unlock()\n\n\t// check if function is actual a function\n\tif reflect.TypeOf(function).Kind() != reflect.Func {\n\t\tpanic(fmt.Errorf(\"cannot sub with %v, must be reflect.Func\", reflect.TypeOf(function).Kind()))\n\t}\n\n\thandler := &handler{\n\t\ttopic:    topic,\n\t\twatch:    w,\n\t\tfunction: reflect.ValueOf(function),\n\t}\n\n\t// append watch handler to topic list\n\tw.topics[topic] = append(w.topics[topic], handler)\n\n\treturn handler\n}\n\nfunc (w *watcher) SubAs(function interface{}) Handler {\n\tfuncType := reflect.TypeOf(function)\n\n\t// check if function is actual a function\n\tif funcType.Kind() != reflect.Func {\n\t\tpanic(fmt.Errorf(\"cannot sub with %v, must be reflect.Func\", funcType.Kind()))\n\t}\n\n\tif funcType.NumIn() == 0 {\n\t\tpanic(fmt.Errorf(\"cannot sub with %v, must have at least 1 input parameter\", funcType))\n\t}\n\n\treturn w.SubTo(funcType.In(0), function)\n}\n\nfunc (w *watcher) SubTo(topicType reflect.Type, function interface{}) Handler {\n\treturn w.Sub(topicType.String(), function)\n}\n\ntype handler struct {\n\ttopic string\n\twatch *watcher\n\n\tfunction reflect.Value\n}\n\nfunc (h *handler) UnSub() {\n\thandlers := h.watch.topics[h.topic]\n\tif handlers == nil {\n\t\treturn\n\t}\n\n\tfor i, elem := range handlers {\n\t\tif elem == h {\n\t\t\th.watch.topics[h.topic] = append(h.watch.topics[h.topic][:i], h.watch.topics[h.topic][i+1:]...)\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "apis/uuid/uuids.go",
    "content": "package uuid\n\nimport (\n\t\"encoding/binary\"\n\n\t\"github.com/satori/go.uuid\"\n)\n\ntype UUID = uuid.UUID\n\nfunc NewUUID() UUID {\n\tgen := uuid.NewV4()\n\t/*if err != nil {\n\t\tpanic(err)\n\t}*/\n\n\treturn gen\n}\n\nfunc TextToUUID(text string) (data UUID, err error) {\n\treturn uuid.FromString(text)\n}\n\nfunc BitsToUUID(msb, lsb int64) (data UUID, err error) {\n\tmBytes := make([]byte, 8)\n\tlBytes := make([]byte, 8)\n\n\tbinary.BigEndian.PutUint64(mBytes, uint64(msb))\n\tbinary.BigEndian.PutUint64(lBytes, uint64(lsb))\n\n\treturn uuid.FromBytes(append(mBytes, lBytes...))\n}\n\nfunc UUIDToText(uuid UUID) (text string, err error) {\n\tdata, err := uuid.MarshalText()\n\n\tif err == nil {\n\t\ttext = string(data)\n\t}\n\n\treturn\n}\n\nfunc SigBits(uuid UUID) (msb, lsb int64) {\n\tbytes := uuid.Bytes()\n\n\tmsb = 0\n\tlsb = 0\n\n\tfor i := 0; i < 8; i++ {\n\t\tmsb = (msb << 0x08) | int64(bytes[i]&0xFF)\n\t}\n\n\tfor i := 8; i < 16; i++ {\n\t\tlsb = (lsb << 0x08) | int64(bytes[i]&0xFF)\n\t}\n\n\treturn\n}\n"
  },
  {
    "path": "go.mod",
    "content": "module github.com/golangmc/minecraft-server\n\ngo 1.13\n\nrequire (\n\tgithub.com/fatih/color v1.9.0\n\tgithub.com/hako/durafmt v0.0.0-20191009132224-3f39dc1ed9f4\n\tgithub.com/mattn/go-colorable v0.1.6 // indirect\n\tgithub.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e // indirect\n\tgithub.com/satori/go.uuid v1.2.0\n\tgolang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527 // indirect\n\tgopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f // indirect\n)\n"
  },
  {
    "path": "go.sum",
    "content": "github.com/fatih/color v1.9.0 h1:8xPHl4/q1VyqGIPif1F+1V3Y3lSmrq01EabUW3CoW5s=\ngithub.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU=\ngithub.com/golangmc/minecraft-server v0.0.0-20200307201348-f5daeb2b6d07 h1:BCos3PMMuZxapSHWy/FfT1PBai2qInTqk1z5JjsiCE4=\ngithub.com/golangmc/minecraft-server v0.0.0-20200307201348-f5daeb2b6d07/go.mod h1:KXyWige3rVvzcZEnSzJJYCeyTdyaBATU03/dVMpS72M=\ngithub.com/hako/durafmt v0.0.0-20191009132224-3f39dc1ed9f4 h1:60gBOooTSmNtrqNaRvrDbi8VAne0REaek2agjnITKSw=\ngithub.com/hako/durafmt v0.0.0-20191009132224-3f39dc1ed9f4/go.mod h1:5Scbynm8dF1XAPwIwkGPqzkM/shndPm79Jd1003hTjE=\ngithub.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=\ngithub.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=\ngithub.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=\ngithub.com/mattn/go-colorable v0.1.4 h1:snbPLB8fVfU9iwbbo30TPtbLRzwWu6aJS6Xh4eaaviA=\ngithub.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=\ngithub.com/mattn/go-colorable v0.1.6 h1:6Su7aK7lXmJ/U79bYtBjLNaha4Fs1Rg9plHpcH+vvnE=\ngithub.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=\ngithub.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=\ngithub.com/mattn/go-isatty v0.0.11 h1:FxPOTFNqGkuDUGi3H/qkUbQO4ZiBa2brKq5r0l8TGeM=\ngithub.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE=\ngithub.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY=\ngithub.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=\ngithub.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs=\ngithub.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=\ngithub.com/satori/go.uuid v1.2.0 h1:0uYX9dsZ2yD7q2RtLRtPSdGDWzjeM3TbMJP9utgA0ww=\ngithub.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0=\ngolang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=\ngolang.org/x/sys v0.0.0-20191026070338-33540a1f6037 h1:YyJpGZS1sBuBCzLAR1VEpK193GlqGZbnPFnPV/5Rsb4=\ngolang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527 h1:uYVVQ9WP/Ds2ROhcaGPeIdVq0RIXVLwsHlnvJ+cT1So=\ngolang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU=\ngopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=\n"
  },
  {
    "path": "impl/base/combine.go",
    "content": "package base\n\nimport \"github.com/golangmc/minecraft-server/apis/ents\"\n\ntype PlayerAndConnection struct {\n\tConnection\n\tents.Player\n}\n"
  },
  {
    "path": "impl/base/compact.go",
    "content": "package base\n\ntype Compacter struct {\n\tValues []int64\n\n\tbpb int\n\tmax int\n}\n\nfunc NewCompacter(bits, size int) *Compacter {\n\tsliceSize := iDontKnowWhatThisDoes(size*bits, 64) / 64\n\n\treturn &Compacter{\n\t\tbpb:    bits,\n\t\tmax:    (1 << bits) - 1,\n\t\tValues: make([]int64, sliceSize, sliceSize),\n\t}\n}\n\nfunc (c *Compacter) Set(index int, value int) int {\n\tbIndex := index * c.bpb\n\n\tsIndex := bIndex >> 0x06\n\teIndex := (((index + 1) * c.bpb) - 1) >> 0x06\n\n\tuIndex := bIndex ^ (sIndex << 0x06)\n\n\tpreviousValue := int64(uint64(c.Values[sIndex])>>uIndex) & int64(c.max)\n\n\tc.Values[sIndex] = c.Values[sIndex]&int64(^(c.max<<uIndex)) | int64((value&c.max)<<uIndex)\n\n\tif sIndex != eIndex {\n\t\tzIndex := 64 - uIndex\n\t\tpIndex := c.bpb - 1\n\n\t\tpreviousValue |= (c.Values[eIndex] << zIndex) & int64(c.max)\n\n\t\tc.Values[eIndex] = int64(((uint64(c.Values[eIndex]) >> pIndex) << pIndex) | uint64((value&c.max)>>zIndex))\n\t}\n\n\treturn int(previousValue)\n}\n\nfunc (c *Compacter) Get(index int) int {\n\tbIndex := index * c.bpb\n\n\tsIndex := bIndex >> 0x06\n\teIndex := (((index + 1) * c.bpb) - 1) >> 0x06\n\n\tuIndex := bIndex ^ (sIndex << 0x06)\n\n\tif sIndex == eIndex {\n\t\treturn int((uint64(c.Values[sIndex]) >> uIndex) & uint64(c.max))\n\t}\n\n\tzIndex := 64 - uIndex\n\n\treturn int(uint64(c.Values[sIndex]>>uIndex) | uint64(c.Values[eIndex]<<zIndex)&uint64(c.max))\n}\n\nfunc iDontKnowWhatThisDoes(var0, var1 int) int {\n\tif var1 == 0 {\n\t\treturn 0\n\t} else if var0 == 0 {\n\t\treturn var1\n\t} else {\n\t\tif var0 < 0 {\n\t\t\tvar1 *= -1\n\t\t}\n\n\t\tvar2 := var0 % var1\n\n\t\tif var2 == 0 {\n\t\t\treturn var0\n\t\t} else {\n\t\t\treturn var0 + var1 - var2\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "impl/base/connect.go",
    "content": "package base\n\nimport \"net\"\n\ntype Connection interface {\n\tAddress() net.Addr\n\n\tGetState() PacketState\n\tSetState(state PacketState)\n\n\tEncrypt(data []byte) (output []byte)\n\tDecrypt(data []byte) (output []byte)\n\n\tCertifyName() string\n\n\tCertifyData() []byte\n\n\tCertifyValues(name string)\n\tCertifyUpdate(secret []byte)\n\n\tDeflate(data []byte) (output []byte)\n\tInflate(data []byte) (output []byte)\n\n\tPull(data []byte) (len int, err error)\n\tPush(data []byte) (len int, err error)\n\n\tStop() (err error)\n\n\tSendPacket(packet PacketO)\n}\n"
  },
  {
    "path": "impl/base/network.go",
    "content": "package base\n\nimport (\n\t\"github.com/golangmc/minecraft-server/apis/base\"\n)\n\ntype Network interface {\n\tbase.State\n}\n"
  },
  {
    "path": "impl/base/packets.go",
    "content": "package base\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/golangmc/minecraft-server/apis/buff\"\n\t\"github.com/golangmc/minecraft-server/apis/util\"\n)\n\ntype PacketState int\n\nconst (\n\tSHAKE PacketState = iota\n\tSTATUS\n\tLOGIN\n\tPLAY\n)\n\nfunc ValueOfPacketState(s PacketState) int {\n\treturn int(s)\n}\n\nfunc PacketStateValueOf(s int) PacketState {\n\tswitch s {\n\tcase 0:\n\t\treturn SHAKE\n\tcase 1:\n\t\treturn STATUS\n\tcase 2:\n\t\treturn LOGIN\n\tcase 3:\n\t\treturn PLAY\n\tdefault:\n\t\tpanic(fmt.Errorf(\"no state for value: %d\", s))\n\t}\n}\n\nfunc (state PacketState) String() string {\n\tswitch state {\n\tcase SHAKE:\n\t\treturn \"Shake\"\n\tcase STATUS:\n\t\treturn \"Status\"\n\tcase LOGIN:\n\t\treturn \"Login\"\n\tcase PLAY:\n\t\treturn \"Play\"\n\tdefault:\n\t\tpanic(fmt.Errorf(\"no state for value: %d\", state))\n\t}\n}\n\nfunc (state PacketState) Next() PacketState {\n\tswitch state {\n\tcase SHAKE:\n\t\treturn STATUS\n\tcase STATUS:\n\t\treturn LOGIN\n\tcase LOGIN:\n\t\treturn PLAY\n\tcase PLAY:\n\t\treturn SHAKE\n\tdefault:\n\t\tpanic(fmt.Errorf(\"no state for value: %d\", state))\n\t}\n}\n\ntype Packet interface {\n\t// the uuid of this packet\n\tUUID() int32\n}\n\ntype PacketI interface {\n\tPacket\n\n\t// decode the server_data from the reader into this packet\n\tPull(reader buff.Buffer, conn Connection)\n}\n\ntype PacketO interface {\n\tPacket\n\n\t// encode the server_data from the packet into this writer\n\tPush(writer buff.Buffer, conn Connection)\n}\n\ntype Packets interface {\n\tutil.Watcher\n\n\t/*GetPacketM(uuid int32, state PacketState) (pid int32, cont bool)*/\n\n\tGetPacketI(uuid int32, state PacketState) PacketI\n\n\t/*GetPacketO(uuid int32, state PacketState) PacketO*/\n}\n"
  },
  {
    "path": "impl/conf/config.go",
    "content": "package conf\n\nvar DefaultServerConfig = ServerConfig{\n\tNetwork: Network{\n\t\tHost: \"0.0.0.0\",\n\t\tPort: 25565,\n\t},\n}\n\ntype ServerConfig struct {\n\tNetwork Network\n}\n\ntype Network struct {\n\tHost string `toml:\"host\"`\n\tPort int    `toml:\"port\"`\n}\n"
  },
  {
    "path": "impl/conn/buffers.go",
    "content": "package conn\n\nimport (\n\t\"encoding/binary\"\n\t\"fmt\"\n\t\"math\"\n\t\"strconv\"\n\n\t\"github.com/golangmc/minecraft-server/apis/buff\"\n\t\"github.com/golangmc/minecraft-server/apis/data\"\n\t\"github.com/golangmc/minecraft-server/apis/data/tags\"\n\t\"github.com/golangmc/minecraft-server/apis/uuid\"\n)\n\n/*\n Language used:\n\t- Len = Length\n\t- Arr = Array\n\n\t- Bit = Boolean\n\t- Byt = Byte\n\t- Int = int\n\t- VrI = VarInt\n\t- Srt = Short\n\t- Txt = String\n*/\n\ntype buffer struct {\n\tiIndex int32\n\toIndex int32\n\n\tbArray []byte\n}\n\nfunc (b *buffer) String() string {\n\treturn fmt.Sprintf(\"Buffer[%d](i: %d, o: %d)%v\", b.Len(), b.iIndex, b.oIndex, b.bArray)\n}\n\n// new\nfunc NewBuffer() buff.Buffer {\n\treturn NewBufferWith(make([]byte, 0))\n}\n\nfunc NewBufferWith(bArray []byte) buff.Buffer {\n\treturn &buffer{bArray: bArray}\n}\n\n// server_data\nfunc (b *buffer) Len() int32 {\n\treturn int32(len(b.bArray))\n}\n\nfunc (b *buffer) SAS() []int8 {\n\treturn asSArray(b.bArray)\n}\n\nfunc (b *buffer) UAS() []byte {\n\treturn b.bArray\n}\n\nfunc (b *buffer) InI() int32 {\n\treturn b.iIndex\n}\n\nfunc (b *buffer) InO() int32 {\n\treturn b.oIndex\n}\n\nfunc (b *buffer) SkpAll() {\n\tb.SkpLen(b.Len() - 1)\n}\n\nfunc (b *buffer) SkpLen(delta int32) {\n\tb.iIndex += delta\n}\n\n// pull\nfunc (b *buffer) PullBit() bool {\n\treturn b.pullNext() != 0\n}\n\nfunc (b *buffer) PullByt() byte {\n\treturn b.pullNext()\n}\n\nfunc (b *buffer) PullI16() int16 {\n\treturn int16(binary.BigEndian.Uint16(b.pullSize(4)))\n}\n\nfunc (b *buffer) PullU16() uint16 {\n\treturn uint16(b.pullNext())<<8 | uint16(b.pullNext())\n}\n\nfunc (b *buffer) PullI32() int32 {\n\treturn int32(binary.BigEndian.Uint32(b.pullSize(4)))\n}\n\nfunc (b *buffer) PullI64() int64 {\n\treturn int64(b.PullU64())\n}\n\nfunc (b *buffer) PullU64() uint64 {\n\treturn binary.BigEndian.Uint64(b.pullSize(8))\n}\n\nfunc (b *buffer) PullF32() float32 {\n\treturn math.Float32frombits(binary.BigEndian.Uint32(b.pullSize(4)))\n}\n\nfunc (b *buffer) PullF64() float64 {\n\treturn math.Float64frombits(binary.BigEndian.Uint64(b.pullSize(8)))\n}\n\nfunc (b *buffer) PullVrI() int32 {\n\treturn int32(b.pullVariable(5))\n}\n\nfunc (b *buffer) PullVrL() int64 {\n\treturn b.pullVariable(10)\n}\n\nfunc (b *buffer) PullTxt() string {\n\treturn string(b.PullUAS())\n}\n\nfunc (b *buffer) PullUAS() []byte {\n\tsze := b.PullVrI()\n\tarr := b.bArray[b.iIndex : b.iIndex+sze]\n\n\tb.iIndex += sze\n\n\treturn arr\n}\n\nfunc (b *buffer) PullSAS() []int8 {\n\treturn asSArray(b.PullUAS())\n}\n\nfunc (b *buffer) PullUID() uuid.UUID {\n\tdata, _ := uuid.BitsToUUID(b.PullI64(), b.PullI64())\n\n\treturn data\n}\n\nfunc (b *buffer) PullPos() data.PositionI {\n\tval := b.PullU64()\n\n\tx := int64(val) >> 38\n\ty := int64(val) & 0xFFF\n\tz := int64(val) << 26 >> 38\n\n\treturn data.PositionI{\n\t\tX: x,\n\t\tY: y,\n\t\tZ: z,\n\t}\n}\n\nfunc (b *buffer) PullNbt() *tags.NbtCompound {\n\ttyp := tags.Typ(b.PullByt())\n\n\tfmt.Println(\"==type\")\n\tfmt.Println(typ)\n\n\tif typ != tags.TAG_Compound {\n\t\tpanic(\"root tag must be compound\") // probably shouldn't panic?\n\t}\n\n\tname := b.PullTxt()\n\tif len(name) != 0 {\n\t\tpanic(\"root compound should have an empty name\")\n\t}\n\n\tfmt.Println(\"==name\")\n\tfmt.Println(name)\n\n\ttag := &tags.NbtCompound{}\n\tb.pullNbt(tag)\n\n\treturn tag\n}\n\n// push\nfunc (b *buffer) PushBit(data bool) {\n\tif data {\n\t\tb.pushNext(byte(0x01))\n\t} else {\n\t\tb.pushNext(byte(0x00))\n\t}\n}\n\nfunc (b *buffer) PushByt(data byte) {\n\tb.pushNext(data)\n}\n\nfunc (b *buffer) PushI16(data int16) {\n\tb.pushNext(\n\t\tbyte(data)>>8,\n\t\tbyte(data))\n}\n\nfunc (b *buffer) PushI32(data int32) {\n\tb.pushNext(\n\t\tbyte(data>>24),\n\t\tbyte(data>>16),\n\t\tbyte(data>>8),\n\t\tbyte(data))\n}\n\nfunc (b *buffer) PushI64(data int64) {\n\tb.pushNext(\n\t\tbyte(data>>56),\n\t\tbyte(data>>48),\n\t\tbyte(data>>40),\n\t\tbyte(data>>32),\n\t\tbyte(data>>24),\n\t\tbyte(data>>16),\n\t\tbyte(data>>8),\n\t\tbyte(data))\n}\n\nfunc (b *buffer) PushF32(data float32) {\n\tb.PushI32(int32(math.Float32bits(data)))\n}\n\nfunc (b *buffer) PushF64(data float64) {\n\tb.PushI64(int64(math.Float64bits(data)))\n}\n\nfunc (b *buffer) PushVrI(data int32) {\n\tfor {\n\t\ttemp := data & 0x7F\n\t\tdata >>= 7\n\n\t\tif data != 0 {\n\t\t\ttemp |= 0x80\n\t\t}\n\n\t\tb.pushNext(byte(temp))\n\n\t\tif data == 0 {\n\t\t\tbreak\n\t\t}\n\t}\n}\n\nfunc (b *buffer) PushVrL(data int64) {\n\tfor {\n\t\ttemp := data & 0x7F\n\t\tdata >>= 7\n\n\t\tif data != 0 {\n\t\t\ttemp |= 0x80\n\t\t}\n\n\t\tb.pushNext(byte(temp))\n\n\t\tif data == 0 {\n\t\t\tbreak\n\t\t}\n\t}\n}\n\nfunc (b *buffer) PushTxt(data string) {\n\tb.PushUAS([]byte(data), true)\n}\n\nfunc (b *buffer) PushUAS(data []byte, prefixWithLen bool) {\n\tif prefixWithLen {\n\t\tb.PushVrI(int32(len(data)))\n\t}\n\n\tb.pushNext(data...)\n}\n\nfunc (b *buffer) PushSAS(data []int8, prefixWithLen bool) {\n\tb.PushUAS(asUArray(data), prefixWithLen)\n}\n\nfunc (b *buffer) PushUID(data uuid.UUID) {\n\tmsb, lsb := uuid.SigBits(data)\n\n\tb.PushI64(msb)\n\tb.PushI64(lsb)\n}\n\nfunc (b *buffer) PushPos(data data.PositionI) {\n\tb.PushI64(((data.X & 0x3FFFFFF) << 38) | ((data.Z & 0x3FFFFFF) << 12) | (data.Y & 0xFFF))\n}\n\nfunc (b *buffer) PushNbt(data *tags.NbtCompound) {\n\tif data == nil {\n\t\tb.PushByt(0)\n\t} else {\n\t\tb.PushByt(byte(data.Type()))\n\n\t\tb.pushNext(0, 0)\n\n\t\tb.pushNbt(data)\n\t}\n}\n\n// internal\nfunc (b *buffer) pullNext() byte {\n\n\tif b.iIndex >= b.Len() {\n\t\treturn 0\n\t\t// panic(\"reached end of buffer\")\n\t}\n\n\tnext := b.bArray[b.iIndex]\n\tb.iIndex++\n\n\tif b.oIndex > 0 {\n\t\tb.oIndex--\n\t}\n\n\treturn next\n}\n\nfunc (b *buffer) pullSize(next int) []byte {\n\tbytes := make([]byte, next)\n\n\tfor i := 0; i < next; i++ {\n\t\tbytes[i] = b.pullNext()\n\t}\n\n\treturn bytes\n}\n\nfunc (b *buffer) pushNext(bArray ...byte) {\n\tb.oIndex += int32(len(bArray))\n\tb.bArray = append(b.bArray, bArray...)\n}\n\nfunc (b *buffer) pullVariable(max int) int64 {\n\tvar num int\n\tvar res int64\n\n\tfor {\n\t\ttmp := int64(b.pullNext())\n\t\tres |= (tmp & 0x7F) << uint(num*7)\n\n\t\tif num++; num > max {\n\t\t\tpanic(\"VarInt > \" + strconv.Itoa(max))\n\t\t}\n\n\t\tif tmp&0x80 != 0x80 {\n\t\t\tbreak\n\t\t}\n\t}\n\n\treturn res\n}\n\nfunc asSArray(bytes []byte) []int8 {\n\tarray := make([]int8, 0)\n\n\tfor _, b := range bytes {\n\t\tarray = append(array, int8(b))\n\t}\n\n\treturn array\n}\n\nfunc asUArray(bytes []int8) []byte {\n\tarray := make([]byte, 0)\n\n\tfor _, b := range bytes {\n\t\tarray = append(array, byte(b))\n\t}\n\n\treturn array\n}\n\nvar typeToInst = map[tags.Typ]func() tags.Nbt{\n\ttags.TAG_End: func() tags.Nbt {\n\t\treturn &tags.NbtEnd{}\n\t},\n\ttags.TAG_Byte: func() tags.Nbt {\n\t\treturn &tags.NbtByt{}\n\t},\n\ttags.TAG_Short: func() tags.Nbt {\n\t\treturn &tags.NbtI16{}\n\t},\n\ttags.TAG_Int: func() tags.Nbt {\n\t\treturn &tags.NbtI32{}\n\t},\n\ttags.TAG_Long: func() tags.Nbt {\n\t\treturn &tags.NbtI64{}\n\t},\n\ttags.TAG_Float: func() tags.Nbt {\n\t\treturn &tags.NbtF32{}\n\t},\n\ttags.TAG_Double: func() tags.Nbt {\n\t\treturn &tags.NbtF64{}\n\t},\n\ttags.TAG_Byte_Array: func() tags.Nbt {\n\t\treturn &tags.NbtArrByt{}\n\t},\n\ttags.TAG_String: func() tags.Nbt {\n\t\treturn &tags.NbtTxt{}\n\t},\n\ttags.TAG_List: func() tags.Nbt {\n\t\treturn &tags.NbtArrAny{}\n\t},\n\ttags.TAG_Compound: func() tags.Nbt {\n\t\treturn &tags.NbtCompound{}\n\t},\n\ttags.TAG_Int_Array: func() tags.Nbt {\n\t\treturn &tags.NbtArrI32{}\n\t},\n\ttags.TAG_Long_Array: func() tags.Nbt {\n\t\treturn &tags.NbtArrI64{}\n\t},\n}\n\nfunc (b *buffer) pullNbt(data tags.Nbt) {\n\tswitch data.Type() {\n\tcase tags.TAG_End:\n\t\t// nothing\n\t\tbreak\n\tcase tags.TAG_Byte:\n\t\tdata.(*tags.NbtByt).Value = int8(b.PullByt())\n\t\tbreak\n\tcase tags.TAG_Short:\n\t\tpanic(\"unimplemented\")\n\t\tbreak\n\tcase tags.TAG_Int:\n\t\tpanic(\"unimplemented\")\n\t\tbreak\n\tcase tags.TAG_Long:\n\t\tpanic(\"unimplemented\")\n\t\tbreak\n\tcase tags.TAG_Float:\n\t\tpanic(\"unimplemented\")\n\t\tbreak\n\tcase tags.TAG_Double:\n\t\tpanic(\"unimplemented\")\n\t\tbreak\n\tcase tags.TAG_Byte_Array:\n\t\tpanic(\"unimplemented\")\n\t\tbreak\n\tcase tags.TAG_String:\n\t\tpanic(\"unimplemented\")\n\t\tbreak\n\tcase tags.TAG_List:\n\t\tpanic(\"unimplemented\")\n\t\tbreak\n\tcase tags.TAG_Compound:\n\t\tvalue := make(map[string]tags.Nbt)\n\n\t\tfmt.Println(\"reading compound\")\n\n\t\tfor {\n\t\t\ttyp := tags.Typ(b.PullByt())\n\t\t\tif typ == tags.TAG_End {\n\t\t\t\tfmt.Println(\"encountered break\")\n\t\t\t\tbreak\n\t\t\t}\n\n\t\t\tfmt.Println(\"===type\")\n\t\t\tfmt.Println(typ)\n\n\t\t\tname := b.pullNbtTxt()\n\n\t\t\tfmt.Println(\"===name\")\n\t\t\tfmt.Println(name)\n\n\t\t\tinst := typeToInst[typ]()\n\t\t\tb.pullNbt(inst)\n\n\t\t\tvalue[name] = inst\n\t\t}\n\n\t\tdata.(*tags.NbtCompound).Value = value\n\t\tbreak\n\tcase tags.TAG_Int_Array:\n\t\tpanic(\"unimplemented\")\n\t\tbreak\n\tcase tags.TAG_Long_Array:\n\t\tvalue := make([]int64, b.PullI32())\n\n\t\tfor i := 0; i < len(value); i++ {\n\t\t\tvalue[i] = b.PullI64()\n\t\t}\n\n\t\tdata.(*tags.NbtArrI64).Value = value\n\t\tbreak\n\t}\n}\n\nfunc (b *buffer) pushNbt(data tags.Nbt) {\n\tswitch data.Type() {\n\tcase tags.TAG_End:\n\t\t// nothing\n\t\tbreak\n\tcase tags.TAG_Byte:\n\t\tb.PushByt(byte(data.(*tags.NbtByt).Value))\n\t\tbreak\n\tcase tags.TAG_Short:\n\t\tpanic(\"unimplemented\")\n\t\tbreak\n\tcase tags.TAG_Int:\n\t\tpanic(\"unimplemented\")\n\t\tbreak\n\tcase tags.TAG_Long:\n\t\tpanic(\"unimplemented\")\n\t\tbreak\n\tcase tags.TAG_Float:\n\t\tpanic(\"unimplemented\")\n\t\tbreak\n\tcase tags.TAG_Double:\n\t\tpanic(\"unimplemented\")\n\t\tbreak\n\tcase tags.TAG_Byte_Array:\n\t\tpanic(\"unimplemented\")\n\t\tbreak\n\tcase tags.TAG_String:\n\t\tpanic(\"unimplemented\")\n\t\tbreak\n\tcase tags.TAG_List:\n\t\tpanic(\"unimplemented\")\n\t\tbreak\n\tcase tags.TAG_Compound:\n\t\tfor name, tag := range data.(*tags.NbtCompound).Value {\n\t\t\tb.PushByt(byte(tag.Type()))\n\n\t\t\tif tag.Type() == tags.TAG_End {\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\tb.pushNbtTxt(name)\n\t\t\tb.pushNbt(tag)\n\t\t}\n\n\t\tb.PushByt(0)\n\t\tbreak\n\tcase tags.TAG_Int_Array:\n\t\tpanic(\"unimplemented\")\n\t\tbreak\n\tcase tags.TAG_Long_Array:\n\t\tvalue := data.(*tags.NbtArrI64).Value\n\n\t\tb.PushI32(int32(len(value)))\n\n\t\tfor _, value := range value {\n\t\t\tb.PushI64(value)\n\t\t}\n\n\t\tbreak\n\t}\n}\n\nfunc (b *buffer) pullNbtTxt() string {\n\tsize := b.PullI16()\n\tdata := b.pullSize(int(size))\n\n\treturn string(data)\n}\n\nfunc (b *buffer) pushNbtTxt(data string) {\n\tb.PushI16(int16(len(data)))\n\tb.PushUAS([]byte(data), false)\n}\n"
  },
  {
    "path": "impl/conn/connect.go",
    "content": "package conn\n\nimport (\n\t\"bytes\"\n\t\"compress/zlib\"\n\t\"crypto/cipher\"\n\t\"fmt\"\n\t\"io\"\n\t\"net\"\n\n\t\"github.com/golangmc/minecraft-server/apis/rand\"\n\t\"github.com/golangmc/minecraft-server/impl/base\"\n\t\"github.com/golangmc/minecraft-server/impl/conn/crypto\"\n)\n\ntype connection struct {\n\tnew bool\n\ttcp *net.TCPConn\n\n\tstate base.PacketState\n\n\tcertify Certify\n\tcompact Compact\n}\n\nfunc NewConnection(conn *net.TCPConn) base.Connection {\n\treturn &connection{\n\t\tnew: true,\n\t\ttcp: conn,\n\n\t\tcertify: Certify{},\n\t\tcompact: Compact{},\n\t}\n}\n\nfunc (c *connection) Address() net.Addr {\n\treturn c.tcp.RemoteAddr()\n}\n\nfunc (c *connection) GetState() base.PacketState {\n\treturn c.state\n}\n\nfunc (c *connection) SetState(state base.PacketState) {\n\tc.state = state\n}\n\ntype Certify struct {\n\tname string\n\n\tused bool\n\tdata []byte\n\n\tencrypt cipher.Stream\n\tdecrypt cipher.Stream\n}\n\nfunc (c *connection) Encrypt(data []byte) (output []byte) {\n\tif !c.certify.used {\n\t\treturn data\n\t}\n\n\toutput = make([]byte, len(data))\n\tc.certify.encrypt.XORKeyStream(output, data)\n\n\treturn\n}\n\nfunc (c *connection) Decrypt(data []byte) (output []byte) {\n\tif !c.certify.used {\n\t\treturn data\n\t}\n\n\toutput = make([]byte, len(data))\n\tc.certify.decrypt.XORKeyStream(output, data)\n\n\treturn\n}\n\nfunc (c *connection) CertifyName() string {\n\treturn c.certify.name\n}\n\nfunc (c *connection) CertifyData() []byte {\n\treturn c.certify.data\n}\n\nfunc (c *connection) CertifyUpdate(secret []byte) {\n\tencrypt, decrypt, err := crypto.NewEncryptAndDecrypt(secret)\n\n\tc.certify.encrypt = encrypt\n\tc.certify.decrypt = decrypt\n\n\tif err != nil {\n\t\tpanic(fmt.Errorf(\"failed to enable encryption for user: %s\\n%v\", c.CertifyName(), err))\n\t}\n\n\tc.certify.used = true\n\tc.certify.data = secret\n}\n\nfunc (c *connection) CertifyValues(name string) {\n\tc.certify.name = name\n\tc.certify.data = rand.RandomByteArray(4)\n}\n\ntype Compact struct {\n\tused bool\n\tsize int32\n}\n\nfunc (c *connection) Deflate(data []byte) (output []byte) {\n\tif !c.compact.used {\n\t\treturn data\n\t}\n\n\tvar out bytes.Buffer\n\n\twriter, _ := zlib.NewWriterLevel(&out, zlib.BestCompression)\n\t_, _ = writer.Write(data)\n\t_ = writer.Close()\n\n\toutput = out.Bytes()\n\n\treturn\n}\n\nfunc (c *connection) Inflate(data []byte) (output []byte) {\n\tif !c.compact.used {\n\t\treturn data\n\t}\n\n\treader, err := zlib.NewReader(bytes.NewReader(data))\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\n\tvar out bytes.Buffer\n\t_, _ = io.Copy(&out, reader)\n\n\toutput = out.Bytes()\n\n\treturn\n}\n\nfunc (c *connection) Pull(data []byte) (len int, err error) {\n\tlen, err = c.tcp.Read(data)\n\treturn\n}\n\nfunc (c *connection) Push(data []byte) (len int, err error) {\n\tlen, err = c.tcp.Write(data)\n\treturn\n}\n\nfunc (c *connection) Stop() (err error) {\n\terr = c.tcp.Close()\n\treturn\n}\n\nfunc (c *connection) SendPacket(packet base.PacketO) {\n\tbufO := NewBuffer()\n\ttemp := NewBuffer()\n\n\t// write buffer\n\tbufO.PushVrI(packet.UUID())\n\tpacket.Push(bufO, c)\n\n\ttemp.PushVrI(bufO.Len())\n\ttemp.PushUAS(bufO.UAS(), false)\n\n\t_, _ = c.tcp.Write(c.Encrypt(temp.UAS()))\n}\n"
  },
  {
    "path": "impl/conn/crypto/cfb8.go",
    "content": "package crypto\n\nimport (\n\t\"crypto/aes\"\n\t\"crypto/cipher\"\n)\n\ntype cfb8 struct {\n\tb       cipher.Block\n\tsr      []byte\n\tsrEnc   []byte\n\tsrPos   int\n\tdecrypt bool\n}\n\nfunc newEncrypt(block cipher.Block, iv []byte) cipher.Stream {\n\tif len(iv) != block.BlockSize() {\n\t\tpanic(\"cfb8.newEncrypt: IV length must equal block size\")\n\t}\n\n\treturn newCFB8(block, iv, false)\n}\n\nfunc newDecrypt(block cipher.Block, iv []byte) cipher.Stream {\n\tif len(iv) != block.BlockSize() {\n\t\tpanic(\"cfb8.newDecrypt: IV length must equal block size\")\n\t}\n\n\treturn newCFB8(block, iv, true)\n}\n\nfunc newCFB8(block cipher.Block, iv []byte, decrypt bool) cipher.Stream {\n\tblockSize := block.BlockSize()\n\tif len(iv) != blockSize {\n\t\treturn nil\n\t}\n\n\tx := &cfb8{\n\t\tb:       block,\n\t\tsr:      make([]byte, blockSize*4),\n\t\tsrEnc:   make([]byte, blockSize),\n\t\tsrPos:   0,\n\t\tdecrypt: decrypt,\n\t}\n\n\tcopy(x.sr, iv)\n\n\treturn x\n}\n\nfunc (x *cfb8) XORKeyStream(dst, src []byte) {\n\tblockSize := x.b.BlockSize()\n\n\tfor i := 0; i < len(src); i++ {\n\t\tx.b.Encrypt(x.srEnc, x.sr[x.srPos:x.srPos+blockSize])\n\n\t\tvar c byte\n\t\tif x.decrypt {\n\t\t\tc = src[i]\n\t\t\tdst[i] = c ^ x.srEnc[0]\n\t\t} else {\n\t\t\tc = src[i] ^ x.srEnc[0]\n\t\t\tdst[i] = c\n\t\t}\n\n\t\tx.sr[x.srPos+blockSize] = c\n\t\tx.srPos++\n\n\t\tif x.srPos+blockSize == len(x.sr) {\n\t\t\tcopy(x.sr, x.sr[x.srPos:])\n\t\t\tx.srPos = 0\n\t\t}\n\t}\n}\n\nfunc NewEncryptAndDecrypt(secret []byte) (encrypt cipher.Stream, decrypt cipher.Stream, err error) {\n\tblock, err := aes.NewCipher(secret)\n\n\tif err != nil {\n\t\treturn nil, nil, err\n\t}\n\n\tencrypt = newEncrypt(block, secret)\n\tdecrypt = newDecrypt(block, secret)\n\n\treturn\n}\n"
  },
  {
    "path": "impl/conn/network.go",
    "content": "package conn\n\nimport (\n\t\"fmt\"\n\t\"net\"\n\t\"reflect\"\n\t\"strconv\"\n\n\t\"github.com/golangmc/minecraft-server/apis/buff\"\n\t\"github.com/golangmc/minecraft-server/apis/logs\"\n\t\"github.com/golangmc/minecraft-server/impl/base\"\n\t\"github.com/golangmc/minecraft-server/impl/data/system\"\n)\n\ntype network struct {\n\thost string\n\tport int\n\n\tlogger  *logs.Logging\n\tpackets base.Packets\n\n\tjoin chan base.PlayerAndConnection\n\tquit chan base.PlayerAndConnection\n\n\treport chan system.Message\n}\n\nfunc NewNetwork(host string, port int, packet base.Packets, report chan system.Message, join chan base.PlayerAndConnection, quit chan base.PlayerAndConnection) base.Network {\n\treturn &network{\n\t\thost: host,\n\t\tport: port,\n\n\t\tjoin: join,\n\t\tquit: quit,\n\n\t\treport: report,\n\n\t\tlogger:  logs.NewLogging(\"network\", logs.EveryLevel...),\n\t\tpackets: packet,\n\t}\n}\n\nfunc (n *network) Load() {\n\tif err := n.startListening(); err != nil {\n\t\tn.report <- system.Make(system.FAIL, err)\n\t\treturn\n\t}\n}\n\nfunc (n *network) Kill() {\n\n}\n\nfunc (n *network) startListening() error {\n\tser, err := net.ResolveTCPAddr(\"tcp\", n.host+\":\"+strconv.Itoa(n.port))\n\tif err != nil {\n\t\treturn fmt.Errorf(\"address resolution failed [%v]\", err)\n\t}\n\n\ttcp, err := net.ListenTCP(\"tcp\", ser)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to bind [%v]\", err)\n\t}\n\n\tn.logger.InfoF(\"listening on %s:%d\", n.host, n.port)\n\n\tgo func() {\n\t\tfor {\n\t\t\tcon, err := tcp.AcceptTCP()\n\n\t\t\tif err != nil {\n\t\t\t\tn.report <- system.Make(system.FAIL, err)\n\t\t\t\tbreak\n\t\t\t}\n\n\t\t\t_ = con.SetNoDelay(true)\n\t\t\t_ = con.SetKeepAlive(true)\n\n\t\t\tgo handleConnect(n, NewConnection(con))\n\t\t}\n\t}()\n\n\treturn nil\n}\n\nfunc handleConnect(network *network, conn base.Connection) {\n\tnetwork.logger.DataF(\"New Connection from &6%v\", conn.Address())\n\n\tvar inf []byte\n\n\tfor {\n\t\tinf = make([]byte, 1024)\n\t\tsze, err := conn.Pull(inf)\n\n\t\tif err != nil && err.Error() == \"EOF\" {\n\t\t\tnetwork.quit <- base.PlayerAndConnection{\n\t\t\t\tPlayer:     nil,\n\t\t\t\tConnection: conn,\n\t\t\t}\n\n\t\t\tbreak\n\t\t}\n\n\t\tif err != nil || sze == 0 {\n\t\t\t_ = conn.Stop()\n\n\t\t\tnetwork.quit <- base.PlayerAndConnection{\n\t\t\t\tPlayer:     nil,\n\t\t\t\tConnection: conn,\n\t\t\t}\n\t\t\tbreak\n\t\t}\n\n\t\tbuf := NewBufferWith(conn.Decrypt(inf[:sze]))\n\n\t\t// decompression\n\t\t// decryption\n\n\t\tif buf.UAS()[0] == 0xFE { // LEGACY PING\n\t\t\tcontinue\n\t\t}\n\n\t\tpacketLen := buf.PullVrI()\n\n\t\tbufI := NewBufferWith(buf.UAS()[buf.InI() : buf.InI()+packetLen])\n\t\tbufO := NewBuffer()\n\n\t\thandleReceive(network, conn, bufI, bufO)\n\n\t\tif bufO.Len() > 1 {\n\t\t\ttemp := NewBuffer()\n\t\t\ttemp.PushVrI(bufO.Len())\n\n\t\t\tcomp := NewBuffer()\n\t\t\tcomp.PushUAS(conn.Deflate(bufO.UAS()), false)\n\n\t\t\ttemp.PushUAS(comp.UAS(), false)\n\n\t\t\t_, err := conn.Push(conn.Encrypt(temp.UAS()))\n\n\t\t\tif err != nil {\n\t\t\t\tnetwork.logger.Fail(\"Failed to push client bound packet: %v\", err)\n\t\t\t}\n\t\t}\n\t}\n}\n\nfunc handleReceive(network *network, conn base.Connection, bufI buff.Buffer, bufO buff.Buffer) {\n\tuuid := bufI.PullVrI()\n\n\tpacketI := network.packets.GetPacketI(uuid, conn.GetState())\n\tif packetI == nil {\n\t\tnetwork.logger.DataF(\"unable to decode %v packet with uuid: %d\", conn.GetState(), uuid)\n\t\treturn\n\t}\n\n\tnetwork.logger.DataF(\"GET packet: %d | %v | %v\", packetI.UUID(), reflect.TypeOf(packetI), conn.GetState())\n\n\t// populate incoming packet\n\tpacketI.Pull(bufI, conn)\n\n\tnetwork.packets.PubAs(packetI)\n\tnetwork.packets.PubAs(packetI, conn)\n}\n"
  },
  {
    "path": "impl/cons/console.go",
    "content": "package cons\n\nimport (\n\t\"bufio\"\n\t\"io\"\n\t\"os\"\n\n\t\"github.com/golangmc/minecraft-server/apis/base\"\n\t\"github.com/golangmc/minecraft-server/apis/logs\"\n\t\"github.com/golangmc/minecraft-server/impl/data/system\"\n)\n\ntype Console struct {\n\ti io.Reader\n\to io.Writer\n\n\tlogger *logs.Logging\n\n\tIChannel chan string\n\tOChannel chan string\n\n\treport chan system.Message\n}\n\nfunc NewConsole(report chan system.Message) *Console {\n\tconsole := &Console{\n\t\tIChannel: make(chan string),\n\t\tOChannel: make(chan string),\n\n\t\treport: report,\n\t}\n\n\tconsole.i = io.MultiReader(os.Stdin)\n\tconsole.o = io.MultiWriter(os.Stdout, console.newLogFile(\"latest.log\"))\n\n\tconsole.logger = logs.NewLoggingWith(\"console\", console.o, logs.EveryLevel...)\n\n\treturn console\n}\n\nfunc (c *Console) Load() {\n\t// handle i channel\n\tgo func() {\n\t\tscanner := bufio.NewScanner(c.i)\n\n\t\tfor scanner.Scan() {\n\t\t\terr := base.Attempt(func() {\n\t\t\t\tc.IChannel <- scanner.Text()\n\t\t\t})\n\n\t\t\tif err != nil {\n\t\t\t\tc.report <- system.Make(system.FAIL, err)\n\t\t\t}\n\t\t}\n\t}()\n\n\t// handle o channel\n\tgo func() {\n\t\tfor line := range c.OChannel {\n\t\t\tc.logger.Info(line)\n\t\t}\n\t}()\n}\n\nfunc (c *Console) Kill() {\n\tdefer func() {\n\t\t_ = recover() // ignore panic with closing closed channel\n\t}()\n\n\t// save the log file as YYYY-MM-DD-{index}.log{.gz optionally compressed}\n\n\tclose(c.IChannel)\n\tclose(c.OChannel)\n}\n\nfunc (c *Console) Name() string {\n\treturn \"ConsoleSender\"\n}\n\nfunc (c *Console) SendMessage(message ...interface{}) {\n\tdefer func() {\n\t\tif err := recover(); err != nil {\n\t\t\tc.report <- system.Make(system.FAIL, err)\n\t\t}\n\t}()\n\n\tc.OChannel <- base.ConvertToString(message...)\n}\n\ntype logFileWriter struct {\n\tfile *os.File\n}\n\nfunc (c *Console) newLogFile(name string) io.Writer {\n\tfile, err := os.Create(name)\n\tif err != nil {\n\t\tc.report <- system.Make(system.FAIL, err)\n\t\treturn nil\n\t}\n\n\treturn &logFileWriter{file: file}\n}\n\nfunc (l *logFileWriter) Write(p []byte) (n int, err error) {\n\n\t// this is going to be messy, but this should convert to string, strip colors, and then write to file. Don't @ me.\n\n\treturn l.file.Write(p)\n}\n"
  },
  {
    "path": "impl/data/client/abilities.go",
    "content": "package client\n\nimport (\n\t\"github.com/golangmc/minecraft-server/apis/buff\"\n\t\"github.com/golangmc/minecraft-server/impl/mask\"\n)\n\ntype PlayerAbilities struct {\n\tmask.Masking\n\n\tInvulnerable bool\n\tFlying       bool\n\tAllowFlight  bool\n\tInstantBuild bool // creative??\n}\n\nfunc (p *PlayerAbilities) Push(writer buff.Buffer) {\n\tflags := byte(0)\n\n\tp.Set(&flags, 0x01, p.Invulnerable)\n\tp.Set(&flags, 0x02, p.Flying)\n\tp.Set(&flags, 0x04, p.AllowFlight)\n\tp.Set(&flags, 0x08, p.InstantBuild)\n\n\twriter.PushByt(flags)\n}\n\nfunc (p *PlayerAbilities) Pull(reader buff.Buffer) {\n\tflags := reader.PullByt()\n\n\tp.Invulnerable = p.Has(flags, 0x01)\n\tp.Flying = p.Has(flags, 0x02)\n\tp.AllowFlight = p.Has(flags, 0x04)\n\tp.InstantBuild = p.Has(flags, 0x08)\n}\n"
  },
  {
    "path": "impl/data/client/chat.go",
    "content": "package client\n\ntype ChatMode int\n\nconst (\n\tFull ChatMode = iota\n\tCmds\n\tNone\n)\n"
  },
  {
    "path": "impl/data/client/hand.go",
    "content": "package client\n\ntype MainHand int\n\nconst (\n\tHand_L MainHand = iota\n\tHand_R\n)\n"
  },
  {
    "path": "impl/data/client/playerinfo.go",
    "content": "package client\n\nimport (\n\t\"github.com/golangmc/minecraft-server/apis/buff\"\n\t\"github.com/golangmc/minecraft-server/apis/ents\"\n)\n\ntype PlayerInfoAction int32\n\nconst (\n\tAddPlayer PlayerInfoAction = iota\n\tUpdateGameMode\n\tUpdateLatency\n\tUpdateDisplayName\n\tRemovePlayer\n)\n\ntype PlayerInfo interface {\n\tbuff.BufferPush\n}\n\ntype PlayerInfoAddPlayer struct {\n\tPlayer ents.Player\n}\n\nfunc (p *PlayerInfoAddPlayer) Push(writer buff.Buffer) {\n\tprof := p.Player.GetProfile()\n\twriter.PushUID(prof.UUID)\n\twriter.PushTxt(prof.Name)\n\n\twriter.PushVrI(int32(len(prof.Properties)))\n\n\tfor _, prop := range prof.Properties {\n\t\twriter.PushTxt(prop.Name)\n\t\twriter.PushTxt(prop.Value)\n\n\t\tif prop.Signature == nil {\n\t\t\twriter.PushBit(false)\n\t\t} else {\n\t\t\twriter.PushBit(true)\n\t\t\twriter.PushTxt(*prop.Signature)\n\t\t}\n\t}\n\n\twriter.PushVrI(int32(p.Player.GetGameMode()))\n\n\twriter.PushVrI(0) // update this to the player's actual ping\n\n\twriter.PushBit(false) // update this to be whether the player has a custom display name or not, write that name as json if they do\n}\n\ntype PlayerInfoUpdateLatency struct {\n}\n"
  },
  {
    "path": "impl/data/client/position.go",
    "content": "package client\n\nimport (\n\t\"github.com/golangmc/minecraft-server/apis/buff\"\n\t\"github.com/golangmc/minecraft-server/impl/mask\"\n)\n\ntype Relativity struct {\n\tmask.Masking\n\n\tX bool\n\tY bool\n\tZ bool\n\n\tAxisX bool\n\tAxisY bool\n}\n\nfunc (r *Relativity) Push(writer buff.Buffer) {\n\tflags := byte(0)\n\n\tr.Set(&flags, 0x01, r.X)\n\tr.Set(&flags, 0x02, r.Y)\n\tr.Set(&flags, 0x04, r.Z)\n\n\t// the fact that these are flipped deeply bothers me.\n\tr.Set(&flags, 0x08, r.AxisY)\n\tr.Set(&flags, 0x10, r.AxisX)\n\n\twriter.PushByt(flags)\n}\n"
  },
  {
    "path": "impl/data/client/skin.go",
    "content": "package client\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/golangmc/minecraft-server/apis/buff\"\n\t\"github.com/golangmc/minecraft-server/impl/mask\"\n)\n\ntype SkinParts struct {\n\tmask.Masking\n\n\tCape bool\n\tHead bool\n\tBody bool\n\tArmL bool\n\tArmR bool\n\tLegL bool\n\tLegR bool\n}\n\nfunc (d *SkinParts) String() string {\n\treturn fmt.Sprintf(\"Cape:%t Head:%t Body:%t ArmL:%t ArmR:%t LegL:%t LegR:%t\", d.Cape, d.Head, d.Body, d.ArmL, d.ArmR, d.LegL, d.LegR)\n}\n\nfunc (d *SkinParts) Push(writer buff.Buffer) {\n\tflags := byte(0)\n\n\td.Set(&flags, 0x01, d.Cape)\n\td.Set(&flags, 0x02, d.Body)\n\td.Set(&flags, 0x04, d.ArmL)\n\td.Set(&flags, 0x08, d.ArmR)\n\td.Set(&flags, 0x10, d.LegL)\n\td.Set(&flags, 0x20, d.LegR)\n\td.Set(&flags, 0x40, d.Head)\n\n\twriter.PushByt(flags)\n}\n\nfunc (d *SkinParts) Pull(reader buff.Buffer) {\n\tflags := reader.PullByt()\n\n\td.Cape = d.Has(flags, 0x01)\n\td.Body = d.Has(flags, 0x02)\n\td.ArmL = d.Has(flags, 0x04)\n\td.ArmR = d.Has(flags, 0x08)\n\td.LegL = d.Has(flags, 0x10)\n\td.LegR = d.Has(flags, 0x20)\n\td.Head = d.Has(flags, 0x40)\n}\n"
  },
  {
    "path": "impl/data/client/slot.go",
    "content": "package client\n\ntype HotBarSlot byte\n\nconst (\n\tSLOT_0 HotBarSlot = iota\n\tSLOT_1\n\tSLOT_2\n\tSLOT_3\n\tSLOT_4\n\tSLOT_5\n\tSLOT_6\n\tSLOT_7\n\tSLOT_8\n)\n"
  },
  {
    "path": "impl/data/client/status.go",
    "content": "package client\n\ntype StatusAction int\n\nconst (\n\tRespawn StatusAction = iota\n\tRequest\n)\n"
  },
  {
    "path": "impl/data/plugin/message.go",
    "content": "package plugin\n\nimport (\n\t\"github.com/golangmc/minecraft-server/apis/buff\"\n\t\"github.com/golangmc/minecraft-server/apis/data\"\n)\n\ntype Message interface {\n\tChan() string\n\n\tbuff.BufferPush\n\tbuff.BufferPull\n}\n\nvar registry = createMessageRegistry()\n\ntype MessageRegistry struct {\n\tchannels map[string]func() Message\n}\n\nfunc createMessageRegistry() MessageRegistry {\n\tregistry := MessageRegistry{make(map[string]func() Message)}\n\n\tregistry.channels[\"minecraft:brand\"] = func() Message {\n\t\treturn &Brand{}\n\t}\n\n\tregistry.channels[\"minecraft:debug/paths\"] = func() Message {\n\t\treturn &DebugPaths{}\n\t}\n\n\tregistry.channels[\"minecraft:debug/neighbors_update\"] = func() Message {\n\t\treturn &DebugNeighbors{}\n\t}\n\n\treturn registry\n}\n\nfunc GetMessageForChannel(channel string) Message {\n\tcreator := registry.channels[channel]\n\tif creator == nil {\n\t\treturn nil\n\t}\n\n\treturn creator()\n}\n\nconst (\n\tCHANNEL_BRAND           = \"minecraft:brand\"\n\tCHANNEL_DEBUG_PATHS     = \"minecraft:debug/paths\"\n\tCHANNEL_DEBUG_NEIGHBORS = \"minecraft:debug/neighbors_update\"\n)\n\n// look, they're like cute little packets :D\n\ntype Brand struct {\n\tName string\n}\n\nfunc (b *Brand) Chan() string {\n\treturn CHANNEL_BRAND\n}\n\nfunc (b *Brand) Push(writer buff.Buffer) {\n\twriter.PushTxt(b.Name)\n}\n\nfunc (b *Brand) Pull(reader buff.Buffer) {\n\tb.Name = reader.PullTxt()\n}\n\ntype DebugPaths struct { // unused? honestly why did I do this\n\tUnknownValue1 int32\n\tUnknownValue2 float32\n\tPathEntity    PathEntity\n}\n\ntype PathEntity struct {\n\tIndex   int\n\tTarget  PathPoint\n\tPSetLen int\n\tPSet    []PathPoint\n\tOSetLen int\n\tOSet    []PathPoint\n\tCSetLen int\n\tCSet    []PathPoint\n}\n\nfunc (p *PathEntity) Push(writer buff.Buffer) {\n\twriter.PushI32(int32(p.Index))\n\n\tp.Target.Push(writer)\n\n\twriter.PushI32(int32(p.PSetLen))\n\tfor _, point := range p.PSet {\n\t\tpoint.Push(writer)\n\t}\n\n\twriter.PushI32(int32(p.OSetLen))\n\tfor _, point := range p.OSet {\n\t\tpoint.Push(writer)\n\t}\n\n\twriter.PushI32(int32(p.CSetLen))\n\tfor _, point := range p.CSet {\n\t\tpoint.Push(writer)\n\t}\n}\n\nfunc (p *PathEntity) Pull(reader buff.Buffer) {\n\tp.Index = int(reader.PullI32())\n\n\ttarget := PathPoint{}\n\ttarget.Pull(reader)\n\n\tp.Target = target\n\n\tp.PSet = make([]PathPoint, 0)\n\tp.PSetLen = int(reader.PullI32())\n\n\tfor i := 0; i < p.PSetLen; i++ {\n\t\tpoint := PathPoint{}\n\t\tpoint.Pull(reader)\n\n\t\tp.PSet = append(p.PSet, point)\n\t}\n\n\tp.OSet = make([]PathPoint, 0)\n\tp.OSetLen = int(reader.PullI32())\n\n\tfor i := 0; i < p.OSetLen; i++ {\n\t\tpoint := PathPoint{}\n\t\tpoint.Pull(reader)\n\n\t\tp.OSet = append(p.OSet, point)\n\t}\n\n\tp.CSet = make([]PathPoint, 0)\n\tp.CSetLen = int(reader.PullI32())\n\n\tfor i := 0; i < p.CSetLen; i++ {\n\t\tpoint := PathPoint{}\n\t\tpoint.Pull(reader)\n\n\t\tp.CSet = append(p.CSet, point)\n\t}\n}\n\ntype PathPoint struct {\n\tX int32\n\tY int32\n\tZ int32\n\n\tDistanceOrigin float32\n\tCost           float32\n\tCostMalus      float32\n\tVisited        bool\n\tNodeType       NodeType\n\tDistanceTarget float32\n}\n\nfunc (p *PathPoint) Push(writer buff.Buffer) {\n\twriter.PushI32(p.X)\n\twriter.PushI32(p.Y)\n\twriter.PushI32(p.Z)\n\twriter.PushF32(p.DistanceOrigin)\n\twriter.PushF32(p.Cost)\n\twriter.PushF32(p.CostMalus)\n\twriter.PushBit(p.Visited)\n\twriter.PushI32(int32(p.NodeType))\n\twriter.PushF32(p.DistanceTarget)\n}\n\nfunc (p *PathPoint) Pull(reader buff.Buffer) {\n\tp.X = reader.PullI32()\n\tp.Y = reader.PullI32()\n\tp.Z = reader.PullI32()\n\tp.DistanceOrigin = reader.PullF32()\n\tp.Cost = reader.PullF32()\n\tp.CostMalus = reader.PullF32()\n\tp.Visited = reader.PullBit()\n\tp.NodeType = NodeType(reader.PullI32())\n\tp.DistanceTarget = reader.PullF32()\n}\n\ntype NodeType int\n\nconst (\n\tBLOCKED NodeType = iota\n\tOPEN\n\tWALKABLE\n\tTRAPDOOR\n\tFENCE\n\tLAVA\n\tWATER\n\tRAIL\n\tDANGER_FIRE\n\tDAMAGE_FIRE\n\tDANGER_CACTUS\n\tDAMAGE_CACTUS\n\tDANGER_OTHER\n\tDAMAGE_OTHER\n\tDOOR_OPEN\n\tDOOR_WOOD_CLOSED\n\tDOOR_IRON_CLOSED\n)\n\nfunc (d *DebugPaths) Chan() string {\n\treturn CHANNEL_DEBUG_PATHS\n}\n\nfunc (d *DebugPaths) Push(writer buff.Buffer) {\n\twriter.PushI32(d.UnknownValue1)\n\twriter.PushF32(d.UnknownValue2)\n\td.PathEntity.Push(writer)\n}\n\nfunc (d *DebugPaths) Pull(reader buff.Buffer) {\n\td.UnknownValue1 = reader.PullI32()\n\td.UnknownValue2 = reader.PullF32()\n\n\tentity := PathEntity{}\n\tentity.Pull(reader)\n\n\td.PathEntity = entity\n}\n\ntype DebugNeighbors struct {\n\tTime     int64\n\tLocation data.PositionI\n}\n\nfunc (d *DebugNeighbors) Chan() string {\n\treturn CHANNEL_DEBUG_NEIGHBORS\n}\n\nfunc (d *DebugNeighbors) Push(writer buff.Buffer) {\n\twriter.PushVrL(d.Time)\n\twriter.PushPos(d.Location)\n}\n\nfunc (d *DebugNeighbors) Pull(reader buff.Buffer) {\n\td.Time = reader.PullVrL()\n\td.Location = reader.PullPos()\n}\n"
  },
  {
    "path": "impl/data/status/response.go",
    "content": "package status\n\nimport (\n\t\"github.com/golangmc/minecraft-server/apis/data\"\n\t\"github.com/golangmc/minecraft-server/apis/data/chat\"\n)\n\nconst (\n\tSxtannaName = \"Sxtanna\"\n\tSxtannaUUID = \"41d1fed5-aa44-432c-ab1b-2810001f3270\"\n\n\tServerMotd = \"                      &bA GoLang Server\"\n\tServerIcon = \"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAIAAAAlC+aJAAAACXBIWXMAAAMTAAADEwE9ZoPHAAAKT2lDQ1BQaG90b3Nob3AgSUNDIHByb2ZpbGUAAHjanVNnVFPpFj333vRCS4iAlEtvUhUIIFJCi4AUkSYqIQkQSoghodkVUcERRUUEG8igiAOOjoCMFVEsDIoK2AfkIaKOg6OIisr74Xuja9a89+bN/rXXPues852zzwfACAyWSDNRNYAMqUIeEeCDx8TG4eQuQIEKJHAAEAizZCFz/SMBAPh+PDwrIsAHvgABeNMLCADATZvAMByH/w/qQplcAYCEAcB0kThLCIAUAEB6jkKmAEBGAYCdmCZTAKAEAGDLY2LjAFAtAGAnf+bTAICd+Jl7AQBblCEVAaCRACATZYhEAGg7AKzPVopFAFgwABRmS8Q5ANgtADBJV2ZIALC3AMDOEAuyAAgMADBRiIUpAAR7AGDIIyN4AISZABRG8lc88SuuEOcqAAB4mbI8uSQ5RYFbCC1xB1dXLh4ozkkXKxQ2YQJhmkAuwnmZGTKBNA/g88wAAKCRFRHgg/P9eM4Ors7ONo62Dl8t6r8G/yJiYuP+5c+rcEAAAOF0ftH+LC+zGoA7BoBt/qIl7gRoXgugdfeLZrIPQLUAoOnaV/Nw+H48PEWhkLnZ2eXk5NhKxEJbYcpXff5nwl/AV/1s+X48/Pf14L7iJIEyXYFHBPjgwsz0TKUcz5IJhGLc5o9H/LcL//wd0yLESWK5WCoU41EScY5EmozzMqUiiUKSKcUl0v9k4t8s+wM+3zUAsGo+AXuRLahdYwP2SycQWHTA4vcAAPK7b8HUKAgDgGiD4c93/+8//UegJQCAZkmScQAAXkQkLlTKsz/HCAAARKCBKrBBG/TBGCzABhzBBdzBC/xgNoRCJMTCQhBCCmSAHHJgKayCQiiGzbAdKmAv1EAdNMBRaIaTcA4uwlW4Dj1wD/phCJ7BKLyBCQRByAgTYSHaiAFiilgjjggXmYX4IcFIBBKLJCDJiBRRIkuRNUgxUopUIFVIHfI9cgI5h1xGupE7yAAygvyGvEcxlIGyUT3UDLVDuag3GoRGogvQZHQxmo8WoJvQcrQaPYw2oefQq2gP2o8+Q8cwwOgYBzPEbDAuxsNCsTgsCZNjy7EirAyrxhqwVqwDu4n1Y8+xdwQSgUXACTYEd0IgYR5BSFhMWE7YSKggHCQ0EdoJNwkDhFHCJyKTqEu0JroR+cQYYjIxh1hILCPWEo8TLxB7iEPENyQSiUMyJ7mQAkmxpFTSEtJG0m5SI+ksqZs0SBojk8naZGuyBzmULCAryIXkneTD5DPkG+Qh8lsKnWJAcaT4U+IoUspqShnlEOU05QZlmDJBVaOaUt2ooVQRNY9aQq2htlKvUYeoEzR1mjnNgxZJS6WtopXTGmgXaPdpr+h0uhHdlR5Ol9BX0svpR+iX6AP0dwwNhhWDx4hnKBmbGAcYZxl3GK+YTKYZ04sZx1QwNzHrmOeZD5lvVVgqtip8FZHKCpVKlSaVGyovVKmqpqreqgtV81XLVI+pXlN9rkZVM1PjqQnUlqtVqp1Q61MbU2epO6iHqmeob1Q/pH5Z/YkGWcNMw09DpFGgsV/jvMYgC2MZs3gsIWsNq4Z1gTXEJrHN2Xx2KruY/R27iz2qqaE5QzNKM1ezUvOUZj8H45hx+Jx0TgnnKKeX836K3hTvKeIpG6Y0TLkxZVxrqpaXllirSKtRq0frvTau7aedpr1Fu1n7gQ5Bx0onXCdHZ4/OBZ3nU9lT3acKpxZNPTr1ri6qa6UbobtEd79up+6Ynr5egJ5Mb6feeb3n+hx9L/1U/W36p/VHDFgGswwkBtsMzhg8xTVxbzwdL8fb8VFDXcNAQ6VhlWGX4YSRudE8o9VGjUYPjGnGXOMk423GbcajJgYmISZLTepN7ppSTbmmKaY7TDtMx83MzaLN1pk1mz0x1zLnm+eb15vft2BaeFostqi2uGVJsuRaplnutrxuhVo5WaVYVVpds0atna0l1rutu6cRp7lOk06rntZnw7Dxtsm2qbcZsOXYBtuutm22fWFnYhdnt8Wuw+6TvZN9un2N/T0HDYfZDqsdWh1+c7RyFDpWOt6azpzuP33F9JbpL2dYzxDP2DPjthPLKcRpnVOb00dnF2e5c4PziIuJS4LLLpc+Lpsbxt3IveRKdPVxXeF60vWdm7Obwu2o26/uNu5p7ofcn8w0nymeWTNz0MPIQ+BR5dE/C5+VMGvfrH5PQ0+BZ7XnIy9jL5FXrdewt6V3qvdh7xc+9j5yn+M+4zw33jLeWV/MN8C3yLfLT8Nvnl+F30N/I/9k/3r/0QCngCUBZwOJgUGBWwL7+Hp8Ib+OPzrbZfay2e1BjKC5QRVBj4KtguXBrSFoyOyQrSH355jOkc5pDoVQfujW0Adh5mGLw34MJ4WHhVeGP45wiFga0TGXNXfR3ENz30T6RJZE3ptnMU85ry1KNSo+qi5qPNo3ujS6P8YuZlnM1VidWElsSxw5LiquNm5svt/87fOH4p3iC+N7F5gvyF1weaHOwvSFpxapLhIsOpZATIhOOJTwQRAqqBaMJfITdyWOCnnCHcJnIi/RNtGI2ENcKh5O8kgqTXqS7JG8NXkkxTOlLOW5hCepkLxMDUzdmzqeFpp2IG0yPTq9MYOSkZBxQqohTZO2Z+pn5mZ2y6xlhbL+xW6Lty8elQfJa7OQrAVZLQq2QqboVFoo1yoHsmdlV2a/zYnKOZarnivN7cyzytuQN5zvn//tEsIS4ZK2pYZLVy0dWOa9rGo5sjxxedsK4xUFK4ZWBqw8uIq2Km3VT6vtV5eufr0mek1rgV7ByoLBtQFr6wtVCuWFfevc1+1dT1gvWd+1YfqGnRs+FYmKrhTbF5cVf9go3HjlG4dvyr+Z3JS0qavEuWTPZtJm6ebeLZ5bDpaql+aXDm4N2dq0Dd9WtO319kXbL5fNKNu7g7ZDuaO/PLi8ZafJzs07P1SkVPRU+lQ27tLdtWHX+G7R7ht7vPY07NXbW7z3/T7JvttVAVVN1WbVZftJ+7P3P66Jqun4lvttXa1ObXHtxwPSA/0HIw6217nU1R3SPVRSj9Yr60cOxx++/p3vdy0NNg1VjZzG4iNwRHnk6fcJ3/ceDTradox7rOEH0x92HWcdL2pCmvKaRptTmvtbYlu6T8w+0dbq3nr8R9sfD5w0PFl5SvNUyWna6YLTk2fyz4ydlZ19fi753GDborZ752PO32oPb++6EHTh0kX/i+c7vDvOXPK4dPKy2+UTV7hXmq86X23qdOo8/pPTT8e7nLuarrlca7nuer21e2b36RueN87d9L158Rb/1tWeOT3dvfN6b/fF9/XfFt1+cif9zsu72Xcn7q28T7xf9EDtQdlD3YfVP1v+3Njv3H9qwHeg89HcR/cGhYPP/pH1jw9DBY+Zj8uGDYbrnjg+OTniP3L96fynQ89kzyaeF/6i/suuFxYvfvjV69fO0ZjRoZfyl5O/bXyl/erA6xmv28bCxh6+yXgzMV70VvvtwXfcdx3vo98PT+R8IH8o/2j5sfVT0Kf7kxmTk/8EA5jz/GMzLdsAAEqNaVRYdFhNTDpjb20uYWRvYmUueG1wAAAAAAA8P3hwYWNrZXQgYmVnaW49Iu+7vyIgaWQ9Ilc1TTBNcENlaGlIenJlU3pOVGN6a2M5ZCI/Pgo8eDp4bXBtZXRhIHhtbG5zOng9ImFkb2JlOm5zOm1ldGEvIiB4OnhtcHRrPSJBZG9iZSBYTVAgQ29yZSA1LjYtYzA2NyA3OS4xNTc3NDcsIDIwMTUvMDMvMzAtMjM6NDA6NDIgICAgICAgICI+CiAgIDxyZGY6UkRGIHhtbG5zOnJkZj0iaHR0cDovL3d3dy53My5vcmcvMTk5OS8wMi8yMi1yZGYtc3ludGF4LW5zIyI+CiAgICAgIDxyZGY6RGVzY3JpcHRpb24gcmRmOmFib3V0PSIiCiAgICAgICAgICAgIHhtbG5zOnhtcD0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wLyIKICAgICAgICAgICAgeG1sbnM6ZGM9Imh0dHA6Ly9wdXJsLm9yZy9kYy9lbGVtZW50cy8xLjEvIgogICAgICAgICAgICB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIKICAgICAgICAgICAgeG1sbnM6c3RFdnQ9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZUV2ZW50IyIKICAgICAgICAgICAgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiCiAgICAgICAgICAgIHhtbG5zOnBob3Rvc2hvcD0iaHR0cDovL25zLmFkb2JlLmNvbS9waG90b3Nob3AvMS4wLyIKICAgICAgICAgICAgeG1sbnM6dGlmZj0iaHR0cDovL25zLmFkb2JlLmNvbS90aWZmLzEuMC8iCiAgICAgICAgICAgIHhtbG5zOmV4aWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20vZXhpZi8xLjAvIj4KICAgICAgICAgPHhtcDpDcmVhdG9yVG9vbD5BZG9iZSBQaG90b3Nob3AgQ0MgMjAxNSAoV2luZG93cyk8L3htcDpDcmVhdG9yVG9vbD4KICAgICAgICAgPHhtcDpDcmVhdGVEYXRlPjIwMTktMDctMjJUMjM6NTA6MTUtMDQ6MDA8L3htcDpDcmVhdGVEYXRlPgogICAgICAgICA8eG1wOk1ldGFkYXRhRGF0ZT4yMDE5LTA4LTEzVDE3OjQ2OjIzLTA0OjAwPC94bXA6TWV0YWRhdGFEYXRlPgogICAgICAgICA8eG1wOk1vZGlmeURhdGU+MjAxOS0wOC0xM1QxNzo0NjoyMy0wNDowMDwveG1wOk1vZGlmeURhdGU+CiAgICAgICAgIDxkYzpmb3JtYXQ+aW1hZ2UvcG5nPC9kYzpmb3JtYXQ+CiAgICAgICAgIDx4bXBNTTpJbnN0YW5jZUlEPnhtcC5paWQ6NzNlNTdkYTYtMDFiOC1mNDQ1LTlmMTEtYjIxODc1NmJjZWZlPC94bXBNTTpJbnN0YW5jZUlEPgogICAgICAgICA8eG1wTU06RG9jdW1lbnRJRD5hZG9iZTpkb2NpZDpwaG90b3Nob3A6NWJiYWE4Y2ItYmUxMy0xMWU5LTljNWUtY2IzZWQ2NWEzZDZlPC94bXBNTTpEb2N1bWVudElEPgogICAgICAgICA8eG1wTU06T3JpZ2luYWxEb2N1bWVudElEPnhtcC5kaWQ6ZDI0NTZmNTUtOTlmYi05OTRlLThhNDItODA5N2RjYjhhYmQ4PC94bXBNTTpPcmlnaW5hbERvY3VtZW50SUQ+CiAgICAgICAgIDx4bXBNTTpIaXN0b3J5PgogICAgICAgICAgICA8cmRmOlNlcT4KICAgICAgICAgICAgICAgPHJkZjpsaSByZGY6cGFyc2VUeXBlPSJSZXNvdXJjZSI+CiAgICAgICAgICAgICAgICAgIDxzdEV2dDphY3Rpb24+Y3JlYXRlZDwvc3RFdnQ6YWN0aW9uPgogICAgICAgICAgICAgICAgICA8c3RFdnQ6aW5zdGFuY2VJRD54bXAuaWlkOmQyNDU2ZjU1LTk5ZmItOTk0ZS04YTQyLTgwOTdkY2I4YWJkODwvc3RFdnQ6aW5zdGFuY2VJRD4KICAgICAgICAgICAgICAgICAgPHN0RXZ0OndoZW4+MjAxOS0wNy0yMlQyMzo1MDoxNS0wNDowMDwvc3RFdnQ6d2hlbj4KICAgICAgICAgICAgICAgICAgPHN0RXZ0OnNvZnR3YXJlQWdlbnQ+QWRvYmUgUGhvdG9zaG9wIENDIDIwMTUgKFdpbmRvd3MpPC9zdEV2dDpzb2Z0d2FyZUFnZW50PgogICAgICAgICAgICAgICA8L3JkZjpsaT4KICAgICAgICAgICAgICAgPHJkZjpsaSByZGY6cGFyc2VUeXBlPSJSZXNvdXJjZSI+CiAgICAgICAgICAgICAgICAgIDxzdEV2dDphY3Rpb24+c2F2ZWQ8L3N0RXZ0OmFjdGlvbj4KICAgICAgICAgICAgICAgICAgPHN0RXZ0Omluc3RhbmNlSUQ+eG1wLmlpZDo5NzZlZmVlMC1kOTZmLWQ1NDYtOTIxMC0wNjA5NGFiN2RlNTE8L3N0RXZ0Omluc3RhbmNlSUQ+CiAgICAgICAgICAgICAgICAgIDxzdEV2dDp3aGVuPjIwMTktMDctMjJUMjM6NTA6NDYtMDQ6MDA8L3N0RXZ0OndoZW4+CiAgICAgICAgICAgICAgICAgIDxzdEV2dDpzb2Z0d2FyZUFnZW50PkFkb2JlIFBob3Rvc2hvcCBDQyAyMDE1IChXaW5kb3dzKTwvc3RFdnQ6c29mdHdhcmVBZ2VudD4KICAgICAgICAgICAgICAgICAgPHN0RXZ0OmNoYW5nZWQ+Lzwvc3RFdnQ6Y2hhbmdlZD4KICAgICAgICAgICAgICAgPC9yZGY6bGk+CiAgICAgICAgICAgICAgIDxyZGY6bGkgcmRmOnBhcnNlVHlwZT0iUmVzb3VyY2UiPgogICAgICAgICAgICAgICAgICA8c3RFdnQ6YWN0aW9uPnNhdmVkPC9zdEV2dDphY3Rpb24+CiAgICAgICAgICAgICAgICAgIDxzdEV2dDppbnN0YW5jZUlEPnhtcC5paWQ6MmU5Yjg4ZjItNzJhZS0zMjQ5LTg5OGUtN2IxNDI0ZjY2ZTI4PC9zdEV2dDppbnN0YW5jZUlEPgogICAgICAgICAgICAgICAgICA8c3RFdnQ6d2hlbj4yMDE5LTA3LTI2VDE4OjEyOjUxLTA0OjAwPC9zdEV2dDp3aGVuPgogICAgICAgICAgICAgICAgICA8c3RFdnQ6c29mdHdhcmVBZ2VudD5BZG9iZSBQaG90b3Nob3AgQ0MgMjAxNSAoV2luZG93cyk8L3N0RXZ0OnNvZnR3YXJlQWdlbnQ+CiAgICAgICAgICAgICAgICAgIDxzdEV2dDpjaGFuZ2VkPi88L3N0RXZ0OmNoYW5nZWQ+CiAgICAgICAgICAgICAgIDwvcmRmOmxpPgogICAgICAgICAgICAgICA8cmRmOmxpIHJkZjpwYXJzZVR5cGU9IlJlc291cmNlIj4KICAgICAgICAgICAgICAgICAgPHN0RXZ0OmFjdGlvbj5jb252ZXJ0ZWQ8L3N0RXZ0OmFjdGlvbj4KICAgICAgICAgICAgICAgICAgPHN0RXZ0OnBhcmFtZXRlcnM+ZnJvbSBhcHBsaWNhdGlvbi92bmQuYWRvYmUucGhvdG9zaG9wIHRvIGltYWdlL2pwZWc8L3N0RXZ0OnBhcmFtZXRlcnM+CiAgICAgICAgICAgICAgIDwvcmRmOmxpPgogICAgICAgICAgICAgICA8cmRmOmxpIHJkZjpwYXJzZVR5cGU9IlJlc291cmNlIj4KICAgICAgICAgICAgICAgICAgPHN0RXZ0OmFjdGlvbj5kZXJpdmVkPC9zdEV2dDphY3Rpb24+CiAgICAgICAgICAgICAgICAgIDxzdEV2dDpwYXJhbWV0ZXJzPmNvbnZlcnRlZCBmcm9tIGFwcGxpY2F0aW9uL3ZuZC5hZG9iZS5waG90b3Nob3AgdG8gaW1hZ2UvanBlZzwvc3RFdnQ6cGFyYW1ldGVycz4KICAgICAgICAgICAgICAgPC9yZGY6bGk+CiAgICAgICAgICAgICAgIDxyZGY6bGkgcmRmOnBhcnNlVHlwZT0iUmVzb3VyY2UiPgogICAgICAgICAgICAgICAgICA8c3RFdnQ6YWN0aW9uPnNhdmVkPC9zdEV2dDphY3Rpb24+CiAgICAgICAgICAgICAgICAgIDxzdEV2dDppbnN0YW5jZUlEPnhtcC5paWQ6M2Q5ZTkzMmYtZTRmNC05MDRlLWE2MTQtY2YwMjBkYzYzZGNmPC9zdEV2dDppbnN0YW5jZUlEPgogICAgICAgICAgICAgICAgICA8c3RFdnQ6d2hlbj4yMDE5LTA3LTI2VDE4OjEyOjUxLTA0OjAwPC9zdEV2dDp3aGVuPgogICAgICAgICAgICAgICAgICA8c3RFdnQ6c29mdHdhcmVBZ2VudD5BZG9iZSBQaG90b3Nob3AgQ0MgMjAxNSAoV2luZG93cyk8L3N0RXZ0OnNvZnR3YXJlQWdlbnQ+CiAgICAgICAgICAgICAgICAgIDxzdEV2dDpjaGFuZ2VkPi88L3N0RXZ0OmNoYW5nZWQ+CiAgICAgICAgICAgICAgIDwvcmRmOmxpPgogICAgICAgICAgICAgICA8cmRmOmxpIHJkZjpwYXJzZVR5cGU9IlJlc291cmNlIj4KICAgICAgICAgICAgICAgICAgPHN0RXZ0OmFjdGlvbj5zYXZlZDwvc3RFdnQ6YWN0aW9uPgogICAgICAgICAgICAgICAgICA8c3RFdnQ6aW5zdGFuY2VJRD54bXAuaWlkOmQ2YzUzY2FhLWRhMzktNzI0Zi1iNGZmLTY4ZWRkOWRiYWZkNjwvc3RFdnQ6aW5zdGFuY2VJRD4KICAgICAgICAgICAgICAgICAgPHN0RXZ0OndoZW4+MjAxOS0wOC0xM1QxNzo0MzozMC0wNDowMDwvc3RFdnQ6d2hlbj4KICAgICAgICAgICAgICAgICAgPHN0RXZ0OnNvZnR3YXJlQWdlbnQ+QWRvYmUgUGhvdG9zaG9wIENDIDIwMTUgKFdpbmRvd3MpPC9zdEV2dDpzb2Z0d2FyZUFnZW50PgogICAgICAgICAgICAgICAgICA8c3RFdnQ6Y2hhbmdlZD4vPC9zdEV2dDpjaGFuZ2VkPgogICAgICAgICAgICAgICA8L3JkZjpsaT4KICAgICAgICAgICAgICAgPHJkZjpsaSByZGY6cGFyc2VUeXBlPSJSZXNvdXJjZSI+CiAgICAgICAgICAgICAgICAgIDxzdEV2dDphY3Rpb24+Y29udmVydGVkPC9zdEV2dDphY3Rpb24+CiAgICAgICAgICAgICAgICAgIDxzdEV2dDpwYXJhbWV0ZXJzPmZyb20gaW1hZ2UvanBlZyB0byBpbWFnZS9wbmc8L3N0RXZ0OnBhcmFtZXRlcnM+CiAgICAgICAgICAgICAgIDwvcmRmOmxpPgogICAgICAgICAgICAgICA8cmRmOmxpIHJkZjpwYXJzZVR5cGU9IlJlc291cmNlIj4KICAgICAgICAgICAgICAgICAgPHN0RXZ0OmFjdGlvbj5kZXJpdmVkPC9zdEV2dDphY3Rpb24+CiAgICAgICAgICAgICAgICAgIDxzdEV2dDpwYXJhbWV0ZXJzPmNvbnZlcnRlZCBmcm9tIGltYWdlL2pwZWcgdG8gaW1hZ2UvcG5nPC9zdEV2dDpwYXJhbWV0ZXJzPgogICAgICAgICAgICAgICA8L3JkZjpsaT4KICAgICAgICAgICAgICAgPHJkZjpsaSByZGY6cGFyc2VUeXBlPSJSZXNvdXJjZSI+CiAgICAgICAgICAgICAgICAgIDxzdEV2dDphY3Rpb24+c2F2ZWQ8L3N0RXZ0OmFjdGlvbj4KICAgICAgICAgICAgICAgICAgPHN0RXZ0Omluc3RhbmNlSUQ+eG1wLmlpZDo0MmIzNjk2NS04ZjI5LWQ0NDEtYjJmOS05NTNiZTJhNWJhZTY8L3N0RXZ0Omluc3RhbmNlSUQ+CiAgICAgICAgICAgICAgICAgIDxzdEV2dDp3aGVuPjIwMTktMDgtMTNUMTc6NDM6MzAtMDQ6MDA8L3N0RXZ0OndoZW4+CiAgICAgICAgICAgICAgICAgIDxzdEV2dDpzb2Z0d2FyZUFnZW50PkFkb2JlIFBob3Rvc2hvcCBDQyAyMDE1IChXaW5kb3dzKTwvc3RFdnQ6c29mdHdhcmVBZ2VudD4KICAgICAgICAgICAgICAgICAgPHN0RXZ0OmNoYW5nZWQ+Lzwvc3RFdnQ6Y2hhbmdlZD4KICAgICAgICAgICAgICAgPC9yZGY6bGk+CiAgICAgICAgICAgICAgIDxyZGY6bGkgcmRmOnBhcnNlVHlwZT0iUmVzb3VyY2UiPgogICAgICAgICAgICAgICAgICA8c3RFdnQ6YWN0aW9uPnNhdmVkPC9zdEV2dDphY3Rpb24+CiAgICAgICAgICAgICAgICAgIDxzdEV2dDppbnN0YW5jZUlEPnhtcC5paWQ6NzNlNTdkYTYtMDFiOC1mNDQ1LTlmMTEtYjIxODc1NmJjZWZlPC9zdEV2dDppbnN0YW5jZUlEPgogICAgICAgICAgICAgICAgICA8c3RFdnQ6d2hlbj4yMDE5LTA4LTEzVDE3OjQ2OjIzLTA0OjAwPC9zdEV2dDp3aGVuPgogICAgICAgICAgICAgICAgICA8c3RFdnQ6c29mdHdhcmVBZ2VudD5BZG9iZSBQaG90b3Nob3AgQ0MgMjAxNSAoV2luZG93cyk8L3N0RXZ0OnNvZnR3YXJlQWdlbnQ+CiAgICAgICAgICAgICAgICAgIDxzdEV2dDpjaGFuZ2VkPi88L3N0RXZ0OmNoYW5nZWQ+CiAgICAgICAgICAgICAgIDwvcmRmOmxpPgogICAgICAgICAgICA8L3JkZjpTZXE+CiAgICAgICAgIDwveG1wTU06SGlzdG9yeT4KICAgICAgICAgPHhtcE1NOkRlcml2ZWRGcm9tIHJkZjpwYXJzZVR5cGU9IlJlc291cmNlIj4KICAgICAgICAgICAgPHN0UmVmOmluc3RhbmNlSUQ+eG1wLmlpZDpkNmM1M2NhYS1kYTM5LTcyNGYtYjRmZi02OGVkZDlkYmFmZDY8L3N0UmVmOmluc3RhbmNlSUQ+CiAgICAgICAgICAgIDxzdFJlZjpkb2N1bWVudElEPmFkb2JlOmRvY2lkOnBob3Rvc2hvcDo3ZDBjYmQ1Mi1hZmYyLTExZTktOGY4ZS05YzQ4OTgwOWNiOTU8L3N0UmVmOmRvY3VtZW50SUQ+CiAgICAgICAgICAgIDxzdFJlZjpvcmlnaW5hbERvY3VtZW50SUQ+eG1wLmRpZDpkMjQ1NmY1NS05OWZiLTk5NGUtOGE0Mi04MDk3ZGNiOGFiZDg8L3N0UmVmOm9yaWdpbmFsRG9jdW1lbnRJRD4KICAgICAgICAgPC94bXBNTTpEZXJpdmVkRnJvbT4KICAgICAgICAgPHBob3Rvc2hvcDpMZWdhY3lJUFRDRGlnZXN0PjI3QUUyMTVBODcyNUI0NDlFQ0Q4QzNGNEQxQkI2QkFDPC9waG90b3Nob3A6TGVnYWN5SVBUQ0RpZ2VzdD4KICAgICAgICAgPHBob3Rvc2hvcDpDb2xvck1vZGU+MzwvcGhvdG9zaG9wOkNvbG9yTW9kZT4KICAgICAgICAgPHBob3Rvc2hvcDpJQ0NQcm9maWxlPnNSR0IgSUVDNjE5NjYtMi4xPC9waG90b3Nob3A6SUNDUHJvZmlsZT4KICAgICAgICAgPHRpZmY6SW1hZ2VXaWR0aD4xMDAwPC90aWZmOkltYWdlV2lkdGg+CiAgICAgICAgIDx0aWZmOkltYWdlTGVuZ3RoPjEwMDA8L3RpZmY6SW1hZ2VMZW5ndGg+CiAgICAgICAgIDx0aWZmOkJpdHNQZXJTYW1wbGU+CiAgICAgICAgICAgIDxyZGY6U2VxPgogICAgICAgICAgICAgICA8cmRmOmxpPjg8L3JkZjpsaT4KICAgICAgICAgICAgICAgPHJkZjpsaT44PC9yZGY6bGk+CiAgICAgICAgICAgICAgIDxyZGY6bGk+ODwvcmRmOmxpPgogICAgICAgICAgICA8L3JkZjpTZXE+CiAgICAgICAgIDwvdGlmZjpCaXRzUGVyU2FtcGxlPgogICAgICAgICA8dGlmZjpQaG90b21ldHJpY0ludGVycHJldGF0aW9uPjI8L3RpZmY6UGhvdG9tZXRyaWNJbnRlcnByZXRhdGlvbj4KICAgICAgICAgPHRpZmY6T3JpZW50YXRpb24+MTwvdGlmZjpPcmllbnRhdGlvbj4KICAgICAgICAgPHRpZmY6U2FtcGxlc1BlclBpeGVsPjM8L3RpZmY6U2FtcGxlc1BlclBpeGVsPgogICAgICAgICA8dGlmZjpYUmVzb2x1dGlvbj4yMDAwMDAvMTAwMDA8L3RpZmY6WFJlc29sdXRpb24+CiAgICAgICAgIDx0aWZmOllSZXNvbHV0aW9uPjIwMDAwMC8xMDAwMDwvdGlmZjpZUmVzb2x1dGlvbj4KICAgICAgICAgPHRpZmY6UmVzb2x1dGlvblVuaXQ+MjwvdGlmZjpSZXNvbHV0aW9uVW5pdD4KICAgICAgICAgPGV4aWY6RXhpZlZlcnNpb24+MDIyMTwvZXhpZjpFeGlmVmVyc2lvbj4KICAgICAgICAgPGV4aWY6Q29sb3JTcGFjZT4xPC9leGlmOkNvbG9yU3BhY2U+CiAgICAgICAgIDxleGlmOlBpeGVsWERpbWVuc2lvbj42NDwvZXhpZjpQaXhlbFhEaW1lbnNpb24+CiAgICAgICAgIDxleGlmOlBpeGVsWURpbWVuc2lvbj42NDwvZXhpZjpQaXhlbFlEaW1lbnNpb24+CiAgICAgIDwvcmRmOkRlc2NyaXB0aW9uPgogICA8L3JkZjpSREY+CjwveDp4bXBtZXRhPgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgIAo8P3hwYWNrZXQgZW5kPSJ3Ij8+NSu5mgAAACBjSFJNAAB6JQAAgIMAAPn/AACA6QAAdTAAAOpgAAA6mAAAF2+SX8VGAAAHiklEQVR42uxZS49cVxGuqnPOffS7ZzwziWN7DIkBkYcEYsOG30AkNlkRARILxGOBWPAX2ASxCBtASLADxBokxGPDgqdFFMdREnsmnmHePdPd93EeVSx6xunusdvd80Cy1LXse7t0vlP1VX1VF59fvQlPsxE85TYHMAcwBzAHMAcwBzAHMAcwB/AUm57+VUTFbH2xBcDjyIWBtElWABUIT/RCIMEXW8IOUI0+YwAyyTNA+glOzgZAuFAqbXzsq8o0hMuROKrUFVu9rd+LMI4fa8yLQ8DWjddM8iyHbBRaEuxed+t3whZRXzAARCzz/aj5maVb30IkDvnwU2XqvtzPD/5hs3vKtCY4cWUXo2cXP/51kywHdzR6C4kIl913soO/63jp4gFYV5InwhD8kbAbfsjiQQKqZHLoEcB5C4QIwr4jIxFA5gJ1jXRFJFwKB0jXbL7R2fqL0tWRCAiQqYdi02X3AIRDBsKoEqToGA+SsJVQACkQLvv3D7f/nFRXvTscdoIqhdCz2Zoy9RmYOeVMTETOc6+3QxTpqDUcAQFRyiRmcFQDIgDAIUdUgHTySkBKkNAHzrIuACiVyFC4BESpOKIcIZBuiPgLjgAzo/QardXlW99Wps6hGCYmAqDSRAmACICJVzoPfr3/wc90fAUAQ7nbvvl669qXXLmFgALAPhMJo6VMlK6y7+zc/aEvd0lXL4EDxWGSvthY/nzw2XAEEEAAQATwxGlyNW28jIOSipiXdqn6ibh2E1AhIh5f+Tg9ADXpFw+rvy37H1wKAB/E2j5RTHE8GoFTTqO2iBd2iMgi1joRjpI2+6OJWZoEDuyzJxTiM5NYR+2iv7b+1hs6bnPIEU1wR77cRRpxwiJxsmA7f/UuR9xm5uBg486bxeGdEdYe9xav40VlGsyedEqhY7M1FbUunsSIyAxZ0XXZ7iDkwmCSetp8SdgNZ4SIGI1JukBmASQAgvNcZNvsjpDMuFeKss5tV/SQQClIk8Qky4CX0IlFhAhrlbqkg+zEvHtv6YXXr730/TJbH8tmEWF4yAhAJAABkKHfji2qXN+684Ptu29EleuIKHIiTC4jhUQEj08DCGAdANWY8+C6p092mqaPdOldT5kWkkEEETiD6ZneHlSbATUDg803OZQAIMKAAMIgAoiTrwEQAQkEAFGCdfkGyOByzmJ4tuUuIvb63SAqqV47vjqUYA+E/UnzeqwkRFQqWgBABknjBP1uCPn06u1cERi2Slovbdd1bwMSggRv29dfrbReDq4z4V/KtPLD/+yv/YaURlS2VCZuEaUz6Z8LADDgdCVtQFoHwOD7ztMzt75Wbb/iyt2JtXih6N7x3X9KyElXmBkAznz6c0VAREQEAAjBOV84BAARDxNPI+yYRQBYGJjh3HZ2AIAkwXLoASrhwuX9nXu/qi1+1pf7k1IoarveWz7fRIoDewAmVUUVz1Q6L4DEDzUc6SYSBZa8yLw9RMAJVUhEtFJpHJOpAahBcwjuEESeQP3LiIDLN1s3Xlt64Ruu2MLj3hxEwiN7wlD5AgACVHgs+1Z23/vxwdovTHL1/woAEfLCtszVKF1m3wfEKcu4jEZEx4tRdXXQXyYjv0gAiCgizoOETEdNE7cFztJFEVCZJvts+vHlfACQgL0rNgEYgVBg892fZodvcyjGb5adjto6viLsB2OaL3e93R8TcwKQxHXX/ZcEdvmGSEDUs65VZiGxeFJRZfELZBrAlgWLfM8XO6c0JpCu9ff/lnXWlAEAYA9p80Z14XPse6O5JEZhXFkh3RRxRIm3+/2dPwnI9CPB1AMNgC0PosYry5/8LpCRkCPi4zI/Sq/t3//lg9vfM/EyIOa9D5/79HdWnv9Kma2dqkv8UMORSoXtev/9vPNvHV+5aABE1hYYNIAL5QFMzlqMgAxSDCDCXDoRIVfu+HJv0tjtj0g3lWnORImpOSCCKnH5f/Ojd5WujS3VQARQIUWD1EDVLXvvCVsAEmAOIe+9H9yRd4MUQmELEsY6BqoK5xs2W1dTD8SzrVWs5153W+uKjtosbqyeMFukCCkS5iRONPQDWyIjAv2sGxhNsjiY8YGdsEUyI7VLRKnYUB/Fkm5Mr45mWKsoyRvNa+3VL2tTGxvqlanb7MPtuz9iLkglXCLrGqpEhBGxktad6wW7BqBQSsFo5dY34+r14LqjTiriu/v3fs6ugyq9hN1ocZC0P7W0+iqHYnS1CKRTDrbY+0PRfVtHi8IsJ5PhQLcmSR2khohlsYfx6uKNLypdYZ+NBBE1UNrb+WNv5765DAAuBHI5klaYcqCx7XQILgQrAnxKY36kWwGc9wI5EildGdOtqGIRFHY4iy6agcQ6ahX99Qd33tSmObwbFQClq+B3g90jXX/CJwZdy8vdzXd+EleeC6NtgVRKfOSy+xP22+cgMaJnyLIjV+yNaRYR0AoraarjpckfOE52M/0y38ZTo7IiqKSJiZeQoulJPEMnHkggedT5TjoaTtMQZbAEOIeTc6xVEB/Z5GXqlYgAPM7JDF7OvlY52+7mEpx8lNvwlNscwBzAHMAcwBzAHMAcwBzAOex/AwBoET5bwRr9gwAAAABJRU5ErkJggg==\"\n)\n\ntype Response struct {\n\tVersion     Version `json:\"version,string\"`\n\tPlayers     Players `json:\"players,string\"`\n\tDescription Message `json:\"description\"`\n\tFavicon     string  `json:\"favicon\"`\n}\n\ntype Version struct {\n\tName     string `json:\"name\"`\n\tProtocol int    `json:\"protocol\"`\n}\n\ntype Players struct {\n\tMax    int            `json:\"max\"`\n\tOnline int            `json:\"online\"`\n\tSample []SamplePlayer `json:\"sample\"`\n}\n\ntype SamplePlayer struct {\n\tName string `json:\"name\"`\n\tID   string `json:\"id\"`\n}\n\ntype Message struct {\n\tText string `json:\"text\"`\n}\n\nfunc DefaultResponse() Response {\n\treturn Response{\n\t\tVersion: Version{\n\t\t\tName:     \"GoLang Server\",\n\t\t\tProtocol: data.CurrentProtocol.Protocol(),\n\t\t},\n\t\tPlayers: Players{\n\t\t\tMax:    10,\n\t\t\tOnline: 1,\n\t\t\tSample: []SamplePlayer{\n\t\t\t\t{\n\t\t\t\t\tName: SxtannaName,\n\t\t\t\t\tID:   SxtannaUUID,\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\tDescription: Message{\n\t\t\tText: chat.Translate(ServerMotd),\n\t\t},\n\t\tFavicon: ServerIcon,\n\t}\n}\n"
  },
  {
    "path": "impl/data/system/command.go",
    "content": "package system\n\ntype Command int\n\ntype Message struct {\n\tCommand\n\tMessage interface{}\n}\n\nconst (\n\t// stops the server entirely\n\tSTOP Command = iota\n\tFAIL\n)\n\nfunc Make(command Command, message interface{}) Message {\n\treturn struct {\n\t\tCommand\n\t\tMessage interface{}\n\t}{Command: command, Message: message}\n}\n"
  },
  {
    "path": "impl/data/values/constants.go",
    "content": "package values\n\nimport (\n\t\"encoding/binary\"\n\n\t\"github.com/golangmc/minecraft-server/apis/base\"\n)\n\nconst (\n\t// ticks per second\n\tTPS = 20\n\t// milliseconds per tick\n\tMPT = 1_000 / TPS\n)\n\nvar DefaultWorldHashedSeed = int64(binary.LittleEndian.Uint64(base.JavaSHA256HashLong(int64(base.JavaStringHashCode(\"North Carolina\")))))\n"
  },
  {
    "path": "impl/game/auth/authenticate.go",
    "content": "package auth\n\nimport (\n\t\"crypto/sha1\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"strings\"\n\n\t\"github.com/golangmc/minecraft-server/apis/urls\"\n)\n\nconst url = \"https://sessionserver.mojang.com/session/minecraft/hasJoined\"\n\ntype Auth struct {\n\tUUID string `json:\"id\"`\n\tName string `json:\"name\"`\n\tProp []Prop `json:\"properties\"`\n}\n\ntype Prop struct {\n\tName string  `json:\"name\"`\n\tData string  `json:\"value\"`\n\tSign *string `json:\"signature\"`\n}\n\nfunc RunAuthGet(secret []byte, name string, callback func(auth *Auth, err error)) {\n\tgo execute(generateAuthURL(name, generateAuthSHA(secret)), callback)\n}\n\nfunc execute(url string, callback func(auth *Auth, err error)) {\n\tget, err := urls.GetByte(url)\n\tif err != nil {\n\t\tcallback(nil, err)\n\t\treturn\n\t}\n\n\tvar auth Auth\n\n\terr = json.Unmarshal(get, &auth)\n\n\tif err != nil {\n\t\tcallback(nil, err)\n\t} else {\n\t\tcallback(&auth, nil)\n\t}\n}\n\nfunc generateAuthURL(name, hash string) string {\n\treturn fmt.Sprintf(\"%s?username=%s&serverId=%s\", url, name, hash)\n}\n\nfunc generateAuthSHA(secret []byte) string {\n\tsha := sha1.New()\n\n\t// update with encoded secret, and encoded public\n\t_, public := NewCrypt()\n\n\tsha.Write(secret)\n\tsha.Write(public)\n\n\thash := sha.Sum(nil)\n\n\t// Check for negative hashes\n\tnegative := (hash[0] & 0x80) == 0x80\n\n\tif negative {\n\t\tcarry := true\n\n\t\tfor i := len(hash) - 1; i >= 0; i-- {\n\t\t\thash[i] = ^hash[i]\n\t\t\tif carry {\n\t\t\t\tcarry = hash[i] == 0xff\n\t\t\t\thash[i]++\n\t\t\t}\n\t\t}\n\t}\n\n\t// Trim away zeroes\n\tres := strings.TrimLeft(fmt.Sprintf(\"%x\", hash), \"0\")\n\tif negative {\n\t\tres = \"-\" + res\n\t}\n\n\treturn res\n}\n"
  },
  {
    "path": "impl/game/auth/cryptography.go",
    "content": "package auth\n\nimport (\n\t\"crypto/rand\"\n\t\"crypto/rsa\"\n\t\"crypto/x509\"\n)\n\nvar secretKey *rsa.PrivateKey\nvar publicKey *rsa.PublicKey\n\nvar secretArr []byte\nvar publicArr []byte\n\nfunc NewCrypt() (secret []byte, public []byte) {\n\n\t// initialize keys\n\tif secretKey == nil || publicKey == nil {\n\t\tsecretKey, publicKey = generate()\n\n\t\tx509Secret := x509.MarshalPKCS1PrivateKey(secretKey)\n\t\tx509Public, _ := x509.MarshalPKIXPublicKey(publicKey)\n\n\t\tsecretArr = x509Secret\n\t\tpublicArr = x509Public\n\t}\n\n\treturn secretArr, publicArr\n}\n\nfunc Encrypt(data []byte) ([]byte, error) {\n\treturn rsa.EncryptPKCS1v15(rand.Reader, publicKey, data)\n}\n\nfunc Decrypt(data []byte) ([]byte, error) {\n\treturn rsa.DecryptPKCS1v15(rand.Reader, secretKey, data)\n}\n\nfunc generate() (secretKey *rsa.PrivateKey, publicKey *rsa.PublicKey) {\n\tkey, err := rsa.GenerateKey(rand.Reader, 1024)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\n\tsecretKey = key\n\tpublicKey = &key.PublicKey\n\n\tsecretKey.Precompute()\n\tif err := secretKey.Validate(); err != nil {\n\t\tpanic(err)\n\t}\n\n\treturn\n}\n"
  },
  {
    "path": "impl/game/ents/entity.go",
    "content": "package ents\n\nimport \"github.com/golangmc/minecraft-server/apis/uuid\"\n\nvar entityCounter = int64(0)\n\ntype entity struct {\n\tname string\n\tuuid uuid.UUID\n\n\tentityID int64\n}\n\nfunc newEntity() entity {\n\tid := entityCounter\n\tentityCounter++\n\n\treturn entity{entityID: id}\n}\n\nfunc (e *entity) Name() string {\n\treturn e.name\n}\n\nfunc (e *entity) UUID() uuid.UUID {\n\treturn e.uuid\n}\n\nfunc (e *entity) SetName(name string) {\n\te.name = name\n}\n\nfunc (e *entity) SetUUID(uuid uuid.UUID) {\n\te.uuid = uuid\n}\n\nfunc (e *entity) SendMessage(message ...interface{}) {\n\t// nothing\n}\n\nfunc (e *entity) EntityUUID() int64 {\n\treturn e.entityID\n}\n"
  },
  {
    "path": "impl/game/ents/living.go",
    "content": "package ents\n\ntype entityLiving struct {\n\tentity\n\n\thealth float64\n}\n\nfunc newEntityLiving() entityLiving {\n\treturn entityLiving{entity: newEntity()}\n}\n\nfunc (e *entityLiving) GetHealth() float64 {\n\treturn e.health\n}\n\nfunc (e *entityLiving) SetHealth(health float64) {\n\te.health = health\n}\n"
  },
  {
    "path": "impl/game/ents/player.go",
    "content": "package ents\n\nimport (\n\t\"github.com/golangmc/minecraft-server/apis/data/msgs\"\n\t\"github.com/golangmc/minecraft-server/apis/ents\"\n\t\"github.com/golangmc/minecraft-server/apis/game\"\n\n\t\"github.com/golangmc/minecraft-server/impl/prot/client\"\n\n\tapis_base \"github.com/golangmc/minecraft-server/apis/base\"\n\timpl_base \"github.com/golangmc/minecraft-server/impl/base\"\n)\n\ntype player struct {\n\tentityLiving\n\n\tprof *game.Profile\n\n\tonline bool\n\n\tconn impl_base.Connection\n\n\tmode game.GameMode\n}\n\nfunc NewPlayer(prof *game.Profile, conn impl_base.Connection) ents.Player {\n\tplayer := &player{\n\t\tprof:         prof,\n\t\tentityLiving: newEntityLiving(),\n\t}\n\n\tplayer.SetName(prof.Name)\n\tplayer.SetUUID(prof.UUID)\n\n\tplayer.SetConn(conn)\n\n\treturn player\n}\n\nfunc (p *player) SendMessage(message ...interface{}) {\n\tpacket := client.PacketOChatMessage{\n\t\tMessage:         *msgs.New(apis_base.ConvertToString(message...)),\n\t\tMessagePosition: msgs.NormalChat,\n\t}\n\n\tp.conn.SendPacket(&packet)\n}\n\nfunc (p *player) GetGameMode() game.GameMode {\n\treturn p.mode\n}\n\nfunc (p *player) SetGameMode(mode game.GameMode) {\n\tp.mode = mode\n}\n\nfunc (p *player) GetIsOnline() bool {\n\treturn p.online\n}\n\nfunc (p *player) SetIsOnline(state bool) {\n\tp.online = state\n}\n\nfunc (p *player) GetProfile() *game.Profile {\n\treturn p.prof\n}\n\nfunc (p *player) SetConn(conn impl_base.Connection) {\n\tp.conn = conn\n}\n"
  },
  {
    "path": "impl/game/event/events.go",
    "content": "package event\n\nimport (\n\t\"github.com/golangmc/minecraft-server/impl/base\"\n\t\"github.com/golangmc/minecraft-server/impl/data/plugin\"\n)\n\ntype PlayerConnJoinEvent struct {\n\tConn base.PlayerAndConnection\n}\n\ntype PlayerConnQuitEvent struct {\n\tConn base.PlayerAndConnection\n}\n\ntype PlayerPluginMessagePullEvent struct {\n\tConn base.PlayerAndConnection\n\n\tChannel string\n\tMessage plugin.Message\n}\n"
  },
  {
    "path": "impl/game/level/block.go",
    "content": "package level\n\nimport (\n\tapis_level \"github.com/golangmc/minecraft-server/apis/game/level\"\n)\n\ntype block struct {\n\t// these should always be level coordinates\n\tx int\n\ty int\n\tz int\n\n\tslice *slice\n}\n\nfunc (b *block) X() int {\n\treturn b.x\n}\n\nfunc (b *block) Y() int {\n\treturn b.y\n}\n\nfunc (b *block) Z() int {\n\treturn b.z\n}\n\nfunc (b *block) Chunk() apis_level.Chunk {\n\treturn b.slice.chunk\n}\n\nfunc (b *block) Level() apis_level.Level {\n\treturn b.slice.chunk.level\n}\n\nfunc (b *block) GetBlockType() (value int) {\n\tvalue = b.slice.sliceBlockGet(sliceIndex(blockLevelToSlice(b.x, b.y, b.z)))\n\treturn\n}\n\nfunc (b *block) SetBlockType(value int) {\n\tvalue = b.slice.sliceBlockSet(sliceIndex(blockLevelToSlice(b.x, b.y, b.z)), value)\n\treturn\n}\n"
  },
  {
    "path": "impl/game/level/chunk.go",
    "content": "package level\n\nimport (\n\t\"github.com/golangmc/minecraft-server/apis/buff\"\n\t\"github.com/golangmc/minecraft-server/apis/data/tags\"\n\tapis_level \"github.com/golangmc/minecraft-server/apis/game/level\"\n\t\"github.com/golangmc/minecraft-server/impl/base\"\n)\n\ntype chunk struct {\n\tx int\n\tz int\n\n\tlevel *level\n\n\tslices []*slice\n\n\theightMap map[heightMapType]*heightMap\n}\n\nfunc newChunk(level *level, x, z int) *chunk {\n\tchunk := &chunk{\n\t\tx: x,\n\t\tz: z,\n\n\t\tlevel: level,\n\n\t\tslices:    make([]*slice, apis_level.SliceC, apis_level.SliceC),\n\t\theightMap: make(map[heightMapType]*heightMap),\n\t}\n\n\tfor _, mapType := range heightMapTypes {\n\t\tchunk.heightMap[mapType] = &heightMap{\n\t\t\tchunk: chunk,\n\n\t\t\theightMapType: mapType,\n\t\t\theightMapData: base.NewCompacter(9, 256),\n\t\t}\n\t}\n\n\treturn chunk\n}\n\nfunc (c *chunk) ChunkX() int {\n\treturn c.x\n}\n\nfunc (c *chunk) ChunkZ() int {\n\treturn c.z\n}\n\nfunc (c *chunk) Level() apis_level.Level {\n\treturn c.level\n}\n\nfunc (c *chunk) Slices() []apis_level.Slice {\n\tslices := make([]apis_level.Slice, apis_level.SliceC, apis_level.SliceC)\n\n\tfor index, slice := range c.slices {\n\t\tslices[index] = slice\n\t}\n\n\treturn slices\n}\n\nfunc (c *chunk) GetSlice(y int) apis_level.Slice {\n\tif y < 0 || y > 15 {\n\t\tpanic(\"index out of range [0:15]\")\n\t}\n\n\tslc := c.slices[y]\n\tif slc != nil {\n\t\treturn slc\n\t}\n\n\tgen := newSlice(c, y)\n\tc.slices[y] = gen\n\n\treturn gen\n}\n\nfunc (c *chunk) GetBlock(x, y, z int) apis_level.Block {\n\tif x < 0 || x > 15 {\n\t\tpanic(\"invalid x value for chunk get block\")\n\t}\n\tif y < 0 || y > 255 {\n\t\tpanic(\"invalid y value for chunk get block\")\n\t}\n\tif z < 0 || z > 15 {\n\t\tpanic(\"invalid z value for chunk get block\")\n\t}\n\n\treturn &block{\n\t\tx: (c.x << 0x04) | x,\n\t\ty: y,\n\t\tz: (c.z << 0x04) | z,\n\n\t\tslice: c.GetSlice(y >> 0x04).(*slice),\n\t}\n}\n\nfunc (c *chunk) Push(writer buff.Buffer) {\n\tmask := int32(0)\n\n\tfor i := 0; i < apis_level.SliceC; i++ {\n\t\tif len(c.slices) < i {\n\t\t\tbreak\n\t\t}\n\n\t\tmask |= 1 << i\n\n\t\tslice := c.slices[i]\n\t\tslice.Push(writer)\n\t}\n\n\twriter.PushVrI(mask)\n}\n\nfunc (c *chunk) HeightMapNbtCompound() *tags.NbtCompound {\n\tcompound := tags.NbtCompound{Value: make(map[string]tags.Nbt)}\n\n\tmotionBlocking := c.heightMap[MotionBlocking]\n\tcompound.Set(string(motionBlocking.heightMapType), &tags.NbtArrI64{Value: motionBlocking.heightMapData.Values})\n\n\treturn &compound\n}\n\ntype heightMapType string\n\nconst (\n\tWorldSurfaceWg         heightMapType = \"WORLD_SURFACE_WG\"\n\tWorldSurface           heightMapType = \"WORLD_SURFACE\"\n\tOceanFloorWg           heightMapType = \"OCEAN_FLOOR_WG\"\n\tOceanFloor             heightMapType = \"OCEAN_FLOOR\"\n\tMotionBlocking         heightMapType = \"MOTION_BLOCKING\"\n\tMotionBlockingNoLeaves heightMapType = \"MOTION_BLOCKING_NO_LEAVES\"\n)\n\nvar heightMapTypes = []heightMapType{\n\tWorldSurfaceWg,\n\tWorldSurface,\n\tOceanFloorWg,\n\tOceanFloor,\n\tMotionBlocking,\n\tMotionBlockingNoLeaves,\n}\n\ntype heightMap struct {\n\tchunk *chunk\n\tcheck func(b *block) bool\n\n\theightMapType heightMapType\n\theightMapData *base.Compacter\n}\n"
  },
  {
    "path": "impl/game/level/level.go",
    "content": "package level\n\nimport (\n\tapis_level \"github.com/golangmc/minecraft-server/apis/game/level\"\n\t\"github.com/golangmc/minecraft-server/apis/uuid\"\n)\n\ntype level struct {\n\tname string\n\tuuid uuid.UUID\n\n\tchunks map[int64]*chunk\n}\n\nfunc NewLevel(name string) apis_level.Level {\n\tlevel := &level{\n\t\tname: name,\n\t\tuuid: uuid.NewUUID(),\n\n\t\tchunks: make(map[int64]*chunk),\n\t}\n\n\treturn level\n}\n\nfunc (l *level) Name() string {\n\treturn l.name\n}\n\nfunc (l *level) UUID() uuid.UUID {\n\treturn l.uuid\n}\n\nfunc (l *level) Chunks() []apis_level.Chunk {\n\tchunks := make([]apis_level.Chunk, len(l.chunks), len(l.chunks))\n\n\tindex := 0\n\tfor _, chunk := range l.chunks {\n\t\tchunks[index] = chunk\n\t\tindex++\n\t}\n\n\treturn chunks\n}\n\nfunc (l *level) GetChunk(x, z int) apis_level.Chunk {\n\treturn l.getChunk(x, z, true)\n}\n\nfunc (l *level) GetChunkIfLoaded(x, z int) apis_level.Chunk {\n\treturn l.getChunk(x, z, false)\n}\n\nfunc (l *level) GetBlock(x, y, z int) apis_level.Block {\n\treturn &block{\n\t\tx: x,\n\t\ty: y,\n\t\tz: z,\n\n\t\tslice: l.GetChunk(blockXZToChunkXZ(x, z)).GetSlice(blockYToSliceY(y)).(*slice),\n\t}\n}\n\nfunc (l *level) getChunk(x, z int, generate bool) apis_level.Chunk {\n\tidx := chunkIndex(x, z)\n\n\tcnk, con := l.chunks[idx]\n\tif con {\n\t\treturn cnk\n\t}\n\n\tif generate {\n\t\tgen := newChunk(l, x, z)\n\t\tl.chunks[idx] = gen\n\n\t\treturn gen\n\t}\n\n\treturn nil\n}\n\n// generates chunks with the normal super-flat style\nfunc GenSuperFlat(level apis_level.Level, size int) {\n\n\tid := 210\n\tfor x := -size; x < size; x++ {\n\t\tfor z := -size; z < size; z++ {\n\t\t\tchunk := level.GetChunk(x, z)\n\n\t\t\tfor sliceY := 0; sliceY < apis_level.SliceC; sliceY++ {\n\t\t\t\tchunk.GetSlice(sliceY)\n\t\t\t}\n\n\t\t\tchunk.GetSlice(0).(*slice).fill(id)\n\t\t\tchunk.GetSlice(1).(*slice).fill(id)\n\t\t\tchunk.GetSlice(2).(*slice).fill(id)\n\t\t\tid++\n\t\t}\n\t}\n\n\tfor _, c := range level.Chunks() {\n\t\t_ = c.(*chunk).heightMap[MotionBlocking]\n\n\t\tfor x := 0; x < apis_level.ChunkW; x++ {\n\t\t\tfor z := 0; z < apis_level.ChunkL; z++ {\n\t\t\t\t// height.heightMapData.Set(x + z * 16, 16 * 3)\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "impl/game/level/slice.go",
    "content": "package level\n\nimport (\n\t\"github.com/golangmc/minecraft-server/apis/buff\"\n\tapis_level \"github.com/golangmc/minecraft-server/apis/game/level\"\n\t\"github.com/golangmc/minecraft-server/impl/base\"\n)\n\ntype slice struct {\n\tindex int\n\n\tchunk *chunk\n\n\tvalues *base.Compacter\n}\n\nfunc newSlice(chunk *chunk, index int) *slice {\n\tslice := &slice{\n\t\tindex: index,\n\n\t\tchunk: chunk,\n\n\t\tvalues: base.NewCompacter(apis_level.BitsPerBlock, apis_level.SliceS),\n\t}\n\n\treturn slice\n}\n\nfunc (s *slice) Index() int {\n\treturn s.index\n}\n\nfunc (s *slice) Chunk() apis_level.Chunk {\n\treturn s.chunk\n}\n\nfunc (s *slice) Level() apis_level.Level {\n\treturn s.chunk.level\n}\n\nfunc (s *slice) GetBlock(x, y, z int) apis_level.Block {\n\tif x < 0 || x > 15 {\n\t\tpanic(\"invalid x value for slice get block\")\n\t}\n\tif y < 0 || y > 15 {\n\t\tpanic(\"invalid y value for slice get block\")\n\t}\n\tif z < 0 || z > 15 {\n\t\tpanic(\"invalid z value for slice get block\")\n\t}\n\n\treturn &block{\n\t\tx: (s.chunk.x << 0x04) | x,\n\t\ty: (apis_level.SliceH * s.index) + y,\n\t\tz: (s.chunk.z << 0x04) | z,\n\n\t\tslice: s,\n\t}\n}\n\nfunc (s *slice) Push(writer buff.Buffer) {\n\twriter.PushI16(apis_level.SliceS) // full slice\n\n\twriter.PushByt(apis_level.BitsPerBlock)\n\n\t// the server is using the direct palette\n\n\twriter.PushVrI(int32(len(s.values.Values)))\n\n\tfor _, value := range s.values.Values {\n\t\twriter.PushI64(value)\n\t}\n}\n\nfunc (s *slice) sliceBlockGet(index int) int {\n\treturn s.values.Get(index)\n}\n\nfunc (s *slice) sliceBlockSet(index int, value int) int {\n\treturn s.values.Set(index, value)\n}\n\nfunc (s *slice) fill(value int) {\n\tfor y := 0; y < apis_level.SliceH; y++ {\n\t\ts.layer(y, value)\n\t}\n}\n\nfunc (s *slice) layer(index int, value int) {\n\tfor x := 0; x < apis_level.ChunkW; x++ {\n\t\tfor z := 0; z < apis_level.ChunkL; z++ {\n\t\t\ts.sliceBlockSet(sliceIndex(x, index, z), value)\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "impl/game/level/value.go",
    "content": "package level\n\nfunc chunkIndex(x, z int) int64 {\n\treturn (int64(z) << 0x20) | (int64(x) & 0xFFFFFFFF)\n}\n\nfunc sliceIndex(x, y, z int) int {\n\treturn y<<0x08 | z<<0x04 | x\n}\n\nfunc blockYToSliceY(blockY int) (sliceY int) {\n\tsliceY = blockY >> 0x04\n\treturn\n}\n\nfunc blockXZToChunkXZ(blockX, blockZ int) (chunkX, chunkZ int) {\n\tchunkX = blockX >> 0x04\n\tchunkZ = blockZ >> 0x04\n\treturn\n}\n\nfunc blockLevelToSlice(levelBlockX, levelBlockY, levelBlockZ int) (sliceBlockX, sliceBlockY, sliceBlockZ int) {\n\tsliceBlockX = levelBlockX & 0xF\n\tsliceBlockY = levelBlockY & 0xF\n\tsliceBlockZ = levelBlockZ & 0xF\n\n\treturn\n}\n"
  },
  {
    "path": "impl/game/mode/mode_state0.go",
    "content": "package mode\n\nimport (\n\t\"github.com/golangmc/minecraft-server/apis/util\"\n\t\"github.com/golangmc/minecraft-server/impl/base\"\n\t\"github.com/golangmc/minecraft-server/impl/prot/server\"\n)\n\n/**\n * handshake\n */\n\nfunc HandleState0(watcher util.Watcher) {\n\n\twatcher.SubAs(func(packet *server.PacketIHandshake, conn base.Connection) {\n\t\tconn.SetState(packet.State)\n\t})\n\n}\n"
  },
  {
    "path": "impl/game/mode/mode_state1.go",
    "content": "package mode\n\nimport (\n\t\"github.com/golangmc/minecraft-server/apis/util\"\n\t\"github.com/golangmc/minecraft-server/impl/base\"\n\t\"github.com/golangmc/minecraft-server/impl/data/status\"\n\t\"github.com/golangmc/minecraft-server/impl/prot/client\"\n\t\"github.com/golangmc/minecraft-server/impl/prot/server\"\n)\n\n/**\n * status\n */\n\nfunc HandleState1(watcher util.Watcher) {\n\n\twatcher.SubAs(func(packet *server.PacketIRequest, conn base.Connection) {\n\t\tresponse := client.PacketOResponse{Status: status.DefaultResponse()}\n\t\tconn.SendPacket(&response)\n\t})\n\n\twatcher.SubAs(func(packet *server.PacketIPing, conn base.Connection) {\n\t\tresponse := client.PacketOPong{Ping: packet.Ping}\n\t\tconn.SendPacket(&response)\n\t})\n\n}\n"
  },
  {
    "path": "impl/game/mode/mode_state2.go",
    "content": "package mode\n\nimport (\n\t\"bytes\"\n\t\"fmt\"\n\n\t\"github.com/golangmc/minecraft-server/apis/data/chat\"\n\t\"github.com/golangmc/minecraft-server/apis/data/msgs\"\n\t\"github.com/golangmc/minecraft-server/apis/game\"\n\t\"github.com/golangmc/minecraft-server/apis/util\"\n\t\"github.com/golangmc/minecraft-server/apis/uuid\"\n\t\"github.com/golangmc/minecraft-server/impl/base\"\n\t\"github.com/golangmc/minecraft-server/impl/game/auth\"\n\t\"github.com/golangmc/minecraft-server/impl/game/ents\"\n\t\"github.com/golangmc/minecraft-server/impl/prot/client\"\n\t\"github.com/golangmc/minecraft-server/impl/prot/server\"\n)\n\n/**\n * login\n */\n\nfunc HandleState2(watcher util.Watcher, join chan base.PlayerAndConnection) {\n\n\twatcher.SubAs(func(packet *server.PacketILoginStart, conn base.Connection) {\n\t\tconn.CertifyValues(packet.PlayerName)\n\n\t\t_, public := auth.NewCrypt()\n\n\t\tresponse := client.PacketOEncryptionRequest{\n\t\t\tServer: \"\",\n\t\t\tPublic: public,\n\t\t\tVerify: conn.CertifyData(),\n\t\t}\n\n\t\tconn.SendPacket(&response)\n\t})\n\n\twatcher.SubAs(func(packet *server.PacketIEncryptionResponse, conn base.Connection) {\n\t\tdefer func() {\n\t\t\tif err := recover(); err != nil {\n\t\t\t\tconn.SendPacket(&client.PacketODisconnect{\n\t\t\t\t\tReason: *msgs.New(fmt.Sprintf(\"Authentication failed: %v\", err)).SetColor(chat.Red),\n\t\t\t\t})\n\t\t\t}\n\t\t}()\n\n\t\tver, err := auth.Decrypt(packet.Verify)\n\t\tif err != nil {\n\t\t\tpanic(fmt.Errorf(\"failed to decrypt token: %s\\n%v\\n\", conn.CertifyName(), err))\n\t\t}\n\n\t\tif !bytes.Equal(ver, conn.CertifyData()) {\n\t\t\tpanic(fmt.Errorf(\"encryption failed, tokens are different: %s\\n%v | %v\", conn.CertifyName(), ver, conn.CertifyData()))\n\t\t}\n\n\t\tsec, err := auth.Decrypt(packet.Secret)\n\t\tif err != nil {\n\t\t\tpanic(fmt.Errorf(\"failed to decrypt secret: %s\\n%v\\n\", conn.CertifyName(), err))\n\t\t}\n\n\t\tconn.CertifyUpdate(sec) // enable encryption on the connection\n\n\t\tauth.RunAuthGet(sec, conn.CertifyName(), func(auth *auth.Auth, err error) {\n\t\t\tdefer func() {\n\t\t\t\tif err := recover(); err != nil {\n\t\t\t\t\tconn.SendPacket(&client.PacketODisconnect{\n\t\t\t\t\t\tReason: *msgs.New(fmt.Sprintf(\"Authentication failed: %v\", err)).SetColor(chat.Red),\n\t\t\t\t\t})\n\t\t\t\t}\n\t\t\t}()\n\n\t\t\tif err != nil {\n\t\t\t\tpanic(fmt.Errorf(\"failed to authenticate: %s\\n%v\\n\", conn.CertifyName(), err))\n\t\t\t}\n\n\t\t\tuuid, err := uuid.TextToUUID(auth.UUID)\n\t\t\tif err != nil {\n\t\t\t\tpanic(fmt.Errorf(\"failed to decode uuid for %s: %s\\n%v\\n\", conn.CertifyName(), auth.UUID, err))\n\t\t\t}\n\n\t\t\tprof := game.Profile{\n\t\t\t\tUUID: uuid,\n\t\t\t\tName: auth.Name,\n\t\t\t}\n\n\t\t\tfor _, prop := range auth.Prop {\n\t\t\t\tprof.Properties = append(prof.Properties, &game.ProfileProperty{\n\t\t\t\t\tName:      prop.Name,\n\t\t\t\t\tValue:     prop.Data,\n\t\t\t\t\tSignature: prop.Sign,\n\t\t\t\t})\n\t\t\t}\n\n\t\t\tplayer := ents.NewPlayer(&prof, conn)\n\n\t\t\tconn.SendPacket(&client.PacketOLoginSuccess{\n\t\t\t\tPlayerName: player.Name(),\n\t\t\t\tPlayerUUID: player.UUID().String(),\n\t\t\t})\n\n\t\t\tconn.SetState(base.PLAY)\n\n\t\t\tjoin <- base.PlayerAndConnection{\n\t\t\t\tPlayer:     player,\n\t\t\t\tConnection: conn,\n\t\t\t}\n\t\t})\n\n\t})\n\n}\n"
  },
  {
    "path": "impl/game/mode/mode_state3.go",
    "content": "package mode\n\nimport (\n\t\"fmt\"\n\t\"time\"\n\n\t\"github.com/golangmc/minecraft-server/apis\"\n\t\"github.com/golangmc/minecraft-server/apis/data\"\n\t\"github.com/golangmc/minecraft-server/apis/data/chat\"\n\t\"github.com/golangmc/minecraft-server/apis/data/msgs\"\n\t\"github.com/golangmc/minecraft-server/apis/game\"\n\t\"github.com/golangmc/minecraft-server/apis/logs\"\n\t\"github.com/golangmc/minecraft-server/apis/task\"\n\t\"github.com/golangmc/minecraft-server/apis/util\"\n\t\"github.com/golangmc/minecraft-server/impl/base\"\n\t\"github.com/golangmc/minecraft-server/impl/data/client\"\n\t\"github.com/golangmc/minecraft-server/impl/data/plugin\"\n\t\"github.com/golangmc/minecraft-server/impl/data/values\"\n\timpl_level \"github.com/golangmc/minecraft-server/impl/game/level\"\n\n\timpl_event \"github.com/golangmc/minecraft-server/impl/game/event\"\n\n\tclient_packet \"github.com/golangmc/minecraft-server/impl/prot/client\"\n\tserver_packet \"github.com/golangmc/minecraft-server/impl/prot/server\"\n)\n\nfunc HandleState3(watcher util.Watcher, logger *logs.Logging, tasking *task.Tasking, join chan base.PlayerAndConnection, quit chan base.PlayerAndConnection) {\n\n\ttasking.EveryTime(10, time.Second, func(task *task.Task) {\n\n\t\tapi := apis.MinecraftServer()\n\n\t\t// I hate this, add a functional method for player iterating\n\t\tfor _, player := range api.Players() {\n\n\t\t\t// also probably add one that returns both the player and their connection\n\t\t\tconn := api.ConnByUUID(player.UUID())\n\n\t\t\t// keep player connection alive via keep alive\n\t\t\tconn.SendPacket(&client_packet.PacketOKeepAlive{KeepAliveID: time.Now().UnixNano() / 1e6})\n\t\t}\n\t})\n\n\twatcher.SubAs(func(packet *server_packet.PacketIKeepAlive, conn base.Connection) {\n\t\tlogger.DataF(\"player %s is being kept alive\", conn.Address())\n\t})\n\n\twatcher.SubAs(func(packet *server_packet.PacketIPluginMessage, conn base.Connection) {\n\t\tapi := apis.MinecraftServer()\n\n\t\tplayer := api.PlayerByConn(conn)\n\t\tif player == nil {\n\t\t\treturn // log no player found?\n\t\t}\n\n\t\tapi.Watcher().PubAs(impl_event.PlayerPluginMessagePullEvent{\n\t\t\tConn: base.PlayerAndConnection{\n\t\t\t\tConnection: conn,\n\t\t\t\tPlayer:     player,\n\t\t\t},\n\t\t\tChannel: packet.Message.Chan(),\n\t\t\tMessage: packet.Message,\n\t\t})\n\t})\n\n\twatcher.SubAs(func(packet *server_packet.PacketIChatMessage, conn base.Connection) {\n\t\tapi := apis.MinecraftServer()\n\n\t\twho := api.PlayerByConn(conn)\n\t\tout := msgs.\n\t\t\tNew(who.Name()).SetColor(chat.White).\n\t\t\tAdd(\":\").SetColor(chat.Gray).\n\t\t\tAdd(\" \").\n\t\t\tAdd(chat.Translate(packet.Message)).SetColor(chat.White).\n\t\t\tAsText() // why not just use translate?\n\n\t\tapi.Broadcast(out)\n\t})\n\n\tgo func() {\n\t\tfor conn := range join {\n\t\t\tapis.MinecraftServer().Watcher().PubAs(impl_event.PlayerConnJoinEvent{Conn: conn})\n\n\t\t\tconn.SendPacket(&client_packet.PacketOJoinGame{\n\t\t\t\tEntityID:      int32(conn.EntityUUID()),\n\t\t\t\tHardcore:      false,\n\t\t\t\tGameMode:      game.CREATIVE,\n\t\t\t\tDimension:     game.OVERWORLD,\n\t\t\t\tHashedSeed:    values.DefaultWorldHashedSeed,\n\t\t\t\tMaxPlayers:    10,\n\t\t\t\tLevelType:     game.DEFAULT,\n\t\t\t\tViewDistance:  12,\n\t\t\t\tReduceDebug:   false,\n\t\t\t\tRespawnScreen: false,\n\t\t\t})\n\n\t\t\tconn.SendPacket(&client_packet.PacketOPluginMessage{\n\t\t\t\tMessage: &plugin.Brand{\n\t\t\t\t\tName: chat.Translate(fmt.Sprintf(\"&b%s&r &a%s&r\", \"GoLangMc\", apis.MinecraftServer().ServerVersion())),\n\t\t\t\t},\n\t\t\t})\n\n\t\t\tconn.SendPacket(&client_packet.PacketOServerDifficulty{\n\t\t\t\tDifficulty: game.PEACEFUL,\n\t\t\t\tLocked:     true,\n\t\t\t})\n\n\t\t\tconn.SendPacket(&client_packet.PacketOPlayerAbilities{\n\t\t\t\tAbilities: client.PlayerAbilities{\n\t\t\t\t\tInvulnerable: true,\n\t\t\t\t\tFlying:       true,\n\t\t\t\t\tAllowFlight:  true,\n\t\t\t\t\tInstantBuild: false,\n\t\t\t\t},\n\t\t\t\tFlyingSpeed: 0.05, // default value\n\t\t\t\tFieldOfView: 0.1,  // default value\n\t\t\t})\n\n\t\t\tconn.SendPacket(&client_packet.PacketOHeldItemChange{\n\t\t\t\tSlot: client.SLOT_0,\n\t\t\t})\n\n\t\t\tconn.SendPacket(&client_packet.PacketODeclareRecipes{})\n\n\t\t\tconn.SendPacket(&client_packet.PacketOPlayerLocation{\n\t\t\t\tID: 0,\n\t\t\t\tLocation: data.Location{\n\t\t\t\t\tPositionF: data.PositionF{\n\t\t\t\t\t\tX: 0,\n\t\t\t\t\t\tY: 10,\n\t\t\t\t\t\tZ: 0,\n\t\t\t\t\t},\n\t\t\t\t\tRotationF: data.RotationF{\n\t\t\t\t\t\tAxisX: 0,\n\t\t\t\t\t\tAxisY: 0,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tRelative: client.Relativity{},\n\t\t\t})\n\n\t\t\tconn.SendPacket(&client_packet.PacketOPlayerInfo{\n\t\t\t\tAction: client.AddPlayer,\n\t\t\t\tValues: []client.PlayerInfo{\n\t\t\t\t\t&client.PlayerInfoAddPlayer{Player: conn.Player},\n\t\t\t\t},\n\t\t\t})\n\n\t\t\tconn.SendPacket(&client_packet.PacketOEntityMetadata{Entity: conn.Player})\n\n\t\t\tlevel := impl_level.NewLevel(\"test\")\n\t\t\timpl_level.GenSuperFlat(level, 6)\n\n\t\t\tfor _, chunk := range level.Chunks() {\n\t\t\t\tconn.SendPacket(&client_packet.PacketOChunkData{Chunk: chunk})\n\t\t\t}\n\n\t\t\tlogger.DataF(\"chunks sent to player: %s\", conn.Player.Name())\n\n\t\t\tconn.SendPacket(&client_packet.PacketOPlayerLocation{\n\t\t\t\tID: 1,\n\t\t\t\tLocation: data.Location{\n\t\t\t\t\tPositionF: data.PositionF{\n\t\t\t\t\t\tX: 0,\n\t\t\t\t\t\tY: 10,\n\t\t\t\t\t\tZ: 0,\n\t\t\t\t\t},\n\t\t\t\t\tRotationF: data.RotationF{\n\t\t\t\t\t\tAxisX: 0,\n\t\t\t\t\t\tAxisY: 0,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tRelative: client.Relativity{},\n\t\t\t})\n\t\t}\n\t}()\n\n\tgo func() {\n\t\tfor conn := range quit {\n\t\t\tapis.MinecraftServer().Watcher().PubAs(impl_event.PlayerConnQuitEvent{Conn: conn})\n\t\t}\n\t}()\n}\n"
  },
  {
    "path": "impl/mask/masking.go",
    "content": "package mask\n\ntype Masking struct{}\n\nfunc (m *Masking) Has(mask, field byte) bool {\n\treturn mask&field != 0\n}\n\nfunc (m *Masking) Set(mask *byte, field byte, when bool) {\n\tif when {\n\t\t*mask |= field\n\t}\n}\n"
  },
  {
    "path": "impl/mask/masking_test.go",
    "content": "package mask\n\nimport (\n\t\"fmt\"\n\t\"testing\"\n)\n\ntype Data struct {\n\tMasking\n\n\tHead bool\n\tBody bool\n}\n\nfunc TestMasking(t *testing.T) {\n\tmask := byte(0)\n\tdata := Data{\n\t\tHead: true,\n\t}\n\n\tdata.Set(&mask, 0x01, data.Head)\n\tdata.Set(&mask, 0x02, data.Body)\n\n\tfmt.Println(data.Has(mask, 0x01))\n\tfmt.Println(data.Has(mask, 0x02))\n}\n"
  },
  {
    "path": "impl/prot/client/to_client_state0.go",
    "content": "package client\n\n// done\n"
  },
  {
    "path": "impl/prot/client/to_client_state1.go",
    "content": "package client\n\nimport (\n\t\"encoding/json\"\n\n\t\"github.com/golangmc/minecraft-server/apis/buff\"\n\t\"github.com/golangmc/minecraft-server/impl/base\"\n\t\"github.com/golangmc/minecraft-server/impl/data/status\"\n)\n\n// done\n\ntype PacketOResponse struct {\n\tStatus status.Response\n}\n\nfunc (p *PacketOResponse) UUID() int32 {\n\treturn 0x00\n}\n\nfunc (p *PacketOResponse) Push(writer buff.Buffer, conn base.Connection) {\n\tif text, err := json.Marshal(p.Status); err != nil {\n\t\tpanic(err)\n\t} else {\n\t\twriter.PushTxt(string(text))\n\t}\n}\n\ntype PacketOPong struct {\n\tPing int64\n}\n\nfunc (p *PacketOPong) UUID() int32 {\n\treturn 0x01\n}\n\nfunc (p *PacketOPong) Push(writer buff.Buffer, conn base.Connection) {\n\twriter.PushI64(p.Ping)\n}\n"
  },
  {
    "path": "impl/prot/client/to_client_state2.go",
    "content": "package client\n\nimport (\n\t\"github.com/golangmc/minecraft-server/apis/buff\"\n\t\"github.com/golangmc/minecraft-server/apis/data/msgs\"\n\t\"github.com/golangmc/minecraft-server/impl/base\"\n)\n\n// done\n\ntype PacketODisconnect struct {\n\tReason msgs.Message\n}\n\nfunc (p *PacketODisconnect) UUID() int32 {\n\treturn 0x00\n}\n\nfunc (p *PacketODisconnect) Push(writer buff.Buffer, conn base.Connection) {\n\tmessage := p.Reason\n\n\twriter.PushTxt(message.AsJson())\n}\n\ntype PacketOEncryptionRequest struct {\n\tServer string // unused?\n\tPublic []byte\n\tVerify []byte\n}\n\nfunc (p *PacketOEncryptionRequest) UUID() int32 {\n\treturn 0x01\n}\n\nfunc (p *PacketOEncryptionRequest) Push(writer buff.Buffer, conn base.Connection) {\n\twriter.PushTxt(p.Server)\n\twriter.PushUAS(p.Public, true)\n\twriter.PushUAS(p.Verify, true)\n}\n\ntype PacketOLoginSuccess struct {\n\tPlayerUUID string\n\tPlayerName string\n}\n\nfunc (p *PacketOLoginSuccess) UUID() int32 {\n\treturn 0x02\n}\n\nfunc (p *PacketOLoginSuccess) Push(writer buff.Buffer, conn base.Connection) {\n\twriter.PushTxt(p.PlayerUUID)\n\twriter.PushTxt(p.PlayerName)\n}\n\ntype PacketOSetCompression struct {\n\tThreshold int32\n}\n\nfunc (p *PacketOSetCompression) UUID() int32 {\n\treturn 0x03\n}\n\nfunc (p *PacketOSetCompression) Push(writer buff.Buffer, conn base.Connection) {\n\twriter.PushVrI(p.Threshold)\n}\n\ntype PacketOLoginPluginRequest struct {\n\tMessageID int32\n\tChannel   string\n\tOptData   []byte\n}\n\nfunc (p *PacketOLoginPluginRequest) UUID() int32 {\n\treturn 0x04\n}\n\nfunc (p *PacketOLoginPluginRequest) Push(writer buff.Buffer, conn base.Connection) {\n\twriter.PushVrI(p.MessageID)\n\twriter.PushTxt(p.Channel)\n\twriter.PushUAS(p.OptData, false)\n}\n"
  },
  {
    "path": "impl/prot/client/to_client_state3.go",
    "content": "package client\n\nimport (\n\t\"github.com/golangmc/minecraft-server/apis/buff\"\n\t\"github.com/golangmc/minecraft-server/apis/data\"\n\t\"github.com/golangmc/minecraft-server/apis/data/msgs\"\n\t\"github.com/golangmc/minecraft-server/apis/ents\"\n\t\"github.com/golangmc/minecraft-server/apis/game\"\n\t\"github.com/golangmc/minecraft-server/apis/game/level\"\n\t\"github.com/golangmc/minecraft-server/impl/base\"\n\t\"github.com/golangmc/minecraft-server/impl/data/client\"\n\t\"github.com/golangmc/minecraft-server/impl/data/plugin\"\n\n\tapis_conn \"github.com/golangmc/minecraft-server/impl/conn\"\n)\n\ntype PacketOChatMessage struct {\n\tMessage         msgs.Message\n\tMessagePosition msgs.MessagePosition\n}\n\nfunc (p *PacketOChatMessage) UUID() int32 {\n\treturn 0x0F\n}\n\nfunc (p *PacketOChatMessage) Push(writer buff.Buffer, conn base.Connection) {\n\tmessage := p.Message\n\n\tif p.MessagePosition == msgs.HotBarText {\n\t\tmessage = *msgs.New(message.AsText())\n\t}\n\n\twriter.PushTxt(message.AsJson())\n\twriter.PushByt(byte(p.MessagePosition))\n}\n\ntype PacketOJoinGame struct {\n\tEntityID      int32\n\tHardcore      bool\n\tGameMode      game.GameMode\n\tDimension     game.Dimension\n\tHashedSeed    int64\n\tMaxPlayers    int\n\tLevelType     game.LevelType\n\tViewDistance  int32\n\tReduceDebug   bool\n\tRespawnScreen bool\n}\n\nfunc (p *PacketOJoinGame) UUID() int32 {\n\treturn 0x26\n}\n\nfunc (p *PacketOJoinGame) Push(writer buff.Buffer, conn base.Connection) {\n\twriter.PushI32(p.EntityID)\n\twriter.PushByt(p.GameMode.Encoded(p.Hardcore /* pull this value from somewhere */))\n\twriter.PushI32(int32(p.Dimension))\n\twriter.PushI64(p.HashedSeed)\n\twriter.PushByt(uint8(p.MaxPlayers))\n\twriter.PushTxt(p.LevelType.String())\n\twriter.PushVrI(p.ViewDistance)\n\twriter.PushBit(p.ReduceDebug)\n\twriter.PushBit(p.RespawnScreen)\n}\n\ntype PacketOPluginMessage struct {\n\tMessage plugin.Message\n}\n\nfunc (p *PacketOPluginMessage) UUID() int32 {\n\treturn 0x19\n}\n\nfunc (p *PacketOPluginMessage) Push(writer buff.Buffer, conn base.Connection) {\n\twriter.PushTxt(p.Message.Chan())\n\tp.Message.Push(writer)\n}\n\ntype PacketOPlayerLocation struct {\n\tLocation data.Location\n\tRelative client.Relativity\n\n\tID int32\n}\n\nfunc (p *PacketOPlayerLocation) UUID() int32 {\n\treturn 0x36\n}\n\nfunc (p *PacketOPlayerLocation) Push(writer buff.Buffer, conn base.Connection) {\n\twriter.PushF64(p.Location.X)\n\twriter.PushF64(p.Location.Y)\n\twriter.PushF64(p.Location.Z)\n\n\twriter.PushF32(p.Location.AxisX)\n\twriter.PushF32(p.Location.AxisY)\n\n\tp.Relative.Push(writer)\n\n\twriter.PushVrI(p.ID)\n}\n\ntype PacketOKeepAlive struct {\n\tKeepAliveID int64\n}\n\nfunc (p *PacketOKeepAlive) UUID() int32 {\n\treturn 0x21\n}\n\nfunc (p *PacketOKeepAlive) Push(writer buff.Buffer, conn base.Connection) {\n\twriter.PushI64(p.KeepAliveID)\n}\n\ntype PacketOServerDifficulty struct {\n\tDifficulty game.Difficulty\n\tLocked     bool // should probably always be true\n}\n\nfunc (p *PacketOServerDifficulty) UUID() int32 {\n\treturn 0x0E\n}\n\nfunc (p *PacketOServerDifficulty) Push(writer buff.Buffer, conn base.Connection) {\n\twriter.PushByt(byte(p.Difficulty))\n\twriter.PushBit(p.Locked)\n}\n\ntype PacketOPlayerAbilities struct {\n\tAbilities   client.PlayerAbilities\n\tFlyingSpeed float32\n\tFieldOfView float32\n}\n\nfunc (p *PacketOPlayerAbilities) UUID() int32 {\n\treturn 0x32\n}\n\nfunc (p *PacketOPlayerAbilities) Push(writer buff.Buffer, conn base.Connection) {\n\tp.Abilities.Push(writer)\n\n\twriter.PushF32(p.FlyingSpeed)\n\twriter.PushF32(p.FieldOfView)\n}\n\ntype PacketOHeldItemChange struct {\n\tSlot client.HotBarSlot\n}\n\nfunc (p *PacketOHeldItemChange) UUID() int32 {\n\treturn 0x40\n}\n\nfunc (p *PacketOHeldItemChange) Push(writer buff.Buffer, conn base.Connection) {\n\twriter.PushByt(byte(p.Slot))\n}\n\ntype PacketODeclareRecipes struct {\n\t// Recipes []*Recipe // this doesn't exist yet ;(\n\tRecipeCount int32\n}\n\nfunc (p *PacketODeclareRecipes) UUID() int32 {\n\treturn 0x5B\n}\n\nfunc (p *PacketODeclareRecipes) Push(writer buff.Buffer, conn base.Connection) {\n\twriter.PushVrI(p.RecipeCount)\n\t// when recipes are implemented, instead of holding a recipe count, simply write the size of the slice, Recipe will implement BufferPush\n}\n\ntype PacketOChunkData struct {\n\tChunk level.Chunk\n}\n\nfunc (p *PacketOChunkData) UUID() int32 {\n\treturn 0x22\n}\n\nfunc (p *PacketOChunkData) Push(writer buff.Buffer, conn base.Connection) {\n\twriter.PushI32(int32(p.Chunk.ChunkX()))\n\twriter.PushI32(int32(p.Chunk.ChunkZ()))\n\n\t// full chunk (for now >:D)\n\twriter.PushBit(true)\n\n\tchunkData := apis_conn.NewBuffer()\n\tp.Chunk.Push(chunkData) // write chunk data and primary bit mask\n\n\t// pull primary bit mask and push to writer\n\twriter.PushVrI(chunkData.PullVrI())\n\n\t// write height-maps\n\twriter.PushNbt(p.Chunk.HeightMapNbtCompound())\n\n\tbiomes := make([]int32, 1024, 1024)\n\tfor i := range biomes {\n\t\tbiomes[i] = 0 // void biome\n\t}\n\n\tfor _, biome := range biomes {\n\t\twriter.PushI32(biome)\n\t}\n\n\t// data, prefixed with len\n\twriter.PushUAS(chunkData.UAS(), true)\n\n\t// write block entities\n\twriter.PushVrI(0)\n}\n\ntype PacketOPlayerInfo struct {\n\tAction client.PlayerInfoAction\n\tValues []client.PlayerInfo\n}\n\nfunc (p *PacketOPlayerInfo) UUID() int32 {\n\treturn 0x34\n}\n\nfunc (p *PacketOPlayerInfo) Push(writer buff.Buffer, conn base.Connection) {\n\twriter.PushVrI(int32(p.Action))\n\twriter.PushVrI(int32(len(p.Values)))\n\n\tfor _, value := range p.Values {\n\t\tvalue.Push(writer)\n\t}\n}\n\ntype PacketOEntityMetadata struct {\n\tEntity ents.Entity\n}\n\nfunc (p *PacketOEntityMetadata) UUID() int32 {\n\treturn 0x44\n}\n\nfunc (p *PacketOEntityMetadata) Push(writer buff.Buffer, conn base.Connection) {\n\twriter.PushVrI(int32(p.Entity.EntityUUID())) // questionable...\n\n\t// only supporting player metadata for now\n\t_, ok := p.Entity.(ents.Player)\n\tif ok {\n\n\t\twriter.PushByt(16) // index | displayed skin parts\n\t\twriter.PushVrI(0)  // type | byte\n\n\t\tskin := client.SkinParts{\n\t\t\tCape: true,\n\t\t\tHead: true,\n\t\t\tBody: true,\n\t\t\tArmL: true,\n\t\t\tArmR: true,\n\t\t\tLegL: true,\n\t\t\tLegR: true,\n\t\t}\n\n\t\tskin.Push(writer)\n\t}\n\n\twriter.PushByt(0xFF)\n}\n"
  },
  {
    "path": "impl/prot/packets.go",
    "content": "package prot\n\nimport (\n\t\"github.com/golangmc/minecraft-server/apis/logs\"\n\t\"github.com/golangmc/minecraft-server/apis/task\"\n\t\"github.com/golangmc/minecraft-server/apis/util\"\n\t\"github.com/golangmc/minecraft-server/impl/base\"\n\t\"github.com/golangmc/minecraft-server/impl/game/mode\"\n\t\"github.com/golangmc/minecraft-server/impl/prot/server\"\n)\n\ntype packets struct {\n\tutil.Watcher\n\n\tlogger  *logs.Logging\n\tpacketI map[base.PacketState]map[int32]func() base.PacketI // UUID to I server_data\n\n\tjoin chan base.PlayerAndConnection\n\tquit chan base.PlayerAndConnection\n}\n\nfunc NewPackets(tasking *task.Tasking, join chan base.PlayerAndConnection, quit chan base.PlayerAndConnection) base.Packets {\n\tpackets := &packets{\n\t\tWatcher: util.NewWatcher(),\n\n\t\tlogger:  logs.NewLogging(\"protocol\", logs.EveryLevel...),\n\t\tpacketI: createPacketI(),\n\t}\n\n\tmode.HandleState0(packets)\n\tmode.HandleState1(packets)\n\tmode.HandleState2(packets, join)\n\tmode.HandleState3(packets, packets.logger, tasking, join, quit)\n\n\treturn packets\n}\n\nfunc (p *packets) GetPacketI(uuid int32, state base.PacketState) base.PacketI {\n\tcreator := p.packetI[state][uuid]\n\tif creator == nil {\n\t\treturn nil\n\t}\n\n\treturn creator()\n}\n\nfunc createPacketI() map[base.PacketState]map[int32]func() base.PacketI {\n\treturn map[base.PacketState]map[int32]func() base.PacketI{\n\t\tbase.SHAKE: {\n\t\t\t0x00: func() base.PacketI {\n\t\t\t\treturn &server.PacketIHandshake{}\n\t\t\t},\n\t\t},\n\t\tbase.STATUS: {\n\t\t\t0x00: func() base.PacketI {\n\t\t\t\treturn &server.PacketIRequest{}\n\t\t\t},\n\t\t\t0x01: func() base.PacketI {\n\t\t\t\treturn &server.PacketIPing{}\n\t\t\t},\n\t\t},\n\t\tbase.LOGIN: {\n\t\t\t0x00: func() base.PacketI {\n\t\t\t\treturn &server.PacketILoginStart{}\n\t\t\t},\n\t\t\t0x01: func() base.PacketI {\n\t\t\t\treturn &server.PacketIEncryptionResponse{}\n\t\t\t},\n\t\t\t0x02: func() base.PacketI {\n\t\t\t\treturn &server.PacketILoginPluginResponse{}\n\t\t\t},\n\t\t},\n\t\tbase.PLAY: {\n\t\t\t0x00: func() base.PacketI {\n\t\t\t\treturn &server.PacketITeleportConfirm{}\n\t\t\t},\n\t\t\t0x01: func() base.PacketI {\n\t\t\t\treturn &server.PacketIQueryBlockNBT{}\n\t\t\t},\n\t\t\t0x02: func() base.PacketI {\n\t\t\t\treturn &server.PacketISetDifficulty{}\n\t\t\t},\n\t\t\t0x03: func() base.PacketI {\n\t\t\t\treturn &server.PacketIChatMessage{}\n\t\t\t},\n\t\t\t0x04: func() base.PacketI {\n\t\t\t\treturn &server.PacketIClientStatus{}\n\t\t\t},\n\t\t\t0x05: func() base.PacketI {\n\t\t\t\treturn &server.PacketIClientSettings{}\n\t\t\t},\n\t\t\t0x0B: func() base.PacketI {\n\t\t\t\treturn &server.PacketIPluginMessage{}\n\t\t\t},\n\t\t\t0x0F: func() base.PacketI {\n\t\t\t\treturn &server.PacketIKeepAlive{}\n\t\t\t},\n\t\t\t0x11: func() base.PacketI {\n\t\t\t\treturn &server.PacketIPlayerPosition{}\n\t\t\t},\n\t\t\t0x12: func() base.PacketI {\n\t\t\t\treturn &server.PacketIPlayerLocation{}\n\t\t\t},\n\t\t\t0x13: func() base.PacketI {\n\t\t\t\treturn &server.PacketIPlayerRotation{}\n\t\t\t},\n\t\t\t0x19: func() base.PacketI {\n\t\t\t\treturn &server.PacketIPlayerAbilities{}\n\t\t\t},\n\t\t},\n\t}\n}\n"
  },
  {
    "path": "impl/prot/server/to_server_state0.go",
    "content": "package server\n\nimport (\n\t\"github.com/golangmc/minecraft-server/apis/buff\"\n\t\"github.com/golangmc/minecraft-server/impl/base\"\n)\n\n// done\n\ntype PacketIHandshake struct {\n\tversion int32\n\n\thost string\n\tport uint16\n\n\tState base.PacketState\n}\n\nfunc (p *PacketIHandshake) UUID() int32 {\n\treturn 0x00\n}\n\nfunc (p *PacketIHandshake) Pull(reader buff.Buffer, conn base.Connection) {\n\tp.version = reader.PullVrI()\n\n\tp.host = reader.PullTxt()\n\tp.port = reader.PullU16()\n\n\tstate := reader.PullVrI()\n\n\tp.State = base.PacketStateValueOf(int(state))\n}\n"
  },
  {
    "path": "impl/prot/server/to_server_state1.go",
    "content": "package server\n\nimport (\n\t\"github.com/golangmc/minecraft-server/apis/buff\"\n\t\"github.com/golangmc/minecraft-server/impl/base\"\n)\n\n// done\n\ntype PacketIRequest struct {\n}\n\nfunc (p *PacketIRequest) UUID() int32 {\n\treturn 0x00\n}\n\nfunc (p *PacketIRequest) Pull(reader buff.Buffer, conn base.Connection) {\n\t// no fields\n}\n\ntype PacketIPing struct {\n\tPing int64\n}\n\nfunc (p *PacketIPing) UUID() int32 {\n\treturn 0x01\n}\n\nfunc (p *PacketIPing) Pull(reader buff.Buffer, conn base.Connection) {\n\tp.Ping = reader.PullI64()\n}\n"
  },
  {
    "path": "impl/prot/server/to_server_state2.go",
    "content": "package server\n\nimport (\n\t\"github.com/golangmc/minecraft-server/apis/buff\"\n\t\"github.com/golangmc/minecraft-server/impl/base\"\n)\n\n// done\n\ntype PacketILoginStart struct {\n\tPlayerName string\n}\n\nfunc (p *PacketILoginStart) UUID() int32 {\n\treturn 0x00\n}\n\nfunc (p *PacketILoginStart) Pull(reader buff.Buffer, conn base.Connection) {\n\tp.PlayerName = reader.PullTxt()\n}\n\ntype PacketIEncryptionResponse struct {\n\tSecret []byte\n\tVerify []byte\n}\n\nfunc (p *PacketIEncryptionResponse) UUID() int32 {\n\treturn 0x01\n}\n\nfunc (p *PacketIEncryptionResponse) Pull(reader buff.Buffer, conn base.Connection) {\n\tp.Secret = reader.PullUAS()\n\tp.Verify = reader.PullUAS()\n}\n\ntype PacketILoginPluginResponse struct {\n\tMessage int32\n\tSuccess bool\n\tOptData []byte\n}\n\nfunc (p *PacketILoginPluginResponse) UUID() int32 {\n\treturn 0x02\n}\n\nfunc (p *PacketILoginPluginResponse) Pull(reader buff.Buffer, conn base.Connection) {\n\tp.Message = reader.PullVrI()\n\tp.Success = reader.PullBit()\n\tp.OptData = reader.UAS()[reader.InI():reader.Len()]\n}\n"
  },
  {
    "path": "impl/prot/server/to_server_state3.go",
    "content": "package server\n\nimport (\n\t\"github.com/golangmc/minecraft-server/apis/buff\"\n\t\"github.com/golangmc/minecraft-server/apis/data\"\n\t\"github.com/golangmc/minecraft-server/apis/game\"\n\t\"github.com/golangmc/minecraft-server/impl/base\"\n\t\"github.com/golangmc/minecraft-server/impl/data/client\"\n\t\"github.com/golangmc/minecraft-server/impl/data/plugin\"\n)\n\ntype PacketIKeepAlive struct {\n\tKeepAliveID int64\n}\n\nfunc (p *PacketIKeepAlive) UUID() int32 {\n\treturn 0x0F\n}\n\nfunc (p *PacketIKeepAlive) Pull(reader buff.Buffer, conn base.Connection) {\n\tp.KeepAliveID = reader.PullI64()\n}\n\ntype PacketIChatMessage struct {\n\tMessage string\n}\n\nfunc (p *PacketIChatMessage) UUID() int32 {\n\treturn 0x03\n}\n\nfunc (p *PacketIChatMessage) Pull(reader buff.Buffer, conn base.Connection) {\n\tp.Message = reader.PullTxt()\n}\n\ntype PacketITeleportConfirm struct {\n\tTeleportID int32\n}\n\nfunc (p *PacketITeleportConfirm) UUID() int32 {\n\treturn 0x00\n}\n\nfunc (p *PacketITeleportConfirm) Pull(reader buff.Buffer, conn base.Connection) {\n\tp.TeleportID = reader.PullVrI()\n}\n\ntype PacketIQueryBlockNBT struct {\n\tTransactionID int32\n\tPosition      data.PositionI\n}\n\nfunc (p *PacketIQueryBlockNBT) UUID() int32 {\n\treturn 0x01\n}\n\nfunc (p *PacketIQueryBlockNBT) Pull(reader buff.Buffer, conn base.Connection) {\n\tp.TransactionID = reader.PullVrI()\n\tp.Position = reader.PullPos()\n}\n\ntype PacketISetDifficulty struct {\n\tDifficult game.Difficulty\n}\n\nfunc (p *PacketISetDifficulty) UUID() int32 {\n\treturn 0x02\n}\n\nfunc (p *PacketISetDifficulty) Pull(reader buff.Buffer, conn base.Connection) {\n\tp.Difficult = game.DifficultyValueOf(reader.PullByt())\n}\n\ntype PacketIPluginMessage struct {\n\tMessage plugin.Message\n}\n\nfunc (p *PacketIPluginMessage) UUID() int32 {\n\treturn 0x0B\n}\n\nfunc (p *PacketIPluginMessage) Pull(reader buff.Buffer, conn base.Connection) {\n\tchannel := reader.PullTxt()\n\tmessage := plugin.GetMessageForChannel(channel)\n\n\tif message == nil {\n\t\treturn // log unregistered channel?\n\t}\n\n\tmessage.Pull(reader)\n\n\tp.Message = message\n}\n\ntype PacketIClientStatus struct {\n\tAction client.StatusAction\n}\n\nfunc (p *PacketIClientStatus) UUID() int32 {\n\treturn 0x04\n}\n\nfunc (p *PacketIClientStatus) Pull(reader buff.Buffer, conn base.Connection) {\n\tp.Action = client.StatusAction(reader.PullVrI())\n}\n\ntype PacketIClientSettings struct {\n\tLocale       string\n\tViewDistance byte\n\tChatMode     client.ChatMode\n\tChatColors   bool // if false, strip messages of colors before sending\n\tSkinParts    client.SkinParts\n\tMainHand     client.MainHand\n}\n\nfunc (p *PacketIClientSettings) UUID() int32 {\n\treturn 0x05\n}\n\nfunc (p *PacketIClientSettings) Pull(reader buff.Buffer, conn base.Connection) {\n\tp.Locale = reader.PullTxt()\n\tp.ViewDistance = reader.PullByt()\n\tp.ChatMode = client.ChatMode(reader.PullVrI())\n\tp.ChatColors = reader.PullBit()\n\n\tparts := client.SkinParts{}\n\tparts.Pull(reader)\n\n\tp.SkinParts = parts\n\tp.MainHand = client.MainHand(reader.PullVrI())\n}\n\ntype PacketIPlayerAbilities struct {\n\tAbilities   client.PlayerAbilities\n\tFlightSpeed float32\n\tGroundSpeed float32\n}\n\nfunc (p *PacketIPlayerAbilities) UUID() int32 {\n\treturn 0x19\n}\n\nfunc (p *PacketIPlayerAbilities) Pull(reader buff.Buffer, conn base.Connection) {\n\tabilities := client.PlayerAbilities{}\n\tabilities.Pull(reader)\n\n\tp.Abilities = abilities\n\n\tp.FlightSpeed = reader.PullF32()\n\tp.GroundSpeed = reader.PullF32()\n}\n\ntype PacketIPlayerPosition struct {\n\tPosition data.PositionF\n\tOnGround bool\n}\n\nfunc (p *PacketIPlayerPosition) UUID() int32 {\n\treturn 0x11\n}\n\nfunc (p *PacketIPlayerPosition) Pull(reader buff.Buffer, conn base.Connection) {\n\tp.Position = data.PositionF{\n\t\tX: reader.PullF64(),\n\t\tY: reader.PullF64(),\n\t\tZ: reader.PullF64(),\n\t}\n\n\tp.OnGround = reader.PullBit()\n}\n\ntype PacketIPlayerLocation struct {\n\tLocation data.Location\n\tOnGround bool\n}\n\nfunc (p *PacketIPlayerLocation) UUID() int32 {\n\treturn 0x12\n}\n\nfunc (p *PacketIPlayerLocation) Pull(reader buff.Buffer, conn base.Connection) {\n\tp.Location = data.Location{\n\t\tPositionF: data.PositionF{\n\t\t\tX: reader.PullF64(),\n\t\t\tY: reader.PullF64(),\n\t\t\tZ: reader.PullF64(),\n\t\t},\n\t\tRotationF: data.RotationF{\n\t\t\tAxisX: reader.PullF32(),\n\t\t\tAxisY: reader.PullF32(),\n\t\t},\n\t}\n\n\tp.OnGround = reader.PullBit()\n}\n\ntype PacketIPlayerRotation struct {\n\tRotation data.RotationF\n\tOnGround bool\n}\n\nfunc (p *PacketIPlayerRotation) UUID() int32 {\n\treturn 0x13\n}\n\nfunc (p *PacketIPlayerRotation) Pull(reader buff.Buffer, conn base.Connection) {\n\tp.Rotation = data.RotationF{\n\t\tAxisX: reader.PullF32(),\n\t\tAxisY: reader.PullF32(),\n\t}\n\n\tp.OnGround = reader.PullBit()\n}\n"
  },
  {
    "path": "impl/server.go",
    "content": "package impl\n\nimport (\n\t\"fmt\"\n\t\"strconv\"\n\t\"strings\"\n\t\"time\"\n\n\t\"github.com/golangmc/minecraft-server/apis\"\n\t\"github.com/golangmc/minecraft-server/apis/cmds\"\n\t\"github.com/golangmc/minecraft-server/apis/data/chat\"\n\t\"github.com/golangmc/minecraft-server/apis/ents\"\n\t\"github.com/golangmc/minecraft-server/apis/logs\"\n\t\"github.com/golangmc/minecraft-server/apis/task\"\n\t\"github.com/golangmc/minecraft-server/apis/util\"\n\t\"github.com/golangmc/minecraft-server/apis/uuid\"\n\t\"github.com/golangmc/minecraft-server/impl/conf\"\n\t\"github.com/golangmc/minecraft-server/impl/data/plugin\"\n\n\t\"github.com/golangmc/minecraft-server/impl/conn\"\n\t\"github.com/golangmc/minecraft-server/impl/cons\"\n\t\"github.com/golangmc/minecraft-server/impl/data/system\"\n\t\"github.com/golangmc/minecraft-server/impl/data/values\"\n\t\"github.com/golangmc/minecraft-server/impl/prot\"\n\n\tapis_base \"github.com/golangmc/minecraft-server/apis/base\"\n\timpl_base \"github.com/golangmc/minecraft-server/impl/base\"\n\n\tapis_event \"github.com/golangmc/minecraft-server/apis/game/event\"\n\timpl_event \"github.com/golangmc/minecraft-server/impl/game/event\"\n)\n\ntype server struct {\n\tmessage chan system.Message\n\n\tconsole *cons.Console\n\n\tlogging *logs.Logging\n\ttasking *task.Tasking\n\twatcher util.Watcher\n\n\tcommand *cmds.CommandManager\n\n\tnetwork impl_base.Network\n\tpackets impl_base.Packets\n\n\tplayers *playerAssociation\n}\n\n// ==== new ====\nfunc NewServer(conf conf.ServerConfig) apis.Server {\n\tmessage := make(chan system.Message)\n\n\tconsole := cons.NewConsole(message)\n\n\tlogging := logs.NewLogging(\"server\", logs.EveryLevel...)\n\ttasking := task.NewTasking(values.MPT)\n\twatcher := util.NewWatcher()\n\n\tjoin := make(chan impl_base.PlayerAndConnection)\n\tquit := make(chan impl_base.PlayerAndConnection)\n\n\tpackets := prot.NewPackets(tasking, join, quit)\n\tnetwork := conn.NewNetwork(conf.Network.Host, conf.Network.Port, packets, message, join, quit)\n\n\tcommand := cmds.NewCommandManager()\n\n\treturn &server{\n\t\tmessage: message,\n\n\t\tconsole: console,\n\n\t\tlogging: logging,\n\t\ttasking: tasking,\n\t\twatcher: watcher,\n\n\t\tcommand: command,\n\n\t\tpackets: packets,\n\t\tnetwork: network,\n\n\t\tplayers: &playerAssociation{\n\t\t\tuuidToData: make(map[uuid.UUID]ents.Player),\n\n\t\t\tconnToUUID: make(map[impl_base.Connection]uuid.UUID),\n\t\t\tuuidToConn: make(map[uuid.UUID]impl_base.Connection),\n\t\t},\n\t}\n}\n\n// ==== State ====\nfunc (s *server) Load() {\n\tapis.SetMinecraftServer(s)\n\n\tgo s.loadServer()\n\tgo s.readInputs()\n\n\ts.wait()\n}\n\nfunc (s *server) Kill() {\n\n\ts.console.Kill()\n\ts.command.Kill()\n\ts.tasking.Kill()\n\ts.network.Kill()\n\n\t// push the stop message to the server exit channel\n\ts.message <- system.Make(system.STOP, \"normal stop\")\n\tclose(s.message)\n\n\ts.logging.Info(chat.DarkRed, \"server stopped\")\n}\n\n// ==== Server ====\nfunc (s *server) Logging() *logs.Logging {\n\treturn s.logging\n}\n\nfunc (s *server) Command() *cmds.CommandManager {\n\treturn s.command\n}\n\nfunc (s *server) Tasking() *task.Tasking {\n\treturn s.tasking\n}\n\nfunc (s *server) Watcher() util.Watcher {\n\treturn s.watcher\n}\n\nfunc (s *server) Players() []ents.Player {\n\tplayers := make([]ents.Player, 0)\n\n\tfor _, player := range s.players.uuidToData {\n\t\tplayers = append(players, player)\n\t}\n\n\treturn players\n}\n\nfunc (s *server) ConnByUUID(uuid uuid.UUID) impl_base.Connection {\n\treturn s.players.uuidToConn[uuid]\n}\n\nfunc (s *server) PlayerByUUID(uuid uuid.UUID) ents.Player {\n\treturn s.players.uuidToData[uuid]\n}\n\nfunc (s *server) PlayerByConn(conn impl_base.Connection) ents.Player {\n\tuuid, con := s.players.connToUUID[conn]\n\tif !con {\n\t\treturn nil\n\t}\n\n\treturn s.PlayerByUUID(uuid)\n}\n\nfunc (s *server) ServerVersion() string {\n\treturn \"0.0.1-SNAPSHOT\"\n}\n\nfunc (s *server) Broadcast(message string) {\n\ts.console.SendMessage(message)\n\n\tfor _, player := range s.Players() {\n\t\tplayer.SendMessage(message)\n\t}\n}\n\n// ==== server commands ====\nfunc (s *server) broadcastCommand(sender ents.Sender, params []string) {\n\tmessage := strings.Join(params, \" \")\n\n\tfor _, player := range s.Players() {\n\t\tplayer.SendMessage(message)\n\t}\n}\n\nfunc (s *server) stopServerCommand(sender ents.Sender, params []string) {\n\tif _, ok := sender.(*cons.Console); !ok {\n\t\ts.logging.FailF(\"non console sender %s tried to stop the server\", sender.Name())\n\t\treturn\n\t}\n\n\tvar after int64 = 0\n\n\tif len(params) > 0 {\n\t\tparam, err := strconv.Atoi(params[0])\n\n\t\tif err != nil {\n\t\t\tpanic(err)\n\t\t}\n\n\t\tif param <= 0 {\n\t\t\tpanic(fmt.Errorf(\"value must be a positive whole number. [1..]\"))\n\t\t}\n\n\t\tafter = int64(param)\n\t}\n\n\tif after == 0 {\n\n\t\ts.Kill()\n\n\t} else {\n\n\t\t// inform future shutdown\n\t\ts.logging.Warn(chat.Gold, \"stopping server in \", chat.Green, util.FormatTime(after))\n\n\t\t// schedule shutdown {after} seconds later\n\t\ts.tasking.AfterTime(after, time.Second, func(task *task.Task) {\n\t\t\ts.Kill()\n\t\t})\n\n\t}\n}\n\nfunc (s *server) versionCommand(sender ents.Sender, params []string) {\n\tsender.SendMessage(s.ServerVersion())\n}\n\n// ==== internal ====\nfunc (s *server) loadServer() {\n\ts.console.Load()\n\ts.command.Load()\n\ts.tasking.Load()\n\ts.network.Load()\n\n\ts.command.Register(\"vers\", s.versionCommand)\n\ts.command.Register(\"send\", s.broadcastCommand)\n\ts.command.Register(\"stop\", s.stopServerCommand)\n\n\ts.watcher.SubAs(func(event apis_event.PlayerJoinEvent) {\n\t\ts.logging.InfoF(\"player %s logged in with uuid:%v\", event.Player.Name(), event.Player.UUID())\n\n\t\ts.Broadcast(chat.Translate(fmt.Sprintf(\"%s%s has joined!\", chat.Yellow, event.Player.Name())))\n\t})\n\ts.watcher.SubAs(func(event apis_event.PlayerQuitEvent) {\n\t\ts.logging.InfoF(\"%s disconnected!\", event.Player.Name())\n\n\t\ts.Broadcast(chat.Translate(fmt.Sprintf(\"%s%s has left!\", chat.Yellow, event.Player.Name())))\n\t})\n\n\ts.watcher.SubAs(func(event impl_event.PlayerConnJoinEvent) {\n\t\ts.players.addData(event.Conn)\n\n\t\ts.watcher.PubAs(apis_event.PlayerJoinEvent{PlayerEvent: apis_event.PlayerEvent{Player: event.Conn.Player}})\n\t})\n\ts.watcher.SubAs(func(event impl_event.PlayerConnQuitEvent) {\n\t\tplayer := s.players.playerByConn(event.Conn.Connection)\n\n\t\tif player != nil {\n\t\t\ts.watcher.PubAs(apis_event.PlayerQuitEvent{PlayerEvent: apis_event.PlayerEvent{Player: player}})\n\t\t}\n\n\t\ts.players.delData(event.Conn)\n\t})\n\n\ts.watcher.SubAs(func(event impl_event.PlayerPluginMessagePullEvent) {\n\t\ts.logging.DataF(\"received message on channel '%s' from player %s:%s\", event.Channel, event.Conn.Name(), event.Conn.UUID())\n\n\t\tswitch event.Channel {\n\t\tcase plugin.CHANNEL_BRAND:\n\t\t\ts.logging.DataF(\"their client's brand is '%s'\", event.Message.(*plugin.Brand).Name)\n\t\t}\n\t})\n}\n\nfunc (s *server) readInputs() {\n\tfor {\n\t\t// read input from console\n\t\ttext := strings.Trim(<-s.console.IChannel, \" \")\n\t\tif len(text) == 0 {\n\t\t\tcontinue\n\t\t}\n\n\t\targs := strings.Split(text, \" \")\n\t\tif len(args) == 0 {\n\t\t\tcontinue\n\t\t}\n\n\t\tif command := s.command.Search(args[0]); command != nil {\n\n\t\t\terr := apis_base.Attempt(func() {\n\t\t\t\t(*command).Evaluate(s.console, args[1:])\n\t\t\t})\n\n\t\t\tif err != nil {\n\t\t\t\ts.logging.Fail(\n\t\t\t\t\tchat.Red, \"failed to evaluate \",\n\t\t\t\t\tchat.DarkGray, \"`\",\n\t\t\t\t\tchat.White, (*command).Name(),\n\t\t\t\t\tchat.DarkGray, \"`\",\n\t\t\t\t\tchat.Red, \": \", err.Error()[8:])\n\t\t\t}\n\n\t\t\tcontinue\n\t\t}\n\n\t\ts.console.SendMessage(text)\n\t}\n}\n\nfunc (s *server) wait() {\n\t// select over server commands channel\n\tselect {\n\tcase command := <-s.message:\n\t\tswitch command.Command {\n\t\t// stop selecting when stop is received\n\t\tcase system.STOP:\n\t\t\treturn\n\t\tcase system.FAIL:\n\t\t\ts.logging.Fail(\"internal server error: \", command.Message)\n\t\t\ts.logging.Fail(\"stopping server\")\n\t\t\treturn\n\t\t}\n\t}\n\n\ts.wait()\n}\n\n// ==== players ====\ntype playerAssociation struct {\n\tuuidToData map[uuid.UUID]ents.Player\n\n\tconnToUUID map[impl_base.Connection]uuid.UUID\n\tuuidToConn map[uuid.UUID]impl_base.Connection\n}\n\nfunc (p *playerAssociation) addData(data impl_base.PlayerAndConnection) {\n\tp.uuidToData[data.Player.UUID()] = data.Player\n\n\tp.connToUUID[data.Connection] = data.Player.UUID()\n\tp.uuidToConn[data.Player.UUID()] = data.Connection\n}\n\nfunc (p *playerAssociation) delData(data impl_base.PlayerAndConnection) {\n\tplayer := p.playerByConn(data.Connection)\n\n\tuuid := p.connToUUID[data.Connection]\n\n\tdelete(p.connToUUID, data.Connection)\n\tdelete(p.uuidToConn, uuid)\n\n\tif player != nil {\n\t\tdelete(p.uuidToData, player.UUID())\n\t}\n}\n\nfunc (p *playerAssociation) playerByUUID(uuid uuid.UUID) ents.Player {\n\treturn p.uuidToData[uuid]\n}\n\nfunc (p *playerAssociation) playerByConn(conn impl_base.Connection) ents.Player {\n\tuuid, con := p.connToUUID[conn]\n\n\tif !con {\n\t\treturn nil\n\t}\n\n\tdata, con := p.uuidToData[uuid]\n\n\tif !con {\n\t\treturn nil\n\t}\n\n\treturn data\n}\n"
  },
  {
    "path": "main.go",
    "content": "package main\n\nimport (\n\t\"flag\"\n\n\t\"github.com/fatih/color\"\n\n\t\"github.com/golangmc/minecraft-server/impl\"\n\t\"github.com/golangmc/minecraft-server/impl/conf\"\n)\n\nfunc main() {\n\tcolor.NoColor = false\n\n\tserver := impl.NewServer(mergeWithFlags(conf.DefaultServerConfig))\n\tserver.Load()\n}\n\nfunc mergeWithFlags(c conf.ServerConfig) conf.ServerConfig {\n\thost := flag.String(\"host\",\n\t\tconf.DefaultServerConfig.Network.Host,\n\t\t\"the address this server will bind to\")\n\n\tport := flag.Int(\"port\",\n\t\tconf.DefaultServerConfig.Network.Port,\n\t\t\"the port this server will bind to\")\n\n\tflag.Parse()\n\n\tif *host != conf.DefaultServerConfig.Network.Host {\n\t\tc.Network.Host = *host\n\t}\n\n\tif *port != conf.DefaultServerConfig.Network.Port {\n\t\tc.Network.Port = *port\n\t}\n\n\treturn c\n}\n"
  }
]