Change stuffs around

This commit is contained in:
Zontreck 2020-08-20 14:58:22 -07:00
parent 375f623715
commit 7392ef6878
7 changed files with 776 additions and 2 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.4.4000")]
[assembly: AssemblyFileVersion("5.0.4.1001")]
[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.4.4000";
public static string BotVer = "5.0.4.1001";
public static string GitPassword
{
get

303
Charts/ChartCommands.cs Normal file
View file

@ -0,0 +1,303 @@
using System;
using System.Collections.Generic;
using System.Text;
using Bot.CommandSystem;
using Bot;
using OpenMetaverse;
using System.Linq;
namespace Bot.Charts
{
class ChartCommands : BaseCommands
{
[CommandGroup("mkchart", 5, "mkchart [name] - Makes a new empty chart", Bot.Destinations.DEST_AGENT | Bot.Destinations.DEST_LOCAL | Bot.Destinations.DEST_GROUP)]
public void makeNewChart(UUID client, int level, string[] additionalArgs,
Destinations source,
UUID agentKey, string agentName)
{
if (ChartMemory.HasChart(additionalArgs[0]))
{
MHE(source, client, "A chart by that name already exists");
return;
}
ChartMemory.Instance.Charts.Add(new Chart(additionalArgs[0]));
ChartMemory.SaveToFile();
MHE(source, client, "New chart created successfully");
}
[CommandGroup("renamechart", 5, "renamechart [name] [newName] - Renames a chart", Bot.Destinations.DEST_AGENT | Bot.Destinations.DEST_LOCAL | Bot.Destinations.DEST_GROUP)]
public void renameChart(UUID client, int level, string[] additionalArgs,
Destinations source,
UUID agentKey, string agentName)
{
if (ChartMemory.HasChart(additionalArgs[0]))
{
Chart v = ChartMemory.GetNamedChart(additionalArgs[0]);
int index = ChartMemory.Instance.Charts.IndexOf(v);
v.ChartName = additionalArgs[1];
ChartMemory.Instance.Charts[index] = v;
ChartMemory.SaveToFile();
MHE(source, client, "Chart renamed");
return;
}
}
[CommandGroup("delchart", 5, "delchart [name] - Deletes named chart", Bot.Destinations.DEST_AGENT | Bot.Destinations.DEST_LOCAL | Bot.Destinations.DEST_GROUP)]
public void deleteChart(UUID client, int level, string[] additionalArgs,
Destinations source,
UUID agentKey, string agentName)
{
if (ChartMemory.HasChart(additionalArgs[0]))
{
Chart v = ChartMemory.GetNamedChart(additionalArgs[0]);
ChartMemory.Instance.Charts.Remove(v);
ChartMemory.SaveToFile();
MHE(source, client, "Chart deleted");
return;
}
}
[CommandGroup("addchartrow", 5, "addchartrow [name] [bitmask] [index] [label]", Bot.Destinations.DEST_AGENT | Bot.Destinations.DEST_LOCAL | Bot.Destinations.DEST_GROUP)]
public void addChartRow(UUID client, int level, string[] additionalArgs,
Destinations source,
UUID agentKey, string agentName)
{
if (ChartMemory.HasChart(additionalArgs[0]))
{
Chart v = ChartMemory.GetNamedChart(additionalArgs[0]);
int index = ChartMemory.Instance.Charts.IndexOf(v);
ChartRow row = new ChartRow();
row.Label = "";
row.Mask = Convert.ToInt32(additionalArgs[1]);
int masterIndex;
bool hasIndex = int.TryParse(additionalArgs[2], out masterIndex);
void getRowLabel()
{
row.Label = "";
if (hasIndex)
{
// the label is at 3 and above
for(int i = 3; i < additionalArgs.Length; i++)
{
row.Label += additionalArgs[i] + " ";
}
if (row.Label.EndsWith(" ")) row.Label=row.Label.TrimEnd(' ');
}else
{
// the label is at 2 and above
for (int i = 2; i < additionalArgs.Length; i++)
{
row.Label += additionalArgs[i] + " ";
}
if (row.Label.EndsWith(" ")) row.Label=row.Label.TrimEnd(' ');
}
}
getRowLabel();
if (v.RowData.Where(x => x.Label == row.Label).Count() > 0)
{
MHE(source, client, "A chart row with that label already exists.");
return;
}else
{
// index optional
if(hasIndex)
{
v.RowData.Insert(masterIndex, row);
ChartMemory.Instance.Charts[index] = v;
ChartMemory.SaveToFile();
}else
{
// row label might start at 2 instead, but we only add anyway
getRowLabel();
v.RowData.Add(row);
ChartMemory.Instance.Charts[index] = v;
ChartMemory.SaveToFile();
}
}
MHE(source, client, "Chart row added");
return;
}
}
[CommandGroup("reloadcharts", 5, "reloadcharts - Reloads the charts.json file from disk", Bot.Destinations.DEST_AGENT | Bot.Destinations.DEST_LOCAL | Bot.Destinations.DEST_GROUP)]
public void reloadCharts(UUID client, int level, string[] additionalArgs,
Destinations source,
UUID agentKey, string agentName)
{
ChartMemory.Reload();
MHE(source, client, "Reload completed");
}
[CommandGroup("setchartdesc", 5, "setchartdesc [chartName] [args...] - Sets the chart description on the chart page header", Bot.Destinations.DEST_AGENT | Bot.Destinations.DEST_LOCAL | Bot.Destinations.DEST_GROUP)]
public void setchartdesc(UUID client, int level, string[] additionalArgs,
Destinations source,
UUID agentKey, string agentName)
{
string finalStr = "";
int pos = 0;
foreach(string s in additionalArgs)
{
if (pos == 0) continue;
else
finalStr += s+" ";
pos++;
}
if (finalStr.EndsWith(" ")) finalStr = finalStr.TrimEnd(' ');
if (ChartMemory.HasChart(additionalArgs[0]))
{
Chart v = ChartMemory.GetNamedChart(additionalArgs[0]);
pos = ChartMemory.Instance.Charts.IndexOf(v);
v.ChartDescription = finalStr;
ChartMemory.Instance.Charts[pos] = v;
ChartMemory.SaveToFile();
MHE(source, client, "Chart description has been set");
}
else
{
MHE(source, client, "No such chart");
}
}
[CommandGroup("delchartrow", 5, "delchartrow [name] [label]", Bot.Destinations.DEST_AGENT | Bot.Destinations.DEST_LOCAL | Bot.Destinations.DEST_GROUP)]
public void removeChartRow(UUID client, int level, string[] additionalArgs,
Destinations source,
UUID agentKey, string agentName)
{
if (ChartMemory.HasChart(additionalArgs[0]))
{
Chart v = ChartMemory.GetNamedChart(additionalArgs[0]);
int index = ChartMemory.Instance.Charts.IndexOf(v);
ChartRow row = new ChartRow();
row.Label = "";
void getRowLabel()
{
row.Label = "";
for (int i = 1; i < additionalArgs.Length; i++)
{
row.Label += additionalArgs[i] + " ";
}
if (row.Label.EndsWith(" ")) row.Label=row.Label.TrimEnd(' ');
}
getRowLabel();
if (v.RowData.Where(x => x.Label == row.Label).Count() > 0)
{
row=v.RowData.Where(x => x.Label == row.Label).First();
v.RowData.Remove(row);
ChartMemory.Instance.Charts[index] = v;
ChartMemory.SaveToFile();
}
else
{
MHE(source, client, "No such row in that chart");
return;
}
MHE(source, client, "Chart row deleted");
return;
}
}
[CommandGroup("addchartcol", 5, "addchartcol [name] [label] [color code] [colIndex]", Bot.Destinations.DEST_AGENT | Bot.Destinations.DEST_LOCAL | Bot.Destinations.DEST_GROUP)]
public void setChartCols(UUID client, int level, string[] additionalArgs,
Destinations source,
UUID agentKey, string agentName)
{
if (ChartMemory.HasChart(additionalArgs[0]))
{
Chart v = ChartMemory.GetNamedChart(additionalArgs[0]);
int index = ChartMemory.Instance.Charts.IndexOf(v);
ChartColumn col = v.ColumnData;
if (col == null) col = new ChartColumn();
if (col.Fields == null) col.Fields = new List<ChartColumnField>();
if (col.Fields.Where(x => x.Label == additionalArgs[1]).Count() > 0)
{
// already has this column
MHE(source, client, "That column already exists");
return;
}else
{
ChartColumnField field = new ChartColumnField();
field.ColorCode = additionalArgs[2];
field.Label = additionalArgs[1];
if (additionalArgs.Length == 4)
{
// insert at index
col.Fields.Insert(Convert.ToInt32(additionalArgs[3]), field);
}else
col.Fields.Add(field);
}
v.ColumnData = col;
ChartMemory.Instance.Charts[index] = v;
ChartMemory.SaveToFile();
MHE(source, client, "Column data has been updated");
}
else
{
MHE(source, client, "No such chart");
}
}
[CommandGroup("delchartcol", 5, "delchartcol [name] [label]", Bot.Destinations.DEST_AGENT | Bot.Destinations.DEST_LOCAL | Bot.Destinations.DEST_GROUP)]
public void remChartCols(UUID client, int level, string[] additionalArgs,
Destinations source,
UUID agentKey, string agentName)
{
if (ChartMemory.HasChart(additionalArgs[0]))
{
Chart v = ChartMemory.GetNamedChart(additionalArgs[0]);
int index = ChartMemory.Instance.Charts.IndexOf(v);
if (v.ColumnData.Fields.Where(x => x.Label == additionalArgs[1]).Count() > 0)
{
ChartColumnField theChartField = v.ColumnData.Fields.Where(x => x.Label == additionalArgs[1]).First();
v.ColumnData.Fields.Remove(theChartField);
ChartMemory.Instance.Charts[index] = v;
ChartMemory.SaveToFile();
MHE(source, client, "Column removed");
}
else
{
MHE(source, client, "Column does not exist, nothing to remove");
}
}
else
{
MHE(source, client, "No such chart");
}
}
}
}

162
Charts/ChartMemory.cs Normal file
View file

@ -0,0 +1,162 @@
using Newtonsoft.Json;
using OpenMetaverse;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.IO;
using System.Linq;
using System.Text;
namespace Bot.Charts
{
public sealed class ChartMemory
{
private static readonly object lck = new object();
private static ChartMemory a;
static ChartMemory() { }
public static ChartMemory Instance
{
get
{
if (a != null) return a;
else
{
lock (lck)
{
if (a == null) a = LoadFromFile();
return a;
}
}
}
}
private static readonly object FileHandler = new object();
private static ChartMemory LoadFromFile()
{
lock (FileHandler)
{
// Read json file
if (!File.Exists("Charts.json")) return new ChartMemory();
return JsonConvert.DeserializeObject<ChartMemory>(File.ReadAllText("Charts.json"));
}
}
public static void Reload()
{
lock (lck)
{
a = LoadFromFile();
}
}
public static void SaveToFile()
{
lock (FileHandler)
{
File.WriteAllText("Charts.json", JsonConvert.SerializeObject(Instance, Formatting.Indented));
}
}
public List<Chart> Charts { get; set; } = new List<Chart>();
public static bool HasChart(string ChartName)
{
if (Instance.Charts.Where(x => x.ChartName == ChartName).Count() > 0) return true;
else return false;
}
public static bool HasChartID(string ID)
{
if (Instance.Charts.Where(x => x.ChartID.ToString() == ID).Count() > 0) return true;
else return false;
}
public static Chart GetNamedChart(string chartName)
{
return Instance.Charts.Where(x => x.ChartName == chartName).First();
}
public static Chart GetChartByID(string ID)
{
return Instance.Charts.Where(x => x.ChartID.ToString() == ID).First();
}
}
/// <summary>
/// A chart itself
/// </summary>
public class Chart
{
public string ChartName;
public ChartColumn ColumnData;
public List<ChartRow> RowData;
public UUID ChartID;
public string ChartDescription = "";
public Chart(string ChartNm)
{
ChartName = ChartNm;
ColumnData = new ChartColumn();
RowData = new List<ChartRow>();
ChartID = UUID.Random();
ChartDescription = "A chart generated by the BotCore5 system";
}
}
/// <summary>
/// Field data for column
/// </summary>
public class ChartColumnField
{
public string Label;
public string ColorCode;
}
/// <summary>
/// The column itself
/// </summary>
public class ChartColumn
{
public List<ChartColumnField> Fields;
public int Bit2Pos(int bit)
{
return Convert.ToInt32(Math.Round(Math.Log10(Convert.ToDouble(bit))));
}
public int Field2Bit(string FieldLabel)
{
if (Fields.Select(x => x.Label == FieldLabel).Count() > 0)
{
return Convert.ToInt32(Math.Pow(2,Fields.IndexOf(Fields.Where(x => x.Label == FieldLabel).First())));
}
else
{
return 0;
}
}
public int Pos2Bit(int pos)
{
return Convert.ToInt32(Math.Pow(2, Convert.ToDouble(pos)));
}
public string ColorForBit(int BitMask)
{
int posInList = Bit2Pos(BitMask);
return Fields[posInList].ColorCode;
}
}
/// <summary>
/// A row occupying all columns
/// </summary>
public class ChartRow
{
public string Label;
public int Mask;
}
}

101
Charts/ChartRenderer.cs Normal file
View file

@ -0,0 +1,101 @@
using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Text;
using Bot.WebHookServer;
namespace Bot.Charts
{
class ChartRenderer
{
public string TABLE_CSS = "<style>\n.the_table {\nborder:1px inset #00FFFF;\nborder-collapse:separate;\nborder-spacing:0px;\npadding:6px;\n}\n\n.the_table th {\nborder:1px inset #00FFFF;\npadding:6px;\nbackground:#F0F0F0;\n}\n.the_table td {\nborder:1px inset #00FFFF;\npadding:6px;\nbackground:#000000;\ncolor:#FFFFFF;\n}\n</style>";
[WebhookAttribs("/charts/%", HTTPMethod = "GET")]
public WebhookRegistry.HTTPResponseData renderChart(List<string> arguments, string body, string method, NameValueCollection headers)
{
WebhookRegistry.HTTPResponseData hrd = new WebhookRegistry.HTTPResponseData();
if (ChartMemory.HasChartID(arguments[0]))
{
hrd.Status = 200;
hrd.ReturnContentType = "text/html";
Chart C = ChartMemory.GetChartByID(arguments[0]);
string page = "<html><head><title>Chart - " + C.ChartName + "</title></head><body bgcolor='black'>";
// Don't prepend the Table CSS since we need to set colors custom
page += "<center><a style='color:white'><h2>" + C.ChartDescription + "</h2></a>";
page += "<table style=\"border:1px inset #00FFFF;border-collapse:separate;border-spacing:0px;padding:6px;\">";
ChartColumn col = C.ColumnData;
page += "<thead><th style=\"background:#F0F0F0;border:1px inset #00FFFF;padding:6px\">"+C.ChartName+"</th>";
foreach (ChartColumnField field in col.Fields)
{
page += "<th style=\"background:" + field.ColorCode + "\";border:1px inset #00FFFF;padding:6px\">" + field.Label + "</th>";
}
page += "</thead><tbody>";
int Pos = 0;
foreach(ChartRow row in C.RowData)
{
Pos = 0;
page += "<tr><td style=\"border:1px inset #00FFFF;padding:6px;background:#F0F0F0;color:black\">" + row.Label + "</td>";
foreach(ChartColumnField field in col.Fields)
{
// Begin processing row. Keep index of what position we are at
int MaskForPos = col.Pos2Bit(Pos);
string ColorCode = "#000000";
if ((row.Mask & MaskForPos) == MaskForPos)
{
// set the color code to the col code
ColorCode = col.Fields[Pos].ColorCode;
}
page += "<td style=\"border:1px inset #00FFFF;padding:6px;background:" + ColorCode + ";color:white\"> </td>";
Pos++;
}
page += "</tr>";
}
page += "</tbody></table></body>";
page += "<script type='text/javascript'>";
page += "setInterval(function(){window.location.reload(true);}, 30000);";
page += "</script>";
hrd.ReplyString = page;
}else
{
hrd.ReplyString = "Not found";
hrd.Status = 404;
hrd.ReturnContentType = "text/plain";
}
return hrd;
}
[WebhookAttribs("/charts", HTTPMethod = "GET")]
public WebhookRegistry.HTTPResponseData listCharts(List<string> arguments, string body, string method, NameValueCollection headers)
{
WebhookRegistry.HTTPResponseData hrd = new WebhookRegistry.HTTPResponseData();
string webpage = "<html><head><title>BotCore5 chart list</title></head><body bgcolor='#000000'>";
webpage += TABLE_CSS;
webpage += "\n\n<table class=\"the_table\"><thead><tr><th>Chart Name</th><th>Chart Path</th><th>Description of chart</th></tr></thead><tbody>";
foreach(Chart c in ChartMemory.Instance.Charts)
{
webpage += "\n<tr><td>" + c.ChartName;
webpage += "</td><td><a href='/charts/" + c.ChartID+"'>"+c.ChartName+"</a></td><td>"+c.ChartDescription+"</td></tr>";
}
webpage += "</tbody>";
webpage += "</table></body></html>";
hrd.ReplyString = webpage;
hrd.ReturnContentType = "text/html";
hrd.Status = 200;
return hrd;
}
}
}

View file

@ -68,6 +68,10 @@ namespace Bot
public bool LogChatAndIMs { get; set; } = false;
public string IMAndChatFormat { get; set; } = "[%TIME%] (%NAME%): %MESSAGE%";
public bool GreeterEnabled { get; set; } = false;
public string GreeterMessage { get; set; } = "";
public Dictionary<UUID, int> BotAdmins { get; set; } = new Dictionary<UUID, int>();
public List<string> AuthedGithubUsers { get; set; } = new List<string>();

132
Visitors/Greeter.cs Normal file
View file

@ -0,0 +1,132 @@
using Bot.CommandSystem;
using System;
using System.Collections.Generic;
using System.Text;
using OpenMetaverse;
using System.Linq;
using System.Threading;
namespace Bot.Visitors
{
class Greeter : BaseCommands, IProgram
{
[CommandGroup("greet", 5, "greet [array:Message] - Greets any new visitors to the parcel", Destinations.DEST_AGENT | Destinations.DEST_GROUP | Destinations.DEST_LOCAL)]
public void enable_greeter_and_set_msg
(UUID client, int level, string[] additionalArgs,
Destinations source,
UUID agentKey, string agentName)
{
List<string> greeterMsg = additionalArgs.ToList();
string msg = string.Join(' ', greeterMsg);
MainConfiguration.Instance.GreeterEnabled = true;
MainConfiguration.Instance.GreeterMessage = msg;
MainConfiguration.Instance.Save();
MHE(source, client, "Greeter enabled, and message updated. The greeter will only greet for the current parcel the bot is standing in");
}
[CommandGroup("greet_off", 5, "greet_off - Turns off the greeter", Destinations.DEST_AGENT | Destinations.DEST_GROUP | Destinations.DEST_LOCAL)]
public void disable_greeter
(UUID client, int level, string[] additionalArgs,
Destinations source,
UUID agentKey, string agentName)
{
MainConfiguration.Instance.GreeterEnabled = false;
MainConfiguration.Instance.GreeterMessage = "";
MainConfiguration.Instance.Save();
MHE(source, client, "Greeter has been disabled");
}
private ManualResetEvent WaitForInventory = new ManualResetEvent(false);
private UUID FoundInventoryItem = UUID.Zero;
public string ProgramName => "Greeter";
public float ProgramVersion => 1.0f;
[CommandGroup("set_give_on_greet", 5, "set_give_on_greet [array:InventoryPath] - Finds and sets the inventory item to give when greeting someone", Destinations.DEST_AGENT | Destinations.DEST_GROUP | Destinations.DEST_LOCAL)]
public void set_greeter_item
(UUID client, int level, string[] additionalArgs,
Destinations source,
UUID agentKey, string agentName)
{
List<string> greeterMsg = additionalArgs.ToList();
string sItem = string.Join(' ', greeterMsg);
MHE(source, client, "Searching for: " + sItem);
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);
if (WaitForInventory.WaitOne(30001))
{
// 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");
}
}
private void Inventory_FindObjectByPathReply(object sender, FindObjectByPathReplyEventArgs e)
{
FoundInventoryItem = e.InventoryObjectID;
BotSession.Instance.grid.Inventory.FindObjectByPathReply -= Inventory_FindObjectByPathReply;
BotSession.Instance.grid.Inventory.RequestFetchInventory(FoundInventoryItem, BotSession.Instance.grid.Self.AgentID);
}
TimeSpan tickCounter = new TimeSpan();
public void run()
{
// Every 2 seconds, tick
// cant implement yet- visitor log needed
if (tickCounter == null)
{
tickCounter = new TimeSpan();
tickCounter.Add(TimeSpan.FromSeconds(2));
}
if(tickCounter > TimeSpan.FromMinutes(1))
{
// update everyones' seen minute count who is on sim
}
}
public void getTick()
{
}
public void passArguments(string data)
{
}
public void LoadConfiguration()
{
}
public void onIMEvent(object sender, InstantMessageEventArgs e)
{
BotSession.Instance.grid.Self.IM -= onIMEvent;
}
}
}

72
Visitors/VisitorLog.cs Normal file
View file

@ -0,0 +1,72 @@
using Newtonsoft.Json;
using OpenMetaverse;
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
namespace Bot.Visitors
{
public sealed class VisitorLog
{
private static readonly object lck = new object();
private static VisitorLog l;
static VisitorLog() { }
public static VisitorLog Instance
{
get
{
if (l != null) return l;
else
{
lock (lck)
{
if (l == null) l = LoadMemory();
return l;
}
}
}
}
private static readonly object fileLock = new object();
public static VisitorLog LoadMemory()
{
lock (fileLock)
{
if (File.Exists("VisitorLog.json"))
return JsonConvert.DeserializeObject<VisitorLog>(File.ReadAllText("VisitorLog.json"));
else return new VisitorLog();
}
}
public static void SaveMemory()
{
lock (fileLock)
{
File.WriteAllText("VisitorLog.json", JsonConvert.SerializeObject(l, Formatting.Indented));
}
}
public List<Visitor> Visitors { get; set; } = new List<Visitor>();
}
public class Visitor
{
public UUID ID { get; set} = UUID.Zero;
public string username { get; set; } = "first.last";
public DateTime LastSeen { get; set; } = DateTime.Now;
public Dictionary<DateTime, TimeSpan> MinutesSeenPerDay { get; set; } = new Dictionary<DateTime, TimeSpan>();
internal Visitor(UUID kID)
{
ID = kID;
username = "";
LastSeen = DateTime.Now;
MinutesSeenPerDay = new Dictionary<DateTime, TimeSpan>();
MinutesSeenPerDay.Add(DateTime.Today, TimeSpan.FromMinutes(0));
}
}
}