commit
3c7baf2838
16 changed files with 272 additions and 600 deletions
|
|
@ -73,6 +73,7 @@ ENV basic_Username='' \
|
|||
homebound_AtHomeSeekLocation='false' \
|
||||
homebound_AtBackupSeekLocation='false' \
|
||||
homebound_AtHomeAutoSitUuid='00000000-0000-0000-0000-000000000000' \
|
||||
homebound_ReturnToHomeSimAfterMins=5 \
|
||||
http_Enabled='false' \
|
||||
http_Port=80 \
|
||||
interaction_Enabled='true' \
|
||||
|
|
|
|||
|
|
@ -43,11 +43,11 @@
|
|||
<Optimize>True</Optimize>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="log4net" Version="2.0.15" />
|
||||
<PackageReference Include="Microsoft.Extensions.ObjectPool" Version="8.0.0" />
|
||||
<PackageReference Include="log4net" Version="2.0.17" />
|
||||
<PackageReference Include="Microsoft.Extensions.ObjectPool" Version="8.0.6" />
|
||||
<PackageReference Include="OggVorbisEncoder" Version="1.2.2" />
|
||||
<PackageReference Include="OpenJpegDotNet-LMV" Version="2.4.0.5" />
|
||||
<PackageReference Include="System.Drawing.Common" Version="8.0.0" />
|
||||
<PackageReference Include="System.Drawing.Common" Version="8.0.6" />
|
||||
<PackageReference Include="System.Net.Http" Version="4.3.4" />
|
||||
<PackageReference Include="System.Net.NameResolution" Version="4.3.0" />
|
||||
<PackageReference Include="System.Threading.Channels" Version="8.0.0" />
|
||||
|
|
|
|||
|
|
@ -116,7 +116,7 @@ namespace OpenMetaverse
|
|||
|
||||
/// <summary>Milliseconds without receiving a packet before the
|
||||
/// connection to a simulator is assumed lost</summary>
|
||||
public int SIMULATOR_TIMEOUT = 30 * 1000;
|
||||
public int SIMULATOR_TIMEOUT = 60 * 1000;
|
||||
|
||||
/// <summary>Milliseconds to wait for a simulator info request through
|
||||
/// the grid interface</summary>
|
||||
|
|
@ -338,7 +338,7 @@ namespace OpenMetaverse
|
|||
/// You will get no output on the console. This behavior can be overriden by creating
|
||||
/// a logger configuration file for log4net
|
||||
/// </summary>
|
||||
public static Helpers.LogLevel LOG_LEVEL = Helpers.LogLevel.None;
|
||||
public static Helpers.LogLevel LOG_LEVEL = Helpers.LogLevel.Error;
|
||||
|
||||
/// <summary>Attach avatar names to log messages</summary>
|
||||
public bool LOG_NAMES = true;
|
||||
|
|
|
|||
|
|
@ -1,4 +1,7 @@
|
|||
using SecondBotEvents.Services;
|
||||
using Newtonsoft.Json;
|
||||
using SecondBotEvents.Services;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace SecondBotEvents.Commands
|
||||
{
|
||||
|
|
@ -42,6 +45,20 @@ namespace SecondBotEvents.Commands
|
|||
return BasicReply(master.DiscordService.BanMember(serverid, memberid, why).Result.ToString(), new [] { serverid, memberid, why });
|
||||
}
|
||||
|
||||
public object Discord_GetMemberRoles(string serverid, string memberid)
|
||||
{
|
||||
if (master.DiscordService.DiscordReady() == false)
|
||||
{
|
||||
return Failure("Discord client not ready");
|
||||
}
|
||||
KeyValuePair<bool, List<string>> reply = master.DiscordService.DiscordMemerRoles(serverid, memberid);
|
||||
if(reply.Key == false)
|
||||
{
|
||||
return Failure(reply.Value.First());
|
||||
}
|
||||
return BasicReply(JsonConvert.SerializeObject(reply.Value));
|
||||
}
|
||||
|
||||
[About("Clears messages on the server sent by the member in the last 13 days, 22hours 59mins")]
|
||||
[ReturnHintsFailure("Discord client not ready")]
|
||||
[ReturnHints("true|false")]
|
||||
|
|
|
|||
|
|
@ -24,7 +24,12 @@ namespace SecondBotEvents.Commands
|
|||
[ArgHints("outputTarget", "HTTP url, channel, avatar UUID or clear to remove all events for the selected type")]
|
||||
public object SetInventoryUpdate(string inventoryType, string outputTarget)
|
||||
{
|
||||
return Failure("@todo inventory update events");
|
||||
if (master.EventsService.isRunning() == true)
|
||||
{
|
||||
master.EventsService.AddInventoryEvent(inventoryType, outputTarget);
|
||||
return BasicReply("Ok");
|
||||
}
|
||||
return Failure("Events service is not running");
|
||||
}
|
||||
|
||||
[About("Uploads a new sound file to inventory")]
|
||||
|
|
@ -151,7 +156,7 @@ namespace SecondBotEvents.Commands
|
|||
[ReturnHints("ok")]
|
||||
[ReturnHints("okMulti")]
|
||||
[ReturnHints("invaild item uuid pr invaild attach point")]
|
||||
[ArgHints("item", "UUID of item, or the attach point")]
|
||||
[ArgHints("item", "UUID of item, or the attach point, or * to remove everything")]
|
||||
public object Detach(string item)
|
||||
{
|
||||
if (UUID.TryParse(item, out UUID itemuuid) == false)
|
||||
|
|
@ -159,7 +164,7 @@ namespace SecondBotEvents.Commands
|
|||
List<InventoryItem> toBeRemoved = new List<InventoryItem>();
|
||||
foreach (KeyValuePair<UUID, AttachmentPoint> pair in GetClient().Appearance.GetAttachmentsByItemId())
|
||||
{
|
||||
if(pair.Value.ToString() != item)
|
||||
if((pair.Value.ToString() != item) || (item == "*"))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
|
@ -425,6 +430,15 @@ namespace SecondBotEvents.Commands
|
|||
}
|
||||
if (RealObject.Value == null)
|
||||
{
|
||||
GetClient().Objects.RequestObjectMedia(objectUUID, GetClient().Network.CurrentSim, null);
|
||||
foreach (KeyValuePair<uint, Primitive> Obj in objects_copy)
|
||||
{
|
||||
if (Obj.Value.ID == objectUUID)
|
||||
{
|
||||
RealObject = Obj;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return Failure("Unable to find object", new [] { item, objectuuid, running });
|
||||
}
|
||||
bool scriptState = runscript;
|
||||
|
|
|
|||
|
|
@ -14,6 +14,10 @@ namespace SecondBotEvents.Config
|
|||
settings.Add("ServerID");
|
||||
settings.Add("ClientToken");
|
||||
settings.Add("AllowDiscordCommands");
|
||||
settings.Add("InteractionEnabled");
|
||||
settings.Add("InteractionCommandName");
|
||||
settings.Add("InteractionHttpTarget");
|
||||
settings.Add("InteractionChannelNumber");
|
||||
settings.Add("HideStatusOutput");
|
||||
}
|
||||
|
||||
|
|
@ -36,5 +40,30 @@ namespace SecondBotEvents.Config
|
|||
{
|
||||
return ReadSettingAsBool("AllowDiscordCommands");
|
||||
}
|
||||
|
||||
public bool GetInteractionEnabled()
|
||||
{
|
||||
return ReadSettingAsBool("InteractionEnabled");
|
||||
}
|
||||
|
||||
public string GetInteractionHttpTarget()
|
||||
{
|
||||
return ReadSettingAsString("InteractionHttpTarget", "https://localhost/interaction.php");
|
||||
}
|
||||
|
||||
public string GetInteractionCommandName()
|
||||
{
|
||||
return ReadSettingAsString("InteractionCommandName","Go");
|
||||
}
|
||||
|
||||
public string GetInteractionChannelNumber()
|
||||
{
|
||||
return ReadSettingAsString("InteractionChannelNumber", "-1");
|
||||
}
|
||||
|
||||
public void SetInteractionEnabled(bool enabled)
|
||||
{
|
||||
mysettings["InteractionEnabled"] = enabled.ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -14,6 +14,7 @@ namespace SecondBotEvents.Config
|
|||
settings.Add("Enabled");
|
||||
settings.Add("HomeSimSlUrl");
|
||||
settings.Add("BackupSimSLUrl");
|
||||
settings.Add("ReturnToHomeSimAfterMins");
|
||||
settings.Add("AtHomeSeekLocation");
|
||||
settings.Add("AtBackupSeekLocation");
|
||||
settings.Add("AtHomeAutoSitUuid");
|
||||
|
|
@ -25,6 +26,11 @@ namespace SecondBotEvents.Config
|
|||
return ReadSettingAsString("AtHomeAutoSitUuid", UUID.Zero.ToString());
|
||||
}
|
||||
|
||||
public int GetReturnToHomeSimAfterMins()
|
||||
{
|
||||
return ReadSettingAsInt("ReturnToHomeSimAfterMins", 1);
|
||||
}
|
||||
|
||||
public bool GetAtHomeSeekLocation()
|
||||
{
|
||||
return ReadSettingAsBool("AtHomeSeekLocation", true);
|
||||
|
|
|
|||
|
|
@ -10,17 +10,17 @@
|
|||
<DockerfileRunEnvironmentFiles>settings.env</DockerfileRunEnvironmentFiles>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Discord.Net" Version="3.13.0" />
|
||||
<PackageReference Include="Discord.Net.WebSocket" Version="3.13.0" />
|
||||
<PackageReference Include="Discord.Net" Version="3.15.2" />
|
||||
<PackageReference Include="Discord.Net.WebSocket" Version="3.15.2" />
|
||||
<PackageReference Include="EmbedIO" Version="3.4.3" />
|
||||
<PackageReference Include="Microsoft.NET.Build.Containers" Version="8.0.100" />
|
||||
<PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.19.5" />
|
||||
<PackageReference Include="Microsoft.NET.Build.Containers" Version="8.0.302" />
|
||||
<PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.20.1" />
|
||||
<PackageReference Include="MSBuildGitHash" Version="2.0.2">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
|
||||
<PackageReference Include="RestSharp" Version="110.2.0" />
|
||||
<PackageReference Include="RestSharp" Version="111.3.0" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\LibreMetaverse\LibreMetaverse.csproj" />
|
||||
|
|
|
|||
|
|
@ -298,7 +298,7 @@ namespace SecondBotEvents.Services
|
|||
return new KeyValuePair<bool, string>(false, e.Message);
|
||||
}
|
||||
}
|
||||
CommandNotice(C.command, source + " ~~ Failure: incorrect number of args", String.Join("@@@", C.args), false);
|
||||
CommandNotice(C.command, source + " ~~ Failure: incorrect number of args expected: "+ theMethod.GetParameters().Count().ToString()+" but got "+ argsList.Count.ToString()+"", String.Join("@@@", C.args), false);
|
||||
return new KeyValuePair<bool, string>(status, reply);
|
||||
}
|
||||
return new KeyValuePair<bool, string>(false, "theMethod is null");
|
||||
|
|
|
|||
|
|
@ -203,7 +203,7 @@ namespace SecondBotEvents.Services
|
|||
foreach(string url in DialogRelayHTTP)
|
||||
{
|
||||
long unixtime = SecondbotHelpers.UnixTimeNow();
|
||||
string token = SecondbotHelpers.GetSHA1(unixtime.ToString() + "DialogRelay"+GetClient().Self.AgentID+ eventMessage);
|
||||
string token = SecondbotHelpers.GetSHA1(unixtime.ToString() + "DialogRelay"+GetClient().Self.AgentID+ eventMessage + master.CommandsService.myConfig.GetSharedSecret());
|
||||
var client = new RestClient(url);
|
||||
var request = new RestRequest("Dialog/Relay", Method.Post);
|
||||
request.AddParameter("token", token);
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ using SecondBotEvents.Commands;
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Net.Http;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
|
@ -94,6 +95,86 @@ namespace SecondBotEvents.Services
|
|||
remove { lock (m_discordEventChatLock) { m_discordChatEvent -= value; } }
|
||||
}
|
||||
|
||||
public KeyValuePair<bool, List<string>> DiscordMemerRoles(string givenserverid, string givenmemberid)
|
||||
{
|
||||
if (GetReadyForDiscordActions() == false)
|
||||
{
|
||||
// bot is not ready this message should not have got here yet.
|
||||
return new KeyValuePair<bool, List<string>>(false,new List<string>() { "not ready"});
|
||||
}
|
||||
if (ulong.TryParse(givenserverid, out ulong serverid) == false)
|
||||
{
|
||||
return new KeyValuePair<bool, List<string>>(false, new List<string>() { "invaild server"});
|
||||
}
|
||||
if (ulong.TryParse(givenmemberid, out ulong memberid) == false)
|
||||
{
|
||||
return new KeyValuePair<bool, List<string>>(false, new List<string>() { "invaild member"});
|
||||
}
|
||||
SocketGuild server = DiscordClient.GetGuild(serverid);
|
||||
if (server == null)
|
||||
{
|
||||
return new KeyValuePair<bool, List<string>>(false, new List<string>() { "Cant get server"});
|
||||
}
|
||||
SocketGuildUser user = server.GetUser(memberid);
|
||||
if(user == null)
|
||||
{
|
||||
return new KeyValuePair<bool, List<string>>(false, new List<string>() { "Cant get user" });
|
||||
}
|
||||
List<string> roleids = new List<string>();
|
||||
foreach(SocketRole role in user.Roles)
|
||||
{
|
||||
roleids.Add(role.Id.ToString());
|
||||
}
|
||||
return new KeyValuePair<bool, List<string>>(true, roleids);
|
||||
}
|
||||
|
||||
protected HttpClient HTTPclient = new HttpClient();
|
||||
protected bool MessageInteractionEvent(SocketMessage message, SocketChannel socketChannel)
|
||||
{
|
||||
if (myConfig.GetInteractionEnabled() != true)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (myConfig.GetInteractionChannelNumber() != socketChannel.Id.ToString())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if(message.Content.StartsWith(myConfig.GetInteractionCommandName()) == false)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if(myConfig.GetInteractionHttpTarget().StartsWith("http") == false)
|
||||
{
|
||||
myConfig.SetInteractionEnabled(false);
|
||||
return false;
|
||||
}
|
||||
string getmessage = message.Content.Replace(myConfig.GetInteractionCommandName(), "");
|
||||
long unixtime = SecondbotHelpers.UnixTimeNow();
|
||||
string hash = SecondbotHelpers.GetSHA1(unixtime.ToString()+getmessage + master.CommandsService.myConfig.GetSharedSecret());
|
||||
Dictionary<string, string> values = new Dictionary<string, string>
|
||||
{
|
||||
{ "message", getmessage },
|
||||
{ "username", message.Author.Username },
|
||||
{ "userid", message.Author.Id.ToString() },
|
||||
{ "unixtime", unixtime.ToString() },
|
||||
{ "hash", hash }
|
||||
};
|
||||
var content = new FormUrlEncodedContent(values);
|
||||
try
|
||||
{
|
||||
HTTPclient.PostAsync(myConfig.GetInteractionHttpTarget(), content);
|
||||
_ = MarkMessage((IUserMessage)message, "✅");
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
LogFormater.Crit("[MessageInteractionEvent] HTTP failed: " + e.Message + "");
|
||||
_ = MarkMessage((IUserMessage)message, "❌");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
protected Task DiscordClientMessageReceived(SocketMessage message)
|
||||
{
|
||||
if(GetReadyForDiscordActions() == false)
|
||||
|
|
@ -102,6 +183,10 @@ namespace SecondBotEvents.Services
|
|||
return Task.CompletedTask;
|
||||
}
|
||||
SocketChannel socketChannel = DiscordClient.GetChannel(message.Channel.Id);
|
||||
if(MessageInteractionEvent(message, socketChannel) == true)
|
||||
{
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
if(socketChannel.GetChannelType() != Discord.ChannelType.Text)
|
||||
{
|
||||
// bot only does stuff on text channels.
|
||||
|
|
@ -471,6 +556,20 @@ namespace SecondBotEvents.Services
|
|||
_ = DiscordClient.LoginAsync(TokenType.Bot, myConfig.GetClientToken()).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
protected Task DiscordInteraction(SocketMessageCommand msg)
|
||||
{
|
||||
if (myConfig.GetInteractionEnabled() == false)
|
||||
{
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
if (msg.CommandName != myConfig.GetInteractionCommandName())
|
||||
{
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
public override void Stop()
|
||||
{
|
||||
if(running == true)
|
||||
|
|
|
|||
|
|
@ -25,6 +25,60 @@ namespace SecondBotEvents.Services
|
|||
protected UUID OutputAvatar = UUID.Zero;
|
||||
protected long lastGroupMembershipUpdate = 0;
|
||||
|
||||
public void InventoryUpdateEvent(Dictionary<string, string> detail)
|
||||
{
|
||||
if (InventoryEvents.ContainsKey(detail["itemtype"]) == true)
|
||||
{
|
||||
foreach(string A in InventoryEvents[detail["itemtype"]])
|
||||
{
|
||||
string output = JsonConvert.SerializeObject(detail);
|
||||
if(UUID.TryParse(A, out UUID OutputAvatar) == true)
|
||||
{
|
||||
if (OutputAvatar != UUID.Zero)
|
||||
{
|
||||
GetClient().Self.InstantMessage(OutputAvatar, output);
|
||||
}
|
||||
}
|
||||
else if (A.StartsWith("http") == true)
|
||||
{
|
||||
long unixtime = SecondbotHelpers.UnixTimeNow();
|
||||
string token = SecondbotHelpers.GetSHA1(unixtime.ToString() + "EventService" + GetClient().Self.AgentID + output+master.CommandsService.myConfig.GetSharedSecret());
|
||||
var client = new RestClient(A);
|
||||
var request = new RestRequest("Inventory/Update", Method.Post);
|
||||
request.AddParameter("token", token);
|
||||
request.AddParameter("unixtime", unixtime.ToString());
|
||||
request.AddParameter("method", "Inventory");
|
||||
request.AddParameter("action", "Update");
|
||||
request.AddParameter("botname", GetClient().Self.Name);
|
||||
request.AddParameter("event", output);
|
||||
request.AddHeader("content-type", "application/x-www-form-urlencoded");
|
||||
client.ExecutePostAsync(request);
|
||||
}
|
||||
else if (int.TryParse(A, out int chann) == true)
|
||||
{
|
||||
if (chann >= 0)
|
||||
{
|
||||
GetClient().Self.Chat(output, chann, ChatType.Normal);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Dictionary<string, List<string>> InventoryEvents = new Dictionary<string, List<string>>();
|
||||
public void AddInventoryEvent(string inventoryType, string outputTarget)
|
||||
{
|
||||
if(InventoryEvents.ContainsKey(inventoryType) == false)
|
||||
{
|
||||
InventoryEvents.Add(inventoryType, new List<string>());
|
||||
}
|
||||
if (InventoryEvents[inventoryType].Contains(outputTarget) == false)
|
||||
{
|
||||
InventoryEvents[inventoryType].Add(outputTarget);
|
||||
}
|
||||
}
|
||||
|
||||
public EventsService(EventsSecondBot setMaster) : base(setMaster)
|
||||
{
|
||||
myConfig = new EventsConfig(master.fromEnv, master.fromFolder);
|
||||
|
|
@ -207,7 +261,7 @@ namespace SecondBotEvents.Services
|
|||
if(myConfig.GetOutputHttpURL() != null)
|
||||
{
|
||||
long unixtime = SecondbotHelpers.UnixTimeNow();
|
||||
string token = SecondbotHelpers.GetSHA1(unixtime.ToString() + "EventService" + GetClient().Self.AgentID + output);
|
||||
string token = SecondbotHelpers.GetSHA1(unixtime.ToString() + "EventService" + GetClient().Self.AgentID + output + master.CommandsService.myConfig.GetSharedSecret());
|
||||
var client = new RestClient(myConfig.GetOutputHttpURL());
|
||||
var request = new RestRequest("Event/Service", Method.Post);
|
||||
request.AddParameter("token", token);
|
||||
|
|
|
|||
|
|
@ -17,9 +17,11 @@ namespace SecondBotEvents.Services
|
|||
protected UUID sitTarget = UUID.Zero;
|
||||
protected long lastAlertTeleport = 0;
|
||||
protected bool evacWanted = false;
|
||||
protected bool evacTeleport = false;
|
||||
protected bool gotoPosAttemptedTp = false;
|
||||
protected bool gotoPosAttemptedWalk = false;
|
||||
protected long lastGotoAction = 0;
|
||||
protected long lastTeleportHomeAttempt = 0;
|
||||
protected bool softDisable = false;
|
||||
protected bool closeToHome = false;
|
||||
protected bool softDisableSit = false;
|
||||
|
|
@ -67,11 +69,13 @@ namespace SecondBotEvents.Services
|
|||
public bool GoHome()
|
||||
{
|
||||
attemptedTeleportHome = true;
|
||||
lastTeleportHomeAttempt = SecondbotHelpers.UnixTimeNow();
|
||||
LogFormater.Info("Teleporting to home sim");
|
||||
return GetClient().Self.Teleport(home.name, new Vector3(home.x, home.y, home.z), new Vector3(0, 0, 0));
|
||||
}
|
||||
protected void Tick()
|
||||
{
|
||||
long dif = 0;
|
||||
if (evacWanted == true)
|
||||
{
|
||||
BotAlertMessage(null, new AlertMessageEventArgs("restart", "999", new OpenMetaverse.StructuredData.OSDMap()));
|
||||
|
|
@ -79,6 +83,7 @@ namespace SecondBotEvents.Services
|
|||
if (GetClient().Network.CurrentSim.Name == home.name)
|
||||
{
|
||||
simNickname = "Home # ";
|
||||
evacTeleport = false;
|
||||
if (sitTarget != UUID.Zero)
|
||||
{
|
||||
if (GetClient().Self.SittingOn == 0)
|
||||
|
|
@ -102,6 +107,7 @@ namespace SecondBotEvents.Services
|
|||
{
|
||||
GetToPos(backup);
|
||||
}
|
||||
TryGoHome();
|
||||
return;
|
||||
}
|
||||
if (simNickname == "")
|
||||
|
|
@ -115,26 +121,38 @@ namespace SecondBotEvents.Services
|
|||
simNickname = "Someplace # ";
|
||||
}
|
||||
}
|
||||
TryGoHome();
|
||||
}
|
||||
|
||||
protected void TryGoHome()
|
||||
{
|
||||
long dif = SecondbotHelpers.UnixTimeNow() - teleportActionLockout;
|
||||
if(dif < 30)
|
||||
if (dif < 30)
|
||||
{
|
||||
return;
|
||||
}
|
||||
teleportActionLockout = SecondbotHelpers.UnixTimeNow();
|
||||
if (attemptedTeleportHome == false)
|
||||
{
|
||||
if(GoHome() == false)
|
||||
dif = SecondbotHelpers.UnixTimeNow() - lastTeleportHomeAttempt;
|
||||
if ((dif / 60) >= myConfig.GetReturnToHomeSimAfterMins())
|
||||
{
|
||||
LogFormater.Warn("Unable to teleport to home sim");
|
||||
attemptedTeleportHome = false;
|
||||
evacTeleport = false;
|
||||
LogFormater.Info("trying to return to home sim");
|
||||
if (GoHome() == false)
|
||||
{
|
||||
LogFormater.Warn("Unable to teleport to home sim");
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
else if(attemptedTeleportBackup == false)
|
||||
else if (attemptedTeleportBackup == false)
|
||||
{
|
||||
attemptedTeleportBackup = true;
|
||||
LogFormater.Info("Teleporting to backup sim");
|
||||
teleportActionLockout = SecondbotHelpers.UnixTimeNow();
|
||||
if(GetClient().Self.Teleport(backup.name, new Vector3(backup.x, backup.y, backup.z), new Vector3(0, 0, 0)) == false)
|
||||
if (GetClient().Self.Teleport(backup.name, new Vector3(backup.x, backup.y, backup.z), new Vector3(0, 0, 0)) == false)
|
||||
{
|
||||
LogFormater.Warn("Unable to teleport to backup sim");
|
||||
}
|
||||
|
|
@ -170,6 +188,10 @@ namespace SecondBotEvents.Services
|
|||
{
|
||||
return simNickname + "Sitting on a thing";
|
||||
}
|
||||
else if(evacTeleport == true)
|
||||
{
|
||||
return simNickname + "Evac teleport";
|
||||
}
|
||||
else if(closeToHome == true)
|
||||
{
|
||||
return simNickname + "In a safe space";
|
||||
|
|
@ -258,6 +280,7 @@ namespace SecondBotEvents.Services
|
|||
return;
|
||||
}
|
||||
evacWanted = false;
|
||||
evacTeleport = true;
|
||||
if (GetClient().Network.CurrentSim.Name == home.name)
|
||||
{
|
||||
LogFormater.Info("Teleporting to backup sim to avoid restart");
|
||||
|
|
|
|||
|
|
@ -165,11 +165,17 @@ namespace SecondBotEvents.Services
|
|||
|
||||
protected void BotInventoryAdd(object o, InventoryObjectAddedEventArgs e)
|
||||
{
|
||||
InventoryItem F = (InventoryItem)e.Obj;
|
||||
Dictionary<string, string> details = new Dictionary<string, string>
|
||||
{
|
||||
{ "itemname", e.Obj.Name },
|
||||
{ "itemuuid", e.Obj.UUID.ToString() },
|
||||
{ "itemtype", F.AssetType.ToString() },
|
||||
};
|
||||
if (master.EventsService.isRunning() == true)
|
||||
{
|
||||
master.EventsService.InventoryUpdateEvent(details);
|
||||
}
|
||||
JsonOuputCleaner(details, "InventoryAdd");
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -204,7 +204,7 @@ namespace SecondBotEvents.Services
|
|||
else if(targetType == "http")
|
||||
{
|
||||
long unixtime = SecondbotHelpers.UnixTimeNow();
|
||||
string token = SecondbotHelpers.GetSHA1(unixtime.ToString() + "RelayService" + GetClient().Self.AgentID + eventMessage);
|
||||
string token = SecondbotHelpers.GetSHA1(unixtime.ToString() + "RelayService" + GetClient().Self.AgentID + eventMessage + master.CommandsService.myConfig.GetSharedSecret());
|
||||
var client = new RestClient(targetOption);
|
||||
var request = new RestRequest("Relay/Service", Method.Post);
|
||||
request.AddParameter("token", token);
|
||||
|
|
|
|||
|
|
@ -1,577 +0,0 @@
|
|||
namespace SecondBotEvents.Services
|
||||
{
|
||||
using global::SecondBotEvents.Commands;
|
||||
using global::SecondBotEvents.Config;
|
||||
using OpenMetaverse;
|
||||
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 "sitground":
|
||||
{
|
||||
if (args != "force")
|
||||
{
|
||||
break;
|
||||
}
|
||||
Self A = new Self(master);
|
||||
A.Sit("ground");
|
||||
break;
|
||||
}
|
||||
case "sit":
|
||||
{
|
||||
if ((args == "add") || (args == "y") || (args == "rem") || (args == "n"))
|
||||
{
|
||||
RlvRules = RemoveRule(command, "*", "*", RlvRules);
|
||||
if ((args == "add") || (args == "y"))
|
||||
{
|
||||
RlvRules = AddRule(Source, command, "*", "*", RlvRules);
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (args != "force")
|
||||
{
|
||||
break;
|
||||
}
|
||||
Self A = new Self(master);
|
||||
A.Sit(subcommand);
|
||||
break;
|
||||
}
|
||||
case "unsit":
|
||||
{
|
||||
if ((args == "add") || (args == "y") || (args == "rem") || (args == "n"))
|
||||
{
|
||||
RlvRules = RemoveRule(command, "*", "*", RlvRules);
|
||||
if ((args == "add") || (args == "y"))
|
||||
{
|
||||
RlvRules = AddRule(Source, command, "*", "*", RlvRules);
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (args != "force")
|
||||
{
|
||||
break;
|
||||
}
|
||||
Self A = new Self(master);
|
||||
A.Stand();
|
||||
break;
|
||||
}
|
||||
case "detach":
|
||||
{
|
||||
if ((args == "add") || (args == "y") || (args == "rem") || (args == "n"))
|
||||
{
|
||||
RlvRules = RemoveRule(command, subcommand, "*", RlvRules);
|
||||
if ((args == "add") || (args == "y"))
|
||||
{
|
||||
RlvRules = AddRule(Source, command, subcommand, "*", RlvRules);
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (args != "force")
|
||||
{
|
||||
break;
|
||||
}
|
||||
InventoryCommands A = new InventoryCommands(master);
|
||||
A.Detach(subcommand);
|
||||
break;
|
||||
}
|
||||
case "getsitid":
|
||||
{
|
||||
uint index = GetClient().Self.SittingOn;
|
||||
if (index > 0)
|
||||
{
|
||||
if (!GetClient().Network.CurrentSim.ObjectsPrimitives.ContainsKey(index))
|
||||
{
|
||||
ChatOutput("!", argAsInt);
|
||||
break;
|
||||
}
|
||||
ChatOutput(GetClient().Network.CurrentSim.ObjectsPrimitives[index].ID.ToString(), argAsInt);
|
||||
break;
|
||||
}
|
||||
ChatOutput(UUID.Zero.ToString(), argAsInt);
|
||||
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 "showinv":
|
||||
case "viewnote":
|
||||
case "viewscript":
|
||||
case "viewtexture":
|
||||
case "rez":
|
||||
case "editworld":
|
||||
case "editattach":
|
||||
case "share_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 "edit":
|
||||
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 "editobj":
|
||||
case "share":
|
||||
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