diff --git a/Dockerfile b/Dockerfile index 55c7f28..11e3362 100644 --- a/Dockerfile +++ b/Dockerfile @@ -86,6 +86,10 @@ ENV basic_Username='' \ interaction_AcceptFriendRequests='false' \ interaction_EnableJsonOutputEvents='false' \ interaction_JsonOutputEventsTarget='none' \ + interaction_FriendRequestLevel='Owner' \ + interaction_InventoryTransferLevel='Owner' \ + interaction_GroupInviteLevel=Owner'' \ + interaction_TeleportRequestLevel='Owner' \ commands_HideStatusOutput='false' \ datastore_HideStatusOutput='false' \ discord_HideStatusOutput='false' \ diff --git a/SecondBotEvents/Commands/Avatars.cs b/SecondBotEvents/Commands/Avatars.cs index 1882ee2..db9622a 100644 --- a/SecondBotEvents/Commands/Avatars.cs +++ b/SecondBotEvents/Commands/Avatars.cs @@ -15,6 +15,62 @@ namespace SecondBotEvents.Commands } + [About("Adds avatars to the one time accept list for interactions")] + [ReturnHints("ok")] + [ReturnHintsFailure("Invaild avatar uuid")] + [ReturnHintsFailure("Unknown store type")] + [ReturnHintsFailure("Unable to process request store")] + [ArgHints("store", "What type of request to accept: \"FriendRequest\", \"InventoryOffer\", \"GroupInvite\", \"Teleport\"")] + [ArgHints("avatar", "a UUID or Firstname Lastname")] + [ArgHints("remove", "set to \"true\" or \"True\" to remove that avatar from the accept next for that store type")] + public Object AcceptNext(string store, string avatar, string remove) + { + ProcessAvatar(avatar); + if (avataruuid == UUID.Zero) + { + return Failure("Invaild avatar uuid", new[] { store, avatar, remove }); + } + bool toberemoved = false; + if((remove == "true") || (remove == "True")) + { + toberemoved = true; + } + if(master.DataStoreService.KnownStoreType(store) == false) + { + return Failure("Unknown store type", new[] { store, avatar, remove }); + } + if (master.DataStoreService.AddToAcceptNext(store, avataruuid, toberemoved) == false) + { + return Failure("Unable to process request store", new[] { store, avatar, remove }); + } + return BasicReply("ok", new[] { store, avatar, remove }); + } + [About("Checks if the avatar is on the accept next list (without using the token) for the given store")] + [ReturnHints("true")] + [ReturnHints("false")] + [ReturnHintsFailure("Invaild avatar uuid")] + [ReturnHintsFailure("Unknown store type")] + [ArgHints("store", "What type of request to check: \"FriendRequest\", \"InventoryOffer\", \"GroupInvite\", \"Teleport\"")] + [ArgHints("avatar", "a UUID or Firstname Lastname")] + public Object IsOnAcceptNext(string store, string avatar) + { + ProcessAvatar(avatar); + if (avataruuid == UUID.Zero) + { + return Failure("Invaild avatar uuid", new[] { store, avatar }); + } + if (master.DataStoreService.KnownStoreType(store) == false) + { + return Failure("Unknown store type", new[] { store, avatar }); + } + if(master.DataStoreService.IsInAcceptNext(store,avataruuid) == false) + { + return BasicReply("false", new[] { store, avatar }); + } + return BasicReply("true", new[] { store, avatar }); + } + + [About("an improved version of near me with extra details
NearMeDetails is a object formated as follows
")] [ReturnHints("array NearMeDetails")] [ReturnHintsFailure("Error not in a sim")] diff --git a/SecondBotEvents/Config/InteractionConfig.cs b/SecondBotEvents/Config/InteractionConfig.cs index 9847317..729cb69 100644 --- a/SecondBotEvents/Config/InteractionConfig.cs +++ b/SecondBotEvents/Config/InteractionConfig.cs @@ -16,10 +16,31 @@ namespace SecondBotEvents.Config settings.Add("EnableJsonOutputEvents"); settings.Add("JsonOutputEventsTarget"); settings.Add("AcceptFriendRequests"); + settings.Add("FriendRequestLevel"); + settings.Add("InventoryTransferLevel"); + settings.Add("GroupInviteLevel"); + settings.Add("TeleportRequestLevel"); settings.Add("Enabled"); settings.Add("HideStatusOutput"); } + public string GetFriendRequestLevel() + { + return ReadSettingAsString("FriendRequestLevel", "Owner"); + } + public string GetInventoryTransferLevel() + { + return ReadSettingAsString("InventoryTransferLevel", "Owner"); + } + public string GetGroupInviteLevel() + { + return ReadSettingAsString("GroupInviteLevel", "Owner"); + } + public string GetTeleportRequestLevel() + { + return ReadSettingAsString("TeleportRequestLevel", "Owner"); + } + public bool GetEnabled() { return ReadSettingAsBool("Enabled", true); diff --git a/SecondBotEvents/Services/DataStoreService.cs b/SecondBotEvents/Services/DataStoreService.cs index 82ae539..5a498ba 100644 --- a/SecondBotEvents/Services/DataStoreService.cs +++ b/SecondBotEvents/Services/DataStoreService.cs @@ -47,6 +47,60 @@ namespace SecondBotEvents.Services protected long lastCleanupKeyValueStore = 0; protected long lastCleanupAvatarStore = 0; + protected List acceptedStores = new List() { "FriendRequest", "InventoryOffer", "GroupInvite", "Teleport" }; + protected Dictionary> AcceptNextStore = new Dictionary>(); + public bool KnownStoreType(string storeType) + { + return acceptedStores.Contains(storeType); + } + public bool GetNextAccept(string store,UUID avatar) + { + if(AcceptNextStore.ContainsKey(store) == false) + { + return false; + } + else if (AcceptNextStore[store].Contains(avatar) == false) + { + return false; + } + AcceptNextStore[store].Remove(avatar); + return true; + } + public bool IsInAcceptNext(string store,UUID avatar) + { + if (AcceptNextStore.ContainsKey(store) == false) + { + return false; + } + return AcceptNextStore[store].Contains(avatar); + } + public bool AddToAcceptNext(string store,UUID avatar, bool remove) + { + if(acceptedStores.Contains(store) == false) + { + return false; + } + if(AcceptNextStore.ContainsKey(store) == false) + { + AcceptNextStore.Add(store, new List()); + } + if(AcceptNextStore[store].Contains(avatar) == true) + { + if(remove == true) + { + AcceptNextStore[store].Remove(avatar); + return true; + } + return true; // already in the store + } + if(remove == true) + { + return true; // already removed from the store + } + AcceptNextStore[store].Add(avatar); + return true; + } + public bool GetIsGroup(UUID MaybeGroupUUID) { return groupsKey2Name.ContainsKey(MaybeGroupUUID); diff --git a/SecondBotEvents/Services/InteractionService.cs b/SecondBotEvents/Services/InteractionService.cs index 6ec5110..bdeb634 100644 --- a/SecondBotEvents/Services/InteractionService.cs +++ b/SecondBotEvents/Services/InteractionService.cs @@ -44,31 +44,56 @@ namespace SecondBotEvents.Services return "Active"; } - protected bool ProcessRequest(bool enabledByConfig, string avatarName, string sourceName) + protected bool ProcessRequest(bool enabledByConfig, string ConfigAcceptLevel, string avatarName, string sourceName, UUID avataruuid) { if(myConfig.GetEnabled() == false) { JsonOuput(false, sourceName, avatarName, "Interactions hooks disabled"); return false; } + if(enabledByConfig == false) + { + JsonOuput(false, sourceName, avatarName, "disabled by config"); + return false; + } if (master.CommandsService.myConfig.GetEnableMasterControls() == false) { // master avatars list is not enabled. unable to continue JsonOuput(false, sourceName, avatarName, "masters AV list is disabled: Please set EnableMasterControls in Commands service to true"); return false; } - if(enabledByConfig == true) - { - return true; - } + bool accepted = false; + string whyAccepted = "rejected request"; if (master.CommandsService.myConfig.GetMastersCSV().Contains(avatarName) == true) { + whyAccepted = "on owners list"; return true; } - JsonOuput(false, sourceName, avatarName, "disabled by config"); - return false; + else if (ConfigAcceptLevel == "Anyone") + { + whyAccepted = "Accepting from anyone"; + accepted = true; + } + else if((ConfigAcceptLevel == "Friends") && (sourceName != "FriendRequest")) + { + whyAccepted = "on friends list"; + accepted = GetClient().Friends.FriendList.ContainsKey(avataruuid); + } + if (accepted == false) + { + // check the one time accept list + accepted = master.DataStoreService.GetNextAccept(sourceName, avataruuid); + if(accepted == true) + { + whyAccepted = "was on NextAccept list"; + } + } + JsonOuput(accepted, sourceName, avatarName, whyAccepted); + return accepted; } + + protected void BotClientRestart(object o, BotClientNotice e) { botConnected = false; @@ -126,7 +151,7 @@ namespace SecondBotEvents.Services mode = "Teleport Av to Bot"; markTeleport = false; } - if (ProcessRequest(myConfig.GetAcceptTeleports(), e.IM.FromAgentName, mode) == false) + if (ProcessRequest(myConfig.GetAcceptTeleports(),myConfig.GetTeleportRequestLevel(), e.IM.FromAgentName, "Teleport", e.IM.FromAgentID) == false) { // rejected requests if (e.IM.Dialog != InstantMessageDialog.RequestLure) @@ -152,7 +177,7 @@ namespace SecondBotEvents.Services protected void BotGroupInviteOffer(object o, GroupInvitationEventArgs e) { - if (ProcessRequest(myConfig.GetAcceptGroupInvites(), e.FromName, "GroupInvite") == false) + if (ProcessRequest(myConfig.GetAcceptGroupInvites(),myConfig.GetGroupInviteLevel(), e.FromName, "GroupInvite", e.AgentID) == false) { return; } @@ -181,8 +206,9 @@ namespace SecondBotEvents.Services protected void BotInventoryOffer(object o, InventoryObjectOfferedEventArgs e) { - if(ProcessRequest(myConfig.GetAcceptInventory(),e.Offer.FromAgentName, "InventoryOffer") == false) + if(ProcessRequest(myConfig.GetAcceptInventory(),myConfig.GetInventoryTransferLevel(),e.Offer.FromAgentName, "InventoryOffer", e.Offer.FromAgentID) == false) { + e.Accept = false; return; } e.Accept = true; @@ -210,7 +236,7 @@ namespace SecondBotEvents.Services protected void BotFriendRequested(object o, FriendshipOfferedEventArgs e) { - if (ProcessRequest(myConfig.GetAcceptGroupInvites(), e.AgentName, "FriendRequest") == false) + if (ProcessRequest(myConfig.GetAcceptFriendRequests(),myConfig.GetFriendRequestLevel(), e.AgentName, "FriendRequest", e.AgentID) == false) { return; }