added http and settings
This commit is contained in:
parent
3c4bfbe772
commit
0f404019b6
6 changed files with 327 additions and 2 deletions
105
MosswartMassacre/HttpCommandServer.cs
Normal file
105
MosswartMassacre/HttpCommandServer.cs
Normal file
|
|
@ -0,0 +1,105 @@
|
|||
using System;
|
||||
using System.Net;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Decal.Adapter;
|
||||
|
||||
namespace MosswartMassacre
|
||||
{
|
||||
public static class HttpCommandServer
|
||||
{
|
||||
private static HttpListener listener;
|
||||
private static CancellationTokenSource cts;
|
||||
private static bool isRunning = false;
|
||||
|
||||
public static bool IsRunning => isRunning;
|
||||
|
||||
public static void Start()
|
||||
{
|
||||
if (isRunning) return;
|
||||
|
||||
try
|
||||
{
|
||||
listener = new HttpListener();
|
||||
listener.Prefixes.Add("http://localhost:8085/");
|
||||
listener.Start();
|
||||
cts = new CancellationTokenSource();
|
||||
Task.Run(() => ListenLoop(cts.Token));
|
||||
|
||||
isRunning = true;
|
||||
PluginCore.WriteToChat("[HTTP] Server started on port 8085.");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
PluginCore.WriteToChat("[HTTP] Error starting server: " + ex.Message);
|
||||
}
|
||||
}
|
||||
|
||||
public static void Stop()
|
||||
{
|
||||
if (!isRunning) return;
|
||||
|
||||
try
|
||||
{
|
||||
cts.Cancel();
|
||||
listener.Stop();
|
||||
listener.Close();
|
||||
listener = null;
|
||||
isRunning = false;
|
||||
PluginCore.WriteToChat("[HTTP] Server stopped.");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
PluginCore.WriteToChat("[HTTP] Error stopping server: " + ex.Message);
|
||||
}
|
||||
}
|
||||
|
||||
private static async Task ListenLoop(CancellationToken token)
|
||||
{
|
||||
while (!token.IsCancellationRequested)
|
||||
{
|
||||
HttpListenerContext context = null;
|
||||
|
||||
try
|
||||
{
|
||||
context = await listener.GetContextAsync();
|
||||
}
|
||||
catch (HttpListenerException)
|
||||
{
|
||||
break; // Listener was stopped
|
||||
}
|
||||
|
||||
if (context == null) continue;
|
||||
|
||||
string requestBody = new System.IO.StreamReader(context.Request.InputStream).ReadToEnd();
|
||||
|
||||
PluginCore.WriteToChat("[HTTP] Received request: " + requestBody);
|
||||
|
||||
// Parse simple format: target=Name&command=/say hello
|
||||
string target = "";
|
||||
string command = "";
|
||||
foreach (var pair in requestBody.Split('&'))
|
||||
{
|
||||
var parts = pair.Split('=');
|
||||
if (parts.Length == 2)
|
||||
{
|
||||
if (parts[0] == "target") target = WebUtility.UrlDecode(parts[1]);
|
||||
else if (parts[0] == "command") command = WebUtility.UrlDecode(parts[1]);
|
||||
}
|
||||
}
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(target) && !string.IsNullOrWhiteSpace(command))
|
||||
{
|
||||
string tellCmd = $"/a {target} {command}";
|
||||
CoreManager.Current.Actions.InvokeChatParser(tellCmd);
|
||||
}
|
||||
|
||||
byte[] buffer = Encoding.UTF8.GetBytes("Command received.");
|
||||
context.Response.ContentLength64 = buffer.Length;
|
||||
context.Response.OutputStream.Write(buffer, 0, buffer.Length);
|
||||
context.Response.OutputStream.Close();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -59,8 +59,13 @@
|
|||
<Reference Include="VirindiViewService">
|
||||
<HintPath>lib\VirindiViewService.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="YamlDotNet, Version=16.0.0.0, Culture=neutral, PublicKeyToken=ec19458f3c15af5e, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\YamlDotNet.16.3.0\lib\net47\YamlDotNet.dll</HintPath>
|
||||
</Reference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="PluginSettings.cs" />
|
||||
<Compile Include="HttpCommandServer.cs" />
|
||||
<Compile Include="DelayedCommandManager.cs" />
|
||||
<Compile Include="MainView.cs" />
|
||||
<Compile Include="PluginCore.cs" />
|
||||
|
|
@ -85,5 +90,9 @@
|
|||
<ItemGroup>
|
||||
<EmbeddedResource Include="ViewXML\mainView.xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="app.config" />
|
||||
<None Include="packages.config" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
</Project>
|
||||
|
|
@ -19,7 +19,10 @@ namespace MosswartMassacre
|
|||
internal static double killsPerHour = 0;
|
||||
internal static DateTime statsStartTime = DateTime.Now;
|
||||
internal static Timer updateTimer;
|
||||
public static bool RareMetaEnabled { get; private set; } = true;
|
||||
public static bool RareMetaEnabled { get; set; } = true;
|
||||
public static bool RemoteCommandsEnabled { get; set; } = false;
|
||||
public static bool HttpServerEnabled { get; set; } = false;
|
||||
public static string CharTag { get; set; } = "";
|
||||
private static Queue<string> rareMessageQueue = new Queue<string>();
|
||||
private static DateTime _lastSent = DateTime.MinValue;
|
||||
private static readonly Queue<string> _chatQueue = new Queue<string>();
|
||||
|
|
@ -29,11 +32,13 @@ namespace MosswartMassacre
|
|||
try
|
||||
{
|
||||
MyHost = Host;
|
||||
|
||||
WriteToChat("Mosswart Massacre has started!");
|
||||
|
||||
// Subscribe to chat message event
|
||||
CoreManager.Current.ChatBoxMessage += new EventHandler<ChatTextInterceptEventArgs>(OnChatText);
|
||||
CoreManager.Current.CommandLineText += OnChatCommand;
|
||||
CoreManager.Current.CharacterFilter.LoginComplete += CharacterFilter_LoginComplete;
|
||||
|
||||
// Initialize the timer
|
||||
updateTimer = new Timer(1000); // Update every second
|
||||
|
|
@ -53,6 +58,7 @@ namespace MosswartMassacre
|
|||
{
|
||||
try
|
||||
{
|
||||
PluginSettings.Save();
|
||||
WriteToChat("Mosswart Massacre is shutting down...");
|
||||
|
||||
// Unsubscribe from chat message event
|
||||
|
|
@ -76,6 +82,20 @@ namespace MosswartMassacre
|
|||
WriteToChat("Error during shutdown: " + ex.Message);
|
||||
}
|
||||
}
|
||||
private void CharacterFilter_LoginComplete(object sender, EventArgs e)
|
||||
{
|
||||
CoreManager.Current.CharacterFilter.LoginComplete -= CharacterFilter_LoginComplete;
|
||||
|
||||
PluginSettings.Initialize(); // Safe to call now
|
||||
|
||||
// Apply the values
|
||||
RareMetaEnabled = PluginSettings.Instance.RareMetaEnabled;
|
||||
RemoteCommandsEnabled = PluginSettings.Instance.RemoteCommandsEnabled;
|
||||
HttpServerEnabled = PluginSettings.Instance.HttpServerEnabled;
|
||||
MainView.SetRareMetaToggleState(RareMetaEnabled);
|
||||
|
||||
WriteToChat("Settings loaded.");
|
||||
}
|
||||
|
||||
private void OnChatText(object sender, ChatTextInterceptEventArgs e)
|
||||
{
|
||||
|
|
@ -133,6 +153,39 @@ namespace MosswartMassacre
|
|||
WriteToChat($"[Mosswart Massacre] Reporting to allegiance: {reportMessage}");
|
||||
MyHost.Actions.InvokeChatParser($"/a {reportMessage}");
|
||||
}
|
||||
if (RemoteCommandsEnabled && e.Color == 18)
|
||||
{
|
||||
string characterName = Regex.Escape(CoreManager.Current.CharacterFilter.Name);
|
||||
string pattern = $@"^\[Allegiance\].*Dunking Rares.*say[s]?, \""!do {characterName} (?<command>.+)\""$";
|
||||
string tag = Regex.Escape(PluginCore.CharTag);
|
||||
string patterntag = $@"^\[Allegiance\].*Dunking Rares.*say[s]?, \""!dot {tag} (?<command>.+)\""$";
|
||||
|
||||
|
||||
var match = Regex.Match(e.Text, pattern);
|
||||
var matchtag = Regex.Match(e.Text, patterntag);
|
||||
|
||||
if (match.Success)
|
||||
{
|
||||
string command = match.Groups["command"].Value;
|
||||
DispatchChatToBoxWithPluginIntercept(command);
|
||||
DelayedCommandManager.AddDelayedCommand($"/a [Remote] Executing: {command}", 2000);
|
||||
}
|
||||
else if (matchtag.Success)
|
||||
{
|
||||
string command = matchtag.Groups["command"].Value;
|
||||
DispatchChatToBoxWithPluginIntercept(command);
|
||||
DelayedCommandManager.AddDelayedCommand($"/a [Remote] Executing: {command}", 2000);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
|
@ -268,7 +321,8 @@ namespace MosswartMassacre
|
|||
}
|
||||
public static void ToggleRareMeta()
|
||||
{
|
||||
RareMetaEnabled = !RareMetaEnabled;
|
||||
PluginSettings.Instance.RareMetaEnabled = !PluginSettings.Instance.RareMetaEnabled;
|
||||
RareMetaEnabled = PluginSettings.Instance.RareMetaEnabled;
|
||||
MainView.SetRareMetaToggleState(RareMetaEnabled);
|
||||
}
|
||||
|
||||
|
|
@ -314,6 +368,8 @@ namespace MosswartMassacre
|
|||
WriteToChat("/mm report - Show current stats");
|
||||
WriteToChat("/mm reset - Reset all counters");
|
||||
WriteToChat("/mm meta - Toggle rare meta state");
|
||||
WriteToChat("/mm http - http server enable|disable");
|
||||
WriteToChat("/mm remotecommand - Listen to remote commands enable|disable");
|
||||
break;
|
||||
|
||||
case "report":
|
||||
|
|
@ -332,6 +388,58 @@ namespace MosswartMassacre
|
|||
MainView.SetRareMetaToggleState(RareMetaEnabled); // <-- sync the UI
|
||||
break;
|
||||
|
||||
case "http":
|
||||
if (args.Length > 1)
|
||||
{
|
||||
if (args[1].Equals("enable", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
PluginSettings.Instance.HttpServerEnabled = true;
|
||||
HttpServerEnabled = true;
|
||||
HttpCommandServer.Start();
|
||||
}
|
||||
else if (args[1].Equals("disable", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
PluginSettings.Instance.HttpServerEnabled = false;
|
||||
HttpServerEnabled = false;
|
||||
HttpCommandServer.Stop();
|
||||
}
|
||||
else
|
||||
{
|
||||
WriteToChat("Usage: /mm http <enable|disable>");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
WriteToChat("Usage: /mm http <enable|disable>");
|
||||
}
|
||||
break;
|
||||
|
||||
case "remotecommands":
|
||||
if (args.Length > 1)
|
||||
{
|
||||
if (args[1].Equals("enable", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
PluginSettings.Instance.RemoteCommandsEnabled = true;
|
||||
RemoteCommandsEnabled = true;
|
||||
WriteToChat("Remote command listening is now ENABLED.");
|
||||
}
|
||||
else if (args[1].Equals("disable", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
PluginSettings.Instance.RemoteCommandsEnabled = false;
|
||||
RemoteCommandsEnabled = false;
|
||||
WriteToChat("Remote command listening is now DISABLED.");
|
||||
}
|
||||
else
|
||||
{
|
||||
WriteToChat("Invalid remotecommands argument. Use 'enable' or 'disable'.");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
WriteToChat("Usage: /mm remotecommands <enable|disable>");
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
WriteToChat($"Unknown /mm command: {subCommand}. Try /mm help");
|
||||
break;
|
||||
|
|
|
|||
80
MosswartMassacre/PluginSettings.cs
Normal file
80
MosswartMassacre/PluginSettings.cs
Normal file
|
|
@ -0,0 +1,80 @@
|
|||
using System;
|
||||
using System.IO;
|
||||
using YamlDotNet.Serialization;
|
||||
using YamlDotNet.Serialization.NamingConventions;
|
||||
using Decal.Adapter;
|
||||
|
||||
namespace MosswartMassacre
|
||||
{
|
||||
public class PluginSettings
|
||||
{
|
||||
private static PluginSettings _instance;
|
||||
private static string _filePath;
|
||||
private bool _remoteCommandsEnabled = false;
|
||||
private bool _rareMetaEnabled = true;
|
||||
private bool _httpServerEnabled = false;
|
||||
private string _charTag = "default";
|
||||
public static PluginSettings Instance => _instance;
|
||||
|
||||
public static void Initialize()
|
||||
{
|
||||
string characterName = CoreManager.Current.CharacterFilter.Name;
|
||||
string pluginFolder = Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location);
|
||||
_filePath = Path.Combine(pluginFolder, $"{characterName}.yaml");
|
||||
|
||||
if (File.Exists(_filePath))
|
||||
{
|
||||
var deserializer = new DeserializerBuilder()
|
||||
.WithNamingConvention(UnderscoredNamingConvention.Instance)
|
||||
.Build();
|
||||
|
||||
string yaml = File.ReadAllText(_filePath);
|
||||
_instance = deserializer.Deserialize<PluginSettings>(yaml);
|
||||
}
|
||||
else
|
||||
{
|
||||
_instance = new PluginSettings();
|
||||
Save();
|
||||
}
|
||||
|
||||
// Apply settings to runtime state
|
||||
PluginCore.RareMetaEnabled = _instance.RareMetaEnabled;
|
||||
PluginCore.RemoteCommandsEnabled = _instance.RemoteCommandsEnabled;
|
||||
PluginCore.HttpServerEnabled = _instance.HttpServerEnabled;
|
||||
PluginCore.CharTag = _instance.CharTag;
|
||||
}
|
||||
|
||||
public static void Save()
|
||||
{
|
||||
var serializer = new SerializerBuilder()
|
||||
.WithNamingConvention(UnderscoredNamingConvention.Instance)
|
||||
.Build();
|
||||
|
||||
string yaml = serializer.Serialize(_instance);
|
||||
File.WriteAllText(_filePath, yaml);
|
||||
}
|
||||
|
||||
public bool RemoteCommandsEnabled
|
||||
{
|
||||
get => _remoteCommandsEnabled;
|
||||
set { _remoteCommandsEnabled = value; Save(); }
|
||||
}
|
||||
|
||||
public bool RareMetaEnabled
|
||||
{
|
||||
get => _rareMetaEnabled;
|
||||
set { _rareMetaEnabled = value; Save(); }
|
||||
}
|
||||
|
||||
public bool HttpServerEnabled
|
||||
{
|
||||
get => _httpServerEnabled;
|
||||
set { _httpServerEnabled = value; Save(); }
|
||||
}
|
||||
public string CharTag
|
||||
{
|
||||
get => _charTag;
|
||||
set { _charTag = value; Save(); }
|
||||
}
|
||||
}
|
||||
}
|
||||
19
MosswartMassacre/app.config
Normal file
19
MosswartMassacre/app.config
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<configuration>
|
||||
<runtime>
|
||||
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="Decal.Interop.Core" publicKeyToken="481f17d392f1fb65" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-2.9.8.3" newVersion="2.9.8.3" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="Decal.Adapter" publicKeyToken="bd1c8ce002ce221e" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-2.9.8.3" newVersion="2.9.8.3" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="Decal.Interop.Inject" publicKeyToken="481f17d392f1fb65" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-2.9.8.3" newVersion="2.9.8.3" />
|
||||
</dependentAssembly>
|
||||
</assemblyBinding>
|
||||
</runtime>
|
||||
</configuration>
|
||||
4
MosswartMassacre/packages.config
Normal file
4
MosswartMassacre/packages.config
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="YamlDotNet" version="16.3.0" targetFramework="net48" />
|
||||
</packages>
|
||||
Loading…
Add table
Add a link
Reference in a new issue