MosswartMassacre/MosswartMassacre/VtankControl.cs

228 lines
9.5 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using System;
namespace MosswartMassacre
{
/// <summary>
/// Provides helper methods to control VTank from within your plugin.
/// </summary>
public static class VtankControl
{
/// <summary>
/// Sends a chat command to VTank to switch its current meta-state.
/// </summary>
/// <param name="state">
/// The name of the VTank meta-state to activate.
/// </param>
/// <returns>Always returns 1 on sending the command.</returns>
public static double VtSetMetaState(string state)
{
// Dispatch a local chat command that VTank will interpret.
PluginCore.Decal_DispatchOnChatCommand($"/vt setmetastate {state}");
return 1;
}
/// <summary>
/// Queries VTank for its currently active meta-state.
/// </summary>
/// <returns>
/// The name of the current meta-state, or empty string if VTank isnt initialized.
/// </returns>
public static string VtGetMetaState()
{
// Instance.CurrentMetaState is typed as object, so cast it:
return (vTank.Instance.CurrentMetaState as string) ?? string.Empty;
}
/// <summary>
/// Attempts to set a VTank configuration value by name.
/// </summary>
/// <param name="setting">
/// The VTank setting key (e.g. “EnableCombat”, “RingDistance”).
/// </param>
/// <param name="value">
/// The string or numeric value to assign. Numeric strings will be parsed.
/// </param>
/// <returns>
/// 1 if the setting was applied or possibly applied; 0 on known failure.
/// </returns>
public static double VtSetSetting(string setting, string value)
{
try
{
var settingType = vTank.Instance.GetSettingType(setting);
if (settingType == typeof(string))
{
vTank.Instance.SetSetting(setting, value);
}
else if (double.TryParse(value, out double number))
{
if (settingType == typeof(bool))
vTank.Instance.SetSetting(setting, number == 1);
else if (settingType == typeof(double))
vTank.Instance.SetSetting(setting, number);
else if (settingType == typeof(int))
vTank.Instance.SetSetting(setting, Convert.ToInt32(number));
else if (settingType == typeof(float))
vTank.Instance.SetSetting(setting, Convert.ToSingle(number));
}
else
{
// Value wasnt parseable—report failure
return 0;
}
}
catch
{
// Swallow any errors and signal failure
return 0;
}
return 1;
}
/// <summary>
/// Reads back a VTank configuration value as a string.
/// </summary>
/// <param name="setting">The name of the setting to read.</param>
/// <returns>
/// The raw string form of the setting, or empty string if undefined.
/// </returns>
public static string VtGetSetting(string setting)
{
var val = vTank.Instance.GetSetting(setting);
return (val as string) ?? string.Empty;
}
/// <summary>
/// Checks whether the VTank macro engine is currently enabled.
/// </summary>
/// <returns>
/// <c>true</c> if macros are active; otherwise <c>false</c>.
/// </returns>
public static bool VtMacroEnabled()
{
return vTank.Instance.MacroEnabled;
}
/// <summary>
/// Advances VTank to the next waypoint in the current navigation route.
/// </summary>
/// <returns>
/// 1 if the waypoint was advanced successfully; 0 on failure.
/// </returns>
public static double VtAdvanceWaypoint()
{
try
{
var externalInterface = vTank.Instance;
// Basic validation
if (externalInterface.NavNumPoints == 0)
{
return 0; // No waypoints
}
int currentWaypoint = externalInterface.NavCurrent;
int totalWaypoints = externalInterface.NavNumPoints;
// Check if we can advance
if (currentWaypoint >= totalWaypoints - 1)
{
return 0; // Already at last waypoint
}
// Check navigation type
var navType = (int)externalInterface.NavType;
if (navType == 2 || navType == 4) // Target or Once
{
return 0;
}
// Access the cExternalInterfaceTrustedRelay and get the PC (PluginCore) reference
// From decompiled code: external interface uses PC.NavCurrent which references dz.o.l
var interfaceType = externalInterface.GetType();
// Look for any way to get to the PluginCore instance
// The interface should have access to PC or some way to reach it
// Try to get the underlying assembly and find the PC static field
var assembly = interfaceType.Assembly;
var pluginCoreType = assembly.GetType("uTank2.PluginCore");
if (pluginCoreType != null)
{
// Get the static PC field
var pcField = pluginCoreType.GetField("PC", System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Static);
if (pcField != null)
{
var pluginCoreInstance = pcField.GetValue(null);
if (pluginCoreInstance != null)
{
// Try to call the advance method 'i' on the PluginCore instance
// Need to specify parameter types to avoid "Ambiguous match found"
Type[] parameterTypes = new Type[] { typeof(object), assembly.GetType("MetaViewWrappers.MVControlEventArgs") };
var advanceMethod = pluginCoreType.GetMethod("i",
System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance,
null, parameterTypes, null);
if (advanceMethod != null)
{
// Call with parameters matching: i(object A_0, MVControlEventArgs A_1)
advanceMethod.Invoke(pluginCoreInstance, new object[] { null, null });
return 1;
}
}
}
// Fallback: try to access dz static field directly
var dzField = pluginCoreType.GetField("dz", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Static);
if (dzField != null)
{
var dzObject = dzField.GetValue(null);
if (dzObject != null)
{
// Navigate the dz.o.l path
var dzType = dzObject.GetType();
var oField = dzType.GetField("o", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
if (oField != null)
{
var oObject = oField.GetValue(dzObject);
if (oObject != null)
{
var oType = oObject.GetType();
var lField = oType.GetField("l", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
if (lField != null)
{
// Get current value and increment it
int current = (int)lField.GetValue(oObject);
current++;
if (current >= totalWaypoints)
{
current = totalWaypoints - 1;
}
lField.SetValue(oObject, current);
return 1;
}
}
}
}
}
}
return 0;
}
catch (System.Exception ex)
{
PluginCore.WriteToChat("VTank advance error: " + ex.Message);
return 0;
}
}
}
}