Merge pull request #96 from Madpeterz/OnEventsFeature
On events feature
This commit is contained in:
commit
190f4c40e6
16 changed files with 1052 additions and 65 deletions
|
|
@ -20,7 +20,16 @@ namespace OpenMetaverse.StructuredData
|
|||
|
||||
public static OSD DeserializeJson(string json)
|
||||
{
|
||||
return DeserializeJson(JsonMapper.ToObject(json));
|
||||
try
|
||||
{
|
||||
JsonData A = JsonMapper.ToObject(json);
|
||||
return DeserializeJson(A);
|
||||
}
|
||||
catch
|
||||
{
|
||||
return null; // something fucky happened to the input
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static OSD DeserializeJson(JsonData json)
|
||||
|
|
|
|||
|
|
@ -2091,30 +2091,37 @@ namespace OpenMetaverse
|
|||
// TODO: create Current Outfit Folder
|
||||
}
|
||||
|
||||
OSDMap request = new OSDMap(1) { ["cof_version"] = currentoutfitfolder.Version };
|
||||
|
||||
string msg = "Server side baking failed";
|
||||
|
||||
OSD res = null;
|
||||
|
||||
await Client.HttpCapsClient.PostRequestAsync(cap, OSDFormat.Xml, request, cancellationToken,
|
||||
(response, data, error) => res = OSDParser.Deserialize(data));
|
||||
|
||||
if (res is OSDMap result)
|
||||
try
|
||||
{
|
||||
if (result["success"])
|
||||
{
|
||||
Logger.Log("Successfully set appearance", Helpers.LogLevel.Info, Client);
|
||||
// TODO: Set local visual params and baked textures based on the result here
|
||||
return true;
|
||||
}
|
||||
if (result.ContainsKey("error"))
|
||||
{
|
||||
msg += ": " + result["error"].AsString();
|
||||
}
|
||||
}
|
||||
OSDMap request = new OSDMap(1) { ["cof_version"] = currentoutfitfolder.Version };
|
||||
|
||||
Logger.Log(msg, Helpers.LogLevel.Error, Client);
|
||||
string msg = "Server side baking failed";
|
||||
|
||||
OSD res = null;
|
||||
|
||||
await Client.HttpCapsClient.PostRequestAsync(cap, OSDFormat.Xml, request, cancellationToken,
|
||||
(response, data, error) => res = OSDParser.Deserialize(data));
|
||||
|
||||
if (res is OSDMap result)
|
||||
{
|
||||
if (result["success"])
|
||||
{
|
||||
Logger.Log("Successfully set appearance", Helpers.LogLevel.Info, Client);
|
||||
// TODO: Set local visual params and baked textures based on the result here
|
||||
return true;
|
||||
}
|
||||
if (result.ContainsKey("error"))
|
||||
{
|
||||
msg += ": " + result["error"].AsString();
|
||||
}
|
||||
}
|
||||
|
||||
Logger.Log(msg, Helpers.LogLevel.Error, Client);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Logger.Log("UpdateAvatarAppearanceAsync has failed to unpack data: "+e.Message, Helpers.LogLevel.Error, Client);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1056,7 +1056,12 @@ namespace OpenMetaverse
|
|||
if (error != null) { return; }
|
||||
|
||||
OSD result = OSDParser.Deserialize(data);
|
||||
GroupMembersHandlerCaps(requestID, result);
|
||||
if (result != null)
|
||||
{
|
||||
GroupMembersHandlerCaps(requestID, result);
|
||||
return;
|
||||
}
|
||||
Logger.Log("Failed to json decode data from uri "+cap.AbsoluteUri+": ", Helpers.LogLevel.Error, Client);
|
||||
});
|
||||
}
|
||||
else
|
||||
|
|
|
|||
|
|
@ -607,14 +607,17 @@ namespace OpenMetaverse
|
|||
try
|
||||
{
|
||||
OSD result = OSDParser.Deserialize(data);
|
||||
OSDMap res = (OSDMap)result;
|
||||
OSDArray itemsOSD = (OSDArray)res["items"];
|
||||
|
||||
foreach (var it in itemsOSD)
|
||||
if (result != null)
|
||||
{
|
||||
InventoryItem item = InventoryItem.FromOSD(it);
|
||||
_Store[item.UUID] = item;
|
||||
OnItemReceived(new ItemReceivedEventArgs(item));
|
||||
OSDMap res = (OSDMap)result;
|
||||
OSDArray itemsOSD = (OSDArray)res["items"];
|
||||
|
||||
foreach (var it in itemsOSD)
|
||||
{
|
||||
InventoryItem item = InventoryItem.FromOSD(it);
|
||||
_Store[item.UUID] = item;
|
||||
OnItemReceived(new ItemReceivedEventArgs(item));
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
|
|
|
|||
|
|
@ -106,27 +106,27 @@ namespace OpenMetaverse
|
|||
/// <summary>Number of milliseconds before a CAPS call will time out</summary>
|
||||
/// <remarks>Setting this too low will cause web requests time out and
|
||||
/// possibly retry repeatedly</remarks>
|
||||
public int CAPS_TIMEOUT = 60 * 1000;
|
||||
public int CAPS_TIMEOUT = 63 * 1000;
|
||||
|
||||
/// <summary>Number of milliseconds for xml-rpc to timeout</summary>
|
||||
public int LOGIN_TIMEOUT = 60 * 1000;
|
||||
public int LOGIN_TIMEOUT = 63 * 1000;
|
||||
|
||||
/// <summary>Milliseconds before a packet is assumed lost and resent</summary>
|
||||
public int RESEND_TIMEOUT = 4000;
|
||||
|
||||
/// <summary>Milliseconds without receiving a packet before the
|
||||
/// connection to a simulator is assumed lost</summary>
|
||||
public int SIMULATOR_TIMEOUT = 60 * 1000;
|
||||
public int SIMULATOR_TIMEOUT = 75 * 1000;
|
||||
|
||||
/// <summary>Milliseconds to wait for a simulator info request through
|
||||
/// the grid interface</summary>
|
||||
public int MAP_REQUEST_TIMEOUT = 5 * 1000;
|
||||
|
||||
/// <summary>Number of milliseconds between sending pings to each sim</summary>
|
||||
public const int PING_INTERVAL = 2200;
|
||||
public const int PING_INTERVAL = 3000;
|
||||
|
||||
/// <summary>Number of milliseconds between sending camera updates</summary>
|
||||
public const int DEFAULT_AGENT_UPDATE_INTERVAL = 500;
|
||||
public const int DEFAULT_AGENT_UPDATE_INTERVAL = 1000;
|
||||
|
||||
/// <summary>Number of milliseconds between updating the current
|
||||
/// positions of moving, non-accelerating and non-colliding objects</summary>
|
||||
|
|
@ -134,7 +134,7 @@ namespace OpenMetaverse
|
|||
|
||||
/// <summary>Millisecond interval between ticks, where all ACKs are
|
||||
/// sent out and the age of unACKed packets is checked</summary>
|
||||
public const int NETWORK_TICK_INTERVAL = 500;
|
||||
public const int NETWORK_TICK_INTERVAL = 650;
|
||||
|
||||
#endregion
|
||||
#region Sizes
|
||||
|
|
|
|||
|
|
@ -145,6 +145,7 @@ namespace SecondBotEvents.Commands
|
|||
[ReturnHints("ok")]
|
||||
public object Logoff()
|
||||
{
|
||||
master.BotClient.flagLogoutExpected();
|
||||
GetClient().Network.BeginLogout();
|
||||
return BasicReply("ok");
|
||||
}
|
||||
|
|
|
|||
101
SecondBotEvents/Config/OnEventConfig.cs
Normal file
101
SecondBotEvents/Config/OnEventConfig.cs
Normal file
|
|
@ -0,0 +1,101 @@
|
|||
using OpenMetaverse;
|
||||
using SecondBotEvents.Services;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace SecondBotEvents.Config
|
||||
{
|
||||
public class OnEventConfig : Config
|
||||
{
|
||||
public OnEventConfig(bool fromENV, string fromFolder = "") : base(fromENV, fromFolder) { }
|
||||
protected override void MakeSettings()
|
||||
{
|
||||
filename = "onevent";
|
||||
settings.Add("Enabled");
|
||||
settings.Add("Count");
|
||||
settings.Add("HideStatusOutput");
|
||||
}
|
||||
|
||||
public void unloadEvents()
|
||||
{
|
||||
int loop = 1;
|
||||
while (loop <= GetCount())
|
||||
{
|
||||
if (GetEventEnabled(loop) == false)
|
||||
{
|
||||
loop++;
|
||||
continue;
|
||||
}
|
||||
RemoveSetting("Event" + loop.ToString() + "Enabled");
|
||||
RemoveSetting("Event" + loop.ToString() + "Source");
|
||||
RemoveSetting("Event" + loop.ToString() + "Monitor");
|
||||
int loop2 = 1;
|
||||
while (loop2 <= GetWhereCount(loop))
|
||||
{
|
||||
RemoveSetting("Event" + loop.ToString() + "Where" + loop2.ToString());
|
||||
loop2++;
|
||||
}
|
||||
RemoveSetting("Event" + loop.ToString() + "WhereCount");
|
||||
loop2 = 1;
|
||||
while (loop2 <= GetActionCount(loop))
|
||||
{
|
||||
settings.Remove("Event" + loop.ToString() + "Action" + loop2.ToString());
|
||||
loop2++;
|
||||
}
|
||||
RemoveSetting("Event" + loop.ToString() + "ActionCount");
|
||||
loop++;
|
||||
}
|
||||
}
|
||||
|
||||
protected void RemoveSetting(string name)
|
||||
{
|
||||
mysettings.Remove(name);
|
||||
settings.Remove(name);
|
||||
}
|
||||
|
||||
public bool GetEnabled()
|
||||
{
|
||||
return ReadSettingAsBool("Enabled", false);
|
||||
}
|
||||
|
||||
public int GetCount()
|
||||
{
|
||||
return ReadSettingAsInt("Count", 0);
|
||||
}
|
||||
|
||||
public int GetActionCount(int oneventid)
|
||||
{
|
||||
return ReadSettingAsInt("Event" + oneventid.ToString() + "ActionCount", 0);
|
||||
}
|
||||
|
||||
public string GetActionStep(int oneventid, int stepid)
|
||||
{
|
||||
return ReadSettingAsString("Event" + oneventid.ToString() + "Action" + stepid.ToString(), "");
|
||||
}
|
||||
|
||||
public string GetWhereCheck(int oneventid, int checkid)
|
||||
{
|
||||
return ReadSettingAsString("Event" + oneventid.ToString() + "Where" + checkid.ToString(), "");
|
||||
}
|
||||
|
||||
public int GetWhereCount(int oneventid)
|
||||
{
|
||||
return ReadSettingAsInt("Event" + oneventid.ToString() + "WhereCount", 0);
|
||||
}
|
||||
|
||||
public bool GetEventEnabled(int oneventid)
|
||||
{
|
||||
return ReadSettingAsBool("Event" + oneventid.ToString() + "Enabled", false);
|
||||
}
|
||||
|
||||
public string GetSource(int oneventid)
|
||||
{
|
||||
return ReadSettingAsString("Event" + oneventid.ToString() + "Source", "");
|
||||
}
|
||||
public string GetSourceMonitor(int oneventid)
|
||||
{
|
||||
return ReadSettingAsString("Event" + oneventid.ToString() + "Monitor", "");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -13,16 +13,6 @@ namespace SecondBotEvents.Config
|
|||
filename = "relay";
|
||||
settings.Add("count");
|
||||
settings.Add("HideStatusOutput");
|
||||
int loop = 1;
|
||||
while(loop <= GetRelayCount())
|
||||
{
|
||||
settings.Add(loop.ToString() + "_enabled");
|
||||
settings.Add(loop.ToString() + "_source_type");
|
||||
settings.Add(loop.ToString() + "_source_option");
|
||||
settings.Add(loop.ToString() + "_target_type");
|
||||
settings.Add(loop.ToString() + "_target_option");
|
||||
loop++;
|
||||
}
|
||||
}
|
||||
|
||||
public int GetRelayCount()
|
||||
|
|
|
|||
|
|
@ -79,22 +79,26 @@ namespace SecondBotEvents.Config
|
|||
MakeSettingsFile(fromFolder);
|
||||
return;
|
||||
}
|
||||
JObject result = JObject.Parse(IO.ReadFile(readfile));
|
||||
foreach (string setting in settings)
|
||||
try
|
||||
{
|
||||
if(result.ContainsKey(setting) == false)
|
||||
JObject result = JObject.Parse(IO.ReadFile(readfile));
|
||||
foreach (var x in result)
|
||||
{
|
||||
continue;
|
||||
settings.Add(x.Key);
|
||||
string value = x.Value.ToString();
|
||||
if (SecondbotHelpers.notempty(value) == false)
|
||||
{
|
||||
mysettings.Add(x.Key, "");
|
||||
continue;
|
||||
}
|
||||
mysettings.Add(x.Key, value);
|
||||
}
|
||||
string value = result[setting].ToString();
|
||||
if (SecondbotHelpers.notempty(value) == false)
|
||||
{
|
||||
mysettings.Add(setting, "");
|
||||
continue;
|
||||
}
|
||||
mysettings.Add(setting, value);
|
||||
loaded = true;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogFormater.Warn("Json format for " + readfile + " is broken: " + ex.Message);
|
||||
}
|
||||
loaded = true;
|
||||
}
|
||||
|
||||
protected void LoadSettingsFromEnv()
|
||||
|
|
@ -152,7 +156,8 @@ namespace SecondBotEvents.Config
|
|||
|
||||
protected int ReadSettingAsInt(string key, int defaultValue = 30)
|
||||
{
|
||||
bool result = int.TryParse(ReadSettingAsString(key, defaultValue.ToString()), out int value);
|
||||
string read = ReadSettingAsString(key, defaultValue.ToString());
|
||||
bool result = int.TryParse(read, out int value);
|
||||
if (result == false)
|
||||
{
|
||||
return defaultValue;
|
||||
|
|
|
|||
|
|
@ -42,6 +42,8 @@ namespace SecondBotEvents
|
|||
public EventsService EventsService { get { return (EventsService)GetService("EventsService"); } }
|
||||
public DialogService DialogService { get { return (DialogService)GetService("DialogService"); } }
|
||||
|
||||
public TriggerOnEventService TriggerOnEventService { get { return (TriggerOnEventService)GetService("TriggerOnEventService"); } }
|
||||
|
||||
public CurrentOutfitFolder CurrentOutfitFolder { get { return (CurrentOutfitFolder)GetService("CurrentOutfitFolder"); } }
|
||||
public RLVService RLV { get { return (RLVService)GetService("RLVService"); } }
|
||||
|
||||
|
|
@ -161,6 +163,7 @@ namespace SecondBotEvents
|
|||
RegisterService("EventsService");
|
||||
RegisterService("DialogService");
|
||||
RegisterService("CustomCommandsService");
|
||||
RegisterService("TriggerOnEventService");
|
||||
if (BotClient.IsLoaded() == false)
|
||||
{
|
||||
LogFormater.Info("Config is not loaded :(");
|
||||
|
|
|
|||
|
|
@ -15,6 +15,12 @@ namespace SecondBotEvents.Services
|
|||
public GridClient client = null;
|
||||
public BasicConfig basicCfg = null;
|
||||
|
||||
protected bool LogoutExpected = false;
|
||||
public void flagLogoutExpected()
|
||||
{
|
||||
LogoutExpected = true;
|
||||
}
|
||||
|
||||
protected bool ExitBot = false;
|
||||
|
||||
protected Timer AutoRestartLoginTimer;
|
||||
|
|
@ -78,6 +84,15 @@ namespace SecondBotEvents.Services
|
|||
protected void BotDisconnected(object o, DisconnectedEventArgs e)
|
||||
{
|
||||
LogFormater.Info("Client service ~ Network disconnected: " + e.Message);
|
||||
if (LogoutExpected == false)
|
||||
{
|
||||
AutoRestartLoginTimer = new Timer();
|
||||
AutoRestartLoginTimer.Interval = 75 * 1000;
|
||||
AutoRestartLoginTimer.AutoReset = false;
|
||||
AutoRestartLoginTimer.Elapsed += RestartTimer;
|
||||
LogFormater.Info("Client service ~ Unexpected disconnect (starting reconnect timer for 75s)");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
protected void BotLoginStatus(object o, LoginProgressEventArgs e)
|
||||
|
|
@ -163,7 +178,10 @@ namespace SecondBotEvents.Services
|
|||
bool isRestart = false;
|
||||
if (client != null)
|
||||
{
|
||||
client.Network.Logout();
|
||||
if (client.Network != null)
|
||||
{
|
||||
client.Network.Logout();
|
||||
}
|
||||
isRestart = true;
|
||||
}
|
||||
client = null;
|
||||
|
|
|
|||
|
|
@ -153,6 +153,7 @@ namespace SecondBotEvents.Services
|
|||
{
|
||||
break;
|
||||
}
|
||||
master.DataStoreService.AddAvatar(e.IM.FromAgentID, e.IM.FromAgentName);
|
||||
requireSigning = false;
|
||||
acceptMessage = myConfig.GetMastersCSV().Contains(e.IM.FromAgentName);
|
||||
break;
|
||||
|
|
@ -415,11 +416,9 @@ namespace SecondBotEvents.Services
|
|||
if (requireSigning == false)
|
||||
{
|
||||
accepted = true; // just accept the command
|
||||
master.CommandNotice(command, source, String.Join("@@@", args), accepted);
|
||||
return;
|
||||
}
|
||||
Vaildate(requireTimewindow, windowSize, secret);
|
||||
master.CommandNotice(command, source, String.Join("@@@", args), accepted);
|
||||
}
|
||||
|
||||
public SignedCommand(CommandsService setMaster, string source, string setCommand, string setSigningCode, string[] setArgs,
|
||||
|
|
|
|||
|
|
@ -976,7 +976,7 @@ namespace SecondBotEvents.Services
|
|||
GetClient().Groups.RequestCurrentGroups();
|
||||
}
|
||||
|
||||
protected void AddAvatar(UUID id, string name)
|
||||
public void AddAvatar(UUID id, string name)
|
||||
{
|
||||
lock (avatarsName2Key) lock (avatarLastUsed)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@ 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)
|
||||
|
|
@ -143,6 +144,7 @@ namespace SecondBotEvents.Services
|
|||
GetClient().Self.AlertMessage += BotAlertMessage;
|
||||
}
|
||||
|
||||
protected long lastAvUpdate = 0;
|
||||
protected string avatarhash = "";
|
||||
protected void TrackAvatarsOnParcel()
|
||||
{
|
||||
|
|
@ -152,6 +154,13 @@ namespace SecondBotEvents.Services
|
|||
GuestListLoaded = false;
|
||||
return;
|
||||
}
|
||||
long dif = SecondbotHelpers.UnixTimeNow() - lastAvUpdate;
|
||||
if(dif < 30)
|
||||
{
|
||||
// only check for changes every 30 secs
|
||||
return;
|
||||
}
|
||||
lastAvUpdate = SecondbotHelpers.UnixTimeNow();
|
||||
|
||||
string hashstring = "";
|
||||
List<UUID> avs = new List<UUID>();
|
||||
|
|
@ -471,4 +480,13 @@ namespace SecondBotEvents.Services
|
|||
Hash = SecondbotHelpers.GetSHA1(raw);
|
||||
}
|
||||
}
|
||||
|
||||
public class GuestUpdateEvent
|
||||
{
|
||||
public string parcelName = "";
|
||||
public string regionName = "";
|
||||
public string avatarName = "";
|
||||
public UUID avatarUUID = UUID.Zero;
|
||||
public bool entered = false;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -196,6 +196,7 @@ namespace SecondBotEvents.Services
|
|||
};
|
||||
if(e.FromTask == false)
|
||||
{
|
||||
master.DataStoreService.AddAvatar(e.Offer.FromAgentID, e.Offer.FromAgentName);
|
||||
details.Add("itemuuid", e.ObjectID.ToString());
|
||||
details.Add("itemname", "?");
|
||||
InventoryItem itm = GetClient().Inventory.FetchItem(e.ObjectID, GetClient().Self.AgentID, 2000);
|
||||
|
|
@ -213,6 +214,7 @@ namespace SecondBotEvents.Services
|
|||
{
|
||||
return;
|
||||
}
|
||||
master.DataStoreService.AddAvatar(e.AgentID, e.AgentName);
|
||||
GetClient().Friends.AcceptFriendship(e.AgentID, e.SessionID);
|
||||
JsonOuputCleaner(e.AgentName, "FriendRequest");
|
||||
|
||||
|
|
@ -278,7 +280,6 @@ namespace SecondBotEvents.Services
|
|||
GetClient().Groups.GroupInvitation -= BotGroupInviteOffer;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
827
SecondBotEvents/Services/TriggerOnEventService.cs
Normal file
827
SecondBotEvents/Services/TriggerOnEventService.cs
Normal file
|
|
@ -0,0 +1,827 @@
|
|||
using OpenMetaverse;
|
||||
using OpenMetaverse.Rendering;
|
||||
using SecondBotEvents.Config;
|
||||
using Swan.Logging;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Reflection.Metadata.Ecma335;
|
||||
|
||||
namespace SecondBotEvents.Services
|
||||
{
|
||||
public class TriggerOnEventService : BotServices
|
||||
{
|
||||
protected OnEventConfig myConfig;
|
||||
protected bool botConnected = false;
|
||||
Dictionary<string,List<CustomOnEvent>> MyCustomEvents = new Dictionary<string, List<CustomOnEvent>>();
|
||||
Dictionary<string, long> lockouts = new Dictionary<string, long>();
|
||||
List<UUID> trackEventGroups = new List<UUID>();
|
||||
public TriggerOnEventService(EventsSecondBot setMaster) : base(setMaster)
|
||||
{
|
||||
myConfig = new OnEventConfig(master.fromEnv, master.fromFolder);
|
||||
int loop = 1;
|
||||
string[] delimiterChars = new string[] { "{IS}", "{NOT}", "{IS_UUD}", "{MISSING}", "{CONTAINS}", "{IN_GROUP}", "{NOT_IN_GROUP}", "{LESSTHAN}", "{MORETHAN}", "{LOCKOUT}" };
|
||||
if(myConfig.GetCount() == 0)
|
||||
{
|
||||
myConfig.setEnabled(false);
|
||||
LogFormater.Info("OnEvent Service - No events enabled stopping");
|
||||
}
|
||||
while (loop <= myConfig.GetCount())
|
||||
{
|
||||
if(myConfig.GetEventEnabled(loop) == false)
|
||||
{
|
||||
LogFormater.Info("OnEvent Service - Event "+loop.ToString()+" is not enabled");
|
||||
loop++;
|
||||
continue;
|
||||
}
|
||||
CustomOnEvent Event = new CustomOnEvent();
|
||||
Event.Source = myConfig.GetSource(loop);
|
||||
Event.MonitorFlags = myConfig.GetSourceMonitor(loop).Split("=#=").ToList();
|
||||
bool eventWhereOk = true;
|
||||
int loop2 = 1;
|
||||
while(loop2 <= myConfig.GetWhereCount(loop))
|
||||
{
|
||||
string check = myConfig.GetWhereCheck(loop, loop2);
|
||||
foreach (string delimiterChar in delimiterChars)
|
||||
{
|
||||
if(check.Contains(delimiterChar) == false)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
string[] bits = check.Split(delimiterChar, StringSplitOptions.RemoveEmptyEntries);
|
||||
if (bits.Length == 2)
|
||||
{
|
||||
string delimiterCharU = delimiterChar.Replace("{", "");
|
||||
delimiterCharU = delimiterCharU.Replace("}", "");
|
||||
delimiterCharU = delimiterCharU.Trim();
|
||||
Event.WhereChecksLeft.Add(bits[0].Trim());
|
||||
Event.WhereChecksCenter.Add(delimiterCharU);
|
||||
Event.WhereChecksRight.Add(bits[1].Trim());
|
||||
}
|
||||
else
|
||||
{
|
||||
eventWhereOk = false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
loop2++;
|
||||
}
|
||||
if (eventWhereOk == false)
|
||||
{
|
||||
LogFormater.Info("OnEvent Service - Event " + loop.ToString() + " failed where config checks");
|
||||
loop++;
|
||||
continue;
|
||||
}
|
||||
Event.Source = myConfig.GetSource(loop);
|
||||
Event.MonitorFlags = myConfig.GetSourceMonitor(loop).Split("=#=").ToList();
|
||||
if ((Event.Source == "GroupMemberJoin") || (Event.Source == "GroupMemberLeave"))
|
||||
{
|
||||
UUID groupUUID = UUID.Zero;
|
||||
if (Event.MonitorFlags.Count != 1)
|
||||
{
|
||||
LogFormater.Info("OnEvent Service - Event " + loop.ToString() + " GroupMember monitor flags not vaild");
|
||||
loop++;
|
||||
continue;
|
||||
}
|
||||
if (UUID.TryParse(Event.MonitorFlags[0], out groupUUID) == false)
|
||||
{
|
||||
LogFormater.Info("OnEvent Service - Event " + loop.ToString() + " GroupMember monitor flags not vaild");
|
||||
loop++;
|
||||
continue;
|
||||
}
|
||||
if (trackEventGroups.Contains(groupUUID) == false)
|
||||
{
|
||||
trackEventGroups.Add(groupUUID);
|
||||
}
|
||||
}
|
||||
else if ((Event.Source == "GuestJoins") || (Event.Source == "GuestLeaves"))
|
||||
{
|
||||
if(Event.MonitorFlags.Count != 2)
|
||||
{
|
||||
LogFormater.Info("OnEvent Service - Event " + loop.ToString() + " Guest monitor flags not vaild");
|
||||
loop++;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else if (Event.Source == "AvatarIm")
|
||||
{
|
||||
if (Event.MonitorFlags.Count != 1)
|
||||
{
|
||||
LogFormater.Info("OnEvent Service - Event " + loop.ToString() + " AvatarIm monitor flags not vaild");
|
||||
loop++;
|
||||
continue;
|
||||
}
|
||||
UUID testUUID = UUID.Zero;
|
||||
UUID.TryParse(Event.MonitorFlags[0],out testUUID);
|
||||
if ((Event.MonitorFlags[0] != "Any") && (testUUID != UUID.Zero))
|
||||
{
|
||||
LogFormater.Info("OnEvent Service - Event " + loop.ToString() + " AvatarIm monitor flags not vaild");
|
||||
loop++;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
loop2 = 1;
|
||||
while (loop2 <= myConfig.GetActionCount(loop))
|
||||
{
|
||||
Event.Actions.Add(myConfig.GetActionStep(loop, loop2));
|
||||
loop2++;
|
||||
}
|
||||
if(Event.Actions.Count == 0)
|
||||
{
|
||||
LogFormater.Info("OnEvent Service - Event " + loop.ToString() + " Actions are not setup");
|
||||
loop++;
|
||||
continue;
|
||||
}
|
||||
if(MyCustomEvents.ContainsKey(Event.Source) == false)
|
||||
{
|
||||
MyCustomEvents.Add(Event.Source, new List<CustomOnEvent>());
|
||||
}
|
||||
MyCustomEvents[Event.Source].Add(Event);
|
||||
loop++;
|
||||
}
|
||||
myConfig.unloadEvents(); // remove unneeded copy of events from the config as we wont be using it
|
||||
if (MyCustomEvents.Count == 0)
|
||||
{
|
||||
myConfig.setEnabled(false);
|
||||
LogFormater.Info("OnEvent Service - failed to load any events stopping");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
protected void BotClientRestart(object o, BotClientNotice e)
|
||||
{
|
||||
botConnected = false;
|
||||
LogFormater.Info("OnEvent Service [Attached to new client]");
|
||||
GetClient().Network.LoggedOut += BotLoggedOut;
|
||||
GetClient().Network.SimConnected += BotLoggedIn;
|
||||
}
|
||||
|
||||
protected void BotLoggedOut(object o, LoggedOutEventArgs e)
|
||||
{
|
||||
botConnected = false;
|
||||
GetClient().Network.SimConnected += BotLoggedIn;
|
||||
LogFormater.Info("OnEvent Service [Standby]");
|
||||
}
|
||||
|
||||
protected void BotImMessage(object o, InstantMessageEventArgs e)
|
||||
{
|
||||
switch (e.IM.Dialog)
|
||||
{
|
||||
case InstantMessageDialog.MessageFromObject:
|
||||
{
|
||||
break;
|
||||
}
|
||||
case InstantMessageDialog.MessageFromAgent: // shared with SessionSend
|
||||
case InstantMessageDialog.SessionSend:
|
||||
{
|
||||
if (e.IM.GroupIM == true)
|
||||
{
|
||||
break;
|
||||
}
|
||||
master.DataStoreService.AddAvatar(e.IM.FromAgentID, e.IM.FromAgentName);
|
||||
// trigger avatar IM
|
||||
TriggerEvent("AvatarIm", new Dictionary<string, string>() {
|
||||
{ "message", e.IM.Message} ,
|
||||
{ "avatarname", e.IM.FromAgentName},
|
||||
{ "avataruuid", e.IM.FromAgentID.ToString() },
|
||||
});
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected void RemoveEvents()
|
||||
{
|
||||
if (master.BotClient != null)
|
||||
{
|
||||
if (GetClient() != null)
|
||||
{
|
||||
GetClient().Self.IM -= BotImMessage;
|
||||
GetClient().Groups.GroupMembersReply -= BotGroupMembers;
|
||||
GetClient().Groups.CurrentGroups -= BotGroupsCurrent;
|
||||
GetClient().Network.SimChanged -= BotChangedSim;
|
||||
GetClient().Self.MoneyBalance -= BotFundsEvent;
|
||||
GetClient().Self.AlertMessage -= BotAlertMessage;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected void AttachEvents()
|
||||
{
|
||||
GetClient().Self.IM += BotImMessage;
|
||||
GetClient().Groups.GroupMembersReply += BotGroupMembers;
|
||||
GetClient().Groups.CurrentGroups += BotGroupsCurrent;
|
||||
GetClient().Network.SimChanged += BotChangedSim;
|
||||
GetClient().Self.MoneyBalance += BotFundsEvent;
|
||||
GetClient().Self.AlertMessage += BotAlertMessage;
|
||||
GetClient().Groups.RequestCurrentGroups();
|
||||
GetClient().Self.RequestBalance();
|
||||
}
|
||||
|
||||
protected void BotAlertMessage(object o, AlertMessageEventArgs e)
|
||||
{
|
||||
TriggerEvent("SimAlert", new Dictionary<string, string>() {
|
||||
{ "alertmessage", e.Message},
|
||||
});
|
||||
}
|
||||
|
||||
protected void BotFundsEvent(object o, BalanceEventArgs e)
|
||||
{
|
||||
TriggerEvent("BalanceUpdate", new Dictionary<string, string>() {
|
||||
{ "funds", e.Balance.ToString()},
|
||||
});
|
||||
}
|
||||
|
||||
protected void BotGroupsCurrent(object o, CurrentGroupsEventArgs e)
|
||||
{
|
||||
lock (GroupMembership) lock (GroupMembershipUpdated) lock(GroupNames)
|
||||
{
|
||||
foreach(Group G in e.Groups.Values)
|
||||
{
|
||||
if (trackEventGroups.Contains(G.ID) == false)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (GroupNames.ContainsKey(G.ID) == true)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
GroupNames.Add(G.ID, G.Name);
|
||||
GroupMembership.Add(G.ID, new List<UUID>());
|
||||
GroupMembershipUpdated.Add(G.ID, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected Dictionary<UUID, List<UUID>> GroupMembership = new Dictionary<UUID, List<UUID>>();
|
||||
protected Dictionary<UUID, string> GroupNames = new Dictionary<UUID, string>();
|
||||
protected Dictionary<UUID, long> GroupMembershipUpdated = new Dictionary<UUID, long>();
|
||||
protected long lastGroupMembershipUpdate = 0;
|
||||
// request group membership updates max of once per 60 secs
|
||||
// request membership update for group once every 15 mins
|
||||
protected void GroupMembershipUpkeep()
|
||||
{
|
||||
lock (GroupMembershipUpdated)
|
||||
{
|
||||
long dif = SecondbotHelpers.UnixTimeNow() - lastGroupMembershipUpdate;
|
||||
if (dif < 60)
|
||||
{
|
||||
return;
|
||||
}
|
||||
UUID updateGroup = UUID.Zero;
|
||||
foreach (KeyValuePair<UUID, long> entry in GroupMembershipUpdated)
|
||||
{
|
||||
dif = SecondbotHelpers.UnixTimeNow() - entry.Value;
|
||||
if (dif > (15 * 60))
|
||||
{
|
||||
updateGroup = entry.Key;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (updateGroup != UUID.Zero)
|
||||
{
|
||||
lastGroupMembershipUpdate = SecondbotHelpers.UnixTimeNow();
|
||||
GroupMembershipUpdated[updateGroup] = SecondbotHelpers.UnixTimeNow();
|
||||
GetClient().Groups.RequestGroupMembers(updateGroup);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected void BotGroupMembers(object sender, GroupMembersReplyEventArgs e)
|
||||
{
|
||||
if(trackEventGroups.Contains(e.GroupID) == false)
|
||||
{
|
||||
return;
|
||||
}
|
||||
lock (GroupMembership) lock(GroupMembershipUpdated)
|
||||
{
|
||||
bool GroupLoaded = false;
|
||||
if (GroupMembership.ContainsKey(e.GroupID) == true)
|
||||
{
|
||||
if (GroupMembership[e.GroupID].Count > 0)
|
||||
{
|
||||
GroupLoaded = true;
|
||||
}
|
||||
}
|
||||
if (GroupLoaded == false)
|
||||
{
|
||||
foreach (GroupMember a in e.Members.Values)
|
||||
{
|
||||
GroupMembership[e.GroupID].Add(a.ID);
|
||||
}
|
||||
return;
|
||||
}
|
||||
List<UUID> joined = new List<UUID>();
|
||||
List<UUID> tracked = new List<UUID>();
|
||||
foreach (UUID a in GroupMembership[e.GroupID])
|
||||
{
|
||||
tracked.Add(a);
|
||||
}
|
||||
master.DataStoreService.GetAvatarNames(tracked);
|
||||
foreach (UUID a in e.Members.Keys)
|
||||
{
|
||||
if (tracked.Contains(a) == true)
|
||||
{
|
||||
tracked.Remove(a);
|
||||
continue;
|
||||
}
|
||||
joined.Add(a);
|
||||
|
||||
}
|
||||
string groupname = "none";
|
||||
if(GroupNames.ContainsKey(e.GroupID) == true)
|
||||
{
|
||||
groupname = GroupNames[e.GroupID];
|
||||
}
|
||||
foreach (UUID a in tracked)
|
||||
{
|
||||
// leave
|
||||
GroupMembership[e.GroupID].Remove(a);
|
||||
TriggerEvent("GroupMemberLeave", new Dictionary<string, string>() {
|
||||
{ "groupuuid", e.GroupID.ToString()},
|
||||
{ "groupname", groupname },
|
||||
{ "avataruuid", a.ToString() }
|
||||
});
|
||||
}
|
||||
foreach (UUID a in joined)
|
||||
{
|
||||
// join
|
||||
GroupMembership[e.GroupID].Add(a);
|
||||
TriggerEvent("GroupMemberJoin", new Dictionary<string, string>() {
|
||||
{ "groupuuid", e.GroupID.ToString()},
|
||||
{ "groupname", groupname },
|
||||
{ "avataruuid", a.ToString() }
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected string GetAvName(string avataruuid)
|
||||
{
|
||||
string avatarname = "lookup";
|
||||
if (avataruuid != null)
|
||||
{
|
||||
if (UUID.TryParse(avataruuid, out UUID avUUID) == true)
|
||||
{
|
||||
avatarname = master.DataStoreService.GetAvatarName(avUUID);
|
||||
}
|
||||
}
|
||||
return avatarname;
|
||||
}
|
||||
|
||||
protected bool IsLockedout(string uuid)
|
||||
{
|
||||
lock (lockouts)
|
||||
{
|
||||
if (lockouts.ContainsKey(uuid) == false)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
long now = SecondbotHelpers.UnixTimeNow();
|
||||
if(now >= lockouts[uuid])
|
||||
{
|
||||
lockouts.Remove(uuid);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
protected void AddToLockout(string uuid, int mins)
|
||||
{
|
||||
lock (lockouts)
|
||||
{
|
||||
long newvalue = SecondbotHelpers.UnixTimeNow() + (mins * 60);
|
||||
if (lockouts.ContainsKey(uuid) == true)
|
||||
{
|
||||
if (lockouts[uuid] < newvalue)
|
||||
{
|
||||
lockouts[uuid] = newvalue;
|
||||
}
|
||||
return;
|
||||
}
|
||||
lockouts.Add(uuid, newvalue);
|
||||
}
|
||||
}
|
||||
|
||||
long lastCleanedLockouts = 0;
|
||||
protected void CleanLockouts()
|
||||
{
|
||||
long dif = SecondbotHelpers.UnixTimeNow() - lastCleanedLockouts;
|
||||
if(dif < 60)
|
||||
{
|
||||
return;
|
||||
}
|
||||
lastCleanedLockouts = SecondbotHelpers.UnixTimeNow();
|
||||
long now = SecondbotHelpers.UnixTimeNow();
|
||||
lock (lockouts)
|
||||
{
|
||||
List<string> toberemoved = new List<string>();
|
||||
foreach(KeyValuePair<string, long> pair in lockouts)
|
||||
{
|
||||
if(pair.Value > now)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
toberemoved.Add(pair.Key);
|
||||
}
|
||||
foreach(string A in toberemoved)
|
||||
{
|
||||
lockouts.Remove(A);
|
||||
}
|
||||
}
|
||||
}
|
||||
protected void BotChangedSim(object sender, SimChangedEventArgs e)
|
||||
{
|
||||
TriggerEvent("ChangeSim", new Dictionary<string, string>()
|
||||
{
|
||||
{ "oldsimname", e.PreviousSimulator.Name },
|
||||
{ "newsimname", GetClient().Network.CurrentSim.Name },
|
||||
});
|
||||
}
|
||||
|
||||
protected string inArgsOrDefault(string arg, Dictionary<string, string> args, string defaultvalue)
|
||||
{
|
||||
if (args.ContainsKey(arg) == true)
|
||||
{
|
||||
return args[arg];
|
||||
}
|
||||
return defaultvalue;
|
||||
}
|
||||
protected void TriggerEvent(string eventName, Dictionary<string,string> args)
|
||||
{
|
||||
if (MyCustomEvents.ContainsKey(eventName) == false)
|
||||
{
|
||||
return;
|
||||
}
|
||||
string avataruuid = inArgsOrDefault("avataruuid", args, null);
|
||||
|
||||
List<int> AvPos = GetAvPos(avataruuid);
|
||||
Vector3 A = GetClient().Self.SimPosition;
|
||||
List<int> BotPos = new List<int>() { (int)Math.Round(A.X), (int)Math.Round(A.Y), (int)Math.Round(A.Z) };
|
||||
Dictionary<string, string> values = new Dictionary<string, string>
|
||||
{
|
||||
{ "alertmessage", inArgsOrDefault("alertmessage", args, "none") },
|
||||
{ "message", inArgsOrDefault("message", args, "none") },
|
||||
{ "funds", inArgsOrDefault("funds", args, "-1") },
|
||||
{ "eventype", eventName },
|
||||
{ "groupuuid", inArgsOrDefault("groupuuid", args, "none") },
|
||||
{ "groupname", inArgsOrDefault("groupname", args, "none") },
|
||||
{ "oldsimname", inArgsOrDefault("oldsimname", args, "none") },
|
||||
{ "newsimname", inArgsOrDefault("newsimname", args, "none") },
|
||||
{ "avataruuid", avataruuid },
|
||||
{ "avatarname", GetAvName(avataruuid) },
|
||||
{ "avatarparcel", GetAvParcel(avataruuid) },
|
||||
{ "botsim", GetClient().Network.CurrentSim.Name },
|
||||
{ "botparcel", GetBotParcel() },
|
||||
{ "avatarx", AvPos[0].ToString() },
|
||||
{ "avatary", AvPos[1].ToString() },
|
||||
{ "avatarz", AvPos[2].ToString() },
|
||||
{ "avatardistance", AvPos[3].ToString() },
|
||||
{ "botx", AvPos[0].ToString() },
|
||||
{ "boty", AvPos[1].ToString() },
|
||||
{ "botz", AvPos[2].ToString() },
|
||||
{ "clockhour", DateTime.Now.ToString("HH") },
|
||||
{ "clockmin", DateTime.Now.ToString("mm") },
|
||||
{ "dayofweek", ((int)DateTime.Now.DayOfWeek).ToString() }
|
||||
};
|
||||
|
||||
foreach (CustomOnEvent E in MyCustomEvents[eventName])
|
||||
{
|
||||
bool canFireEvent = true;
|
||||
if ((E.Source == "GroupMemberJoin") || (E.Source == "GroupMemberLeave"))
|
||||
{
|
||||
if (E.MonitorFlags[0] != values["groupuuid"])
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else if ((E.Source == "GuestJoins") || (E.Source == "GuestLeaves"))
|
||||
{
|
||||
if (
|
||||
(E.MonitorFlags[0] != values["botsim"]) ||
|
||||
(E.MonitorFlags[1] != values["botparcel"]) ||
|
||||
(E.MonitorFlags[1] != values["avatarparcel"])
|
||||
)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
int loop = 0;
|
||||
while(loop < E.WhereChecksLeft.Count)
|
||||
{
|
||||
string left = swapvalues(E.WhereChecksLeft[loop],values);
|
||||
string center = E.WhereChecksCenter[loop];
|
||||
string right = swapvalues(E.WhereChecksRight[loop], values);
|
||||
int leftAsInt = -1;
|
||||
int rightAsInt = -1;
|
||||
int.TryParse(left, out leftAsInt);
|
||||
int.TryParse(right, out rightAsInt);
|
||||
bool leftAsBool = false;
|
||||
if(left == "true") leftAsBool = true;
|
||||
bool rightAsBool = false;
|
||||
if (right == "true") rightAsBool = true;
|
||||
bool leftContactinsRight = left.Contains(right);
|
||||
UUID leftAsUUID = UUID.Zero;
|
||||
bool leftIsUUID = UUID.TryParse(left, out leftAsUUID);
|
||||
UUID rightAsUUID = UUID.Zero;
|
||||
bool rightIsUUID = UUID.TryParse(right, out rightAsUUID);
|
||||
bool leftIsInGroup = false;
|
||||
bool leftIsLockedout = IsLockedout(left);
|
||||
bool leftIsEven = true;
|
||||
bool leftIsDivs = true;
|
||||
if (leftAsInt != 0)
|
||||
{
|
||||
leftIsEven = ((leftAsInt % 2) == 0);
|
||||
if(rightAsInt != 0)
|
||||
{
|
||||
leftIsDivs = ((leftAsInt % rightAsInt) == 0);
|
||||
}
|
||||
}
|
||||
if ((leftIsUUID == true) && (rightIsUUID == true))
|
||||
{
|
||||
leftIsInGroup = master.DataStoreService.IsGroupMember(rightAsUUID, leftAsUUID);
|
||||
}
|
||||
if ((center == "IS") && (left != right)) { canFireEvent = false; }
|
||||
else if ((center == "NOT") && (left == right)) { canFireEvent = false; }
|
||||
else if ((center == "IS_UUID") && (leftIsUUID != rightAsBool)) { canFireEvent = false; }
|
||||
else if ((center == "MISSING") && (leftContactinsRight == true)) { canFireEvent = false; }
|
||||
else if ((center == "CONTAINS") && (leftContactinsRight == false)) { canFireEvent = false; }
|
||||
else if ((center == "IN_GROUP") && (leftIsInGroup == false)) { canFireEvent = false; }
|
||||
else if ((center == "NOT_IN_GROUP") && (leftIsUUID == true) && (rightIsUUID == true) && (leftIsInGroup == true)) { canFireEvent = false; }
|
||||
else if ((center == "LESSTHAN") && (leftAsInt >= rightAsInt)) { canFireEvent = false; }
|
||||
else if ((center == "MORETHAN") && (leftAsInt <= rightAsInt)) { canFireEvent = false; }
|
||||
else if ((center == "LOCKOUT") && (leftIsLockedout != rightAsBool)) { canFireEvent = false; }
|
||||
else if ((center == "IS_EVEN") && (leftIsEven != rightAsBool)) { canFireEvent = false; }
|
||||
else if ((center == "DIVISIBLE") && (leftIsDivs == false)) { canFireEvent = false; }
|
||||
if (canFireEvent == false)
|
||||
{
|
||||
break;
|
||||
}
|
||||
loop++;
|
||||
}
|
||||
if (canFireEvent == false)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
foreach(string action in E.Actions)
|
||||
{
|
||||
string useaction = swapvalues(action, values);
|
||||
string[] bits = useaction.Split('=');
|
||||
if(bits.Length == 2)
|
||||
{
|
||||
if (bits[0] == "lockout")
|
||||
{
|
||||
bits = bits[1].Split("+");
|
||||
if(bits.Length == 2)
|
||||
{
|
||||
if (int.TryParse(bits[1],out int mins) == true)
|
||||
{
|
||||
AddToLockout(bits[0], mins);
|
||||
}
|
||||
}
|
||||
continue;
|
||||
}
|
||||
}
|
||||
master.CommandsService.CommandInterfaceCaller(useaction, false, false, "OnEvents");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected string swapvalues(string input, Dictionary<string, string> values)
|
||||
{
|
||||
foreach(KeyValuePair<string, string> pair in values)
|
||||
{
|
||||
input = input.Replace("["+pair.Key+"]", pair.Value);
|
||||
}
|
||||
return input;
|
||||
}
|
||||
|
||||
protected List<int> GetAvPos(string avataruuid)
|
||||
{
|
||||
if (UUID.TryParse(avataruuid, out UUID avUUID) == false)
|
||||
{
|
||||
return new List<int>() { -1, -1, -1, -1 };
|
||||
}
|
||||
foreach (Avatar A in GetClient().Network.CurrentSim.ObjectsAvatars.Copy().Values)
|
||||
{
|
||||
if (A.ID != avUUID)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
Vector3 avpos = A.Position;
|
||||
int dist = (int)Math.Round(Vector3.Distance(avpos, GetClient().Self.SimPosition));
|
||||
return new List<int>() { (int)Math.Round(A.Position.X), (int)Math.Round(A.Position.Y), (int)Math.Round(A.Position.Z), dist };
|
||||
}
|
||||
return new List<int>() { -1, -1, -1, -1 };
|
||||
}
|
||||
|
||||
protected string GetAvParcel(string avataruuid)
|
||||
{
|
||||
if (UUID.TryParse(avataruuid, out UUID avUUID) == false)
|
||||
{
|
||||
return "?";
|
||||
}
|
||||
foreach (Avatar A in GetClient().Network.CurrentSim.ObjectsAvatars.Copy().Values)
|
||||
{
|
||||
if(A.ID != avUUID)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
int localid = GetClient().Parcels.GetParcelLocalID(GetClient().Network.CurrentSim, A.Position);
|
||||
if (GetClient().Network.CurrentSim.Parcels.ContainsKey(localid) == false)
|
||||
{
|
||||
return "?";
|
||||
}
|
||||
return GetClient().Network.CurrentSim.Parcels[localid].Name;
|
||||
}
|
||||
return "?";
|
||||
}
|
||||
|
||||
protected string GetBotParcel()
|
||||
{
|
||||
int localid = GetClient().Parcels.GetParcelLocalID(GetClient().Network.CurrentSim, GetClient().Self.SimPosition);
|
||||
if (GetClient().Network.CurrentSim.Parcels.ContainsKey(localid) == false)
|
||||
{
|
||||
return "-";
|
||||
}
|
||||
return GetClient().Network.CurrentSim.Parcels[localid].Name;
|
||||
}
|
||||
|
||||
string avatarhash = "";
|
||||
bool GuestListLoaded = false;
|
||||
protected List<UUID> AvatarsOnSim = new List<UUID>();
|
||||
protected void TrackAvatarsOnParcel()
|
||||
{
|
||||
long dif = SecondbotHelpers.UnixTimeNow() - lastAvUpdate;
|
||||
if (dif < 30)
|
||||
{
|
||||
// only check for changes every 30 secs
|
||||
return;
|
||||
}
|
||||
lastAvUpdate = SecondbotHelpers.UnixTimeNow();
|
||||
string hashstring = "";
|
||||
List<UUID> avs = new List<UUID>();
|
||||
foreach (Avatar A in GetClient().Network.CurrentSim.ObjectsAvatars.Copy().Values)
|
||||
{
|
||||
avs.Add(A.ID);
|
||||
master.DataStoreService.AddAvatar(A.ID, A.Name);
|
||||
hashstring = hashstring + A.ID.ToString();
|
||||
}
|
||||
string hash = SecondbotHelpers.GetSHA1(hashstring);
|
||||
if (hash == avatarhash)
|
||||
{
|
||||
// no changes
|
||||
return;
|
||||
}
|
||||
avatarhash = hash;
|
||||
|
||||
if (GuestListLoaded == true)
|
||||
{
|
||||
List<UUID> joined = new List<UUID>();
|
||||
List<UUID> tracked = new List<UUID>();
|
||||
foreach (UUID a in AvatarsOnSim)
|
||||
{
|
||||
tracked.Add(a);
|
||||
}
|
||||
foreach (UUID a in avs)
|
||||
{
|
||||
if (tracked.Contains(a) == true)
|
||||
{
|
||||
tracked.Remove(a);
|
||||
continue;
|
||||
}
|
||||
joined.Add(a);
|
||||
}
|
||||
if ((tracked.Count > 0) || (joined.Count > 0))
|
||||
{
|
||||
List<UUID> seen = new List<UUID>();
|
||||
if (tracked.Count > 0)
|
||||
{
|
||||
|
||||
foreach (UUID a in tracked)
|
||||
{
|
||||
if(seen.Contains(a) == true)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
seen.Add(a);
|
||||
TriggerEvent("GuestLeaves", new Dictionary<string, string>() { { "avataruuid", a.ToString() } });
|
||||
}
|
||||
}
|
||||
if (joined.Count > 0)
|
||||
{
|
||||
foreach (UUID a in joined)
|
||||
{
|
||||
if (seen.Contains(a) == true)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
seen.Add(a);
|
||||
TriggerEvent("GuestJoins", new Dictionary<string, string>() { { "avataruuid", a.ToString() } });
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
AvatarsOnSim = avs;
|
||||
GuestListLoaded = true;
|
||||
}
|
||||
|
||||
long lastClockEvent = 0;
|
||||
protected void ClockEvent()
|
||||
{
|
||||
long dif = SecondbotHelpers.UnixTimeNow() - lastClockEvent;
|
||||
if (dif < 60)
|
||||
{
|
||||
return;
|
||||
}
|
||||
lastClockEvent = SecondbotHelpers.UnixTimeNow();
|
||||
TriggerEvent("Clock", new Dictionary<string, string>());
|
||||
}
|
||||
|
||||
long lastAvUpdate = 0;
|
||||
protected void TimedEvents()
|
||||
{
|
||||
TrackAvatarsOnParcel();
|
||||
CleanLockouts();
|
||||
ClockEvent();
|
||||
GroupMembershipUpkeep();
|
||||
}
|
||||
|
||||
public override string Status()
|
||||
{
|
||||
if (myConfig == null)
|
||||
{
|
||||
return "No Config";
|
||||
}
|
||||
else if (myConfig.GetEnabled() == false)
|
||||
{
|
||||
return "- Not requested -";
|
||||
}
|
||||
if (botConnected == true)
|
||||
{
|
||||
TimedEvents();
|
||||
}
|
||||
if (myConfig.GetHideStatusOutput() == true)
|
||||
{
|
||||
return "hidden";
|
||||
}
|
||||
else if (botConnected == false)
|
||||
{
|
||||
return "Waiting for bot";
|
||||
}
|
||||
return "Active";
|
||||
}
|
||||
|
||||
protected void BotLoggedIn(object o, SimConnectedEventArgs e)
|
||||
{
|
||||
GetClient().Network.SimConnected -= BotLoggedIn;
|
||||
botConnected = true;
|
||||
LogFormater.Info("OnEvent Service [Active]");
|
||||
AttachEvents();
|
||||
}
|
||||
|
||||
public override void Start()
|
||||
{
|
||||
if (myConfig.GetEnabled() == false)
|
||||
{
|
||||
LogFormater.Info("OnEvent Service [- Not requested -]");
|
||||
return;
|
||||
}
|
||||
Stop();
|
||||
running = true;
|
||||
master.BotClientNoticeEvent += BotClientRestart;
|
||||
LogFormater.Info("OnEvent Service [Starting]");
|
||||
}
|
||||
|
||||
public override void Stop()
|
||||
{
|
||||
if (running == true)
|
||||
{
|
||||
LogFormater.Info("OnEvent Service [Stopping]");
|
||||
}
|
||||
running = false;
|
||||
if (myConfig.GetEnabled() == false)
|
||||
{
|
||||
return;
|
||||
}
|
||||
master.BotClientNoticeEvent -= BotClientRestart;
|
||||
RemoveEvents();
|
||||
}
|
||||
}
|
||||
|
||||
public class CustomOnEvent
|
||||
{
|
||||
public string Source = "";
|
||||
public List<string> MonitorFlags = new List<string>();
|
||||
public List<string> WhereChecksLeft = new List<string>();
|
||||
public List<string> WhereChecksCenter = new List<string>();
|
||||
public List<string> WhereChecksRight = new List<string>();
|
||||
public List<string> Actions = new List<string>();
|
||||
}
|
||||
}
|
||||
Loading…
Reference in a new issue