Push feature: visitor logging, and greeting

This commit is contained in:
Zontreck 2020-08-20 16:58:24 -07:00
parent 7392ef6878
commit 9364c2e52e
6 changed files with 246 additions and 27 deletions

View file

@ -6,7 +6,7 @@ using System.Reflection;
[assembly: AssemblyCompany("ZNI")]
[assembly: AssemblyAlgorithmId(System.Configuration.Assemblies.AssemblyHashAlgorithm.MD5)]
[assembly: AssemblyCopyright("(C) 2020 Tara Piccari")]
[assembly: AssemblyFileVersion("5.0.4.1001")]
[assembly: AssemblyFileVersion("5.0.5.1002")]
[assembly: AssemblyDescription("Second Life Bot - BotCore5")]
@ -15,7 +15,7 @@ namespace Bot.Assemble
public class ASMInfo
{
public static string BotName = "ZBotCore";
public static string BotVer = "5.0.4.1001";
public static string BotVer = "5.0.5.1002";
public static string GitPassword
{
get

View file

@ -71,6 +71,7 @@ namespace Bot
public bool GreeterEnabled { get; set; } = false;
public string GreeterMessage { get; set; } = "";
public bool VisitorLogEnabled { get; set; } = false;
public Dictionary<UUID, int> BotAdmins { get; set; } = new Dictionary<UUID, int>();

View file

@ -294,9 +294,53 @@ namespace Bot
}
CommandRegistry.Instance.LocateCommands();
if (!File.Exists("Inventory.blob"))
{
BotSession.Instance.grid.Inventory.RequestFolderContents(BotSession.Instance.grid.Inventory.Store.RootFolder.OwnerID, BotSession.Instance.grid.Inventory.Store.Owner, true, true, InventorySortOrder.SystemFoldersToTop);
BotSession.Instance.grid.Inventory.RequestFolderContents(BotSession.Instance.grid.Inventory.FindFolderForType(AssetType.Animation), BotSession.Instance.grid.Inventory.Store.Owner, true, true, InventorySortOrder.SystemFoldersToTop);
BotSession.Instance.grid.Inventory.RequestFolderContents(BotSession.Instance.grid.Inventory.FindFolderForType(AssetType.Bodypart), BotSession.Instance.grid.Inventory.Store.Owner, true, true, InventorySortOrder.SystemFoldersToTop);
BotSession.Instance.grid.Inventory.RequestFolderContents(BotSession.Instance.grid.Inventory.FindFolderForType(AssetType.CallingCard), BotSession.Instance.grid.Inventory.Store.Owner, true, true, InventorySortOrder.SystemFoldersToTop);
BotSession.Instance.grid.Inventory.RequestFolderContents(BotSession.Instance.grid.Inventory.FindFolderForType(AssetType.Clothing), BotSession.Instance.grid.Inventory.Store.Owner, true, true, InventorySortOrder.SystemFoldersToTop);
BotSession.Instance.grid.Inventory.RequestFolderContents(BotSession.Instance.grid.Inventory.FindFolderForType(AssetType.Folder), BotSession.Instance.grid.Inventory.Store.Owner, true, true, InventorySortOrder.SystemFoldersToTop);
BotSession.Instance.grid.Inventory.RequestFolderContents(BotSession.Instance.grid.Inventory.FindFolderForType(AssetType.Gesture), BotSession.Instance.grid.Inventory.Store.Owner, true, true, InventorySortOrder.SystemFoldersToTop);
BotSession.Instance.grid.Inventory.RequestFolderContents(BotSession.Instance.grid.Inventory.FindFolderForType(AssetType.ImageJPEG), BotSession.Instance.grid.Inventory.Store.Owner, true, true, InventorySortOrder.SystemFoldersToTop);
BotSession.Instance.grid.Inventory.RequestFolderContents(BotSession.Instance.grid.Inventory.FindFolderForType(AssetType.ImageTGA), BotSession.Instance.grid.Inventory.Store.Owner, true, true, InventorySortOrder.SystemFoldersToTop);
BotSession.Instance.grid.Inventory.RequestFolderContents(BotSession.Instance.grid.Inventory.FindFolderForType(AssetType.Landmark), BotSession.Instance.grid.Inventory.Store.Owner, true, true, InventorySortOrder.SystemFoldersToTop);
BotSession.Instance.grid.Inventory.RequestFolderContents(BotSession.Instance.grid.Inventory.FindFolderForType(AssetType.Link), BotSession.Instance.grid.Inventory.Store.Owner, true, true, InventorySortOrder.SystemFoldersToTop);
BotSession.Instance.grid.Inventory.RequestFolderContents(BotSession.Instance.grid.Inventory.FindFolderForType(AssetType.LinkFolder), BotSession.Instance.grid.Inventory.Store.Owner, true, true, InventorySortOrder.SystemFoldersToTop);
BotSession.Instance.grid.Inventory.RequestFolderContents(BotSession.Instance.grid.Inventory.FindFolderForType(AssetType.LSLBytecode), BotSession.Instance.grid.Inventory.Store.Owner, true, true, InventorySortOrder.SystemFoldersToTop);
BotSession.Instance.grid.Inventory.RequestFolderContents(BotSession.Instance.grid.Inventory.FindFolderForType(AssetType.LSLText), BotSession.Instance.grid.Inventory.Store.Owner, true, true, InventorySortOrder.SystemFoldersToTop);
BotSession.Instance.grid.Inventory.RequestFolderContents(BotSession.Instance.grid.Inventory.FindFolderForType(AssetType.Mesh), BotSession.Instance.grid.Inventory.Store.Owner, true, true, InventorySortOrder.SystemFoldersToTop);
BotSession.Instance.grid.Inventory.RequestFolderContents(BotSession.Instance.grid.Inventory.FindFolderForType(AssetType.Notecard), BotSession.Instance.grid.Inventory.Store.Owner, true, true, InventorySortOrder.SystemFoldersToTop);
BotSession.Instance.grid.Inventory.RequestFolderContents(BotSession.Instance.grid.Inventory.FindFolderForType(AssetType.Object), BotSession.Instance.grid.Inventory.Store.Owner, true, true, InventorySortOrder.SystemFoldersToTop);
BotSession.Instance.grid.Inventory.RequestFolderContents(BotSession.Instance.grid.Inventory.FindFolderForType(AssetType.Person), BotSession.Instance.grid.Inventory.Store.Owner, true, true, InventorySortOrder.SystemFoldersToTop);
BotSession.Instance.grid.Inventory.RequestFolderContents(BotSession.Instance.grid.Inventory.FindFolderForType(AssetType.Simstate), BotSession.Instance.grid.Inventory.Store.Owner, true, true, InventorySortOrder.SystemFoldersToTop);
BotSession.Instance.grid.Inventory.RequestFolderContents(BotSession.Instance.grid.Inventory.FindFolderForType(AssetType.Sound), BotSession.Instance.grid.Inventory.Store.Owner, true, true, InventorySortOrder.SystemFoldersToTop);
BotSession.Instance.grid.Inventory.RequestFolderContents(BotSession.Instance.grid.Inventory.FindFolderForType(AssetType.SoundWAV), BotSession.Instance.grid.Inventory.Store.Owner, true, true, InventorySortOrder.SystemFoldersToTop);
BotSession.Instance.grid.Inventory.RequestFolderContents(BotSession.Instance.grid.Inventory.FindFolderForType(AssetType.Texture), BotSession.Instance.grid.Inventory.Store.Owner, true, true, InventorySortOrder.SystemFoldersToTop);
BotSession.Instance.grid.Inventory.RequestFolderContents(BotSession.Instance.grid.Inventory.FindFolderForType(AssetType.TextureTGA), BotSession.Instance.grid.Inventory.Store.Owner, true, true, InventorySortOrder.SystemFoldersToTop);
BotSession.Instance.grid.Inventory.RequestFolderContents(BotSession.Instance.grid.Inventory.FindFolderForType(AssetType.Unknown), BotSession.Instance.grid.Inventory.Store.Owner, true, true, InventorySortOrder.SystemFoldersToTop);
BotSession.Instance.grid.Inventory.RequestFolderContents(BotSession.Instance.grid.Inventory.FindFolderForType(AssetType.Widget), BotSession.Instance.grid.Inventory.Store.Owner, true, true, InventorySortOrder.SystemFoldersToTop);
}
else
BotSession.Instance.grid.Inventory.Store.RestoreFromDisk("Inventory.blob");
int iLastInvLength = 0;
while (g_iIsRunning)
{
if(iLastInvLength != BotSession.Instance.grid.Inventory.Store.Items.Count)
{
BotSession.Instance.grid.Inventory.Store.SaveToDisk("Inventory.blob");
iLastInvLength = BotSession.Instance.grid.Inventory.Store.Items.Count;
}
string consoleCmd = "N/A";
try
{

View file

@ -29,6 +29,27 @@ namespace Bot.Visitors
}
[CommandGroup("visitor_log_on", 5, "visitor_log_on - Enables the visitor log", Destinations.DEST_AGENT | Destinations.DEST_GROUP | Destinations.DEST_LOCAL)]
public void enable_visitor_log
(UUID client, int level, string[] additionalArgs,
Destinations source,
UUID agentKey, string agentName)
{
MainConfiguration.Instance.VisitorLogEnabled = true;
MainConfiguration.Instance.Save();
MHE(source, client, "Visitor Logging enabled");
}
[CommandGroup("visitor_log_off", 5, "visitor_log_off - Disables the visitor log", Destinations.DEST_AGENT | Destinations.DEST_GROUP | Destinations.DEST_LOCAL)]
public void disable_visitor_log
(UUID client, int level, string[] additionalArgs,
Destinations source,
UUID agentKey, string agentName)
{
MainConfiguration.Instance.VisitorLogEnabled = false;
MainConfiguration.Instance.Save();
MHE(source, client, "Visitor Logging disabled");
}
[CommandGroup("greet_off", 5, "greet_off - Turns off the greeter", Destinations.DEST_AGENT | Destinations.DEST_GROUP | Destinations.DEST_LOCAL)]
public void disable_greeter
@ -47,6 +68,80 @@ namespace Bot.Visitors
[CommandGroup("dump_visitors", 5, "dump_visitors", Destinations.DEST_AGENT | Destinations.DEST_GROUP | Destinations.DEST_LOCAL)]
public void dump_visitors
(UUID client, int level, string[] additionalArgs,
Destinations source,
UUID agentKey, string agentName)
{
// dump the visitors
foreach(Visitor v in VisitorLog.Instance.Visitors)
{
List<TimeSpan> Avgs = new List<TimeSpan>();
foreach (KeyValuePair<DateTime,TimeSpan> kvvp in v.MinutesSeenPerDay)
{
Avgs.Add(kvvp.Value);
}
double avg = Avgs.Average(ts => ts.TotalHours);
MHE(Destinations.DEST_AGENT, agentKey, $"GREETED: {v.Greeted}\nSLURL: secondlife:///app/agent/{v.ID}/about\nLastSeen: {v.LastSeen}\nIs member of my active group: {v.IsMemberOfMyActiveGroup}\nAverage Time on sim: {avg} hours over a period of {v.MinutesSeenPerDay.Count} days, not necessarily consecutive.");
}
}
[CommandGroup("dump_visitors_local", 5, "dump_visitors_local", Destinations.DEST_AGENT | Destinations.DEST_GROUP | Destinations.DEST_LOCAL)]
public void dump_visitors_local
(UUID client, int level, string[] additionalArgs,
Destinations source,
UUID agentKey, string agentName)
{
// dump the visitors
foreach (Visitor v in VisitorLog.Instance.Visitors)
{
List<TimeSpan> Avgs = new List<TimeSpan>();
foreach (KeyValuePair<DateTime, TimeSpan> kvvp in v.MinutesSeenPerDay)
{
Avgs.Add(kvvp.Value);
}
double avg = Avgs.Average(ts => ts.TotalHours);
MHE(Destinations.DEST_LOCAL, agentKey, $"GREETED: {v.Greeted}\nSLURL: secondlife:///app/agent/{v.ID}/about\nLastSeen: {v.LastSeen}\nIs member of my active group: {v.IsMemberOfMyActiveGroup}\nAverage Time on sim: {avg} hours over a period of {v.MinutesSeenPerDay.Count} days, not necessarily consecutive.");
}
}
[CommandGroup("rm_non_group_visitors", 5, "rm_non_group_visitors", Destinations.DEST_AGENT | Destinations.DEST_GROUP | Destinations.DEST_LOCAL)]
public void rm_non_group_vis
(UUID client, int level, string[] additionalArgs,
Destinations source,
UUID agentKey, string agentName)
{
List<Visitor> toRemove = new List<Visitor>();
// dump the visitors
foreach (Visitor v in VisitorLog.Instance.Visitors)
{
if (v.IsMemberOfMyActiveGroup) continue;
else
{
toRemove.Add(v);
}
}
foreach(Visitor v in toRemove)
{
VisitorLog.Instance.Visitors.Remove(v);
VisitorLog.SaveMemory();
}
MHE(source, client, "Operations complete");
}
private ManualResetEvent WaitForInventory = new ManualResetEvent(false);
private UUID FoundInventoryItem = UUID.Zero;
@ -68,21 +163,29 @@ namespace Bot.Visitors
BotSession.Instance.grid.Inventory.FindObjectByPathReply += Inventory_FindObjectByPathReply;
WaitForInventory.Reset();
BotSession.Instance.grid.Inventory.RequestFindObjectByPath(BotSession.Instance.grid.Inventory.Store.RootFolder.UUID, BotSession.Instance.grid.Self.AgentID, sItem);
FoundInventoryItem = BotSession.Instance.grid.Inventory.FindObjectByPath(BotSession.Instance.grid.Inventory.Store.RootFolder.UUID, BotSession.Instance.grid.Self.AgentID, sItem, 10000);
if (WaitForInventory.WaitOne(30001))
if(FoundInventoryItem == UUID.Zero)
{
MHE(source, client, "Nothing found");
return;
}
if (WaitForInventory.WaitOne(5001))
{
// check if the item has been cached
if (BotSession.Instance.grid.Inventory.Store.Contains(FoundInventoryItem) && FoundInventoryItem!=UUID.Zero)
{
MHE(source, client, "Inventory item found. Sending you a copy to ensure it is correct!");
InventoryNode item = BotSession.Instance.grid.Inventory.Store.Items[FoundInventoryItem];
BotSession.Instance.grid.Inventory.GiveItem(FoundInventoryItem, item.Data.Name, AssetType.Unknown, client, true);
return;
}
MHE(source, client, "Timed out on searching inventory for that item");
}
// check if the item has been cached
if (BotSession.Instance.grid.Inventory.Store.Contains(FoundInventoryItem) && FoundInventoryItem != UUID.Zero)
{
MHE(source, client, "Inventory item found. Sending you a copy to ensure it is correct!");
InventoryNode item = BotSession.Instance.grid.Inventory.Store.Items[FoundInventoryItem];
BotSession.Instance.grid.Inventory.GiveItem(FoundInventoryItem, item.Data.Name, AssetType.Unknown, client, true);
return;
}
}
private void Inventory_FindObjectByPathReply(object sender, FindObjectByPathReplyEventArgs e)
@ -95,25 +198,94 @@ namespace Bot.Visitors
TimeSpan tickCounter = new TimeSpan();
public void run()
{
}
public void getTick()
{
if (MainConfiguration.Instance.VisitorLogEnabled == false) return; // We can't even use the greeter without the log
// Every 2 seconds, tick
// cant implement yet- visitor log needed
if (tickCounter == null)
{
tickCounter = new TimeSpan();
tickCounter.Add(TimeSpan.FromSeconds(2));
tickCounter = tickCounter.Add(TimeSpan.FromSeconds(2));
}
if(tickCounter > TimeSpan.FromMinutes(1))
else
{
// update everyones' seen minute count who is on sim
tickCounter=tickCounter.Add(TimeSpan.FromSeconds(2));
}
if (tickCounter > TimeSpan.FromMinutes(1))
{
tickCounter = new TimeSpan();
// update everyones' seen minute count who is on sim
Dictionary<UUID, Vector3> dict = BotSession.Instance.grid.Network.CurrentSim.AvatarPositions.Copy();
foreach (KeyValuePair<UUID, Vector3> kvp in dict)
{
if (VisitorLog.Instance.Visitors.Where(x => x.ID == kvp.Key).Count() > 0)
{
Visitor V = VisitorLog.Instance.Visitors.Where(x => x.ID == kvp.Key).First();
int index = VisitorLog.Instance.Visitors.IndexOf(V);
V.LastSeen = DateTime.Now;
// get today's entry if it exists
if (V.MinutesSeenPerDay.ContainsKey(DateTime.Today))
{
V.MinutesSeenPerDay[DateTime.Today] = V.MinutesSeenPerDay[DateTime.Today].Add(TimeSpan.FromMinutes(1));
}
else
{
V.MinutesSeenPerDay.Add(DateTime.Today, TimeSpan.FromMinutes(1));
}
if (!V.IsMemberOfMyActiveGroup)
{
UUID botgroup = BotSession.Instance.grid.Self.ActiveGroup;
if (BotSession.Instance.grid.Network.CurrentSim.ObjectsAvatars.Copy().Where(x => x.Value.ID == kvp.Key).Count() > 0)
{
// the avatar's instance was found
Avatar avi = BotSession.Instance.grid.Network.CurrentSim.ObjectsAvatars.Copy().Where(x => x.Value.ID == kvp.Key).First().Value;
if(botgroup == avi.GroupID || avi.Groups.Contains(botgroup))
{
V.IsMemberOfMyActiveGroup = true;
}
}
}
VisitorLog.Instance.Visitors[index] = V;
}
else
{
// does not yet contain this visitor
Visitor V = new Visitor(kvp.Key);
VisitorLog.Instance.Visitors.Add(V);
}
if (MainConfiguration.Instance.GreeterEnabled)
{
Visitor V = VisitorLog.Instance.Visitors.Where(x => x.ID == kvp.Key).First();
int index = VisitorLog.Instance.Visitors.IndexOf(V);
if (!V.Greeted)
{
MHE(Destinations.DEST_AGENT, V.ID, MainConfiguration.Instance.GreeterMessage);
V.Greeted = true;
VisitorLog.Instance.Visitors[index] = V;
// This is also where the give on greet action will go
}
}
}
VisitorLog.SaveMemory();
}
}
public void getTick()
{
}
public void passArguments(string data)

View file

@ -54,19 +54,21 @@ namespace Bot.Visitors
public class Visitor
{
public UUID ID { get; set} = UUID.Zero;
public string username { get; set; } = "first.last";
public UUID ID { get; set; } = UUID.Zero;
public bool Greeted { get; set; } = false;
public DateTime LastSeen { get; set; } = DateTime.Now;
public Dictionary<DateTime, TimeSpan> MinutesSeenPerDay { get; set; } = new Dictionary<DateTime, TimeSpan>();
public bool IsMemberOfMyActiveGroup { get; set; } = false;
internal Visitor(UUID kID)
{
ID = kID;
username = "";
Greeted = false;
LastSeen = DateTime.Now;
MinutesSeenPerDay = new Dictionary<DateTime, TimeSpan>();
MinutesSeenPerDay.Add(DateTime.Today, TimeSpan.FromMinutes(0));
}
public Visitor() { }
}
}

View file

@ -88,7 +88,7 @@ namespace Bot.WebHookServer
}catch(Exception e)
{
MessageFactory.Post(Destinations.DEST_LOCAL, "Error: Program could not escalate to Admin Privileges. WebHook engine not running\n\n" + e.Message + "\n" + e.StackTrace, UUID.Zero);
//MessageFactory.Post(Destinations.DEST_LOCAL, "Error: Program could not escalate to Admin Privileges. WebHook engine not running\n\n" + e.Message + "\n" + e.StackTrace, UUID.Zero);
}
}