using OpenMetaverse; using SecondBotEvents.Config; using System.Collections.Generic; using Newtonsoft.Json; using RestSharp; using OpenMetaverse.StructuredData; using System.Linq; using System.Text.RegularExpressions; using System.Text; using System; using SecondBotEvents.RLV; using SecondBotEvents.Commands; using Discord; using System.Threading; namespace SecondBotEvents.Services { public class RLVService : BotServices { protected RlvConfig myConfig; protected bool botConnected = false; protected CurrentOutfitFolder CurrentOutfitFolder = null; public RLVService(EventsSecondBot setMaster) : base(setMaster) { myConfig = new RlvConfig(master.fromEnv, master.fromFolder); this.instance = setMaster; if (myConfig.GetEnabled() == false) { return; } } public override string Status() { if (myConfig == null) { return "No Config"; } else if (myConfig.GetHideStatusOutput() == true) { return "hidden"; } else if (myConfig.GetEnabled() == false) { return "- Not requested -"; } else if (botConnected == false) { return "Waiting for bot"; } return "Active"; } protected void BotClientRestart(object o, BotClientNotice e) { if (e.isStart == false) { return; } LogFormater.Info("RLV service [Attached to new client]"); GetClient().Network.LoggedOut += BotLoggedOut; GetClient().Network.SimConnected += BotLoggedIn; } protected void BotLoggedOut(object o, LoggedOutEventArgs e) { GetClient().Network.SimConnected += BotLoggedIn; botConnected = false; LogFormater.Info("RLV service [Logged out]"); removeEvents(); } protected void BotLoggedIn(object o, SimConnectedEventArgs e) { GetClient().Network.SimConnected -= BotLoggedIn; GetClient().Self.ChatFromSimulator += BotChatEvents; CurrentOutfitFolder = master.CurrentOutfitFolder; botConnected = true; // attach events RLVWearables = new List(); RLVAttachments = new List { new RLVAttachment() {Name = "none", Point = AttachmentPoint.Default} }; foreach (WearableType wear in Enum.GetValues(typeof(WearableType))) { if (wear.Equals(WearableType.Invalid)) continue; string wearstr = Utils.EnumToText(wear); RLVWearables.Add(new RLVWearable() { Name = wearstr.ToLower(), Type = wear }); } foreach (AttachmentPoint pt in Enum.GetValues(typeof(AttachmentPoint))) { string ptstr = Utils.EnumToText(pt); if (pt.Equals(AttachmentPoint.Default) || ptstr.StartsWith("HUD")) continue; RLVAttachments.Add(new RLVAttachment { Name = ptstr.ToLower(), Point = pt }); } // auto load the #RLV folder var rootContent = GetClient().Inventory.Store.GetContents(GetClient().Inventory.Store.RootFolder.UUID); UUID RLVfolder = UUID.Zero; foreach (var baseItem in rootContent) { if (baseItem is InventoryFolder folder && folder.Name == "#RLV") { RLVfolder = folder.UUID; break; } } if(RLVfolder == UUID.Zero) { LogFormater.Info("RLV service [#RLV folder is not setup]"); } } protected UUID GetFolderFromPath(string path) { InventoryNode A = FindFolder(path); if(A != null) { return A.Data.UUID; } return UUID.Zero; } protected void removeEvents() { botConnected = false; if (GetClient() != null) { // remove events GetClient().Self.ChatFromSimulator -= BotChatEvents; } } public override void Start(bool updateEnabled = false, bool setEnabledTo = false) { if(updateEnabled) { myConfig.setEnabled(setEnabledTo); } if (myConfig.GetEnabled() == false) { LogFormater.Info("Events service [Disabled]"); return; } Stop(); running = true; master.BotClientNoticeEvent += BotClientRestart; } public override void Stop() { if (myConfig.GetEnabled() == false) { return; } running = false; master.BotClientNoticeEvent -= BotClientRestart; removeEvents(); } #region Events /// The event subscribers. null if no subcribers private EventHandler m_RLVRuleChanged; /// Raises the RLVRuleChanged event /// An RLVRuleChangedEventArgs object containing the /// data returned from the data server protected virtual void OnRLVRuleChanged(RLVEventArgs e) { EventHandler handler = m_RLVRuleChanged; try { handler?.Invoke(this, e); } catch (Exception) { } } /// Thread sync lock object private readonly object m_RLVRuleChangedLock = new object(); /// Triggered when an RLVRuleChangedUpdate packet is received, /// telling us what our avatar is currently wearing /// request. public event EventHandler RLVRuleChanged { add { lock (m_RLVRuleChangedLock) { m_RLVRuleChanged += value; } } remove { lock (m_RLVRuleChangedLock) { m_RLVRuleChanged -= value; } } } #endregion #region Helper classes, methods, structs and enums public struct RLVWearable { public string Name { get; set; } public WearableType Type { get; set; } } public struct RLVAttachment { public string Name { get; set; } public AttachmentPoint Point { get; set; } } public List RLVWearables; public List RLVAttachments; public WearableType WearableFromString(string type) { var found = RLVWearables.FindAll(w => w.Name == type); return found.Count == 1 ? found[0].Type : WearableType.Invalid; } public AttachmentPoint AttachmentPointFromString(string point) { var found = RLVAttachments.FindAll(a => a.Name == point); return found.Count == 1 ? found[0].Point : AttachmentPoint.Default; } #endregion Helper classes, structs and enums public bool Enabled { get { return myConfig.GetEnabled(); } set { myConfig.setEnabled(value); if (value) StartTimer(); else StopTimer(); } } GridClient client => instance.BotClient.GetClient(); EventsSecondBot instance = null; readonly Regex rlv_regex = new Regex(@"(?[^:=]+)(:(?