From a91eeda956561ba2b011720154d482cf9659b478 Mon Sep 17 00:00:00 2001 From: goat Date: Sun, 8 Dec 2019 16:09:43 +0900 Subject: [PATCH] feat: CfPreferredRole notification WIP, needs configuration --- Dalamud/Dalamud.cs | 16 +++++ Dalamud/DiscordBot/DiscordBotManager.cs | 26 +++++++++ .../DiscordBot/DiscordFeatureConfiguration.cs | 1 + Dalamud/Game/Internal/Network/GameNetwork.cs | 4 +- Dalamud/Game/Network/NetworkHandlers.cs | 58 +++++++++++++++++++ 5 files changed, 104 insertions(+), 1 deletion(-) diff --git a/Dalamud/Dalamud.cs b/Dalamud/Dalamud.cs index 0eefca08a..7e2bc3ca3 100644 --- a/Dalamud/Dalamud.cs +++ b/Dalamud/Dalamud.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Diagnostics; +using System.IO; using System.Linq; using System.Text; using System.Threading; @@ -178,6 +179,14 @@ namespace Dalamud { { HelpMessage = "Link an item by name. Usage: /xlitem " }); + +#if DEBUG + CommandManager.AddHandler("/xldzpi", new CommandInfo(OnDebugZoneDownInject) + { + HelpMessage = "Inject zone down channel", + ShowInHelp = false + }); +#endif } private void OnUnloadCommand(string command, string arguments) { @@ -406,5 +415,12 @@ namespace Dalamud { }); } + + private void OnDebugZoneDownInject(string command, string arguments) { + var data = File.ReadAllBytes(arguments); + + Framework.Network.InjectZoneProtoPacket(data); + Framework.Gui.Chat.Print($"{arguments} OK with {data.Length} bytes"); + } } } diff --git a/Dalamud/DiscordBot/DiscordBotManager.cs b/Dalamud/DiscordBot/DiscordBotManager.cs index 74a66b195..fdf1a945f 100644 --- a/Dalamud/DiscordBot/DiscordBotManager.cs +++ b/Dalamud/DiscordBot/DiscordBotManager.cs @@ -122,6 +122,32 @@ namespace Dalamud.DiscordBot { await channel.SendMessageAsync(embed: embedBuilder.Build()); } + public async Task ProcessCfPreferredRoleChange(string rouletteName, string prevRoleName, string currentRoleName) + { + if (this.config.CfPreferredRoleChannel == null) + return; + + var channel = await GetChannel(this.config.CfPreferredRoleChannel); + + var world = string.Empty; + + if (this.dalamud.ClientState.Actors.Length > 0) + world = this.dalamud.ClientState.LocalPlayer.CurrentWorld.Name; + + var embedBuilder = new EmbedBuilder + { + Title = "Roulette bonus changed: " + rouletteName, + Description = $"From {prevRoleName} to {currentRoleName}", + Footer = new EmbedFooterBuilder { + Text = $"On {world} | XIVLauncher" + }, + Timestamp = DateTimeOffset.Now, + Color = new Color(0xf5aa42), + }; + + await channel.SendMessageAsync(embed: embedBuilder.Build()); + } + public async Task ProcessRetainerSale(int itemId, int amount, bool isHq) { if (this.config.RetainerNotificationChannel == null) return; diff --git a/Dalamud/DiscordBot/DiscordFeatureConfiguration.cs b/Dalamud/DiscordBot/DiscordFeatureConfiguration.cs index 2bd717863..dcf86dd22 100644 --- a/Dalamud/DiscordBot/DiscordFeatureConfiguration.cs +++ b/Dalamud/DiscordBot/DiscordFeatureConfiguration.cs @@ -43,6 +43,7 @@ namespace Dalamud.DiscordBot public List ChatTypeConfigurations { get; set; } public ChannelConfiguration CfNotificationChannel { get; set; } + public ChannelConfiguration CfPreferredRoleChannel { get; set; } public ChannelConfiguration FateNotificationChannel { get; set; } public ChannelConfiguration RetainerNotificationChannel { get; set; } } diff --git a/Dalamud/Game/Internal/Network/GameNetwork.cs b/Dalamud/Game/Internal/Network/GameNetwork.cs index 90d565c6e..eb59ce2a5 100644 --- a/Dalamud/Game/Internal/Network/GameNetwork.cs +++ b/Dalamud/Game/Internal/Network/GameNetwork.cs @@ -69,7 +69,8 @@ namespace Dalamud.Game.Internal.Network { } } - private void InjectZoneProtoPacket(byte[] data) { +#if DEBUG + public void InjectZoneProtoPacket(byte[] data) { this.zoneInjectQueue.Enqueue(data); } @@ -86,6 +87,7 @@ namespace Dalamud.Game.Internal.Network { InjectZoneProtoPacket(packetData); } +#endif /// /// Process a chat queue. diff --git a/Dalamud/Game/Network/NetworkHandlers.cs b/Dalamud/Game/Network/NetworkHandlers.cs index d5f0186c5..9def7eef8 100644 --- a/Dalamud/Game/Network/NetworkHandlers.cs +++ b/Dalamud/Game/Network/NetworkHandlers.cs @@ -17,6 +17,8 @@ namespace Dalamud.Game.Network { private readonly bool optOutMbUploads; private readonly IMarketBoardUploader uploader; + private byte[] lastPreferredRole; + public NetworkHandlers(Dalamud dalamud, bool optOutMbUploads) { this.dalamud = dalamud; this.optOutMbUploads = optOutMbUploads; @@ -53,6 +55,52 @@ namespace Dalamud.Game.Network { return; } + if (opCode == ZoneOpCode.CfPreferredRole) + { + var data = new byte[64]; + Marshal.Copy(dataPtr, data, 0, 32); + + if (this.lastPreferredRole == null) { + this.lastPreferredRole = data; + return; + } + + + Task.Run(async () => { + + for (var rouletteIndex = 1; rouletteIndex < 11; rouletteIndex++) { + var currentRole = data[16 + rouletteIndex]; + var prevRole = this.lastPreferredRole[16 + rouletteIndex]; + + Log.Verbose("CfPreferredRole: {0} - {1} => {2}", rouletteIndex, prevRole, currentRole); + + if (currentRole != prevRole) { + var rouletteName = rouletteIndex switch { + 1 => "Duty Roulette: Leveling", + 2 => "Duty Roulette: Level 50/60/70 Dungeons", + 3 => "Duty Roulette: Main Scenario", + 4 => "Duty Roulette: Guildhests", + 5 => "Duty Roulette: Expert", + 6 => "Duty Roulette: Trials", + 8 => "Duty Roulette: Mentor", + 9 => "Duty Roulette: Alliance Raids", + 10 => "Duty Roulette: Normal Raids", + _ => "Unknown ContentRoulette" + }; + + var prevRoleName = RoleKeyToName(prevRole); + var currentRoleName = RoleKeyToName(currentRole); + + if (this.dalamud.BotManager.IsConnected) + await this.dalamud.BotManager.ProcessCfPreferredRoleChange(rouletteName, prevRoleName, currentRoleName); + } + } + }); + + this.lastPreferredRole = data; + return; + } + if (!this.optOutMbUploads) { if (opCode == ZoneOpCode.MarketBoardItemRequestStart) { var catalogId = (uint) Marshal.ReadInt32(dataPtr + 0x10); @@ -166,10 +214,20 @@ namespace Dalamud.Game.Network { private enum ZoneOpCode { CfNotifyPop = 0x2B0, + CfPreferredRole = 0x2c7, MarketTaxRates = 0x185, MarketBoardItemRequestStart = 0x23A, MarketBoardOfferings = 0x390, MarketBoardHistory = 0x1C2 } + + private string RoleKeyToName(int key) => key switch + { + 1 => "Tank", + 2 => "DPS", + 3 => "DPS", + 4 => "Healer", + _ => "No Bonus " + }; } }