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);
|
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)
|
public KeyValuePair<bool, string> CommandInterfaceCaller(string message, bool requireSigning=false, bool viaCustomCommand=false)
|
||||||
{
|
{
|
||||||
string source = "command interface";
|
string source = "command interface";
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@ using System.Linq;
|
||||||
using System.Collections;
|
using System.Collections;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
|
using SecondBotEvents.Commands;
|
||||||
|
|
||||||
namespace SecondBotEvents.Services
|
namespace SecondBotEvents.Services
|
||||||
{
|
{
|
||||||
|
|
@ -505,7 +506,6 @@ namespace SecondBotEvents.Services
|
||||||
* if not the bot will attempt to
|
* if not the bot will attempt to
|
||||||
* lookup the avatar
|
* lookup the avatar
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public bool KnownAvatar(string name)
|
public bool KnownAvatar(string name)
|
||||||
{
|
{
|
||||||
return KnownAvatar(name, UUID.Zero);
|
return KnownAvatar(name, UUID.Zero);
|
||||||
|
|
|
||||||
|
|
@ -73,6 +73,7 @@ namespace SecondBotEvents.Services
|
||||||
protected void BotLoggedOut(object o, LoggedOutEventArgs e)
|
protected void BotLoggedOut(object o, LoggedOutEventArgs e)
|
||||||
{
|
{
|
||||||
GetClient().Network.SimConnected += BotLoggedIn;
|
GetClient().Network.SimConnected += BotLoggedIn;
|
||||||
|
botConnected = false;
|
||||||
LogFormater.Info("Events service [Bot commands disabled]");
|
LogFormater.Info("Events service [Bot commands disabled]");
|
||||||
removeEvents();
|
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