diff --git a/SecondBotEvents/Commands/Dialogs.cs b/SecondBotEvents/Commands/Dialogs.cs
index a7ef234..352f35d 100644
--- a/SecondBotEvents/Commands/Dialogs.cs
+++ b/SecondBotEvents/Commands/Dialogs.cs
@@ -1,4 +1,5 @@
-using SecondBotEvents.Services;
+using OpenMetaverse;
+using SecondBotEvents.Services;
namespace SecondBotEvents.Commands
@@ -8,21 +9,68 @@ namespace SecondBotEvents.Commands
public Dialogs(EventsSecondBot setmaster) : base(setmaster)
{
}
- [About("Updates the relay target (you can have 1 of each type)
Clear will disable them all")]
- [ReturnHints("cleared")]
- [ReturnHints("set/avatar [ok]")]
- [ReturnHints("set/http [ok]")]
- [ReturnHints("set/channel [ok]")]
- [ReturnHintsFailure("Not a vaild option")]
- [ArgHints("target", "Options: Channel (Any number),Avatar UUID,HTTPurl
Clear")]
- public object DialogRelay(string target)
+
+ [About("adds a avatar dialog relay target [or removes if it exists]")]
+ [ReturnHints("added")]
+ [ReturnHints("removed")]
+ [ReturnHintsFailure("unable to find avatar")]
+ [ReturnHintsFailure("looking up avatar please try again")]
+ [ArgHints("avatar", "the UUID or avatar name to add")]
+ public object DialogRelayAvatarTarget(string avatar)
{
- return Failure("@todo dialog relay");
+ if(UUID.TryParse(avatar, out UUID avUUID) == false)
+ {
+ string avataruuid = master.DataStoreService.GetAvatarUUID(avatar);
+ if (avataruuid == "lookup")
+ {
+ return Failure("looking up avatar please try again");
+ }
+ if (UUID.TryParse(avataruuid, out avUUID) == false)
+ {
+ return Failure("unable to find avatar");
+ }
+ }
+ return BasicReply(master.DialogService.AvatarRelayTarget(avUUID));
}
+ [About("adds a chat dialog relay target [or removes if it exists]")]
+ [ReturnHints("added")]
+ [ReturnHints("removed")]
+ [ReturnHintsFailure("channel must be zero or more")]
+ [ReturnHintsFailure("channel is not vaild")]
+ [ArgHints("channel", "a number >= 0")]
+ public object DialogRelayChatTarget(string channel)
+ {
+ if (int.TryParse(channel, out int channelnum) == false)
+ {
+ return Failure("channel is not vaild");
+ }
+ if(channelnum < 0)
+ {
+ return Failure("channel must be zero or more");
+ }
+ return BasicReply(master.DialogService.ChannelRelayTarget(channelnum));
+ }
+
+ [About("adds a http dialog relay target [or removes if it exists]")]
+ [ReturnHints("added")]
+ [ReturnHints("removed")]
+ [ReturnHintsFailure("url must start with http")]
+ [ArgHints("url", "a vaild http url")]
+ public object DialogRelayHttpTarget(string url)
+ {
+ if(url.StartsWith("http") == false)
+ {
+ return Failure("url must start with http");
+ }
+ return BasicReply(master.DialogService.HttpRelayTarget(url));
+ }
+
+
[About("Makes the bot interact with the dialog [dialogid] with the button [buttontext]")]
- [ReturnHints("true")]
- [ReturnHints("false")]
+ [ReturnHints("action")]
+ [ReturnHintsFailure("Invaild dialog window")]
+ [ReturnHintsFailure("Invaild dialog button")]
[ReturnHintsFailure("bad dialog id")]
[ArgHints("dialogid", "The ID for the dialog")]
[ArgHints("buttontext", "The button text to push")]
@@ -32,20 +80,7 @@ namespace SecondBotEvents.Commands
{
return Failure("bad dialog id", new [] { dialogid, buttontext });
}
- return Failure("@todo dialog relay");
- }
-
- [About("Should the bot track dialogs and send them to the relays setup?")]
- [ReturnHints("updated")]
- [ReturnHintsFailure("bad status")]
- [ArgHints("status", "true or false")]
- public object DialogTrack(string status)
- {
- if (bool.TryParse(status, out bool statuscode) == false)
- {
- return Failure("bad status", new [] { status });
- }
- return Failure("@todo dialog relay");
+ return BasicReply(master.DialogService.DialogAction(dialogidnum, buttontext));
}
}
diff --git a/SecondBotEvents/Config/DialogRelayConfig.cs b/SecondBotEvents/Config/DialogRelayConfig.cs
new file mode 100644
index 0000000..07daafb
--- /dev/null
+++ b/SecondBotEvents/Config/DialogRelayConfig.cs
@@ -0,0 +1,40 @@
+using OpenMetaverse;
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace SecondBotEvents.Config
+{
+ public class DialogRelayConfig : Config
+ {
+ public DialogRelayConfig(bool fromENV, string fromFolder = "") : base(fromENV, fromFolder) { }
+ protected override void MakeSettings()
+ {
+ filename = "dialogrelay";
+ settings.Add("RelayChannel");
+ settings.Add("RelayAvatar");
+ settings.Add("RelayObjectOwnerOnly");
+ settings.Add("RelayHttpurl");
+ }
+
+ public string GetRelayHttpurl()
+ {
+ return ReadSettingAsString("RelayHttpurl", "-");
+ }
+
+ public int GetRelayChannel()
+ {
+ return ReadSettingAsInt("RelayChannel", -1);
+ }
+
+ public string GetRelayAvatar()
+ {
+ return ReadSettingAsString("RelayAvatar", UUID.Zero.ToString());
+ }
+
+ public string RelayObjectOwnerOnly()
+ {
+ return ReadSettingAsString("RelayObjectOwnerOnly", UUID.Zero.ToString());
+ }
+ }
+}
\ No newline at end of file
diff --git a/SecondBotEvents/EventsSecondBot.cs b/SecondBotEvents/EventsSecondBot.cs
index de81870..7188606 100644
--- a/SecondBotEvents/EventsSecondBot.cs
+++ b/SecondBotEvents/EventsSecondBot.cs
@@ -37,6 +37,7 @@ namespace SecondBotEvents
public DataStoreService DataStoreService { get { return (DataStoreService)GetService("DataStoreService"); } }
public HomeboundService HomeboundService { get { return (HomeboundService)GetService("HomeboundService"); } }
public EventsService EventsService { get { return (EventsService)GetService("EventsService"); } }
+ public DialogService DialogService { get { return (DialogService)GetService("DialogService"); } }
private EventHandler SystemStatusMessages;
@@ -147,6 +148,7 @@ namespace SecondBotEvents
RegisterService("InteractionService");
RegisterService("HomeboundService");
RegisterService("EventsService");
+ RegisterService("DialogService");
if (BotClient.IsLoaded() == false)
{
Console.WriteLine("Config is not loaded :(");
diff --git a/SecondBotEvents/Services/DialogService.cs b/SecondBotEvents/Services/DialogService.cs
new file mode 100644
index 0000000..66f2e26
--- /dev/null
+++ b/SecondBotEvents/Services/DialogService.cs
@@ -0,0 +1,239 @@
+using OpenMetaverse;
+using SecondBotEvents.Config;
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Threading;
+using Newtonsoft.Json;
+using System.Linq;
+using Swan;
+using SecondBotEvents.Commands;
+
+namespace SecondBotEvents.Services
+{
+ public class DialogService : BotServices
+ {
+ protected bool botConnected = false;
+ protected DialogRelayConfig myConfig;
+ public DialogService(EventsSecondBot setMaster) : base(setMaster)
+ {
+ myConfig = new DialogRelayConfig(master.fromEnv, master.fromFolder);
+ if(myConfig.GetRelayChannel() >= 0)
+ {
+ DialogRelayChannels.Add(myConfig.GetRelayChannel());
+ }
+ if(UUID.TryParse(myConfig.GetRelayAvatar(), out UUID newAV) == true)
+ {
+ if(newAV != UUID.Zero)
+ {
+ DialogRelayAvatars.Add(newAV);
+ }
+ }
+ if (UUID.TryParse(myConfig.RelayObjectOwnerOnly(), out UUID newObjectOwnerAv) == true)
+ {
+ if (newObjectOwnerAv != UUID.Zero)
+ {
+ objectOwnerOnly = newObjectOwnerAv;
+ }
+ }
+ if(myConfig.GetRelayHttpurl().StartsWith("http") == true)
+ {
+ DialogRelayHTTP.Add(myConfig.GetRelayHttpurl());
+ }
+ }
+ public override string Status()
+ {
+ if(botConnected == false)
+ {
+ return "Waiting for client";
+ }
+ if(DialogWindows.Count > 0)
+ {
+ return DialogWindows.Count().ToString()+" Dialogs waiting";
+ }
+ CleanUp();
+ return "Active";
+ }
+
+ public string AvatarRelayTarget(UUID avatar)
+ {
+ lock (DialogRelayAvatars)
+ {
+ if (DialogRelayAvatars.Contains(avatar) == false)
+ {
+ DialogRelayAvatars.Add(avatar);
+ return "added";
+ }
+ DialogRelayAvatars.Remove(avatar);
+ return "removed";
+ }
+ }
+
+ public string ChannelRelayTarget(int channel)
+ {
+ lock (DialogRelayChannels)
+ {
+ if (DialogRelayChannels.Contains(channel) == false)
+ {
+ DialogRelayChannels.Add(channel);
+ return "added";
+ }
+ DialogRelayChannels.Remove(channel);
+ return "removed";
+ }
+ }
+
+ public string HttpRelayTarget(string url)
+ {
+ lock (DialogRelayHTTP)
+ {
+ if (DialogRelayHTTP.Contains(url) == false)
+ {
+ DialogRelayHTTP.Add(url);
+ return "added";
+ }
+ DialogRelayHTTP.Remove(url);
+ return "removed";
+ }
+ }
+
+ public string DialogAction(int dialogID, string button)
+ {
+ lock(DialogWindows)
+ {
+ if(DialogWindows.ContainsKey(dialogID) == false)
+ {
+ return "Invaild dialog window";
+ }
+ else if (DialogWindows[dialogID].ButtonLabels.Contains(button) == false)
+ {
+ return "Invaild dialog button";
+ }
+ ScriptDialogEventArgs e = DialogWindows[dialogID];
+ GetClient().Self.ReplyToScriptDialog(e.Channel, e.ButtonLabels.IndexOf(button), button, e.ObjectID);
+ DialogWindowsExpire.Remove(dialogID);
+ DialogWindows.Remove(dialogID);
+ return "action";
+ }
+ }
+
+ protected long lastclean = 0;
+ protected void CleanUp()
+ {
+ long dif = SecondbotHelpers.UnixTimeNow() - lastclean;
+ if(dif > 30)
+ {
+ lastclean = SecondbotHelpers.UnixTimeNow();
+ lock(DialogWindows)
+ {
+ long unixtime = SecondbotHelpers.UnixTimeNow();
+ List removeids = new List();
+ foreach(KeyValuePair a in DialogWindowsExpire)
+ {
+ if(a.Value > unixtime)
+ {
+ removeids.Add(a.Key);
+ }
+ }
+ foreach(int id in removeids)
+ {
+ DialogWindowsExpire.Remove(id);
+ DialogWindows.Remove(id);
+ }
+ }
+ }
+ }
+
+ 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();
+ protected int nextDialogWindow = 1;
+ protected List DialogRelayChannels = new List();
+ protected List DialogRelayAvatars = new List();
+ protected List DialogRelayHTTP = new List();
+ protected UUID objectOwnerOnly = UUID.Zero;
+
+ protected void DialogWindowEvent(object sender, ScriptDialogEventArgs e)
+ {
+ lock (DialogWindows)
+ {
+ if((objectOwnerOnly != UUID.Zero) && (objectOwnerOnly != e.OwnerID))
+ {
+ return;
+ }
+ int windowid = nextDialogWindow;
+ nextDialogWindow++;
+ if(nextDialogWindow > 999)
+ {
+ nextDialogWindow = 1;
+ }
+ DialogWindows.Add(windowid, e);
+ DialogWindowsExpire.Add(windowid, SecondbotHelpers.UnixTimeNow() + 440);
+ DialogWindow window = new DialogWindow();
+ window.buttons = e.ButtonLabels.ToArray();
+ window.dialogid = windowid;
+ window.message = e.Message;
+ window.objectname = e.ObjectName;
+ string eventMessage = JsonConvert.SerializeObject(window);
+ foreach(int a in DialogRelayChannels)
+ {
+ if(a >= 0)
+ {
+ GetClient().Self.Chat(eventMessage, a, ChatType.Normal);
+ }
+ }
+ foreach(UUID av in DialogRelayAvatars)
+ {
+ GetClient().Self.InstantMessage(av, eventMessage);
+ }
+ // @todo add http output
+ }
+ }
+
+
+
+
+ public override void Start()
+ {
+ Stop();
+ master.BotClientNoticeEvent += BotClientRestart;
+ }
+
+ public override void Stop()
+ {
+ master.BotClientNoticeEvent -= BotClientRestart;
+ }
+ }
+
+ public class DialogWindow
+ {
+ public string message;
+ public string[] buttons;
+ public string objectname;
+ public int dialogid;
+ }
+}