rlv
This commit is contained in:
parent
3e58148299
commit
25ebadc39b
5 changed files with 536 additions and 1 deletions
32
SecondBotEvents/Config/RlvConfig.cs
Normal file
32
SecondBotEvents/Config/RlvConfig.cs
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace SecondBotEvents.Config
|
||||
{
|
||||
public class RlvConfig : Config
|
||||
{
|
||||
public RlvConfig(bool fromENV, string fromFolder = "") : base(fromENV, fromFolder) { }
|
||||
protected override void MakeSettings()
|
||||
{
|
||||
filename = "rlv";
|
||||
settings.Add("Enabled");
|
||||
settings.Add("AllowRlvViaIm");
|
||||
settings.Add("AllowRlvViaObjectOwnerSay");
|
||||
settings.Add("HideStatusOutput");
|
||||
}
|
||||
public bool GetAllowRlvViaIm()
|
||||
{
|
||||
return ReadSettingAsBool("AllowRlvViaIm", false);
|
||||
}
|
||||
public bool GetAllowRlvViaObjectOwnerSay()
|
||||
{
|
||||
return ReadSettingAsBool("AllowRlvViaObjectOwnerSay", false);
|
||||
}
|
||||
|
||||
public bool GetEnabled()
|
||||
{
|
||||
return ReadSettingAsBool("Enabled", false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -168,6 +168,22 @@ namespace SecondBotEvents.Services
|
|||
CommandInterfaceCaller(e.IM.Message, requireSigning);
|
||||
}
|
||||
|
||||
public bool AvatarUUIDIsMaster(UUID avatar)
|
||||
{
|
||||
foreach(string name in myConfig.GetMastersCSV())
|
||||
{
|
||||
string find = master.DataStoreService.GetAvatarUUID(name);
|
||||
if (find != "lookup")
|
||||
{
|
||||
if(avatar.ToString() == find)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public KeyValuePair<bool, string> CommandInterfaceCaller(string message, bool requireSigning=false, bool viaCustomCommand=false)
|
||||
{
|
||||
string source = "command interface";
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ using System.Linq;
|
|||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
using SecondBotEvents.Commands;
|
||||
|
||||
namespace SecondBotEvents.Services
|
||||
{
|
||||
|
|
@ -505,7 +506,6 @@ namespace SecondBotEvents.Services
|
|||
* if not the bot will attempt to
|
||||
* lookup the avatar
|
||||
*/
|
||||
|
||||
public bool KnownAvatar(string name)
|
||||
{
|
||||
return KnownAvatar(name, UUID.Zero);
|
||||
|
|
|
|||
|
|
@ -73,6 +73,7 @@ namespace SecondBotEvents.Services
|
|||
protected void BotLoggedOut(object o, LoggedOutEventArgs e)
|
||||
{
|
||||
GetClient().Network.SimConnected += BotLoggedIn;
|
||||
botConnected = false;
|
||||
LogFormater.Info("Events service [Bot commands disabled]");
|
||||
removeEvents();
|
||||
}
|
||||
|
|
|
|||
486
SecondBotEvents/Services/RlvService.cs
Normal file
486
SecondBotEvents/Services/RlvService.cs
Normal file
|
|
@ -0,0 +1,486 @@
|
|||
namespace SecondBotEvents.Services
|
||||
{
|
||||
using Discord;
|
||||
using global::SecondBotEvents.Commands;
|
||||
using global::SecondBotEvents.Config;
|
||||
using OpenMetaverse;
|
||||
using OpenMetaverse.ImportExport.Collada14;
|
||||
using SecondBotEvents.Commands;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Data;
|
||||
|
||||
namespace SecondBotEvents.Services
|
||||
{
|
||||
public class RlvService : BotServices
|
||||
{
|
||||
protected bool botConnected = false;
|
||||
protected RlvConfig myConfig;
|
||||
protected List<RLVRule> RlvRules = new List<RLVRule>();
|
||||
|
||||
protected List<RLVRule> NotifyRules = new List<RLVRule>();
|
||||
|
||||
|
||||
public RlvService(EventsSecondBot setMaster) : base(setMaster)
|
||||
{
|
||||
myConfig = new RlvConfig(master.fromEnv, master.fromFolder);
|
||||
}
|
||||
public override string Status()
|
||||
{
|
||||
if (myConfig == null)
|
||||
{
|
||||
return "Config broken";
|
||||
}
|
||||
else if(myConfig.GetEnabled() == false)
|
||||
{
|
||||
return "Disabled by config";
|
||||
}
|
||||
else if (myConfig.GetHideStatusOutput() == true)
|
||||
{
|
||||
return "hidden";
|
||||
}
|
||||
else if (botConnected == false)
|
||||
{
|
||||
return "Waiting for client";
|
||||
}
|
||||
return "Active";
|
||||
}
|
||||
|
||||
protected void BotClientRestart(object o, BotClientNotice e)
|
||||
{
|
||||
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;
|
||||
GetClient().Self.IM -= BotImMessage;
|
||||
GetClient().Self.ChatFromSimulator -= LocalChat;
|
||||
botConnected = false;
|
||||
LogFormater.Info("Rlv service [waiting for new client]");
|
||||
}
|
||||
|
||||
protected void BotLoggedIn(object o, SimConnectedEventArgs e)
|
||||
{
|
||||
GetClient().Network.SimConnected -= BotLoggedIn;
|
||||
GetClient().Self.IM += BotImMessage;
|
||||
GetClient().Self.ChatFromSimulator += LocalChat;
|
||||
botConnected = true;
|
||||
}
|
||||
|
||||
public override void Start()
|
||||
{
|
||||
if (myConfig.GetEnabled() == false)
|
||||
{
|
||||
return;
|
||||
}
|
||||
running = true;
|
||||
master.BotClientNoticeEvent += BotClientRestart;
|
||||
}
|
||||
|
||||
public override void Stop()
|
||||
{
|
||||
if (myConfig.GetEnabled() == false)
|
||||
{
|
||||
return;
|
||||
}
|
||||
running = false;
|
||||
master.BotClientNoticeEvent -= BotClientRestart;
|
||||
}
|
||||
|
||||
protected int RlvoutputChannel = 0;
|
||||
|
||||
protected void rlvEvent(UUID fromAvatar, string message, bool fromAv, UUID Source)
|
||||
{
|
||||
if((fromAvatar != GetClient().Self.AgentID) && (master.CommandsService.AvatarUUIDIsMaster(fromAvatar) == false))
|
||||
{
|
||||
return;
|
||||
}
|
||||
if(message.StartsWith("@") == false)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
string[] bits = message.Split(',');
|
||||
foreach(string bit in bits)
|
||||
{
|
||||
string[] subbits = bit.Split("=", 2);
|
||||
// if 2 subbits then command = args
|
||||
// if 1 then just command
|
||||
string command = subbits[0];
|
||||
string? subcommand = null;
|
||||
string args = "";
|
||||
if (subbits.Length > 1)
|
||||
{
|
||||
args = subbits[1];
|
||||
}
|
||||
subbits = command.Split(":");
|
||||
command = subbits[0];
|
||||
if (subbits.Length > 1)
|
||||
{
|
||||
subcommand = subbits[1];
|
||||
}
|
||||
rlvCommand(command, subcommand, args, fromAv, Source);
|
||||
}
|
||||
}
|
||||
// https://wiki.secondlife.com/wiki/LSL_Protocol/RestrainedLoveAPI#Audience
|
||||
// currently to inventory
|
||||
|
||||
protected void rlvCommand(string command,string? subcommand, string args,bool fromAv,UUID Source)
|
||||
{
|
||||
int argAsInt = RlvoutputChannel;
|
||||
if(int.TryParse(args, out argAsInt) == false)
|
||||
{
|
||||
argAsInt = RlvoutputChannel;
|
||||
}
|
||||
switch(command)
|
||||
{
|
||||
case "version":
|
||||
case "versionnew":
|
||||
{
|
||||
ChatOutput("RestrainedLife viewer v2.8 (Secondbot [Events] "+master.GetVersion()+")", argAsInt);
|
||||
break;
|
||||
}
|
||||
case "versionnum":
|
||||
{
|
||||
ChatOutput("2080000", argAsInt);
|
||||
break;
|
||||
}
|
||||
case "versionnumbl":
|
||||
{
|
||||
ChatOutput("2080000" + GetBlackListAsString(subcommand), argAsInt);
|
||||
break;
|
||||
}
|
||||
case "getblacklist":
|
||||
{
|
||||
if(fromAv == false)
|
||||
{
|
||||
break;
|
||||
}
|
||||
ImChatOutput(Source, "Current RLV blacklist is "+GetBlackListAsString(subcommand));
|
||||
break;
|
||||
}
|
||||
case "notify":
|
||||
{
|
||||
string[] bits = subcommand.Split(';');
|
||||
if (bits.Length == 1)
|
||||
{
|
||||
bits = new string[] { "*", bits[0] };
|
||||
}
|
||||
if ((args == "add") || (args == "y"))
|
||||
{
|
||||
NotifyRules = AddRule(Source, bits[0], bits[1], "*", NotifyRules);
|
||||
break;
|
||||
}
|
||||
NotifyRules = RemoveRule(bits[0], bits[1],"*", NotifyRules);
|
||||
break;
|
||||
}
|
||||
case "chatwhisper":
|
||||
case "chatnormal":
|
||||
case "chatshout":
|
||||
case "sendchat":
|
||||
case "setcam_unlock":
|
||||
case "camunlock":
|
||||
case "alwaysrun":
|
||||
case "temprun":
|
||||
case "fly":
|
||||
case "recvchat_sec":
|
||||
case "sendgesture":
|
||||
case "emote":
|
||||
case "recvemote_sec":
|
||||
case "sendim_sec":
|
||||
case "tplm":
|
||||
case "tploc":
|
||||
case "tplure_sec":
|
||||
case "permissive":
|
||||
{
|
||||
RlvRules = RemoveRule(command, "*", "*", RlvRules);
|
||||
if ((args == "add") || (args == "y"))
|
||||
{
|
||||
RlvRules = AddRule(Source, command, "*", "*", RlvRules);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "setrot":
|
||||
{
|
||||
if(args != "force")
|
||||
{
|
||||
break;
|
||||
}
|
||||
if(double.TryParse(subcommand, System.Globalization.NumberStyles.Float, Utils.EnUsCulture, out double rot) == false)
|
||||
{
|
||||
break;
|
||||
}
|
||||
GetClient().Self.Movement.UpdateFromHeading(Math.PI / 2d - rot, true);
|
||||
break;
|
||||
}
|
||||
case "tpto":
|
||||
{
|
||||
if (args != "force")
|
||||
{
|
||||
break;
|
||||
}
|
||||
if (subcommand == null)
|
||||
{
|
||||
break;
|
||||
}
|
||||
string[] bits = subcommand.Split(';');
|
||||
if(bits.Length == 2)
|
||||
{
|
||||
// look at (ignored as docs suck)
|
||||
subcommand = bits[0];
|
||||
}
|
||||
bits = subcommand.Split('/');
|
||||
if(bits.Length == 3)
|
||||
{
|
||||
master.HomeboundService.MarkTeleport();
|
||||
Movement A = new Movement(master);
|
||||
A.Teleport(GetClient().Network.CurrentSim.Name, bits[0], bits[1], bits[2]);
|
||||
break;
|
||||
}
|
||||
else if(bits.Length == 4)
|
||||
{
|
||||
master.HomeboundService.MarkTeleport();
|
||||
Movement A = new Movement(master);
|
||||
A.Teleport(bits[0], bits[1], bits[2], bits[3]);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "getcam_fov":
|
||||
case "camtextures":
|
||||
case "camavdist":
|
||||
case "camdrawmax":
|
||||
case "camdrawmin":
|
||||
case "camdistmax":
|
||||
case "camzoommin":
|
||||
case "camzoommax":
|
||||
case "setcam_textures":
|
||||
case "setcam_fov":
|
||||
case "adjustheight":
|
||||
case "standtp":
|
||||
{
|
||||
break;
|
||||
}
|
||||
case "redirchat":
|
||||
case "camdrawalphamax":
|
||||
case "camdrawalphamin":
|
||||
case "setcam_avdistmin":
|
||||
case "setcam_avdistmax":
|
||||
case "setcam_fovmax":
|
||||
case "setcam_fovmin":
|
||||
case "recvchat":
|
||||
case "recvchatfrom":
|
||||
case "rediremote":
|
||||
case "recvemotefrom":
|
||||
case "recvemote":
|
||||
case "sendchannel":
|
||||
case "sendchannel_sec":
|
||||
case "sendchannel_except":
|
||||
case "sendim":
|
||||
case "sendimto":
|
||||
case "startim":
|
||||
case "startimto":
|
||||
case "recvim":
|
||||
case "recvimfrom":
|
||||
case "tplocal":
|
||||
case "accepttp":
|
||||
case "accepttprequest":
|
||||
case "tprequest":
|
||||
case "tplure":
|
||||
{
|
||||
RlvRules = RemoveRule(command, subcommand, "*", RlvRules);
|
||||
if ((args == "add") || (args == "y"))
|
||||
{
|
||||
RlvRules = AddRule(Source, command, subcommand, "*", RlvRules);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "getcam_fovmax":
|
||||
case "getcam_avdistmax":
|
||||
{
|
||||
GetMaxRulesetValue(command.Replace("get", "set"), argAsInt);
|
||||
break;
|
||||
}
|
||||
case "getcam_zoommin":
|
||||
case "getcam_avdistmin":
|
||||
case "getcam_fovmin":
|
||||
{
|
||||
GetMinRulesetValue(command.Replace("get","set"), argAsInt);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
protected void GetMaxRulesetValue(string ruleName, int channelout)
|
||||
{
|
||||
List<RLVRule> appliedRules = GetRules(ruleName);
|
||||
int maxDis = 9999;
|
||||
foreach (RLVRule rule in appliedRules)
|
||||
{
|
||||
if (int.TryParse(rule.Option, out int value) == true)
|
||||
{
|
||||
if (value < maxDis)
|
||||
{
|
||||
maxDis = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
ChatOutput(maxDis.ToString(), channelout);
|
||||
}
|
||||
|
||||
protected void GetMinRulesetValue(string ruleName, int channelout)
|
||||
{
|
||||
List<RLVRule> appliedRules = GetRules(ruleName);
|
||||
int minDis = 0;
|
||||
foreach (RLVRule rule in appliedRules)
|
||||
{
|
||||
if (int.TryParse(rule.Option, out int value) == true)
|
||||
{
|
||||
if (value > minDis)
|
||||
{
|
||||
minDis = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
ChatOutput(minDis.ToString(), channelout);
|
||||
}
|
||||
|
||||
protected List<RLVRule> GetRules(string command)
|
||||
{
|
||||
List<RLVRule> reply = new List<RLVRule>();
|
||||
foreach(RLVRule rule in RlvRules)
|
||||
{
|
||||
if(rule.Behaviour == command)
|
||||
{
|
||||
reply.Add(rule);
|
||||
}
|
||||
}
|
||||
return reply;
|
||||
|
||||
}
|
||||
|
||||
protected List<RLVRule> AddRule(UUID Source,string Behaviour, string Option, string Param, List<RLVRule> ruleset)
|
||||
{
|
||||
RLVRule newRule = new RLVRule();
|
||||
newRule.Behaviour = "permissive";
|
||||
newRule.Sender = Source;
|
||||
newRule.Option = "*";
|
||||
newRule.Param = "*";
|
||||
ruleset.Add(newRule);
|
||||
return ruleset;
|
||||
}
|
||||
|
||||
protected List<RLVRule> RemoveRule(string Behaviour, string Option,string Param,List<RLVRule> ruleset)
|
||||
{
|
||||
bool foundRule = true;
|
||||
while (foundRule == true)
|
||||
{
|
||||
foundRule = false;
|
||||
int index = -1;
|
||||
foreach (RLVRule rule in ruleset)
|
||||
{
|
||||
if ((rule.Behaviour == Behaviour) && (rule.Option == Option) && (rule.Param == Param))
|
||||
{
|
||||
index = NotifyRules.IndexOf(rule);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (index != -1)
|
||||
{
|
||||
foundRule = true;
|
||||
ruleset.RemoveAt(index);
|
||||
}
|
||||
}
|
||||
return ruleset;
|
||||
}
|
||||
|
||||
protected string GetBlackListAsString(string? filter=null)
|
||||
{
|
||||
return "";
|
||||
}
|
||||
|
||||
protected void ImChatOutput(UUID target, string message)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
protected void ChatOutput(string message, int chan=0)
|
||||
{
|
||||
GetClient().Self.Chat(message, chan, ChatType.Normal);
|
||||
}
|
||||
|
||||
protected void LocalChat(object o, ChatEventArgs e)
|
||||
{
|
||||
if(myConfig.GetAllowRlvViaObjectOwnerSay() == false)
|
||||
{
|
||||
return;
|
||||
}
|
||||
switch (e.Type)
|
||||
{
|
||||
case ChatType.OwnerSay:
|
||||
{
|
||||
rlvEvent(e.OwnerID, e.Message,false, e.SourceID);
|
||||
break;
|
||||
}
|
||||
case ChatType.Whisper:
|
||||
case ChatType.Normal:
|
||||
case ChatType.Shout:
|
||||
case ChatType.RegionSayTo:
|
||||
default:
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected void BotImMessage(object o, InstantMessageEventArgs e)
|
||||
{
|
||||
if (myConfig.GetAllowRlvViaIm() == false)
|
||||
{
|
||||
return;
|
||||
}
|
||||
switch (e.IM.Dialog)
|
||||
{
|
||||
case InstantMessageDialog.MessageFromObject:
|
||||
{
|
||||
// trigger object IM
|
||||
rlvEvent(e.IM.FromAgentID, e.IM.Message,false, e.IM.FromAgentID);
|
||||
break;
|
||||
}
|
||||
case InstantMessageDialog.MessageFromAgent: // shared with SessionSend
|
||||
case InstantMessageDialog.SessionSend:
|
||||
{
|
||||
if (master.DataStoreService.GetIsGroup(e.IM.IMSessionID) == true)
|
||||
{
|
||||
break;
|
||||
}
|
||||
// trigger avatar IM
|
||||
rlvEvent(e.IM.FromAgentID, e.IM.Message, true, e.IM.FromAgentID);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class RLVRule
|
||||
{
|
||||
public string Behaviour { set; get; }
|
||||
public string Option { set; get; }
|
||||
public string Param { set; get; }
|
||||
public UUID Sender { set; get; }
|
||||
public string SenderName { set; get; }
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return string.Format("{0}: {1}:{2}={3} [{4}]", SenderName, Behaviour, Option, Param, Sender);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
Loading…
Reference in a new issue