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 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 } } protected void BotClientRestart(object o, BotClientNotice e) { LogFormater.Info("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; LogFormater.Info("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() { Stop(); running = true; master.BotClientNoticeEvent += BotClientRestart; } public override void Stop() { running = false; master.BotClientNoticeEvent -= BotClientRestart; } } public class DialogWindow { public string message; public string[] buttons; public string objectname; public int dialogid; } }