From e478053988980bab3db472ada911481634db42a6 Mon Sep 17 00:00:00 2001 From: Madpeter <57852827+Madpeterz@users.noreply.github.com> Date: Mon, 24 Oct 2022 22:26:50 +0100 Subject: [PATCH] wip --- .../Config/CustomCommandsConfig.cs | 57 ++++++++ SecondBotEvents/Config/config.cs | 34 +++-- SecondBotEvents/EventsSecondBot.cs | 4 + .../{Commands.cs => CommandsService.cs} | 61 ++++++--- .../Services/CustomCommandsService.cs | 123 ++++++++++++++++++ SecondBotEvents/Services/DialogService.cs | 48 +++---- 6 files changed, 276 insertions(+), 51 deletions(-) create mode 100644 SecondBotEvents/Config/CustomCommandsConfig.cs rename SecondBotEvents/Services/{Commands.cs => CommandsService.cs} (92%) create mode 100644 SecondBotEvents/Services/CustomCommandsService.cs diff --git a/SecondBotEvents/Config/CustomCommandsConfig.cs b/SecondBotEvents/Config/CustomCommandsConfig.cs new file mode 100644 index 0000000..dc966db --- /dev/null +++ b/SecondBotEvents/Config/CustomCommandsConfig.cs @@ -0,0 +1,57 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace SecondBotEvents.Config +{ + public class CustomCommandsConfig : Config + { + public CustomCommandsConfig(bool fromENV, string fromFolder = "") : base(fromENV, fromFolder) { } + + protected override void MakeSettings() + { + filename = "customcommands"; + settings.Add("count"); + int loop = 1; + while(loop <= GetCount()) + { + settings.Add(loop.ToString() + "_trigger"); + settings.Add(loop.ToString() + "_args"); + settings.Add(loop.ToString() + "_steps"); + int loop2 = 1; + while(loop2 <= GetCommandSteps(loop)) + { + settings.Add(loop.ToString() + "_commands_"+loop2.ToString()); + loop2++; + } + loop++; + } + } + + public string GetCommandStep(int commandIndex, int step) + { + return ReadSettingAsString(commandIndex.ToString() + "_commands_"+ step.ToString(), "Logoff"); + } + + public string GetCommandTrigger(int commandIndex) + { + return ReadSettingAsString(commandIndex.ToString() + "_trigger", "exitplease"); + } + + public int GetCommandSteps(int commandIndex) + { + return ReadSettingAsInt(commandIndex.ToString() + "_steps", 0); + } + + public int GetCommandArgs(int commandIndex) + { + return ReadSettingAsInt(commandIndex.ToString() + "_args", 0); + } + + public int GetCount() + { + return ReadSettingAsInt("count", 1); + } + } + +} \ No newline at end of file diff --git a/SecondBotEvents/Config/config.cs b/SecondBotEvents/Config/config.cs index 77eaded..6d58b6e 100644 --- a/SecondBotEvents/Config/config.cs +++ b/SecondBotEvents/Config/config.cs @@ -14,6 +14,8 @@ namespace SecondBotEvents.Config protected List settings = new List(); protected string filename = "config"; protected bool loaded = false; + protected bool tryLoadfromEnv = false; + public Config(bool fromENV, string fromFolder="") { MakeSettings(); @@ -29,6 +31,7 @@ namespace SecondBotEvents.Config { if(fromENV == true) { + tryLoadfromEnv = true; LoadSettingsFromEnv(); return; } @@ -88,14 +91,7 @@ namespace SecondBotEvents.Config { foreach (string setting in settings) { - string key = filename + "_" + setting; - string value = Environment.GetEnvironmentVariable(key); - if (SecondbotHelpers.notempty(value) == false) - { - mysettings.Add(setting, ""); - continue; - } - mysettings.Add(setting, value); + TryLoadSetting(setting); } loaded = true; } @@ -105,11 +101,31 @@ namespace SecondBotEvents.Config } + protected bool TryLoadSetting(string setting) + { + if(tryLoadfromEnv == false) + { + return false; + } + string key = filename + "_" + setting; + string value = Environment.GetEnvironmentVariable(key); + if(value == null) + { + return false; + } + mysettings.Add(setting, value); + return true; + + } + protected string ReadSettingAsString(string key, string defaultValue) { if (mysettings.ContainsKey(key) == false) { - return defaultValue; + if(TryLoadSetting(key) == false) + { + return defaultValue; + } } return mysettings[key]; } diff --git a/SecondBotEvents/EventsSecondBot.cs b/SecondBotEvents/EventsSecondBot.cs index 7188606..96e827e 100644 --- a/SecondBotEvents/EventsSecondBot.cs +++ b/SecondBotEvents/EventsSecondBot.cs @@ -39,6 +39,8 @@ namespace SecondBotEvents public EventsService EventsService { get { return (EventsService)GetService("EventsService"); } } public DialogService DialogService { get { return (DialogService)GetService("DialogService"); } } + public CustomCommandsService CustomCommandsService { get { return (CustomCommandsService)GetService("CustomCommandsService"); } } + private EventHandler SystemStatusMessages; public event EventHandler SystemStatusMessagesEvent @@ -46,6 +48,7 @@ namespace SecondBotEvents add { lock (SystemStatusMessagesEventsLockable) { SystemStatusMessages += value; } } remove { lock (SystemStatusMessagesEventsLockable) { SystemStatusMessages -= value; } } } + private readonly object SystemStatusMessagesEventsLockable = new object(); public void TriggerSystemStatusMessageEvent(bool change, string message) @@ -149,6 +152,7 @@ namespace SecondBotEvents RegisterService("HomeboundService"); RegisterService("EventsService"); RegisterService("DialogService"); + RegisterService("CustomCommandsService"); if (BotClient.IsLoaded() == false) { Console.WriteLine("Config is not loaded :("); diff --git a/SecondBotEvents/Services/Commands.cs b/SecondBotEvents/Services/CommandsService.cs similarity index 92% rename from SecondBotEvents/Services/Commands.cs rename to SecondBotEvents/Services/CommandsService.cs index b182971..50831bd 100644 --- a/SecondBotEvents/Services/Commands.cs +++ b/SecondBotEvents/Services/CommandsService.cs @@ -132,21 +132,27 @@ namespace SecondBotEvents.Services { return; } - SignedCommand C = new SignedCommand(e.IM.Message, - requireSigning, - myConfig.GetEnforceTimeWindow(), + CommandInterfaceCaller(e.IM.Message, requireSigning); + } + + public KeyValuePair CommandInterfaceCaller(string message, bool requireSigning=false, bool viaCustomCommand=false) + { + SignedCommand C = new SignedCommand(message, + requireSigning, + myConfig.GetEnforceTimeWindow(), myConfig.GetTimeWindowSecs(), myConfig.GetSharedSecret() ); if (C.accepted == false) { - return; + return new KeyValuePair(false, "Not accepted via signing"); } - KeyValuePair reply = RunCommand(C); - if(C.replyTarget != null) + KeyValuePair reply = RunCommand(C, viaCustomCommand); + if (C.replyTarget != null) { SmartCommandReply(C.replyTarget, reply.Value, C.command); } + return reply; } public void SmartCommandReply(string target, string output, string command) @@ -210,21 +216,10 @@ namespace SecondBotEvents.Services } protected HttpClient HTTPclient = new HttpClient(); - public KeyValuePair RunCommand(SignedCommand C) + protected KeyValuePair RunBaseCommand(SignedCommand C) { - if(acceptNewCommands == false) - { - return new KeyValuePair(false, "Not accepting commands"); - } try { - string lowerName = C.command.ToLower(); - if(commandnameLowerToReal.ContainsKey(lowerName) == false) - { - return new KeyValuePair(false, "Unknown command"); - } - C.command = commandnameLowerToReal[lowerName]; - CommandsAPI Endpoint = commandEndpoints[endpointcommandmap[C.command]]; MethodInfo theMethod = Endpoint.GetType().GetMethod(C.command); if (theMethod != null) @@ -264,6 +259,36 @@ namespace SecondBotEvents.Services return new KeyValuePair(false, e.Message); } } + public KeyValuePair RunCommand(SignedCommand C, bool inCustomCommand=false) + { + if(acceptNewCommands == false) + { + return new KeyValuePair(false, "Not accepting commands"); + } + try + { + string lowerName = C.command.ToLower(); + if(commandnameLowerToReal.ContainsKey(lowerName) == false) + { + return new KeyValuePair(false, "Unknown command"); + } + C.command = commandnameLowerToReal[lowerName]; + if(master.CustomCommandsService.HasCommand(C.command) == false) + { + if(inCustomCommand == true) + { + return new KeyValuePair(false, "Custom command chaining is not allowed"); + } + return master.CustomCommandsService.RunCommand(C); + } + return RunBaseCommand(C); + + } + catch (Exception e) + { + return new KeyValuePair(false, e.Message); + } + } public string[] GetFullListOfCommands() { diff --git a/SecondBotEvents/Services/CustomCommandsService.cs b/SecondBotEvents/Services/CustomCommandsService.cs new file mode 100644 index 0000000..21a87eb --- /dev/null +++ b/SecondBotEvents/Services/CustomCommandsService.cs @@ -0,0 +1,123 @@ +using OpenMetaverse; +using SecondBotEvents.Config; +using System; +using System.Collections.Generic; +using System.Configuration; +using System.Linq; +using System.Security.Cryptography; +using System.Text; + +namespace SecondBotEvents.Services +{ + public class CustomCommandsService: BotServices + { + protected CustomCommandsConfig myConfig; + protected bool botConnected = false; + protected Dictionary commands = new Dictionary(); + public bool HasCommand(string C) + { + return commands.ContainsKey(C); + } + public KeyValuePair RunCommand(SignedCommand C) + { + if(commands.ContainsKey(C.command) == false) + { + return new KeyValuePair(false, "Unknown custom command"); + } + CustomCommand Cc = commands[C.command]; + if(C.args.Count() < Cc.args) + { + return new KeyValuePair(false, "Incorrect number of args"); + } + int commandsRun = 0; + foreach(string A in Cc.steps) + { + string Av = A; + int loop = 1; + while(loop <= Cc.args) + { + Av = Av.Replace("[C_ARG_"+ loop.ToString()+"]", C.args[loop - 1]); + loop++; + } + KeyValuePair reply = master.CommandsService.CommandInterfaceCaller(Av, false, true); + if(reply.Key == true) + { + commandsRun++; + } + } + if(commandsRun == 0) + { + return new KeyValuePair(false, "all custom commands have failed for: "+C.command); + } + return new KeyValuePair(false, C.command+": ran with "+commandsRun.ToString()+" commands issued"); + } + public CustomCommandsService(EventsSecondBot setMaster) : base(setMaster) + { + myConfig = new CustomCommandsConfig(master.fromEnv, master.fromFolder); + int loop = 1; + while(loop <= myConfig.GetCount()) + { + CustomCommand C = new CustomCommand(); + C.trigger = myConfig.GetCommandTrigger(loop); + C.args = myConfig.GetCommandArgs(loop); + int loop2 = 1; + while(loop2 <= myConfig.GetCommandSteps(loop)) + { + C.steps.Add(myConfig.GetCommandStep(loop, loop2)); + loop2++; + } + commands.Add(C.trigger, C); + loop++; + } + } + public override string Status() + { + if (myConfig == null) + { + return "Config broken"; + } + else if (botConnected == false) + { + return "Waiting for client"; + } + return "Active "+myConfig.GetCount().ToString()+" custom commands"; + } + + protected void BotClientRestart(object o, BotClientNotice e) + { + Console.WriteLine("CustomCommands service [Attached to new client]"); + GetClient().Network.LoggedOut += BotLoggedOut; + GetClient().Network.SimConnected += BotLoggedIn; + } + + protected void BotLoggedOut(object o, LoggedOutEventArgs e) + { + GetClient().Network.SimConnected += BotLoggedIn; + Console.WriteLine("CustomCommands service [waiting for new client]"); + } + + protected void BotLoggedIn(object o, SimConnectedEventArgs e) + { + GetClient().Network.SimConnected -= BotLoggedIn; + botConnected = true; + } + + public override void Start() + { + Stop(); + master.BotClientNoticeEvent += BotClientRestart; + } + + public override void Stop() + { + master.BotClientNoticeEvent -= BotClientRestart; + } + } + + public class CustomCommand + { + public string trigger = ""; + public int args = 0; + public List steps = new List(); + } +} diff --git a/SecondBotEvents/Services/DialogService.cs b/SecondBotEvents/Services/DialogService.cs index 66f2e26..130193a 100644 --- a/SecondBotEvents/Services/DialogService.cs +++ b/SecondBotEvents/Services/DialogService.cs @@ -144,30 +144,7 @@ namespace SecondBotEvents.Services } } - protected void BotClientRestart(object o, BotClientNotice e) - { - Console.WriteLine("Dialog service [Attached to new client]"); - GetClient().Network.LoggedOut += BotLoggedOut; - GetClient().Network.SimConnected += BotLoggedIn; - } - protected void BotLoggedOut(object o, LoggedOutEventArgs e) - { - GetClient().Network.SimConnected += BotLoggedIn; - Console.WriteLine("Dialog service [waiting for new client]"); - if (GetClient() != null) - { - GetClient().Self.ScriptDialog -= DialogWindowEvent; - } - } - - protected void BotLoggedIn(object o, SimConnectedEventArgs e) - { - GetClient().Network.SimConnected -= BotLoggedIn; - botConnected = true; - // attach events - GetClient().Self.ScriptDialog += DialogWindowEvent; - } protected Dictionary DialogWindows = new Dictionary(); protected Dictionary DialogWindowsExpire = new Dictionary(); @@ -214,8 +191,31 @@ namespace SecondBotEvents.Services } } - + protected void BotClientRestart(object o, BotClientNotice e) + { + Console.WriteLine("Dialog service [Attached to new client]"); + GetClient().Network.LoggedOut += BotLoggedOut; + GetClient().Network.SimConnected += BotLoggedIn; + } + + protected void BotLoggedOut(object o, LoggedOutEventArgs e) + { + GetClient().Network.SimConnected += BotLoggedIn; + Console.WriteLine("Dialog service [waiting for new client]"); + if (GetClient() != null) + { + GetClient().Self.ScriptDialog -= DialogWindowEvent; + } + } + + protected void BotLoggedIn(object o, SimConnectedEventArgs e) + { + GetClient().Network.SimConnected -= BotLoggedIn; + botConnected = true; + // attach events + GetClient().Self.ScriptDialog += DialogWindowEvent; + } public override void Start() {