diff --git a/MinecraftClient/McClient.cs b/MinecraftClient/McClient.cs
index a8d71884..a098fd87 100644
--- a/MinecraftClient/McClient.cs
+++ b/MinecraftClient/McClient.cs
@@ -1100,6 +1100,51 @@ namespace MinecraftClient
#region Event handlers: An event occurs on the Server
+ ///
+ /// Dispatch a ChatBot event with automatic exception handling
+ ///
+ ///
+ /// Example for calling SomeEvent() on all bots at once:
+ /// DispatchBotEvent(bot => bot.SomeEvent());
+ ///
+ /// Action to execute on each bot
+ /// Only fire the event for the specified bot list (default: all bots)
+ private void DispatchBotEvent(Action action, IEnumerable botList = null)
+ {
+ ChatBot[] selectedBots;
+
+ if (botList != null)
+ {
+ selectedBots = botList.ToArray();
+ }
+ else
+ {
+ selectedBots = bots.ToArray();
+ }
+
+ foreach (ChatBot bot in selectedBots)
+ {
+ try
+ {
+ action(bot);
+ }
+ catch (Exception e)
+ {
+ if (!(e is ThreadAbortException))
+ {
+ //Retrieve parent method name to determine which event caused the exception
+ System.Diagnostics.StackFrame frame = new System.Diagnostics.StackFrame(1);
+ System.Reflection.MethodBase method = frame.GetMethod();
+ string parentMethodName = method.Name;
+
+ //Display a meaningful error message to help debugging the ChatBot
+ ConsoleIO.WriteLogLine(parentMethodName + ": Got error from " + bot.ToString() + ": " + e.ToString());
+ }
+ else throw; //ThreadAbortException should not be caught here as in can happen when disconnecting from server
+ }
+ }
+ }
+
///
/// Called when a server was successfully joined
///
@@ -1118,27 +1163,7 @@ namespace MinecraftClient
Settings.MCSettings_Skin_All,
Settings.MCSettings_MainHand);
- if (inventoryHandlingEnabled)
- {
- inventories.Clear();
- inventories[0] = new Container(0, ContainerType.PlayerInventory, "Player Inventory");
- }
-
- foreach (ChatBot bot in bots.ToArray())
- {
- try
- {
- bot.AfterGameJoined();
- }
- catch (Exception e)
- {
- if (!(e is ThreadAbortException))
- {
- ConsoleIO.WriteLogLine("AfterGameJoined: Got error from " + bot.ToString() + ": " + e.ToString());
- }
- else throw; //ThreadAbortException should not be caught
- }
- }
+ DispatchBotEvent(bot => bot.AfterGameJoined());
if (inventoryHandlingRequested)
{
@@ -1146,6 +1171,8 @@ namespace MinecraftClient
inventoryHandlingEnabled = true;
ConsoleIO.WriteLogLine("Inventory handling is now enabled.");
}
+
+ ClearInventories();
}
///
@@ -1153,12 +1180,6 @@ namespace MinecraftClient
///
public void OnRespawn()
{
- if (inventoryHandlingEnabled)
- {
- inventories.Clear();
- inventories[0] = new Container(0, ContainerType.PlayerInventory, "Player Inventory");
- }
-
if (terrainAndMovementsRequested)
{
terrainAndMovementsEnabled = true;
@@ -1170,6 +1191,8 @@ namespace MinecraftClient
{
world.Clear();
}
+
+ ClearInventories();
}
///
@@ -1274,34 +1297,24 @@ namespace MinecraftClient
{
lastKeepAlive = DateTime.Now;
}
+
List links = new List();
string json = null;
+
if (isJson)
{
json = text;
text = ChatParser.ParseText(json, links);
}
+
ConsoleIO.WriteLineFormatted(text, true);
+
if (Settings.DisplayChatLinks)
foreach (string link in links)
ConsoleIO.WriteLogLine("Link: " + link, false);
- foreach (ChatBot bot in bots.ToArray())
- {
- try
- {
- bot.GetText(text);
- if (bots.Contains(bot))
- bot.GetText(text, json);
- }
- catch (Exception e)
- {
- if (!(e is ThreadAbortException))
- {
- ConsoleIO.WriteLogLine("GetText: Got error from " + bot.ToString() + ": " + e.ToString());
- }
- else throw; //ThreadAbortException should not be caught
- }
- }
+
+ DispatchBotEvent(bot => bot.GetText(text));
+ DispatchBotEvent(bot => bot.GetText(text, json));
}
///
@@ -1440,10 +1453,7 @@ namespace MinecraftClient
if (registeredBotPluginChannels.ContainsKey(channel))
{
- foreach (ChatBot bot in registeredBotPluginChannels[channel])
- {
- bot.OnPluginMessage(channel, data);
- }
+ DispatchBotEvent(bot => bot.OnPluginMessage(channel, data), registeredBotPluginChannels[channel]);
}
}
@@ -1457,22 +1467,7 @@ namespace MinecraftClient
OnDestroyEntities(new[] { entity.ID });
entities.Add(entity.ID, entity);
-
- foreach (ChatBot bot in bots.ToArray())
- {
- try
- {
- bot.OnEntitySpawn(entity);
- }
- catch (Exception e)
- {
- if (!(e is ThreadAbortException))
- {
- ConsoleIO.WriteLogLine("OnEntitySpawn: Got error from " + bot.ToString() + ": " + e.ToString());
- }
- else throw; //ThreadAbortException should not be caught
- }
- }
+ DispatchBotEvent(bot => bot.OnEntitySpawn(entity));
}
///
@@ -1495,21 +1490,9 @@ namespace MinecraftClient
/// Item)
public void OnEntityEquipment(int entityid, int slot, Item item)
{
- foreach (ChatBot bot in bots.ToArray())
+ if (entities.ContainsKey(entityid))
{
- try
- {
- if (entities.ContainsKey(entityid))
- bot.OnEntityEquipment(entities[entityid], slot, item);
- }
- catch (Exception e)
- {
- if (!(e is ThreadAbortException))
- {
- ConsoleIO.WriteLogLine("OnEntityEquipment: Got error from " + bot.ToString() + ": " + e.ToString());
- }
- else throw; //ThreadAbortException should not be caught
- }
+ DispatchBotEvent(bot => bot.OnEntityEquipment(entities[entityid], slot, item));
}
}
@@ -1531,8 +1514,7 @@ namespace MinecraftClient
string playerName = onlinePlayers[uuid];
if (playerName == this.username)
this.gamemode = gamemode;
- foreach (ChatBot bot in bots.ToArray())
- bot.OnGamemodeUpdate(playerName, uuid, gamemode);
+ DispatchBotEvent(bot => bot.OnGamemodeUpdate(playerName, uuid, gamemode));
}
}
@@ -1545,21 +1527,7 @@ namespace MinecraftClient
{
if (entities.ContainsKey(a))
{
- foreach (ChatBot bot in bots.ToArray())
- {
- try
- {
- bot.OnEntityDespawn(entities[a]);
- }
- catch (Exception e)
- {
- if (!(e is ThreadAbortException))
- {
- ConsoleIO.WriteLogLine("OnEntityDespawn: Got error from " + bot.ToString() + ": " + e.ToString());
- }
- else throw; //ThreadAbortException should not be caught
- }
- }
+ DispatchBotEvent(bot => bot.OnEntityDespawn(entities[a]));
entities.Remove(a);
}
}
@@ -1582,22 +1550,7 @@ namespace MinecraftClient
L.Y += Dy;
L.Z += Dz;
entities[EntityID].Location = L;
-
- foreach (ChatBot bot in bots.ToArray())
- {
- try
- {
- bot.OnEntityMove(entities[EntityID]);
- }
- catch (Exception e)
- {
- if (!(e is ThreadAbortException))
- {
- ConsoleIO.WriteLogLine("OnEntityMove: Got error from " + bot.ToString() + ": " + e.ToString());
- }
- else throw; //ThreadAbortException should not be caught
- }
- }
+ DispatchBotEvent(bot => bot.OnEntityMove(entities[EntityID]));
}
}
@@ -1616,22 +1569,7 @@ namespace MinecraftClient
{
Location location = new Location(X, Y, Z);
entities[EntityID].Location = location;
-
- foreach (ChatBot bot in bots.ToArray())
- {
- try
- {
- bot.OnEntityMove(entities[EntityID]);
- }
- catch (Exception e)
- {
- if (!(e is ThreadAbortException))
- {
- ConsoleIO.WriteLogLine("OnEntityMove: Got error from " + bot.ToString() + ": " + e.ToString());
- }
- else throw; //ThreadAbortException should not be caught
- }
- }
+ DispatchBotEvent(bot => bot.OnEntityMove(entities[EntityID]));
}
}
@@ -1644,21 +1582,7 @@ namespace MinecraftClient
{
if (EntityID == playerEntityID)
{
- foreach (ChatBot bot in bots.ToArray())
- {
- try
- {
- bot.OnPlayerProperty(prop);
- }
- catch (Exception e)
- {
- if (!(e is ThreadAbortException))
- {
- ConsoleIO.WriteLogLine("OnPlayerProperty: Got error from " + bot.ToString() + ": " + e.ToString());
- }
- else throw; //ThreadAbortException should not be caught
- }
- }
+ DispatchBotEvent(bot => bot.OnPlayerProperty(prop));
}
}
@@ -1680,22 +1604,7 @@ namespace MinecraftClient
if (tps <= 20.0 && tps >= 0.0 && serverTPS != tps)
{
serverTPS = tps;
- // invoke ChatBot
- foreach (ChatBot bot in bots.ToArray())
- {
- try
- {
- bot.OnServerTpsUpdate(tps);
- }
- catch (Exception e)
- {
- if (!(e is ThreadAbortException))
- {
- ConsoleIO.WriteLogLine("OnServerTpsUpdate: Got error from " + bot.ToString() + ": " + e.ToString());
- }
- else throw; //ThreadAbortException should not be caught
- }
- }
+ DispatchBotEvent(bot => bot.OnServerTpsUpdate(tps));
}
}
else
@@ -1713,6 +1622,7 @@ namespace MinecraftClient
{
playerHealth = health;
playerFoodSaturation = food;
+
if (health <= 0)
{
if (Settings.AutoRespawn)
@@ -1725,21 +1635,8 @@ namespace MinecraftClient
ConsoleIO.WriteLogLine("You are dead. Type /respawn to respawn.");
}
}
- foreach (ChatBot bot in bots.ToArray())
- {
- try
- {
- bot.OnHealthUpdate(health, food);
- }
- catch (Exception e)
- {
- if (!(e is ThreadAbortException))
- {
- ConsoleIO.WriteLogLine("OnHealthUpdate: Got error from " + bot.ToString() + ": " + e.ToString());
- }
- else throw; //ThreadAbortException should not be caught
- }
- }
+
+ DispatchBotEvent(bot => bot.OnHealthUpdate(health, food));
}
///
@@ -1752,21 +1649,7 @@ namespace MinecraftClient
{
playerLevel = Level;
playerTotalExperience = TotalExperience;
- foreach (ChatBot bot in bots.ToArray())
- {
- try
- {
- bot.OnSetExperience(Experiencebar, Level, TotalExperience);
- }
- catch (Exception e)
- {
- if (!(e is ThreadAbortException))
- {
- ConsoleIO.WriteLogLine("OnSetExperience: Got error from " + bot.ToString() + ": " + e.ToString());
- }
- else throw; //ThreadAbortException should not be caught
- }
- }
+ DispatchBotEvent(bot => bot.OnSetExperience(Experiencebar, Level, TotalExperience));
}
///
@@ -1777,21 +1660,7 @@ namespace MinecraftClient
/// Amount of affected blocks
public void OnExplosion(Location location, float strength, int affectedBlocks)
{
- foreach (ChatBot bot in bots.ToArray())
- {
- try
- {
- bot.OnExplosion(location, strength, affectedBlocks);
- }
- catch (Exception e)
- {
- if (!(e is ThreadAbortException))
- {
- ConsoleIO.WriteLogLine("OnExplosion: Got error from " + bot.ToString() + ": " + e.ToString());
- }
- else throw; //ThreadAbortException should not be caught
- }
- }
+ DispatchBotEvent(bot => bot.OnExplosion(location, strength, affectedBlocks));
}
///
@@ -1805,21 +1674,7 @@ namespace MinecraftClient
if (onlinePlayers.ContainsKey(uuid))
{
playerName = onlinePlayers[uuid];
- foreach (ChatBot bot in bots.ToArray())
- {
- try
- {
- bot.OnLatencyUpdate(playerName, uuid, latency);
- }
- catch (Exception e)
- {
- if (!(e is ThreadAbortException))
- {
- ConsoleIO.WriteLogLine("OnLatencyUpdate: Got error from " + bot.ToString() + ": " + e.ToString());
- }
- else throw; //ThreadAbortException should not be caught
- }
- }
+ DispatchBotEvent(bot => bot.OnLatencyUpdate(playerName, uuid, latency));
}
}
@@ -1829,22 +1684,8 @@ namespace MinecraftClient
/// item slot
public void OnHeldItemChange(byte slot)
{
- foreach (ChatBot bot in bots.ToArray())
- {
- try
- {
- bot.OnHeldItemChange(slot);
- }
- catch (Exception e)
- {
- if (!(e is ThreadAbortException))
- {
- ConsoleIO.WriteLogLine("OnHeldItemChange: Got error from " + bot.ToString() + ": " + e.ToString());
- }
- else throw; //ThreadAbortException should not be caught
- }
- }
CurrentSlot = slot;
+ DispatchBotEvent(bot => bot.OnHeldItemChange(slot));
}
///
@@ -1857,21 +1698,7 @@ namespace MinecraftClient
///
public void OnMapData(int mapid, byte scale, bool trackingposition, bool locked, int iconcount)
{
- foreach (ChatBot bot in bots.ToArray())
- {
- try
- {
- bot.OnMapData(mapid, scale, trackingposition, locked, iconcount);
- }
- catch (Exception e)
- {
- if (!(e is ThreadAbortException))
- {
- ConsoleIO.WriteLogLine("OnMapData: Got error from " + bot.ToString() + ": " + e.ToString());
- }
- else throw; //ThreadAbortException should not be caught
- }
- }
+ DispatchBotEvent(bot => bot.OnMapData(mapid, scale, trackingposition, locked, iconcount));
}
///
@@ -1886,21 +1713,7 @@ namespace MinecraftClient
/// json text
public void OnTitle(int action, string titletext, string subtitletext, string actionbartext, int fadein, int stay, int fadeout, string json)
{
- foreach (ChatBot bot in bots.ToArray())
- {
- try
- {
- bot.OnTitle(action, titletext, subtitletext, actionbartext, fadein, stay, fadeout, json);
- }
- catch (Exception e)
- {
- if (!(e is ThreadAbortException))
- {
- ConsoleIO.WriteLogLine("OnTitle: Got error from " + bot.ToString() + ": " + e.ToString());
- }
- else throw; //ThreadAbortException should not be caught
- }
- }
+ DispatchBotEvent(bot => bot.OnTitle(action, titletext, subtitletext, actionbartext, fadein, stay, fadeout, json));
}
#endregion