format repo with "gofumpt" tool
This commit is contained in:
@ -1,9 +1,10 @@
|
|||||||
package basic
|
package basic
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/Tnze/go-mc/chat"
|
|
||||||
"unsafe"
|
"unsafe"
|
||||||
|
|
||||||
|
"github.com/Tnze/go-mc/chat"
|
||||||
|
|
||||||
"github.com/Tnze/go-mc/data/packetid"
|
"github.com/Tnze/go-mc/data/packetid"
|
||||||
"github.com/Tnze/go-mc/nbt"
|
"github.com/Tnze/go-mc/nbt"
|
||||||
pk "github.com/Tnze/go-mc/net/packet"
|
pk "github.com/Tnze/go-mc/net/packet"
|
||||||
@ -123,7 +124,7 @@ func (p *Player) handleLoginPacket(packet pk.Packet) error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return Error{err}
|
return Error{err}
|
||||||
}
|
}
|
||||||
err = p.c.Conn.WritePacket(pk.Marshal( //PluginMessage packet
|
err = p.c.Conn.WritePacket(pk.Marshal( // PluginMessage packet
|
||||||
int32(packetid.ServerboundCustomPayload),
|
int32(packetid.ServerboundCustomPayload),
|
||||||
pk.Identifier("minecraft:brand"),
|
pk.Identifier("minecraft:brand"),
|
||||||
pk.String(p.Settings.Brand),
|
pk.String(p.Settings.Brand),
|
||||||
@ -148,6 +149,7 @@ func (p *Player) handleLoginPacket(packet pk.Packet) error {
|
|||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *Player) handleRespawnPacket(packet pk.Packet) error {
|
func (p *Player) handleRespawnPacket(packet pk.Packet) error {
|
||||||
var copyMeta bool
|
var copyMeta bool
|
||||||
err := packet.Scan(
|
err := packet.Scan(
|
||||||
|
@ -2,12 +2,12 @@ package basic
|
|||||||
|
|
||||||
// Settings of client
|
// Settings of client
|
||||||
type Settings struct {
|
type Settings struct {
|
||||||
Locale string //地区
|
Locale string // 地区
|
||||||
ViewDistance int //视距
|
ViewDistance int // 视距
|
||||||
ChatMode int //聊天模式
|
ChatMode int // 聊天模式
|
||||||
ChatColors bool //聊天颜色
|
ChatColors bool // 聊天颜色
|
||||||
DisplayedSkinParts uint8 //皮肤显示
|
DisplayedSkinParts uint8 // 皮肤显示
|
||||||
MainHand int //主手
|
MainHand int // 主手
|
||||||
|
|
||||||
// Enables filtering of text on signs and written book titles.
|
// Enables filtering of text on signs and written book titles.
|
||||||
// Currently, always false (i.e. the filtering is disabled)
|
// Currently, always false (i.e. the filtering is disabled)
|
||||||
|
@ -79,7 +79,9 @@ func (p *PlayerMessage) ReadFrom(r io.Reader) (n int64, err error) {
|
|||||||
var timestamp pk.Long
|
var timestamp pk.Long
|
||||||
var unsignedContent chat.Message
|
var unsignedContent chat.Message
|
||||||
n, err = pk.Tuple{
|
n, err = pk.Tuple{
|
||||||
&hasMsgSign, pk.Opt{Has: &hasMsgSign,
|
&hasMsgSign,
|
||||||
|
pk.Opt{
|
||||||
|
Has: &hasMsgSign,
|
||||||
Field: (*pk.ByteArray)(&p.signature),
|
Field: (*pk.ByteArray)(&p.signature),
|
||||||
},
|
},
|
||||||
(*pk.UUID)(&p.sender),
|
(*pk.UUID)(&p.sender),
|
||||||
@ -88,7 +90,9 @@ func (p *PlayerMessage) ReadFrom(r io.Reader) (n int64, err error) {
|
|||||||
×tamp,
|
×tamp,
|
||||||
(*pk.Long)(&p.salt),
|
(*pk.Long)(&p.salt),
|
||||||
pk.Array(&p.prevMessages),
|
pk.Array(&p.prevMessages),
|
||||||
&hasUnsignedContent, pk.Opt{Has: &hasUnsignedContent,
|
&hasUnsignedContent,
|
||||||
|
pk.Opt{
|
||||||
|
Has: &hasUnsignedContent,
|
||||||
Field: &unsignedContent,
|
Field: &unsignedContent,
|
||||||
},
|
},
|
||||||
(*pk.VarInt)(&p.filterType),
|
(*pk.VarInt)(&p.filterType),
|
||||||
|
14
bot/event.go
14
bot/event.go
@ -35,12 +35,14 @@ func (e *Events) AddGeneric(listeners ...PacketHandler) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
type PacketHandlerFunc func(p pk.Packet) error
|
type (
|
||||||
type PacketHandler struct {
|
PacketHandlerFunc func(p pk.Packet) error
|
||||||
ID packetid.ClientboundPacketID
|
PacketHandler struct {
|
||||||
Priority int
|
ID packetid.ClientboundPacketID
|
||||||
F func(p pk.Packet) error
|
Priority int
|
||||||
}
|
F func(p pk.Packet) error
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
// handlerHeap is PriorityQueue<PacketHandlerFunc>
|
// handlerHeap is PriorityQueue<PacketHandlerFunc>
|
||||||
type handlerHeap []PacketHandler
|
type handlerHeap []PacketHandler
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
package bot
|
package bot
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"encoding/hex"
|
||||||
"log"
|
"log"
|
||||||
|
|
||||||
"encoding/hex"
|
|
||||||
"github.com/Tnze/go-mc/offline"
|
"github.com/Tnze/go-mc/offline"
|
||||||
"github.com/Tnze/go-mc/yggdrasil"
|
"github.com/Tnze/go-mc/yggdrasil"
|
||||||
)
|
)
|
||||||
@ -25,7 +25,7 @@ func ExampleClient_JoinServer_offline() {
|
|||||||
id := offline.NameToUUID(c.Auth.Name) // optional, get uuid of offline mode game
|
id := offline.NameToUUID(c.Auth.Name) // optional, get uuid of offline mode game
|
||||||
c.Auth.UUID = hex.EncodeToString(id[:])
|
c.Auth.UUID = hex.EncodeToString(id[:])
|
||||||
|
|
||||||
//Login
|
// Login
|
||||||
err := c.JoinServer("127.0.0.1")
|
err := c.JoinServer("127.0.0.1")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
@ -33,12 +33,9 @@ func ExampleClient_JoinServer_offline() {
|
|||||||
log.Println("Login success")
|
log.Println("Login success")
|
||||||
|
|
||||||
// Register event handlers
|
// Register event handlers
|
||||||
// c.Events.GameStart = onGameStartFunc
|
// c.Events.AddListener(...)
|
||||||
// c.Events.ChatMsg = onChatMsgFunc
|
|
||||||
// c.Events.Disconnect = onDisconnectFunc
|
|
||||||
// ...
|
|
||||||
|
|
||||||
//JoinGame
|
// JoinGame
|
||||||
err = c.HandleGame()
|
err = c.HandleGame()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
@ -61,7 +58,7 @@ func ExampleClient_JoinServer_online() {
|
|||||||
c.Auth.UUID, c.Auth.Name = auth.SelectedProfile()
|
c.Auth.UUID, c.Auth.Name = auth.SelectedProfile()
|
||||||
c.Auth.AsTk = auth.AccessToken()
|
c.Auth.AsTk = auth.AccessToken()
|
||||||
|
|
||||||
//Connect server
|
// Connect server
|
||||||
err = c.JoinServer("127.0.0.1")
|
err = c.JoinServer("127.0.0.1")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
@ -74,7 +71,7 @@ func ExampleClient_JoinServer_online() {
|
|||||||
// c.Events.Disconnect = onDisconnectFunc
|
// c.Events.Disconnect = onDisconnectFunc
|
||||||
// ...
|
// ...
|
||||||
|
|
||||||
//Join the game
|
// Join the game
|
||||||
err = c.HandleGame()
|
err = c.HandleGame()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
|
@ -12,12 +12,12 @@ import (
|
|||||||
func (c *Client) HandleGame() error {
|
func (c *Client) HandleGame() error {
|
||||||
var p pk.Packet
|
var p pk.Packet
|
||||||
for {
|
for {
|
||||||
//Read packets
|
// Read packets
|
||||||
if err := c.Conn.ReadPacket(&p); err != nil {
|
if err := c.Conn.ReadPacket(&p); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
//handle packets
|
// handle packets
|
||||||
err := c.handlePacket(p)
|
err := c.handlePacket(p)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
20
bot/mcbot.go
20
bot/mcbot.go
@ -22,8 +22,10 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// ProtocolVersion is the protocol version number of minecraft net protocol
|
// ProtocolVersion is the protocol version number of minecraft net protocol
|
||||||
const ProtocolVersion = 760
|
const (
|
||||||
const DefaultPort = mcnet.DefaultPort
|
ProtocolVersion = 760
|
||||||
|
DefaultPort = mcnet.DefaultPort
|
||||||
|
)
|
||||||
|
|
||||||
// JoinServer connect a Minecraft server for playing the game.
|
// JoinServer connect a Minecraft server for playing the game.
|
||||||
// Using roughly the same way to parse address as minecraft.
|
// Using roughly the same way to parse address as minecraft.
|
||||||
@ -98,15 +100,15 @@ func (c *Client) join(ctx context.Context, d *mcnet.Dialer, addr string) error {
|
|||||||
return LoginErr{"login start", err}
|
return LoginErr{"login start", err}
|
||||||
}
|
}
|
||||||
for {
|
for {
|
||||||
//Receive Packet
|
// Receive Packet
|
||||||
var p pk.Packet
|
var p pk.Packet
|
||||||
if err = c.Conn.ReadPacket(&p); err != nil {
|
if err = c.Conn.ReadPacket(&p); err != nil {
|
||||||
return LoginErr{"receive packet", err}
|
return LoginErr{"receive packet", err}
|
||||||
}
|
}
|
||||||
|
|
||||||
//Handle Packet
|
// Handle Packet
|
||||||
switch p.ID {
|
switch p.ID {
|
||||||
case packetid.LoginDisconnect: //LoginDisconnect
|
case packetid.LoginDisconnect: // LoginDisconnect
|
||||||
var reason chat.Message
|
var reason chat.Message
|
||||||
err = p.Scan(&reason)
|
err = p.Scan(&reason)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -114,12 +116,12 @@ func (c *Client) join(ctx context.Context, d *mcnet.Dialer, addr string) error {
|
|||||||
}
|
}
|
||||||
return LoginErr{"disconnect", DisconnectErr(reason)}
|
return LoginErr{"disconnect", DisconnectErr(reason)}
|
||||||
|
|
||||||
case packetid.LoginEncryptionRequest: //Encryption Request
|
case packetid.LoginEncryptionRequest: // Encryption Request
|
||||||
if err := handleEncryptionRequest(c, p); err != nil {
|
if err := handleEncryptionRequest(c, p); err != nil {
|
||||||
return LoginErr{"encryption", err}
|
return LoginErr{"encryption", err}
|
||||||
}
|
}
|
||||||
|
|
||||||
case packetid.LoginSuccess: //Login Success
|
case packetid.LoginSuccess: // Login Success
|
||||||
err := p.Scan(
|
err := p.Scan(
|
||||||
(*pk.UUID)(&c.UUID),
|
(*pk.UUID)(&c.UUID),
|
||||||
(*pk.String)(&c.Name),
|
(*pk.String)(&c.Name),
|
||||||
@ -129,14 +131,14 @@ func (c *Client) join(ctx context.Context, d *mcnet.Dialer, addr string) error {
|
|||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
|
|
||||||
case packetid.LoginCompression: //Set Compression
|
case packetid.LoginCompression: // Set Compression
|
||||||
var threshold pk.VarInt
|
var threshold pk.VarInt
|
||||||
if err := p.Scan(&threshold); err != nil {
|
if err := p.Scan(&threshold); err != nil {
|
||||||
return LoginErr{"compression", err}
|
return LoginErr{"compression", err}
|
||||||
}
|
}
|
||||||
c.Conn.SetThreshold(int(threshold))
|
c.Conn.SetThreshold(int(threshold))
|
||||||
|
|
||||||
case packetid.LoginPluginRequest: //Login Plugin Request
|
case packetid.LoginPluginRequest: // Login Plugin Request
|
||||||
var (
|
var (
|
||||||
msgid pk.VarInt
|
msgid pk.VarInt
|
||||||
channel pk.Identifier
|
channel pk.Identifier
|
||||||
|
@ -79,11 +79,11 @@ func pingAndList(ctx context.Context, addr string, conn *mcnet.Conn) (data []byt
|
|||||||
}
|
}
|
||||||
|
|
||||||
const Handshake = 0x00
|
const Handshake = 0x00
|
||||||
//握手
|
// 握手
|
||||||
err = conn.WritePacket(pk.Marshal(
|
err = conn.WritePacket(pk.Marshal(
|
||||||
Handshake, //Handshake packet ID
|
Handshake, // Handshake packet ID
|
||||||
pk.VarInt(ProtocolVersion), //Protocol version
|
pk.VarInt(ProtocolVersion), // Protocol version
|
||||||
pk.String(host), //Server's address
|
pk.String(host), // Server's address
|
||||||
pk.UnsignedShort(port),
|
pk.UnsignedShort(port),
|
||||||
pk.Byte(1),
|
pk.Byte(1),
|
||||||
))
|
))
|
||||||
@ -91,8 +91,8 @@ func pingAndList(ctx context.Context, addr string, conn *mcnet.Conn) (data []byt
|
|||||||
return nil, 0, fmt.Errorf("bot: send handshake packect fail: %v", err)
|
return nil, 0, fmt.Errorf("bot: send handshake packect fail: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
//LIST
|
// LIST
|
||||||
//请求服务器状态
|
// 请求服务器状态
|
||||||
err = conn.WritePacket(pk.Marshal(
|
err = conn.WritePacket(pk.Marshal(
|
||||||
packetid.StatusRequest,
|
packetid.StatusRequest,
|
||||||
))
|
))
|
||||||
@ -101,7 +101,7 @@ func pingAndList(ctx context.Context, addr string, conn *mcnet.Conn) (data []byt
|
|||||||
}
|
}
|
||||||
|
|
||||||
var p pk.Packet
|
var p pk.Packet
|
||||||
//服务器返回状态
|
// 服务器返回状态
|
||||||
if err := conn.ReadPacket(&p); err != nil {
|
if err := conn.ReadPacket(&p); err != nil {
|
||||||
return nil, 0, fmt.Errorf("bot: recv list packect fail: %v", err)
|
return nil, 0, fmt.Errorf("bot: recv list packect fail: %v", err)
|
||||||
}
|
}
|
||||||
@ -111,7 +111,7 @@ func pingAndList(ctx context.Context, addr string, conn *mcnet.Conn) (data []byt
|
|||||||
return nil, 0, fmt.Errorf("bot: scan list packect fail: %v", err)
|
return nil, 0, fmt.Errorf("bot: scan list packect fail: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
//PING
|
// PING
|
||||||
startTime := time.Now()
|
startTime := time.Now()
|
||||||
err = conn.WritePacket(pk.Marshal(
|
err = conn.WritePacket(pk.Marshal(
|
||||||
packetid.StatusPingRequest,
|
packetid.StatusPingRequest,
|
||||||
|
@ -57,15 +57,15 @@ const (
|
|||||||
type Message struct {
|
type Message struct {
|
||||||
Text string `json:"text"`
|
Text string `json:"text"`
|
||||||
|
|
||||||
Bold bool `json:"bold,omitempty"` //粗体
|
Bold bool `json:"bold,omitempty"` // 粗体
|
||||||
Italic bool `json:"italic,omitempty"` //斜体
|
Italic bool `json:"italic,omitempty"` // 斜体
|
||||||
UnderLined bool `json:"underlined,omitempty"` //下划线
|
UnderLined bool `json:"underlined,omitempty"` // 下划线
|
||||||
StrikeThrough bool `json:"strikethrough,omitempty"` //删除线
|
StrikeThrough bool `json:"strikethrough,omitempty"` // 删除线
|
||||||
Obfuscated bool `json:"obfuscated,omitempty"` //随机
|
Obfuscated bool `json:"obfuscated,omitempty"` // 随机
|
||||||
// Font of the message, could be one of minecraft:uniform, minecraft:alt or minecraft:default
|
// Font of the message, could be one of minecraft:uniform, minecraft:alt or minecraft:default
|
||||||
// This option is only valid on 1.16+, otherwise the property is ignored.
|
// This option is only valid on 1.16+, otherwise the property is ignored.
|
||||||
Font string `json:"font,omitempty"` //字体
|
Font string `json:"font,omitempty"` // 字体
|
||||||
Color string `json:"color,omitempty"` //颜色
|
Color string `json:"color,omitempty"` // 颜色
|
||||||
|
|
||||||
// Insertion contains text to insert. Only used for messages in chat.
|
// Insertion contains text to insert. Only used for messages in chat.
|
||||||
// When shift is held, clicking the component inserts the given text
|
// When shift is held, clicking the component inserts the given text
|
||||||
@ -207,6 +207,7 @@ var fmtCode = map[byte]string{
|
|||||||
'o': "3",
|
'o': "3",
|
||||||
'r': "0",
|
'r': "0",
|
||||||
}
|
}
|
||||||
|
|
||||||
var colors = map[string]string{
|
var colors = map[string]string{
|
||||||
Black: "30",
|
Black: "30",
|
||||||
DarkBlue: "34",
|
DarkBlue: "34",
|
||||||
@ -241,7 +242,7 @@ func (m Message) ClearString() string {
|
|||||||
text, _ := TransCtrlSeq(m.Text, false)
|
text, _ := TransCtrlSeq(m.Text, false)
|
||||||
msg.WriteString(text)
|
msg.WriteString(text)
|
||||||
|
|
||||||
//handle translate
|
// handle translate
|
||||||
if m.Translate != "" {
|
if m.Translate != "" {
|
||||||
args := make([]interface{}, len(m.With))
|
args := make([]interface{}, len(m.With))
|
||||||
for i, v := range m.With {
|
for i, v := range m.With {
|
||||||
@ -286,7 +287,7 @@ func (m Message) String() string {
|
|||||||
text, ok := TransCtrlSeq(m.Text, true)
|
text, ok := TransCtrlSeq(m.Text, true)
|
||||||
msg.WriteString(text)
|
msg.WriteString(text)
|
||||||
|
|
||||||
//handle translate
|
// handle translate
|
||||||
if m.Translate != "" {
|
if m.Translate != "" {
|
||||||
args := make([]interface{}, len(m.With))
|
args := make([]interface{}, len(m.With))
|
||||||
for i, v := range m.With {
|
for i, v := range m.With {
|
||||||
@ -323,9 +324,9 @@ func TransCtrlSeq(str string, ansi bool) (dst string, change bool) {
|
|||||||
change = true
|
change = true
|
||||||
return "\033[" + f + "m" // enable, add ANSI code
|
return "\033[" + f + "m" // enable, add ANSI code
|
||||||
}
|
}
|
||||||
return "" //disable, remove the § code
|
return "" // disable, remove the § code
|
||||||
}
|
}
|
||||||
return str //not a § code
|
return str // not a § code
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
return
|
return
|
||||||
|
@ -17,7 +17,7 @@ import (
|
|||||||
const (
|
const (
|
||||||
version = "1.17"
|
version = "1.17"
|
||||||
infoURL = "https://raw.githubusercontent.com/PrismarineJS/minecraft-data/master/data/pc/" + version + "/entities.json"
|
infoURL = "https://raw.githubusercontent.com/PrismarineJS/minecraft-data/master/data/pc/" + version + "/entities.json"
|
||||||
//language=gohtml
|
// language=gohtml
|
||||||
entityTmpl = `// Code generated by gen_entity.go DO NOT EDIT.
|
entityTmpl = `// Code generated by gen_entity.go DO NOT EDIT.
|
||||||
// Package entity stores information about entities in Minecraft.
|
// Package entity stores information about entities in Minecraft.
|
||||||
package entity
|
package entity
|
||||||
|
@ -17,7 +17,7 @@ import (
|
|||||||
const (
|
const (
|
||||||
version = "1.17"
|
version = "1.17"
|
||||||
infoURL = "https://raw.githubusercontent.com/PrismarineJS/minecraft-data/master/data/pc/" + version + "/items.json"
|
infoURL = "https://raw.githubusercontent.com/PrismarineJS/minecraft-data/master/data/pc/" + version + "/items.json"
|
||||||
//language=gohtml
|
// language=gohtml
|
||||||
itemTmpl = `// Code generated by gen_item.go DO NOT EDIT.
|
itemTmpl = `// Code generated by gen_item.go DO NOT EDIT.
|
||||||
// Package item stores information about items in Minecraft.
|
// Package item stores information about items in Minecraft.
|
||||||
package item
|
package item
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
//+build generate
|
//go:build generate
|
||||||
|
// +build generate
|
||||||
|
|
||||||
// This program can automatically download language.json file and convert into .go
|
// This program can automatically download language.json file and convert into .go
|
||||||
package main
|
package main
|
||||||
@ -17,9 +18,8 @@ import (
|
|||||||
"text/template"
|
"text/template"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
// language=gohtml
|
||||||
//language=gohtml
|
var langTmpl = `// Code generated by downloader.go; DO NOT EDIT.
|
||||||
langTmpl = `// Code generated by downloader.go; DO NOT EDIT.
|
|
||||||
package {{.Name}}
|
package {{.Name}}
|
||||||
{{if ne .Name "en_us"}}
|
{{if ne .Name "en_us"}}
|
||||||
import "github.com/Tnze/go-mc/chat"
|
import "github.com/Tnze/go-mc/chat"
|
||||||
@ -28,7 +28,6 @@ func init() { chat.SetLanguage(Map) }
|
|||||||
{{end}}
|
{{end}}
|
||||||
var Map = {{.LangMap | printf "%#v"}}
|
var Map = {{.LangMap | printf "%#v"}}
|
||||||
`
|
`
|
||||||
)
|
|
||||||
|
|
||||||
//go:generate go run $GOFILE
|
//go:generate go run $GOFILE
|
||||||
//go:generate go fmt ./...
|
//go:generate go fmt ./...
|
||||||
@ -90,7 +89,7 @@ func main() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func lang(name, hash string) {
|
func lang(name, hash string) {
|
||||||
//download language
|
// download language
|
||||||
LangURL := "http://resources.download.minecraft.net/" + hash[:2] + "/" + hash
|
LangURL := "http://resources.download.minecraft.net/" + hash[:2] + "/" + hash
|
||||||
resp, err := http.Get(LangURL)
|
resp, err := http.Get(LangURL)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -112,12 +111,12 @@ func readLang(name string, r io.Reader) {
|
|||||||
pName := strings.ReplaceAll(name, "_", "-")
|
pName := strings.ReplaceAll(name, "_", "-")
|
||||||
|
|
||||||
// mkdir
|
// mkdir
|
||||||
err = os.Mkdir(pName, 0777)
|
err = os.Mkdir(pName, 0o777)
|
||||||
if err != nil && !os.IsExist(err) {
|
if err != nil && !os.IsExist(err) {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
f, err := os.OpenFile(filepath.Join(pName, name+".go"), os.O_CREATE|os.O_RDWR|os.O_TRUNC, 0666)
|
f, err := os.OpenFile(filepath.Join(pName, name+".go"), os.O_CREATE|os.O_RDWR|os.O_TRUNC, 0o666)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
@ -143,7 +142,7 @@ var javaN = regexp.MustCompile(`%[0-9]\$s`)
|
|||||||
|
|
||||||
// Java use %2$s to refer to the second arg, but Golang use %2s, so we need this
|
// Java use %2$s to refer to the second arg, but Golang use %2s, so we need this
|
||||||
func trans(m map[string]string) {
|
func trans(m map[string]string) {
|
||||||
//replace "%[0-9]\$s" with "%[0-9]s"
|
// replace "%[0-9]\$s" with "%[0-9]s"
|
||||||
for i := range m {
|
for i := range m {
|
||||||
c := m[i]
|
c := m[i]
|
||||||
if javaN.MatchString(c) {
|
if javaN.MatchString(c) {
|
||||||
@ -169,8 +168,8 @@ func assetIndexURL() (string, error) {
|
|||||||
Latest struct {
|
Latest struct {
|
||||||
Release string `json:"release"`
|
Release string `json:"release"`
|
||||||
} `json:"latest"`
|
} `json:"latest"`
|
||||||
Versions []struct{
|
Versions []struct {
|
||||||
ID string `json:"id"`
|
ID string `json:"id"`
|
||||||
URL string `json:"url"`
|
URL string `json:"url"`
|
||||||
} `json:"versions"`
|
} `json:"versions"`
|
||||||
}
|
}
|
||||||
@ -196,8 +195,8 @@ func assetIndexURL() (string, error) {
|
|||||||
return "", errors.New("could not determine versionURL")
|
return "", errors.New("could not determine versionURL")
|
||||||
}
|
}
|
||||||
|
|
||||||
var version struct{
|
var version struct {
|
||||||
AssetIndex struct{
|
AssetIndex struct {
|
||||||
URL string `json:"url"`
|
URL string `json:"url"`
|
||||||
} `json:"assetIndex"`
|
} `json:"assetIndex"`
|
||||||
}
|
}
|
||||||
|
@ -2,9 +2,10 @@ package packetid
|
|||||||
|
|
||||||
//go:generate stringer -type ClientboundPacketID
|
//go:generate stringer -type ClientboundPacketID
|
||||||
//go:generate stringer -type ServerboundPacketID
|
//go:generate stringer -type ServerboundPacketID
|
||||||
|
type (
|
||||||
type ClientboundPacketID int32
|
ClientboundPacketID int32
|
||||||
type ServerboundPacketID int32
|
ServerboundPacketID int32
|
||||||
|
)
|
||||||
|
|
||||||
// Login Clientbound
|
// Login Clientbound
|
||||||
const (
|
const (
|
||||||
|
@ -71,7 +71,7 @@ func main() {
|
|||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
err = os.WriteFile("blockentitytype/blockentitytype.go", formattedSource, 0666)
|
err = os.WriteFile("blockentitytype/blockentitytype.go", formattedSource, 0o666)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
|
@ -16,7 +16,7 @@ import (
|
|||||||
const (
|
const (
|
||||||
version = "1.17.1"
|
version = "1.17.1"
|
||||||
protocolURL = "https://pokechu22.github.io/Burger/" + version + ".json"
|
protocolURL = "https://pokechu22.github.io/Burger/" + version + ".json"
|
||||||
//language=gohtml
|
// language=gohtml
|
||||||
soundTmpl = `// Code generated by gen_soundid.go. DO NOT EDIT.
|
soundTmpl = `// Code generated by gen_soundid.go. DO NOT EDIT.
|
||||||
|
|
||||||
package soundid
|
package soundid
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
botchat "github.com/Tnze/go-mc/bot/chat"
|
|
||||||
"log"
|
"log"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@ -9,6 +8,7 @@ import (
|
|||||||
|
|
||||||
"github.com/Tnze/go-mc/bot"
|
"github.com/Tnze/go-mc/bot"
|
||||||
"github.com/Tnze/go-mc/bot/basic"
|
"github.com/Tnze/go-mc/bot/basic"
|
||||||
|
botchat "github.com/Tnze/go-mc/bot/chat"
|
||||||
"github.com/Tnze/go-mc/chat"
|
"github.com/Tnze/go-mc/chat"
|
||||||
_ "github.com/Tnze/go-mc/data/lang/en-us"
|
_ "github.com/Tnze/go-mc/data/lang/en-us"
|
||||||
"github.com/Tnze/go-mc/data/packetid"
|
"github.com/Tnze/go-mc/data/packetid"
|
||||||
@ -26,7 +26,7 @@ var (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
//log.SetOutput(colorable.NewColorableStdout()) // optional for colorable output
|
// log.SetOutput(colorable.NewColorableStdout()) // optional for colorable output
|
||||||
c = bot.NewClient()
|
c = bot.NewClient()
|
||||||
p = basic.NewPlayer(c, basic.DefaultSettings, basic.EventsListener{
|
p = basic.NewPlayer(c, basic.DefaultSettings, basic.EventsListener{
|
||||||
GameStart: onGameStart,
|
GameStart: onGameStart,
|
||||||
@ -36,18 +36,18 @@ func main() {
|
|||||||
})
|
})
|
||||||
bc = botchat.NewChat(c, p, botchat.EventsHandler{PlayerChatMessage: onChatMsg})
|
bc = botchat.NewChat(c, p, botchat.EventsHandler{PlayerChatMessage: onChatMsg})
|
||||||
|
|
||||||
//Register event handlers
|
// Register event handlers
|
||||||
|
|
||||||
c.Events.AddListener(soundListener)
|
c.Events.AddListener(soundListener)
|
||||||
|
|
||||||
//Login
|
// Login
|
||||||
err := c.JoinServer("127.0.0.1")
|
err := c.JoinServer("127.0.0.1")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
log.Println("Login success")
|
log.Println("Login success")
|
||||||
|
|
||||||
//JoinGame
|
// JoinGame
|
||||||
err = c.HandleGame()
|
err = c.HandleGame()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
@ -96,12 +96,12 @@ func UseItem(hand int32) error {
|
|||||||
//goland:noinspection SpellCheckingInspection
|
//goland:noinspection SpellCheckingInspection
|
||||||
func onSound(id int, category int, x, y, z float64, volume, pitch float32) error {
|
func onSound(id int, category int, x, y, z float64, volume, pitch float32) error {
|
||||||
if id == 369 {
|
if id == 369 {
|
||||||
if err := UseItem(0); err != nil { //retrieve
|
if err := UseItem(0); err != nil { // retrieve
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
log.Println("gra~")
|
log.Println("gra~")
|
||||||
time.Sleep(time.Millisecond * 300)
|
time.Sleep(time.Millisecond * 300)
|
||||||
if err := UseItem(0); err != nil { //throw
|
if err := UseItem(0); err != nil { // throw
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
watch <- time.Now()
|
watch <- time.Now()
|
||||||
|
@ -21,20 +21,24 @@ import (
|
|||||||
"github.com/Tnze/go-mc/level"
|
"github.com/Tnze/go-mc/level"
|
||||||
)
|
)
|
||||||
|
|
||||||
var address = flag.String("address", "127.0.0.1", "The server address")
|
var (
|
||||||
var name = flag.String("name", "Daze", "The player's name")
|
address = flag.String("address", "127.0.0.1", "The server address")
|
||||||
var playerID = flag.String("uuid", "", "The player's UUID")
|
name = flag.String("name", "Daze", "The player's name")
|
||||||
var accessToken = flag.String("token", "", "AccessToken")
|
playerID = flag.String("uuid", "", "The player's UUID")
|
||||||
|
accessToken = flag.String("token", "", "AccessToken")
|
||||||
|
)
|
||||||
|
|
||||||
var client *bot.Client
|
var (
|
||||||
var player *basic.Player
|
client *bot.Client
|
||||||
var chatHandler *botchat.Chat
|
player *basic.Player
|
||||||
var worldManager *world.World
|
chatHandler *botchat.Chat
|
||||||
var screenManager *screen.Manager
|
worldManager *world.World
|
||||||
|
screenManager *screen.Manager
|
||||||
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
flag.Parse()
|
flag.Parse()
|
||||||
//log.SetOutput(colorable.NewColorableStdout())
|
// log.SetOutput(colorable.NewColorableStdout())
|
||||||
client = bot.NewClient()
|
client = bot.NewClient()
|
||||||
client.Auth = bot.Auth{
|
client.Auth = bot.Auth{
|
||||||
Name: *name,
|
Name: *name,
|
||||||
@ -61,14 +65,14 @@ func main() {
|
|||||||
Close: nil,
|
Close: nil,
|
||||||
})
|
})
|
||||||
|
|
||||||
//Login
|
// Login
|
||||||
err := client.JoinServer(*address)
|
err := client.JoinServer(*address)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
log.Println("Login success")
|
log.Println("Login success")
|
||||||
|
|
||||||
//JoinGame
|
// JoinGame
|
||||||
for {
|
for {
|
||||||
if err = client.HandleGame(); err == nil {
|
if err = client.HandleGame(); err == nil {
|
||||||
panic("HandleGame never return nil")
|
panic("HandleGame never return nil")
|
||||||
@ -103,7 +107,7 @@ func onDeath() error {
|
|||||||
|
|
||||||
func onGameStart() error {
|
func onGameStart() error {
|
||||||
log.Println("Game start")
|
log.Println("Game start")
|
||||||
return nil //if err isn't nil, HandleGame() will return it.
|
return nil // if err isn't nil, HandleGame() will return it.
|
||||||
}
|
}
|
||||||
|
|
||||||
func onPlayerMsg(msg chat.Message) error {
|
func onPlayerMsg(msg chat.Message) error {
|
||||||
|
@ -18,14 +18,16 @@ import (
|
|||||||
pk "github.com/Tnze/go-mc/net/packet"
|
pk "github.com/Tnze/go-mc/net/packet"
|
||||||
)
|
)
|
||||||
|
|
||||||
var address = flag.String("address", "127.0.0.1", "The server address")
|
var (
|
||||||
var client *bot.Client
|
address = flag.String("address", "127.0.0.1", "The server address")
|
||||||
var player *basic.Player
|
client *bot.Client
|
||||||
var screenManager *screen.Manager
|
player *basic.Player
|
||||||
|
screenManager *screen.Manager
|
||||||
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
flag.Parse()
|
flag.Parse()
|
||||||
//log.SetOutput(colorable.NewColorableStdout())
|
// log.SetOutput(colorable.NewColorableStdout())
|
||||||
client = bot.NewClient()
|
client = bot.NewClient()
|
||||||
client.Auth.Name = "Daze"
|
client.Auth.Name = "Daze"
|
||||||
player = basic.NewPlayer(client, basic.DefaultSettings, basic.EventsListener{})
|
player = basic.NewPlayer(client, basic.DefaultSettings, basic.EventsListener{})
|
||||||
@ -35,14 +37,14 @@ func main() {
|
|||||||
F: onCommands,
|
F: onCommands,
|
||||||
})
|
})
|
||||||
|
|
||||||
//Login
|
// Login
|
||||||
err := client.JoinServer(*address)
|
err := client.JoinServer(*address)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
log.Println("Login success")
|
log.Println("Login success")
|
||||||
|
|
||||||
//JoinGame
|
// JoinGame
|
||||||
for {
|
for {
|
||||||
if err = client.HandleGame(); err == nil {
|
if err = client.HandleGame(); err == nil {
|
||||||
panic("HandleGame never return nil")
|
panic("HandleGame never return nil")
|
||||||
@ -62,8 +64,7 @@ func onCommands(p pk.Packet) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
type Node struct {
|
type Node struct{}
|
||||||
}
|
|
||||||
|
|
||||||
func (n Node) ReadFrom(r io.Reader) (int64, error) {
|
func (n Node) ReadFrom(r io.Reader) (int64, error) {
|
||||||
var Flags pk.Byte
|
var Flags pk.Byte
|
||||||
@ -71,7 +72,7 @@ func (n Node) ReadFrom(r io.Reader) (int64, error) {
|
|||||||
var Redirect pk.VarInt
|
var Redirect pk.VarInt
|
||||||
var Name pk.String
|
var Name pk.String
|
||||||
var Parser pk.Identifier
|
var Parser pk.Identifier
|
||||||
var Properties = Prop{Type: &Parser}
|
Properties := Prop{Type: &Parser}
|
||||||
var SuggestionsType pk.Identifier
|
var SuggestionsType pk.Identifier
|
||||||
m, err := pk.Tuple{
|
m, err := pk.Tuple{
|
||||||
&Flags,
|
&Flags,
|
||||||
|
@ -8,8 +8,10 @@ import (
|
|||||||
"github.com/Tnze/go-mc/yggdrasil"
|
"github.com/Tnze/go-mc/yggdrasil"
|
||||||
)
|
)
|
||||||
|
|
||||||
var user = flag.String("user", "", "Can be an email address or player name for unmigrated accounts")
|
var (
|
||||||
var pswd = flag.String("password", "", "Your password")
|
user = flag.String("user", "", "Can be an email address or player name for unmigrated accounts")
|
||||||
|
pswd = flag.String("password", "", "Your password")
|
||||||
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
flag.Parse()
|
flag.Parse()
|
||||||
|
@ -13,8 +13,10 @@ import (
|
|||||||
"github.com/Tnze/go-mc/save/region"
|
"github.com/Tnze/go-mc/save/region"
|
||||||
)
|
)
|
||||||
|
|
||||||
var decomp = flag.Bool("x", false, "decompress each chunk to NBT format")
|
var (
|
||||||
var repack = flag.Bool("p", false, "repack .mcc file to .mca")
|
decomp = flag.Bool("x", false, "decompress each chunk to NBT format")
|
||||||
|
repack = flag.Bool("p", false, "repack .mcc file to .mca")
|
||||||
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
flag.Usage = usage
|
flag.Usage = usage
|
||||||
@ -79,7 +81,7 @@ func unpack(f, o string) {
|
|||||||
|
|
||||||
fn := fmt.Sprintf("c.%d.%d.mcc", x*32+i, z*32+j)
|
fn := fmt.Sprintf("c.%d.%d.mcc", x*32+i, z*32+j)
|
||||||
if *decomp {
|
if *decomp {
|
||||||
fn += ".nbt" //解压后就是一个标准的NBT文件,可以加个.nbt后缀
|
fn += ".nbt" // 解压后就是一个标准的NBT文件,可以加个.nbt后缀
|
||||||
switch data[0] {
|
switch data[0] {
|
||||||
default:
|
default:
|
||||||
err = fmt.Errorf("unknown compression type 0x%02x", data[0])
|
err = fmt.Errorf("unknown compression type 0x%02x", data[0])
|
||||||
@ -91,7 +93,7 @@ func unpack(f, o string) {
|
|||||||
checkerr(err)
|
checkerr(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
cf, err := os.OpenFile(filepath.Join(o, fn), os.O_CREATE|os.O_RDWR|os.O_EXCL, 0666)
|
cf, err := os.OpenFile(filepath.Join(o, fn), os.O_CREATE|os.O_RDWR|os.O_EXCL, 0o666)
|
||||||
checkerr(err)
|
checkerr(err)
|
||||||
|
|
||||||
_, err = io.Copy(cf, r)
|
_, err = io.Copy(cf, r)
|
||||||
|
@ -20,8 +20,10 @@ import (
|
|||||||
"github.com/Tnze/go-mc/chat"
|
"github.com/Tnze/go-mc/chat"
|
||||||
)
|
)
|
||||||
|
|
||||||
var protocol = flag.Int("p", 578, "The protocol version number sent during ping")
|
var (
|
||||||
var favicon = flag.String("f", "", "If specified, the server's icon will be save to")
|
protocol = flag.Int("p", 578, "The protocol version number sent during ping")
|
||||||
|
favicon = flag.String("f", "", "If specified, the server's icon will be save to")
|
||||||
|
)
|
||||||
|
|
||||||
type status struct {
|
type status struct {
|
||||||
Description chat.Message
|
Description chat.Message
|
||||||
|
@ -13,12 +13,14 @@ import (
|
|||||||
"github.com/Tnze/go-mc/chat"
|
"github.com/Tnze/go-mc/chat"
|
||||||
)
|
)
|
||||||
|
|
||||||
var address = flag.String("address", "127.0.0.1", "The server address")
|
var (
|
||||||
var number = flag.Int("number", 1023, "The number of clients")
|
address = flag.String("address", "127.0.0.1", "The server address")
|
||||||
|
number = flag.Int("number", 1023, "The number of clients")
|
||||||
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
flag.Parse()
|
flag.Parse()
|
||||||
//log.SetOutput(colorable.NewColorableStdout())
|
// log.SetOutput(colorable.NewColorableStdout())
|
||||||
|
|
||||||
for i := 0; i < *number; i++ {
|
for i := 0; i < *number; i++ {
|
||||||
go func(i int) {
|
go func(i int) {
|
||||||
@ -52,7 +54,7 @@ func newIndividual(id int, name string) (i *individual) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (i *individual) run(address string) {
|
func (i *individual) run(address string) {
|
||||||
//Login
|
// Login
|
||||||
err := i.client.JoinServer(address)
|
err := i.client.JoinServer(address)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("[%d]Login fail: %v", i.id, err)
|
log.Printf("[%d]Login fail: %v", i.id, err)
|
||||||
@ -60,7 +62,7 @@ func (i *individual) run(address string) {
|
|||||||
}
|
}
|
||||||
log.Printf("[%d]Login success", i.id)
|
log.Printf("[%d]Login success", i.id)
|
||||||
|
|
||||||
//JoinGame
|
// JoinGame
|
||||||
if err = i.client.HandleGame(); err == nil {
|
if err = i.client.HandleGame(); err == nil {
|
||||||
panic("HandleGame never return nil")
|
panic("HandleGame never return nil")
|
||||||
}
|
}
|
||||||
|
@ -11,8 +11,10 @@ import (
|
|||||||
"github.com/Tnze/go-mc/offline"
|
"github.com/Tnze/go-mc/offline"
|
||||||
)
|
)
|
||||||
|
|
||||||
const ProtocolVersion = 578
|
const (
|
||||||
const MaxPlayer = 200
|
ProtocolVersion = 578
|
||||||
|
MaxPlayer = 200
|
||||||
|
)
|
||||||
|
|
||||||
// Packet IDs
|
// Packet IDs
|
||||||
const (
|
const (
|
||||||
@ -45,11 +47,11 @@ func acceptConn(conn net.Conn) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
switch intention {
|
switch intention {
|
||||||
default: //unknown error
|
default: // unknown error
|
||||||
log.Printf("Unknown handshake intention: %v", intention)
|
log.Printf("Unknown handshake intention: %v", intention)
|
||||||
case 1: //for status
|
case 1: // for status
|
||||||
acceptListPing(conn)
|
acceptListPing(conn)
|
||||||
case 2: //for login
|
case 2: // for login
|
||||||
handlePlaying(conn, protocol)
|
handlePlaying(conn, protocol)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -103,19 +105,19 @@ type PlayerInfo struct {
|
|||||||
|
|
||||||
// acceptLogin check player's account
|
// acceptLogin check player's account
|
||||||
func acceptLogin(conn net.Conn) (info PlayerInfo, err error) {
|
func acceptLogin(conn net.Conn) (info PlayerInfo, err error) {
|
||||||
//login start
|
// login start
|
||||||
var p pk.Packet
|
var p pk.Packet
|
||||||
err = conn.ReadPacket(&p)
|
err = conn.ReadPacket(&p)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
err = p.Scan((*pk.String)(&info.Name)) //decode username as pk.String
|
err = p.Scan((*pk.String)(&info.Name)) // decode username as pk.String
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
//auth
|
// auth
|
||||||
const OnlineMode = false
|
const OnlineMode = false
|
||||||
if OnlineMode {
|
if OnlineMode {
|
||||||
log.Panic("Not Implement")
|
log.Panic("Not Implement")
|
||||||
@ -146,7 +148,7 @@ func handshake(conn net.Conn) (protocol, intention int32, err error) {
|
|||||||
// loginSuccess send LoginSuccess packet to client
|
// loginSuccess send LoginSuccess packet to client
|
||||||
func loginSuccess(conn net.Conn, name string, uuid uuid.UUID) error {
|
func loginSuccess(conn net.Conn, name string, uuid uuid.UUID) error {
|
||||||
return conn.WritePacket(pk.Marshal(0x02,
|
return conn.WritePacket(pk.Marshal(0x02,
|
||||||
pk.String(uuid.String()), //uuid as string with hyphens
|
pk.String(uuid.String()), // uuid as string with hyphens
|
||||||
pk.String(name),
|
pk.String(name),
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
@ -20,9 +20,9 @@ func acceptListPing(conn net.Conn) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
switch p.ID {
|
switch p.ID {
|
||||||
case 0x00: //List
|
case 0x00: // List
|
||||||
err = conn.WritePacket(pk.Marshal(0x00, pk.String(listResp())))
|
err = conn.WritePacket(pk.Marshal(0x00, pk.String(listResp())))
|
||||||
case 0x01: //Ping
|
case 0x01: // Ping
|
||||||
err = conn.WritePacket(p)
|
err = conn.WritePacket(p)
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -13,8 +13,10 @@ import (
|
|||||||
"github.com/Tnze/go-mc/offline"
|
"github.com/Tnze/go-mc/offline"
|
||||||
)
|
)
|
||||||
|
|
||||||
const ProtocolVersion = 756
|
const (
|
||||||
const MaxPlayer = 200
|
ProtocolVersion = 756
|
||||||
|
MaxPlayer = 200
|
||||||
|
)
|
||||||
|
|
||||||
// Packet IDs
|
// Packet IDs
|
||||||
const (
|
const (
|
||||||
@ -47,11 +49,11 @@ func acceptConn(conn net.Conn) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
switch intention {
|
switch intention {
|
||||||
default: //unknown error
|
default: // unknown error
|
||||||
log.Printf("Unknown handshake intention: %v", intention)
|
log.Printf("Unknown handshake intention: %v", intention)
|
||||||
case 1: //for status
|
case 1: // for status
|
||||||
acceptListPing(conn)
|
acceptListPing(conn)
|
||||||
case 2: //for login
|
case 2: // for login
|
||||||
handlePlaying(conn, protocol)
|
handlePlaying(conn, protocol)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -106,19 +108,19 @@ type PlayerInfo struct {
|
|||||||
|
|
||||||
// acceptLogin check player's account
|
// acceptLogin check player's account
|
||||||
func acceptLogin(conn net.Conn) (info PlayerInfo, err error) {
|
func acceptLogin(conn net.Conn) (info PlayerInfo, err error) {
|
||||||
//login start
|
// login start
|
||||||
var p pk.Packet
|
var p pk.Packet
|
||||||
err = conn.ReadPacket(&p)
|
err = conn.ReadPacket(&p)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
err = p.Scan((*pk.String)(&info.Name)) //decode username as pk.String
|
err = p.Scan((*pk.String)(&info.Name)) // decode username as pk.String
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
//auth
|
// auth
|
||||||
const OnlineMode = false
|
const OnlineMode = false
|
||||||
if OnlineMode {
|
if OnlineMode {
|
||||||
log.Panic("Not Implement")
|
log.Panic("Not Implement")
|
||||||
|
@ -2,11 +2,12 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"log"
|
||||||
|
|
||||||
"github.com/Tnze/go-mc/chat"
|
"github.com/Tnze/go-mc/chat"
|
||||||
"github.com/Tnze/go-mc/net"
|
"github.com/Tnze/go-mc/net"
|
||||||
pk "github.com/Tnze/go-mc/net/packet"
|
pk "github.com/Tnze/go-mc/net/packet"
|
||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
"log"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func acceptListPing(conn net.Conn) {
|
func acceptListPing(conn net.Conn) {
|
||||||
@ -18,9 +19,9 @@ func acceptListPing(conn net.Conn) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
switch p.ID {
|
switch p.ID {
|
||||||
case 0x00: //List
|
case 0x00: // List
|
||||||
err = conn.WritePacket(pk.Marshal(0x00, pk.String(listResp())))
|
err = conn.WritePacket(pk.Marshal(0x00, pk.String(listResp())))
|
||||||
case 0x01: //Ping
|
case 0x01: // Ping
|
||||||
err = conn.WritePacket(p)
|
err = conn.WritePacket(p)
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -8,8 +8,10 @@ import (
|
|||||||
pk "github.com/Tnze/go-mc/net/packet"
|
pk "github.com/Tnze/go-mc/net/packet"
|
||||||
)
|
)
|
||||||
|
|
||||||
const indexOutOfBounds = "index out of bounds"
|
const (
|
||||||
const valueOutOfBounds = "value out of bounds"
|
indexOutOfBounds = "index out of bounds"
|
||||||
|
valueOutOfBounds = "value out of bounds"
|
||||||
|
)
|
||||||
|
|
||||||
// BitStorage implement the compacted data array used in chunk storage and heightmaps.
|
// BitStorage implement the compacted data array used in chunk storage and heightmaps.
|
||||||
// You can think of this as a []intN whose N is called "bits" in NewBitStorage.
|
// You can think of this as a []intN whose N is called "bits" in NewBitStorage.
|
||||||
|
@ -1,14 +1,17 @@
|
|||||||
package level
|
package level
|
||||||
|
|
||||||
import (
|
import (
|
||||||
pk "github.com/Tnze/go-mc/net/packet"
|
|
||||||
"math/bits"
|
"math/bits"
|
||||||
"reflect"
|
"reflect"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
pk "github.com/Tnze/go-mc/net/packet"
|
||||||
)
|
)
|
||||||
|
|
||||||
var data = []uint64{0x0020863148418841, 0x01018A7260F68C87}
|
var (
|
||||||
var want = []int{1, 2, 2, 3, 4, 4, 5, 6, 6, 4, 8, 0, 7, 4, 3, 13, 15, 16, 9, 14, 10, 12, 0, 2}
|
data = []uint64{0x0020863148418841, 0x01018A7260F68C87}
|
||||||
|
want = []int{1, 2, 2, 3, 4, 4, 5, 6, 6, 4, 8, 0, 7, 4, 3, 13, 15, 16, 9, 14, 10, 12, 0, 2}
|
||||||
|
)
|
||||||
|
|
||||||
func TestBitStorage_Get(t *testing.T) {
|
func TestBitStorage_Get(t *testing.T) {
|
||||||
bs := NewBitStorage(5, 24, data)
|
bs := NewBitStorage(5, 24, data)
|
||||||
|
@ -20,18 +20,22 @@ type Block interface {
|
|||||||
//go:embed block_states.nbt
|
//go:embed block_states.nbt
|
||||||
var blockStates []byte
|
var blockStates []byte
|
||||||
|
|
||||||
var ToStateID map[Block]StateID
|
var (
|
||||||
var StateList []Block
|
ToStateID map[Block]StateID
|
||||||
|
StateList []Block
|
||||||
|
)
|
||||||
|
|
||||||
// BitsPerBlock indicates how many bits are needed to represent all possible
|
// BitsPerBlock indicates how many bits are needed to represent all possible
|
||||||
// block states. This value is used to determine the size of the global palette.
|
// block states. This value is used to determine the size of the global palette.
|
||||||
var BitsPerBlock int
|
var BitsPerBlock int
|
||||||
|
|
||||||
type StateID int
|
type (
|
||||||
type State struct {
|
StateID int
|
||||||
Name string
|
State struct {
|
||||||
Properties nbt.RawMessage
|
Name string
|
||||||
}
|
Properties nbt.RawMessage
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
var states []State
|
var states []State
|
||||||
|
@ -70,7 +70,7 @@ func genSourceFile(states []State) {
|
|||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
err = os.WriteFile("blocks.go", formattedSource, 0666)
|
err = os.WriteFile("blocks.go", formattedSource, 0o666)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
@ -78,7 +78,7 @@ func main() {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
log.Panic(err)
|
log.Panic(err)
|
||||||
}
|
}
|
||||||
err = os.WriteFile("properties_enum.go", formattedSource, 0666)
|
err = os.WriteFile("properties_enum.go", formattedSource, 0o666)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Panic(err)
|
log.Panic(err)
|
||||||
}
|
}
|
||||||
|
@ -406,6 +406,7 @@ type Section struct {
|
|||||||
func (s *Section) GetBlock(i int) BlocksState {
|
func (s *Section) GetBlock(i int) BlocksState {
|
||||||
return s.States.Get(i)
|
return s.States.Get(i)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Section) SetBlock(i int, v BlocksState) {
|
func (s *Section) SetBlock(i int, v BlocksState) {
|
||||||
if block.IsAir(s.States.Get(i)) {
|
if block.IsAir(s.States.Get(i)) {
|
||||||
s.BlockCount--
|
s.BlockCount--
|
||||||
|
@ -13,8 +13,10 @@ import (
|
|||||||
type State interface {
|
type State interface {
|
||||||
~int
|
~int
|
||||||
}
|
}
|
||||||
type BlocksState = block.StateID
|
type (
|
||||||
type BiomesState int
|
BlocksState = block.StateID
|
||||||
|
BiomesState int
|
||||||
|
)
|
||||||
|
|
||||||
type PaletteContainer[T State] struct {
|
type PaletteContainer[T State] struct {
|
||||||
bits int
|
bits int
|
||||||
@ -206,6 +208,7 @@ func (b biomesCfg) bits(bits int) int {
|
|||||||
return biome.BitsPerBiome
|
return biome.BitsPerBiome
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b biomesCfg) create(bits int) palette[BiomesState] {
|
func (b biomesCfg) create(bits int) palette[BiomesState] {
|
||||||
switch bits {
|
switch bits {
|
||||||
case 0:
|
case 0:
|
||||||
|
@ -33,7 +33,7 @@ func (d *Decoder) Decode(v interface{}) (string, error) {
|
|||||||
if val.Kind() != reflect.Ptr {
|
if val.Kind() != reflect.Ptr {
|
||||||
return "", errors.New("nbt: non-pointer passed to Decode")
|
return "", errors.New("nbt: non-pointer passed to Decode")
|
||||||
}
|
}
|
||||||
//start read NBT
|
// start read NBT
|
||||||
tagType, tagName, err := d.readTag()
|
tagType, tagName, err := d.readTag()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return tagName, fmt.Errorf("nbt: %w", err)
|
return tagName, fmt.Errorf("nbt: %w", err)
|
||||||
@ -246,7 +246,7 @@ func (d *Decoder) unmarshal(val reflect.Value, tagType byte) error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
vt := val.Type() //receiver must be []int or []int32
|
vt := val.Type() // receiver must be []int or []int32
|
||||||
if vt.Kind() == reflect.Interface {
|
if vt.Kind() == reflect.Interface {
|
||||||
vt = reflect.TypeOf([]int32{}) // pass
|
vt = reflect.TypeOf([]int32{}) // pass
|
||||||
} else if vt.Kind() == reflect.Array && vt.Len() != int(aryLen) {
|
} else if vt.Kind() == reflect.Array && vt.Len() != int(aryLen) {
|
||||||
@ -277,7 +277,7 @@ func (d *Decoder) unmarshal(val reflect.Value, tagType byte) error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
vt := val.Type() //receiver must be []int or []int64
|
vt := val.Type() // receiver must be []int or []int64
|
||||||
if vt.Kind() == reflect.Interface {
|
if vt.Kind() == reflect.Interface {
|
||||||
vt = reflect.TypeOf([]int64{}) // pass
|
vt = reflect.TypeOf([]int64{}) // pass
|
||||||
} else if vt.Kind() != reflect.Slice {
|
} else if vt.Kind() != reflect.Slice {
|
||||||
@ -591,7 +591,7 @@ func (d *Decoder) readTag() (tagType byte, tagName string, err error) {
|
|||||||
c := d.checkCompressed(tagType)
|
c := d.checkCompressed(tagType)
|
||||||
err = fmt.Errorf("nbt: unknown Tag %#02x, which seems like %s header and you should uncompress it first", tagType, c)
|
err = fmt.Errorf("nbt: unknown Tag %#02x, which seems like %s header and you should uncompress it first", tagType, c)
|
||||||
case TagEnd:
|
case TagEnd:
|
||||||
default: //Read Tag
|
default: // Read Tag
|
||||||
tagName, err = d.readString()
|
tagName, err = d.readString()
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
|
@ -11,12 +11,12 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func TestUnmarshal_string(t *testing.T) {
|
func TestUnmarshal_string(t *testing.T) {
|
||||||
var data = []byte{
|
data := []byte{
|
||||||
0x08, 0x00, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x00, 0x09,
|
0x08, 0x00, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x00, 0x09,
|
||||||
0x42, 0x61, 0x6e, 0x61, 0x6e, 0x72, 0x61, 0x6d, 0x61,
|
0x42, 0x61, 0x6e, 0x61, 0x6e, 0x72, 0x61, 0x6d, 0x61,
|
||||||
}
|
}
|
||||||
|
|
||||||
//Unmarshal to string
|
// Unmarshal to string
|
||||||
var Name string
|
var Name string
|
||||||
if err := Unmarshal(data, &Name); err != nil {
|
if err := Unmarshal(data, &Name); err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
@ -26,7 +26,7 @@ func TestUnmarshal_string(t *testing.T) {
|
|||||||
t.Errorf("Unmarshal NBT fail: get %q, want %q", Name, "Bananrama")
|
t.Errorf("Unmarshal NBT fail: get %q, want %q", Name, "Bananrama")
|
||||||
}
|
}
|
||||||
|
|
||||||
//Unmarshal to interface{}
|
// Unmarshal to interface{}
|
||||||
var infName interface{}
|
var infName interface{}
|
||||||
if err := Unmarshal(data, &infName); err != nil {
|
if err := Unmarshal(data, &infName); err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
@ -38,7 +38,7 @@ func TestUnmarshal_string(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestUnmarshal_simple(t *testing.T) {
|
func TestUnmarshal_simple(t *testing.T) {
|
||||||
var data = []byte{
|
data := []byte{
|
||||||
0x0a, 0x00, 0x0b, 0x68, 0x65, 0x6c, 0x6c, 0x6f,
|
0x0a, 0x00, 0x0b, 0x68, 0x65, 0x6c, 0x6c, 0x6f,
|
||||||
0x20, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x08, 0x00,
|
0x20, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x08, 0x00,
|
||||||
0x04, 0x6e, 0x61, 0x6d, 0x65, 0x00, 0x09, 0x42,
|
0x04, 0x6e, 0x61, 0x6d, 0x65, 0x00, 0x09, 0x42,
|
||||||
@ -46,7 +46,7 @@ func TestUnmarshal_simple(t *testing.T) {
|
|||||||
0x00,
|
0x00,
|
||||||
}
|
}
|
||||||
|
|
||||||
//test parse
|
// test parse
|
||||||
var value struct {
|
var value struct {
|
||||||
Name string `nbt:"name"`
|
Name string `nbt:"name"`
|
||||||
}
|
}
|
||||||
@ -57,7 +57,7 @@ func TestUnmarshal_simple(t *testing.T) {
|
|||||||
t.Errorf("Unmarshal NBT fail: get %q, want %q", value.Name, "Bananrama")
|
t.Errorf("Unmarshal NBT fail: get %q, want %q", value.Name, "Bananrama")
|
||||||
}
|
}
|
||||||
|
|
||||||
//test rawRead
|
// test rawRead
|
||||||
var empty struct{}
|
var empty struct{}
|
||||||
if err := Unmarshal(data, &empty); err != nil {
|
if err := Unmarshal(data, &empty); err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
@ -184,7 +184,7 @@ func MakeBigTestStruct() BigTestStruct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestDecoder_Decode_bigTest(t *testing.T) {
|
func TestDecoder_Decode_bigTest(t *testing.T) {
|
||||||
//test parse
|
// test parse
|
||||||
var value BigTestStruct
|
var value BigTestStruct
|
||||||
r, err := gzip.NewReader(bytes.NewReader(bigTestData[:]))
|
r, err := gzip.NewReader(bytes.NewReader(bigTestData[:]))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -199,7 +199,7 @@ func TestDecoder_Decode_bigTest(t *testing.T) {
|
|||||||
t.Errorf("parse fail, expect %v, get %v", want, value)
|
t.Errorf("parse fail, expect %v, get %v", want, value)
|
||||||
}
|
}
|
||||||
|
|
||||||
//test rawRead
|
// test rawRead
|
||||||
var empty struct{}
|
var empty struct{}
|
||||||
r, err = gzip.NewReader(bytes.NewReader(bigTestData[:]))
|
r, err = gzip.NewReader(bytes.NewReader(bigTestData[:]))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -345,7 +345,7 @@ func TestDecoder_Decode_ByteArray(t *testing.T) {
|
|||||||
want = []byte{0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07}
|
want = []byte{0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07}
|
||||||
)
|
)
|
||||||
|
|
||||||
//Unmarshal to []byte
|
// Unmarshal to []byte
|
||||||
if err := Unmarshal(data, &value); err != nil {
|
if err := Unmarshal(data, &value); err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
@ -354,7 +354,7 @@ func TestDecoder_Decode_ByteArray(t *testing.T) {
|
|||||||
}
|
}
|
||||||
// t.Log(value)
|
// t.Log(value)
|
||||||
|
|
||||||
//Unmarshal to interface{}
|
// Unmarshal to interface{}
|
||||||
if err := Unmarshal(data, &infValue); err != nil {
|
if err := Unmarshal(data, &infValue); err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
@ -377,7 +377,7 @@ func TestDecoder_Decode_bool(t *testing.T) {
|
|||||||
}
|
}
|
||||||
var value bool
|
var value bool
|
||||||
for i, v := range data {
|
for i, v := range data {
|
||||||
//Unmarshal to []byte
|
// Unmarshal to []byte
|
||||||
if err := Unmarshal(v, &value); err != nil {
|
if err := Unmarshal(v, &value); err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
@ -388,12 +388,12 @@ func TestDecoder_Decode_bool(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestDecoder_Decode_ErrorString(t *testing.T) {
|
func TestDecoder_Decode_ErrorString(t *testing.T) {
|
||||||
var data = []byte{
|
data := []byte{
|
||||||
0x08, 0x00, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0xFF, 0xFE,
|
0x08, 0x00, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0xFF, 0xFE,
|
||||||
0x42, 0x61, 0x6e, 0x61, 0x6e, 0x72, 0x61, 0x6d, 0x61,
|
0x42, 0x61, 0x6e, 0x61, 0x6e, 0x72, 0x61, 0x6d, 0x61,
|
||||||
}
|
}
|
||||||
|
|
||||||
//Unmarshal to string
|
// Unmarshal to string
|
||||||
var Name string
|
var Name string
|
||||||
err := Unmarshal(data, &Name)
|
err := Unmarshal(data, &Name)
|
||||||
|
|
||||||
@ -401,7 +401,6 @@ func TestDecoder_Decode_ErrorString(t *testing.T) {
|
|||||||
t.Error("should return a error if len < 0")
|
t.Error("should return a error if len < 0")
|
||||||
}
|
}
|
||||||
t.Log(err)
|
t.Log(err)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type TextBool bool
|
type TextBool bool
|
||||||
@ -409,6 +408,7 @@ type TextBool bool
|
|||||||
func (b TextBool) MarshalText() (text []byte, err error) {
|
func (b TextBool) MarshalText() (text []byte, err error) {
|
||||||
return []byte(strconv.FormatBool(bool(b))), nil
|
return []byte(strconv.FormatBool(bool(b))), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *TextBool) UnmarshalText(text []byte) (err error) {
|
func (b *TextBool) UnmarshalText(text []byte) (err error) {
|
||||||
*((*bool)(b)), err = strconv.ParseBool(string(text))
|
*((*bool)(b)), err = strconv.ParseBool(string(text))
|
||||||
return
|
return
|
||||||
|
@ -390,7 +390,8 @@ func (e *Encoder) writeInt32(n int32) error {
|
|||||||
func (e *Encoder) writeInt64(n int64) error {
|
func (e *Encoder) writeInt64(n int64) error {
|
||||||
_, err := e.w.Write([]byte{
|
_, err := e.w.Write([]byte{
|
||||||
byte(n >> 56), byte(n >> 48), byte(n >> 40), byte(n >> 32),
|
byte(n >> 56), byte(n >> 48), byte(n >> 40), byte(n >> 32),
|
||||||
byte(n >> 24), byte(n >> 16), byte(n >> 8), byte(n)})
|
byte(n >> 24), byte(n >> 16), byte(n >> 8), byte(n),
|
||||||
|
})
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -12,7 +12,8 @@ import (
|
|||||||
func TestEncoder_Encode_intArray(t *testing.T) {
|
func TestEncoder_Encode_intArray(t *testing.T) {
|
||||||
// Test marshal pure Int array
|
// Test marshal pure Int array
|
||||||
v := []int32{0, -10, 3}
|
v := []int32{0, -10, 3}
|
||||||
out := []byte{TagIntArray, 0x00, 0x00, 0, 0, 0, 3,
|
out := []byte{
|
||||||
|
TagIntArray, 0x00, 0x00, 0, 0, 0, 3,
|
||||||
0x00, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00,
|
||||||
0xff, 0xff, 0xff, 0xf6,
|
0xff, 0xff, 0xff, 0xf6,
|
||||||
0x00, 0x00, 0x00, 0x03,
|
0x00, 0x00, 0x00, 0x03,
|
||||||
@ -27,7 +28,8 @@ func TestEncoder_Encode_intArray(t *testing.T) {
|
|||||||
v2 := struct {
|
v2 := struct {
|
||||||
Ary []int32 `nbt:"ary"`
|
Ary []int32 `nbt:"ary"`
|
||||||
}{[]int32{0, -10, 3}}
|
}{[]int32{0, -10, 3}}
|
||||||
out = []byte{TagCompound, 0x00, 0x00,
|
out = []byte{
|
||||||
|
TagCompound, 0x00, 0x00,
|
||||||
TagIntArray, 0x00, 0x03, 'a', 'r', 'y', 0, 0, 0, 3,
|
TagIntArray, 0x00, 0x03, 'a', 'r', 'y', 0, 0, 0, 3,
|
||||||
0x00, 0x00, 0x00, 0x00, // 0
|
0x00, 0x00, 0x00, 0x00, // 0
|
||||||
0xff, 0xff, 0xff, 0xf6, // -10
|
0xff, 0xff, 0xff, 0xf6, // -10
|
||||||
@ -72,7 +74,8 @@ func TestEncoder_encodeBool(t *testing.T) {
|
|||||||
func TestEncoder_Encode_floatArray(t *testing.T) {
|
func TestEncoder_Encode_floatArray(t *testing.T) {
|
||||||
// Test marshal pure Int array
|
// Test marshal pure Int array
|
||||||
v := []float32{0.3, -100, float32(math.NaN())}
|
v := []float32{0.3, -100, float32(math.NaN())}
|
||||||
out := []byte{TagList, 0x00, 0x00, TagFloat, 0, 0, 0, 3,
|
out := []byte{
|
||||||
|
TagList, 0x00, 0x00, TagFloat, 0, 0, 0, 3,
|
||||||
0x3e, 0x99, 0x99, 0x9a, // 0.3
|
0x3e, 0x99, 0x99, 0x9a, // 0.3
|
||||||
0xc2, 0xc8, 0x00, 0x00, // -100
|
0xc2, 0xc8, 0x00, 0x00, // -100
|
||||||
0x7f, 0xc0, 0x00, 0x00, // NaN
|
0x7f, 0xc0, 0x00, 0x00, // NaN
|
||||||
@ -86,8 +89,10 @@ func TestEncoder_Encode_floatArray(t *testing.T) {
|
|||||||
|
|
||||||
func TestEncoder_Encode_string(t *testing.T) {
|
func TestEncoder_Encode_string(t *testing.T) {
|
||||||
v := "Test"
|
v := "Test"
|
||||||
out := []byte{TagString, 0x00, 0x00, 0, 4,
|
out := []byte{
|
||||||
'T', 'e', 's', 't'}
|
TagString, 0x00, 0x00, 0, 4,
|
||||||
|
'T', 'e', 's', 't',
|
||||||
|
}
|
||||||
|
|
||||||
if data, err := Marshal(v); err != nil {
|
if data, err := Marshal(v); err != nil {
|
||||||
t.Error(err)
|
t.Error(err)
|
||||||
|
@ -62,7 +62,7 @@ func ExampleDecoder_Decode_singleTagString() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func ExampleEncoder_Encode_tagCompound() {
|
func ExampleEncoder_Encode_tagCompound() {
|
||||||
var value = struct {
|
value := struct {
|
||||||
Name string `nbt:"name"`
|
Name string `nbt:"name"`
|
||||||
}{"Tnze"}
|
}{"Tnze"}
|
||||||
|
|
||||||
|
@ -398,7 +398,7 @@ func (d *decodeState) scanNext() {
|
|||||||
d.opcode = d.scan.step(&d.scan, d.data[d.off])
|
d.opcode = d.scan.step(&d.scan, d.data[d.off])
|
||||||
d.off++
|
d.off++
|
||||||
} else {
|
} else {
|
||||||
//d.opcode = d.scan.eof()
|
// d.opcode = d.scan.eof()
|
||||||
d.off = len(d.data) + 1 // mark processed EOF with len+1
|
d.off = len(d.data) + 1 // mark processed EOF with len+1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,7 +6,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func TestSNBT_checkScanCode(t *testing.T) {
|
func TestSNBT_checkScanCode(t *testing.T) {
|
||||||
//t.SkipNow()
|
// t.SkipNow()
|
||||||
var s scanner
|
var s scanner
|
||||||
s.reset()
|
s.reset()
|
||||||
for _, c := range []byte(`{b:[vanilla],c:0D}`) {
|
for _, c := range []byte(`{b:[vanilla],c:0D}`) {
|
||||||
@ -66,6 +66,7 @@ func TestSNBT_compound(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestSNBT_list(t *testing.T) {
|
func TestSNBT_list(t *testing.T) {
|
||||||
goods := []string{
|
goods := []string{
|
||||||
`[]`, `[a, 'b', "c", d]`, // List of string
|
`[]`, `[a, 'b', "c", d]`, // List of string
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
//From https://play.golang.org/p/LTbId4b6M2
|
// Package CFB8 is copied from https://play.golang.org/p/LTbId4b6M2
|
||||||
|
|
||||||
package CFB8
|
package CFB8
|
||||||
|
|
||||||
import "crypto/cipher"
|
import "crypto/cipher"
|
||||||
|
@ -213,8 +213,8 @@ func (c *Conn) WritePacket(p pk.Packet) error {
|
|||||||
|
|
||||||
// SetCipher load the decode/encode stream to this Conn
|
// SetCipher load the decode/encode stream to this Conn
|
||||||
func (c *Conn) SetCipher(ecoStream, decoStream cipher.Stream) {
|
func (c *Conn) SetCipher(ecoStream, decoStream cipher.Stream) {
|
||||||
//加密连接
|
// 加密连接
|
||||||
c.Reader = cipher.StreamReader{ //Set receiver for AES
|
c.Reader = cipher.StreamReader{ // Set receiver for AES
|
||||||
S: decoStream,
|
S: decoStream,
|
||||||
R: c.Socket,
|
R: c.Socket,
|
||||||
}
|
}
|
||||||
|
@ -37,6 +37,7 @@ func TestVarInt_WriteTo(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestVarInt_ReadFrom(t *testing.T) {
|
func TestVarInt_ReadFrom(t *testing.T) {
|
||||||
for i, v := range PackedVarInts {
|
for i, v := range PackedVarInts {
|
||||||
var vi pk.VarInt
|
var vi pk.VarInt
|
||||||
@ -51,7 +52,7 @@ func TestVarInt_ReadFrom(t *testing.T) {
|
|||||||
|
|
||||||
func TestVarInt_ReadFrom_tooLongData(t *testing.T) {
|
func TestVarInt_ReadFrom_tooLongData(t *testing.T) {
|
||||||
var vi pk.VarInt
|
var vi pk.VarInt
|
||||||
var data = []byte{0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x01}
|
data := []byte{0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x01}
|
||||||
if _, err := vi.ReadFrom(bytes.NewReader(data)); err != nil {
|
if _, err := vi.ReadFrom(bytes.NewReader(data)); err != nil {
|
||||||
t.Logf("unpack \"% x\" error: %v", data, err)
|
t.Logf("unpack \"% x\" error: %v", data, err)
|
||||||
} else {
|
} else {
|
||||||
@ -87,6 +88,7 @@ func TestVarLong_WriteTo(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestVarLong_ReadFrom(t *testing.T) {
|
func TestVarLong_ReadFrom(t *testing.T) {
|
||||||
for i, v := range PackedVarLongs {
|
for i, v := range PackedVarLongs {
|
||||||
var vi pk.VarLong
|
var vi pk.VarLong
|
||||||
|
@ -3,10 +3,11 @@ package packet
|
|||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"errors"
|
"errors"
|
||||||
"github.com/google/uuid"
|
|
||||||
"io"
|
"io"
|
||||||
"math"
|
"math"
|
||||||
|
|
||||||
|
"github.com/google/uuid"
|
||||||
|
|
||||||
"github.com/Tnze/go-mc/nbt"
|
"github.com/Tnze/go-mc/nbt"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -23,62 +24,64 @@ type FieldEncoder io.WriterTo
|
|||||||
type FieldDecoder io.ReaderFrom
|
type FieldDecoder io.ReaderFrom
|
||||||
|
|
||||||
type (
|
type (
|
||||||
//Boolean of True is encoded as 0x01, false as 0x00.
|
// Boolean of True is encoded as 0x01, false as 0x00.
|
||||||
Boolean bool
|
Boolean bool
|
||||||
//Byte is signed 8-bit integer, two's complement
|
// Byte is signed 8-bit integer, two's complement
|
||||||
Byte int8
|
Byte int8
|
||||||
//UnsignedByte is unsigned 8-bit integer
|
// UnsignedByte is unsigned 8-bit integer
|
||||||
UnsignedByte uint8
|
UnsignedByte uint8
|
||||||
//Short is signed 16-bit integer, two's complement
|
// Short is signed 16-bit integer, two's complement
|
||||||
Short int16
|
Short int16
|
||||||
//UnsignedShort is unsigned 16-bit integer
|
// UnsignedShort is unsigned 16-bit integer
|
||||||
UnsignedShort uint16
|
UnsignedShort uint16
|
||||||
//Int is signed 32-bit integer, two's complement
|
// Int is signed 32-bit integer, two's complement
|
||||||
Int int32
|
Int int32
|
||||||
//Long is signed 64-bit integer, two's complement
|
// Long is signed 64-bit integer, two's complement
|
||||||
Long int64
|
Long int64
|
||||||
//A Float is a single-precision 32-bit IEEE 754 floating point number
|
// A Float is a single-precision 32-bit IEEE 754 floating point number
|
||||||
Float float32
|
Float float32
|
||||||
//A Double is a double-precision 64-bit IEEE 754 floating point number
|
// A Double is a double-precision 64-bit IEEE 754 floating point number
|
||||||
Double float64
|
Double float64
|
||||||
//String is sequence of Unicode scalar values
|
// String is sequence of Unicode scalar values
|
||||||
String string
|
String string
|
||||||
|
|
||||||
//Chat is encoded as a String with max length of 32767.
|
// Chat is encoded as a String with max length of 32767.
|
||||||
// Deprecated: Use chat.Message
|
// Deprecated: Use chat.Message
|
||||||
Chat = String
|
Chat = String
|
||||||
|
|
||||||
//Identifier is encoded as a String with max length of 32767.
|
// Identifier is encoded as a String with max length of 32767.
|
||||||
Identifier = String
|
Identifier = String
|
||||||
|
|
||||||
//VarInt is variable-length data encoding a two's complement signed 32-bit integer
|
// VarInt is variable-length data encoding a two's complement signed 32-bit integer
|
||||||
VarInt int32
|
VarInt int32
|
||||||
//VarLong is variable-length data encoding a two's complement signed 64-bit integer
|
// VarLong is variable-length data encoding a two's complement signed 64-bit integer
|
||||||
VarLong int64
|
VarLong int64
|
||||||
|
|
||||||
//Position x as a 26-bit integer, followed by y as a 12-bit integer, followed by z as a 26-bit integer (all signed, two's complement)
|
// Position x as a 26-bit integer, followed by y as a 12-bit integer, followed by z as a 26-bit integer (all signed, two's complement)
|
||||||
Position struct {
|
Position struct {
|
||||||
X, Y, Z int
|
X, Y, Z int
|
||||||
}
|
}
|
||||||
|
|
||||||
//Angle is rotation angle in steps of 1/256 of a full turn
|
// Angle is rotation angle in steps of 1/256 of a full turn
|
||||||
Angle Byte
|
Angle Byte
|
||||||
|
|
||||||
//UUID encoded as an unsigned 128-bit integer
|
// UUID encoded as an unsigned 128-bit integer
|
||||||
UUID uuid.UUID
|
UUID uuid.UUID
|
||||||
|
|
||||||
//ByteArray is []byte with prefix VarInt as length
|
// ByteArray is []byte with prefix VarInt as length
|
||||||
ByteArray []byte
|
ByteArray []byte
|
||||||
|
|
||||||
//PluginMessageData is only used in LoginPlugin,and it will read all left bytes
|
// PluginMessageData is only used in LoginPlugin,and it will read all left bytes
|
||||||
PluginMessageData []byte
|
PluginMessageData []byte
|
||||||
|
|
||||||
//BitSet represents Java's BitSet, a list of bits.
|
// BitSet represents Java's BitSet, a list of bits.
|
||||||
BitSet []int64
|
BitSet []int64
|
||||||
)
|
)
|
||||||
|
|
||||||
const MaxVarIntLen = 5
|
const (
|
||||||
const MaxVarLongLen = 10
|
MaxVarIntLen = 5
|
||||||
|
MaxVarLongLen = 10
|
||||||
|
)
|
||||||
|
|
||||||
func (b Boolean) WriteTo(w io.Writer) (int64, error) {
|
func (b Boolean) WriteTo(w io.Writer) (int64, error) {
|
||||||
var v byte
|
var v byte
|
||||||
@ -112,7 +115,7 @@ func (s String) WriteTo(w io.Writer) (int64, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *String) ReadFrom(r io.Reader) (n int64, err error) {
|
func (s *String) ReadFrom(r io.Reader) (n int64, err error) {
|
||||||
var l VarInt //String length
|
var l VarInt // String length
|
||||||
|
|
||||||
nn, err := l.ReadFrom(r)
|
nn, err := l.ReadFrom(r)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -245,7 +248,7 @@ func (l *Long) ReadFrom(r io.Reader) (n int64, err error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (v VarInt) WriteTo(w io.Writer) (n int64, err error) {
|
func (v VarInt) WriteTo(w io.Writer) (n int64, err error) {
|
||||||
var vi = make([]byte, 0, MaxVarIntLen)
|
vi := make([]byte, 0, MaxVarIntLen)
|
||||||
num := uint32(v)
|
num := uint32(v)
|
||||||
for {
|
for {
|
||||||
b := num & 0x7F
|
b := num & 0x7F
|
||||||
@ -282,7 +285,7 @@ func (v *VarInt) ReadFrom(r io.Reader) (n int64, err error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (v VarLong) WriteTo(w io.Writer) (n int64, err error) {
|
func (v VarLong) WriteTo(w io.Writer) (n int64, err error) {
|
||||||
var vi = make([]byte, 0, MaxVarLongLen)
|
vi := make([]byte, 0, MaxVarLongLen)
|
||||||
num := uint64(v)
|
num := uint64(v)
|
||||||
for {
|
for {
|
||||||
b := num & 0x7F
|
b := num & 0x7F
|
||||||
@ -340,7 +343,7 @@ func (p *Position) ReadFrom(r io.Reader) (n int64, err error) {
|
|||||||
y := int(v & 0xFFF)
|
y := int(v & 0xFFF)
|
||||||
z := int(v << 26 >> 38)
|
z := int(v << 26 >> 38)
|
||||||
|
|
||||||
//处理负数
|
// 处理负数
|
||||||
if x >= 1<<25 {
|
if x >= 1<<25 {
|
||||||
x -= 1 << 26
|
x -= 1 << 26
|
||||||
}
|
}
|
||||||
|
@ -3,8 +3,9 @@ package packet_test
|
|||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"fmt"
|
"fmt"
|
||||||
pk "github.com/Tnze/go-mc/net/packet"
|
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
pk "github.com/Tnze/go-mc/net/packet"
|
||||||
)
|
)
|
||||||
|
|
||||||
func ExampleAry_WriteTo() {
|
func ExampleAry_WriteTo() {
|
||||||
@ -34,12 +35,12 @@ func ExampleAry_ReadFrom() {
|
|||||||
|
|
||||||
func TestAry_ReadFrom(t *testing.T) {
|
func TestAry_ReadFrom(t *testing.T) {
|
||||||
var ary []pk.String
|
var ary []pk.String
|
||||||
var bin = []byte{
|
bin := []byte{
|
||||||
0, 0, 0, 2,
|
0, 0, 0, 2,
|
||||||
4, 'T', 'n', 'z', 'e',
|
4, 'T', 'n', 'z', 'e',
|
||||||
0,
|
0,
|
||||||
}
|
}
|
||||||
var data = pk.Ary[pk.Int]{Ary: &ary}
|
data := pk.Ary[pk.Int]{Ary: &ary}
|
||||||
if _, err := data.ReadFrom(bytes.NewReader(bin)); err != nil {
|
if _, err := data.ReadFrom(bytes.NewReader(bin)); err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
24
net/rcon.go
24
net/rcon.go
@ -24,14 +24,14 @@ func DialRCON(addr string, password string) (client RCONClientConn, err error) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
//Login
|
// Login
|
||||||
err = c.WritePacket(c.ReqID, 3, password)
|
err = c.WritePacket(c.ReqID, 3, password)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
err = fmt.Errorf("login fail: %v", err)
|
err = fmt.Errorf("login fail: %v", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
//Login resp
|
// Login resp
|
||||||
r, _, _, err := c.ReadPacket()
|
r, _, _, err := c.ReadPacket()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
err = fmt.Errorf("read login resp fail: %v", err)
|
err = fmt.Errorf("read login resp fail: %v", err)
|
||||||
@ -55,7 +55,7 @@ type RCONConn struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (r *RCONConn) ReadPacket() (RequestID, Type int32, Payload string, err error) {
|
func (r *RCONConn) ReadPacket() (RequestID, Type int32, Payload string, err error) {
|
||||||
//read packet length
|
// read packet length
|
||||||
var Length int32
|
var Length int32
|
||||||
err = binary.Read(r, binary.LittleEndian, &Length)
|
err = binary.Read(r, binary.LittleEndian, &Length)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -63,7 +63,7 @@ func (r *RCONConn) ReadPacket() (RequestID, Type int32, Payload string, err erro
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
//check length
|
// check length
|
||||||
if Length < 4+4+0+2 {
|
if Length < 4+4+0+2 {
|
||||||
err = errors.New("packet too short")
|
err = errors.New("packet too short")
|
||||||
return
|
return
|
||||||
@ -73,7 +73,7 @@ func (r *RCONConn) ReadPacket() (RequestID, Type int32, Payload string, err erro
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
//read packet data
|
// read packet data
|
||||||
buf := make([]byte, Length)
|
buf := make([]byte, Length)
|
||||||
err = binary.Read(r, binary.LittleEndian, &buf)
|
err = binary.Read(r, binary.LittleEndian, &buf)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -91,11 +91,11 @@ func (r *RCONConn) WritePacket(RequestID, Type int32, Payload string) error {
|
|||||||
buf := new(bytes.Buffer)
|
buf := new(bytes.Buffer)
|
||||||
|
|
||||||
for _, v := range []interface{}{
|
for _, v := range []interface{}{
|
||||||
int32(4 + 4 + len(Payload) + 2), //Length
|
int32(4 + 4 + len(Payload) + 2), // Length
|
||||||
RequestID, //Request ID
|
RequestID, // Request ID
|
||||||
Type, //Type
|
Type, // Type
|
||||||
[]byte(Payload), //Payload
|
[]byte(Payload), // Payload
|
||||||
[]byte{0, 0}, //pad
|
[]byte{0, 0}, // pad
|
||||||
} {
|
} {
|
||||||
err := binary.Write(buf, binary.LittleEndian, v)
|
err := binary.Write(buf, binary.LittleEndian, v)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -136,7 +136,7 @@ func (r *RCONConn) AcceptLogin(password string) error {
|
|||||||
|
|
||||||
r.ReqID = R
|
r.ReqID = R
|
||||||
|
|
||||||
//Check packet type
|
// Check packet type
|
||||||
if T != 3 {
|
if T != 3 {
|
||||||
return fmt.Errorf("not a login packet: %d", T)
|
return fmt.Errorf("not a login packet: %d", T)
|
||||||
}
|
}
|
||||||
@ -165,7 +165,7 @@ func (r *RCONConn) AcceptCmd() (string, error) {
|
|||||||
|
|
||||||
r.ReqID = R
|
r.ReqID = R
|
||||||
|
|
||||||
//Check packet type
|
// Check packet type
|
||||||
if T != 2 {
|
if T != 2 {
|
||||||
return P, fmt.Errorf("not a command packet: %d", T)
|
return P, fmt.Errorf("not a command packet: %d", T)
|
||||||
}
|
}
|
||||||
|
@ -2,12 +2,13 @@ package offline
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"crypto/md5"
|
"crypto/md5"
|
||||||
|
|
||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
)
|
)
|
||||||
|
|
||||||
// NameToUUID return the UUID from player name in offline mode
|
// NameToUUID return the UUID from player name in offline mode
|
||||||
func NameToUUID(name string) uuid.UUID {
|
func NameToUUID(name string) uuid.UUID {
|
||||||
var version = 3
|
version := 3
|
||||||
h := md5.New()
|
h := md5.New()
|
||||||
h.Write([]byte("OfflinePlayer:"))
|
h.Write([]byte("OfflinePlayer:"))
|
||||||
h.Write([]byte(name))
|
h.Write([]byte(name))
|
||||||
|
@ -23,7 +23,7 @@ type Server struct {
|
|||||||
MiniGameID *int
|
MiniGameID *int
|
||||||
MinigameImage *string
|
MinigameImage *string
|
||||||
ActiveSlot int
|
ActiveSlot int
|
||||||
//Slots interface{}
|
// Slots interface{}
|
||||||
Member bool
|
Member bool
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -49,7 +49,7 @@ func (r *Realms) Worlds() ([]Server, error) {
|
|||||||
// Server returns a single server listing about a server.
|
// Server returns a single server listing about a server.
|
||||||
// you must be the owner of the server.
|
// you must be the owner of the server.
|
||||||
func (r *Realms) Server(ID int) (s Server, err error) {
|
func (r *Realms) Server(ID int) (s Server, err error) {
|
||||||
var resp = struct {
|
resp := struct {
|
||||||
*Server
|
*Server
|
||||||
*Error
|
*Error
|
||||||
}{Server: &s}
|
}{Server: &s}
|
||||||
@ -124,7 +124,7 @@ func (r *Realms) Ops(s Server) (ops []string, err error) {
|
|||||||
|
|
||||||
// SubscriptionLife returns the current life of a server subscription.
|
// SubscriptionLife returns the current life of a server subscription.
|
||||||
func (r *Realms) SubscriptionLife(s Server) (startDate int64, daysLeft int, Type string, err error) {
|
func (r *Realms) SubscriptionLife(s Server) (startDate int64, daysLeft int, Type string, err error) {
|
||||||
var resp = struct {
|
resp := struct {
|
||||||
StartDate *int64
|
StartDate *int64
|
||||||
DaysLeft *int
|
DaysLeft *int
|
||||||
SubscriptionType *string
|
SubscriptionType *string
|
||||||
|
@ -1,8 +1,9 @@
|
|||||||
package save
|
package save
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/Tnze/go-mc/nbt"
|
|
||||||
"io"
|
"io"
|
||||||
|
|
||||||
|
"github.com/Tnze/go-mc/nbt"
|
||||||
)
|
)
|
||||||
|
|
||||||
type PlayerData struct {
|
type PlayerData struct {
|
||||||
|
@ -37,7 +37,7 @@ func At(cx, cz int) (int, int) {
|
|||||||
// Open a .mca file and read the head.
|
// Open a .mca file and read the head.
|
||||||
// Close the Region after used.
|
// Close the Region after used.
|
||||||
func Open(name string) (r *Region, err error) {
|
func Open(name string) (r *Region, err error) {
|
||||||
f, err := os.OpenFile(name, os.O_RDWR, 0666)
|
f, err := os.OpenFile(name, os.O_RDWR, 0o666)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -85,7 +85,7 @@ func Load(f io.ReadWriteSeeker) (r *Region, err error) {
|
|||||||
|
|
||||||
// Create open .mca file with os.O_CREATE|os. O_EXCL, and init the region
|
// Create open .mca file with os.O_CREATE|os. O_EXCL, and init the region
|
||||||
func Create(name string) (*Region, error) {
|
func Create(name string) (*Region, error) {
|
||||||
f, err := os.OpenFile(name, os.O_CREATE|os.O_RDWR|os.O_EXCL, 0666)
|
f, err := os.OpenFile(name, os.O_CREATE|os.O_RDWR|os.O_EXCL, 0o666)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -206,13 +206,13 @@ func (r *Region) WriteSector(x, z int, data []byte) error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
//data length
|
// data length
|
||||||
err = binary.Write(r.f, binary.BigEndian, int32(len(data)))
|
err = binary.Write(r.f, binary.BigEndian, int32(len(data)))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
//data
|
// data
|
||||||
_, err = r.f.Write(data)
|
_, err = r.f.Write(data)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -48,10 +48,9 @@ func TestReadRegion(t *testing.T) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
t.Error(err)
|
t.Error(err)
|
||||||
}
|
}
|
||||||
//t.Log(b)
|
// t.Log(b)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestFindSpace(t *testing.T) {
|
func TestFindSpace(t *testing.T) {
|
||||||
|
@ -28,7 +28,7 @@ const verifyTokenLen = 16
|
|||||||
|
|
||||||
// Encrypt a connection, with authentication
|
// Encrypt a connection, with authentication
|
||||||
func Encrypt(conn *net.Conn, name string, profilePubKey *rsa.PublicKey) (*Resp, error) {
|
func Encrypt(conn *net.Conn, name string, profilePubKey *rsa.PublicKey) (*Resp, error) {
|
||||||
//generate keys
|
// generate keys
|
||||||
key, err := rsa.GenerateKey(rand.Reader, 1024)
|
key, err := rsa.GenerateKey(rand.Reader, 1024)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -39,30 +39,30 @@ func Encrypt(conn *net.Conn, name string, profilePubKey *rsa.PublicKey) (*Resp,
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
//encryption request
|
// encryption request
|
||||||
nonce, err := encryptionRequest(conn, publicKey)
|
nonce, err := encryptionRequest(conn, publicKey)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
//encryption response
|
// encryption response
|
||||||
SharedSecret, err := encryptionResponse(conn, profilePubKey, nonce, key)
|
SharedSecret, err := encryptionResponse(conn, profilePubKey, nonce, key)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
//encryption the connection
|
// encryption the connection
|
||||||
block, err := aes.NewCipher(SharedSecret)
|
block, err := aes.NewCipher(SharedSecret)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.New("load aes encryption key fail")
|
return nil, errors.New("load aes encryption key fail")
|
||||||
}
|
}
|
||||||
|
|
||||||
conn.SetCipher( //启用加密
|
conn.SetCipher( // 启用加密
|
||||||
CFB8.NewCFB8Encrypt(block, SharedSecret),
|
CFB8.NewCFB8Encrypt(block, SharedSecret),
|
||||||
CFB8.NewCFB8Decrypt(block, SharedSecret),
|
CFB8.NewCFB8Decrypt(block, SharedSecret),
|
||||||
)
|
)
|
||||||
hash := authDigest("", SharedSecret, publicKey)
|
hash := authDigest("", SharedSecret, publicKey)
|
||||||
resp, err := authentication(name, hash) //auth
|
resp, err := authentication(name, hash) // auth
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.New("auth servers down")
|
return nil, errors.New("auth servers down")
|
||||||
}
|
}
|
||||||
@ -136,7 +136,7 @@ func encryptionResponse(conn *net.Conn, profilePubKey *rsa.PublicKey, nonce []by
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//confirm to verify token
|
// confirm to verify token
|
||||||
SharedSecret, err := rsa.DecryptPKCS1v15(rand.Reader, key, ESharedSecret)
|
SharedSecret, err := rsa.DecryptPKCS1v15(rand.Reader, key, ESharedSecret)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -15,17 +15,17 @@ func TestResp(t *testing.T) {
|
|||||||
}
|
}
|
||||||
wantID := uuid.Must(uuid.Parse("853c80ef3c3749fdaa49938b674adae6"))
|
wantID := uuid.Must(uuid.Parse("853c80ef3c3749fdaa49938b674adae6"))
|
||||||
|
|
||||||
//check UUID
|
// check UUID
|
||||||
if resp.ID != wantID {
|
if resp.ID != wantID {
|
||||||
t.Errorf("uuid doesn't match: %v, want %s", resp.ID, wantID)
|
t.Errorf("uuid doesn't match: %v, want %s", resp.ID, wantID)
|
||||||
}
|
}
|
||||||
|
|
||||||
//check name
|
// check name
|
||||||
if resp.Name != "jeb_" {
|
if resp.Name != "jeb_" {
|
||||||
t.Errorf("name doesn't match: %s, want %s", resp.Name, "jeb_")
|
t.Errorf("name doesn't match: %s, want %s", resp.Name, "jeb_")
|
||||||
}
|
}
|
||||||
|
|
||||||
//check texture
|
// check texture
|
||||||
texture, err := resp.Texture()
|
texture, err := resp.Texture()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
|
@ -10,8 +10,10 @@ import (
|
|||||||
|
|
||||||
// Packet758 is a packet in protocol 757.
|
// Packet758 is a packet in protocol 757.
|
||||||
// We are using type system to force programmers to update packets.
|
// We are using type system to force programmers to update packets.
|
||||||
type Packet758 pk.Packet
|
type (
|
||||||
type Packet757 pk.Packet
|
Packet758 pk.Packet
|
||||||
|
Packet757 pk.Packet
|
||||||
|
)
|
||||||
|
|
||||||
type WritePacketError struct {
|
type WritePacketError struct {
|
||||||
Err error
|
Err error
|
||||||
|
@ -70,8 +70,10 @@ type Node struct {
|
|||||||
Parser Parser
|
Parser Parser
|
||||||
Run HandlerFunc
|
Run HandlerFunc
|
||||||
}
|
}
|
||||||
type Literal Node
|
type (
|
||||||
type Argument Node
|
Literal Node
|
||||||
|
Argument Node
|
||||||
|
)
|
||||||
|
|
||||||
func (n *Node) parse(cmd string) (left string, value ParsedData, err error) {
|
func (n *Node) parse(cmd string) (left string, value ParsedData, err error) {
|
||||||
switch n.kind & 0x03 {
|
switch n.kind & 0x03 {
|
||||||
|
@ -1,4 +1,6 @@
|
|||||||
package server
|
package server
|
||||||
|
|
||||||
type Pos struct{ X, Y, Z float64 }
|
type (
|
||||||
type Rot struct{ Yaw, Pitch float32 }
|
Pos struct{ X, Y, Z float64 }
|
||||||
|
Rot struct{ Yaw, Pitch float32 }
|
||||||
|
)
|
||||||
|
@ -3,6 +3,7 @@ package bvh
|
|||||||
import (
|
import (
|
||||||
"container/heap"
|
"container/heap"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"golang.org/x/exp/constraints"
|
"golang.org/x/exp/constraints"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -194,12 +195,14 @@ func TouchBound[B interface{ Touch(B) bool }](other B) func(bound B) bool {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
type searchHeap[I constraints.Float, V any] []searchItem[I, V]
|
type (
|
||||||
type searchItem[I constraints.Float, V any] struct {
|
searchHeap[I constraints.Float, V any] []searchItem[I, V]
|
||||||
pointer *V
|
searchItem[I constraints.Float, V any] struct {
|
||||||
parentTo **V
|
pointer *V
|
||||||
inheritedCost I
|
parentTo **V
|
||||||
}
|
inheritedCost I
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
func (h searchHeap[I, V]) Len() int { return len(h) }
|
func (h searchHeap[I, V]) Len() int { return len(h) }
|
||||||
func (h searchHeap[I, V]) Less(i, j int) bool { return h[i].inheritedCost < h[j].inheritedCost }
|
func (h searchHeap[I, V]) Less(i, j int) bool { return h[i].inheritedCost < h[j].inheritedCost }
|
||||||
|
@ -1,8 +1,9 @@
|
|||||||
package bvh
|
package bvh
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"golang.org/x/exp/constraints"
|
|
||||||
"math"
|
"math"
|
||||||
|
|
||||||
|
"golang.org/x/exp/constraints"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Vec2[I constraints.Signed | constraints.Float] [2]I
|
type Vec2[I constraints.Signed | constraints.Float] [2]I
|
||||||
@ -22,6 +23,7 @@ type Vec3[I constraints.Signed | constraints.Float] [3]I
|
|||||||
func (v Vec3[I]) Add(other Vec3[I]) Vec3[I] {
|
func (v Vec3[I]) Add(other Vec3[I]) Vec3[I] {
|
||||||
return Vec3[I]{v[0] + other[0], v[1] + other[1], v[2] + other[2]}
|
return Vec3[I]{v[0] + other[0], v[1] + other[1], v[2] + other[2]}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v Vec3[I]) Sub(other Vec3[I]) Vec3[I] {
|
func (v Vec3[I]) Sub(other Vec3[I]) Vec3[I] {
|
||||||
return Vec3[I]{v[0] - other[0], v[1] - other[1], v[2] - other[2]}
|
return Vec3[I]{v[0] - other[0], v[1] - other[1], v[2] - other[2]}
|
||||||
}
|
}
|
||||||
@ -29,6 +31,7 @@ func (v Vec3[I]) Mul(i I) Vec3[I] { return Vec3[I]{v[0] * i, v[1] * i, v[2] * i}
|
|||||||
func (v Vec3[I]) Max(other Vec3[I]) Vec3[I] {
|
func (v Vec3[I]) Max(other Vec3[I]) Vec3[I] {
|
||||||
return Vec3[I]{max(v[0], other[0]), max(v[1], other[1]), max(v[2], other[2])}
|
return Vec3[I]{max(v[0], other[0]), max(v[1], other[1]), max(v[2], other[2])}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v Vec3[I]) Min(other Vec3[I]) Vec3[I] {
|
func (v Vec3[I]) Min(other Vec3[I]) Vec3[I] {
|
||||||
return Vec3[I]{min(v[0], other[0]), min(v[1], other[1]), min(v[2], other[2])}
|
return Vec3[I]{min(v[0], other[0]), min(v[1], other[1]), min(v[2], other[2])}
|
||||||
}
|
}
|
||||||
|
@ -50,14 +50,14 @@ func (s *Server) acceptListPing(conn *net.Conn) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
switch p.ID {
|
switch p.ID {
|
||||||
case packetid.StatusResponse: //List
|
case packetid.StatusResponse: // List
|
||||||
var resp []byte
|
var resp []byte
|
||||||
resp, err = s.listResp()
|
resp, err = s.listResp()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
err = conn.WritePacket(pk.Marshal(0x00, pk.String(resp)))
|
err = conn.WritePacket(pk.Marshal(0x00, pk.String(resp)))
|
||||||
case packetid.StatusPongResponse: //Ping
|
case packetid.StatusPongResponse: // Ping
|
||||||
err = conn.WritePacket(p)
|
err = conn.WritePacket(p)
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -59,7 +59,7 @@ type authResp struct {
|
|||||||
type Profile struct {
|
type Profile struct {
|
||||||
ID string `json:"id"`
|
ID string `json:"id"`
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
//Legacy bool `json:"legacy"` // we don't care
|
// Legacy bool `json:"legacy"` // we don't care
|
||||||
}
|
}
|
||||||
|
|
||||||
// Authenticate authenticates a user using their password.
|
// Authenticate authenticates a user using their password.
|
||||||
@ -105,6 +105,7 @@ func (a *Access) AvailableProfiles() []Profile {
|
|||||||
func (a *Access) SetTokens(tokens Tokens) {
|
func (a *Access) SetTokens(tokens Tokens) {
|
||||||
a.ar.Tokens = tokens
|
a.ar.Tokens = tokens
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *Access) GetTokens() Tokens {
|
func (a *Access) GetTokens() Tokens {
|
||||||
return a.ar.Tokens
|
return a.ar.Tokens
|
||||||
}
|
}
|
||||||
|
@ -17,7 +17,7 @@ type refreshPayload struct {
|
|||||||
func (a *Access) Refresh(profile *Profile) error {
|
func (a *Access) Refresh(profile *Profile) error {
|
||||||
pl := refreshPayload{
|
pl := refreshPayload{
|
||||||
Tokens: a.ar.Tokens,
|
Tokens: a.ar.Tokens,
|
||||||
SelectedProfile: profile, //used to change profile, don't use now
|
SelectedProfile: profile, // used to change profile, don't use now
|
||||||
RequestUser: true,
|
RequestUser: true,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user