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:
erik 2026-02-27 07:24:43 +00:00
parent 9e9a94f159
commit 4845a67c1f
5 changed files with 585 additions and 516 deletions

View file

@ -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)

View 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}");
}
}
}
}
}

View 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;
}
}

View file

@ -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" />

View file

@ -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;
}
} }