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 new 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 = [];
RLVAttachments =
[
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();
/// 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(@"(?[^:=]+)(:(?