Add bot source
This commit is contained in:
parent
020d43b81c
commit
437cc0e0e1
14 changed files with 1788 additions and 0 deletions
19
Source/Assembly/ASMInfo.cs
Normal file
19
Source/Assembly/ASMInfo.cs
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
/*
|
||||||
|
Copyright © 2019 Tara Piccari (Aria; Tashia Redrose)
|
||||||
|
Licensed under the AGPL-3.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace Bot.Assemble
|
||||||
|
{
|
||||||
|
public class ASMInfo
|
||||||
|
{
|
||||||
|
public static string BotName = "ZBotCore";
|
||||||
|
public static double BotVer = 5.0;
|
||||||
|
public static string GitPassword = "**REMOVED**";
|
||||||
|
}
|
||||||
|
}
|
49
Source/BotSession.cs
Normal file
49
Source/BotSession.cs
Normal file
|
@ -0,0 +1,49 @@
|
||||||
|
/*
|
||||||
|
Copyright © 2019 Tara Piccari (Aria; Tashia Redrose)
|
||||||
|
Licensed under the AGPL-3.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using OpenMetaverse;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Bot
|
||||||
|
{
|
||||||
|
public sealed class BotSession
|
||||||
|
{
|
||||||
|
private static BotSession _inst = null;
|
||||||
|
private static readonly object lockHandle = new object();
|
||||||
|
|
||||||
|
static BotSession()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public static BotSession Instance
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
lock (lockHandle)
|
||||||
|
{
|
||||||
|
if (_inst == null)
|
||||||
|
{
|
||||||
|
_inst = new BotSession();
|
||||||
|
}
|
||||||
|
return _inst;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public GridClient grid { get; set; }
|
||||||
|
public SysOut Logger { get; set; }
|
||||||
|
public MessageHandler.MessageHandleEvent MHE;
|
||||||
|
public MessageHandler MH;
|
||||||
|
|
||||||
|
public MainConfiguration ConfigurationHandle;
|
||||||
|
}
|
||||||
|
}
|
45
Source/CommandSystem/CommandGroup.cs
Normal file
45
Source/CommandSystem/CommandGroup.cs
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
/*
|
||||||
|
Copyright © 2019 Tara Piccari (Aria; Tashia Redrose)
|
||||||
|
Licensed under the AGPL-3.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Reflection;
|
||||||
|
|
||||||
|
|
||||||
|
namespace Bot.CommandSystem
|
||||||
|
{
|
||||||
|
|
||||||
|
[System.AttributeUsage(AttributeTargets.Method, AllowMultiple = true)]
|
||||||
|
public class CommandGroup : Attribute
|
||||||
|
{
|
||||||
|
public string Command;
|
||||||
|
public int minLevel;
|
||||||
|
public MethodInfo AssignedMethod;
|
||||||
|
public int arguments = 0;
|
||||||
|
public CommandHelp cmdUsage;
|
||||||
|
public MessageHandler.Destinations CommandSource;
|
||||||
|
|
||||||
|
public CommandGroup(string Command, int minLevel, int argCount, string HelpText, MessageHandler.Destinations SourceType)
|
||||||
|
{
|
||||||
|
this.Command = Command;
|
||||||
|
this.minLevel = minLevel;
|
||||||
|
arguments = argCount;
|
||||||
|
CommandSource = SourceType;
|
||||||
|
cmdUsage = new CommandHelp(Command, minLevel, argCount, HelpText, SourceType);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[AttributeUsage(AttributeTargets.Method, AllowMultiple = true)]
|
||||||
|
public class CommandGroupMaster : Attribute
|
||||||
|
{
|
||||||
|
public string CommandGroupName;
|
||||||
|
public CommandGroupMaster(string CmdGroupName)
|
||||||
|
{
|
||||||
|
CommandGroupName = CmdGroupName;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
69
Source/CommandSystem/CommandHelp.cs
Normal file
69
Source/CommandSystem/CommandHelp.cs
Normal file
|
@ -0,0 +1,69 @@
|
||||||
|
/*
|
||||||
|
Copyright © 2019 Tara Piccari (Aria; Tashia Redrose)
|
||||||
|
Licensed under the AGPL-3.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
using System.IO;
|
||||||
|
using OpenMetaverse;
|
||||||
|
|
||||||
|
|
||||||
|
namespace Bot.CommandSystem
|
||||||
|
{
|
||||||
|
public class CommandHelp
|
||||||
|
{
|
||||||
|
Help h;
|
||||||
|
|
||||||
|
public bool hasGroupFlag()
|
||||||
|
{
|
||||||
|
if ((h.dests_allowed & MessageHandler.Destinations.DEST_GROUP) == MessageHandler.Destinations.DEST_GROUP) return true;
|
||||||
|
else return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static readonly string NoAdditionalArguments = "This command does not take any arguments";
|
||||||
|
public struct Help
|
||||||
|
{
|
||||||
|
public string Name;
|
||||||
|
public int minLevel;
|
||||||
|
public int args;
|
||||||
|
public string Text;
|
||||||
|
public string sources;
|
||||||
|
public MessageHandler.Destinations dests_allowed;
|
||||||
|
}
|
||||||
|
public string GetUsage()
|
||||||
|
{
|
||||||
|
return "_\nCommand [" + h.Name + "]\n" + h.sources + "\nMinimum Level Required [" + h.minLevel.ToString() + "]\nTotal Arguments [" + h.args.ToString() + "]\nUsage: " + h.Text;
|
||||||
|
|
||||||
|
}
|
||||||
|
public string RawUsage()
|
||||||
|
{
|
||||||
|
return "Usage: " + h.Text;
|
||||||
|
}
|
||||||
|
public CommandHelp(string CmdName, int minLevel, int argCount, string HelpText, MessageHandler.Destinations DESTS)
|
||||||
|
{
|
||||||
|
h = new Help();
|
||||||
|
string Applicable = "Command can be used in [";
|
||||||
|
if ((DESTS & MessageHandler.Destinations.DEST_LOCAL) == MessageHandler.Destinations.DEST_LOCAL) Applicable += "Local, ";
|
||||||
|
if ((DESTS & MessageHandler.Destinations.DEST_AGENT) == MessageHandler.Destinations.DEST_AGENT) Applicable += "IM, ";
|
||||||
|
if ((DESTS & MessageHandler.Destinations.DEST_GROUP) == MessageHandler.Destinations.DEST_GROUP) Applicable += "Group, ";
|
||||||
|
if ((DESTS & MessageHandler.Destinations.DEST_DISCORD) == MessageHandler.Destinations.DEST_DISCORD) Applicable += "Discord, ";
|
||||||
|
|
||||||
|
if (Applicable.Substring(Applicable.Length - 1, 1) == " ") Applicable = Applicable.Substring(0, Applicable.Length - 2) + "]";
|
||||||
|
|
||||||
|
h.dests_allowed = DESTS;
|
||||||
|
h.args = argCount;
|
||||||
|
h.Name = CmdName;
|
||||||
|
h.minLevel = minLevel;
|
||||||
|
if (HelpText == "") HelpText = NoAdditionalArguments;
|
||||||
|
h.Text = HelpText;
|
||||||
|
h.sources = Applicable;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
260
Source/CommandSystem/CommandRegistry.cs
Normal file
260
Source/CommandSystem/CommandRegistry.cs
Normal file
|
@ -0,0 +1,260 @@
|
||||||
|
/*
|
||||||
|
Copyright © 2019 Tara Piccari (Aria; Tashia Redrose)
|
||||||
|
Licensed under the AGPL-3.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using OpenMetaverse;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Threading;
|
||||||
|
|
||||||
|
|
||||||
|
namespace Bot.CommandSystem
|
||||||
|
{
|
||||||
|
public sealed class CommandRegistry
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* ===============================
|
||||||
|
* START SINGLETON PATTERN
|
||||||
|
* ===============================
|
||||||
|
*/
|
||||||
|
private static CommandRegistry _instance = null;
|
||||||
|
private static readonly object lockhandle = new object();
|
||||||
|
|
||||||
|
static CommandRegistry()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public static CommandRegistry Instance
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
lock (lockhandle)
|
||||||
|
{
|
||||||
|
if (_instance == null)
|
||||||
|
{
|
||||||
|
BotSession bs = BotSession.Instance;
|
||||||
|
_instance = new CommandRegistry();
|
||||||
|
_instance.client = bs.grid;
|
||||||
|
_instance.config = bs.ConfigurationHandle;
|
||||||
|
_instance.Log = bs.Logger;
|
||||||
|
_instance.MHEx = bs.MHE;
|
||||||
|
_instance.LocateCommands();
|
||||||
|
}
|
||||||
|
return _instance;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ==============================
|
||||||
|
* SINGLETON PATTERN END
|
||||||
|
* Usage: CommandRegistry reg = CommandRegistry.Instance
|
||||||
|
* ==============================
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Define the registry
|
||||||
|
public Dictionary<string, CommandGroup> Cmds = new Dictionary<string, CommandGroup>();
|
||||||
|
public GridClient client;
|
||||||
|
public SysOut Log;
|
||||||
|
public IConfig config;
|
||||||
|
public MessageHandler.MessageHandleEvent MHEx;
|
||||||
|
public void LocateCommands()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
|
||||||
|
int i = 0;
|
||||||
|
// Locate all commands--
|
||||||
|
for (i = 0; i < AppDomain.CurrentDomain.GetAssemblies().Length; i++)
|
||||||
|
{
|
||||||
|
Assembly A = null;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
A = AppDomain.CurrentDomain.GetAssemblies()[i];
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
// MHEx(MessageHandler.Destinations.DEST_LOCAL, UUID.Zero, "")
|
||||||
|
}
|
||||||
|
if (A != null)
|
||||||
|
{
|
||||||
|
int ii = 0;
|
||||||
|
for (ii = 0; ii < A.GetTypes().Length; ii++)
|
||||||
|
{
|
||||||
|
Type T = null;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
T = A.GetTypes()[ii];
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
if (T != null)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (T.IsClass)
|
||||||
|
{
|
||||||
|
foreach (MethodInfo MI in T.GetMethods())
|
||||||
|
{
|
||||||
|
CommandGroup[] Command = (CommandGroup[])MI.GetCustomAttributes(typeof(CommandGroup), false);
|
||||||
|
//var CommandO = MI.GetCustomAttributes(typeof(CommandGroup), false);
|
||||||
|
if (Command.Length > 0)
|
||||||
|
{
|
||||||
|
for (int ix = 0; ix < Command.Length; ix++)
|
||||||
|
{
|
||||||
|
CommandGroup CG = Command[ix];
|
||||||
|
CG.AssignedMethod = MI;
|
||||||
|
|
||||||
|
if (Cmds.ContainsKey(CG.Command) == false)
|
||||||
|
{
|
||||||
|
Console.WriteLine("DISCOVER: " + CG.Command);
|
||||||
|
Cmds.Add(CG.Command, CG);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Console.WriteLine("Discovered " + Cmds.Count.ToString() + " total commands");
|
||||||
|
}
|
||||||
|
catch (ReflectionTypeLoadException e)
|
||||||
|
{
|
||||||
|
MHEx(MessageHandler.Destinations.DEST_LOCAL, UUID.Zero, "FAILURE!!!\n \n[Assembly load failure]");
|
||||||
|
foreach (Exception X in e.LoaderExceptions)
|
||||||
|
{
|
||||||
|
MHEx(MessageHandler.Destinations.DEST_LOCAL, UUID.Zero, X.Message + "\n \nSTACK: " + X.StackTrace);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void PrintHelpAll(MessageHandler.Destinations dest, UUID uid)
|
||||||
|
{
|
||||||
|
|
||||||
|
for (int i = 0; i < Cmds.Count; i++)
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
KeyValuePair<string, CommandGroup> kvp = Cmds.ElementAt(i);
|
||||||
|
|
||||||
|
CommandHelp HE = kvp.Value.cmdUsage;
|
||||||
|
if (dest == MessageHandler.Destinations.DEST_GROUP)
|
||||||
|
{
|
||||||
|
if (!HE.hasGroupFlag())
|
||||||
|
{
|
||||||
|
//return;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
MHEx(dest, uid, HE.GetUsage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
|
||||||
|
MHEx(dest, uid, HE.GetUsage());
|
||||||
|
}
|
||||||
|
|
||||||
|
// MHEx(dest, uid, kvp.Value.cmdUsage.GetUsage());
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void PrintHelp(MessageHandler.Destinations dest, string cmd, UUID uid)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
|
||||||
|
CommandHelp HE = Cmds[cmd].cmdUsage;
|
||||||
|
if (dest == MessageHandler.Destinations.DEST_GROUP)
|
||||||
|
{
|
||||||
|
if (!HE.hasGroupFlag())
|
||||||
|
{
|
||||||
|
//return; // DO NOT SCHEDULE THIS HELP INFO FOR GROUP!!!
|
||||||
|
}
|
||||||
|
}
|
||||||
|
MHEx(dest, uid, Cmds[cmd].cmdUsage.GetUsage());
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
MHEx(dest, uid, "Error: Unrecognized command");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void RunCommand(string cmdString, UUID user, int level, MessageHandler.MessageHandleEvent MHE, MessageHandler.Destinations source, UUID agentKey, string agentName)
|
||||||
|
{
|
||||||
|
MHEx = MHE;
|
||||||
|
int pos = 0;
|
||||||
|
string[] cmdStruct = cmdString.Split(' ');
|
||||||
|
int IgnoreCount = 0;
|
||||||
|
foreach (string S in cmdStruct)
|
||||||
|
{
|
||||||
|
if (IgnoreCount > 0) { IgnoreCount--; }
|
||||||
|
else
|
||||||
|
{
|
||||||
|
|
||||||
|
// Search for Command
|
||||||
|
if (Cmds.ContainsKey(S))
|
||||||
|
{
|
||||||
|
// this must be a command
|
||||||
|
// argument types will ALWAYS be structured like this:
|
||||||
|
// UUID, int, GridClient, [args up to argCount], optional:{SysOut}
|
||||||
|
|
||||||
|
CommandGroup cgX = Cmds[S];
|
||||||
|
if (level >= cgX.minLevel)
|
||||||
|
{
|
||||||
|
// Check that the destination is allowed.
|
||||||
|
// If not then skip this command entirely
|
||||||
|
MessageHandler.Destinations dests = cgX.CommandSource;
|
||||||
|
bool Allowed = false;
|
||||||
|
if ((dests & MessageHandler.Destinations.DEST_AGENT) == source) Allowed = true;
|
||||||
|
if ((dests & MessageHandler.Destinations.DEST_GROUP) == source) Allowed = true;
|
||||||
|
if ((dests & MessageHandler.Destinations.DEST_LOCAL) == source) Allowed = true;
|
||||||
|
|
||||||
|
if (!Allowed)
|
||||||
|
{
|
||||||
|
IgnoreCount = cgX.arguments;
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
|
||||||
|
var ovj = Activator.CreateInstance(cgX.AssignedMethod.DeclaringType);
|
||||||
|
string[] additionalArgs = new string[cgX.arguments];
|
||||||
|
IgnoreCount = cgX.arguments;
|
||||||
|
for (int i = 1; i <= cgX.arguments; i++)
|
||||||
|
{
|
||||||
|
additionalArgs[i - 1] = cmdStruct[pos + i];
|
||||||
|
}
|
||||||
|
pos++;
|
||||||
|
//(UUID client, int level, GridClient grid, string[] additionalArgs,
|
||||||
|
//SysOut log, MessageHandler.MessageHandleEvent MHE, MessageHandler.Destinations source,
|
||||||
|
//CommandRegistry registry, UUID agentKey, string agentName)
|
||||||
|
Thread CommandThread = new Thread(() => cgX.AssignedMethod.Invoke(ovj, new object[] { user, level, client, additionalArgs, Log, MHE, source, this, agentKey, agentName }));
|
||||||
|
CommandThread.Start();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
20
Source/ConfigSystem/BaseConfig.cs
Normal file
20
Source/ConfigSystem/BaseConfig.cs
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
/*
|
||||||
|
Copyright © 2019 Tara Piccari (Aria; Tashia Redrose)
|
||||||
|
Licensed under the AGPL-3.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Bot
|
||||||
|
{
|
||||||
|
class BaseConfig : IConfig
|
||||||
|
{
|
||||||
|
public float ConfigVersion { get; set; }
|
||||||
|
public string ConfigFor { get; set; }
|
||||||
|
public List<string> Data { get; set; }
|
||||||
|
}
|
||||||
|
}
|
23
Source/ConfigSystem/IConfig.cs
Normal file
23
Source/ConfigSystem/IConfig.cs
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
/*
|
||||||
|
Copyright © 2019 Tara Piccari (Aria; Tashia Redrose)
|
||||||
|
Licensed under the AGPL-3.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Bot
|
||||||
|
{
|
||||||
|
public interface IConfig
|
||||||
|
{
|
||||||
|
float ConfigVersion { get; set; }
|
||||||
|
|
||||||
|
string ConfigFor { get; set; }
|
||||||
|
|
||||||
|
List<string> Data { get; set; }
|
||||||
|
}
|
||||||
|
}
|
57
Source/ConfigSystem/MainConfiguration.cs
Normal file
57
Source/ConfigSystem/MainConfiguration.cs
Normal file
|
@ -0,0 +1,57 @@
|
||||||
|
/*
|
||||||
|
Copyright © 2019 Tara Piccari (Aria; Tashia Redrose)
|
||||||
|
Licensed under the AGPL-3.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using System.IO;
|
||||||
|
|
||||||
|
namespace Bot
|
||||||
|
{
|
||||||
|
[Serializable()]
|
||||||
|
public class MainConfiguration : IConfig
|
||||||
|
{
|
||||||
|
public float ConfigVersion
|
||||||
|
{
|
||||||
|
get; set;
|
||||||
|
}
|
||||||
|
public string ConfigFor { get; set; }
|
||||||
|
public List<string> Data
|
||||||
|
{
|
||||||
|
get; set;
|
||||||
|
}
|
||||||
|
|
||||||
|
public string MainProgramDLL;
|
||||||
|
public string first { get; set; }
|
||||||
|
public string last { get; set; }
|
||||||
|
public string password { get; set; }
|
||||||
|
|
||||||
|
//public License LicenseKey { get; set; }
|
||||||
|
public string ActivationCode { get; set; }
|
||||||
|
|
||||||
|
public MainConfiguration()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public static MainConfiguration Load()
|
||||||
|
{
|
||||||
|
MainConfiguration X = new MainConfiguration();
|
||||||
|
SerialManager sm = new SerialManager();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
X = sm.Read<MainConfiguration>("Main");
|
||||||
|
return X;
|
||||||
|
}
|
||||||
|
catch (FileNotFoundException e)
|
||||||
|
{
|
||||||
|
Console.WriteLine("Main.json was not found");
|
||||||
|
return new MainConfiguration();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
30
Source/IProgram.cs
Normal file
30
Source/IProgram.cs
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
/*
|
||||||
|
Copyright © 2019 Tara Piccari (Aria; Tashia Redrose)
|
||||||
|
Licensed under the AGPL-3.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using OpenMetaverse;
|
||||||
|
|
||||||
|
namespace Bot
|
||||||
|
{
|
||||||
|
public interface IProgram
|
||||||
|
{
|
||||||
|
void run(GridClient client, MessageHandler MH, CommandSystem.CommandRegistry registry); // Define the run command since a thread needs a entry point
|
||||||
|
|
||||||
|
string getTick(); // Run every second to check for queued data. If queue exists, then it will be returned as a JSON string.
|
||||||
|
// getTick can reply with data for the serializer for instance.
|
||||||
|
|
||||||
|
void passArguments(string data); // json!!
|
||||||
|
|
||||||
|
string ProgramName { get; }
|
||||||
|
float ProgramVersion { get; }
|
||||||
|
|
||||||
|
void LoadConfiguration();
|
||||||
|
void onIMEvent(object sender, InstantMessageEventArgs e);
|
||||||
|
}
|
||||||
|
}
|
171
Source/MessageHandler.cs
Normal file
171
Source/MessageHandler.cs
Normal file
|
@ -0,0 +1,171 @@
|
||||||
|
|
||||||
|
/*
|
||||||
|
Copyright © 2019 Tara Piccari (Aria; Tashia Redrose)
|
||||||
|
Licensed under the AGPL-3.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using OpenMetaverse;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
using System.IO;
|
||||||
|
using System.Threading;
|
||||||
|
|
||||||
|
|
||||||
|
namespace Bot
|
||||||
|
{
|
||||||
|
public class MessageHandler
|
||||||
|
{
|
||||||
|
private List<MessageQueuePacket> MSGQueue = new List<MessageQueuePacket>();
|
||||||
|
private List<ActionPacket> ActionQueue = new List<ActionPacket>();
|
||||||
|
private List<DiscordAction> DiscordQueue = new List<DiscordAction>();
|
||||||
|
public ManualResetEvent GroupJoinWaiter = new ManualResetEvent(false);
|
||||||
|
private SysOut Log = SysOut.Instance;
|
||||||
|
|
||||||
|
|
||||||
|
[Flags]
|
||||||
|
public enum Destinations
|
||||||
|
{
|
||||||
|
DEST_AGENT = 1,
|
||||||
|
DEST_GROUP = 2,
|
||||||
|
DEST_LOCAL = 4,
|
||||||
|
DEST_CONSOLE_DEBUG = 8,
|
||||||
|
DEST_CONSOLE_INFO = 16,
|
||||||
|
DEST_ACTION = 32,
|
||||||
|
DEST_DISCORD = 64
|
||||||
|
};
|
||||||
|
|
||||||
|
public struct MessageQueuePacket
|
||||||
|
{
|
||||||
|
public Destinations Dest;
|
||||||
|
public UUID DestID;
|
||||||
|
public string Msg;
|
||||||
|
public int channel;
|
||||||
|
}
|
||||||
|
|
||||||
|
public struct ActionPacket
|
||||||
|
{
|
||||||
|
public Destinations Dest;
|
||||||
|
public string ActionStr;
|
||||||
|
}
|
||||||
|
|
||||||
|
public struct DiscordAction
|
||||||
|
{
|
||||||
|
public string Action;
|
||||||
|
}
|
||||||
|
|
||||||
|
public delegate void MessageHandleEvent(MessageHandler.Destinations DType, UUID AgentOrSession, string MSG, int channel = 0);
|
||||||
|
public volatile MessageHandleEvent callbacks;
|
||||||
|
public void MessageHandle(Destinations DType, UUID AgentOrSession, string MSG, int channel = 0)
|
||||||
|
{
|
||||||
|
if (DType == Destinations.DEST_ACTION)
|
||||||
|
{
|
||||||
|
if (MSG == "RESET_QUEUE")
|
||||||
|
{
|
||||||
|
ClearQueues();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ActionPacket PKT = new ActionPacket();
|
||||||
|
PKT.Dest = DType;
|
||||||
|
PKT.ActionStr = MSG;
|
||||||
|
ActionQueue.Add(PKT);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else if (DType == Destinations.DEST_DISCORD)
|
||||||
|
{
|
||||||
|
DiscordAction DA = new DiscordAction();
|
||||||
|
DA.Action = MSG;
|
||||||
|
DiscordQueue.Add(DA);
|
||||||
|
return; // Do nothing
|
||||||
|
}
|
||||||
|
MessageQueuePacket pkt = new MessageQueuePacket();
|
||||||
|
pkt.channel = channel;
|
||||||
|
pkt.Dest = DType;
|
||||||
|
pkt.DestID = AgentOrSession;
|
||||||
|
pkt.Msg = MSG;
|
||||||
|
|
||||||
|
if (MSGQueue != null)
|
||||||
|
MSGQueue.Add(pkt);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void ClearQueues()
|
||||||
|
{
|
||||||
|
MSGQueue = new List<MessageQueuePacket>();
|
||||||
|
DiscordQueue = new List<DiscordAction>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void run(GridClient client)
|
||||||
|
{
|
||||||
|
// Execute one queue item
|
||||||
|
if (MSGQueue.Count == 0) return;
|
||||||
|
MessageQueuePacket pkt = MSGQueue.First();
|
||||||
|
MSGQueue.RemoveAt(MSGQueue.IndexOf(pkt));
|
||||||
|
if (pkt.Dest == Destinations.DEST_AGENT)
|
||||||
|
{
|
||||||
|
client.Self.InstantMessage(pkt.DestID, "[" + MSGQueue.Count.ToString() + "] " + pkt.Msg);
|
||||||
|
}
|
||||||
|
else if (pkt.Dest == Destinations.DEST_CONSOLE_DEBUG)
|
||||||
|
{
|
||||||
|
Log.debug("[" + MSGQueue.Count.ToString() + "] " + pkt.Msg);
|
||||||
|
}
|
||||||
|
else if (pkt.Dest == Destinations.DEST_CONSOLE_INFO)
|
||||||
|
{
|
||||||
|
Log.info("[" + MSGQueue.Count.ToString() + "] " + pkt.Msg);
|
||||||
|
}
|
||||||
|
else if (pkt.Dest == Destinations.DEST_GROUP)
|
||||||
|
{
|
||||||
|
if (client.Self.GroupChatSessions.ContainsKey(pkt.DestID))
|
||||||
|
client.Self.InstantMessageGroup(pkt.DestID, "[" + MSGQueue.Count.ToString() + "] " + pkt.Msg);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
GroupJoinWaiter.Reset();
|
||||||
|
client.Groups.ActivateGroup(pkt.DestID);
|
||||||
|
client.Self.RequestJoinGroupChat(pkt.DestID);
|
||||||
|
//callbacks(Destinations.DEST_LOCAL, UUID.Zero, "Attempting to join group chat for secondlife:///app/group/" + pkt.DestID.ToString() + "/about");
|
||||||
|
|
||||||
|
if (GroupJoinWaiter.WaitOne(TimeSpan.FromSeconds(20), false))
|
||||||
|
{
|
||||||
|
|
||||||
|
client.Self.InstantMessageGroup(pkt.DestID, "[" + MSGQueue.Count.ToString() + "] " + pkt.Msg);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
MSGQueue.Add(pkt); // Because we failed to join the group chat we'll tack this onto the end of the queue and try again
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (pkt.Dest == Destinations.DEST_LOCAL)
|
||||||
|
{
|
||||||
|
client.Self.Chat("[" + MSGQueue.Count.ToString() + "] " + pkt.Msg, pkt.channel, ChatType.Normal);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public string CheckActions()
|
||||||
|
{
|
||||||
|
string RETURNStr = "";
|
||||||
|
if (ActionQueue.Count == 0) return "NONE";
|
||||||
|
else
|
||||||
|
{
|
||||||
|
RETURNStr = ActionQueue.First().ActionStr;
|
||||||
|
ActionQueue.Remove(ActionQueue.First());
|
||||||
|
return RETURNStr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public string CheckDiscordActions()
|
||||||
|
{
|
||||||
|
if (DiscordQueue.Count == 0) return "NONE";
|
||||||
|
else
|
||||||
|
{
|
||||||
|
string RET = DiscordQueue.First().Action;
|
||||||
|
DiscordQueue.Remove(DiscordQueue.First());
|
||||||
|
return RET;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
44
Source/PluginActivator.cs
Normal file
44
Source/PluginActivator.cs
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
/*
|
||||||
|
Copyright © 2019 Tara Piccari (Aria; Tashia Redrose)
|
||||||
|
Licensed under the AGPL-3.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Bot
|
||||||
|
{
|
||||||
|
public class PluginActivator
|
||||||
|
{
|
||||||
|
public Assembly LoadedASM = null;
|
||||||
|
public void LoadLibrary(string DLL)
|
||||||
|
{
|
||||||
|
|
||||||
|
LoadedASM = Assembly.LoadFrom(DLL);
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<IProgram> Activate(Assembly asm)
|
||||||
|
{
|
||||||
|
List<IProgram> Plugins = new List<IProgram>();
|
||||||
|
foreach (Type A in asm.GetTypes())
|
||||||
|
{
|
||||||
|
Type check = A.GetInterface("IProgram");
|
||||||
|
if (check == null)
|
||||||
|
{
|
||||||
|
//return null;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
IProgram plugin = Activator.CreateInstance(A) as IProgram;
|
||||||
|
Plugins.Add(plugin);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return Plugins;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
743
Source/Program.cs
Normal file
743
Source/Program.cs
Normal file
|
@ -0,0 +1,743 @@
|
||||||
|
/*
|
||||||
|
Copyright © 2019 Tara Piccari (Aria; Tashia Redrose)
|
||||||
|
Licensed under the AGPL-3.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
using Bot.CommandSystem;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
using OpenMetaverse;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Diagnostics;
|
||||||
|
using System.IO;
|
||||||
|
using System.Net;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading;
|
||||||
|
using OpenMetaverse.Packets;
|
||||||
|
using Bot.Assemble;
|
||||||
|
using OpenMetaverse.Interfaces;
|
||||||
|
using System.Security.Cryptography;
|
||||||
|
|
||||||
|
namespace Bot
|
||||||
|
{
|
||||||
|
public class Program
|
||||||
|
{
|
||||||
|
public static SysOut Log = SysOut.Instance;
|
||||||
|
public static double BotVer = ASMInfo.BotVer;
|
||||||
|
public static string BotStr = ASMInfo.BotName; // internal identifier for linden
|
||||||
|
public static MainConfiguration conf;
|
||||||
|
public static string Flavor = "Bot"; // inworld identification - must be customized
|
||||||
|
public static SerialManager SM = new SerialManager();
|
||||||
|
public static string DefaultProgram = "BlankBot.dll"; // default bot - blank will only contain the commands to switch programs. It is a complete blank!
|
||||||
|
public static GridClient client = new GridClient();
|
||||||
|
public static bool g_iIsRunning = true;
|
||||||
|
public static MessageHandler MH;
|
||||||
|
public static CommandRegistry registry;
|
||||||
|
public static List<IProgram> g_ZPrograms = new List<IProgram>();
|
||||||
|
|
||||||
|
static readonly object _CacheLock = new object();
|
||||||
|
//public static License LicenseKey; // Not to be used yet
|
||||||
|
|
||||||
|
public static void msg(MessageHandler.Destinations D, UUID x, string m)
|
||||||
|
{
|
||||||
|
MH.callbacks(D, x, m);
|
||||||
|
}
|
||||||
|
public static unsafe void Main(string[] args)
|
||||||
|
{
|
||||||
|
Console.WriteLine("Setting up Main Configuration");
|
||||||
|
conf = MainConfiguration.Load();
|
||||||
|
//MasterObjectCaches = ObjectCaches.Instance;
|
||||||
|
Log.debugf(true, "main", args);
|
||||||
|
|
||||||
|
if (args.Length == 2)
|
||||||
|
{
|
||||||
|
// Check if this is activation command
|
||||||
|
if (args[0] == "-a")
|
||||||
|
{
|
||||||
|
conf.ActivationCode = args[1];
|
||||||
|
SM.Write<MainConfiguration>("Main", conf);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else if (args[0] == "-m")
|
||||||
|
{
|
||||||
|
conf.MainProgramDLL = args[1];
|
||||||
|
SM.Write<MainConfiguration>("Main", conf);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (args.Length == 4)
|
||||||
|
{
|
||||||
|
if (args[0] == "-l")
|
||||||
|
{
|
||||||
|
conf.first = args[1];
|
||||||
|
conf.last = args[2];
|
||||||
|
conf.password = args[3];
|
||||||
|
SM.Write<MainConfiguration>("Main", conf);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Initiate bot login
|
||||||
|
// Main thread must be caught in the bot loop so it does not terminate early.
|
||||||
|
// Other programs may hook into the bot to control it
|
||||||
|
|
||||||
|
/*
|
||||||
|
if (conf.ActivationCode != "")
|
||||||
|
{
|
||||||
|
|
||||||
|
License L = new License();
|
||||||
|
L.NewKey();
|
||||||
|
L.InitUniqueMachine();
|
||||||
|
L.Key = conf.ActivationCode;
|
||||||
|
License def = new License();
|
||||||
|
def.NewKey();
|
||||||
|
def.InitUniqueMachine();
|
||||||
|
string Reply;
|
||||||
|
HttpWebRequest _request = (HttpWebRequest)WebRequest.Create("http://bak.cloud.xsinode.net/act_handle.php?r=verify&act=" + conf.ActivationCode + "&LIC=" + L.Key + "&mac="+def.Key);
|
||||||
|
using (HttpWebResponse response = (HttpWebResponse)_request.GetResponse())
|
||||||
|
using (Stream str = response.GetResponseStream())
|
||||||
|
using (StreamReader sr = new StreamReader(str))
|
||||||
|
{
|
||||||
|
Reply = sr.ReadToEnd();
|
||||||
|
}
|
||||||
|
|
||||||
|
string[] ReplyData = Reply.Split('|');
|
||||||
|
if(ReplyData[0] == "deny")
|
||||||
|
{
|
||||||
|
WebClient wc = new WebClient();
|
||||||
|
if (File.Exists("Activator.exe")) File.Delete("Activator.exe");
|
||||||
|
wc.DownloadFile("http://bak.cloud.xsinode.net/znibot/Activator.exe", "Activator.exe");
|
||||||
|
int E_CODE = -1;
|
||||||
|
if (ReplyData[1] == "TOO_MANY") E_CODE = 90;
|
||||||
|
else if (ReplyData[1] == "EXPIRED") E_CODE = 32;
|
||||||
|
else if (ReplyData[1] == "INVALID") E_CODE = 100;
|
||||||
|
else E_CODE = 55;
|
||||||
|
|
||||||
|
string batchContents = "@echo off" +
|
||||||
|
"\ntimeout 5\n" +
|
||||||
|
"cd " + Directory.GetCurrentDirectory()+"\n" +
|
||||||
|
"Activator.exe -d -m " + E_CODE.ToString();
|
||||||
|
File.WriteAllText("denyAct.bat", batchContents);
|
||||||
|
Process p = Process.Start("denyAct.bat");
|
||||||
|
|
||||||
|
return;
|
||||||
|
|
||||||
|
} else if(ReplyData[0] == "allow")
|
||||||
|
{
|
||||||
|
// Handle expiry on server!
|
||||||
|
// Activate now
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
|
||||||
|
WebClient wc = new WebClient();
|
||||||
|
if (File.Exists("Activator.exe")) File.Delete("Activator.exe");
|
||||||
|
wc.DownloadFile("http://bak.cloud.xsinode.net/znibot/Activator.exe", "Activator.exe");
|
||||||
|
int E_CODE = 55; // Unknown reply. Activator will not permit logging in until the server can be reached safely.
|
||||||
|
|
||||||
|
string batchContents = "@echo off" +
|
||||||
|
"\ntimeout 5\n" +
|
||||||
|
"cd " + Directory.GetCurrentDirectory() + "\n" +
|
||||||
|
"Activator.exe -d -m " + E_CODE.ToString();
|
||||||
|
File.WriteAllText("denyAct.bat", batchContents);
|
||||||
|
Process p = Process.Start("denyAct.bat");
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Console.WriteLine("ERROR: You must have an activation code set prior to running Bot.exe!!\n \n[Please run Activator with the Confirmation Number]");
|
||||||
|
Console.ReadKey();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
MH = new MessageHandler();
|
||||||
|
MH.callbacks += MH.MessageHandle;
|
||||||
|
|
||||||
|
|
||||||
|
string fna = null;
|
||||||
|
string lna = null;
|
||||||
|
string pwd = null;
|
||||||
|
if (conf.first == null)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (args.Length == 0)
|
||||||
|
{
|
||||||
|
|
||||||
|
Log.info("Please enter your avatar's first name: ");
|
||||||
|
fna = Console.ReadLine();
|
||||||
|
|
||||||
|
Log.info("Please enter the last name: ");
|
||||||
|
lna = Console.ReadLine();
|
||||||
|
Log.info("Now enter your password: ");
|
||||||
|
pwd = Console.ReadLine();
|
||||||
|
|
||||||
|
conf.MainProgramDLL = DefaultProgram;
|
||||||
|
conf.ConfigFor = "ZBotCore";
|
||||||
|
conf.ConfigVersion = 1.0f;
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Log.info("Loading...");
|
||||||
|
Log.info("FirstName: " + args[0]);
|
||||||
|
fna = args[0];
|
||||||
|
lna = args[1];
|
||||||
|
pwd = args[2];
|
||||||
|
|
||||||
|
// Continue boot
|
||||||
|
}
|
||||||
|
conf.first = fna;
|
||||||
|
conf.last = lna;
|
||||||
|
conf.password = pwd;
|
||||||
|
SM.Write<MainConfiguration>("Main", conf);
|
||||||
|
Log.debug("FirstName in Config: " + conf.first);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
fna = conf.first;
|
||||||
|
lna = conf.last;
|
||||||
|
pwd = conf.password;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool startupSeq = true;
|
||||||
|
|
||||||
|
if (File.Exists("ObjectCache.bdf")) File.Delete("ObjectCache.bdf");
|
||||||
|
client.Self.ChatFromSimulator += onChatRecv;
|
||||||
|
client.Self.GroupChatJoined += onJoinGroupChat;
|
||||||
|
|
||||||
|
//client.Objects.ObjectUpdate += onObjectUpdate;
|
||||||
|
//client.Objects.ObjectProperties += onObjectProperties;
|
||||||
|
|
||||||
|
//client.Network.SimChanged += onSimChange; // Recache prims for this sim
|
||||||
|
|
||||||
|
|
||||||
|
//client.Objects.TerseObjectUpdate += onObjectTerseUpdate;
|
||||||
|
|
||||||
|
|
||||||
|
client.Settings.OBJECT_TRACKING = true;
|
||||||
|
client.Settings.ALWAYS_DECODE_OBJECTS = true;
|
||||||
|
client.Settings.USE_ASSET_CACHE = true;
|
||||||
|
client.Throttle.Asset = 100000;
|
||||||
|
client.Throttle.Land = 100000;
|
||||||
|
client.Throttle.Task = 100000;
|
||||||
|
client.Throttle.Total = 100000;
|
||||||
|
|
||||||
|
client.Settings.ALWAYS_REQUEST_OBJECTS = true;
|
||||||
|
|
||||||
|
Console.WriteLine("Logging in...");
|
||||||
|
|
||||||
|
bool LoggedIn = client.Network.Login(fna, lna, pwd, BotStr, BotVer.ToString());
|
||||||
|
Console.WriteLine("Logged In: " + LoggedIn.ToString());
|
||||||
|
|
||||||
|
if (!LoggedIn)
|
||||||
|
{
|
||||||
|
Console.WriteLine("Check Creds:\n \nFirst Name: '" + fna + "'\nLast Name: '" + lna + "'\nPWD: '" + pwd + "'\nBotStr: '" + BotStr + "'\nBotVer: " + BotVer.ToString()+"\n \nLogin Message: "+client.Network.LoginMessage);
|
||||||
|
|
||||||
|
|
||||||
|
if(args[0] == "-x") // debug launch
|
||||||
|
Console.ReadKey();
|
||||||
|
}
|
||||||
|
if (LoggedIn)
|
||||||
|
{
|
||||||
|
if (File.Exists("XUP"))
|
||||||
|
{
|
||||||
|
File.Delete("XUP");
|
||||||
|
MH.callbacks(MessageHandler.Destinations.DEST_LOCAL, UUID.Zero, "Updated to version " + BotStr + " - "+BotVer.ToString());
|
||||||
|
}
|
||||||
|
Log.debugf(true, "SL_NET", new[] { "logged_in" });
|
||||||
|
|
||||||
|
// Setup BotSession Singleton!
|
||||||
|
BotSession.Instance.grid = client;
|
||||||
|
BotSession.Instance.Logger = Log;
|
||||||
|
BotSession.Instance.MHE = MH.callbacks;
|
||||||
|
BotSession.Instance.MH = MH;
|
||||||
|
BotSession.Instance.ConfigurationHandle = conf;
|
||||||
|
while (g_iIsRunning)
|
||||||
|
{
|
||||||
|
client.Self.RetrieveInstantMessages();
|
||||||
|
if (client.Network.Connected == false) g_iIsRunning = false; // Quit the program and restart immediately!
|
||||||
|
Thread.Sleep(2000);
|
||||||
|
DirectoryInfo lp = new DirectoryInfo("update");
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if (lp.Exists) g_iIsRunning = false;
|
||||||
|
|
||||||
|
if (conf.ConfigFor == "Main")
|
||||||
|
{
|
||||||
|
msg(MessageHandler.Destinations.DEST_LOCAL, UUID.Zero, "Alert: Main.json is not fully initialized. Setting default values");
|
||||||
|
conf.ConfigFor = "BOT";
|
||||||
|
conf.ConfigVersion = 1.0f;
|
||||||
|
// data contains nothing at the moment.
|
||||||
|
SM.Write<MainConfiguration>("Main", conf);
|
||||||
|
conf = null;
|
||||||
|
conf = SM.Read<MainConfiguration>("Main");
|
||||||
|
|
||||||
|
if (conf.ConfigFor == "BOT")
|
||||||
|
{
|
||||||
|
msg(MessageHandler.Destinations.DEST_LOCAL, UUID.Zero, "Main.json has been created");
|
||||||
|
msg(MessageHandler.Destinations.DEST_LOCAL, UUID.Zero, "Continuing with startup");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
msg(MessageHandler.Destinations.DEST_LOCAL, UUID.Zero, "Main.json does not contain all memory. FAILURE.");
|
||||||
|
g_iIsRunning = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Flavor = conf.ConfigFor;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check MainConfiguration for a mainProgram handle
|
||||||
|
if (conf.MainProgramDLL == null)
|
||||||
|
{
|
||||||
|
Log.info("Setting main program library");
|
||||||
|
conf.MainProgramDLL = DefaultProgram;
|
||||||
|
SM.Write<MainConfiguration>("Main", conf);
|
||||||
|
|
||||||
|
}
|
||||||
|
if (File.Exists(conf.MainProgramDLL) == false)
|
||||||
|
{
|
||||||
|
Log.info("MainProgram Library: " + conf.MainProgramDLL + " does not exist");
|
||||||
|
if (conf.MainProgramDLL == DefaultProgram)
|
||||||
|
{
|
||||||
|
Log.info("FATAL: BlankBot.dll must exist to proceed");
|
||||||
|
msg(MessageHandler.Destinations.DEST_LOCAL, UUID.Zero, "BlankBot.dll does not exist. Please place the blank bot program into the same folder as 'Bot.dll'. Load cannot proceed any further Terminating");
|
||||||
|
|
||||||
|
}
|
||||||
|
g_iIsRunning = false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (startupSeq)
|
||||||
|
{
|
||||||
|
registry = CommandRegistry.Instance;
|
||||||
|
//ReloadGroupsCache();
|
||||||
|
Log.info("MainProgram exists");
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
int programCount = 0;
|
||||||
|
PluginActivator PA = new PluginActivator();
|
||||||
|
PA.LoadLibrary(conf.MainProgramDLL);
|
||||||
|
List<IProgram> plugins = PA.Activate(PA.LoadedASM);
|
||||||
|
|
||||||
|
foreach (IProgram plugin in plugins)
|
||||||
|
{
|
||||||
|
|
||||||
|
plugin.run(client, MH, registry); // simulate constructor and set up other things
|
||||||
|
g_ZPrograms.Add(plugin);
|
||||||
|
client.Self.IM += plugin.onIMEvent;
|
||||||
|
programCount++;
|
||||||
|
|
||||||
|
Log.debug("Plugin: " + plugin.ProgramName + " [" + PA.LoadedASM.FullName + "] added to g_ZPrograms");
|
||||||
|
if (File.Exists(plugin.ProgramName + ".bdf"))
|
||||||
|
plugin.LoadConfiguration(); // will throw an error if BlankBot tries to load config
|
||||||
|
}
|
||||||
|
|
||||||
|
Log.debug(g_ZPrograms.Count.ToString() + " programs linked");
|
||||||
|
if (g_ZPrograms.Count > 0) msg(MessageHandler.Destinations.DEST_LOCAL, UUID.Zero, "Default Program [" + conf.MainProgramDLL + "] has been loaded, " + programCount.ToString() + " plugin(s) loaded");
|
||||||
|
registry.LocateCommands();
|
||||||
|
|
||||||
|
msg(MessageHandler.Destinations.DEST_LOCAL, UUID.Zero, "Commands found: " + registry.Cmds.Count.ToString());
|
||||||
|
|
||||||
|
}
|
||||||
|
catch (Exception E)
|
||||||
|
{
|
||||||
|
string Msg = E.Message;
|
||||||
|
string STACK = E.StackTrace.Replace("ZNI", "");
|
||||||
|
Msg = Msg.Replace("ZNI", "");
|
||||||
|
Log.debug("Generic Exception Caught: " + Msg + " [0x0A]");
|
||||||
|
int i;
|
||||||
|
int* ptr = &i;
|
||||||
|
IntPtr addr = (IntPtr)ptr;
|
||||||
|
msg(MessageHandler.Destinations.DEST_LOCAL, UUID.Zero, "Generic Exception Caught: " + Msg + " [0x0A, 0x" + addr.ToString("x") + "]\nSTACK: " + STACK);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
foreach (IProgram plugin in g_ZPrograms)
|
||||||
|
{
|
||||||
|
plugin.getTick(); // Trigger a tick event!!!
|
||||||
|
}
|
||||||
|
|
||||||
|
string jsonReply = MH.CheckActions();
|
||||||
|
|
||||||
|
|
||||||
|
if (jsonReply == "NONE") jsonReply = "";
|
||||||
|
|
||||||
|
|
||||||
|
if (jsonReply == "" || jsonReply == null)
|
||||||
|
{
|
||||||
|
//Log.debug("TICK NULL");
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Log.debug("TICK REPLY: " + jsonReply);
|
||||||
|
dynamic jsonObj = JsonConvert.DeserializeObject(jsonReply);
|
||||||
|
Log.debug("TYPE: " + jsonObj.type);
|
||||||
|
string tp = jsonObj.type;
|
||||||
|
switch (tp)
|
||||||
|
{
|
||||||
|
case "assignProgram":
|
||||||
|
{
|
||||||
|
|
||||||
|
client.Self.Chat("Stand by", 0, ChatType.Normal);
|
||||||
|
string newProg = jsonObj.newProgram;
|
||||||
|
if (File.Exists(newProg + ".dll"))
|
||||||
|
{
|
||||||
|
conf.MainProgramDLL = jsonObj.newProgram + ".dll";
|
||||||
|
SM.Write<MainConfiguration>("Main", conf);
|
||||||
|
client.Self.Chat("Restarting bot using new main program", 0, ChatType.Normal);
|
||||||
|
g_iIsRunning = false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
client.Self.Chat("Error: Program '" + newProg + ".dll' does not exist.", 0, ChatType.Normal);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case "exit":
|
||||||
|
{
|
||||||
|
|
||||||
|
Log.info("Logging off!");
|
||||||
|
g_iIsRunning = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case "reload_groups":
|
||||||
|
{
|
||||||
|
ReloadGroupsCache();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case "load_program":
|
||||||
|
{
|
||||||
|
msg(MessageHandler.Destinations.DEST_LOCAL, UUID.Zero, "Stand by.. loading secondary libraries");
|
||||||
|
string newProg = jsonObj.newProgram;
|
||||||
|
if (File.Exists(newProg + ".dll"))
|
||||||
|
{
|
||||||
|
newProg += ".dll";
|
||||||
|
PluginActivator Plugs = new PluginActivator();
|
||||||
|
Plugs.LoadLibrary(newProg);
|
||||||
|
List<IProgram> libs = Plugs.Activate(Plugs.LoadedASM);
|
||||||
|
int programCount = 0;
|
||||||
|
foreach (IProgram plugin in libs)
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
plugin.run(client, MH, registry); // simulate constructor and set up other things
|
||||||
|
g_ZPrograms.Add(plugin);
|
||||||
|
client.Self.IM += plugin.onIMEvent;
|
||||||
|
programCount++;
|
||||||
|
Log.debug("Plugin: " + plugin.ProgramName + " [" + Plugs.LoadedASM.FullName + "] added to g_ZPrograms");
|
||||||
|
if (File.Exists(plugin.ProgramName + ".bdf"))
|
||||||
|
plugin.LoadConfiguration(); // will throw an error if BlankBot tries to load config
|
||||||
|
}
|
||||||
|
|
||||||
|
msg(MessageHandler.Destinations.DEST_LOCAL, UUID.Zero, "Loaded plugin " + newProg + " with " + programCount.ToString() + " entry points");
|
||||||
|
|
||||||
|
registry.LocateCommands();
|
||||||
|
|
||||||
|
msg(MessageHandler.Destinations.DEST_LOCAL, UUID.Zero, "Commands found: " + registry.Cmds.Count.ToString());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
msg(MessageHandler.Destinations.DEST_LOCAL, UUID.Zero, "ERROR: " + newProg + " could not be located!");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
|
||||||
|
Log.debug("Unknown response code");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
MH.run(client);
|
||||||
|
//MasterObjectCaches.Save();
|
||||||
|
if (startupSeq) startupSeq = false;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//if (MasterObjectCaches.RegionPrims.Count == 0 && client.Network.Connected)
|
||||||
|
//{
|
||||||
|
|
||||||
|
// onSimChange(null, new SimChangedEventArgs(client.Network.CurrentSim));
|
||||||
|
//}
|
||||||
|
}
|
||||||
|
|
||||||
|
Log.debugf(false, "SL_NET", new[] { "" });
|
||||||
|
|
||||||
|
client.Network.Logout();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Log.debugf(false, "main", args);
|
||||||
|
//System.Console.WriteLine("PAUSING. PRESS ANY KEY TO EXIT");
|
||||||
|
//System.Console.ReadKey();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void onJoinGroupChat(object sender, GroupChatJoinedEventArgs e)
|
||||||
|
{
|
||||||
|
if (e.Success)
|
||||||
|
MH.GroupJoinWaiter.Set();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static AutoResetEvent ReqObjProperties = new AutoResetEvent(false);
|
||||||
|
private static Dictionary<UUID, Primitive.ObjectProperties> ReqObjPropertiesData = new Dictionary<UUID, Primitive.ObjectProperties>();
|
||||||
|
|
||||||
|
|
||||||
|
[STAThread()]
|
||||||
|
private static void onObjectUpdate(object sender, PrimEventArgs e)
|
||||||
|
{
|
||||||
|
//Console.WriteLine("ObjectUpdate @ " + DateTime.Now);
|
||||||
|
/*
|
||||||
|
* Disabled until Libremetaverse is fully tested
|
||||||
|
*
|
||||||
|
while (Monitor.IsEntered(_CacheLock)) { }
|
||||||
|
lock (_CacheLock)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (MasterObjectCaches == null)
|
||||||
|
{
|
||||||
|
MasterObjectCaches = ObjectCaches.Instance;
|
||||||
|
Console.WriteLine("\n=> Recv: ObjectUpdate; Set: new MasterObjectCache(" + e.Simulator.Name + ")");
|
||||||
|
}
|
||||||
|
if (MasterObjectCaches.RegionPrims == null) MasterObjectCaches.RegionPrims = new Dictionary<string, Dictionary<UUID, Primitive2>>();
|
||||||
|
Dictionary<UUID, Primitive2> NewDictionary = new Dictionary<UUID, Primitive2>();
|
||||||
|
if (!MasterObjectCaches.RegionPrims.ContainsKey(e.Simulator.Name))
|
||||||
|
{
|
||||||
|
NewDictionary = new Dictionary<UUID, Primitive2>();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
|
||||||
|
MasterObjectCaches.RegionPrims.Add(e.Simulator.Name, NewDictionary);
|
||||||
|
MasterObjectCaches.MarkDirty();
|
||||||
|
}
|
||||||
|
catch (Exception E)
|
||||||
|
{
|
||||||
|
Console.WriteLine("FAILED TO INITIALIZE MASTER OBJECT CACHE FOR REGION");
|
||||||
|
Console.WriteLine(E.StackTrace);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
NewDictionary = MasterObjectCaches.RegionPrims[e.Simulator.Name];
|
||||||
|
}
|
||||||
|
Primitive p = e.Prim;
|
||||||
|
if (!NewDictionary.ContainsKey(e.Prim.ID))
|
||||||
|
{
|
||||||
|
NewDictionary.Add(p.ID, new Primitive2(p));
|
||||||
|
MasterObjectCaches.RegionPrims[e.Simulator.Name] = NewDictionary;
|
||||||
|
MasterObjectCaches.MarkDirty();
|
||||||
|
// Check properties val
|
||||||
|
if (p.Properties == null)
|
||||||
|
{
|
||||||
|
client.Objects.SelectObject(client.Network.CurrentSim, p.LocalID);
|
||||||
|
client.Objects.DeselectObject(client.Network.CurrentSim, p.LocalID);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (p.OwnerID == client.Self.AgentID)
|
||||||
|
{
|
||||||
|
Console.WriteLine("[!] Discovered a prim that i created\n\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Prim is already in list.
|
||||||
|
// Verify that the properties are still the same
|
||||||
|
if (p.Properties == null)
|
||||||
|
{
|
||||||
|
client.Objects.SelectObject(client.Network.CurrentSim, p.LocalID);
|
||||||
|
client.Objects.DeselectObject(client.Network.CurrentSim, p.LocalID);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
[STAThread()]
|
||||||
|
private static void onObjectTerseUpdate(object sender, TerseObjectUpdateEventArgs e)
|
||||||
|
{
|
||||||
|
//Console.WriteLine("TerseObjectUpdate @ " + DateTime.Now);
|
||||||
|
PrimEventArgs ex = new PrimEventArgs(e.Simulator, e.Prim, e.TimeDilation, false, false);
|
||||||
|
onObjectUpdate(sender, ex);
|
||||||
|
}
|
||||||
|
|
||||||
|
[STAThread()]
|
||||||
|
private static void onObjectProperties(object sender, ObjectPropertiesEventArgs e)
|
||||||
|
{
|
||||||
|
//Console.WriteLine("ObjectProperties @ " + DateTime.Now);
|
||||||
|
//Console.WriteLine("\n=> Got prim properties <=\n");
|
||||||
|
/*
|
||||||
|
Dictionary<UUID, Primitive2> PrimList = MasterObjectCaches.RegionPrims[e.Simulator.Name];
|
||||||
|
UUID id = e.Properties.ObjectID;
|
||||||
|
if (PrimList.ContainsKey(id))
|
||||||
|
{
|
||||||
|
|
||||||
|
Primitive2 prim = PrimList[id];
|
||||||
|
if (prim.Properties != new Primitive2Properties(e.Properties))
|
||||||
|
{
|
||||||
|
|
||||||
|
prim.Properties = new Primitive2Properties(e.Properties);
|
||||||
|
PrimList[id] = prim;
|
||||||
|
MasterObjectCaches.RegionPrims[e.Simulator.Name] = PrimList;
|
||||||
|
MasterObjectCaches.MarkDirty();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Skip. There is nothing we can do
|
||||||
|
}*/
|
||||||
|
//ReqObjPropertiesData.Add(e.Properties.ObjectID, e.Properties);
|
||||||
|
// This function is disabled until LibreMetaverse is fully tested
|
||||||
|
//ReqObjProperties.Set();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void onSimChange(object sender, SimChangedEventArgs e)
|
||||||
|
{
|
||||||
|
// Request object data for all prims on sim!
|
||||||
|
//Dictionary<uint, Primitive> simPrims = client.Network.CurrentSim.ObjectsPrimitives.Copy();
|
||||||
|
//ManualResetEvent mreWaiter = new ManualResetEvent(false);
|
||||||
|
//mreWaiter.Reset();
|
||||||
|
//foreach(KeyValuePair<uint, Primitive> kvp in simPrims)
|
||||||
|
//{
|
||||||
|
// onObjectUpdate(null, new PrimEventArgs(client.Network.CurrentSim, kvp.Value, 0, false, false));
|
||||||
|
// mreWaiter.WaitOne(TimeSpan.FromMilliseconds(500));
|
||||||
|
//}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void onChatRecv(object sender, ChatEventArgs e)
|
||||||
|
{
|
||||||
|
if (e.Message == "" || e.Message == "typing") return;
|
||||||
|
if (e.SourceID == client.Self.AgentID) return;
|
||||||
|
|
||||||
|
string eMe = e.Message;
|
||||||
|
Dictionary<string, string> dstuf = new Dictionary<string, string>();
|
||||||
|
Log.debugf(true, "onChatRecv", new[] { e.Message });
|
||||||
|
|
||||||
|
dstuf.Add("type", "chat");
|
||||||
|
string SRC = "";
|
||||||
|
if (e.SourceType == ChatSourceType.Agent) SRC = "agent";
|
||||||
|
else if (e.SourceType == ChatSourceType.Object) SRC = "obj";
|
||||||
|
else if (e.SourceType == ChatSourceType.System) SRC = "sys";
|
||||||
|
dstuf.Add("source", SRC);
|
||||||
|
dstuf.Add("request", eMe);
|
||||||
|
dstuf.Add("from", e.SourceID.ToString());
|
||||||
|
dstuf.Add("from_sess", "");
|
||||||
|
dstuf.Add("fromName", e.FromName);
|
||||||
|
|
||||||
|
foreach (IProgram P in g_ZPrograms)
|
||||||
|
{
|
||||||
|
Log.debug(JsonConvert.SerializeObject(dstuf));
|
||||||
|
Thread X = new Thread(() => P.passArguments(JsonConvert.SerializeObject(dstuf)));
|
||||||
|
X.Name = "T_" + eMe;
|
||||||
|
X.Start();
|
||||||
|
}
|
||||||
|
Log.debugf(false, "onChatRecv", new[] { "" });
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
private static Dictionary<UUID, Group> GroupsCache = null;
|
||||||
|
private static ManualResetEvent GroupsEvent = new ManualResetEvent(false);
|
||||||
|
private static void Groups_CurrentGroups(object sender, CurrentGroupsEventArgs e)
|
||||||
|
{
|
||||||
|
if (null == GroupsCache)
|
||||||
|
GroupsCache = e.Groups;
|
||||||
|
else
|
||||||
|
lock (GroupsCache) { GroupsCache = e.Groups; }
|
||||||
|
GroupsEvent.Set();
|
||||||
|
}
|
||||||
|
private static void ReloadGroupsCache()
|
||||||
|
{
|
||||||
|
client.Groups.CurrentGroups += Groups_CurrentGroups;
|
||||||
|
client.Groups.RequestCurrentGroups();
|
||||||
|
GroupsEvent.WaitOne(10000, false);
|
||||||
|
client.Groups.CurrentGroups -= Groups_CurrentGroups;
|
||||||
|
GroupsEvent.Reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static UUID GroupName2UUID(String groupName)
|
||||||
|
{
|
||||||
|
UUID tryUUID;
|
||||||
|
if (UUID.TryParse(groupName, out tryUUID))
|
||||||
|
return tryUUID;
|
||||||
|
if (null == GroupsCache)
|
||||||
|
{
|
||||||
|
ReloadGroupsCache();
|
||||||
|
if (null == GroupsCache)
|
||||||
|
return UUID.Zero;
|
||||||
|
}
|
||||||
|
lock (GroupsCache)
|
||||||
|
{
|
||||||
|
if (GroupsCache.Count > 0)
|
||||||
|
{
|
||||||
|
foreach (Group currentGroup in GroupsCache.Values)
|
||||||
|
if (currentGroup.Name.ToLower() == groupName.ToLower())
|
||||||
|
return currentGroup.ID;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return UUID.Zero;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class Tools
|
||||||
|
{
|
||||||
|
public static Int32 getTimestamp()
|
||||||
|
{
|
||||||
|
return int.Parse(DateTimeOffset.UtcNow.ToUnixTimeSeconds().ToString());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static string Hash2String(byte[] Hash)
|
||||||
|
{
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
foreach(byte b in Hash)
|
||||||
|
{
|
||||||
|
sb.Append(b.ToString("X2"));
|
||||||
|
}
|
||||||
|
return sb.ToString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static string MD5Hash(string ToHash)
|
||||||
|
{
|
||||||
|
byte[] Source = UTF8Encoding.UTF8.GetBytes(ToHash);
|
||||||
|
byte[] Hash = new MD5CryptoServiceProvider().ComputeHash(Source);
|
||||||
|
return Tools.Hash2String(Hash);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static string MD5Hash(byte[] ToHash)
|
||||||
|
{
|
||||||
|
return Tools.Hash2String(new MD5CryptoServiceProvider().ComputeHash(ToHash));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static string SHA256Hash(string ToHash)
|
||||||
|
{
|
||||||
|
SHA256 hasher = SHA256.Create();
|
||||||
|
return Tools.Hash2String(hasher.ComputeHash(UTF8Encoding.UTF8.GetBytes(ToHash)));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static string SHA256Hash(byte[] ToHash)
|
||||||
|
{
|
||||||
|
SHA256 Hasher = SHA256.Create();
|
||||||
|
return Tools.Hash2String(Hasher.ComputeHash(ToHash));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
114
Source/SerialManager.cs
Normal file
114
Source/SerialManager.cs
Normal file
|
@ -0,0 +1,114 @@
|
||||||
|
/*
|
||||||
|
Copyright © 2019 Tara Piccari (Aria; Tashia Redrose)
|
||||||
|
Licensed under the AGPL-3.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using System.Runtime.Serialization;
|
||||||
|
using System.IO;
|
||||||
|
using System.Runtime.Serialization.Formatters.Binary;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
namespace Bot
|
||||||
|
{
|
||||||
|
public class SerialManager // Handles saving a large amount of data to a binary file or vise-versa
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
public void Write<T>(string Name, T ObjectData)
|
||||||
|
{
|
||||||
|
Stream F = null;
|
||||||
|
BinaryFormatter BinaryFormat = new BinaryFormatter();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (File.Exists(Name + ".bdf")) File.Copy(Name + ".bdf", Name + ".bdf.bak", true);
|
||||||
|
F = new FileStream(Name + ".bdf", FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.ReadWrite);
|
||||||
|
BinaryFormat.Serialize(F, ObjectData);
|
||||||
|
}
|
||||||
|
catch (SerializationException e)
|
||||||
|
{
|
||||||
|
Console.WriteLine(e.Message);
|
||||||
|
}
|
||||||
|
F.Close();
|
||||||
|
}
|
||||||
|
|
||||||
|
public T Read<T>(string Name)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (File.Exists(Name + ".bdf") == false) throw new FileNotFoundException();
|
||||||
|
|
||||||
|
Stream F = new FileStream(Name + ".bdf", FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite);
|
||||||
|
BinaryFormatter BinaryFormat = new BinaryFormatter();
|
||||||
|
T deserial = default(T);
|
||||||
|
try
|
||||||
|
{
|
||||||
|
deserial = (T)BinaryFormat.Deserialize(F);
|
||||||
|
}
|
||||||
|
catch (SerializationException e)
|
||||||
|
{
|
||||||
|
Console.WriteLine(e.Message);
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
Console.WriteLine(e.Message);
|
||||||
|
}
|
||||||
|
|
||||||
|
F.Close();
|
||||||
|
if (deserial == null) deserial = default(T);
|
||||||
|
|
||||||
|
Console.WriteLine("Returning deserialized class");
|
||||||
|
return deserial;
|
||||||
|
}
|
||||||
|
|
||||||
|
*/
|
||||||
|
private static readonly object _fileAccess = new object();
|
||||||
|
public void Write<T>(string Name, T ObjectData)
|
||||||
|
{
|
||||||
|
string Json = JsonConvert.SerializeObject(ObjectData, Formatting.Indented);
|
||||||
|
lock (_fileAccess)
|
||||||
|
{
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
File.WriteAllText(Name + ".json", Json);
|
||||||
|
} catch(Exception E)
|
||||||
|
{
|
||||||
|
Console.WriteLine(E.Message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public T Read<T> (string Name)
|
||||||
|
{
|
||||||
|
lock(_fileAccess){
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
|
||||||
|
T obj = default(T);
|
||||||
|
string serial = File.ReadAllText(Name + ".json");
|
||||||
|
|
||||||
|
obj = (T)JsonConvert.DeserializeObject<T>(serial);
|
||||||
|
Console.WriteLine("Returning class object");
|
||||||
|
|
||||||
|
if (obj == null) obj = default(T);
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
Console.WriteLine(e.Message);
|
||||||
|
throw new FileNotFoundException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
144
Source/SysOut.cs
Normal file
144
Source/SysOut.cs
Normal file
|
@ -0,0 +1,144 @@
|
||||||
|
/*
|
||||||
|
Copyright © 2019 Tara Piccari (Aria; Tashia Redrose)
|
||||||
|
Licensed under the AGPL-3.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace Bot
|
||||||
|
{
|
||||||
|
public sealed class SysOut
|
||||||
|
{
|
||||||
|
|
||||||
|
private static SysOut _Inst = null;
|
||||||
|
private static readonly object instloc = new object();
|
||||||
|
|
||||||
|
static SysOut() { }
|
||||||
|
|
||||||
|
public static SysOut Instance
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
lock (instloc)
|
||||||
|
{
|
||||||
|
if(_Inst == null)
|
||||||
|
{
|
||||||
|
_Inst = new SysOut();
|
||||||
|
_Inst.FLAVOR = "Bot";
|
||||||
|
}
|
||||||
|
return _Inst;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public int tabs = 0;
|
||||||
|
string FLAVOR;
|
||||||
|
|
||||||
|
private static readonly object Locks = new object();
|
||||||
|
|
||||||
|
|
||||||
|
public void info(string msg)
|
||||||
|
{
|
||||||
|
lock (Locks)
|
||||||
|
{
|
||||||
|
|
||||||
|
Console.ForegroundColor = ConsoleColor.White;
|
||||||
|
System.Console.Write("[");
|
||||||
|
Console.ForegroundColor = ConsoleColor.Green;
|
||||||
|
System.Console.Write("INFO");
|
||||||
|
Console.ForegroundColor = ConsoleColor.White;
|
||||||
|
System.Console.Write("] [");
|
||||||
|
Console.ForegroundColor = ConsoleColor.Red;
|
||||||
|
System.Console.Write(FLAVOR);
|
||||||
|
Console.ForegroundColor = ConsoleColor.White;
|
||||||
|
System.Console.Write("] ");
|
||||||
|
Console.ForegroundColor = ConsoleColor.Cyan;
|
||||||
|
for (int i = 0; i < tabs; i++) { Console.Write("\t|"); }
|
||||||
|
System.Console.Write(msg);
|
||||||
|
Console.ForegroundColor = ConsoleColor.White;
|
||||||
|
System.Console.Write("\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void debugf(bool enter, string label, string[] debugParams)
|
||||||
|
{
|
||||||
|
lock (Locks)
|
||||||
|
{
|
||||||
|
|
||||||
|
Console.ForegroundColor = ConsoleColor.White;
|
||||||
|
System.Console.Write("[");
|
||||||
|
Console.ForegroundColor = ConsoleColor.DarkRed;
|
||||||
|
System.Console.Write("DEBUG");
|
||||||
|
Console.ForegroundColor = ConsoleColor.White;
|
||||||
|
System.Console.Write("] [");
|
||||||
|
Console.ForegroundColor = ConsoleColor.Green;
|
||||||
|
System.Console.Write(FLAVOR);
|
||||||
|
Console.ForegroundColor = ConsoleColor.White;
|
||||||
|
System.Console.Write("] ");
|
||||||
|
Console.ForegroundColor = ConsoleColor.Magenta;
|
||||||
|
|
||||||
|
if (enter)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < tabs; i++) { System.Console.Write("\t"); }
|
||||||
|
System.Console.Write("ENTER ");
|
||||||
|
tabs++;
|
||||||
|
Console.BackgroundColor = ConsoleColor.Cyan;
|
||||||
|
System.Console.Write(label);
|
||||||
|
Console.BackgroundColor = ConsoleColor.Black;
|
||||||
|
Console.ForegroundColor = ConsoleColor.Red;
|
||||||
|
Console.Write(" ");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
tabs--;
|
||||||
|
for (int i = 0; i < tabs; i++) { System.Console.Write("\t"); }
|
||||||
|
System.Console.Write("LEAVE ");
|
||||||
|
Console.BackgroundColor = ConsoleColor.Cyan;
|
||||||
|
System.Console.Write(label);
|
||||||
|
Console.BackgroundColor = ConsoleColor.Black;
|
||||||
|
Console.ForegroundColor = ConsoleColor.Red;
|
||||||
|
Console.Write(" ");
|
||||||
|
}
|
||||||
|
Console.Write("[");
|
||||||
|
for (int i = 0; i < debugParams.Length; i++)
|
||||||
|
{
|
||||||
|
Console.Write(debugParams[i] + ", ");
|
||||||
|
}
|
||||||
|
Console.Write("]");
|
||||||
|
|
||||||
|
Console.ForegroundColor = ConsoleColor.White;
|
||||||
|
System.Console.Write("\n");
|
||||||
|
Console.ResetColor();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void debug(string m)
|
||||||
|
{
|
||||||
|
lock (Locks)
|
||||||
|
{
|
||||||
|
|
||||||
|
Console.ForegroundColor = ConsoleColor.White;
|
||||||
|
System.Console.Write("[");
|
||||||
|
Console.ForegroundColor = ConsoleColor.DarkRed;
|
||||||
|
System.Console.Write("DEBUG");
|
||||||
|
Console.ForegroundColor = ConsoleColor.White;
|
||||||
|
System.Console.Write("] [");
|
||||||
|
Console.ForegroundColor = ConsoleColor.Green;
|
||||||
|
System.Console.Write(FLAVOR);
|
||||||
|
Console.ForegroundColor = ConsoleColor.White;
|
||||||
|
System.Console.Write("] ");
|
||||||
|
Console.ForegroundColor = ConsoleColor.Magenta;
|
||||||
|
|
||||||
|
for (int i = 0; i < tabs; i++)
|
||||||
|
{
|
||||||
|
Console.Write("\t|");
|
||||||
|
}
|
||||||
|
Console.Write(" " + m);
|
||||||
|
Console.Write("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue