Phase 1: Extract Constants.cs and CommandRouter.cs
- Extract magic numbers (timer intervals, message type IDs, property keys) into Constants.cs - Replace ~600-line HandleMmCommand switch with dictionary-based CommandRouter - All /mm commands preserved with same behavior, now registered via lambdas - PluginCore.cs and CharacterStats.cs updated to use named constants Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
9e9a94f159
commit
4845a67c1f
5 changed files with 585 additions and 516 deletions
|
|
@ -134,9 +134,9 @@ namespace MosswartMassacre
|
||||||
long key = tmpStruct.Value<Int64>("key");
|
long key = tmpStruct.Value<Int64>("key");
|
||||||
long value = tmpStruct.Value<Int64>("value");
|
long value = tmpStruct.Value<Int64>("value");
|
||||||
|
|
||||||
if (key == 6) // AvailableLuminance
|
if (key == Constants.AvailableLuminanceKey)
|
||||||
luminanceEarned = value;
|
luminanceEarned = value;
|
||||||
else if (key == 7) // MaximumLuminance
|
else if (key == Constants.MaximumLuminanceKey)
|
||||||
luminanceTotal = value;
|
luminanceTotal = value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -162,9 +162,9 @@ namespace MosswartMassacre
|
||||||
int key = BitConverter.ToInt32(raw, 5);
|
int key = BitConverter.ToInt32(raw, 5);
|
||||||
long value = BitConverter.ToInt64(raw, 9);
|
long value = BitConverter.ToInt64(raw, 9);
|
||||||
|
|
||||||
if (key == 6) // AvailableLuminance
|
if (key == Constants.AvailableLuminanceKey)
|
||||||
luminanceEarned = value;
|
luminanceEarned = value;
|
||||||
else if (key == 7) // MaximumLuminance
|
else if (key == Constants.MaximumLuminanceKey)
|
||||||
luminanceTotal = value;
|
luminanceTotal = value;
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
|
|
|
||||||
67
MosswartMassacre/CommandRouter.cs
Normal file
67
MosswartMassacre/CommandRouter.cs
Normal file
|
|
@ -0,0 +1,67 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
|
||||||
|
namespace MosswartMassacre
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Dictionary-based /mm command dispatcher. Commands are registered with descriptions
|
||||||
|
/// and routed by name lookup instead of a giant switch statement.
|
||||||
|
/// </summary>
|
||||||
|
internal class CommandRouter
|
||||||
|
{
|
||||||
|
private readonly Dictionary<string, (Action<string[]> handler, string description)> _commands
|
||||||
|
= new Dictionary<string, (Action<string[]>, string)>(StringComparer.OrdinalIgnoreCase);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Register a command with its handler and help description.
|
||||||
|
/// </summary>
|
||||||
|
internal void Register(string name, Action<string[]> handler, string description)
|
||||||
|
{
|
||||||
|
_commands[name] = (handler, description);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Dispatch a raw /mm command string. Returns false if the command was not found.
|
||||||
|
/// </summary>
|
||||||
|
internal bool Dispatch(string rawText)
|
||||||
|
{
|
||||||
|
string[] args = rawText.Substring(3).Trim().Split(' ');
|
||||||
|
|
||||||
|
if (args.Length == 0 || string.IsNullOrEmpty(args[0]))
|
||||||
|
{
|
||||||
|
PluginCore.WriteToChat("Usage: /mm <command>. Try /mm help");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
string subCommand = args[0].ToLower();
|
||||||
|
|
||||||
|
if (subCommand == "help")
|
||||||
|
{
|
||||||
|
PrintHelp();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_commands.TryGetValue(subCommand, out var entry))
|
||||||
|
{
|
||||||
|
entry.handler(args);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
PluginCore.WriteToChat($"Unknown /mm command: {subCommand}. Try /mm help");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void PrintHelp()
|
||||||
|
{
|
||||||
|
PluginCore.WriteToChat("Mosswart Massacre Commands:");
|
||||||
|
foreach (var kvp in _commands)
|
||||||
|
{
|
||||||
|
if (!string.IsNullOrEmpty(kvp.Value.description))
|
||||||
|
{
|
||||||
|
PluginCore.WriteToChat($"/mm {kvp.Key,-18} - {kvp.Value.description}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
30
MosswartMassacre/Constants.cs
Normal file
30
MosswartMassacre/Constants.cs
Normal file
|
|
@ -0,0 +1,30 @@
|
||||||
|
namespace MosswartMassacre
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Centralized constants for timer intervals, message type IDs, and property keys.
|
||||||
|
/// </summary>
|
||||||
|
internal static class Constants
|
||||||
|
{
|
||||||
|
// Timer intervals (milliseconds)
|
||||||
|
internal const int StatsUpdateIntervalMs = 1000;
|
||||||
|
internal const int VitalsUpdateIntervalMs = 5000;
|
||||||
|
internal const int CommandProcessIntervalMs = 10;
|
||||||
|
internal const int QuestStreamingIntervalMs = 30000;
|
||||||
|
internal const int CharacterStatsIntervalMs = 600000; // 10 minutes
|
||||||
|
internal const int LoginDelayMs = 5000;
|
||||||
|
|
||||||
|
// Network message types
|
||||||
|
internal const int GameEventMessageType = 0xF7B0;
|
||||||
|
internal const int PrivateUpdatePropertyInt64 = 0x02CF;
|
||||||
|
|
||||||
|
// Game event IDs (sub-events within 0xF7B0)
|
||||||
|
internal const int AllegianceInfoEvent = 0x0020;
|
||||||
|
internal const int LoginCharacterEvent = 0x0013;
|
||||||
|
internal const int TitlesListEvent = 0x0029;
|
||||||
|
internal const int SetTitleEvent = 0x002b;
|
||||||
|
|
||||||
|
// Int64 property keys
|
||||||
|
internal const int AvailableLuminanceKey = 6;
|
||||||
|
internal const int MaximumLuminanceKey = 7;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -304,6 +304,8 @@
|
||||||
<Compile Include="..\Shared\VCS_Connector.cs">
|
<Compile Include="..\Shared\VCS_Connector.cs">
|
||||||
<Link>Shared\VCS_Connector.cs</Link>
|
<Link>Shared\VCS_Connector.cs</Link>
|
||||||
</Compile>
|
</Compile>
|
||||||
|
<Compile Include="CommandRouter.cs" />
|
||||||
|
<Compile Include="Constants.cs" />
|
||||||
<Compile Include="ClientTelemetry.cs" />
|
<Compile Include="ClientTelemetry.cs" />
|
||||||
<Compile Include="DecalHarmonyClean.cs" />
|
<Compile Include="DecalHarmonyClean.cs" />
|
||||||
<Compile Include="FlagTrackerData.cs" />
|
<Compile Include="FlagTrackerData.cs" />
|
||||||
|
|
|
||||||
|
|
@ -127,6 +127,9 @@ namespace MosswartMassacre
|
||||||
private static DateTime _lastSent = DateTime.MinValue;
|
private static DateTime _lastSent = DateTime.MinValue;
|
||||||
private static readonly Queue<string> _chatQueue = new Queue<string>();
|
private static readonly Queue<string> _chatQueue = new Queue<string>();
|
||||||
|
|
||||||
|
// Command routing
|
||||||
|
private CommandRouter _commandRouter;
|
||||||
|
|
||||||
protected override void Startup()
|
protected override void Startup()
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
|
|
@ -184,18 +187,18 @@ namespace MosswartMassacre
|
||||||
ViewManager.ViewInit();
|
ViewManager.ViewInit();
|
||||||
|
|
||||||
// Initialize the timer
|
// Initialize the timer
|
||||||
updateTimer = new Timer(1000); // Update every second
|
updateTimer = new Timer(Constants.StatsUpdateIntervalMs);
|
||||||
updateTimer.Elapsed += UpdateStats;
|
updateTimer.Elapsed += UpdateStats;
|
||||||
updateTimer.Start();
|
updateTimer.Start();
|
||||||
|
|
||||||
// Initialize vitals streaming timer
|
// Initialize vitals streaming timer
|
||||||
vitalsTimer = new Timer(5000); // Send vitals every 5 seconds
|
vitalsTimer = new Timer(Constants.VitalsUpdateIntervalMs);
|
||||||
vitalsTimer.Elapsed += SendVitalsUpdate;
|
vitalsTimer.Elapsed += SendVitalsUpdate;
|
||||||
vitalsTimer.Start();
|
vitalsTimer.Start();
|
||||||
|
|
||||||
// Initialize command processing timer (Windows Forms timer for main thread)
|
// Initialize command processing timer (Windows Forms timer for main thread)
|
||||||
commandTimer = new System.Windows.Forms.Timer();
|
commandTimer = new System.Windows.Forms.Timer();
|
||||||
commandTimer.Interval = 10; // Process commands every 10ms
|
commandTimer.Interval = Constants.CommandProcessIntervalMs;
|
||||||
commandTimer.Tick += ProcessPendingCommands;
|
commandTimer.Tick += ProcessPendingCommands;
|
||||||
commandTimer.Start();
|
commandTimer.Start();
|
||||||
|
|
||||||
|
|
@ -220,6 +223,10 @@ namespace MosswartMassacre
|
||||||
// Initialize navigation visualization system
|
// Initialize navigation visualization system
|
||||||
navVisualization = new NavVisualization();
|
navVisualization = new NavVisualization();
|
||||||
|
|
||||||
|
// Initialize command router
|
||||||
|
_commandRouter = new CommandRouter();
|
||||||
|
RegisterCommands();
|
||||||
|
|
||||||
// Note: ChestLooter is initialized in LoginComplete after PluginSettings.Initialize()
|
// Note: ChestLooter is initialized in LoginComplete after PluginSettings.Initialize()
|
||||||
|
|
||||||
// Note: DECAL Harmony patches will be initialized in LoginComplete event
|
// Note: DECAL Harmony patches will be initialized in LoginComplete event
|
||||||
|
|
@ -398,7 +405,7 @@ namespace MosswartMassacre
|
||||||
Views.FlagTrackerView.RefreshQuestData();
|
Views.FlagTrackerView.RefreshQuestData();
|
||||||
|
|
||||||
// Initialize quest streaming timer (30 seconds)
|
// Initialize quest streaming timer (30 seconds)
|
||||||
questStreamingTimer = new Timer(30000);
|
questStreamingTimer = new Timer(Constants.QuestStreamingIntervalMs);
|
||||||
questStreamingTimer.Elapsed += OnQuestStreamingUpdate;
|
questStreamingTimer.Elapsed += OnQuestStreamingUpdate;
|
||||||
questStreamingTimer.AutoReset = true;
|
questStreamingTimer.AutoReset = true;
|
||||||
questStreamingTimer.Start();
|
questStreamingTimer.Start();
|
||||||
|
|
@ -416,13 +423,13 @@ namespace MosswartMassacre
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
// Start 10-minute character stats timer
|
// Start 10-minute character stats timer
|
||||||
characterStatsTimer = new Timer(600000); // 10 minutes
|
characterStatsTimer = new Timer(Constants.CharacterStatsIntervalMs);
|
||||||
characterStatsTimer.Elapsed += OnCharacterStatsUpdate;
|
characterStatsTimer.Elapsed += OnCharacterStatsUpdate;
|
||||||
characterStatsTimer.AutoReset = true;
|
characterStatsTimer.AutoReset = true;
|
||||||
characterStatsTimer.Start();
|
characterStatsTimer.Start();
|
||||||
|
|
||||||
// Send initial stats after 5-second delay (let CharacterFilter populate)
|
// Send initial stats after 5-second delay (let CharacterFilter populate)
|
||||||
var initialDelay = new Timer(5000);
|
var initialDelay = new Timer(Constants.LoginDelayMs);
|
||||||
initialDelay.AutoReset = false;
|
initialDelay.AutoReset = false;
|
||||||
initialDelay.Elapsed += (s, args) =>
|
initialDelay.Elapsed += (s, args) =>
|
||||||
{
|
{
|
||||||
|
|
@ -638,7 +645,7 @@ namespace MosswartMassacre
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create new timer
|
// Create new timer
|
||||||
questStreamingTimer = new Timer(30000); // 30 seconds
|
questStreamingTimer = new Timer(Constants.QuestStreamingIntervalMs);
|
||||||
questStreamingTimer.Elapsed += OnQuestStreamingUpdate;
|
questStreamingTimer.Elapsed += OnQuestStreamingUpdate;
|
||||||
questStreamingTimer.AutoReset = true;
|
questStreamingTimer.AutoReset = true;
|
||||||
questStreamingTimer.Start();
|
questStreamingTimer.Start();
|
||||||
|
|
@ -1172,28 +1179,28 @@ namespace MosswartMassacre
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (e.Message.Type == 0xF7B0) // Game Event
|
if (e.Message.Type == Constants.GameEventMessageType)
|
||||||
{
|
{
|
||||||
int eventId = (int)e.Message["event"];
|
int eventId = (int)e.Message["event"];
|
||||||
|
|
||||||
if (eventId == 0x0020) // Allegiance info
|
if (eventId == Constants.AllegianceInfoEvent)
|
||||||
{
|
{
|
||||||
CharacterStats.ProcessAllegianceInfoMessage(e);
|
CharacterStats.ProcessAllegianceInfoMessage(e);
|
||||||
}
|
}
|
||||||
else if (eventId == 0x0013) // Login Character (properties)
|
else if (eventId == Constants.LoginCharacterEvent)
|
||||||
{
|
{
|
||||||
CharacterStats.ProcessCharacterPropertyData(e);
|
CharacterStats.ProcessCharacterPropertyData(e);
|
||||||
}
|
}
|
||||||
else if (eventId == 0x0029) // Titles list
|
else if (eventId == Constants.TitlesListEvent)
|
||||||
{
|
{
|
||||||
CharacterStats.ProcessTitlesMessage(e);
|
CharacterStats.ProcessTitlesMessage(e);
|
||||||
}
|
}
|
||||||
else if (eventId == 0x002b) // Set title
|
else if (eventId == Constants.SetTitleEvent)
|
||||||
{
|
{
|
||||||
CharacterStats.ProcessSetTitleMessage(e);
|
CharacterStats.ProcessSetTitleMessage(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (e.Message.Type == 0x02CF) // PrivateUpdatePropertyInt64 (runtime luminance changes)
|
else if (e.Message.Type == Constants.PrivateUpdatePropertyInt64)
|
||||||
{
|
{
|
||||||
CharacterStats.ProcessPropertyInt64Update(e);
|
CharacterStats.ProcessPropertyInt64Update(e);
|
||||||
}
|
}
|
||||||
|
|
@ -1353,20 +1360,13 @@ namespace MosswartMassacre
|
||||||
}
|
}
|
||||||
private void HandleMmCommand(string text)
|
private void HandleMmCommand(string text)
|
||||||
{
|
{
|
||||||
// Remove the /mm prefix and trim extra whitespace test
|
_commandRouter.Dispatch(text);
|
||||||
string[] args = text.Substring(3).Trim().Split(' ');
|
|
||||||
|
|
||||||
if (args.Length == 0 || string.IsNullOrEmpty(args[0]))
|
|
||||||
{
|
|
||||||
WriteToChat("Usage: /mm <command>. Try /mm help");
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
string subCommand = args[0].ToLower();
|
private void RegisterCommands()
|
||||||
|
{
|
||||||
switch (subCommand)
|
_commandRouter.Register("ws", args =>
|
||||||
{
|
{
|
||||||
case "ws":
|
|
||||||
if (args.Length > 1)
|
if (args.Length > 1)
|
||||||
{
|
{
|
||||||
if (args[1].Equals("enable", StringComparison.OrdinalIgnoreCase))
|
if (args[1].Equals("enable", StringComparison.OrdinalIgnoreCase))
|
||||||
|
|
@ -1388,77 +1388,55 @@ namespace MosswartMassacre
|
||||||
WriteToChat("Usage: /mm ws <enable|disable>");
|
WriteToChat("Usage: /mm ws <enable|disable>");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
WriteToChat("Usage: /mm ws <enable|disable>");
|
WriteToChat("Usage: /mm ws <enable|disable>");
|
||||||
}
|
}
|
||||||
break;
|
}, "Websocket streaming enable|disable");
|
||||||
case "help":
|
|
||||||
WriteToChat("Mosswart Massacre Commands:");
|
_commandRouter.Register("report", args =>
|
||||||
WriteToChat("/mm report - Show current stats");
|
{
|
||||||
WriteToChat("/mm loc - Show current location");
|
|
||||||
WriteToChat("/mm ws - Websocket streaming enable|disable");
|
|
||||||
WriteToChat("/mm reset - Reset all counters");
|
|
||||||
WriteToChat("/mm meta - Toggle rare meta state!!");
|
|
||||||
WriteToChat("/mm getmetastate - Gets the current metastate");
|
|
||||||
WriteToChat("/mm setchest <name> - Set chest name for looter");
|
|
||||||
WriteToChat("/mm setkey <name> - Set key name for looter");
|
|
||||||
WriteToChat("/mm lootchest - Start chest looting");
|
|
||||||
WriteToChat("/mm stoploot - Stop chest looting");
|
|
||||||
WriteToChat("/mm nextwp - Advance VTank to next waypoint");
|
|
||||||
WriteToChat("/mm decalstatus - Check Harmony patch status (UtilityBelt version)");
|
|
||||||
WriteToChat("/mm decaldebug - Enable/disable plugin message debug output + WebSocket streaming");
|
|
||||||
WriteToChat("/mm harmonyraw - Show raw intercepted messages (debug output)");
|
|
||||||
WriteToChat("/mm testprismatic - Test Prismatic Taper detection and icon lookup");
|
|
||||||
WriteToChat("/mm deathstats - Show current death tracking statistics");
|
|
||||||
WriteToChat("/mm testtaper - Test cached Prismatic Taper tracking");
|
|
||||||
WriteToChat("/mm debugtaper - Show detailed taper tracking debug info");
|
|
||||||
WriteToChat("/mm gui - Manually initialize/reinitialize GUI!!!");
|
|
||||||
WriteToChat("/mm checkforupdate - Check for plugin updates");
|
|
||||||
WriteToChat("/mm update - Download and install update (if available)");
|
|
||||||
WriteToChat("/mm debugupdate - Debug update UI controls");
|
|
||||||
WriteToChat("/mm sendinventory - Force inventory upload with ID requests");
|
|
||||||
WriteToChat("/mm refreshquests - Force quest data refresh for Flag Tracker");
|
|
||||||
WriteToChat("/mm queststatus - Show quest streaming status and diagnostics");
|
|
||||||
WriteToChat("/mm verbose - Toggle verbose debug logging");
|
|
||||||
break;
|
|
||||||
case "report":
|
|
||||||
TimeSpan elapsed = DateTime.Now - statsStartTime;
|
TimeSpan elapsed = DateTime.Now - statsStartTime;
|
||||||
string reportMessage = $"Total Kills: {totalKills}, Kills per Hour: {killsPerHour:F2}, Elapsed Time: {elapsed:dd\\.hh\\:mm\\:ss}, Rares Found: {rareCount}, Session Deaths: {sessionDeaths}, Total Deaths: {totalDeaths}";
|
string reportMessage = $"Total Kills: {totalKills}, Kills per Hour: {killsPerHour:F2}, Elapsed Time: {elapsed:dd\\.hh\\:mm\\:ss}, Rares Found: {rareCount}, Session Deaths: {sessionDeaths}, Total Deaths: {totalDeaths}";
|
||||||
WriteToChat(reportMessage);
|
WriteToChat(reportMessage);
|
||||||
break;
|
}, "Show current stats");
|
||||||
case "getmetastate":
|
|
||||||
|
_commandRouter.Register("getmetastate", args =>
|
||||||
|
{
|
||||||
string metaState = VtankControl.VtGetMetaState();
|
string metaState = VtankControl.VtGetMetaState();
|
||||||
WriteToChat(metaState);
|
WriteToChat(metaState);
|
||||||
break;
|
}, "Gets the current metastate");
|
||||||
|
|
||||||
case "loc":
|
_commandRouter.Register("loc", args =>
|
||||||
|
{
|
||||||
Coordinates here = Coordinates.Me;
|
Coordinates here = Coordinates.Me;
|
||||||
var pos = Utils.GetPlayerPosition();
|
var pos = Utils.GetPlayerPosition();
|
||||||
WriteToChat($"Location: {here} (X={pos.X:F1}, Y={pos.Y:F1}, Z={pos.Z:F1})");
|
WriteToChat($"Location: {here} (X={pos.X:F1}, Y={pos.Y:F1}, Z={pos.Z:F1})");
|
||||||
break;
|
}, "Show current location");
|
||||||
case "reset":
|
|
||||||
|
_commandRouter.Register("reset", args =>
|
||||||
|
{
|
||||||
RestartStats();
|
RestartStats();
|
||||||
break;
|
}, "Reset all counters");
|
||||||
case "meta":
|
|
||||||
|
_commandRouter.Register("meta", args =>
|
||||||
|
{
|
||||||
RareMetaEnabled = !RareMetaEnabled;
|
RareMetaEnabled = !RareMetaEnabled;
|
||||||
WriteToChat($"Rare meta state is now {(RareMetaEnabled ? "ON" : "OFF")}");
|
WriteToChat($"Rare meta state is now {(RareMetaEnabled ? "ON" : "OFF")}");
|
||||||
ViewManager.SetRareMetaToggleState(RareMetaEnabled); // <-- sync the UI
|
ViewManager.SetRareMetaToggleState(RareMetaEnabled);
|
||||||
break;
|
}, "Toggle rare meta state");
|
||||||
case "nextwp":
|
|
||||||
|
_commandRouter.Register("nextwp", args =>
|
||||||
|
{
|
||||||
double result = VtankControl.VtAdvanceWaypoint();
|
double result = VtankControl.VtAdvanceWaypoint();
|
||||||
if (result == 1)
|
if (result == 1)
|
||||||
{
|
|
||||||
WriteToChat("Advanced VTank to next waypoint.");
|
WriteToChat("Advanced VTank to next waypoint.");
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
|
||||||
WriteToChat("Failed to advance VTank waypoint. Is VTank running?");
|
WriteToChat("Failed to advance VTank waypoint. Is VTank running?");
|
||||||
}
|
}, "Advance VTank to next waypoint");
|
||||||
break;
|
|
||||||
|
|
||||||
case "setchest":
|
_commandRouter.Register("setchest", args =>
|
||||||
|
{
|
||||||
if (args.Length < 2)
|
if (args.Length < 2)
|
||||||
{
|
{
|
||||||
WriteToChat("[ChestLooter] Usage: /mm setchest <chest name>");
|
WriteToChat("[ChestLooter] Usage: /mm setchest <chest name>");
|
||||||
|
|
@ -1475,9 +1453,10 @@ namespace MosswartMassacre
|
||||||
}
|
}
|
||||||
Views.VVSTabbedMainView.RefreshChestLooterUI();
|
Views.VVSTabbedMainView.RefreshChestLooterUI();
|
||||||
}
|
}
|
||||||
break;
|
}, "Set chest name for looter");
|
||||||
|
|
||||||
case "setkey":
|
_commandRouter.Register("setkey", args =>
|
||||||
|
{
|
||||||
if (args.Length < 2)
|
if (args.Length < 2)
|
||||||
{
|
{
|
||||||
WriteToChat("[ChestLooter] Usage: /mm setkey <key name>");
|
WriteToChat("[ChestLooter] Usage: /mm setkey <key name>");
|
||||||
|
|
@ -1494,34 +1473,31 @@ namespace MosswartMassacre
|
||||||
}
|
}
|
||||||
Views.VVSTabbedMainView.RefreshChestLooterUI();
|
Views.VVSTabbedMainView.RefreshChestLooterUI();
|
||||||
}
|
}
|
||||||
break;
|
}, "Set key name for looter");
|
||||||
|
|
||||||
case "lootchest":
|
_commandRouter.Register("lootchest", args =>
|
||||||
|
{
|
||||||
if (chestLooter != null)
|
if (chestLooter != null)
|
||||||
{
|
{
|
||||||
if (!chestLooter.StartByName())
|
if (!chestLooter.StartByName())
|
||||||
{
|
|
||||||
WriteToChat("[ChestLooter] Failed to start. Check chest/key names are set.");
|
WriteToChat("[ChestLooter] Failed to start. Check chest/key names are set.");
|
||||||
}
|
}
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
WriteToChat("[ChestLooter] Chest looter not initialized");
|
WriteToChat("[ChestLooter] Chest looter not initialized");
|
||||||
}
|
}
|
||||||
break;
|
}, "Start chest looting");
|
||||||
|
|
||||||
case "stoploot":
|
_commandRouter.Register("stoploot", args =>
|
||||||
|
{
|
||||||
if (chestLooter != null)
|
if (chestLooter != null)
|
||||||
{
|
|
||||||
chestLooter.Stop();
|
chestLooter.Stop();
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
|
||||||
WriteToChat("[ChestLooter] Chest looter not initialized");
|
WriteToChat("[ChestLooter] Chest looter not initialized");
|
||||||
}
|
}, "Stop chest looting");
|
||||||
break;
|
|
||||||
|
|
||||||
case "vtanktest":
|
_commandRouter.Register("vtanktest", args =>
|
||||||
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
WriteToChat("Testing VTank interface...");
|
WriteToChat("Testing VTank interface...");
|
||||||
|
|
@ -1536,9 +1512,10 @@ namespace MosswartMassacre
|
||||||
{
|
{
|
||||||
WriteToChat($"VTank test error: {ex.Message}");
|
WriteToChat($"VTank test error: {ex.Message}");
|
||||||
}
|
}
|
||||||
break;
|
}, "Test VTank interface");
|
||||||
|
|
||||||
case "decalstatus":
|
_commandRouter.Register("decalstatus", args =>
|
||||||
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
WriteToChat("=== Harmony Patch Status (UtilityBelt Pattern) ===");
|
WriteToChat("=== Harmony Patch Status (UtilityBelt Pattern) ===");
|
||||||
|
|
@ -1546,14 +1523,11 @@ namespace MosswartMassacre
|
||||||
WriteToChat($"Messages Intercepted: {DecalHarmonyClean.GetMessagesIntercepted()}");
|
WriteToChat($"Messages Intercepted: {DecalHarmonyClean.GetMessagesIntercepted()}");
|
||||||
WriteToChat($"WebSocket Streaming: {(AggressiveChatStreamingEnabled && WebSocketEnabled ? "ACTIVE" : "INACTIVE")}");
|
WriteToChat($"WebSocket Streaming: {(AggressiveChatStreamingEnabled && WebSocketEnabled ? "ACTIVE" : "INACTIVE")}");
|
||||||
|
|
||||||
// Test Harmony availability
|
|
||||||
WriteToChat("=== Harmony Version Status ===");
|
WriteToChat("=== Harmony Version Status ===");
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var harmonyTest = Harmony.HarmonyInstance.Create("test.version.check");
|
var harmonyTest = Harmony.HarmonyInstance.Create("test.version.check");
|
||||||
WriteToChat($"[OK] Harmony Available (ID: {harmonyTest.Id})");
|
WriteToChat($"[OK] Harmony Available (ID: {harmonyTest.Id})");
|
||||||
|
|
||||||
// Check Harmony assembly version
|
|
||||||
var harmonyAssembly = typeof(Harmony.HarmonyInstance).Assembly;
|
var harmonyAssembly = typeof(Harmony.HarmonyInstance).Assembly;
|
||||||
WriteToChat($"[OK] Harmony Version: {harmonyAssembly.GetName().Version}");
|
WriteToChat($"[OK] Harmony Version: {harmonyAssembly.GetName().Version}");
|
||||||
WriteToChat($"[OK] Harmony Location: {harmonyAssembly.Location}");
|
WriteToChat($"[OK] Harmony Location: {harmonyAssembly.Location}");
|
||||||
|
|
@ -1567,9 +1541,10 @@ namespace MosswartMassacre
|
||||||
{
|
{
|
||||||
WriteToChat($"Status check error: {ex.Message}");
|
WriteToChat($"Status check error: {ex.Message}");
|
||||||
}
|
}
|
||||||
break;
|
}, "Check Harmony patch status");
|
||||||
|
|
||||||
case "decaldebug":
|
_commandRouter.Register("decaldebug", args =>
|
||||||
|
{
|
||||||
if (args.Length > 1)
|
if (args.Length > 1)
|
||||||
{
|
{
|
||||||
if (args[1].Equals("enable", StringComparison.OrdinalIgnoreCase))
|
if (args[1].Equals("enable", StringComparison.OrdinalIgnoreCase))
|
||||||
|
|
@ -1591,29 +1566,42 @@ namespace MosswartMassacre
|
||||||
{
|
{
|
||||||
WriteToChat("Usage: /mm decaldebug <enable|disable>");
|
WriteToChat("Usage: /mm decaldebug <enable|disable>");
|
||||||
}
|
}
|
||||||
break;
|
}, "Enable/disable plugin message debug output");
|
||||||
|
|
||||||
|
_commandRouter.Register("harmonyraw", args => { }, "");
|
||||||
|
|
||||||
case "harmonyraw":
|
_commandRouter.Register("gui", args =>
|
||||||
// Debug functionality removed
|
{
|
||||||
break;
|
|
||||||
|
|
||||||
case "initgui":
|
|
||||||
case "gui":
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
WriteToChat("Attempting to manually initialize GUI...");
|
WriteToChat("Attempting to manually initialize GUI...");
|
||||||
ViewManager.ViewDestroy(); // Clean up any existing view
|
ViewManager.ViewDestroy();
|
||||||
ViewManager.ViewInit(); // Reinitialize
|
ViewManager.ViewInit();
|
||||||
WriteToChat("GUI initialization attempt completed.");
|
WriteToChat("GUI initialization attempt completed.");
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
WriteToChat($"GUI initialization error: {ex.Message}");
|
WriteToChat($"GUI initialization error: {ex.Message}");
|
||||||
}
|
}
|
||||||
break;
|
}, "Manually initialize/reinitialize GUI");
|
||||||
|
|
||||||
case "testprismatic":
|
_commandRouter.Register("initgui", args =>
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
WriteToChat("Attempting to manually initialize GUI...");
|
||||||
|
ViewManager.ViewDestroy();
|
||||||
|
ViewManager.ViewInit();
|
||||||
|
WriteToChat("GUI initialization attempt completed.");
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
WriteToChat($"GUI initialization error: {ex.Message}");
|
||||||
|
}
|
||||||
|
}, "");
|
||||||
|
|
||||||
|
_commandRouter.Register("testprismatic", args =>
|
||||||
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
WriteToChat("=== FULL INVENTORY DUMP ===");
|
WriteToChat("=== FULL INVENTORY DUMP ===");
|
||||||
|
|
@ -1631,7 +1619,6 @@ namespace MosswartMassacre
|
||||||
WriteToChat($"{itemNum:D2}: '{item.Name}' (count: {stackCount}, icon: 0x{item.Icon:X}, class: {item.ObjectClass})");
|
WriteToChat($"{itemNum:D2}: '{item.Name}' (count: {stackCount}, icon: 0x{item.Icon:X}, class: {item.ObjectClass})");
|
||||||
itemNum++;
|
itemNum++;
|
||||||
|
|
||||||
// Highlight anything that might be a taper
|
|
||||||
string nameLower = item.Name.ToLower();
|
string nameLower = item.Name.ToLower();
|
||||||
if (nameLower.Contains("taper") || nameLower.Contains("prismatic") ||
|
if (nameLower.Contains("taper") || nameLower.Contains("prismatic") ||
|
||||||
nameLower.Contains("prism") || nameLower.Contains("component"))
|
nameLower.Contains("prism") || nameLower.Contains("component"))
|
||||||
|
|
@ -1643,7 +1630,6 @@ namespace MosswartMassacre
|
||||||
|
|
||||||
WriteToChat($"=== Total items listed: {itemNum - 1} ===");
|
WriteToChat($"=== Total items listed: {itemNum - 1} ===");
|
||||||
|
|
||||||
// Now test our utility functions on the found Prismatic Taper
|
|
||||||
WriteToChat("=== Testing Utility Functions on Prismatic Taper ===");
|
WriteToChat("=== Testing Utility Functions on Prismatic Taper ===");
|
||||||
var foundItem = Utils.FindItemByName("Prismatic Taper");
|
var foundItem = Utils.FindItemByName("Prismatic Taper");
|
||||||
if (foundItem != null)
|
if (foundItem != null)
|
||||||
|
|
@ -1663,16 +1649,16 @@ namespace MosswartMassacre
|
||||||
{
|
{
|
||||||
WriteToChat($"Search error: {ex.Message}");
|
WriteToChat($"Search error: {ex.Message}");
|
||||||
}
|
}
|
||||||
break;
|
}, "Test Prismatic Taper detection and icon lookup");
|
||||||
|
|
||||||
case "deathstats":
|
_commandRouter.Register("deathstats", args =>
|
||||||
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
WriteToChat("=== Death Tracking Statistics ===");
|
WriteToChat("=== Death Tracking Statistics ===");
|
||||||
WriteToChat($"Session Deaths: {sessionDeaths}");
|
WriteToChat($"Session Deaths: {sessionDeaths}");
|
||||||
WriteToChat($"Total Deaths: {totalDeaths}");
|
WriteToChat($"Total Deaths: {totalDeaths}");
|
||||||
|
|
||||||
// Get current character death count to verify sync
|
|
||||||
int currentCharDeaths = CoreManager.Current.CharacterFilter.GetCharProperty((int)IntValueKey.NumDeaths);
|
int currentCharDeaths = CoreManager.Current.CharacterFilter.GetCharProperty((int)IntValueKey.NumDeaths);
|
||||||
WriteToChat($"Character Property NumDeaths: {currentCharDeaths}");
|
WriteToChat($"Character Property NumDeaths: {currentCharDeaths}");
|
||||||
|
|
||||||
|
|
@ -1689,25 +1675,23 @@ namespace MosswartMassacre
|
||||||
{
|
{
|
||||||
WriteToChat($"Death stats error: {ex.Message}");
|
WriteToChat($"Death stats error: {ex.Message}");
|
||||||
}
|
}
|
||||||
break;
|
}, "Show current death tracking statistics");
|
||||||
|
|
||||||
case "testdeath":
|
_commandRouter.Register("testdeath", args =>
|
||||||
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
WriteToChat("=== Manual Death Test ===");
|
WriteToChat("=== Manual Death Test ===");
|
||||||
WriteToChat($"Current sessionDeaths variable: {sessionDeaths}");
|
WriteToChat($"Current sessionDeaths variable: {sessionDeaths}");
|
||||||
WriteToChat($"Current totalDeaths variable: {totalDeaths}");
|
WriteToChat($"Current totalDeaths variable: {totalDeaths}");
|
||||||
|
|
||||||
// Read directly from character property
|
|
||||||
int currentCharDeaths = CoreManager.Current.CharacterFilter.GetCharProperty((int)IntValueKey.NumDeaths);
|
int currentCharDeaths = CoreManager.Current.CharacterFilter.GetCharProperty((int)IntValueKey.NumDeaths);
|
||||||
WriteToChat($"Character Property NumDeaths (43): {currentCharDeaths}");
|
WriteToChat($"Character Property NumDeaths (43): {currentCharDeaths}");
|
||||||
|
|
||||||
// Manually increment session deaths for testing
|
|
||||||
sessionDeaths++;
|
sessionDeaths++;
|
||||||
WriteToChat($"Manually incremented sessionDeaths to: {sessionDeaths}");
|
WriteToChat($"Manually incremented sessionDeaths to: {sessionDeaths}");
|
||||||
WriteToChat("Note: This doesn't simulate a real death, just tests the tracking variables.");
|
WriteToChat("Note: This doesn't simulate a real death, just tests the tracking variables.");
|
||||||
|
|
||||||
// Check if death event is properly subscribed
|
|
||||||
WriteToChat($"Death event subscription check:");
|
WriteToChat($"Death event subscription check:");
|
||||||
var deathEvent = typeof(Decal.Adapter.Wrappers.CharacterFilter).GetEvent("Death");
|
var deathEvent = typeof(Decal.Adapter.Wrappers.CharacterFilter).GetEvent("Death");
|
||||||
WriteToChat($"Death event exists: {deathEvent != null}");
|
WriteToChat($"Death event exists: {deathEvent != null}");
|
||||||
|
|
@ -1716,16 +1700,16 @@ namespace MosswartMassacre
|
||||||
{
|
{
|
||||||
WriteToChat($"Test death error: {ex.Message}");
|
WriteToChat($"Test death error: {ex.Message}");
|
||||||
}
|
}
|
||||||
break;
|
}, "Test death tracking variables");
|
||||||
|
|
||||||
case "testtaper":
|
_commandRouter.Register("testtaper", args =>
|
||||||
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
WriteToChat("=== Cached Taper Tracking Test ===");
|
WriteToChat("=== Cached Taper Tracking Test ===");
|
||||||
WriteToChat($"Cached Count: {cachedPrismaticCount}");
|
WriteToChat($"Cached Count: {cachedPrismaticCount}");
|
||||||
WriteToChat($"Last Count: {lastPrismaticCount}");
|
WriteToChat($"Last Count: {lastPrismaticCount}");
|
||||||
|
|
||||||
// Compare with Utils function
|
|
||||||
int utilsCount = Utils.GetItemStackSize("Prismatic Taper");
|
int utilsCount = Utils.GetItemStackSize("Prismatic Taper");
|
||||||
WriteToChat($"Utils Count: {utilsCount}");
|
WriteToChat($"Utils Count: {utilsCount}");
|
||||||
|
|
||||||
|
|
@ -1751,15 +1735,11 @@ namespace MosswartMassacre
|
||||||
{
|
{
|
||||||
int stackCount = wo.Values(LongValueKey.StackCount, 1);
|
int stackCount = wo.Values(LongValueKey.StackCount, 1);
|
||||||
if (wo.Container == playerId)
|
if (wo.Container == playerId)
|
||||||
{
|
|
||||||
mainPackCount += stackCount;
|
mainPackCount += stackCount;
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
|
||||||
sidePackCount += stackCount;
|
sidePackCount += stackCount;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
WriteToChat($"Main Pack Tapers: {mainPackCount}");
|
WriteToChat($"Main Pack Tapers: {mainPackCount}");
|
||||||
WriteToChat($"Side Pack Tapers: {sidePackCount}");
|
WriteToChat($"Side Pack Tapers: {sidePackCount}");
|
||||||
|
|
@ -1776,13 +1756,12 @@ namespace MosswartMassacre
|
||||||
{
|
{
|
||||||
WriteToChat($"Taper test error: {ex.Message}");
|
WriteToChat($"Taper test error: {ex.Message}");
|
||||||
}
|
}
|
||||||
break;
|
}, "Test cached Prismatic Taper tracking");
|
||||||
|
|
||||||
case "debugtaper":
|
_commandRouter.Register("debugtaper", args => { }, "");
|
||||||
// Debug functionality removed
|
|
||||||
break;
|
|
||||||
|
|
||||||
case "finditem":
|
_commandRouter.Register("finditem", args =>
|
||||||
|
{
|
||||||
if (args.Length > 1)
|
if (args.Length > 1)
|
||||||
{
|
{
|
||||||
string itemName = string.Join(" ", args, 1, args.Length - 1).Trim('"');
|
string itemName = string.Join(" ", args, 1, args.Length - 1).Trim('"');
|
||||||
|
|
@ -1808,14 +1787,13 @@ namespace MosswartMassacre
|
||||||
WriteToChat("Usage: /mm finditem \"Item Name\"");
|
WriteToChat("Usage: /mm finditem \"Item Name\"");
|
||||||
WriteToChat("Example: /mm finditem \"Prismatic Taper\"");
|
WriteToChat("Example: /mm finditem \"Prismatic Taper\"");
|
||||||
}
|
}
|
||||||
break;
|
}, "Find item in inventory by name");
|
||||||
|
|
||||||
case "checkforupdate":
|
_commandRouter.Register("checkforupdate", args =>
|
||||||
// Run the update check asynchronously
|
{
|
||||||
Task.Run(async () =>
|
Task.Run(async () =>
|
||||||
{
|
{
|
||||||
await UpdateManager.CheckForUpdateAsync();
|
await UpdateManager.CheckForUpdateAsync();
|
||||||
// Update UI if available
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
ViewManager.RefreshUpdateStatus();
|
ViewManager.RefreshUpdateStatus();
|
||||||
|
|
@ -1825,34 +1803,31 @@ namespace MosswartMassacre
|
||||||
WriteToChat($"Error refreshing UI: {ex.Message}");
|
WriteToChat($"Error refreshing UI: {ex.Message}");
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
break;
|
}, "Check for plugin updates");
|
||||||
|
|
||||||
case "update":
|
_commandRouter.Register("update", args =>
|
||||||
// Run the update installation asynchronously
|
{
|
||||||
Task.Run(async () =>
|
Task.Run(async () =>
|
||||||
{
|
{
|
||||||
await UpdateManager.DownloadAndInstallUpdateAsync();
|
await UpdateManager.DownloadAndInstallUpdateAsync();
|
||||||
});
|
});
|
||||||
break;
|
}, "Download and install update");
|
||||||
|
|
||||||
case "debugupdate":
|
_commandRouter.Register("debugupdate", args =>
|
||||||
|
{
|
||||||
Views.VVSTabbedMainView.DebugUpdateControls();
|
Views.VVSTabbedMainView.DebugUpdateControls();
|
||||||
break;
|
}, "Debug update UI controls");
|
||||||
|
|
||||||
case "sendinventory":
|
_commandRouter.Register("sendinventory", args =>
|
||||||
// Force inventory upload with ID requests
|
{
|
||||||
if (_inventoryLogger != null)
|
if (_inventoryLogger != null)
|
||||||
{
|
|
||||||
_inventoryLogger.ForceInventoryUpload();
|
_inventoryLogger.ForceInventoryUpload();
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
|
||||||
WriteToChat("[INV] Inventory system not initialized");
|
WriteToChat("[INV] Inventory system not initialized");
|
||||||
}
|
}, "Force inventory upload with ID requests");
|
||||||
break;
|
|
||||||
|
|
||||||
case "refreshquests":
|
_commandRouter.Register("refreshquests", args =>
|
||||||
// Force quest data refresh (same as clicking refresh button)
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
WriteToChat("[QUEST] Refreshing quest data...");
|
WriteToChat("[QUEST] Refreshing quest data...");
|
||||||
|
|
@ -1862,10 +1837,10 @@ namespace MosswartMassacre
|
||||||
{
|
{
|
||||||
WriteToChat($"[QUEST] Refresh failed: {ex.Message}");
|
WriteToChat($"[QUEST] Refresh failed: {ex.Message}");
|
||||||
}
|
}
|
||||||
break;
|
}, "Force quest data refresh for Flag Tracker");
|
||||||
|
|
||||||
case "queststatus":
|
_commandRouter.Register("queststatus", args =>
|
||||||
// Show quest streaming status
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
WriteToChat("=== Quest Streaming Status ===");
|
WriteToChat("=== Quest Streaming Status ===");
|
||||||
|
|
@ -1896,10 +1871,10 @@ namespace MosswartMassacre
|
||||||
{
|
{
|
||||||
WriteToChat($"[QUEST] Status check failed: {ex.Message}");
|
WriteToChat($"[QUEST] Status check failed: {ex.Message}");
|
||||||
}
|
}
|
||||||
break;
|
}, "Show quest streaming status and diagnostics");
|
||||||
|
|
||||||
case "verbose":
|
_commandRouter.Register("verbose", args =>
|
||||||
// Toggle verbose logging
|
{
|
||||||
if (PluginSettings.Instance != null)
|
if (PluginSettings.Instance != null)
|
||||||
{
|
{
|
||||||
PluginSettings.Instance.VerboseLogging = !PluginSettings.Instance.VerboseLogging;
|
PluginSettings.Instance.VerboseLogging = !PluginSettings.Instance.VerboseLogging;
|
||||||
|
|
@ -1909,12 +1884,7 @@ namespace MosswartMassacre
|
||||||
{
|
{
|
||||||
WriteToChat("Settings not initialized");
|
WriteToChat("Settings not initialized");
|
||||||
}
|
}
|
||||||
break;
|
}, "Toggle verbose debug logging");
|
||||||
|
|
||||||
default:
|
|
||||||
WriteToChat($"Unknown /mm command: {subCommand}. Try /mm help");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue