From fe020c74c7f627bbc776d88dfe41545929e66bbb Mon Sep 17 00:00:00 2001 From: ORelio Date: Thu, 2 Apr 2020 23:31:00 +0200 Subject: [PATCH] Catch exceptions from ChatBots for new API events --- MinecraftClient/McTcpClient.cs | 170 ++++++++++++++++-- MinecraftClient/Program.cs | 3 +- .../Protocol/Handlers/Protocol18.cs | 5 +- MinecraftClient/Settings.cs | 7 +- 4 files changed, 167 insertions(+), 18 deletions(-) diff --git a/MinecraftClient/McTcpClient.cs b/MinecraftClient/McTcpClient.cs index 67f29360..d6f8f79b 100644 --- a/MinecraftClient/McTcpClient.cs +++ b/MinecraftClient/McTcpClient.cs @@ -386,7 +386,20 @@ namespace MinecraftClient public void Disconnect() { foreach (ChatBot bot in bots.ToArray()) - bot.OnDisconnect(ChatBot.DisconnectReason.UserLogout, ""); + { + try + { + 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.AddRange(bots); @@ -456,6 +469,7 @@ namespace MinecraftClient { if (!String.IsNullOrWhiteSpace(Settings.BrandInfo)) handler.SendBrandInfo(Settings.BrandInfo.Trim()); + if (Settings.MCSettings_Enabled) handler.SendClientSettings( Settings.MCSettings_Locale, @@ -465,8 +479,23 @@ namespace MinecraftClient Settings.MCSettings_ChatColors, Settings.MCSettings_Skin_All, Settings.MCSettings_MainHand); + foreach (ChatBot bot in bots.ToArray()) - bot.AfterGameJoined(); + { + 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 + } + } + if (inventoryHandlingRequested) { inventoryHandlingRequested = false; @@ -882,7 +911,20 @@ namespace MinecraftClient } foreach (ChatBot bot in bots.ToArray()) - will_restart |= bot.OnDisconnect(reason, message); + { + try + { + 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) Program.HandleFailure(); @@ -893,7 +935,7 @@ namespace MinecraftClient /// public void OnUpdate() { - foreach (var bot in bots.ToArray()) + foreach (ChatBot bot in bots.ToArray()) { try { @@ -1161,7 +1203,20 @@ namespace MinecraftClient Entity entity = new Entity(EntityID, TypeID, EntityType.NonLivingThings, location); entities.Add(EntityID, entity); foreach (ChatBot bot in bots.ToArray()) - bot.OnEntitySpawn(entity); + { + 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 + } + } } /// @@ -1178,7 +1233,20 @@ namespace MinecraftClient Entity entity = new Entity(EntityID, TypeID, EntityType.MobAndAnimal, location); entities.Add(EntityID, entity); foreach (ChatBot bot in bots.ToArray()) - bot.OnEntitySpawn(entity); + { + 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 + } + } } /// @@ -1195,7 +1263,20 @@ namespace MinecraftClient Entity entity = new Entity(EntityID, EntityType.Player, location); entities.Add(EntityID, entity); foreach (ChatBot bot in bots.ToArray()) - bot.OnEntitySpawn(entity); + { + 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 + } + } } /// @@ -1209,7 +1290,20 @@ namespace MinecraftClient if (entities.ContainsKey(a)) { foreach (ChatBot bot in bots.ToArray()) - bot.OnEntityDespawn(new Entity(entities[a].ID, entities[a].TypeID, entities[a].Type, entities[a].Location)); + { + try + { + 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); } } @@ -1234,7 +1328,20 @@ namespace MinecraftClient entities[EntityID].Location = L; foreach (ChatBot bot in bots.ToArray()) - bot.OnEntityMove(new Entity(entities[EntityID].ID, entities[EntityID].TypeID, entities[EntityID].Type, entities[EntityID].Location)); + { + try + { + 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 + } + } } } @@ -1254,7 +1361,20 @@ namespace MinecraftClient entities[EntityID].Location = location; foreach (ChatBot bot in bots.ToArray()) - bot.OnEntityMove(new Entity(entities[EntityID].ID, entities[EntityID].TypeID, entities[EntityID].Type, entities[EntityID].Location)); + { + try + { + 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 + } + } } } @@ -1268,7 +1388,20 @@ namespace MinecraftClient if(EntityID == playerEntityID) { foreach (ChatBot bot in bots.ToArray()) - bot.OnPlayerProperty(prop); + { + 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 + } + } } } @@ -1292,7 +1425,20 @@ namespace MinecraftClient serverTPS = tps; // invoke ChatBot foreach (ChatBot bot in bots.ToArray()) - bot.OnServerTpsUpdate(tps); + { + 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 + } + } } } else diff --git a/MinecraftClient/Program.cs b/MinecraftClient/Program.cs index 283ae8e4..aab6b81a 100644 --- a/MinecraftClient/Program.cs +++ b/MinecraftClient/Program.cs @@ -12,7 +12,7 @@ using MinecraftClient.WinAPI; namespace MinecraftClient { /// - /// 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. /// This source code is released under the CDDL 1.0 License. /// @@ -20,6 +20,7 @@ namespace MinecraftClient /// Typical steps to update MCC for a new Minecraft version /// - Implement protocol changes (see Protocol18.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) /// - Update MCHighestVersion field below (for versionning) /// diff --git a/MinecraftClient/Protocol/Handlers/Protocol18.cs b/MinecraftClient/Protocol/Handlers/Protocol18.cs index c2b72d36..e4c7e539 100644 --- a/MinecraftClient/Protocol/Handlers/Protocol18.cs +++ b/MinecraftClient/Protocol/Handlers/Protocol18.cs @@ -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 /// - 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 + /// - Also see Material.cs and ItemType.cs for updating block and item data inside MCC /// class Protocol18Handler : IMinecraftCom { @@ -70,13 +71,13 @@ namespace MinecraftClient.Protocol.Handlers 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."); 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."); handler.SetEntityHandlingEnabled(false); diff --git a/MinecraftClient/Settings.cs b/MinecraftClient/Settings.cs index 50c7ab56..f2122108 100644 --- a/MinecraftClient/Settings.cs +++ b/MinecraftClient/Settings.cs @@ -237,11 +237,12 @@ namespace MinecraftClient case "showxpbarmessages": DisplayXPBarMessages = str2bool(argValue); break; case "showchatlinks": DisplayChatLinks = 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 "privatemsgscmdname": PrivateMsgsCmdName = argValue.ToLower().Trim(); break; case "botmessagedelay": botMessageDelay = TimeSpan.FromSeconds(str2int(argValue)); break; case "debugmessages": DebugMessages = str2bool(argValue); break; - case "enableentityhandling": EntityHandling = str2bool(argValue); break; case "autorespawn": AutoRespawn = str2bool(argValue); break; case "botowners": @@ -576,7 +577,8 @@ namespace MinecraftClient + "showxpbarmessages=true # Messages displayed above xp bar\r\n" + "showchatlinks=true # Show links embedded in chat messages\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" + "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" @@ -586,7 +588,6 @@ namespace MinecraftClient + "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" + "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" + "\r\n" + "[AppVars]\r\n"