From fb50b0d5cbe622e3d535b3a440ef5d6a65468cb5 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=D0=A0=D0=BE=D0=BC=D0=B0=20=D0=94=D0=B0=D0=BD=D0=B8=D0=BB?=
=?UTF-8?q?=D0=BE=D0=B2?= <35975332+Nekiplay@users.noreply.github.com>
Date: Sat, 4 Jul 2020 13:45:51 +0500
Subject: [PATCH] ChatBot API: OnScoreboardObjective, OnEntityEffect,
OnUpdateScore, EntityInteract, Hand list (#1097)
* Create Effect.cs
* Rename Effect.cs to Effects.cs
* Update MinecraftClient.csproj
* Update Effects.cs
* Update Effects.cs
* add EntityEffect
* Update McClient.cs
* Update Protocol18.cs + EntityEffect
* Update IMinecraftComHandler.cs
* Update Protocol18PacketTypes.cs + EntityEffect
* Update ChatBot.cs + OnEntityEquipment
* Update PacketIncomingType.cs + ScoreboardObjective
* Update Protocol18PacketTypes.cs
* Update Protocol18.cs
* Update IMinecraftComHandler.cs + OnScoreboardObjective
* Update McClient.cs + OnScoreboardObjective
* Update ChatBot.cs + OnScoreboardObjective event
* Update Protocol18.cs: fix scoreboard
* Update McClient.cs
* Update ChatBot.cs
* Update PacketIncomingType.cs
* Update ChatBot.cs + OnUpdateScore
* Update McClient.cs + OnUpdateScore
* Update IMinecraftComHandler.cs + OnUpdateScore
* Update Protocol18.cs
* Update Protocol18PacketTypes.cs
* Update Protocol18.cs + fix micro lags
* Update Protocol18.cs
* Update Protocol18.cs
* Update Protocol18.cs
* Update Protocol16.cs
* Update Protocol18.cs
* Update McClient.cs
* Update IMinecraftCom.cs
* Update McClient.cs
* Update McClient.cs
* Update McClient.cs
* Update ChatBot.cs + GetEntities()
* Create Hand.cs
* Update MinecraftClient.csproj
* Update McClient.cs
* Update ChatBot.cs
* Update Protocol18.cs
* Update ChatBot.cs
* Update ChatBot.cs
* Update ChatBot.cs
* Update ChatBot.cs
* Update ChatBot.cs: fix
* Update AutoAttack.cs: Fix
* Update McClient.cs: compile fix
* Update ChatBot.cs
* Update AutoAttack.cs
* Update ChatBot.cs
* Update Protocol18.cs
* Update IMinecraftComHandler.cs
* Update McClient.cs
* Update ChatBot.cs
* Update Protocol18.cs
* Update IMinecraftComHandler.cs
* Update ChatBot.cs
* Update McClient.cs
* Update McClient.cs: remove check distance
* Update EntityActionType.cs: more actions
* Create CommandBlockMode.cs
* Create CommandBlockFlags.cs
* Update IMinecraftCom.cs
* Update McClient.cs
* Update ChatBot.cs
* Update Protocol18.cs
* Update Protocol16.cs
* Update PacketOutgoingType.cs
* Update Protocol18PacketTypes.cs
* Update Protocol18.cs
---
MinecraftClient/ChatBot.cs | 140 ++++++++++++------
MinecraftClient/ChatBots/AutoAttack.cs | 2 +-
MinecraftClient/Inventory/Effects.cs | 47 ++++++
MinecraftClient/Inventory/Hand.cs | 11 ++
MinecraftClient/Mapping/CommandBlockFlags.cs | 18 +++
MinecraftClient/Mapping/CommandBlockMode.cs | 18 +++
MinecraftClient/McClient.cs | 82 +++++++++-
MinecraftClient/MinecraftClient.csproj | 4 +-
MinecraftClient/Protocol/EntityActionType.cs | 18 ++-
.../Protocol/Handlers/PacketIncomingType.cs | 5 +-
.../Protocol/Handlers/PacketOutgoingType.cs | 1 +
.../Protocol/Handlers/Protocol16.cs | 12 +-
.../Protocol/Handlers/Protocol18.cs | 111 ++++++++++++--
.../Handlers/Protocol18PacketTypes.cs | 32 ++++
MinecraftClient/Protocol/IMinecraftCom.cs | 18 +++
.../Protocol/IMinecraftComHandler.cs | 28 ++++
16 files changed, 469 insertions(+), 78 deletions(-)
create mode 100644 MinecraftClient/Inventory/Effects.cs
create mode 100644 MinecraftClient/Inventory/Hand.cs
create mode 100644 MinecraftClient/Mapping/CommandBlockFlags.cs
create mode 100644 MinecraftClient/Mapping/CommandBlockMode.cs
diff --git a/MinecraftClient/ChatBot.cs b/MinecraftClient/ChatBot.cs
index 69018281..d8bd0544 100644
--- a/MinecraftClient/ChatBot.cs
+++ b/MinecraftClient/ChatBot.cs
@@ -120,7 +120,7 @@ namespace MinecraftClient
/// Text from the server
/// Raw JSON from the server. This parameter will be NULL on MC 1.5 or lower!
public virtual void GetText(string text, string json) { }
-
+
///
/// Is called when the client has been disconnected fom the server
///
@@ -250,6 +250,34 @@ namespace MinecraftClient
/// Equipment slot. 0: main hand, 1: off hand, 2–5: armor slot (2: boots, 3: leggings, 4: chestplate, 5: helmet)
/// Item)
public virtual void OnEntityEquipment(Entity entity, int slot, Item item) { }
+
+ ///
+ /// Called when the Entity use effects
+ ///
+ /// entity ID
+ /// effect id
+ /// effect amplifier
+ /// effect duration
+ /// effect flags
+ public virtual void OnEntityEffect(Entity entity, Effects effect, int amplifier, int duration, byte flags) { }
+
+ ///
+ /// Called when coreboardObjective
+ ///
+ /// objective name
+ /// 0 to create the scoreboard. 1 to remove the scoreboard. 2 to update the display text.
+ /// Only if mode is 0 or 2. The text to be displayed for the score
+ /// Only if mode is 0 or 2. 0 = "integer", 1 = "hearts".
+ public virtual void OnScoreboardObjective(string objectivename, byte mode, string objectivevalue, int type, string json) { }
+
+ ///
+ /// Called when DisplayScoreboard
+ ///
+ /// The entity whose score this is. For players, this is their username; for other entities, it is their UUID.
+ /// 0 to create/update an item. 1 to remove an item.
+ /// The name of the objective the score belongs to
+ /// he score to be displayed next to the entry. Only sent when Action does not equal 1.
+ public virtual void OnUpdateScore(string entityname, byte action, string objectivename, int value) { }
/* =================================================================== */
/* ToolBox - Methods below might be useful while creating your bot. */
@@ -771,6 +799,15 @@ namespace MinecraftClient
return Handler.GetWorld();
return null;
}
+
+ ///
+ /// Get all Entityes
+ ///
+ /// All Entities
+ protected Dictionary GetEntities()
+ {
+ return Handler.GetEntities();
+ }
///
/// Get the current location of the player
@@ -960,10 +997,11 @@ namespace MinecraftClient
///
///
/// 0: interact, 1: attack, 2: interact at
+ /// Hand.MainHand or Hand.OffHand
/// TRUE in case of success
- protected bool InteractEntity(int EntityID, int type)
+ protected bool InteractEntity(int EntityID, int type, Hand hand = Hand.MainHand)
{
- return Handler.InteractEntity(EntityID, type);
+ return Handler.InteractEntity(EntityID, type, hand);
}
///
@@ -983,11 +1021,11 @@ namespace MinecraftClient
///
/// Plays animation (Player arm swing)
///
- /// 0 for left arm, 1 for right arm
- /// TRUE in case of success
- protected bool SendAnimation(int animation)
+ /// Hand.MainHand or Hand.OffHand
+ /// TRUE if animation successfully done
+ public bool SendAnimation(Hand hand = Hand.MainHand)
{
- return Handler.DoAnimation(animation);
+ return Handler.DoAnimation((int)hand);
}
///
@@ -1009,13 +1047,15 @@ namespace MinecraftClient
}
///
- /// Place block
+ /// Place the block at hand in the Minecraft world
///
- /// Block location
- ///
- protected bool SendPlaceBlock(Location location, Direction blockFace)
+ /// Location to place block to
+ /// Block face (e.g. Direction.Down when clicking on the block below to place this block)
+ /// Hand.MainHand or Hand.OffHand
+ /// TRUE if successfully placed
+ public bool SendPlaceBlock(Location location, Direction blockFace, Hand hand = Hand.MainHand)
{
- return Handler.PlaceBlock(location, blockFace);
+ return Handler.PlaceBlock(location, blockFace, hand);
}
///
@@ -1089,6 +1129,18 @@ namespace MinecraftClient
{
return Handler.UpdateSign(location, line1, line2, line3, line4);
}
+
+ ///
+ /// Update command block
+ ///
+ /// command block location
+ /// command
+ /// command block mode
+ /// command block flags
+ protected bool UpdateCommandBlock(Location location, string command, CommandBlockMode mode, CommandBlockFlags flags)
+ {
+ return Handler.UpdateCommandBlock(location, command, mode, flags);
+ }
///
/// Register a command in command prompt
@@ -1101,42 +1153,42 @@ namespace MinecraftClient
{
return Handler.RegisterCommand(CMDName, CMDDesc, Run);
}
- }
-
- ///
- /// Command runner definition.
- /// Returned string will be the output of the command
- ///
- /// Full command
- /// Arguments in the command
- ///
- public delegate string CommandRunner(string command, string[] args);
-
- ///
- /// Command class with constructor for creating command for ChatBots.
- ///
- public class ChatBotCommand : Command
- {
- public CommandRunner Runner;
-
- public override string CMDName { get; }
- public override string CMDDesc { get; }
- public override string Run(McClient handler, string command, Dictionary localVars)
- {
- return this.Runner(command, getArgs(command));
- }
///
- /// Constructor
+ /// Command runner definition.
+ /// Returned string will be the output of the command
///
- /// Name of the command
- /// Description/usage of the command
- /// Method for handling the command
- public ChatBotCommand(string CMDName, string CMDDesc, CommandRunner runner)
+ /// Full command
+ /// Arguments in the command
+ ///
+ public delegate string CommandRunner(string command, string[] args);
+
+ ///
+ /// Command class with constructor for creating command for ChatBots.
+ ///
+ public class ChatBotCommand : Command
{
- this.CMDName = CMDName;
- this.CMDDesc = CMDDesc;
- this.Runner = runner;
+ public CommandRunner Runner;
+
+ public override string CMDName { get; }
+ public override string CMDDesc { get; }
+ public override string Run(McClient handler, string command, Dictionary localVars)
+ {
+ return this.Runner(command, getArgs(command));
+ }
+
+ ///
+ /// Constructor
+ ///
+ /// Name of the command
+ /// Description/usage of the command
+ /// Method for handling the command
+ public ChatBotCommand(string CMDName, string CMDDesc, CommandRunner runner)
+ {
+ this.CMDName = CMDName;
+ this.CMDDesc = CMDDesc;
+ this.Runner = runner;
+ }
}
}
}
diff --git a/MinecraftClient/ChatBots/AutoAttack.cs b/MinecraftClient/ChatBots/AutoAttack.cs
index 4fcbda32..6ec12a0d 100644
--- a/MinecraftClient/ChatBots/AutoAttack.cs
+++ b/MinecraftClient/ChatBots/AutoAttack.cs
@@ -46,7 +46,7 @@ namespace MinecraftClient.ChatBots
bool shouldAttack = handleEntity(entity.Value);
if (shouldAttack)
{
- SendAnimation(0); // Hit Animation
+ SendAnimation(Inventory.Hand.MainHand); // Hit Animation
InteractEntity(entity.Key, 1); // hit the entity!
}
}
diff --git a/MinecraftClient/Inventory/Effects.cs b/MinecraftClient/Inventory/Effects.cs
new file mode 100644
index 00000000..a5f3c194
--- /dev/null
+++ b/MinecraftClient/Inventory/Effects.cs
@@ -0,0 +1,47 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace MinecraftClient.Inventory
+{
+ ///
+ /// Represents a Minecraft effects
+ ///
+ public enum Effects
+ {
+ Speed = 1,
+ Slowness = 2,
+ Haste = 3,
+ MiningFatigue = 4,
+ Strength = 5,
+ InstantHealth = 6,
+ InstantDamage = 7,
+ JumpBoost = 8,
+ Nausea = 9,
+ Regeneration = 10,
+ Resistance = 11,
+ FireResistance = 12,
+ WaterBreathing = 13,
+ Invisibility = 14,
+ Blindness = 15,
+ NightVision = 16,
+ Hunger = 17,
+ Weakness = 18,
+ Poison = 19,
+ Wither = 20,
+ HealthBoost = 21,
+ Absorption = 22,
+ Saturation = 23,
+ Glowing = 24,
+ Levitation = 25,
+ Luck = 26,
+ BadLuck = 27,
+ SlowFalling = 28,
+ ConduitPower = 29,
+ DolphinsGrace = 30,
+ BadOmen = 31,
+ HerooftheVillage = 32,
+ }
+}
diff --git a/MinecraftClient/Inventory/Hand.cs b/MinecraftClient/Inventory/Hand.cs
new file mode 100644
index 00000000..c78ded7f
--- /dev/null
+++ b/MinecraftClient/Inventory/Hand.cs
@@ -0,0 +1,11 @@
+namespace MinecraftClient.Inventory
+{
+ ///
+ /// Represents a Minecraft hand
+ ///
+ public enum Hand
+ {
+ MainHand = 0,
+ OffHand = 1,
+ }
+}
diff --git a/MinecraftClient/Mapping/CommandBlockFlags.cs b/MinecraftClient/Mapping/CommandBlockFlags.cs
new file mode 100644
index 00000000..5807222e
--- /dev/null
+++ b/MinecraftClient/Mapping/CommandBlockFlags.cs
@@ -0,0 +1,18 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace MinecraftClient.Mapping
+{
+ ///
+ /// Represents a unit movement in the world
+ ///
+ ///
+ public enum CommandBlockFlags
+ {
+ TrackOutput = 0x01,
+ IsConditional = 0x02,
+ Automatic = 0x04,
+ }
+}
diff --git a/MinecraftClient/Mapping/CommandBlockMode.cs b/MinecraftClient/Mapping/CommandBlockMode.cs
new file mode 100644
index 00000000..6d4aba67
--- /dev/null
+++ b/MinecraftClient/Mapping/CommandBlockMode.cs
@@ -0,0 +1,18 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace MinecraftClient.Mapping
+{
+ ///
+ /// Represents a unit movement in the world
+ ///
+ ///
+ public enum CommandBlockMode
+ {
+ Sequence = 0,
+ Auto = 1,
+ Redstone = 2,
+ }
+}
diff --git a/MinecraftClient/McClient.cs b/MinecraftClient/McClient.cs
index bdff7eab..ffc0e148 100644
--- a/MinecraftClient/McClient.cs
+++ b/MinecraftClient/McClient.cs
@@ -759,6 +759,15 @@ namespace MinecraftClient
{
return inventories;
}
+
+ ///
+ /// Get all Entityes
+ ///
+ /// All Entities
+ public Dictionary GetEntities()
+ {
+ return entities;
+ }
///
/// Get client player's inventory items
@@ -825,7 +834,7 @@ namespace MinecraftClient
{
lock (locationLock)
{
- if (allowSmallTeleport && location.DistanceSquared(this.location) <= 32)
+ if (allowSmallTeleport)
{
// Allow small teleport within a range of 8 blocks. 1-step path to the desired location without checking anything
UpdateLocation(location, location); // Update yaw and pitch to look at next step
@@ -1037,10 +1046,22 @@ namespace MinecraftClient
///
///
/// 0: interact, 1: attack, 2: interact at
+ /// Hand.MainHand or Hand.OffHand
/// TRUE if interaction succeeded
- public bool InteractEntity(int EntityID, int type)
+ public bool InteractEntity(int EntityID, int type, Hand hand = Hand.MainHand)
{
- return handler.SendInteractEntity(EntityID, type);
+ if (entities.ContainsKey(EntityID))
+ {
+ if (type == 0)
+ {
+ return handler.SendInteractEntity(EntityID, type, (int)hand);
+ }
+ else
+ {
+ return handler.SendInteractEntity(EntityID, type);
+ }
+ }
+ else { return false; }
}
///
@@ -1049,9 +1070,9 @@ namespace MinecraftClient
/// Location to place block to
/// Block face (e.g. Direction.Down when clicking on the block below to place this block)
/// TRUE if successfully placed
- public bool PlaceBlock(Location location, Direction blockFace)
+ public bool PlaceBlock(Location location, Direction blockFace, Hand hand = Hand.MainHand)
{
- return handler.SendPlayerBlockPlacement(0, location, blockFace);
+ return handler.SendPlayerBlockPlacement((int)hand, location, blockFace);
}
///
@@ -1104,7 +1125,18 @@ namespace MinecraftClient
// TODO Open sign editor first https://wiki.vg/Protocol#Open_Sign_Editor
return handler.SendUpdateSign(location, line1, line2, line3, line4);
}
-
+
+ ///
+ /// Update command block
+ ///
+ /// command block location
+ /// command
+ /// command block mode
+ /// command block flags
+ public bool UpdateCommandBlock(Location location, string command, CommandBlockMode mode, CommandBlockFlags flags)
+ {
+ return handler.UpdateCommandBlock(location, command, mode, flags);
+ }
#endregion
#region Event handlers: An event occurs on the Server
@@ -1325,7 +1357,7 @@ namespace MinecraftClient
DispatchBotEvent(bot => bot.GetText(text));
DispatchBotEvent(bot => bot.GetText(text, json));
}
-
+
///
/// Received a connection keep-alive from the server
///
@@ -1478,6 +1510,15 @@ namespace MinecraftClient
entities.Add(entity.ID, entity);
DispatchBotEvent(bot => bot.OnEntitySpawn(entity));
}
+
+ ///
+ /// Called when an entity effects
+ ///
+ public void OnEntityEffect(int entityid, Effects effect, int amplifier, int duration, byte flags)
+ {
+ if (entities.ContainsKey(entityid))
+ DispatchBotEvent(bot => bot.OnEntityEffect(entities[entityid], effect, amplifier, duration, flags));
+ }
///
/// Called when a player spawns or enters the client's render distance
@@ -1724,7 +1765,32 @@ namespace MinecraftClient
{
DispatchBotEvent(bot => bot.OnTitle(action, titletext, subtitletext, actionbartext, fadein, stay, fadeout, json));
}
-
+
+ ///
+ /// Called when coreboardObjective
+ ///
+ /// objective name
+ /// 0 to create the scoreboard. 1 to remove the scoreboard. 2 to update the display text.
+ /// Only if mode is 0 or 2. The text to be displayed for the score
+ /// Only if mode is 0 or 2. 0 = "integer", 1 = "hearts".
+ public void OnScoreboardObjective(string objectivename, byte mode, string objectivevalue, int type)
+ {
+ string json = objectivevalue;
+ objectivevalue = ChatParser.ParseText(objectivevalue);
+ DispatchBotEvent(bot => bot.OnScoreboardObjective(objectivename, mode, objectivevalue, type, json));
+ }
+
+ ///
+ /// Called when DisplayScoreboard
+ ///
+ /// The entity whose score this is. For players, this is their username; for other entities, it is their UUID.
+ /// 0 to create/update an item. 1 to remove an item.
+ /// The name of the objective the score belongs to
+ /// he score to be displayed next to the entry. Only sent when Action does not equal 1.
+ public void OnUpdateScore(string entityname, byte action, string objectivename, int value)
+ {
+ DispatchBotEvent(bot => bot.OnUpdateScore(entityname, action, objectivename, value));
+ }
#endregion
}
}
diff --git a/MinecraftClient/MinecraftClient.csproj b/MinecraftClient/MinecraftClient.csproj
index 9d89fbef..8c763436 100644
--- a/MinecraftClient/MinecraftClient.csproj
+++ b/MinecraftClient/MinecraftClient.csproj
@@ -110,6 +110,8 @@
+
+
@@ -315,4 +317,4 @@
-->
-
\ No newline at end of file
+
diff --git a/MinecraftClient/Protocol/EntityActionType.cs b/MinecraftClient/Protocol/EntityActionType.cs
index 7d560e07..bda20370 100644
--- a/MinecraftClient/Protocol/EntityActionType.cs
+++ b/MinecraftClient/Protocol/EntityActionType.cs
@@ -1,4 +1,4 @@
-using System;
+using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
@@ -7,10 +7,14 @@ namespace MinecraftClient.Protocol
{
public enum EntityActionType
{
- StartSneaking,
- StopSneaking,
- LeaveBed,
- StartSprinting,
- StopSprinting
+ StartSneaking = 0,
+ StopSneaking = 1,
+ LeaveBed = 2,
+ StartSprinting = 3,
+ StopSprinting = 4,
+ StartJumpWithHorse = 5,
+ StopJumpWithHorse = 6,
+ OpenHorseInventory = 7,
+ StartFlyingWithElytra = 8,
}
-}
\ No newline at end of file
+}
diff --git a/MinecraftClient/Protocol/Handlers/PacketIncomingType.cs b/MinecraftClient/Protocol/Handlers/PacketIncomingType.cs
index fcc86cb7..a1fbeca2 100644
--- a/MinecraftClient/Protocol/Handlers/PacketIncomingType.cs
+++ b/MinecraftClient/Protocol/Handlers/PacketIncomingType.cs
@@ -45,6 +45,7 @@ namespace MinecraftClient.Protocol.Handlers
EntityTeleport,
EntityEquipment,
EntityVelocity,
+ EntityEffect,
TimeUpdate,
UpdateHealth,
SetExperience,
@@ -52,7 +53,9 @@ namespace MinecraftClient.Protocol.Handlers
Explosion,
MapData,
Title,
-
+ ScoreboardObjective,
+ UpdateScore,
+
///
/// Represents a packet not implemented in MCC.
///
diff --git a/MinecraftClient/Protocol/Handlers/PacketOutgoingType.cs b/MinecraftClient/Protocol/Handlers/PacketOutgoingType.cs
index d59418c5..eaee99ee 100644
--- a/MinecraftClient/Protocol/Handlers/PacketOutgoingType.cs
+++ b/MinecraftClient/Protocol/Handlers/PacketOutgoingType.cs
@@ -35,5 +35,6 @@ namespace MinecraftClient.Protocol.Handlers
Animation,
PlayerDigging,
UpdateSign,
+ UpdateCommandBlock,
}
}
diff --git a/MinecraftClient/Protocol/Handlers/Protocol16.cs b/MinecraftClient/Protocol/Handlers/Protocol16.cs
index c6fe04d5..329e89f5 100644
--- a/MinecraftClient/Protocol/Handlers/Protocol16.cs
+++ b/MinecraftClient/Protocol/Handlers/Protocol16.cs
@@ -687,7 +687,17 @@ namespace MinecraftClient.Protocol.Handlers
{
return false; //Currently not implemented
}
-
+
+ public bool SendInteractEntity(int EntityID, int type, int hand)
+ {
+ return false; //Currently not implemented
+ }
+
+ public bool UpdateCommandBlock(Location location, string command, CommandBlockMode mode, CommandBlockFlags flags)
+ {
+ return false; //Currently not implemented
+ }
+
public bool SendUseItem(int hand)
{
return false; //Currently not implemented
diff --git a/MinecraftClient/Protocol/Handlers/Protocol18.cs b/MinecraftClient/Protocol/Handlers/Protocol18.cs
index 018e546a..8ab202ea 100644
--- a/MinecraftClient/Protocol/Handlers/Protocol18.cs
+++ b/MinecraftClient/Protocol/Handlers/Protocol18.cs
@@ -12,6 +12,9 @@ using MinecraftClient.Mapping.BlockPalettes;
using MinecraftClient.Mapping.EntityPalettes;
using MinecraftClient.Protocol.Handlers.Forge;
using MinecraftClient.Inventory;
+using System.Windows.Forms;
+using System.Data.SqlClient;
+using System.Diagnostics;
namespace MinecraftClient.Protocol.Handlers
{
@@ -369,17 +372,17 @@ namespace MinecraftClient.Protocol.Handlers
}
break;
case PacketIncomingType.MapData:
- int mapid = dataTypes.ReadNextVarInt(packetData);
- byte scale = dataTypes.ReadNextByte(packetData);
- bool trackingposition = dataTypes.ReadNextBool(packetData);
- bool locked = false;
- if (protocolversion >= MC114Version)
- {
- locked = dataTypes.ReadNextBool(packetData);
- }
- int iconcount = dataTypes.ReadNextVarInt(packetData);
- handler.OnMapData(mapid, scale, trackingposition, locked, iconcount);
- break;
+ int mapid = dataTypes.ReadNextVarInt(packetData);
+ byte scale = dataTypes.ReadNextByte(packetData);
+ bool trackingposition = dataTypes.ReadNextBool(packetData);
+ bool locked = false;
+ if (protocolversion >= MC114Version)
+ {
+ locked = dataTypes.ReadNextBool(packetData);
+ }
+ int iconcount = dataTypes.ReadNextVarInt(packetData);
+ handler.OnMapData(mapid, scale, trackingposition, locked, iconcount);
+ break;
case PacketIncomingType.Title:
if (protocolversion >= MC18Version)
{
@@ -719,7 +722,7 @@ namespace MinecraftClient.Protocol.Handlers
handler.OnEntityEquipment(entityid, slot2, item);
}
break;
- case PacketIncomingType.SpawnLivingEntity:
+ case PacketIncomingType.SpawnLivingEntity:
if (handler.GetEntityHandlingEnabled())
{
Entity entity = dataTypes.ReadNextEntity(packetData, entityPalette, true);
@@ -745,6 +748,20 @@ namespace MinecraftClient.Protocol.Handlers
handler.OnSpawnPlayer(EntityID, UUID, EntityLocation, Yaw, Pitch);
}
break;
+ case PacketIncomingType.EntityEffect:
+ if (handler.GetEntityHandlingEnabled())
+ {
+ int entityid = dataTypes.ReadNextVarInt(packetData);
+ Inventory.Effects effect = Effects.Speed;
+ if (Enum.TryParse(dataTypes.ReadNextByte(packetData).ToString(), out effect))
+ {
+ int amplifier = dataTypes.ReadNextByte(packetData);
+ int duration = dataTypes.ReadNextVarInt(packetData);
+ byte flags = dataTypes.ReadNextByte(packetData);
+ handler.OnEntityEffect(entityid, effect, amplifier, duration, flags);
+ }
+ }
+ break;
case PacketIncomingType.DestroyEntities:
if (handler.GetEntityHandlingEnabled())
{
@@ -867,6 +884,29 @@ namespace MinecraftClient.Protocol.Handlers
byte slot = dataTypes.ReadNextByte(packetData);
handler.OnHeldItemChange(slot);
break;
+ case PacketIncomingType.ScoreboardObjective:
+ string objectivename = dataTypes.ReadNextString(packetData);
+ byte mode = dataTypes.ReadNextByte(packetData);
+ string objectivevalue = String.Empty;
+ int type2 = -1;
+ if (mode == 0 || mode == 2)
+ {
+ objectivevalue = dataTypes.ReadNextString(packetData);
+ type2 = dataTypes.ReadNextVarInt(packetData);
+ }
+ handler.OnScoreboardObjective(objectivename, mode, objectivevalue, type2);
+ break;
+ case PacketIncomingType.UpdateScore:
+ string entityname = dataTypes.ReadNextString(packetData);
+ byte action3 = dataTypes.ReadNextByte(packetData);
+ string objectivename2 = dataTypes.ReadNextString(packetData);
+ int value = -1;
+ if (action3 != 1)
+ {
+ value = dataTypes.ReadNextVarInt(packetData);
+ }
+ handler.OnUpdateScore(entityname, action3, objectivename2, value);
+ break;
default:
return false; //Ignored packet
}
@@ -1078,6 +1118,7 @@ namespace MinecraftClient.Protocol.Handlers
/// Completed text
IEnumerable IAutoComplete.AutoComplete(string BehindCursor)
{
+
if (String.IsNullOrEmpty(BehindCursor))
return new string[] { };
@@ -1117,9 +1158,13 @@ namespace MinecraftClient.Protocol.Handlers
SendPacket(PacketOutgoingType.TabComplete, tabcomplete_packet);
int wait_left = 50; //do not wait more than 5 seconds (50 * 100 ms)
- while (wait_left > 0 && !autocomplete_received) { System.Threading.Thread.Sleep(100); wait_left--; }
- if (autocomplete_result.Count > 0)
- ConsoleIO.WriteLineFormatted("§8" + String.Join(" ", autocomplete_result), false);
+ Thread t1 = new Thread(new ThreadStart(delegate
+ {
+ while (wait_left > 0 && !autocomplete_received) { System.Threading.Thread.Sleep(100); wait_left--; }
+ if (autocomplete_result.Count > 0)
+ ConsoleIO.WriteLineFormatted("§8" + String.Join(" ", autocomplete_result), false);
+ }));
+ t1.Start();
return autocomplete_result;
}
@@ -1418,6 +1463,21 @@ namespace MinecraftClient.Protocol.Handlers
catch (System.IO.IOException) { return false; }
catch (ObjectDisposedException) { return false; }
}
+ public bool SendInteractEntity(int EntityID, int type, int hand)
+ {
+ try
+ {
+ List fields = new List();
+ fields.AddRange(dataTypes.GetVarInt(EntityID));
+ fields.AddRange(dataTypes.GetVarInt(type));
+ fields.AddRange(dataTypes.GetVarInt(hand));
+ SendPacket(PacketOutgoingType.InteractEntity, fields);
+ return true;
+ }
+ catch (SocketException) { return false; }
+ catch (System.IO.IOException) { return false; }
+ catch (ObjectDisposedException) { return false; }
+ }
public bool SendInteractEntity(int EntityID, int type, float X, float Y, float Z)
{
return false;
@@ -1645,5 +1705,26 @@ namespace MinecraftClient.Protocol.Handlers
catch (System.IO.IOException) { return false; }
catch (ObjectDisposedException) { return false; }
}
+
+ public bool UpdateCommandBlock(Location location, string command, CommandBlockMode mode, CommandBlockFlags flags)
+ {
+ if (protocolversion <= MC113Version)
+ {
+ try
+ {
+ List packet = new List();
+ packet.AddRange(dataTypes.GetLocation(location));
+ packet.AddRange(dataTypes.GetString(command));
+ packet.AddRange(dataTypes.GetVarInt((int)mode));
+ packet.Add((byte)flags);
+ SendPacket(PacketOutgoingType.UpdateSign, packet);
+ return true;
+ }
+ catch (SocketException) { return false; }
+ catch (System.IO.IOException) { return false; }
+ catch (ObjectDisposedException) { return false; }
+ }
+ else { return false; }
+ }
}
}
diff --git a/MinecraftClient/Protocol/Handlers/Protocol18PacketTypes.cs b/MinecraftClient/Protocol/Handlers/Protocol18PacketTypes.cs
index a988feb3..b6e792d8 100644
--- a/MinecraftClient/Protocol/Handlers/Protocol18PacketTypes.cs
+++ b/MinecraftClient/Protocol/Handlers/Protocol18PacketTypes.cs
@@ -59,6 +59,7 @@ namespace MinecraftClient.Protocol.Handlers
case 0x18: return PacketIncomingType.EntityTeleport;
case 0x12: return PacketIncomingType.EntityVelocity;
case 0x04: return PacketIncomingType.EntityEquipment;
+ case 0x1E: return PacketIncomingType.EntityEffect;
case 0x03: return PacketIncomingType.TimeUpdate;
case 0x06: return PacketIncomingType.UpdateHealth;
case 0x1F: return PacketIncomingType.SetExperience;
@@ -66,6 +67,8 @@ namespace MinecraftClient.Protocol.Handlers
case 0x27: return PacketIncomingType.Explosion;
case 0x34: return PacketIncomingType.MapData;
case 0x45: return PacketIncomingType.Title;
+ case 0x3B: return PacketIncomingType.ScoreboardObjective;
+ case 0x3C: return PacketIncomingType.UpdateScore;
}
}
else if (protocol <= Protocol18Handler.MC1112Version) // MC 1.9, 1.10 and 1.11
@@ -103,6 +106,7 @@ namespace MinecraftClient.Protocol.Handlers
case 0x49: return PacketIncomingType.EntityTeleport;
case 0x3B: return PacketIncomingType.EntityVelocity;
case 0x3C: return PacketIncomingType.EntityEquipment;
+ case 0x4B: return PacketIncomingType.EntityEffect;
case 0x44: return PacketIncomingType.TimeUpdate;
case 0x3E: return PacketIncomingType.UpdateHealth;
case 0x3D: return PacketIncomingType.SetExperience;
@@ -110,6 +114,8 @@ namespace MinecraftClient.Protocol.Handlers
case 0x1C: return PacketIncomingType.Explosion;
case 0x24: return PacketIncomingType.MapData;
case 0x45: return PacketIncomingType.Title;
+ case 0x3F: return PacketIncomingType.ScoreboardObjective;
+ case 0x42: return PacketIncomingType.UpdateScore;
}
}
else if (protocol <= Protocol18Handler.MC112Version) // MC 1.12.0
@@ -147,6 +153,7 @@ namespace MinecraftClient.Protocol.Handlers
case 0x4B: return PacketIncomingType.EntityTeleport;
case 0x3D: return PacketIncomingType.EntityVelocity;
case 0x3E: return PacketIncomingType.EntityEquipment;
+ case 0x4E: return PacketIncomingType.EntityEffect;
case 0x46: return PacketIncomingType.TimeUpdate;
case 0x40: return PacketIncomingType.UpdateHealth;
case 0x3F: return PacketIncomingType.SetExperience;
@@ -154,6 +161,8 @@ namespace MinecraftClient.Protocol.Handlers
case 0x1C: return PacketIncomingType.Explosion;
case 0x24: return PacketIncomingType.MapData;
case 0x47: return PacketIncomingType.Title;
+ case 0x41: return PacketIncomingType.ScoreboardObjective;
+ case 0x44: return PacketIncomingType.UpdateScore;
}
}
else if (protocol <= Protocol18Handler.MC1122Version) // MC 1.12.2
@@ -191,6 +200,7 @@ namespace MinecraftClient.Protocol.Handlers
case 0x4C: return PacketIncomingType.EntityTeleport;
case 0x3E: return PacketIncomingType.EntityVelocity;
case 0x3F: return PacketIncomingType.EntityEquipment;
+ case 0x4F: return PacketIncomingType.EntityEffect;
case 0x47: return PacketIncomingType.TimeUpdate;
case 0x41: return PacketIncomingType.UpdateHealth;
case 0x40: return PacketIncomingType.SetExperience;
@@ -198,6 +208,8 @@ namespace MinecraftClient.Protocol.Handlers
case 0x1C: return PacketIncomingType.Explosion;
case 0x25: return PacketIncomingType.MapData;
case 0x48: return PacketIncomingType.Title;
+ case 0x42: return PacketIncomingType.ScoreboardObjective;
+ case 0x45: return PacketIncomingType.UpdateScore;
}
}
else if (protocol < Protocol18Handler.MC114Version) // MC 1.13 to 1.13.2
@@ -235,6 +247,7 @@ namespace MinecraftClient.Protocol.Handlers
case 0x50: return PacketIncomingType.EntityTeleport;
case 0x41: return PacketIncomingType.EntityVelocity;
case 0x42: return PacketIncomingType.EntityEquipment;
+ case 0x53: return PacketIncomingType.EntityEffect;
case 0x4A: return PacketIncomingType.TimeUpdate;
case 0x44: return PacketIncomingType.UpdateHealth;
case 0x43: return PacketIncomingType.SetExperience;
@@ -242,6 +255,8 @@ namespace MinecraftClient.Protocol.Handlers
case 0x1E: return PacketIncomingType.Explosion;
case 0x26: return PacketIncomingType.MapData;
case 0x4B: return PacketIncomingType.Title;
+ case 0x45: return PacketIncomingType.ScoreboardObjective;
+ case 0x48: return PacketIncomingType.UpdateScore;
}
}
else if (protocol < Protocol18Handler.MC115Version) // MC 1.14 to 1.14.4
@@ -279,6 +294,7 @@ namespace MinecraftClient.Protocol.Handlers
case 0x56: return PacketIncomingType.EntityTeleport;
case 0x41: return PacketIncomingType.EntityVelocity;
case 0x42: return PacketIncomingType.EntityEquipment;
+ case 0x59: return PacketIncomingType.EntityEffect;
case 0x4E: return PacketIncomingType.TimeUpdate;
case 0x48: return PacketIncomingType.UpdateHealth;
case 0x45: return PacketIncomingType.SetExperience;
@@ -286,6 +302,8 @@ namespace MinecraftClient.Protocol.Handlers
case 0x1C: return PacketIncomingType.Explosion;
case 0x26: return PacketIncomingType.MapData;
case 0x4F: return PacketIncomingType.Title;
+ case 0x49: return PacketIncomingType.ScoreboardObjective;
+ case 0x4C: return PacketIncomingType.UpdateScore;
}
}
else if (protocol <= Protocol18Handler.MC1152Version) // MC 1.15 to 1.15.2
@@ -323,6 +341,7 @@ namespace MinecraftClient.Protocol.Handlers
case 0x57: return PacketIncomingType.EntityTeleport;
case 0x46: return PacketIncomingType.EntityVelocity;
case 0x47: return PacketIncomingType.EntityEquipment;
+ case 0x5A: return PacketIncomingType.EntityEffect;
case 0x4F: return PacketIncomingType.TimeUpdate;
case 0x49: return PacketIncomingType.UpdateHealth;
case 0x48: return PacketIncomingType.SetExperience;
@@ -330,6 +349,9 @@ namespace MinecraftClient.Protocol.Handlers
case 0x1D: return PacketIncomingType.Explosion;
case 0x27: return PacketIncomingType.MapData;
case 0x50: return PacketIncomingType.Title;
+ case 0x4A: return PacketIncomingType.ScoreboardObjective;
+ case 0x4D: return PacketIncomingType.UpdateScore;
+
}
} else {
switch (packetID)
@@ -365,6 +387,7 @@ namespace MinecraftClient.Protocol.Handlers
case 0x56: return PacketIncomingType.EntityTeleport;
case 0x46: return PacketIncomingType.EntityVelocity;
case 0x47: return PacketIncomingType.EntityEquipment;
+ case 0x5A: return PacketIncomingType.EntityEffect;
case 0x4E: return PacketIncomingType.TimeUpdate;
case 0x49: return PacketIncomingType.UpdateHealth;
case 0x48: return PacketIncomingType.SetExperience;
@@ -372,6 +395,8 @@ namespace MinecraftClient.Protocol.Handlers
case 0x1C: return PacketIncomingType.Explosion;
case 0x26: return PacketIncomingType.MapData;
case 0x4F: return PacketIncomingType.Title;
+ case 0x4A: return PacketIncomingType.ScoreboardObjective;
+ case 0x4D: return PacketIncomingType.UpdateScore;
}
}
@@ -417,6 +442,7 @@ namespace MinecraftClient.Protocol.Handlers
case PacketOutgoingType.Animation: return 0x0A;
case PacketOutgoingType.PlayerDigging: return 0x07;
case PacketOutgoingType.UpdateSign: return 0x12;
+ case PacketOutgoingType.UpdateCommandBlock: return 0x20;
}
}
else if (protocol <= Protocol18Handler.MC1112Version) // MC 1.9, 1,10 and 1.11
@@ -444,6 +470,7 @@ namespace MinecraftClient.Protocol.Handlers
case PacketOutgoingType.Animation: return 0x1A;
case PacketOutgoingType.PlayerDigging: return 0x13;
case PacketOutgoingType.UpdateSign: return 0x19;
+ case PacketOutgoingType.UpdateCommandBlock: return 0x20;
}
}
else if (protocol <= Protocol18Handler.MC112Version) // MC 1.12
@@ -471,6 +498,7 @@ namespace MinecraftClient.Protocol.Handlers
case PacketOutgoingType.Animation: return 0x1D;
case PacketOutgoingType.PlayerDigging: return 0x14;
case PacketOutgoingType.UpdateSign: return 0x1C;
+ case PacketOutgoingType.UpdateCommandBlock: return 0x20;
}
}
else if (protocol <= Protocol18Handler.MC1122Version) // 1.12.2
@@ -498,6 +526,7 @@ namespace MinecraftClient.Protocol.Handlers
case PacketOutgoingType.Animation: return 0x1D;
case PacketOutgoingType.PlayerDigging: return 0x14;
case PacketOutgoingType.UpdateSign: return 0x1C;
+ case PacketOutgoingType.UpdateCommandBlock: return 0x20;
}
}
else if (protocol < Protocol18Handler.MC114Version) // MC 1.13 to 1.13.2
@@ -525,6 +554,7 @@ namespace MinecraftClient.Protocol.Handlers
case PacketOutgoingType.Animation: return 0x27;
case PacketOutgoingType.PlayerDigging: return 0x18;
case PacketOutgoingType.UpdateSign: return 0x26;
+ case PacketOutgoingType.UpdateCommandBlock: return 0x22;
}
}
else if (protocol <= Protocol18Handler.MC1152Version) //MC 1.14 to 1.15.2
@@ -552,6 +582,7 @@ namespace MinecraftClient.Protocol.Handlers
case PacketOutgoingType.Animation: return 0x2A;
case PacketOutgoingType.PlayerDigging: return 0x1A;
case PacketOutgoingType.UpdateSign: return 0x29;
+ case PacketOutgoingType.UpdateCommandBlock: return 0x24;
}
}
else
@@ -579,6 +610,7 @@ namespace MinecraftClient.Protocol.Handlers
case PacketOutgoingType.Animation: return 0x2B;
case PacketOutgoingType.PlayerDigging: return 0x1B;
case PacketOutgoingType.UpdateSign: return 0x2A;
+ case PacketOutgoingType.UpdateCommandBlock: return 0x24;
}
}
diff --git a/MinecraftClient/Protocol/IMinecraftCom.cs b/MinecraftClient/Protocol/IMinecraftCom.cs
index 546b0dc5..cd444827 100644
--- a/MinecraftClient/Protocol/IMinecraftCom.cs
+++ b/MinecraftClient/Protocol/IMinecraftCom.cs
@@ -131,6 +131,15 @@ namespace MinecraftClient.Protocol
/// Z coordinate for "interact at"
/// True if packet was successfully sent
bool SendInteractEntity(int EntityID, int type, float X, float Y, float Z);
+
+ ///
+ /// Send an entity interaction packet to the server.
+ ///
+ /// Entity ID to interact with
+ /// Type of interaction (0: interact, 1: attack, 2: interact at)
+ /// Only if Type is interact or interact at; 0: main hand, 1: off hand
+ /// True if packet was successfully sent
+ bool SendInteractEntity(int EntityID, int type, int hand);
///
/// Send a use item packet to the server
@@ -202,5 +211,14 @@ namespace MinecraftClient.Protocol
/// New line 4
/// True if packet was succcessfully sent
bool SendUpdateSign(Location location, string line1, string line2, string line3, string line4);
+
+ ///
+ /// Update command block
+ ///
+ /// command block location
+ /// command
+ /// command block mode
+ /// command block flags
+ bool UpdateCommandBlock(Location location, string command, CommandBlockMode mode, CommandBlockFlags flags);
}
}
diff --git a/MinecraftClient/Protocol/IMinecraftComHandler.cs b/MinecraftClient/Protocol/IMinecraftComHandler.cs
index 69c70e4e..40ddcf81 100644
--- a/MinecraftClient/Protocol/IMinecraftComHandler.cs
+++ b/MinecraftClient/Protocol/IMinecraftComHandler.cs
@@ -273,5 +273,33 @@ namespace MinecraftClient.Protocol
///
/// Player entity ID
void OnReceivePlayerEntityID(int EntityID);
+
+ ///
+ /// Called when the Entity use effects
+ ///
+ /// entity ID
+ /// effect id
+ /// effect amplifier
+ /// effect duration
+ /// effect flags
+ void OnEntityEffect(int entityid, Effects effect, int amplifier, int duration, byte flags);
+
+ ///
+ /// Called when coreboardObjective
+ ///
+ /// objective name
+ /// 0 to create the scoreboard. 1 to remove the scoreboard. 2 to update the display text.
+ /// Only if mode is 0 or 2. The text to be displayed for the score
+ /// Only if mode is 0 or 2. 0 = "integer", 1 = "hearts".
+ void OnScoreboardObjective(string objectivename, byte mode, string objectivevalue, int type);
+
+ ///
+ /// Called when DisplayScoreboard
+ ///
+ /// The entity whose score this is. For players, this is their username; for other entities, it is their UUID.
+ /// 0 to create/update an item. 1 to remove an item.
+ /// The name of the objective the score belongs to
+ /// he score to be displayed next to the entry. Only sent when Action does not equal 1.
+ void OnUpdateScore(string entityname, byte action, string objectivename, int value);
}
}