Add code documentation, move and rename a few methods

This commit is contained in:
ORelio 2020-03-28 00:48:41 +01:00
parent 90c6e776e1
commit 195e162c7d
10 changed files with 286 additions and 96 deletions

View file

@ -6,6 +6,9 @@ using System.Text;
namespace MinecraftClient.ChatBots namespace MinecraftClient.ChatBots
{ {
/// <summary>
/// The AutoAttack bot will automatically attack any hostile mob close to the player
/// </summary>
class AutoAttack : ChatBot class AutoAttack : ChatBot
{ {
private Dictionary<int, Entity> entitiesToAttack = new Dictionary<int, Entity>(); // mobs within attack range private Dictionary<int, Entity> entitiesToAttack = new Dictionary<int, Entity>(); // mobs within attack range
@ -48,7 +51,7 @@ namespace MinecraftClient.ChatBots
public override void OnEntitySpawn(Entity entity) public override void OnEntitySpawn(Entity entity)
{ {
if (entity.GetMobName() != "") if (entity.IsHostile())
{ {
entitiesToTrack.Add(entity.ID, entity); entitiesToTrack.Add(entity.ID, entity);
} }
@ -64,10 +67,9 @@ namespace MinecraftClient.ChatBots
{ {
if (entitiesToTrack.ContainsKey(entity.ID)) if (entitiesToTrack.ContainsKey(entity.ID))
{ {
Double distance = Entity.CalculateDistance(GetCurrentLocation(), entity.Location); if (GetCurrentLocation().Distance(entity.Location) < attackRange)
if(distance < attackRange)
{ {
if(!entitiesToAttack.ContainsKey(entity.ID)) if (!entitiesToAttack.ContainsKey(entity.ID))
entitiesToAttack.Add(entity.ID, entity); entitiesToAttack.Add(entity.ID, entity);
} }
} }

View file

@ -8,6 +8,10 @@ using MinecraftClient.Mapping;
namespace MinecraftClient.ChatBots namespace MinecraftClient.ChatBots
{ {
/// <summary>
/// The AutoFishing bot semi-automates fishing.
/// The player needs to have a fishing rod in hand, then manually send it using the UseItem command.
/// </summary>
class AutoFishing : ChatBot class AutoFishing : ChatBot
{ {
private Entity fishingRod; private Entity fishingRod;
@ -32,7 +36,7 @@ namespace MinecraftClient.ChatBots
{ {
if (entity.TypeID == 102) if (entity.TypeID == 102)
{ {
if (Entity.CalculateDistance(GetCurrentLocation(), entity.Location) < 2 && !isFishing) if (GetCurrentLocation().Distance(entity.Location) < 2 && !isFishing)
{ {
ConsoleIO.WriteLine("Threw a fishing rod"); ConsoleIO.WriteLine("Threw a fishing rod");
fishingRod = entity; fishingRod = entity;
@ -41,6 +45,7 @@ namespace MinecraftClient.ChatBots
} }
} }
} }
public override void OnEntityDespawn(Entity entity) public override void OnEntityDespawn(Entity entity)
{ {
if(entity.TypeID == 102) if(entity.TypeID == 102)
@ -51,6 +56,7 @@ namespace MinecraftClient.ChatBots
} }
} }
} }
public override void OnEntityMove(Entity entity) public override void OnEntityMove(Entity entity)
{ {
if (isFishing) if (isFishing)
@ -107,9 +113,14 @@ namespace MinecraftClient.ChatBots
}); });
} }
/// <summary>
/// Check whether the player has a fishing rod in inventory
/// </summary>
/// <returns>TRUE if the player has a fishing rod</returns>
public bool hasFishingRod() public bool hasFishingRod()
{ {
if (!inventoryEnabled) return false; if (!inventoryEnabled)
return false;
int start = 36; int start = 36;
int end = 44; int end = 44;
Inventory.Container container = GetPlayerInventory(); Inventory.Container container = GetPlayerInventory();

View file

@ -5,97 +5,117 @@ using System.Text;
namespace MinecraftClient.Mapping namespace MinecraftClient.Mapping
{ {
/// <summary>
/// Represents an entity evolving into a Minecraft world
/// </summary>
public class Entity public class Entity
{ {
/// <summary>
/// ID of the entity on the Minecraft server
/// </summary>
public int ID; public int ID;
public int TypeID;
/// <summary>
/// Entity type determined by Minecraft Console Client
/// </summary>
public EntityType Type; public EntityType Type;
public string Name;
/// <summary>
/// Entity type ID (more precise than Type, but may change between Minecraft versions)
/// </summary>
public int TypeID;
/// <summary>
/// Entity location in the Minecraft world
/// </summary>
public Location Location; public Location Location;
/// <summary>
/// Create a new entity based on Entity ID and location
/// </summary>
/// <param name="ID">Entity ID</param>
/// <param name="location">Entity location</param>
public Entity(int ID, Location location) public Entity(int ID, Location location)
{ {
this.ID = ID; this.ID = ID;
this.Location = location; this.Location = location;
} }
/// <summary>
/// Create a new entity based on Entity ID, Entity Type and location
/// </summary>
/// <param name="ID">Entity ID</param>
/// <param name="TypeID">Entity Type ID</param>
/// <param name="location">Entity location</param>
public Entity(int ID, int TypeID, Location location) public Entity(int ID, int TypeID, Location location)
{ {
this.ID = ID; this.ID = ID;
this.TypeID = TypeID; this.TypeID = TypeID;
this.Name = GetMobName(TypeID);
this.Location = location; this.Location = location;
} }
/// <summary>
/// Create a new entity based on Entity ID, Entity Type and location
/// </summary>
/// <param name="ID">Entity ID</param>
/// <param name="TypeID">Entity Type ID</param>
/// <param name="type">Entity Type Enum</param>
/// <param name="location">Entity location</param>
public Entity(int ID, int TypeID, EntityType type, Location location) public Entity(int ID, int TypeID, EntityType type, Location location)
{ {
this.ID = ID; this.ID = ID;
this.TypeID = TypeID; this.TypeID = TypeID;
this.Type = type; this.Type = type;
this.Name = GetMobName(TypeID);
this.Location = location; this.Location = location;
} }
/// <summary>
/// Create a new entity based on Entity ID, Entity Type and location
/// </summary>
/// <param name="ID">Entity ID</param>
/// <param name="type">Entity Type Enum</param>
/// <param name="location">Entity location</param>
public Entity(int ID, EntityType type, Location location) public Entity(int ID, EntityType type, Location location)
{ {
this.ID = ID; this.ID = ID;
this.Type = type; this.Type = type;
this.Location = location; this.Location = location;
} }
public Entity(int ID, int TypeID, string Name, Location location)
{
this.ID = ID;
this.TypeID = TypeID;
this.Name = Name;
this.Location = location;
}
/// <summary> /// <summary>
/// Calculate the distance between two coordinate /// Return TRUE if the Entity is an hostile mob
/// </summary> /// </summary>
/// <param name="l1"></param> /// <remarks>New mobs added in newer Minecraft versions might be absent from the list</remarks>
/// <param name="l2"></param> /// <returns>TRUE if hostile</returns>
/// <returns></returns> public bool IsHostile()
public static double CalculateDistance(Location l1, Location l2)
{ {
return Math.Sqrt(Math.Pow(l2.X - l1.X, 2) + Math.Pow(l2.Y - l1.Y, 2) + Math.Pow(l2.Z - l1.Z, 2)); switch (TypeID)
{
case 5: return true; // Blaze;
case 12: return true; // Creeper
case 16: return true; // Drowned
case 23: return true; // Evoker
case 29: return true; // Ghast
case 31: return true; // Guardian
case 33: return true; // Husk
case 41: return true; // Magma Cube
case 57: return true; // Zombie Pigman
case 63: return true; // Shulker
case 65: return true; // Silverfish
case 66: return true; // Skeleton
case 68: return true; // Slime
case 75: return true; // Stray
case 84: return true; // Vex
case 87: return true; // Vindicator
case 88: return true; // Pillager
case 90: return true; // Witch
case 92: return true; // Wither Skeleton
case 95: return true; // Zombie
case 97: return true; // Zombie Villager
case 98: return true; // Phantom
case 99: return true; // Ravager
default: return false;
} }
/// <summary>
/// Get the mob name by entity type ID.
/// </summary>
/// <param name="EntityType"></param>
/// <returns></returns>
public static string GetMobName(int EntityType)
{
// only mobs in this list will be auto attacked
switch (EntityType)
{
case 5: return "Blaze";
case 12: return "Creeper";
case 16: return "Drowned";
case 23: return "Evoker";
case 29: return "Ghast";
case 31: return "Guardian";
case 33: return "Husk";
case 41: return "Magma Cube";
case 57: return "Zombie Pigman";
case 63: return "Shulker";
case 65: return "Silverfish";
case 66: return "Skeleton";
case 68: return "Slime";
case 75: return "Stray";
case 84: return "Vex";
case 87: return "Vindicator";
case 88: return "Pillager";
case 90: return "Witch";
case 92: return "Wither Skeleton";
case 95: return "Zombie";
case 97: return "Zombie Villager";
case 98: return "Phantom";
case 99: return "Ravager";
default: return "";
}
}
public string GetMobName()
{
return GetMobName(TypeID);
} }
} }
} }

View file

@ -565,6 +565,12 @@ namespace MinecraftClient
return entityHandlingEnabled; return entityHandlingEnabled;
} }
/// <summary>
/// Enable or disable Entity handling.
/// Please note that Enabling will be deferred until next relog.
/// </summary>
/// <param name="enabled">Enabled</param>
/// <returns>TRUE if the setting was applied immediately, FALSE if delayed.</returns>
public bool SetEntityHandlingEnabled(bool enabled) public bool SetEntityHandlingEnabled(bool enabled)
{ {
if (!enabled) if (!enabled)
@ -594,7 +600,6 @@ namespace MinecraftClient
{ {
return playerInventory; return playerInventory;
} }
// TODO: add command for displaying player inventory
/// <summary> /// <summary>
/// Called when the server sends a new player location, /// Called when the server sends a new player location,
@ -791,8 +796,8 @@ namespace MinecraftClient
/// <summary> /// <summary>
/// When received window items from server. /// When received window items from server.
/// </summary> /// </summary>
/// <param name="type"></param> /// <param name="type">Inventory type</param>
/// <param name="itemList"></param> /// <param name="itemList">Item list</param>
public void OnWindowItems(int type, Dictionary<int, Inventory.Item> itemList) public void OnWindowItems(int type, Dictionary<int, Inventory.Item> itemList)
{ {
// 0 is player inventory // 0 is player inventory
@ -800,15 +805,28 @@ namespace MinecraftClient
playerInventory.Items = itemList; playerInventory.Items = itemList;
} }
public void OnSetSlot(byte WindowID, short SlotID, bool Present) /// <summary>
/// When a slot is cleared inside window items
/// </summary>
/// <param name="WindowID">Window ID</param>
/// <param name="SlotID">Slot ID</param>
public void OnSlotClear(byte WindowID, short SlotID)
{ {
if(WindowID == 0) if (WindowID == 0 && playerInventory.Items.ContainsKey(SlotID))
{ {
if (playerInventory.Items.ContainsKey(SlotID))
playerInventory.Items.Remove(SlotID); playerInventory.Items.Remove(SlotID);
} }
} }
public void OnSetSlot(byte WindowID, short SlotID, bool Present, int ItemID, byte Count, Dictionary<string, object> NBT)
/// <summary>
/// When a slot is set inside window items
/// </summary>
/// <param name="WindowID">Window ID</param>
/// <param name="SlotID">Slot ID</param>
/// <param name="ItemID">Item ID</param>
/// <param name="Count">Item Count</param>
/// <param name="NBT">Item Metadata</param>
public void OnSetSlot(byte WindowID, short SlotID, int ItemID, byte Count, Dictionary<string, object> NBT)
{ {
if (WindowID == 0) if (WindowID == 0)
{ {
@ -912,8 +930,6 @@ namespace MinecraftClient
pitch = null; pitch = null;
} }
} }
} }
/// <summary> /// <summary>
@ -1275,12 +1291,16 @@ namespace MinecraftClient
/// <summary> /// <summary>
/// Set client player's ID for later receiving player's own properties /// Set client player's ID for later receiving player's own properties
/// </summary> /// </summary>
/// <param name="EntityID"></param> /// <param name="EntityID">Player Entity ID</param>
public void SetPlayerEntityID(int EntityID) public void SetPlayerEntityID(int EntityID)
{ {
playerEntityID = EntityID; playerEntityID = EntityID;
} }
/// <summary>
/// Use the item currently in the player's hand
/// </summary>
/// <returns>TRUE if the item was successfully used</returns>
public bool UseItemOnHand() public bool UseItemOnHand()
{ {
return handler.SendUseItemPacket(0); return handler.SendUseItemPacket(0);
@ -1296,13 +1316,24 @@ namespace MinecraftClient
{ {
return handler.SendInteractEntityPacket(EntityID, type); return handler.SendInteractEntityPacket(EntityID, type);
} }
// not work :(
/// <summary>
/// Place the block at hand in the Minecraft world
/// </summary>
/// <param name="location">Location to place block to</param>
/// <returns>TRUE if successfully placed</returns>
public bool PlaceBlock(Location location) public bool PlaceBlock(Location location)
{ {
//WORK IN PROGRESS. MAY NOT WORK YET
ConsoleIO.WriteLine(location.ToString()); ConsoleIO.WriteLine(location.ToString());
return handler.SendPlayerBlockPlacement(0, location, 1, 0.5f, 0.5f, 0.5f, false); return handler.SendPlayerBlockPlacement(0, location, 1, 0.5f, 0.5f, 0.5f, false);
} }
/// <summary>
/// Change active slot in the player inventory
/// </summary>
/// <param name="slot">Slot to activate (0 to 8)</param>
/// <returns></returns>
public bool ChangeSlot(short slot) public bool ChangeSlot(short slot)
{ {
if (slot >= 0 && slot <= 8) if (slot >= 0 && slot <= 8)

View file

@ -641,30 +641,34 @@ namespace MinecraftClient.Protocol.Handlers
return false; //Currently not implemented return false; //Currently not implemented
} }
//Currently not implemented
public bool SendInteractEntityPacket(int EntityID, int type) public bool SendInteractEntityPacket(int EntityID, int type)
{ {
return false; return false; //Currently not implemented
} }
public bool SendInteractEntityPacket(int EntityID, int type, float X, float Y, float Z, int hand) public bool SendInteractEntityPacket(int EntityID, int type, float X, float Y, float Z, int hand)
{ {
return false; return false; //Currently not implemented
} }
public bool SendInteractEntityPacket(int EntityID, int type, float X, float Y, float Z) public bool SendInteractEntityPacket(int EntityID, int type, float X, float Y, float Z)
{ {
return false; return false; //Currently not implemented
} }
public bool SendUseItemPacket(int hand) public bool SendUseItemPacket(int hand)
{ {
return false; return false; //Currently not implemented
} }
public bool SendPlayerBlockPlacement(int hand, Location location, int face, float CursorX, float CursorY, float CursorZ, bool insideBlock) public bool SendPlayerBlockPlacement(int hand, Location location, int face, float CursorX, float CursorY, float CursorZ, bool insideBlock)
{ {
return false; return false; //Currently not implemented
} }
public bool SendHeldItemChange(short slot) public bool SendHeldItemChange(short slot)
{ {
return false; return false; //Currently not implemented
} }
/// <summary> /// <summary>
@ -672,7 +676,6 @@ namespace MinecraftClient.Protocol.Handlers
/// </summary> /// </summary>
/// <param name="channel">Channel to send packet on</param> /// <param name="channel">Channel to send packet on</param>
/// <param name="data">packet Data</param> /// <param name="data">packet Data</param>
public bool SendPluginChannelPacket(string channel, byte[] data) public bool SendPluginChannelPacket(string channel, byte[] data)
{ {
try { try {

View file

@ -589,7 +589,7 @@ namespace MinecraftClient.Protocol.Handlers
short ItemID = dataTypes.ReadNextShort(packetData); short ItemID = dataTypes.ReadNextShort(packetData);
if (ItemID == -1) if (ItemID == -1)
{ {
handler.OnSetSlot(WindowID, SlotID, false); handler.OnSlotClear(WindowID, SlotID);
} }
else else
{ {
@ -601,7 +601,7 @@ namespace MinecraftClient.Protocol.Handlers
{ {
NBT = dataTypes.ReadNextNbt(packetData); NBT = dataTypes.ReadNextNbt(packetData);
} }
handler.OnSetSlot(WindowID, SlotID, true, ItemID, Count, NBT); handler.OnSetSlot(WindowID, SlotID, ItemID, Count, NBT);
} }
} }
else else
@ -615,11 +615,11 @@ namespace MinecraftClient.Protocol.Handlers
int ItemID = dataTypes.ReadNextVarInt(packetData); int ItemID = dataTypes.ReadNextVarInt(packetData);
byte Count = dataTypes.ReadNextByte(packetData); byte Count = dataTypes.ReadNextByte(packetData);
Dictionary<string, object> NBT = dataTypes.ReadNextNbt(packetData); Dictionary<string, object> NBT = dataTypes.ReadNextNbt(packetData);
handler.OnSetSlot(WindowID, SlotID, Present, ItemID, Count, NBT); handler.OnSetSlot(WindowID, SlotID, ItemID, Count, NBT);
} }
else else
{ {
handler.OnSetSlot(WindowID, SlotID, Present); handler.OnSlotClear(WindowID, SlotID);
} }
} }
} }

View file

@ -85,14 +85,62 @@ namespace MinecraftClient.Protocol
/// <returns>True if message was successfully sent</returns> /// <returns>True if message was successfully sent</returns>
bool SendPluginChannelPacket(string channel, byte[] data); bool SendPluginChannelPacket(string channel, byte[] data);
/// <summary>
/// Send a held item change packet to the server.
/// </summary>
/// <param name="slot">New active slot in the inventory hotbar</param>
/// <returns>True if packet was successfully sent</returns>
bool SendHeldItemChange(short slot); bool SendHeldItemChange(short slot);
/// <summary>
/// Send an entity interaction packet to the server.
/// </summary>
/// <param name="EntityID">Entity ID to interact with</param>
/// <param name="type">Type of interaction (0: interact, 1: attack, 2: interact at)</param>
/// <returns>True if packet was successfully sent</returns>
bool SendInteractEntityPacket(int EntityID, int type); bool SendInteractEntityPacket(int EntityID, int type);
/// <summary>
/// Send an entity interaction packet to the server.
/// </summary>
/// <param name="EntityID">Entity ID to interact with</param>
/// <param name="type">Type of interaction (0: interact, 1: attack, 2: interact at)</param>
/// <param name="X">X coordinate for "interact at"</param>
/// <param name="Y">Y coordinate for "interact at"</param>
/// <param name="Z">Z coordinate for "interact at"</param>
/// <param name="hand">Player hand (0: main hand, 1: off hand)</param>
/// <returns>True if packet was successfully sent</returns>
bool SendInteractEntityPacket(int EntityID, int type, float X, float Y, float Z, int hand); bool SendInteractEntityPacket(int EntityID, int type, float X, float Y, float Z, int hand);
/// <summary>
/// Send an entity interaction packet to the server.
/// </summary>
/// <param name="EntityID">Entity ID to interact with</param>
/// <param name="type">Type of interaction (0: interact, 1: attack, 2: interact at)</param>
/// <param name="X">X coordinate for "interact at"</param>
/// <param name="Y">Y coordinate for "interact at"</param>
/// <param name="Z">Z coordinate for "interact at"</param>
/// <returns>True if packet was successfully sent</returns>
bool SendInteractEntityPacket(int EntityID, int type, float X, float Y, float Z); bool SendInteractEntityPacket(int EntityID, int type, float X, float Y, float Z);
/// <summary>
/// Send a use item packet to the server
/// </summary>
/// <param name="hand">0: main hand, 1: off hand</param>
/// <returns>True if packet was successfully sent</returns>
bool SendUseItemPacket(int hand); bool SendUseItemPacket(int hand);
/// <summary>
/// Send player block placement packet to the server
/// </summary>
/// <param name="hand">0: main hand, 1: off hand</param>
/// <param name="location">Location to place block at</param>
/// <param name="face">Block face</param>
/// <param name="CursorX">Cursor X</param>
/// <param name="CursorY">Cursor Y</param>
/// <param name="CursorZ">Cursor Z</param>
/// <param name="insideBlock">TRUE if inside block</param>
/// <returns>True if packet was successfully sent</returns>
bool SendPlayerBlockPlacement(int hand, Location location, int face, float CursorX, float CursorY, float CursorZ, bool insideBlock); bool SendPlayerBlockPlacement(int hand, Location location, int face, float CursorX, float CursorY, float CursorZ, bool insideBlock);
} }
} }

View file

@ -128,27 +128,102 @@ namespace MinecraftClient.Protocol
/// <param name="data">The data from the channel</param> /// <param name="data">The data from the channel</param>
void OnPluginChannelMessage(string channel, byte[] data); void OnPluginChannelMessage(string channel, byte[] data);
/// <summary>
/// Called when a non-living entity has spawned
/// </summary>
/// <param name="EntityID">Entity ID</param>
/// <param name="EntityType">Entity Type ID</param>
/// <param name="UUID">Entity UUID</param>
/// <param name="location">Entity location</param>
void OnSpawnEntity(int EntityID, int EntityType, Guid UUID, Location location); void OnSpawnEntity(int EntityID, int EntityType, Guid UUID, Location location);
/// <summary>
/// Called when a living entity has spawned
/// </summary>
/// <param name="EntityID">Entity ID</param>
/// <param name="EntityType">Entity Type ID</param>
/// <param name="UUID">Entity UUID</param>
/// <param name="location">Entity location</param>
void OnSpawnLivingEntity(int EntityID, int EntityType, Guid UUID, Location location); void OnSpawnLivingEntity(int EntityID, int EntityType, Guid UUID, Location location);
/// <summary>
/// Called when a player has spawned
/// </summary>
/// <param name="EntityID">Entity ID</param>
/// <param name="UUID">Entity UUID</param>
/// <param name="location">Entity location</param>
/// <param name="Yaw">Player head yaw</param>
/// <param name="Pitch">Player head pitch</param>
void OnSpawnPlayer(int EntityID, Guid UUID, Location location, byte Yaw, byte Pitch); void OnSpawnPlayer(int EntityID, Guid UUID, Location location, byte Yaw, byte Pitch);
/// <summary>
/// Called when entities have despawned
/// </summary>
/// <param name="EntityID">List of Entity ID that have despawned</param>
void OnDestroyEntities(int[] EntityID); void OnDestroyEntities(int[] EntityID);
/// <summary>
/// Called when an entity moved by coordinate offset
/// </summary>
/// <param name="EntityID">Entity ID</param>
/// <param name="Dx">X offset</param>
/// <param name="Dy">Y offset</param>
/// <param name="Dz">Z offset</param>
/// <param name="onGround">TRUE if on ground</param>
void OnEntityPosition(int EntityID, Double Dx, Double Dy, Double Dz,bool onGround); void OnEntityPosition(int EntityID, Double Dx, Double Dy, Double Dz,bool onGround);
void OnEntityProperties(int EntityID, Dictionary<string, Double> prop); /// <summary>
/// Called when an entity moved to fixed coordinates
void OnTimeUpdate(long WorldAge, long TimeOfDay); /// </summary>
/// <param name="EntityID">Entity ID</param>
/// <param name="Dx">X</param>
/// <param name="Dy">Y</param>
/// <param name="Dz">Z</param>
/// <param name="onGround">TRUE if on ground</param>
void OnEntityTeleport(int EntityID, Double X, Double Y, Double Z, bool onGround); void OnEntityTeleport(int EntityID, Double X, Double Y, Double Z, bool onGround);
/// <summary>
/// Called when additional properties have been received for an entity
/// </summary>
/// <param name="EntityID">Entity ID</param>
/// <param name="prop">Dictionary of properties</param>
void OnEntityProperties(int EntityID, Dictionary<string, Double> prop);
/// <summary>
/// Called when the world age has been updated
/// </summary>
/// <param name="WorldAge">World age</param>
/// <param name="TimeOfDay">Time of Day</param>
void OnTimeUpdate(long WorldAge, long TimeOfDay);
/// <summary>
/// Called when inventory items have been received
/// </summary>
/// <param name="type">Inventory type</param>
/// <param name="itemList">Item list</param>
void OnWindowItems(int type, Dictionary<int, MinecraftClient.Inventory.Item> itemList); void OnWindowItems(int type, Dictionary<int, MinecraftClient.Inventory.Item> itemList);
void OnSetSlot(byte WindowID, short SlotID, bool Present); /// <summary>
void OnSetSlot(byte WindowID, short SlotID, bool Present, int ItemID, byte Count, Dictionary<string, object> NBT); /// Called when a single slot has been cleared inside an inventory
/// </summary>
/// <param name="WindowID">Inventory ID</param>
/// <param name="SlotID">Slot ID</param>
void OnSlotClear(byte WindowID, short SlotID);
/// <summary>
/// Called when a single slot has been updated inside an inventory
/// </summary>
/// <param name="WindowID">Inventory ID</param>
/// <param name="SlotID">Slot ID</param>
/// <param name="ItemID">Item ID</param>
/// <param name="Count">Item Count</param>
/// <param name="NBT">Item Metadata</param>
void OnSetSlot(byte WindowID, short SlotID, int ItemID, byte Count, Dictionary<string, object> NBT);
/// <summary>
/// Called when the Player entity ID has been received from the server
/// </summary>
/// <param name="EntityID">Player entity ID</param>
void SetPlayerEntityID(int EntityID); void SetPlayerEntityID(int EntityID);
} }
} }

View file

@ -261,7 +261,7 @@ Also, remember that when you connect to a server with this program, you will app
This means that **you can die if you log in in an unsafe place on a survival server!** This means that **you can die if you log in in an unsafe place on a survival server!**
Use the script scheduler bot to send a teleport command after logging in. Use the script scheduler bot to send a teleport command after logging in.
You have been reminded that **you may get banned** by your server for using this program. Use accordinly with server rules. We remind you that **you may get banned** by your server for using this program. Use accordingly with server rules.
License License
------ ------

View file

@ -32,15 +32,15 @@ Edit `MinecraftClient.csproj` to set the Build target to `Release` on [line 4](h
### On Windows ### On Windows
1. Locate MSBuild.exe for .NET 4 inside `C:\Windows\Microsoft.NET\Framework\v4.X.XXXXX` 1. Locate `MSBuild.exe` for .NET 4 inside `C:\Windows\Microsoft.NET\Framework\v4.X.XXXXX`
2. Drag and drop `MinecraftClient.csproj` over `MSBuild.exe` to launch the build 2. Drag and drop `MinecraftClient.csproj` over `MSBuild.exe` to launch the build
3. If the build succeededs, you can find `MinecraftClient.exe` under `MinecraftClient\bin\Release` 3. If the build succeeds, you can find `MinecraftClient.exe` under `MinecraftClient\bin\Release`
### On Mac and Linux ### On Mac and Linux
1. Install the [Mono Framework](https://www.mono-project.com/download/stable/#download-lin) if not already installed 1. Install the [Mono Framework](https://www.mono-project.com/download/stable/#download-lin) if not already installed
2. Run `msbuild MinecraftClient.csproj` in a terminal 2. Run `msbuild MinecraftClient.csproj` in a terminal
3. If the build succeededs, you can find `MinecraftClient.exe` under `MinecraftClient\bin\Release` 3. If the build succeeds, you can find `MinecraftClient.exe` under `MinecraftClient\bin\Release`
## How to contribute ## How to contribute