From d53f77dbaea27d5548455bd7710778c6a37e3334 Mon Sep 17 00:00:00 2001 From: Tnze Date: Sat, 8 Jun 2019 11:07:00 +0800 Subject: [PATCH] =?UTF-8?q?=E6=9B=B4=E6=96=B0=E4=BA=86=E5=87=A0=E4=B8=AAAP?= =?UTF-8?q?I?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- bot/ingame.go | 7 +-- bot/motion.go | 143 +++++++++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 138 insertions(+), 12 deletions(-) diff --git a/bot/ingame.go b/bot/ingame.go index 289563d..cab9ed9 100644 --- a/bot/ingame.go +++ b/bot/ingame.go @@ -358,9 +358,8 @@ func handleJoinGamePacket(c *Client, p pk.Packet) error { type pluginMessageData []byte //Encode a PluginMessageData -func (p *pluginMessageData) Encode(r io.Writer) error { - _, err := r.Write([]byte(*p)) - return err +func (p pluginMessageData) Encode() []byte { + return []byte(p) } //Decode a PluginMessageData @@ -491,8 +490,6 @@ func (b *blockEntities) Decode(r pk.DecodeReader) error { return nil } -// var isSpawn bool - func handlePlayerPositionAndLookPacket(c *Client, p pk.Packet) error { var ( x, y, z pk.Double diff --git a/bot/motion.go b/bot/motion.go index e8d8850..0a155aa 100644 --- a/bot/motion.go +++ b/bot/motion.go @@ -6,9 +6,9 @@ import ( pk "github.com/Tnze/go-mc/net/packet" ) -//SwingArm swing player's arm. -//hand could be one of 0: main hand, 1: off hand. -//It's just animation. +// SwingArm swing player's arm. +// hand could be one of 0: main hand, 1: off hand. +// It's just animation. func (c *Client) SwingArm(hand int) error { return c.conn.WritePacket(pk.Marshal( data.AnimationServerbound, @@ -16,7 +16,7 @@ func (c *Client) SwingArm(hand int) error { )) } -//Respawn the player when it was dead. +// Respawn the player when it was dead. func (c *Client) Respawn() error { return c.conn.WritePacket(pk.Marshal( data.ClientStatus, @@ -24,8 +24,8 @@ func (c *Client) Respawn() error { )) } -//UseItem use the item player handing. -//hand could be one of 0: main hand, 1: off hand +// UseItem use the item player handing. +// hand could be one of 0: main hand, 1: off hand func (c *Client) UseItem(hand int) error { return c.conn.WritePacket(pk.Marshal( data.UseItem, @@ -33,7 +33,43 @@ func (c *Client) UseItem(hand int) error { )) } -//Chat send chat as chat message or command at textbox. +// UseEntity used by player to right-clicks another entity. +// hand could be one of 0: main hand, 1: off hand. +// A Notchian server only accepts this packet if +// the entity being attacked/used is visible without obstruction +// and within a 4-unit radius of the player's position. +func (c *Client) UseEntity(entityID int32, hand int) error { + return c.conn.WritePacket(pk.Marshal( + data.UseEntity, + pk.VarInt(entityID), + pk.VarInt(0), + pk.VarInt(hand), + )) +} + +// AttackEntity used by player to left-clicks another entity. +// The attack version of UseEntity. Has the same limit. +func (c *Client) AttackEntity(entityID int32, hand int) error { + return c.conn.WritePacket(pk.Marshal( + data.UseEntity, + pk.VarInt(entityID), + pk.VarInt(1), + pk.VarInt(hand), + )) +} + +// UseEntityAt is a variety of UseEntity with target location +func (c *Client) UseEntityAt(entityID int32, x, y, z float32, hand int) error { + return c.conn.WritePacket(pk.Marshal( + data.UseEntity, + pk.VarInt(entityID), + pk.VarInt(2), + pk.Float(x), pk.Float(y), pk.Float(z), + pk.VarInt(hand), + )) +} + +// Chat send chat as chat message or command at textbox. func (c *Client) Chat(msg string) error { if len(msg) > 256 { return errors.New("message too long") @@ -44,3 +80,96 @@ func (c *Client) Chat(msg string) error { pk.String(msg), )) } + +// PluginMessage is used by mods and plugins to send their data. +func (c *Client) PluginMessage(channal string, msg []byte) error { + return c.conn.WritePacket(pk.Marshal( + data.PluginMessageServerbound, + pk.Identifier(channal), + pluginMessageData(msg), + )) +} + +// PlaceBlock is used to place a block. +// hand is the hand from which the block is placed; 0: main hand, 1: off hand. +// face is the face on which the block is placed. +// +// Cursor position is the position of the crosshair on the block: +// cursorX, from 0 to 1 increasing from west to east; +// cursorY, from 0 to 1 increasing from bottom to top; +// cursorZ, from 0 to 1 increasing from north to south. +// +// insideBlock is true when the player's head is inside of a block's collision. +func (c *Client) PlaceBlock(hand, locX, locY, locZ, face int, cursorX, cursorY, cursorZ float32, insideBlock bool) error { + return c.conn.WritePacket(pk.Marshal( + data.PlayerBlockPlacement, + pk.VarInt(hand), + pk.Position{locX, locY, locZ}, + pk.VarInt(face), + pk.Float(cursorX), pk.Float(cursorY), pk.Float(cursorZ), + pk.Boolean(insideBlock), + )) +} + +// ChangeHeldItem used to change the slot selection in hotbar. +func (c *Client) ChangeHeldItem(slot int) error { + if slot < 0 || slot > 8 { + return errors.New("invalid slot") + } + + return c.conn.WritePacket(pk.Marshal( + data.HeldItemChangeServerbound, + pk.Short(slot), + )) +} + +// PickItem used to swap out an empty space on the hotbar with the item in the given inventory slot. +// The Notchain client uses this for pick block functionality (middle click) to retrieve items from the inventory. +// +// The server will first search the player's hotbar for an empty slot, +// starting from the current slot and looping around to the slot before it. +// If there are no empty slots, it will start a second search from the +// current slot and find the first slot that does not contain an enchanted item. +// If there still are no slots that meet that criteria, then the server will +// use the currently selected slot. After finding the appropriate slot, +// the server swaps the items and then change player's selected slot (cause the HeldItemChange event). +func (c *Client) PickItem(slot int) error { + return c.conn.WritePacket(pk.Marshal( + data.PickItem, + pk.VarInt(slot), + )) +} + +func (c *Client) playerAction(status, locX, locY, locZ, face int) error { + return c.conn.WritePacket(pk.Marshal( + data.PlayerDigging, + pk.VarInt(status), + pk.Position{locX, locY, locZ}, + pk.VarInt(face), + )) +} + +// Dig used to start, end or cancel a digging +func (c *Client) Dig(status, locX, locY, locZ, face int) error { + return c.playerAction(status, locX, locY, locZ, face) +} + +// DropItemStack drop the entire selected stack +func (c *Client) DropItemStack() error { + return c.playerAction(3, 0, 0, 0, 0) +} + +// DropItem drop one item in selected stack +func (c *Client) DropItem() error { + return c.playerAction(4, 0, 0, 0, 0) +} + +// UseItemEnd used to finish UseItem, like eating food, pulling back bows +func (c *Client) UseItemEnd() error { + return c.playerAction(5, 0, 0, 0, 0) +} + +// SwapItem used to swap the items in hands +func (c *Client) SwapItem() error { + return c.playerAction(6, 0, 0, 0, 0) +}