diff --git a/MinecraftClient/ChatBot.cs b/MinecraftClient/ChatBot.cs index d4604310..75b22f3a 100644 --- a/MinecraftClient/ChatBot.cs +++ b/MinecraftClient/ChatBot.cs @@ -354,6 +354,18 @@ namespace MinecraftClient /// Ptotocol version public virtual void OnEntityMetadata(Entity entity, Dictionary metadata) { } + /// + /// Called when a network packet received or sent + /// + /// + /// You need to enable this event by calling with True before you can use this event + /// + /// Packet ID + /// A copy of Packet Data + /// The packet is login phase or playing phase + /// The packet is received from server or sent by client + public virtual void OnNetworkPacket(int packetID, List packetData, bool isLogin, bool isInbound) { } + /* =================================================================== */ /* ToolBox - Methods below might be useful while creating your bot. */ /* You should not need to interact with other classes of the program. */ @@ -1286,6 +1298,27 @@ namespace MinecraftClient else return false; } + /// + /// Enable or disable network packet event calling. If you want to capture every packet including login phase, please enable this in + /// + /// + /// Enable this may increase memory usage. + /// + /// + protected void SetNetworkPacketEventEnabled(bool enabled) + { + Handler.SetNetworkPacketCaptureEnabled(enabled); + } + + /// + /// Get the minecraft protcol number currently in use + /// + /// Protcol number + protected int GetProtocolVersion() + { + return Handler.GetProtocolVersion(); + } + /// /// Command runner definition. /// Returned string will be the output of the command diff --git a/MinecraftClient/ChatBots/ReplayCapture.cs b/MinecraftClient/ChatBots/ReplayCapture.cs new file mode 100644 index 00000000..b8014546 --- /dev/null +++ b/MinecraftClient/ChatBots/ReplayCapture.cs @@ -0,0 +1,91 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using MinecraftClient.Protocol; + +namespace MinecraftClient.ChatBots +{ + /// + /// Record and save replay file that can be used by the Replay mod (https://www.replaymod.com/) + /// + public class ReplayCapture : ChatBot + { + private ReplayHandler replay; + private int backupInterval = 3000; // Unit: second * 10 + private int backupCounter = -1; + + public ReplayCapture(int backupInterval) + { + if (backupInterval != -1) + this.backupInterval = backupInterval * 10; + else this.backupInterval = -1; + } + + public override void Initialize() + { + SetNetworkPacketEventEnabled(true); + replay = new ReplayHandler(GetProtocolVersion()); + replay.MetaData.serverName = GetServerHost() + GetServerPort(); + backupCounter = backupInterval; + + RegisterChatBotCommand("replay", "replay command", Command); + } + + public override void OnNetworkPacket(int packetID, List packetData, bool isLogin, bool isInbound) + { + replay.AddPacket(packetID, packetData, isLogin, isInbound); + } + + public override void Update() + { + if (backupInterval > 0 && replay.RecordRunning) + { + if (backupCounter <= 0) + { + replay.CreateBackupReplay(@"recording_cache\REPLAY_BACKUP.mcpr"); + backupCounter = backupInterval; + } + else backupCounter--; + } + } + + public override bool OnDisconnect(DisconnectReason reason, string message) + { + replay.OnShutDown(); + return base.OnDisconnect(reason, message); + } + + public string Command(string cmd, string[] args) + { + try + { + if (replay.RecordRunning) + { + if (args.Length > 0) + { + switch (args[0].ToLower()) + { + case "save": + { + replay.CreateBackupReplay(@"replay_recordings\" + replay.GetReplayDefaultName()); + return "Replay file created."; + } + case "stop": + { + replay.OnShutDown(); + return "Record stopped."; + } + } + } + return "Available commands: save, stop"; + } + else return "Record was stopped. Restart the program to start another record."; + } + catch (Exception e) + { + return e.Message; + } + } + } +} diff --git a/MinecraftClient/McClient.cs b/MinecraftClient/McClient.cs index 06e5bcb6..fc675489 100644 --- a/MinecraftClient/McClient.cs +++ b/MinecraftClient/McClient.cs @@ -84,6 +84,9 @@ namespace MinecraftClient // players latency private Dictionary playersLatency = new Dictionary(); + // ChatBot OnNetworkPacket event + private bool networkPacketCaptureEnabled = false; + public int GetServerPort() { return port; } public string GetServerHost() { return host; } public string GetUsername() { return username; } @@ -98,6 +101,8 @@ namespace MinecraftClient public int GetTotalExperience() { return playerTotalExperience; } public byte GetCurrentSlot() { return CurrentSlot; } public int GetGamemode() { return gamemode; } + public bool GetNetworkPacketCaptureEnabled() { return networkPacketCaptureEnabled; } + public int GetProtocolVersion() { return handler.GetProtocolVersion(); } // get bots list for unloading them by commands public List GetLoadedChatBots() @@ -185,6 +190,7 @@ namespace MinecraftClient if (Settings.Mailer_Enabled) { BotLoad(new ChatBots.Mailer()); } if (Settings.AutoCraft_Enabled) { BotLoad(new AutoCraft(Settings.AutoCraft_configFile)); } if (Settings.AutoDrop_Enabled) { BotLoad(new AutoDrop(Settings.AutoDrop_Mode, Settings.AutoDrop_items)); } + if (Settings.ReplayMod_Enabled) { BotLoad(new ReplayCapture(Settings.ReplayMod_BackupInterval)); } //Add your ChatBot here by uncommenting and adapting //BotLoad(new ChatBots.YourBot()); @@ -757,6 +763,18 @@ namespace MinecraftClient } } + /// + /// Enable or disable network packet event calling. + /// + /// + /// Enable this may increase memory usage. + /// + /// + public void SetNetworkPacketCaptureEnabled(bool enabled) + { + networkPacketCaptureEnabled = enabled; + } + #endregion #region Getters: Retrieve data for use in other methods or ChatBots @@ -1492,6 +1510,21 @@ namespace MinecraftClient } } + /// + /// Called when a network packet received or sent + /// + /// + /// Only called if is set to True + /// + /// Packet ID + /// A copy of Packet Data + /// The packet is login phase or playing phase + /// The packet is received from server or sent by client + public void OnNetworkPacket(int packetID, List packetData, bool isLogin, bool isInbound) + { + DispatchBotEvent(bot => bot.OnNetworkPacket(packetID, packetData, isLogin, isInbound)); + } + /// /// Called when a server was successfully joined /// diff --git a/MinecraftClient/MinecraftClient.csproj b/MinecraftClient/MinecraftClient.csproj index 930e27ac..4a470974 100644 --- a/MinecraftClient/MinecraftClient.csproj +++ b/MinecraftClient/MinecraftClient.csproj @@ -75,6 +75,7 @@ + @@ -151,6 +152,40 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -172,6 +207,7 @@ + @@ -339,6 +375,7 @@ +