Catch exceptions from ChatBots for new API events

This commit is contained in:
ORelio 2020-04-02 23:31:00 +02:00
parent 7b049576a3
commit fe020c74c7
4 changed files with 167 additions and 18 deletions

View file

@ -386,7 +386,20 @@ namespace MinecraftClient
public void Disconnect() public void Disconnect()
{ {
foreach (ChatBot bot in bots.ToArray()) foreach (ChatBot bot in bots.ToArray())
{
try
{
bot.OnDisconnect(ChatBot.DisconnectReason.UserLogout, ""); bot.OnDisconnect(ChatBot.DisconnectReason.UserLogout, "");
}
catch (Exception e)
{
if (!(e is ThreadAbortException))
{
ConsoleIO.WriteLogLine("OnDisconnect: Got error from " + bot.ToString() + ": " + e.ToString());
}
else throw; //ThreadAbortException should not be caught
}
}
botsOnHold.Clear(); botsOnHold.Clear();
botsOnHold.AddRange(bots); botsOnHold.AddRange(bots);
@ -456,6 +469,7 @@ namespace MinecraftClient
{ {
if (!String.IsNullOrWhiteSpace(Settings.BrandInfo)) if (!String.IsNullOrWhiteSpace(Settings.BrandInfo))
handler.SendBrandInfo(Settings.BrandInfo.Trim()); handler.SendBrandInfo(Settings.BrandInfo.Trim());
if (Settings.MCSettings_Enabled) if (Settings.MCSettings_Enabled)
handler.SendClientSettings( handler.SendClientSettings(
Settings.MCSettings_Locale, Settings.MCSettings_Locale,
@ -465,8 +479,23 @@ namespace MinecraftClient
Settings.MCSettings_ChatColors, Settings.MCSettings_ChatColors,
Settings.MCSettings_Skin_All, Settings.MCSettings_Skin_All,
Settings.MCSettings_MainHand); Settings.MCSettings_MainHand);
foreach (ChatBot bot in bots.ToArray()) foreach (ChatBot bot in bots.ToArray())
{
try
{
bot.AfterGameJoined(); 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
}
}
if (inventoryHandlingRequested) if (inventoryHandlingRequested)
{ {
inventoryHandlingRequested = false; inventoryHandlingRequested = false;
@ -882,7 +911,20 @@ namespace MinecraftClient
} }
foreach (ChatBot bot in bots.ToArray()) foreach (ChatBot bot in bots.ToArray())
{
try
{
will_restart |= bot.OnDisconnect(reason, message); will_restart |= bot.OnDisconnect(reason, message);
}
catch (Exception e)
{
if (!(e is ThreadAbortException))
{
ConsoleIO.WriteLogLine("OnDisconnect: Got error from " + bot.ToString() + ": " + e.ToString());
}
else throw; //ThreadAbortException should not be caught
}
}
if (!will_restart) if (!will_restart)
Program.HandleFailure(); Program.HandleFailure();
@ -893,7 +935,7 @@ namespace MinecraftClient
/// </summary> /// </summary>
public void OnUpdate() public void OnUpdate()
{ {
foreach (var bot in bots.ToArray()) foreach (ChatBot bot in bots.ToArray())
{ {
try try
{ {
@ -1161,8 +1203,21 @@ namespace MinecraftClient
Entity entity = new Entity(EntityID, TypeID, EntityType.NonLivingThings, location); Entity entity = new Entity(EntityID, TypeID, EntityType.NonLivingThings, location);
entities.Add(EntityID, entity); entities.Add(EntityID, entity);
foreach (ChatBot bot in bots.ToArray()) foreach (ChatBot bot in bots.ToArray())
{
try
{
bot.OnEntitySpawn(entity); 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
}
}
}
/// <summary> /// <summary>
/// Called when an Entity was created/spawned. /// Called when an Entity was created/spawned.
@ -1178,8 +1233,21 @@ namespace MinecraftClient
Entity entity = new Entity(EntityID, TypeID, EntityType.MobAndAnimal, location); Entity entity = new Entity(EntityID, TypeID, EntityType.MobAndAnimal, location);
entities.Add(EntityID, entity); entities.Add(EntityID, entity);
foreach (ChatBot bot in bots.ToArray()) foreach (ChatBot bot in bots.ToArray())
{
try
{
bot.OnEntitySpawn(entity); 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
}
}
}
/// <summary> /// <summary>
/// Called when a player was spawned/in the render distance /// Called when a player was spawned/in the render distance
@ -1195,8 +1263,21 @@ namespace MinecraftClient
Entity entity = new Entity(EntityID, EntityType.Player, location); Entity entity = new Entity(EntityID, EntityType.Player, location);
entities.Add(EntityID, entity); entities.Add(EntityID, entity);
foreach (ChatBot bot in bots.ToArray()) foreach (ChatBot bot in bots.ToArray())
{
try
{
bot.OnEntitySpawn(entity); 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
}
}
}
/// <summary> /// <summary>
/// Called when entities dead/despawn. /// Called when entities dead/despawn.
@ -1209,7 +1290,20 @@ namespace MinecraftClient
if (entities.ContainsKey(a)) if (entities.ContainsKey(a))
{ {
foreach (ChatBot bot in bots.ToArray()) foreach (ChatBot bot in bots.ToArray())
{
try
{
bot.OnEntityDespawn(new Entity(entities[a].ID, entities[a].TypeID, entities[a].Type, entities[a].Location)); bot.OnEntityDespawn(new Entity(entities[a].ID, entities[a].TypeID, entities[a].Type, entities[a].Location));
}
catch (Exception e)
{
if (!(e is ThreadAbortException))
{
ConsoleIO.WriteLogLine("OnEntityDespawn: Got error from " + bot.ToString() + ": " + e.ToString());
}
else throw; //ThreadAbortException should not be caught
}
}
entities.Remove(a); entities.Remove(a);
} }
} }
@ -1234,8 +1328,21 @@ namespace MinecraftClient
entities[EntityID].Location = L; entities[EntityID].Location = L;
foreach (ChatBot bot in bots.ToArray()) foreach (ChatBot bot in bots.ToArray())
{
try
{
bot.OnEntityMove(new Entity(entities[EntityID].ID, entities[EntityID].TypeID, entities[EntityID].Type, entities[EntityID].Location)); bot.OnEntityMove(new Entity(entities[EntityID].ID, entities[EntityID].TypeID, entities[EntityID].Type, entities[EntityID].Location));
} }
catch (Exception e)
{
if (!(e is ThreadAbortException))
{
ConsoleIO.WriteLogLine("OnEntityMove: Got error from " + bot.ToString() + ": " + e.ToString());
}
else throw; //ThreadAbortException should not be caught
}
}
}
} }
/// <summary> /// <summary>
@ -1254,8 +1361,21 @@ namespace MinecraftClient
entities[EntityID].Location = location; entities[EntityID].Location = location;
foreach (ChatBot bot in bots.ToArray()) foreach (ChatBot bot in bots.ToArray())
{
try
{
bot.OnEntityMove(new Entity(entities[EntityID].ID, entities[EntityID].TypeID, entities[EntityID].Type, entities[EntityID].Location)); bot.OnEntityMove(new Entity(entities[EntityID].ID, entities[EntityID].TypeID, entities[EntityID].Type, entities[EntityID].Location));
} }
catch (Exception e)
{
if (!(e is ThreadAbortException))
{
ConsoleIO.WriteLogLine("OnEntityMove: Got error from " + bot.ToString() + ": " + e.ToString());
}
else throw; //ThreadAbortException should not be caught
}
}
}
} }
/// <summary> /// <summary>
@ -1268,8 +1388,21 @@ namespace MinecraftClient
if(EntityID == playerEntityID) if(EntityID == playerEntityID)
{ {
foreach (ChatBot bot in bots.ToArray()) foreach (ChatBot bot in bots.ToArray())
{
try
{
bot.OnPlayerProperty(prop); 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
}
}
}
} }
/// <summary> /// <summary>
@ -1292,8 +1425,21 @@ namespace MinecraftClient
serverTPS = tps; serverTPS = tps;
// invoke ChatBot // invoke ChatBot
foreach (ChatBot bot in bots.ToArray()) foreach (ChatBot bot in bots.ToArray())
{
try
{
bot.OnServerTpsUpdate(tps); 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
}
}
}
} }
else else
{ {

View file

@ -12,7 +12,7 @@ using MinecraftClient.WinAPI;
namespace MinecraftClient namespace MinecraftClient
{ {
/// <summary> /// <summary>
/// Minecraft Console Client by ORelio and Contributors (c) 2012-2019. /// Minecraft Console Client by ORelio and Contributors (c) 2012-2020.
/// Allows to connect to any Minecraft server, send and receive text, automated scripts. /// Allows to connect to any Minecraft server, send and receive text, automated scripts.
/// This source code is released under the CDDL 1.0 License. /// This source code is released under the CDDL 1.0 License.
/// </summary> /// </summary>
@ -20,6 +20,7 @@ namespace MinecraftClient
/// Typical steps to update MCC for a new Minecraft version /// Typical steps to update MCC for a new Minecraft version
/// - Implement protocol changes (see Protocol18.cs) /// - Implement protocol changes (see Protocol18.cs)
/// - Handle new block types and states (see Material.cs) /// - Handle new block types and states (see Material.cs)
/// - Add new item types for inventories (see ItemType.cs)
/// - Mark new version as handled (see ProtocolHandler.cs) /// - Mark new version as handled (see ProtocolHandler.cs)
/// - Update MCHighestVersion field below (for versionning) /// - Update MCHighestVersion field below (for versionning)
/// </remarks> /// </remarks>

View file

@ -22,6 +22,7 @@ namespace MinecraftClient.Protocol.Handlers
/// - Perform a diff between latest supported version in MCC and new stable version to support on https://wiki.vg/Protocol /// - Perform a diff between latest supported version in MCC and new stable version to support on https://wiki.vg/Protocol
/// - If there are any changes in packets implemented by MCC, add MCXXXVersion field below and implement new packet layouts /// - If there are any changes in packets implemented by MCC, add MCXXXVersion field below and implement new packet layouts
/// - If packet IDs were changed, also update getPacketIncomingType() and getPacketOutgoingID() inside Protocol18PacketTypes.cs /// - If packet IDs were changed, also update getPacketIncomingType() and getPacketOutgoingID() inside Protocol18PacketTypes.cs
/// - Also see Material.cs and ItemType.cs for updating block and item data inside MCC
/// </remarks> /// </remarks>
class Protocol18Handler : IMinecraftCom class Protocol18Handler : IMinecraftCom
{ {
@ -70,13 +71,13 @@ namespace MinecraftClient.Protocol.Handlers
handler.SetTerrainEnabled(false); handler.SetTerrainEnabled(false);
} }
if (handler.GetInventoryEnabled() && (protocolversion > MC1152Version || protocolversion < MC110Version)) if (handler.GetInventoryEnabled() && (protocolversion < MC110Version || protocolversion > MC1152Version))
{ {
ConsoleIO.WriteLineFormatted("§8Inventories are currently not handled for that MC version."); ConsoleIO.WriteLineFormatted("§8Inventories are currently not handled for that MC version.");
handler.SetInventoryEnabled(false); handler.SetInventoryEnabled(false);
} }
if(handler.GetEntityHandlingEnabled() && protocolversion <= MC1122Version) if (handler.GetEntityHandlingEnabled() && (protocolversion <= MC1122Version || protocolversion > MC1152Version))
{ {
ConsoleIO.WriteLineFormatted("§8Entities are currently not handled for that MC version."); ConsoleIO.WriteLineFormatted("§8Entities are currently not handled for that MC version.");
handler.SetEntityHandlingEnabled(false); handler.SetEntityHandlingEnabled(false);

View file

@ -237,11 +237,12 @@ namespace MinecraftClient
case "showxpbarmessages": DisplayXPBarMessages = str2bool(argValue); break; case "showxpbarmessages": DisplayXPBarMessages = str2bool(argValue); break;
case "showchatlinks": DisplayChatLinks = str2bool(argValue); break; case "showchatlinks": DisplayChatLinks = str2bool(argValue); break;
case "terrainandmovements": TerrainAndMovements = str2bool(argValue); break; case "terrainandmovements": TerrainAndMovements = str2bool(argValue); break;
case "entityhandling": EntityHandling = str2bool(argValue); break;
case "enableentityhandling": EntityHandling = str2bool(argValue); break;
case "inventoryhandling": InventoryHandling = str2bool(argValue); break; case "inventoryhandling": InventoryHandling = str2bool(argValue); break;
case "privatemsgscmdname": PrivateMsgsCmdName = argValue.ToLower().Trim(); break; case "privatemsgscmdname": PrivateMsgsCmdName = argValue.ToLower().Trim(); break;
case "botmessagedelay": botMessageDelay = TimeSpan.FromSeconds(str2int(argValue)); break; case "botmessagedelay": botMessageDelay = TimeSpan.FromSeconds(str2int(argValue)); break;
case "debugmessages": DebugMessages = str2bool(argValue); break; case "debugmessages": DebugMessages = str2bool(argValue); break;
case "enableentityhandling": EntityHandling = str2bool(argValue); break;
case "autorespawn": AutoRespawn = str2bool(argValue); break; case "autorespawn": AutoRespawn = str2bool(argValue); break;
case "botowners": case "botowners":
@ -576,7 +577,8 @@ namespace MinecraftClient
+ "showxpbarmessages=true # Messages displayed above xp bar\r\n" + "showxpbarmessages=true # Messages displayed above xp bar\r\n"
+ "showchatlinks=true # Show links embedded in chat messages\r\n" + "showchatlinks=true # Show links embedded in chat messages\r\n"
+ "terrainandmovements=false # Uses more ram, cpu, bandwidth\r\n" + "terrainandmovements=false # Uses more ram, cpu, bandwidth\r\n"
+ "inventoryhandling=false # Toggle inventory handling (experimental, enable only for development)\r\n" + "inventoryhandling=false # Toggle inventory handling (beta)\r\n"
+ "entityhandling=false # Toggle entity handling (beta)\r\n"
+ "sessioncache=disk # How to retain session tokens. Use 'none', 'memory' or 'disk'\r\n" + "sessioncache=disk # How to retain session tokens. Use 'none', 'memory' or 'disk'\r\n"
+ "resolvesrvrecords=fast # Use 'false', 'fast' (5s timeout), or 'true'. Required for joining some servers.\r\n" + "resolvesrvrecords=fast # Use 'false', 'fast' (5s timeout), or 'true'. Required for joining some servers.\r\n"
+ "accountlist=accounts.txt # See README > 'Servers and Accounts file' for more info about this file\r\n" + "accountlist=accounts.txt # See README > 'Servers and Accounts file' for more info about this file\r\n"
@ -586,7 +588,6 @@ namespace MinecraftClient
+ "debugmessages=false # Please enable this before submitting bug reports. Thanks!\r\n" + "debugmessages=false # Please enable this before submitting bug reports. Thanks!\r\n"
+ "scriptcache=true # Cache compiled scripts for faster load on low-end devices\r\n" + "scriptcache=true # Cache compiled scripts for faster load on low-end devices\r\n"
+ "timestamps=false # Prepend timestamps to chat messages\r\n" + "timestamps=false # Prepend timestamps to chat messages\r\n"
+ "enableentityhandling=false # Toggle entities handling\r\n"
+ "autorespawn=false # Toggle auto respawn if client player was dead (make sure your spawn point is safe)\r\n" + "autorespawn=false # Toggle auto respawn if client player was dead (make sure your spawn point is safe)\r\n"
+ "\r\n" + "\r\n"
+ "[AppVars]\r\n" + "[AppVars]\r\n"