dialog relay support

This commit is contained in:
Madpeter 2022-09-22 01:59:37 +01:00
parent 3eaf98ec6e
commit ed64a509bf
4 changed files with 342 additions and 26 deletions

View file

@ -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)<br/>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<br/>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));
}
}

View file

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

View file

@ -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<SystemStatusMessage> 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 :(");

View file

@ -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<int> removeids = new List<int>();
foreach(KeyValuePair<int,long> 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<int, ScriptDialogEventArgs> DialogWindows = new Dictionary<int, ScriptDialogEventArgs>();
protected Dictionary<int, long> DialogWindowsExpire = new Dictionary<int, long>();
protected int nextDialogWindow = 1;
protected List<int> DialogRelayChannels = new List<int>();
protected List<UUID> DialogRelayAvatars = new List<UUID>();
protected List<string> DialogRelayHTTP = new List<string>();
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<string>();
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;
}
}