Port from bitbucket
This commit is contained in:
commit
4ce4c1b769
156 changed files with 8779 additions and 0 deletions
24
.dockerignore
Normal file
24
.dockerignore
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
**/.classpath
|
||||
**/.dockerignore
|
||||
**/.env
|
||||
**/.gitignore
|
||||
**/.project
|
||||
**/.settings
|
||||
**/.toolstarget
|
||||
**/.vs
|
||||
**/.vscode
|
||||
**/*.*proj.user
|
||||
**/*.dbmdl
|
||||
**/*.jfm
|
||||
**/azds.yaml
|
||||
**/bin
|
||||
**/charts
|
||||
**/docker-compose*
|
||||
**/Dockerfile*
|
||||
**/node_modules
|
||||
**/npm-debug.log
|
||||
**/obj
|
||||
**/secrets.dev.yaml
|
||||
**/values.dev.yaml
|
||||
LICENSE
|
||||
README.md
|
||||
23
.gitignore
vendored
Normal file
23
.gitignore
vendored
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
compile.bat
|
||||
*.user
|
||||
*.userprefs
|
||||
*.suo
|
||||
*.cache
|
||||
*.pfx
|
||||
|
||||
[Oo]bj/
|
||||
[Bb]in/
|
||||
packages/
|
||||
.idea/
|
||||
.vs/
|
||||
/Programs/examples/TestClient/Properties/launchSettings.json
|
||||
.appveyor.yml
|
||||
LICENSE.txt
|
||||
mapgen.bat
|
||||
PrimMesher/
|
||||
Programs/
|
||||
BetterSecondBot/publish
|
||||
Publish/
|
||||
secondbotr5.json
|
||||
CLI/settings.env
|
||||
CLI/Dockerfile
|
||||
154
BSBshared/API/API_interface.cs
Normal file
154
BSBshared/API/API_interface.cs
Normal file
|
|
@ -0,0 +1,154 @@
|
|||
using BetterSecondBotShared.logs;
|
||||
using OpenMetaverse;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace BetterSecondBotShared.API
|
||||
{
|
||||
public abstract class API_interface
|
||||
{
|
||||
public string CommandName { get { return GetType().Name.ToLowerInvariant(); } }
|
||||
public virtual int MinArgs { get { return 0; } }
|
||||
public virtual string Helpfile { get { return "No help given"; } }
|
||||
public virtual string[] ArgTypes { get { return new string[] { }; } }
|
||||
public virtual string[] ArgHints { get { return new string[] { }; } }
|
||||
}
|
||||
|
||||
public class API_supported_interface
|
||||
{
|
||||
protected Type API_type;
|
||||
protected Dictionary<string, Type> subtype_map = new Dictionary<string, Type>();
|
||||
protected Dictionary<string, string> subtype_workspace_map = new Dictionary<string, string>();
|
||||
public virtual int ApiCommandsCount { get { return subtype_map.Count(); } }
|
||||
|
||||
protected API_interface GetCommand(string command)
|
||||
{
|
||||
if (KnownCommand(command) == true)
|
||||
{
|
||||
return Activator.CreateInstance(subtype_map[command]) as API_interface;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
protected virtual void LoadCommandsList()
|
||||
{
|
||||
foreach (var com in GetAPICommandClasses())
|
||||
{
|
||||
if (com != null)
|
||||
{
|
||||
if (com.IsAbstract == false)
|
||||
{
|
||||
API_interface D = (API_interface)Activator.CreateInstance(com);
|
||||
if (D != null)
|
||||
{
|
||||
if (subtype_map.ContainsKey(D.CommandName) == false)
|
||||
{
|
||||
string worknamespace = com.Namespace;
|
||||
worknamespace = worknamespace.Replace("BSB.Commands.", "");
|
||||
worknamespace = worknamespace.Replace("BSB.RLV.", "");
|
||||
worknamespace = worknamespace.Replace("BetterSecondBot.HttpServer.View.", "");
|
||||
worknamespace = worknamespace.Replace("BetterSecondBot.HttpServer.Control.", "");
|
||||
worknamespace = worknamespace.Replace("CMD_", "");
|
||||
subtype_map.Add(D.CommandName, D.GetType());
|
||||
subtype_workspace_map.Add(D.CommandName, worknamespace);
|
||||
}
|
||||
else
|
||||
{
|
||||
ConsoleLog.Crit("[CMD] command: " + D.CommandName + " already defined!");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
protected IEnumerable<Type> GetAPICommandClasses()
|
||||
{
|
||||
if (API_type != null)
|
||||
{
|
||||
return AppDomain.CurrentDomain.GetAssemblies().Where(Ass => {
|
||||
bool reply = false;
|
||||
if (Ass.FullName.StartsWith("BSB") == true) { reply = true; }
|
||||
else if (Ass.FullName.StartsWith("BetterSecondBot") == true){ reply = true; }
|
||||
return reply;
|
||||
}).SelectMany(assembly => assembly.GetTypes()).Where(type => type.IsSubclassOf(API_type));
|
||||
}
|
||||
else
|
||||
{
|
||||
ConsoleLog.Crit(this.GetType() + " Attempted to call GetSubTypes without setting API_TYPE first!");
|
||||
}
|
||||
return null;
|
||||
}
|
||||
public virtual string[] GetCommandsList()
|
||||
{
|
||||
return subtype_map.Keys.ToArray<string>();
|
||||
}
|
||||
public virtual string GetCommandWorkspace(string cmd)
|
||||
{
|
||||
if (subtype_workspace_map.ContainsKey(cmd) == true)
|
||||
{
|
||||
return subtype_workspace_map[cmd];
|
||||
}
|
||||
return "";
|
||||
}
|
||||
protected virtual bool KnownCommand(string command)
|
||||
{
|
||||
if (subtype_map.Count() == 0)
|
||||
{
|
||||
LoadCommandsList();
|
||||
}
|
||||
return subtype_map.ContainsKey(command);
|
||||
}
|
||||
|
||||
public virtual string GetCommandHelp(string cmd)
|
||||
{
|
||||
API_interface cmdGet = GetCommand(cmd);
|
||||
if (cmdGet != null)
|
||||
{
|
||||
return cmdGet.Helpfile;
|
||||
}
|
||||
return "None given";
|
||||
}
|
||||
public virtual int GetCommandArgs(string cmd)
|
||||
{
|
||||
API_interface cmdGet = GetCommand(cmd);
|
||||
if (cmdGet != null)
|
||||
{
|
||||
return cmdGet.MinArgs;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
public virtual string[] GetCommandArgTypes(string cmd)
|
||||
{
|
||||
API_interface CmdGet = GetCommand(cmd);
|
||||
if (CmdGet != null)
|
||||
{
|
||||
return CmdGet.ArgTypes;
|
||||
}
|
||||
return new string[] { };
|
||||
}
|
||||
public virtual string[] GetCommandArgHints(string cmd)
|
||||
{
|
||||
API_interface CmdGet = GetCommand(cmd);
|
||||
if (CmdGet != null)
|
||||
{
|
||||
return CmdGet.ArgHints;
|
||||
}
|
||||
return new string[] { };
|
||||
}
|
||||
|
||||
public virtual List<string> GetAllWorkspaces()
|
||||
{
|
||||
List<string> reply = new List<string>();
|
||||
foreach (string c in GetCommandsList())
|
||||
{
|
||||
string workspace = GetCommandWorkspace(c);
|
||||
if (reply.Contains(workspace) == false)
|
||||
{
|
||||
reply.Add(workspace);
|
||||
}
|
||||
}
|
||||
return reply;
|
||||
}
|
||||
}
|
||||
}
|
||||
24
BSBshared/BSBshared.csproj
Normal file
24
BSBshared/BSBshared.csproj
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netcoreapp3.1</TargetFramework>
|
||||
<Configurations>Debug;Release;DockerBuild</Configurations>
|
||||
<Platforms>x64</Platforms>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DockerBuild|x64'">
|
||||
<ErrorReport>none</ErrorReport>
|
||||
<DockerDefaultTargetOS>Linux</DockerDefaultTargetOS>
|
||||
<PublishTrimmed>false</PublishTrimmed>
|
||||
<PublishSingleFile>false</PublishSingleFile>
|
||||
<TreatWarningsAsErrors>false</TreatWarningsAsErrors>
|
||||
<RuntimeIdentifier>linux-x64</RuntimeIdentifier>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\libremetaverse-core\Libremetaverse.structureddata\LibreMetaverse.StructuredData.csproj" />
|
||||
<ProjectReference Include="..\libremetaverse-core\Libremetaversetypes\LibreMetaverse.Types.csproj" />
|
||||
<ProjectReference Include="..\libremetaverse-core\Libremetaverse\LibreMetaverse.csproj" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
|
||||
188
BSBshared/BotTypes/BasicBot.cs
Normal file
188
BSBshared/BotTypes/BasicBot.cs
Normal file
|
|
@ -0,0 +1,188 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using BetterSecondBotShared.Json;
|
||||
using BetterSecondBotShared.logs;
|
||||
using BetterSecondBotShared.Static;
|
||||
using OpenMetaverse;
|
||||
|
||||
namespace BetterSecondBotShared.bottypes
|
||||
{
|
||||
public abstract class BasicBot
|
||||
{
|
||||
public BasicBot()
|
||||
{
|
||||
LastStatusMessage = "No status";
|
||||
}
|
||||
|
||||
protected bool killMe;
|
||||
protected JsonConfig myconfig;
|
||||
protected string version = "NotSet V1.0.0.0";
|
||||
protected bool reconnect;
|
||||
public string MyVersion { get { return version; } }
|
||||
public string Name { get { return myconfig.userName; } }
|
||||
public string LastStatusMessage { get; set; }
|
||||
|
||||
public bool KillMe { get { return killMe; } }
|
||||
|
||||
|
||||
protected Dictionary<UUID, Group> mygroups = new Dictionary<UUID, Group>();
|
||||
|
||||
public Dictionary<UUID, Group> MyGroups { get { return mygroups; } }
|
||||
|
||||
protected GridClient Client;
|
||||
public GridClient GetClient { get { return Client; } }
|
||||
|
||||
|
||||
|
||||
public virtual void KillMePlease()
|
||||
{
|
||||
killMe = true;
|
||||
}
|
||||
public virtual void Setup(JsonConfig config,string Version)
|
||||
{
|
||||
version = Version;
|
||||
myconfig = config;
|
||||
if(myconfig.code.Length < 8)
|
||||
{
|
||||
myconfig.code = helpers.GetSHA1("" + myconfig.userName + "" + myconfig.password + ""+ helpers.UnixTimeNow().ToString()+"").Substring(0, 8);
|
||||
ConsoleLog.Warn("Given code is not acceptable (min length 8)");
|
||||
}
|
||||
List<string> bits = myconfig.userName.Split(' ').ToList();
|
||||
if (bits.Count == 1)
|
||||
{
|
||||
bits.Add("Resident");
|
||||
myconfig.userName = String.Join(' ', bits);
|
||||
}
|
||||
bits = myconfig.master.Split(new[] { " " }, StringSplitOptions.None).ToList();
|
||||
if (bits.Count == 1)
|
||||
{
|
||||
bits.Add("Resident");
|
||||
}
|
||||
myconfig.master = String.Join(" ", bits);
|
||||
ConsoleLog.Info("Build: " + version);
|
||||
}
|
||||
|
||||
public void Start()
|
||||
{
|
||||
Client = new GridClient();
|
||||
Client.Settings.LOG_RESENDS = false;
|
||||
Client.Settings.ALWAYS_REQUEST_OBJECTS = true;
|
||||
Client.Settings.AVATAR_TRACKING = true;
|
||||
List<string> bits = myconfig.userName.Split(' ').ToList();
|
||||
LoginParams Lp = new LoginParams(Client, bits[0], bits[1], myconfig.password, "BetterSecondBot", "BetterSecondBot "+version);
|
||||
if (reconnect == false)
|
||||
{
|
||||
BotStartHandler();
|
||||
}
|
||||
Client.Network.BeginLogin(Lp);
|
||||
}
|
||||
protected virtual void BotStartHandler()
|
||||
{
|
||||
ConsoleLog.Debug("BotStartHandler proc not overridden");
|
||||
}
|
||||
|
||||
protected string GetSimPositionAsString()
|
||||
{
|
||||
if(Client.Network.Connected == true)
|
||||
{
|
||||
if (Client.Network.CurrentSim != null)
|
||||
{
|
||||
int X = Convert.ToInt32(Math.Floor(Client.Self.SimPosition.X));
|
||||
int Y = Convert.ToInt32(Math.Floor(Client.Self.SimPosition.Y));
|
||||
int Z = Convert.ToInt32(Math.Floor(Client.Self.SimPosition.Z));
|
||||
return "" + X.ToString() + "," + Y.ToString() + "," + Z.ToString() + "";
|
||||
}
|
||||
}
|
||||
return "0,0,0";
|
||||
}
|
||||
|
||||
public virtual string GetStatus()
|
||||
{
|
||||
if (Client != null)
|
||||
{
|
||||
if (Client.Network != null)
|
||||
{
|
||||
if (Client.Network.Connected)
|
||||
{
|
||||
if (Client.Network.CurrentSim != null)
|
||||
{
|
||||
return "Sim: " + Client.Network.CurrentSim.Name + " "+GetSimPositionAsString()+"";
|
||||
}
|
||||
return "Sim: Not on sim";
|
||||
}
|
||||
return "Network: Not connected";
|
||||
}
|
||||
return "Network: Not ready";
|
||||
}
|
||||
return "Info: No client";
|
||||
}
|
||||
|
||||
protected virtual void LoginHandler(object o, LoginProgressEventArgs e)
|
||||
{
|
||||
ConsoleLog.Debug("LoginHandler proc not overridden");
|
||||
}
|
||||
|
||||
protected virtual void AfterBotLoginHandler()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
protected virtual void GroupInvite(InstantMessageEventArgs e)
|
||||
{
|
||||
string[] stage1 = myconfig.master.ToLowerInvariant().Split(' ');
|
||||
string bad_master_name = String.Join('.', stage1);
|
||||
if (e.IM.FromAgentName == bad_master_name)
|
||||
{
|
||||
GroupInvitationEventArgs G = new GroupInvitationEventArgs(e.Simulator, e.IM.FromAgentID, e.IM.FromAgentName, e.IM.Message);
|
||||
Client.Self.GroupInviteRespond(G.AgentID, e.IM.IMSessionID, true);
|
||||
Client.Groups.RequestCurrentGroups(); // reload my groups to include the new group
|
||||
}
|
||||
}
|
||||
protected virtual void FriendshipOffer(UUID IMSessionID,string FromAgentName,UUID FromAgentID)
|
||||
{
|
||||
if(FromAgentName == myconfig.master)
|
||||
{
|
||||
Client.Friends.AcceptFriendship(FromAgentID, IMSessionID);
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual void RequestLure(UUID IMSessionID, string FromAgentName, UUID FromAgentID)
|
||||
{
|
||||
if (FromAgentName == myconfig.master)
|
||||
{
|
||||
Client.Self.SendTeleportLure(FromAgentID);
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual void RequestTeleport(UUID IMSessionID, string FromAgentName, UUID FromAgentID)
|
||||
{
|
||||
if (FromAgentName == myconfig.master)
|
||||
{
|
||||
ResetAnimations();
|
||||
Client.Self.TeleportLureRespond(FromAgentID, IMSessionID, true);
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual void ChatInputHandler(object sender, ChatEventArgs e)
|
||||
{
|
||||
ConsoleLog.Debug("ChatInputHandler proc not overridden");
|
||||
}
|
||||
|
||||
protected virtual void CoreCommandLib(UUID fromUUID, bool from_master, string command, string arg)
|
||||
{
|
||||
CoreCommandLib(fromUUID, from_master, command, arg, "");
|
||||
}
|
||||
|
||||
protected virtual void CoreCommandLib(UUID fromUUID,bool from_master,string command,string arg,string signing_code)
|
||||
{
|
||||
ConsoleLog.Debug("CoreCommandLib proc not overridden");
|
||||
}
|
||||
|
||||
public virtual void ResetAnimations()
|
||||
{
|
||||
ConsoleLog.Debug("reset_animations not enabled at this level");
|
||||
}
|
||||
}
|
||||
}
|
||||
84
BSBshared/IO/SimpleIO.cs
Normal file
84
BSBshared/IO/SimpleIO.cs
Normal file
|
|
@ -0,0 +1,84 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.IO;
|
||||
using Newtonsoft.Json;
|
||||
using BetterSecondBotShared.Json;
|
||||
using BetterSecondBotShared.Static;
|
||||
|
||||
namespace BetterSecondBotShared.IO
|
||||
{
|
||||
public class SimpleIO
|
||||
{
|
||||
protected string root_folder = "";
|
||||
public void ChangeRoot(string A)
|
||||
{
|
||||
|
||||
root_folder = A + "/";
|
||||
create_dir(root_folder);
|
||||
}
|
||||
public void create_dir(string target_folder)
|
||||
{
|
||||
if (dir_exists(root_folder) == false)
|
||||
{
|
||||
System.IO.Directory.CreateDirectory(root_folder);
|
||||
}
|
||||
}
|
||||
public static bool dir_exists(string target_folder)
|
||||
{
|
||||
return System.IO.Directory.Exists(target_folder);
|
||||
}
|
||||
public void Delete(string filename)
|
||||
{
|
||||
System.IO.File.Delete(root_folder+filename);
|
||||
}
|
||||
public void writefile(string filename,string content)
|
||||
{
|
||||
if(Exists(filename))
|
||||
{
|
||||
Delete(filename);
|
||||
}
|
||||
System.IO.File.WriteAllText(@""+root_folder + "" + filename, content);
|
||||
}
|
||||
public void WriteJsonConfig(JsonConfig Config, string targetfile)
|
||||
{
|
||||
JsonSerializer serializer = new JsonSerializer();
|
||||
using (StreamWriter sw = new StreamWriter(@""+root_folder + "" + targetfile))
|
||||
using (JsonWriter writer = new JsonTextWriter(sw) { Formatting = Formatting.Indented })
|
||||
{
|
||||
serializer.Serialize(writer, Config);
|
||||
}
|
||||
}
|
||||
public void makeOld(string targetfile)
|
||||
{
|
||||
System.IO.File.Move(@""+root_folder + "" + targetfile, @"" + root_folder + "" + targetfile+".old");
|
||||
}
|
||||
public bool Exists(string targetfile)
|
||||
{
|
||||
return File.Exists(@""+root_folder+"" + targetfile);
|
||||
}
|
||||
public static bool FileType(string targetfile, string matchtype)
|
||||
{
|
||||
string[] bits = targetfile.Split('.');
|
||||
if (bits[^1] == matchtype)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
public string ReadFile(string targetfile)
|
||||
{
|
||||
if (Exists(targetfile) == true)
|
||||
{
|
||||
string return_text = "";
|
||||
using (var Stream = new FileStream(@"" + root_folder + "" + targetfile, FileMode.Open, FileAccess.Read))
|
||||
using (var StreamReader = new StreamReader(Stream))
|
||||
{
|
||||
return_text = StreamReader.ReadToEnd();
|
||||
}
|
||||
return return_text;
|
||||
}
|
||||
return "";
|
||||
}
|
||||
}
|
||||
}
|
||||
30
BSBshared/Json/JsonConfig.cs
Normal file
30
BSBshared/Json/JsonConfig.cs
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace BetterSecondBotShared.Json
|
||||
{
|
||||
public class JsonConfig
|
||||
{
|
||||
public string userName { get; set; }
|
||||
public string password { get; set; }
|
||||
public string master { get; set; }
|
||||
public string code { get; set; }
|
||||
public string discord { get; set; }
|
||||
public bool allowRLV { get; set; }
|
||||
public string discordGroupTarget { get; set; }
|
||||
public string[] homeRegion { get; set; }
|
||||
public bool EnableHttp { get; set; }
|
||||
public int Httpport { get; set; }
|
||||
public string Httpkey { get; set; }
|
||||
public bool HttpRequireSigned { get; set; }
|
||||
public string HttpHost { get; set; }
|
||||
public bool HttpAsCnC { get; set; }
|
||||
public bool DiscordFullServer { get; set; }
|
||||
public string DiscordClientToken { get; set; }
|
||||
public ulong DiscordServerID { get; set; }
|
||||
public int DiscordServerImHistoryHours { get; set; }
|
||||
public string DefaultSitUUID { get; set; }
|
||||
}
|
||||
|
||||
}
|
||||
315
BSBshared/Json/JsonConfigApi.cs
Normal file
315
BSBshared/Json/JsonConfigApi.cs
Normal file
|
|
@ -0,0 +1,315 @@
|
|||
using BetterSecondBotShared.API;
|
||||
using BetterSecondBotShared.logs;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
|
||||
namespace BetterSecondBotShared.Json
|
||||
{
|
||||
public class MakeJsonConfig : API_supported_interface
|
||||
{
|
||||
public override string GetCommandWorkspace(string cmd)
|
||||
{
|
||||
cmd = cmd.ToLowerInvariant();
|
||||
switch (cmd)
|
||||
{
|
||||
case "username": { return "Required"; }
|
||||
case "password": { return "Required"; }
|
||||
case "master": { return "Required"; }
|
||||
case "homeregion": { return "AtHome"; }
|
||||
case "defaultsituuid": { return "AtHome"; }
|
||||
case "discordgrouptarget": { return "DiscordRelay"; }
|
||||
case "discord": { return "DiscordRelay"; }
|
||||
case "allowrlv": { return "RLV"; }
|
||||
case "code": { return "Required"; }
|
||||
case "enablehttp": { return "HTTP"; }
|
||||
case "httpport": { return "HTTP"; }
|
||||
case "httpkey": { return "HTTP"; }
|
||||
case "httprequiresigned": { return "HTTP"; }
|
||||
case "httphost": { return "HTTP"; }
|
||||
case "httpascnc": { return "HTTP"; }
|
||||
case "discordfullserver": { return "DiscordFull"; }
|
||||
case "discordclienttoken": { return "DiscordFull"; }
|
||||
case "discordserverid": { return "DiscordFull"; }
|
||||
case "discordserverimhistoryhours": { return "DiscordFull"; }
|
||||
default: { return "Unknown"; }
|
||||
}
|
||||
}
|
||||
public override string GetCommandHelp(string cmd)
|
||||
{
|
||||
cmd = cmd.ToLowerInvariant();
|
||||
switch (cmd)
|
||||
{
|
||||
case "username": { return "The full username of the bot"; }
|
||||
case "password": { return "Raw password OR $1$ followed by the md5 of your password"; }
|
||||
case "master": { return "A vaild avatar name, you can skip Resident if thats the last name"; }
|
||||
case "defaultsituuid": { return "The UUID to sit on when at home region [Any invaild UUID to disable like \"none\"]"; }
|
||||
case "homeregion": { return "An array of SLurl strings to teleport to to avoid a sim shutdown"; }
|
||||
case "discordgrouptarget": { return "The target group UUID to relay group chat from, leave empty for all groups"; }
|
||||
case "discord": { return "A vaild discord hook URL to relay group chat onto<br/>leave as \"\" to disable"; }
|
||||
case "allowrlv": { return "Enable RLV commands interface for the bot"; }
|
||||
case "code": { return "A known secret between your secondlife scripts and the bot<br/>Used to support IM commands"; }
|
||||
case "enablehttp": { return "Enable the HTTP interface (using the HTTP settings)"; }
|
||||
case "httpport": { return "What port the HTTP interface should be on<br/> Example: 8080"; }
|
||||
case "httpkey": { return "A known secret between used for HTTP calls<br/>Example: \"DontUseThis\""; }
|
||||
case "httprequiresigned": { return "Force HTTP calls to be Signed with a hash (Not yet KnownCommand)"; }
|
||||
case "httphost": { return "The URL to listen for HTTP connections on"; }
|
||||
case "httpascnc": { return "Switchs the software into command and control mode"; }
|
||||
case "discordfullserver": { return "Should we switch to a full server control discord link"; }
|
||||
case "discordclienttoken": { return "What is the bots client token"; }
|
||||
case "discordserverid": { return "What is the Discord server id we should be using"; }
|
||||
case "discordserverimhistoryhours": { return "How long to keep history messages in Group/IM chats in hours"; }
|
||||
default: { return "None given"; }
|
||||
}
|
||||
}
|
||||
|
||||
public override int ApiCommandsCount { get { return GetCommandsList().Length; } }
|
||||
|
||||
public override string[] GetCommandsList()
|
||||
{
|
||||
JsonConfig Obj = new JsonConfig();
|
||||
return Obj.GetType().GetProperties().Select(X => X.Name).ToArray();
|
||||
}
|
||||
public override string[] GetCommandArgTypes(string cmd)
|
||||
{
|
||||
JsonConfig Obj = new JsonConfig();
|
||||
Type valuetype = Obj.GetType().GetProperties().Where(X => X.Name == cmd).Select(X => X.PropertyType).FirstOrDefault();
|
||||
if (valuetype.Name == "Int32") { return new[] { "Number" }; }
|
||||
else if (valuetype.Name == "String") { return new[] { "Text" }; }
|
||||
else if (valuetype.Name == "Boolean") { return new[] { "True|False" }; }
|
||||
else if (valuetype.Name == "String[]") { return new[] { "Collection" }; }
|
||||
else if (valuetype.Name == "UInt64") { return new[] { "BigNumber" }; }
|
||||
return new[] { "Unknown" };
|
||||
}
|
||||
public override string[] GetCommandArgHints(string cmd)
|
||||
{
|
||||
cmd = cmd.ToLowerInvariant();
|
||||
switch (cmd)
|
||||
{
|
||||
case "username": { return new[] { "\"Firstname LastName\"" }; }
|
||||
case "password": { return new[] { "\"PassWord\"" }; }
|
||||
case "master": { return new[] { "\"Madpeter Zond\"" }; }
|
||||
case "homeregion": { return new[] { "[\"SLurl1\",\"SLurl2\"]" }; }
|
||||
case "discordgrouptarget": { return new[] { "\"" + OpenMetaverse.UUID.Zero + "\"" }; }
|
||||
case "discord": { return new[] { "\"https://discordapp.com/api/webhooks/XXXX/YYYY\"" }; }
|
||||
case "allowrlv": { return new[] { "False" }; }
|
||||
case "code": { return new[] { "\"DontTellAnyoneThis\"" }; }
|
||||
case "enablehttp": { return new[] { "False" }; }
|
||||
case "httpport": { return new[] { "8080" }; }
|
||||
case "httpkey": { return new[] { "\"ThisIsAKeyYo\"" }; }
|
||||
case "httprequiresigned": { return new[] { "False" }; }
|
||||
case "httphost": { return new[] { "\"http://localhost\"" }; }
|
||||
case "httpascnc": { return new[] { "False" }; }
|
||||
case "discordfullserver": { return new[] { "False" }; }
|
||||
case "discordclienttoken": { return new[] { "https://discordapp.com/developers/ Bot" }; }
|
||||
case "discordserverid": { return new[] { "1234567890" }; }
|
||||
case "discordserverimhistoryhours": { return new[] { "24" }; }
|
||||
case "defaultsituuid": { return new[] { "\"" + OpenMetaverse.UUID.Zero + "\"" }; }
|
||||
default: { return new string[] { }; }
|
||||
}
|
||||
}
|
||||
public override int GetCommandArgs(string cmd)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
public string GetProp(JsonConfig reply, string arg)
|
||||
{
|
||||
return reply.GetType().GetProperty(arg, BindingFlags.Public | BindingFlags.Instance).GetValue(reply).ToString();
|
||||
}
|
||||
|
||||
protected JsonConfig process_prop(JsonConfig reply,string arg,string arg_value_default)
|
||||
{
|
||||
string arg_type = GetCommandArgTypes(arg).First();
|
||||
if (arg_type != "")
|
||||
{
|
||||
if (arg_value_default != null)
|
||||
{
|
||||
Type Dtype = reply.GetType();
|
||||
PropertyInfo prop = Dtype.GetProperty(arg, BindingFlags.Public | BindingFlags.Instance);
|
||||
if (prop != null)
|
||||
{
|
||||
if (prop.CanWrite == true)
|
||||
{
|
||||
if (arg_type == "Number")
|
||||
{
|
||||
if (int.TryParse(arg_value_default, out int result) == true)
|
||||
{
|
||||
prop.SetValue(reply, result, null);
|
||||
}
|
||||
}
|
||||
else if (arg_type == "Text")
|
||||
{
|
||||
prop.SetValue(reply, arg_value_default, null);
|
||||
}
|
||||
else if (arg_type == "True|False")
|
||||
{
|
||||
if (bool.TryParse(arg_value_default, out bool result) == true)
|
||||
{
|
||||
prop.SetValue(reply, result, null);
|
||||
}
|
||||
}
|
||||
else if (arg_type == "Collection")
|
||||
{
|
||||
prop.SetValue(reply, arg_value_default.Split(','), null);
|
||||
}
|
||||
else if (arg_type == "BigNumber")
|
||||
{
|
||||
if (ulong.TryParse(arg_value_default, out ulong result) == true)
|
||||
{
|
||||
prop.SetValue(reply, result, null);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ConsoleLog.Debug("unsupported arg_type: " + arg_type + " for " + arg + "");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ConsoleLog.Warn("Unable to write to " + arg + "");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ConsoleLog.Crit("unknown prop " + arg + "");
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ConsoleLog.Debug("unknown arg_type for " + arg + "");
|
||||
}
|
||||
return reply;
|
||||
}
|
||||
|
||||
public static JsonConfig http_config_check(JsonConfig jsonConfig)
|
||||
{
|
||||
if ((jsonConfig.Httpkey != null) && (jsonConfig.HttpHost != null))
|
||||
{
|
||||
if ((jsonConfig.Httpport < 80) || (jsonConfig.Httpkey.Length < 12) || (jsonConfig.HttpHost.StartsWith("http") == false))
|
||||
{
|
||||
jsonConfig.EnableHttp = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
jsonConfig.EnableHttp = false;
|
||||
}
|
||||
if (jsonConfig.EnableHttp == false)
|
||||
{
|
||||
jsonConfig.HttpAsCnC = false;
|
||||
}
|
||||
return jsonConfig;
|
||||
}
|
||||
|
||||
protected JsonConfig FromDockerENV()
|
||||
{
|
||||
string[] args = this.GetCommandsList();
|
||||
JsonConfig reply = new JsonConfig();
|
||||
foreach (string arg in args)
|
||||
{
|
||||
|
||||
string arg_value_default = Environment.GetEnvironmentVariable(arg);
|
||||
if (arg_value_default != null)
|
||||
{
|
||||
arg_value_default = arg_value_default.Replace("[", "");
|
||||
arg_value_default = arg_value_default.Replace("]", "");
|
||||
arg_value_default = arg_value_default.Replace("\"", "");
|
||||
}
|
||||
reply = process_prop(reply, arg, arg_value_default);
|
||||
}
|
||||
return reply;
|
||||
}
|
||||
|
||||
public static JsonConfig FromENV()
|
||||
{
|
||||
return new MakeJsonConfig().FromDockerENV();
|
||||
}
|
||||
|
||||
protected JsonConfig MakeDefault()
|
||||
{
|
||||
string[] args = this.GetCommandsList();
|
||||
JsonConfig reply = new JsonConfig();
|
||||
foreach (string arg in args)
|
||||
{
|
||||
string arg_type = GetCommandArgTypes(arg).First();
|
||||
string arg_value_default = null;
|
||||
if (arg_type != "")
|
||||
{
|
||||
string[] ArgHints = GetCommandArgHints(arg);
|
||||
if (ArgHints.Length > 0)
|
||||
{
|
||||
arg_value_default = ArgHints[0];
|
||||
arg_value_default = arg_value_default.Replace("[", "");
|
||||
arg_value_default = arg_value_default.Replace("]", "");
|
||||
arg_value_default = arg_value_default.Replace("\"", "");
|
||||
}
|
||||
else
|
||||
{
|
||||
ConsoleLog.Debug("[Notice] No args hint found for " + arg + "");
|
||||
}
|
||||
}
|
||||
if (arg_value_default != null)
|
||||
{
|
||||
Type Dtype = reply.GetType();
|
||||
PropertyInfo prop = Dtype.GetProperty(arg, BindingFlags.Public | BindingFlags.Instance);
|
||||
if (prop != null)
|
||||
{
|
||||
if (prop.CanWrite == true)
|
||||
{
|
||||
if (arg_type == "Number")
|
||||
{
|
||||
if (int.TryParse(arg_value_default, out int result) == true)
|
||||
{
|
||||
prop.SetValue(reply, result, null);
|
||||
}
|
||||
}
|
||||
else if (arg_type == "Text")
|
||||
{
|
||||
prop.SetValue(reply, arg_value_default, null);
|
||||
}
|
||||
else if (arg_type == "True|False")
|
||||
{
|
||||
if (bool.TryParse(arg_value_default, out bool result) == true)
|
||||
{
|
||||
prop.SetValue(reply, result, null);
|
||||
}
|
||||
}
|
||||
else if (arg_type == "Collection")
|
||||
{
|
||||
prop.SetValue(reply, arg_value_default.Split(','), null);
|
||||
}
|
||||
else if (arg_type == "BigNumber")
|
||||
{
|
||||
if (ulong.TryParse(arg_value_default, out ulong result) == true)
|
||||
{
|
||||
prop.SetValue(reply, result, null);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ConsoleLog.Debug("unknown arg_type: " + arg_type + " for " + arg + "");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ConsoleLog.Warn("Unable to write to " + arg + "");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ConsoleLog.Crit("unknown prop " + arg + "");
|
||||
}
|
||||
}
|
||||
}
|
||||
return reply;
|
||||
}
|
||||
public static JsonConfig GetDefault()
|
||||
{
|
||||
return new MakeJsonConfig().MakeDefault();
|
||||
}
|
||||
}
|
||||
}
|
||||
83
BSBshared/Staic/ConsoleLog.cs
Normal file
83
BSBshared/Staic/ConsoleLog.cs
Normal file
|
|
@ -0,0 +1,83 @@
|
|||
using System;
|
||||
using System.Text;
|
||||
|
||||
namespace BetterSecondBotShared.logs
|
||||
{
|
||||
public enum ConsoleLogLogLevel
|
||||
{
|
||||
Debug, // [Not logged unless in debug]
|
||||
Info, // [Not logged unless in debug]
|
||||
Status,
|
||||
Warn,
|
||||
Crit
|
||||
};
|
||||
public static class ConsoleLog
|
||||
{
|
||||
public static void Warn(string message)
|
||||
{
|
||||
Add(message, ConsoleLogLogLevel.Warn);
|
||||
}
|
||||
public static void Crit(string message)
|
||||
{
|
||||
Add(message, ConsoleLogLogLevel.Crit);
|
||||
}
|
||||
public static void Info(string message)
|
||||
{
|
||||
Add(message, ConsoleLogLogLevel.Info);
|
||||
}
|
||||
public static void Status(string message)
|
||||
{
|
||||
Add(message, ConsoleLogLogLevel.Status);
|
||||
}
|
||||
public static void Debug(string message)
|
||||
{
|
||||
Add(message, ConsoleLogLogLevel.Debug);
|
||||
}
|
||||
private static void Add(string message, ConsoleLogLogLevel Level)
|
||||
{
|
||||
var date = DateTime.Now;
|
||||
StringBuilder n = new StringBuilder();
|
||||
n.Append("[");
|
||||
if(date.Hour < 10) n.Append("0");
|
||||
n.Append(date.Hour.ToString());
|
||||
n.Append(":");
|
||||
if (date.Minute < 10) n.Append("0");
|
||||
n.Append(date.Minute.ToString());
|
||||
n.Append("] ");
|
||||
switch (Level)
|
||||
{
|
||||
#if DEBUG
|
||||
case ConsoleLogLogLevel.Debug:
|
||||
{
|
||||
n.Append("Debug - ");
|
||||
break;
|
||||
}
|
||||
case ConsoleLogLogLevel.Info:
|
||||
{
|
||||
n.Append("Info - ");
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
case ConsoleLogLogLevel.Status:
|
||||
{
|
||||
n.Append("Status - ");
|
||||
break;
|
||||
}
|
||||
case ConsoleLogLogLevel.Warn:
|
||||
{
|
||||
n.Append("Warn - ");
|
||||
break;
|
||||
}
|
||||
case ConsoleLogLogLevel.Crit:
|
||||
{
|
||||
n.Append("Crit - ");
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
n.Append(message);
|
||||
Console.WriteLine(n.ToString());
|
||||
}
|
||||
}
|
||||
}
|
||||
173
BSBshared/Staic/Helpers.cs
Normal file
173
BSBshared/Staic/Helpers.cs
Normal file
|
|
@ -0,0 +1,173 @@
|
|||
using BetterSecondBotShared.Json;
|
||||
using BetterSecondBotShared.logs;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
|
||||
namespace BetterSecondBotShared.Static
|
||||
{
|
||||
public static class StringExtensions
|
||||
{
|
||||
public static string FirstCharToUpper(this string input)
|
||||
{
|
||||
switch (input)
|
||||
{
|
||||
case null: throw new ArgumentNullException(nameof(input));
|
||||
case "": throw new ArgumentException($"{nameof(input)} cannot be empty", nameof(input));
|
||||
default: return input.First().ToString().ToUpper() + input.Substring(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
public static class helpers
|
||||
{
|
||||
public static string GetSHA1(string text)
|
||||
{
|
||||
SHA1 hash = SHA1CryptoServiceProvider.Create();
|
||||
byte[] plainTextBytes = Encoding.UTF8.GetBytes(text);
|
||||
byte[] hashBytes = hash.ComputeHash(plainTextBytes);
|
||||
string localChecksum = BitConverter.ToString(hashBytes)
|
||||
.Replace("-", "").ToLowerInvariant();
|
||||
return localChecksum;
|
||||
}
|
||||
public static string[] ParseSLurl(string url)
|
||||
{
|
||||
if (url != null)
|
||||
{
|
||||
url = url.Replace("http://maps.secondlife.com/secondlife/", "");
|
||||
string[] bits = url.Split('/');
|
||||
if (bits.Length == 4)
|
||||
{
|
||||
return bits;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
public static string RegionnameFromSLurl(string url)
|
||||
{
|
||||
string[] bits = ParseSLurl(url);
|
||||
if (bits != null)
|
||||
{
|
||||
if (bits.Length == 4)
|
||||
{
|
||||
return bits[0];
|
||||
}
|
||||
}
|
||||
return "";
|
||||
}
|
||||
public static long UnixTimeNow()
|
||||
{
|
||||
var timeSpan = (DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0));
|
||||
return (long)timeSpan.TotalSeconds;
|
||||
}
|
||||
public static bool botRequired(JsonConfig test)
|
||||
{
|
||||
if (helpers.notempty(test.userName) && helpers.notempty(test.password) && helpers.notempty(test.master) && helpers.notempty(test.code))
|
||||
{
|
||||
// required values are set
|
||||
MakeJsonConfig Testing = new MakeJsonConfig();
|
||||
string[] testingfor = new[] { "userName", "password", "code" };
|
||||
bool default_value_found = false;
|
||||
foreach (string a in testingfor)
|
||||
{
|
||||
if (Testing.GetCommandArgTypes(a).First() == Testing.GetProp(test, a))
|
||||
{
|
||||
ConsoleLog.Warn("" + a + " is currently set to the default");
|
||||
default_value_found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (default_value_found == false)
|
||||
{
|
||||
ConsoleLog.Status("User => " + test.userName);
|
||||
ConsoleLog.Status("Master => " + test.master);
|
||||
}
|
||||
return !default_value_found;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (helpers.notempty(test.userName) == false)
|
||||
{
|
||||
ConsoleLog.Warn("Username is null or empty");
|
||||
}
|
||||
if (helpers.notempty(test.password) == false)
|
||||
{
|
||||
ConsoleLog.Warn("Password is null or empty");
|
||||
}
|
||||
if (helpers.notempty(test.master) == false)
|
||||
{
|
||||
ConsoleLog.Warn("Master is null or empty");
|
||||
}
|
||||
if (helpers.notempty(test.code) == false)
|
||||
{
|
||||
ConsoleLog.Warn("Code is null or empty");
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
public static string create_dirty_table(string[] items)
|
||||
{
|
||||
return create_dirty_table(items, 6);
|
||||
}
|
||||
public static string create_dirty_table(string[] items, int cols)
|
||||
{
|
||||
|
||||
bool row_open = false;
|
||||
int col_counter = 0;
|
||||
StringBuilder reply = new StringBuilder();
|
||||
reply.Append("<table border='1'>");
|
||||
foreach (string A in items)
|
||||
{
|
||||
if (row_open == false)
|
||||
{
|
||||
reply.Append("<tr>");
|
||||
row_open = true;
|
||||
}
|
||||
reply.Append("<td>" + A + "</td>");
|
||||
col_counter++;
|
||||
if (col_counter >= cols)
|
||||
{
|
||||
reply.Append("</tr>");
|
||||
col_counter = 0;
|
||||
row_open = false;
|
||||
}
|
||||
}
|
||||
while (row_open == true)
|
||||
{
|
||||
reply.Append("<td></td>");
|
||||
col_counter++;
|
||||
if (col_counter >= cols)
|
||||
{
|
||||
reply.Append("</tr>");
|
||||
row_open = false;
|
||||
}
|
||||
}
|
||||
reply.Append("</table>");
|
||||
return reply.ToString();
|
||||
}
|
||||
public static bool notempty(string V)
|
||||
{
|
||||
if (V != null)
|
||||
{
|
||||
if (V.Length > 0) return true;
|
||||
else return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
public static bool notempty(string[] V)
|
||||
{
|
||||
if (V != null)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
67
BetterSecondBot.sln
Normal file
67
BetterSecondBot.sln
Normal file
|
|
@ -0,0 +1,67 @@
|
|||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio Version 16
|
||||
VisualStudioVersion = 16.0.29123.88
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BSB", "Core\BSB.csproj", "{077DC0CD-6B3D-4BD9-83ED-9E098768AAA8}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BetterSecondBot", "CLI\BetterSecondBot.csproj", "{E34873C1-3860-430A-8AE5-6289C4E68AC7}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BSBshared", "BSBshared\BSBshared.csproj", "{42075C8C-8055-4178-8C12-AE97DAFE8484}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LibreMetaverse", "libremetaverse-core\Libremetaverse\LibreMetaverse.csproj", "{748DEFDD-B7EF-4E67-907C-33C8B2F0C221}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LibreMetaverse.StructuredData", "libremetaverse-core\Libremetaverse.structureddata\LibreMetaverse.StructuredData.csproj", "{9B42196B-00EC-4F33-B78D-8B693B23E56D}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LibreMetaverse.Types", "libremetaverse-core\Libremetaversetypes\LibreMetaverse.Types.csproj", "{53663A03-7508-4D44-9B08-79BEB6AAB47E}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|x64 = Debug|x64
|
||||
DockerBuild|x64 = DockerBuild|x64
|
||||
Release|x64 = Release|x64
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{077DC0CD-6B3D-4BD9-83ED-9E098768AAA8}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{077DC0CD-6B3D-4BD9-83ED-9E098768AAA8}.Debug|x64.Build.0 = Debug|x64
|
||||
{077DC0CD-6B3D-4BD9-83ED-9E098768AAA8}.DockerBuild|x64.ActiveCfg = DockerBuild|x64
|
||||
{077DC0CD-6B3D-4BD9-83ED-9E098768AAA8}.DockerBuild|x64.Build.0 = DockerBuild|x64
|
||||
{077DC0CD-6B3D-4BD9-83ED-9E098768AAA8}.Release|x64.ActiveCfg = Release|x64
|
||||
{077DC0CD-6B3D-4BD9-83ED-9E098768AAA8}.Release|x64.Build.0 = Release|x64
|
||||
{E34873C1-3860-430A-8AE5-6289C4E68AC7}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{E34873C1-3860-430A-8AE5-6289C4E68AC7}.Debug|x64.Build.0 = Debug|x64
|
||||
{E34873C1-3860-430A-8AE5-6289C4E68AC7}.DockerBuild|x64.ActiveCfg = DockerBuild|x64
|
||||
{E34873C1-3860-430A-8AE5-6289C4E68AC7}.DockerBuild|x64.Build.0 = DockerBuild|x64
|
||||
{E34873C1-3860-430A-8AE5-6289C4E68AC7}.Release|x64.ActiveCfg = Release|x64
|
||||
{E34873C1-3860-430A-8AE5-6289C4E68AC7}.Release|x64.Build.0 = Release|x64
|
||||
{42075C8C-8055-4178-8C12-AE97DAFE8484}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{42075C8C-8055-4178-8C12-AE97DAFE8484}.Debug|x64.Build.0 = Debug|x64
|
||||
{42075C8C-8055-4178-8C12-AE97DAFE8484}.DockerBuild|x64.ActiveCfg = DockerBuild|x64
|
||||
{42075C8C-8055-4178-8C12-AE97DAFE8484}.DockerBuild|x64.Build.0 = DockerBuild|x64
|
||||
{42075C8C-8055-4178-8C12-AE97DAFE8484}.Release|x64.ActiveCfg = Release|x64
|
||||
{42075C8C-8055-4178-8C12-AE97DAFE8484}.Release|x64.Build.0 = Release|x64
|
||||
{748DEFDD-B7EF-4E67-907C-33C8B2F0C221}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{748DEFDD-B7EF-4E67-907C-33C8B2F0C221}.Debug|x64.Build.0 = Debug|x64
|
||||
{748DEFDD-B7EF-4E67-907C-33C8B2F0C221}.DockerBuild|x64.ActiveCfg = DockerBuild|x64
|
||||
{748DEFDD-B7EF-4E67-907C-33C8B2F0C221}.DockerBuild|x64.Build.0 = DockerBuild|x64
|
||||
{748DEFDD-B7EF-4E67-907C-33C8B2F0C221}.Release|x64.ActiveCfg = Release|x64
|
||||
{748DEFDD-B7EF-4E67-907C-33C8B2F0C221}.Release|x64.Build.0 = Release|x64
|
||||
{9B42196B-00EC-4F33-B78D-8B693B23E56D}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{9B42196B-00EC-4F33-B78D-8B693B23E56D}.Debug|x64.Build.0 = Debug|x64
|
||||
{9B42196B-00EC-4F33-B78D-8B693B23E56D}.DockerBuild|x64.ActiveCfg = DockerBuild|x64
|
||||
{9B42196B-00EC-4F33-B78D-8B693B23E56D}.DockerBuild|x64.Build.0 = DockerBuild|x64
|
||||
{9B42196B-00EC-4F33-B78D-8B693B23E56D}.Release|x64.ActiveCfg = Release|x64
|
||||
{9B42196B-00EC-4F33-B78D-8B693B23E56D}.Release|x64.Build.0 = Release|x64
|
||||
{53663A03-7508-4D44-9B08-79BEB6AAB47E}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{53663A03-7508-4D44-9B08-79BEB6AAB47E}.Debug|x64.Build.0 = Debug|x64
|
||||
{53663A03-7508-4D44-9B08-79BEB6AAB47E}.DockerBuild|x64.ActiveCfg = DockerBuild|x64
|
||||
{53663A03-7508-4D44-9B08-79BEB6AAB47E}.DockerBuild|x64.Build.0 = DockerBuild|x64
|
||||
{53663A03-7508-4D44-9B08-79BEB6AAB47E}.Release|x64.ActiveCfg = Release|x64
|
||||
{53663A03-7508-4D44-9B08-79BEB6AAB47E}.Release|x64.Build.0 = Release|x64
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {39A7E333-AFC1-4BA8-9EBC-9298791FDC78}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
4
BetterSecondBot.sln.DotSettings
Normal file
4
BetterSecondBot.sln.DotSettings
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=Teleport/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=Xfer/@EntryIndexedValue">True</s:Boolean>
|
||||
</wpf:ResourceDictionary>
|
||||
37
CLI/BetterSecondBot.csproj
Normal file
37
CLI/BetterSecondBot.csproj
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<MSBuildGitHashCommand>git describe --match=NeVeRmAtCh --always --abbrev=7</MSBuildGitHashCommand>
|
||||
<Platforms>AnyCPU;x64</Platforms>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>netcoreapp3.1</TargetFramework>
|
||||
<StartupObject>BetterSecondBot.Program</StartupObject>
|
||||
<Configurations>Debug;Release;DockerBuild;Windows</Configurations>
|
||||
<DockerDefaultTargetOS>Linux</DockerDefaultTargetOS>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DockerBuild|x64'">
|
||||
<ErrorReport>none</ErrorReport>
|
||||
<DockerDefaultTargetOS>Linux</DockerDefaultTargetOS>
|
||||
<PublishTrimmed>false</PublishTrimmed>
|
||||
<PublishSingleFile>false</PublishSingleFile>
|
||||
<TreatWarningsAsErrors>false</TreatWarningsAsErrors>
|
||||
<RuntimeIdentifier>linux-x64</RuntimeIdentifier>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<None Remove="WikiMake\wiki_footer.txt" />
|
||||
<None Remove="WikiMake\wiki_header.txt" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="CommandLineParser" Version="2.7.82" />
|
||||
<PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.9.10" />
|
||||
<PackageReference Include="MSBuildGitHash" Version="1.0.1" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<EmbeddedResource Include="WikiMake\wiki_footer.txt" />
|
||||
<EmbeddedResource Include="WikiMake\wiki_header.txt" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Core\BSB.csproj" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
80
CLI/Cli.cs
Normal file
80
CLI/Cli.cs
Normal file
|
|
@ -0,0 +1,80 @@
|
|||
using System;
|
||||
using CommandLine;
|
||||
using System.Threading;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.IO;
|
||||
using Newtonsoft.Json;
|
||||
using System.Reflection;
|
||||
using System.Linq;
|
||||
using System.Collections.Generic;
|
||||
using BSB;
|
||||
using BSB.bottypes;
|
||||
using BetterSecondBot.HttpServer;
|
||||
using BetterSecondBotShared.Json;
|
||||
using BetterSecondBotShared.IO;
|
||||
using BetterSecondBotShared.API;
|
||||
using BetterSecondBotShared.Static;
|
||||
using BetterSecondBotShared.logs;
|
||||
using BetterSecondBot.WikiMake;
|
||||
namespace BetterSecondBot
|
||||
{
|
||||
class Program
|
||||
{
|
||||
static void Main(string[] args)
|
||||
{
|
||||
if (helpers.notempty(Environment.GetEnvironmentVariable("BotRunningInDocker")) == true)
|
||||
{
|
||||
new CliDocker();
|
||||
}
|
||||
else
|
||||
{
|
||||
new CliHardware(args);
|
||||
}
|
||||
ConsoleLog.Status("- Exiting in 5 secs -");
|
||||
Thread.Sleep(5000);
|
||||
}
|
||||
|
||||
public static class AssemblyInfo
|
||||
{
|
||||
/// <summary> Gets the git hash value from the assembly
|
||||
/// or null if it cannot be found. </summary>
|
||||
public static string GetGitHash()
|
||||
{
|
||||
var asm = typeof(AssemblyInfo).Assembly;
|
||||
var attrs = asm.GetCustomAttributes<AssemblyMetadataAttribute>();
|
||||
return attrs.FirstOrDefault(a => a.Key == "GitHash")?.Value;
|
||||
}
|
||||
}
|
||||
}
|
||||
class Options : API_supported_interface
|
||||
{
|
||||
[Option('j', "json", Required = false, HelpText = "see api")]
|
||||
public string Json { get; set; }
|
||||
|
||||
public override int ApiCommandsCount { get { return 1; } }
|
||||
|
||||
public override string[] GetCommandsList()
|
||||
{
|
||||
return new string[] { "j"};
|
||||
}
|
||||
public override string[] GetCommandArgTypes(string cmd)
|
||||
{
|
||||
return new string[] { "Text" };
|
||||
}
|
||||
public override string[] GetCommandArgHints(string cmd)
|
||||
{
|
||||
return new string[] { "\"Bot4.json\"" };
|
||||
}
|
||||
|
||||
public override string GetCommandHelp(string cmd)
|
||||
{
|
||||
return "json config file [Defaults to: mybot.json] <br/>Example: \"BetterSecondBot.exe -j=otherbot.json\"";
|
||||
}
|
||||
public override int GetCommandArgs(string cmd)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
30
CLI/CliDocker.cs
Normal file
30
CLI/CliDocker.cs
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
using BetterSecondBotShared.IO;
|
||||
using BetterSecondBotShared.Json;
|
||||
using BetterSecondBotShared.logs;
|
||||
using BetterSecondBotShared.Static;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
|
||||
namespace BetterSecondBot
|
||||
{
|
||||
public class CliDocker
|
||||
{
|
||||
public CliDocker()
|
||||
{
|
||||
Thread.Sleep(3000);
|
||||
ConsoleLog.Status("-> Getting config from Docker");
|
||||
JsonConfig Config = MakeJsonConfig.FromENV();
|
||||
Config = MakeJsonConfig.http_config_check(Config);
|
||||
if (Config.HttpAsCnC == true)
|
||||
{
|
||||
new HttpCnC(Config);
|
||||
}
|
||||
else
|
||||
{
|
||||
new CliExitOnLogout(Config);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
49
CLI/CliExitOnLogout.cs
Normal file
49
CLI/CliExitOnLogout.cs
Normal file
|
|
@ -0,0 +1,49 @@
|
|||
using BetterSecondBot.HttpServer;
|
||||
using BetterSecondBotShared.IO;
|
||||
using BetterSecondBotShared.Json;
|
||||
using BetterSecondBotShared.logs;
|
||||
using BetterSecondBotShared.Static;
|
||||
using BSB.bottypes;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using static BetterSecondBot.Program;
|
||||
|
||||
namespace BetterSecondBot
|
||||
{
|
||||
public class CliExitOnLogout
|
||||
{
|
||||
public CliExitOnLogout(JsonConfig Config)
|
||||
{
|
||||
ConsoleLog.Status("Mode: Cli [Basic]");
|
||||
if (helpers.botRequired(Config) == true)
|
||||
{
|
||||
SecondBot Bot = new SecondBot();
|
||||
Bot.Setup(Config, AssemblyInfo.GetGitHash());
|
||||
Bot.Start();
|
||||
if (Config.EnableHttp == true)
|
||||
{
|
||||
http_server my_http_server = null;
|
||||
my_http_server = new http_server();
|
||||
my_http_server.start_http_server(Bot,Config);
|
||||
}
|
||||
while (Bot.KillMe == false)
|
||||
{
|
||||
string NewStatusMessage = Bot.GetStatus();
|
||||
if (NewStatusMessage != Bot.LastStatusMessage)
|
||||
{
|
||||
Bot.LastStatusMessage = NewStatusMessage;
|
||||
ConsoleLog.Status(Bot.LastStatusMessage);
|
||||
}
|
||||
Thread.Sleep(5000);
|
||||
}
|
||||
Bot.GetClient.Network.Logout();
|
||||
}
|
||||
else
|
||||
{
|
||||
ConsoleLog.Warn("Required settings missing");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
93
CLI/CliHardware.cs
Normal file
93
CLI/CliHardware.cs
Normal file
|
|
@ -0,0 +1,93 @@
|
|||
using BetterSecondBot.WikiMake;
|
||||
using BetterSecondBotShared.IO;
|
||||
using BetterSecondBotShared.Json;
|
||||
using BetterSecondBotShared.Static;
|
||||
using CommandLine;
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using static BetterSecondBot.Program;
|
||||
using BetterSecondBotShared.logs;
|
||||
namespace BetterSecondBot
|
||||
{
|
||||
public class CliHardware
|
||||
{
|
||||
public CliHardware(string[] args)
|
||||
{
|
||||
SimpleIO io = new SimpleIO();
|
||||
JsonConfig Config;
|
||||
string json_file = "";
|
||||
#if DEBUG
|
||||
ConsoleLog.Status("Hardware/Debug version");
|
||||
json_file = "debug.json";
|
||||
#else
|
||||
ConsoleLog.Status("Hardware/Live version");
|
||||
Parser.Default.ParseArguments<Options>(args).WithParsed<Options>(o =>
|
||||
{
|
||||
json_file = o.Json;
|
||||
});
|
||||
|
||||
#endif
|
||||
if (SimpleIO.dir_exists("wiki") == false)
|
||||
{
|
||||
ConsoleLog.Info("Basic Wiki [Creating]");
|
||||
new DebugModeCreateWiki(AssemblyInfo.GetGitHash(), io);
|
||||
ConsoleLog.Info("Basic Wiki [Ready]");
|
||||
io = new SimpleIO();
|
||||
}
|
||||
Config = MakeJsonConfig.GetDefault();
|
||||
if (helpers.notempty(json_file) == false)
|
||||
{
|
||||
json_file = "mybot.json";
|
||||
ConsoleLog.Warn("Using: mybot.json as the config");
|
||||
}
|
||||
bool ok_to_try_start = false;
|
||||
if (SimpleIO.FileType(json_file, "json") == true)
|
||||
{
|
||||
if (io.Exists(json_file))
|
||||
{
|
||||
string json = io.ReadFile(json_file);
|
||||
if (json.Length > 0)
|
||||
{
|
||||
try
|
||||
{
|
||||
Config = JsonConvert.DeserializeObject<JsonConfig>(json);
|
||||
ok_to_try_start = true;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
ConsoleLog.Warn("Unable to read config file\n moving config to " + json_file + ".old and creating a empty config\nError was: " + e.Message + "");
|
||||
io.makeOld(json_file);
|
||||
Config = new JsonConfig();
|
||||
io.WriteJsonConfig(MakeJsonConfig.GetDefault(), json_file);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ConsoleLog.Warn("Json config is empty creating an empty one for you");
|
||||
io.WriteJsonConfig(MakeJsonConfig.GetDefault(), json_file);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ConsoleLog.Warn("Json config does not Exist creating it for you");
|
||||
io.WriteJsonConfig(MakeJsonConfig.GetDefault(), json_file);
|
||||
}
|
||||
}
|
||||
else ConsoleLog.Crit("you must select a .json file for config!");
|
||||
if(ok_to_try_start == true)
|
||||
{
|
||||
Config = MakeJsonConfig.http_config_check(Config);
|
||||
if (Config.HttpAsCnC == true)
|
||||
{
|
||||
new HttpCnC(Config);
|
||||
}
|
||||
else
|
||||
{
|
||||
new CliExitOnLogout(Config);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
50
CLI/Dockerfile-ForDebug
Normal file
50
CLI/Dockerfile-ForDebug
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
#See https://aka.ms/containerfastmode to understand how Visual Studio uses this Dockerfile to build your images for faster debugging.
|
||||
|
||||
FROM mcr.microsoft.com/dotnet/core/runtime:3.1-buster-slim AS base
|
||||
WORKDIR /app
|
||||
|
||||
FROM mcr.microsoft.com/dotnet/core/sdk:3.1-buster AS build
|
||||
WORKDIR /src
|
||||
COPY ["CLI/BetterSecondBot.csproj", "CLI/"]
|
||||
COPY ["Core/BSB.csproj", "Core/"]
|
||||
COPY ["BSBshared/BSBshared.csproj", "BSBshared/"]
|
||||
COPY ["libremetaverse-core/Libremetaversetypes/LibreMetaverse.Types.csproj", "libremetaverse-core/Libremetaversetypes/"]
|
||||
COPY ["libremetaverse-core/Libremetaverse/LibreMetaverse.csproj", "libremetaverse-core/Libremetaverse/"]
|
||||
COPY ["libremetaverse-core/Libremetaverse.structureddata/LibreMetaverse.StructuredData.csproj", "libremetaverse-core/Libremetaverse.structureddata/"]
|
||||
RUN dotnet restore "CLI/BetterSecondBot.csproj"
|
||||
COPY . .
|
||||
WORKDIR "/src/CLI"
|
||||
RUN dotnet build "BetterSecondBot.csproj" -c DockerBuild -o /app/build
|
||||
|
||||
FROM build AS publish
|
||||
RUN dotnet publish "BetterSecondBot.csproj" -c DockerBuild -o /app/publish
|
||||
|
||||
FROM base AS final
|
||||
WORKDIR /app
|
||||
COPY --from=publish /app/publish .
|
||||
|
||||
ENV BotRunningInDocker='REQUIRED'
|
||||
ENV userName=''
|
||||
ENV password=''
|
||||
ENV master='Madpeter Zond'
|
||||
ENV code='DontTellAnyoneThis'
|
||||
ENV discord=''
|
||||
ENV discordGroupTarget=''
|
||||
ENV allowRLV=''
|
||||
ENV homeRegion=''
|
||||
ENV EnableHttp=''
|
||||
ENV Httpport=''
|
||||
ENV Httpkey=''
|
||||
ENV HttpRequireSigned=''
|
||||
ENV HttpHost=''
|
||||
ENV HttpAsCnC=''
|
||||
ENV DiscordFullServer=''
|
||||
ENV DiscordClientToken=''
|
||||
ENV DiscordServerID=''
|
||||
ENV DiscordServerImHistoryHours=''
|
||||
ENV DefaultSitUUID='00000000-0000-0000-0000-000000000000'
|
||||
|
||||
EXPOSE 8080
|
||||
ENV ASPNETCORE_URLS http://+:8080
|
||||
|
||||
ENTRYPOINT ["dotnet", "BetterSecondBot.dll"]
|
||||
39
CLI/HttpCnC.cs
Normal file
39
CLI/HttpCnC.cs
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
using BetterSecondBot.HttpServer;
|
||||
using BetterSecondBotShared.Json;
|
||||
using BetterSecondBotShared.logs;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
|
||||
namespace BetterSecondBot
|
||||
{
|
||||
class HttpCnC
|
||||
{
|
||||
protected http_server my_http_server;
|
||||
public HttpCnC(JsonConfig BotConfig)
|
||||
{
|
||||
ConsoleLog.Status("Mode: HTTP C&C");
|
||||
my_http_server = new http_server();
|
||||
my_http_server.HTTPCnCmode = true;
|
||||
my_http_server.ShutdownHTTP = false;
|
||||
my_http_server.start_http_server(BotConfig);
|
||||
string last_cnc_status = "";
|
||||
while (my_http_server.ShutdownHTTP == false)
|
||||
{
|
||||
string NewStatusMessage = my_http_server.GetStatus();
|
||||
if (NewStatusMessage != last_cnc_status)
|
||||
{
|
||||
last_cnc_status = NewStatusMessage;
|
||||
ConsoleLog.Status(last_cnc_status);
|
||||
}
|
||||
Thread.Sleep(5000);
|
||||
}
|
||||
ConsoleLog.Status("Shutting down now");
|
||||
if (my_http_server.GetBot != null)
|
||||
{
|
||||
my_http_server.GetBot.GetClient.Network.Logout();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
32
CLI/HttpServer/control/Actions/logout.cs
Normal file
32
CLI/HttpServer/control/Actions/logout.cs
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace BetterSecondBot.HttpServer.Control.Actions
|
||||
{
|
||||
public class Logout : HTTP_commands_post
|
||||
{
|
||||
public override string Helpfile { get { return "Makes the bot logout<br/> Returns OK,I dont want to go if accepted"; } }
|
||||
|
||||
public override string[] CallFunction(string[] args)
|
||||
{
|
||||
if (bot != null)
|
||||
{
|
||||
if (httpserver.HTTPCnCmode == true)
|
||||
{
|
||||
httpserver.KillBot();
|
||||
return new string[] { "OK", "Bot Shutting down" };
|
||||
}
|
||||
else
|
||||
{
|
||||
bot.KillMePlease();
|
||||
return new string[] { "OK", "I dont want to go" };
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return Failed("No bot logged in");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
40
CLI/HttpServer/control/Interface/cmd_lib.cs
Normal file
40
CLI/HttpServer/control/Interface/cmd_lib.cs
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace BetterSecondBot.HttpServer.Control.Interface
|
||||
{
|
||||
public class CoreCMD : HTTP_commands_post
|
||||
{
|
||||
public override string[] ArgTypes { get { return new string[] { "Text","Text" }; } }
|
||||
public override string[] ArgHints { get { return new string[] { "Command","Args (~#~ split)" }; } }
|
||||
public override string Helpfile { get { return "Calls the Commands interface via HTTP (returns OK if not rejected)"; } }
|
||||
public override int MinArgs { get { return 2; } }
|
||||
|
||||
public override string[] CallFunction(string[] args)
|
||||
{
|
||||
if (bot != null)
|
||||
{
|
||||
if (ArgsCheck(args) == true)
|
||||
{
|
||||
if (bot.GetCommandsInterface.Call(args[0], args[1]) == true)
|
||||
{
|
||||
return new string[] { "OK" };
|
||||
}
|
||||
else
|
||||
{
|
||||
return Failed("Something went wrong with the call");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return Failed("Incorrect number of args");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return Failed("No bot");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
28
CLI/HttpServer/control/Service/LoginBot.cs
Normal file
28
CLI/HttpServer/control/Service/LoginBot.cs
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
using BSB.bottypes;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using static BetterSecondBot.Program;
|
||||
|
||||
namespace BetterSecondBot.HttpServer.Control.CNC
|
||||
{
|
||||
public class CNCStartBot : HTTP_commands_post
|
||||
{
|
||||
public override string Helpfile { get { return "[C&C Mode only]<br/>Starts bot"; } }
|
||||
public override string[] CallFunction(string[] args)
|
||||
{
|
||||
if (httpserver.HTTPCnCmode == true)
|
||||
{
|
||||
if (bot == null)
|
||||
{
|
||||
httpserver.NewBot();
|
||||
httpserver.GetBot.Setup(httpserver.GetConfig, AssemblyInfo.GetGitHash());
|
||||
httpserver.GetBot.Start();
|
||||
return new string[] { "OK","Starting bot now" };
|
||||
}
|
||||
return Failed("Unable to Login the bot (it might already be running)");
|
||||
}
|
||||
return Failed("Not running as CNC");
|
||||
}
|
||||
}
|
||||
}
|
||||
22
CLI/HttpServer/control/Service/ShutdownCNC.cs
Normal file
22
CLI/HttpServer/control/Service/ShutdownCNC.cs
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
using BSB.bottypes;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using static BetterSecondBot.Program;
|
||||
|
||||
namespace BetterSecondBot.HttpServer.Control.CNC
|
||||
{
|
||||
public class ShutdownCNC : HTTP_commands_post
|
||||
{
|
||||
public override string Helpfile { get { return "[C&C Mode only]<br/>Shutsdown the C&C process"; } }
|
||||
public override string[] CallFunction(string[] args)
|
||||
{
|
||||
if (httpserver.HTTPCnCmode == true)
|
||||
{
|
||||
httpserver.ShutdownHTTP = true;
|
||||
return new string[] { "OK", "Shutting down" };
|
||||
}
|
||||
return Failed("Not running as CNC");
|
||||
}
|
||||
}
|
||||
}
|
||||
99
CLI/HttpServer/http_commands.cs
Normal file
99
CLI/HttpServer/http_commands.cs
Normal file
|
|
@ -0,0 +1,99 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Linq;
|
||||
using OpenMetaverse;
|
||||
using BSB;
|
||||
using BSB.bottypes;
|
||||
using BetterSecondBotShared.API;
|
||||
using BetterSecondBotShared.Json;
|
||||
using BetterSecondBotShared.logs;
|
||||
|
||||
namespace BetterSecondBot.HttpServer
|
||||
{
|
||||
public abstract class HTTPCommandsInterface : API_supported_interface
|
||||
{
|
||||
protected SecondBot bot;
|
||||
protected http_server httpserver;
|
||||
|
||||
protected HTTPCommandsInterface(SecondBot linktobot, http_server sethttpserver)
|
||||
{
|
||||
bot = linktobot;
|
||||
httpserver = sethttpserver;
|
||||
}
|
||||
|
||||
public string[] Call(string command, string arg)
|
||||
{
|
||||
command = command.ToLowerInvariant();
|
||||
HTTP_commands cmd = (HTTP_commands)GetCommand(command);
|
||||
if (cmd != null)
|
||||
{
|
||||
cmd.Setup(bot,httpserver);
|
||||
return cmd.CallFunction(arg.Split(new[] { "~#~" }, StringSplitOptions.None));
|
||||
}
|
||||
else
|
||||
{
|
||||
ConsoleLog.Debug("" + command + " [Failed]: I have no fucking idea what you are talking about");
|
||||
return new[] { "Failed", "I have no fucking idea what you are talking about" };
|
||||
}
|
||||
}
|
||||
}
|
||||
public class HTTPCommandsInterfaceGet : HTTPCommandsInterface
|
||||
{
|
||||
public HTTPCommandsInterfaceGet(SecondBot linktobot, http_server sethttpserver) : base(linktobot, sethttpserver)
|
||||
{
|
||||
API_type = typeof(HTTP_commands_get);
|
||||
LoadCommandsList();
|
||||
}
|
||||
}
|
||||
public class HTTPCommandsInterfacePost : HTTPCommandsInterface
|
||||
{
|
||||
public HTTPCommandsInterfacePost(SecondBot linktobot, http_server sethttpserver) : base(linktobot, sethttpserver)
|
||||
{
|
||||
API_type = typeof(HTTP_commands_post);
|
||||
LoadCommandsList();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public abstract class HTTP_commands_get : HTTP_commands
|
||||
{
|
||||
}
|
||||
public abstract class HTTP_commands_post : HTTP_commands
|
||||
{
|
||||
}
|
||||
|
||||
public abstract class HTTP_commands : API_interface
|
||||
{
|
||||
protected SecondBot bot;
|
||||
protected http_server httpserver;
|
||||
public void Setup(SecondBot setBot,http_server Sethttpserver)
|
||||
{
|
||||
bot = setBot;
|
||||
httpserver = Sethttpserver;
|
||||
}
|
||||
public virtual string[] CallFunction(string[] args)
|
||||
{
|
||||
if (ArgsCheck(args) == true)
|
||||
{
|
||||
return new[] { "OK", "No override" };
|
||||
}
|
||||
return Failed("Incorrect number of args");
|
||||
}
|
||||
protected bool ArgsCheck(string[] args)
|
||||
{
|
||||
if (args.Length >= MinArgs)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
protected string[] Failed(string why_failed)
|
||||
{
|
||||
ConsoleLog.Warn("HTTP: " + CommandName + " [Failed]: " + why_failed);
|
||||
return new string[] {"Failed",why_failed};
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
200
CLI/HttpServer/http_server.cs
Normal file
200
CLI/HttpServer/http_server.cs
Normal file
|
|
@ -0,0 +1,200 @@
|
|||
using BetterSecondBotShared.IO;
|
||||
using BetterSecondBotShared.Json;
|
||||
using BetterSecondBotShared.logs;
|
||||
using BetterSecondBotShared.Static;
|
||||
using BSB;
|
||||
using BSB.bottypes;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Net;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace BetterSecondBot.HttpServer
|
||||
{
|
||||
public class http_server
|
||||
{
|
||||
protected HttpListener listener;
|
||||
protected SecondBot Bot;
|
||||
public SecondBot GetBot { get { return Bot; } }
|
||||
protected JsonConfig Config;
|
||||
public JsonConfig GetConfig { get { return Config; } }
|
||||
protected HTTPCommandsInterfaceGet get_controler;
|
||||
protected HTTPCommandsInterfacePost post_controler;
|
||||
protected string url = "";
|
||||
protected bool require_signed_commands;
|
||||
public bool ShutdownHTTP { get; set; }
|
||||
public bool HTTPCnCmode { get; set; }
|
||||
|
||||
public string GetStatus()
|
||||
{
|
||||
string reply = "";
|
||||
if(Bot == null)
|
||||
{
|
||||
reply += "- No bot";
|
||||
}
|
||||
else
|
||||
{
|
||||
Bot.LastStatusMessage = Bot.GetStatus();
|
||||
reply += Bot.LastStatusMessage;
|
||||
}
|
||||
if(listener == null)
|
||||
{
|
||||
reply += " - No HTTP listener";
|
||||
}
|
||||
return reply;
|
||||
}
|
||||
public void NewBot()
|
||||
{
|
||||
Bot = new SecondBot();
|
||||
}
|
||||
public void KillBot()
|
||||
{
|
||||
Bot.GetClient.Network.Logout();
|
||||
Bot.GetClient.Network.Shutdown(OpenMetaverse.NetworkManager.DisconnectType.ClientInitiated);
|
||||
Bot = null;
|
||||
}
|
||||
public void start_http_server(JsonConfig setConfig)
|
||||
{
|
||||
start_http_server(setConfig, null);
|
||||
}
|
||||
public void start_http_server(SecondBot LinkBot, JsonConfig setConfig)
|
||||
{
|
||||
start_http_server(setConfig, LinkBot);
|
||||
}
|
||||
protected void start_http_server(JsonConfig setConfig, SecondBot LinkBot)
|
||||
{
|
||||
Config = setConfig;
|
||||
require_signed_commands = Config.HttpRequireSigned;
|
||||
Bot = LinkBot;
|
||||
int port = Math.Abs(Config.Httpport);
|
||||
if (Config.Httpkey.Length < 12)
|
||||
{
|
||||
Config.Httpkey = helpers.GetSHA1("" + helpers.UnixTimeNow().ToString() + "" + new Random().Next(4, 9999).ToString()).Substring(0, 12);
|
||||
}
|
||||
if (Config.HttpHost == "docker")
|
||||
{
|
||||
url = "http://*:" + port.ToString() + "/";
|
||||
}
|
||||
else
|
||||
{
|
||||
if (url.StartsWith("http://") == false)
|
||||
{
|
||||
url = "http://localhost:" + port.ToString() + "";
|
||||
}
|
||||
if (url.EndsWith("/") == false)
|
||||
{
|
||||
url = "" + url + "/";
|
||||
}
|
||||
}
|
||||
open_http_service();
|
||||
}
|
||||
|
||||
protected async Task HandleIncomingConnections()
|
||||
{
|
||||
while(Bot.KillMe == false)
|
||||
{
|
||||
HttpListenerContext ctx = await listener.GetContextAsync();
|
||||
HttpListenerRequest req = ctx.Request;
|
||||
HttpListenerResponse resp = ctx.Response;
|
||||
string test = req.Url.AbsolutePath.Substring(1);
|
||||
string[] http_args = test.Split('/', StringSplitOptions.RemoveEmptyEntries);
|
||||
byte[] data = Encoding.UTF8.GetBytes("totaly fucked");
|
||||
resp.StatusCode = 404;
|
||||
if (req.HttpMethod == "GET")
|
||||
{
|
||||
resp.StatusCode = 200;
|
||||
string command = "status";
|
||||
string arg = "";
|
||||
if (helpers.notempty(http_args) == true)
|
||||
{
|
||||
if (http_args.Length >= 1)
|
||||
{
|
||||
command = http_args[0];
|
||||
}
|
||||
if (http_args.Length == 2)
|
||||
{
|
||||
arg = http_args[1];
|
||||
}
|
||||
}
|
||||
string content = String.Join("{@}", get_controler.Call(command, arg));
|
||||
data = Encoding.UTF8.GetBytes(content);
|
||||
}
|
||||
else if (req.HttpMethod == "POST")
|
||||
{
|
||||
|
||||
string text;
|
||||
using (var reader = new StreamReader(req.InputStream,req.ContentEncoding))
|
||||
{
|
||||
text = reader.ReadToEnd();
|
||||
}
|
||||
//"command = logout & args = &passkey = Kp83VZaEhcy"
|
||||
string[] pairs = text.Split('&', StringSplitOptions.RemoveEmptyEntries);
|
||||
Dictionary<string, string> post_args = new Dictionary<string, string>();
|
||||
foreach(string B in pairs)
|
||||
{
|
||||
string[] bits = B.Split('=', StringSplitOptions.RemoveEmptyEntries);
|
||||
if(bits.Length == 2) post_args.Add(bits[0].Trim(), bits[1].Trim());
|
||||
}
|
||||
if (post_args.ContainsKey("command") == true)
|
||||
{
|
||||
if (post_args.ContainsKey("passkey") == true)
|
||||
{
|
||||
if (Config.Httpkey == post_args["passkey"])
|
||||
{
|
||||
string command = post_args["command"];
|
||||
resp.StatusCode = 200;
|
||||
string arg = "";
|
||||
if (post_args.ContainsKey("args") == true)
|
||||
{
|
||||
arg = post_args["args"];
|
||||
}
|
||||
data = Encoding.UTF8.GetBytes(String.Join("###", post_controler.Call(command, arg)));
|
||||
}
|
||||
else
|
||||
{
|
||||
data = Encoding.UTF8.GetBytes("totaly fucked");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
data = Encoding.UTF8.GetBytes("post request missing command");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
data = Encoding.UTF8.GetBytes("post request missing command");
|
||||
}
|
||||
}
|
||||
|
||||
resp.ContentType = "text/html";
|
||||
resp.ContentEncoding = Encoding.UTF8;
|
||||
resp.ContentLength64 = data.LongLength;
|
||||
await resp.OutputStream.WriteAsync(data, 0, data.Length);
|
||||
resp.Close();
|
||||
}
|
||||
}
|
||||
protected void open_http_service()
|
||||
{
|
||||
get_controler = new HTTPCommandsInterfaceGet(Bot,this);
|
||||
post_controler = new HTTPCommandsInterfacePost(Bot,this);
|
||||
Thread t = new Thread(delegate (object unused)
|
||||
{
|
||||
listener = new HttpListener();
|
||||
listener.Prefixes.Add(url);
|
||||
listener.Start();
|
||||
ConsoleLog.Status("Listening for connections on " + url + "");
|
||||
Task listenTask = HandleIncomingConnections();
|
||||
listenTask.GetAwaiter().GetResult();
|
||||
listener.Close();
|
||||
})
|
||||
{
|
||||
Name = "http thead",
|
||||
IsBackground = true
|
||||
};
|
||||
t.Start();
|
||||
}
|
||||
}
|
||||
}
|
||||
32
CLI/HttpServer/view/Basic/status.cs
Normal file
32
CLI/HttpServer/view/Basic/status.cs
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace BetterSecondBot.HttpServer.View.Basic
|
||||
{
|
||||
public class Status : HTTP_commands_get
|
||||
{
|
||||
public override int MinArgs { get { return 0; } }
|
||||
|
||||
public override string Helpfile { get { return "returns the status of the bot"; } }
|
||||
|
||||
public override string[] CallFunction(string[] args)
|
||||
{
|
||||
if (bot != null)
|
||||
{
|
||||
if (ArgsCheck(args) == true)
|
||||
{
|
||||
return new string[] { bot.GetStatus() };
|
||||
}
|
||||
else
|
||||
{
|
||||
return Failed("Incorrect number of args");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return Failed("No Bot");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
30
CLI/HttpServer/view/Inventory/getfolders.cs
Normal file
30
CLI/HttpServer/view/Inventory/getfolders.cs
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace BetterSecondBot.HttpServer.view.Inventory
|
||||
{
|
||||
class getfolders : HTTP_commands_get
|
||||
{
|
||||
public override int MinArgs { get { return 0; } }
|
||||
public override string Helpfile { get { return "returns the status of the bot"; } }
|
||||
public override string[] CallFunction(string[] args)
|
||||
{
|
||||
if (bot != null)
|
||||
{
|
||||
if (ArgsCheck(args) == true)
|
||||
{
|
||||
return new string[] { bot.GetStatus() };
|
||||
}
|
||||
else
|
||||
{
|
||||
return Failed("Incorrect number of args");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return Failed("No Bot");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
18
CLI/Properties/PublishProfiles/Linux-x64.pubxml
Normal file
18
CLI/Properties/PublishProfiles/Linux-x64.pubxml
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
https://go.microsoft.com/fwlink/?LinkID=208121.
|
||||
-->
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<PublishProtocol>FileSystem</PublishProtocol>
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
<TargetFramework>netcoreapp3.1</TargetFramework>
|
||||
<PublishDir>..\Publish\linux-x64</PublishDir>
|
||||
<RuntimeIdentifier>linux-x64</RuntimeIdentifier>
|
||||
<SelfContained>true</SelfContained>
|
||||
<PublishSingleFile>True</PublishSingleFile>
|
||||
<PublishReadyToRun>False</PublishReadyToRun>
|
||||
<PublishTrimmed>False</PublishTrimmed>
|
||||
</PropertyGroup>
|
||||
</Project>
|
||||
18
CLI/Properties/PublishProfiles/Windows-64bit.pubxml
Normal file
18
CLI/Properties/PublishProfiles/Windows-64bit.pubxml
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
https://go.microsoft.com/fwlink/?LinkID=208121.
|
||||
-->
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<PublishProtocol>FileSystem</PublishProtocol>
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
<TargetFramework>netcoreapp3.1</TargetFramework>
|
||||
<PublishDir>..\Publish\windows_x64</PublishDir>
|
||||
<RuntimeIdentifier>win-x64</RuntimeIdentifier>
|
||||
<SelfContained>true</SelfContained>
|
||||
<PublishSingleFile>True</PublishSingleFile>
|
||||
<PublishReadyToRun>False</PublishReadyToRun>
|
||||
<PublishTrimmed>False</PublishTrimmed>
|
||||
</PropertyGroup>
|
||||
</Project>
|
||||
10
CLI/Properties/launchSettings.json
Normal file
10
CLI/Properties/launchSettings.json
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
{
|
||||
"profiles": {
|
||||
"BetterSecondBot": {
|
||||
"commandName": "Project"
|
||||
},
|
||||
"Docker": {
|
||||
"commandName": "Docker"
|
||||
}
|
||||
}
|
||||
}
|
||||
11
CLI/WikiMake/wiki_footer.txt
Normal file
11
CLI/WikiMake/wiki_footer.txt
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
</div>
|
||||
<script src="https://code.jquery.com/jquery-3.3.1.js" crossorigin="anonymous"></script>
|
||||
<script src="https://cdn.datatables.net/1.10.20/js/jquery.dataTables.min.js" crossorigin="anonymous"></script>
|
||||
<script src="https://cdn.datatables.net/1.10.20/js/dataTables.bootstrap4.min.js" crossorigin="anonymous"></script>
|
||||
<script>
|
||||
$(document).ready(function() {
|
||||
$('.datatable').DataTable();
|
||||
} );
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
30
CLI/WikiMake/wiki_header.txt
Normal file
30
CLI/WikiMake/wiki_header.txt
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
<html>
|
||||
<head>
|
||||
<title>Secondbot Wiki [[AREA]]</title>
|
||||
<link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.1.3/css/bootstrap.css" rel="stylesheet" crossorigin="anonymous">
|
||||
<link href="https://cdn.datatables.net/1.10.20/css/dataTables.bootstrap4.min.css" rel="stylesheet" crossorigin="anonymous">
|
||||
</head>
|
||||
<body>
|
||||
<nav class="navbar navbar-expand-md navbar-dark bg-dark mb-3">
|
||||
<div class="container-fluid">
|
||||
<a href="[[RETURNROOT]]index.html" class="navbar-brand mr-3">SecondBot Wiki</a>
|
||||
<button type="button" class="navbar-toggler" data-toggle="collapse" data-target="#navbarCollapse">
|
||||
<span class="navbar-toggler-icon"></span>
|
||||
</button>
|
||||
<div class="collapse navbar-collapse" id="navbarCollapse">
|
||||
<div class="navbar-nav">
|
||||
<a href="[[SUBFOLDER]]Core.html" class="nav-item nav-link [[CoreActive]]">Main commands [Core]</a>
|
||||
<a href="[[SUBFOLDER]]CLI.html" class="nav-item nav-link [[CLIActive]]">Command Line [Parameters]</a>
|
||||
<a href="[[SUBFOLDER]]JSON.html" class="nav-item nav-link [[JSONActive]]">JSON [Bot Config file]</a>
|
||||
<a href="[[SUBFOLDER]]RLVapi.html" class="nav-item nav-link [[RLVapiActive]]">Restrained Love API [RLV]</a>
|
||||
<a href="[[SUBFOLDER]]HTTPget.html" class="nav-item nav-link [[HTTPgetActive]]">Get [HTTP]</a>
|
||||
<a href="[[SUBFOLDER]]HTTPpost.html" class="nav-item nav-link [[HTTPpostActive]]">Post [HTTP]</a>
|
||||
</div>
|
||||
<div class="navbar-nav ml-auto">
|
||||
<a href="https://bitbucket.org/streamadmin/secondbot/src/master/" target="_BLANK" class="nav-item nav-link">Get Source</a>
|
||||
<a href="secondlife:///app/group/cbda0f35-1c0b-2a45-e693-62a63a8f9d88/about" target="_BLANK" class="nav-item nav-link">SL group</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
<div class="container-fluid">
|
||||
340
CLI/WikiMake/wikimake.cs
Normal file
340
CLI/WikiMake/wikimake.cs
Normal file
|
|
@ -0,0 +1,340 @@
|
|||
using BetterSecondBotShared.API;
|
||||
using BetterSecondBotShared.IO;
|
||||
using BetterSecondBotShared.Json;
|
||||
using BetterSecondBotShared.logs;
|
||||
using BSB;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
|
||||
namespace BetterSecondBot.WikiMake
|
||||
{
|
||||
class DebugModeCreateWiki
|
||||
{
|
||||
protected Dictionary<string, KeyValuePair<int, string>> api_reports = new Dictionary<string, KeyValuePair<int, string>>();
|
||||
protected string html_header = "";
|
||||
protected string html_footer = "";
|
||||
protected string buildVersion = "";
|
||||
protected SimpleIO io;
|
||||
protected Dictionary<string,string> seen_command_names = new Dictionary<string, string>();
|
||||
|
||||
public static string ReadResourceFile(string filename)
|
||||
{
|
||||
try
|
||||
{
|
||||
var assembly = Assembly.GetExecutingAssembly();
|
||||
string resourceName = assembly.GetManifestResourceNames().Single(str => str.EndsWith(filename));
|
||||
string result = "";
|
||||
using (Stream stream = assembly.GetManifestResourceStream(resourceName))
|
||||
using (StreamReader reader = new StreamReader(stream))
|
||||
{
|
||||
result = reader.ReadToEnd();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
return e.Message;
|
||||
}
|
||||
}
|
||||
public string CreateRoot()
|
||||
{
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.Append(html_header);
|
||||
sb.Append("<h3>Build: ");
|
||||
sb.Append(buildVersion);
|
||||
sb.Append("</h3><br/>");
|
||||
sb.Append("<table class='table table-striped table-bordered'><thead><tr><th>Interface</th><th>Commands</th><th>Status</th></tr></thead><tbody>");
|
||||
foreach (KeyValuePair<string,KeyValuePair<int, string>> entry in api_reports)
|
||||
{
|
||||
sb.Append("<tr>");
|
||||
sb.Append("<td><a href='[[SUBFOLDER]]");
|
||||
sb.Append(entry.Key);
|
||||
sb.Append(".html'>");
|
||||
sb.Append(entry.Key);
|
||||
sb.Append("</a></td>");
|
||||
sb.Append("<td>");
|
||||
sb.Append(entry.Value.Key.ToString());
|
||||
sb.Append("</td><td>");
|
||||
sb.Append(entry.Value.Value);
|
||||
sb.Append("</td></tr>");
|
||||
}
|
||||
sb.Append("</tbody></table>");
|
||||
sb.Replace("[[AREA]]", "Home");
|
||||
sb.Replace("[[SUBFOLDER]]", "files/");
|
||||
sb.Replace("[[RETURNROOT]]", "");
|
||||
sb = MenuActive(sb, "Home");
|
||||
sb.Append(html_footer);
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
protected StringBuilder MenuActive(StringBuilder index,string area)
|
||||
{
|
||||
Dictionary<string, string> active_swaps = new Dictionary<string, string>
|
||||
{
|
||||
{ "CoreActive", "" },
|
||||
{ "CLIActive", "" },
|
||||
{ "JSONActive", "" },
|
||||
{ "RLVapiActive", "" },
|
||||
{ "HTTPgetActive", "" },
|
||||
{ "HTTPpostActive", "" }
|
||||
};
|
||||
active_swaps["" + area + "Active"] = "Active";
|
||||
foreach(KeyValuePair<string,string> pair in active_swaps)
|
||||
{
|
||||
index = index.Replace("[["+ pair.Key+"]]", pair.Value);
|
||||
}
|
||||
return index;
|
||||
}
|
||||
|
||||
protected void InterfaceCommands(string area, API_supported_interface shared_interface,bool track_commands=false)
|
||||
{
|
||||
string[] cmds = shared_interface.GetCommandsList();
|
||||
string interface_name = shared_interface.GetType().Name;
|
||||
foreach (string c in cmds)
|
||||
{
|
||||
if (track_commands == true)
|
||||
{
|
||||
if (seen_command_names.ContainsKey(c) == false)
|
||||
{
|
||||
seen_command_names.Add(c, interface_name);
|
||||
}
|
||||
else
|
||||
{
|
||||
ConsoleLog.Debug("command " + c + " from " + interface_name + " overlaps an ready loaded command from "+ seen_command_names[c]+"");
|
||||
}
|
||||
}
|
||||
string workspace = shared_interface.GetCommandWorkspace(c);
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.Append(html_header);
|
||||
sb.Append("<h3>Build: ");
|
||||
sb.Append(buildVersion);
|
||||
sb.Append("</h3><br/>");
|
||||
sb.Append("<h4>Interface: <a href='[[AREA]].html'>[[AREA]]</a>");
|
||||
if(workspace != "")
|
||||
{
|
||||
sb.Append(" / <a href='[[AREA]][[WORKSPACE]].html'>[[WORKSPACE]]</a>");
|
||||
}
|
||||
sb.Append("</h4><hr/><h3>[[COMMAND]]</h3>");
|
||||
int loop = 0;
|
||||
int minargs = shared_interface.GetCommandArgs(c);
|
||||
string[] arg_types = shared_interface.GetCommandArgTypes(c);
|
||||
string[] arg_hints = shared_interface.GetCommandArgHints(c);
|
||||
if(area == "Core")
|
||||
{
|
||||
string example_call = "Example: [[COMMAND]]";
|
||||
string preaddon = "|||";
|
||||
string addon = "";
|
||||
while (loop < minargs)
|
||||
{
|
||||
example_call += preaddon;
|
||||
example_call += addon;
|
||||
preaddon = "";
|
||||
addon = "~#~";
|
||||
string hint_value = "";
|
||||
if (arg_hints.Length > loop)
|
||||
{
|
||||
if (arg_hints[loop] != null)
|
||||
{
|
||||
string[] bits = arg_hints[loop].Split("<br/>", StringSplitOptions.RemoveEmptyEntries);
|
||||
if (bits.Length >= 1)
|
||||
{
|
||||
hint_value = bits[0];
|
||||
}
|
||||
}
|
||||
}
|
||||
if (hint_value != "")
|
||||
{
|
||||
example_call += hint_value;
|
||||
}
|
||||
else
|
||||
{
|
||||
example_call += "Not sure";
|
||||
ConsoleLog.Debug("[WikiMake] " + area + " Command " + c + " missing some required hint values");
|
||||
}
|
||||
loop++;
|
||||
}
|
||||
sb.Append(example_call);
|
||||
sb.Append("<hr style='border-top: 1px dashed #dcdcdc;'>");
|
||||
}
|
||||
sb.Append("[[HELP]]");
|
||||
if (arg_types.Length > 0)
|
||||
{
|
||||
sb.Append("<hr/><h4>Args helper</h4>");
|
||||
loop = 0;
|
||||
|
||||
sb.Append("<table class='table table-striped table-bordered'><thead><tr><td>Num</td><th>Type</th><th>Required</th><th>Hint</th></tr></thead><tbody>");
|
||||
while (loop < arg_types.Length)
|
||||
{
|
||||
string hint = "";
|
||||
if (arg_hints.Length > loop)
|
||||
{
|
||||
hint = arg_hints[loop];
|
||||
}
|
||||
string Required = "X";
|
||||
if ((loop + 1) > minargs)
|
||||
{
|
||||
Required = "";
|
||||
}
|
||||
sb.Append("<tr><td>" + (loop + 1).ToString() + "</td><td>" + arg_types[loop] + "</td><td>" + Required + "</td><td>" + hint + "</td></tr>");
|
||||
loop++;
|
||||
}
|
||||
sb.Append("</tbody></table>");
|
||||
}
|
||||
sb.Append(html_footer);
|
||||
|
||||
sb.Replace("[[COMMAND]]", c);
|
||||
sb.Replace("[[HELP]]", shared_interface.GetCommandHelp(c));
|
||||
sb.Replace("[[MINARGS]]", minargs.ToString());
|
||||
sb.Replace("[[WORKSPACE]]", workspace);
|
||||
sb.Replace("[[AREA]]", area);
|
||||
sb.Replace("[[SUBFOLDER]]", "");
|
||||
sb.Replace("[[RETURNROOT]]", "../");
|
||||
sb = MenuActive(sb, area);
|
||||
string target_file = "" + area + "" + workspace + "" + c + ".html";
|
||||
io.writefile(target_file, sb.ToString());
|
||||
}
|
||||
}
|
||||
protected void InterfaceWorkspaces(string area, API_supported_interface shared_interface)
|
||||
{
|
||||
string[] cmds = shared_interface.GetCommandsList();
|
||||
foreach (string workspace in shared_interface.GetAllWorkspaces())
|
||||
{
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.Append(html_header);
|
||||
sb.Append("<h3>Interface: <a href='[[AREA]].html'>[[AREA]]</a>");
|
||||
if (workspace != "")
|
||||
{
|
||||
sb.Append(" / [[WORKSPACE]]");
|
||||
}
|
||||
sb.Append("</h3><br/>");
|
||||
sb.Append("<h4>Build: ");
|
||||
sb.Append(buildVersion);
|
||||
sb.Append("</h4><br/>");
|
||||
sb.Append("<table class='datatable table table-striped table-bordered'><thead><tr><th>Command</th><th>Min args</th></tr></thead><tbody>");
|
||||
foreach(string c in cmds)
|
||||
{
|
||||
if(shared_interface.GetCommandWorkspace(c) == workspace)
|
||||
{
|
||||
int args = shared_interface.GetCommandArgs(c);
|
||||
sb.Append("<tr><td><a href='[[AREA]]");
|
||||
sb.Append(workspace);
|
||||
sb.Append(c);
|
||||
sb.Append(".html'>");
|
||||
sb.Append(c);
|
||||
sb.Append("</a></td><td>");
|
||||
sb.Append(args.ToString());
|
||||
sb.Append("</td></tr>");
|
||||
}
|
||||
}
|
||||
sb.Append("</tbody></table>");
|
||||
sb.Replace("[[SUBFOLDER]]", "");
|
||||
sb.Replace("[[RETURNROOT]]", "../");
|
||||
sb.Replace("[[WORKSPACE]]", workspace);
|
||||
sb.Replace("[[AREA]]", area);
|
||||
sb.Append(html_footer);
|
||||
sb = MenuActive(sb, area);
|
||||
string target_file = "" + area + "" + workspace + ".html";
|
||||
io.writefile(target_file, sb.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
protected void InterfaceIndex(string area, API_supported_interface shared_interface)
|
||||
{
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.Append(html_header);
|
||||
sb.Append("<h3>Interface:");
|
||||
sb.Append(area);
|
||||
sb.Append("</h3><br/>");
|
||||
sb.Append("<h4>Build: ");
|
||||
sb.Append(buildVersion);
|
||||
sb.Append("</h4><br/>");
|
||||
string[] cmds = shared_interface.GetCommandsList();
|
||||
sb.Append("<table class='datatable table table-striped table-bordered'><thead><tr><th>Workspace</th><th>Commands</th></tr></thead><tbody>");
|
||||
foreach (string workspace in shared_interface.GetAllWorkspaces())
|
||||
{
|
||||
int commands_count = 0;
|
||||
foreach (string c in cmds)
|
||||
{
|
||||
if (shared_interface.GetCommandWorkspace(c) == workspace)
|
||||
{
|
||||
commands_count++;
|
||||
}
|
||||
}
|
||||
|
||||
string workspace_link = "<a href='[[AREA]]" + workspace + ".html'>" + workspace + "</a>";
|
||||
sb.Append("<tr><td>");
|
||||
sb.Append(workspace_link);
|
||||
sb.Append("</td><td>");
|
||||
sb.Append(commands_count.ToString());
|
||||
sb.Append("</td></tr>");
|
||||
}
|
||||
sb.Append("</tbody></table>");
|
||||
sb.Replace("[[SUBFOLDER]]", "");
|
||||
sb.Replace("[[RETURNROOT]]", "../");
|
||||
sb.Replace("[[AREA]]", area);
|
||||
sb.Append(html_footer);
|
||||
sb = MenuActive(sb, area);
|
||||
io.writefile(""+ area+".html", sb.ToString());
|
||||
}
|
||||
protected void InterfaceWiki(string area,API_supported_interface shared_interface, bool track_commands = false)
|
||||
{
|
||||
ConsoleLog.Info("[WIKI] Starting area " + area + "");
|
||||
// create index
|
||||
InterfaceIndex(area, shared_interface);
|
||||
|
||||
// create workspaces
|
||||
InterfaceWorkspaces(area, shared_interface);
|
||||
|
||||
// create commands
|
||||
InterfaceCommands(area, shared_interface, track_commands);
|
||||
ConsoleLog.Info("[WIKI] Done with area");
|
||||
}
|
||||
|
||||
public DebugModeCreateWiki(string Version, SimpleIO shareio)
|
||||
{
|
||||
io = shareio;
|
||||
buildVersion = Version;
|
||||
html_header = ReadResourceFile("wiki_header.txt");
|
||||
html_footer = ReadResourceFile("wiki_footer.txt");
|
||||
io.ChangeRoot("wiki");
|
||||
io.ChangeRoot("wiki/files");
|
||||
// CLI
|
||||
Options cli = new Options();
|
||||
api_reports.Add("CLI", new KeyValuePair<int, string>(cli.ApiCommandsCount, "Ready"));
|
||||
InterfaceWiki("CLI", cli);
|
||||
|
||||
// JSONcfg
|
||||
MakeJsonConfig defaultJson = new MakeJsonConfig();
|
||||
api_reports.Add("JSON", new KeyValuePair<int, string>(defaultJson.ApiCommandsCount, "Ready"));
|
||||
InterfaceWiki("JSON", defaultJson);
|
||||
|
||||
// CMD
|
||||
BSB.Commands.CoreCommandsInterface cmd = new BSB.Commands.CoreCommandsInterface(null);
|
||||
api_reports.Add("Core", new KeyValuePair<int, string>(cmd.ApiCommandsCount, "Basic"));
|
||||
InterfaceWiki("Core", cmd,true);
|
||||
|
||||
// RLVapi
|
||||
BSB.RLV.RLVcontrol RLVapi = new BSB.RLV.RLVcontrol(null);
|
||||
api_reports.Add("RLVapi", new KeyValuePair<int, string>(RLVapi.ApiCommandsCount, "Basic"));
|
||||
InterfaceWiki("RLVapi", RLVapi, true);
|
||||
|
||||
|
||||
// HTTP get
|
||||
BetterSecondBot.HttpServer.HTTPCommandsInterfaceGet http_get = new BetterSecondBot.HttpServer.HTTPCommandsInterfaceGet(null,null);
|
||||
api_reports.Add("HTTPget", new KeyValuePair<int, string>(http_get.ApiCommandsCount, "Limited"));
|
||||
InterfaceWiki("HTTPget", http_get);
|
||||
|
||||
// HTTP post
|
||||
BetterSecondBot.HttpServer.HTTPCommandsInterfacePost http_post = new BetterSecondBot.HttpServer.HTTPCommandsInterfacePost(null,null);
|
||||
api_reports.Add("HTTPpost", new KeyValuePair<int, string>(http_post.ApiCommandsCount, "Limited"));
|
||||
InterfaceWiki("HTTPpost", http_post);
|
||||
|
||||
io.ChangeRoot("wiki");
|
||||
io.writefile("index.html", CreateRoot());
|
||||
}
|
||||
}
|
||||
}
|
||||
25
Core/BSB.csproj
Normal file
25
Core/BSB.csproj
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netcoreapp3.1</TargetFramework>
|
||||
<Configurations>Debug;Release;DockerBuild</Configurations>
|
||||
<Platforms>x64</Platforms>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DockerBuild|x64'">
|
||||
<ErrorReport>none</ErrorReport>
|
||||
<DockerDefaultTargetOS>Linux</DockerDefaultTargetOS>
|
||||
<PublishTrimmed>false</PublishTrimmed>
|
||||
<PublishSingleFile>false</PublishSingleFile>
|
||||
<TreatWarningsAsErrors>false</TreatWarningsAsErrors>
|
||||
<RuntimeIdentifier>linux-x64</RuntimeIdentifier>
|
||||
</PropertyGroup> <ItemGroup>
|
||||
<PackageReference Include="Discord.Net.Webhook" Version="2.1.1" />
|
||||
<PackageReference Include="Discord.Net.WebSocket" Version="2.1.1" />
|
||||
<PackageReference Include="RestSharp" Version="106.10.1" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\BSBshared\BSBshared.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
32
Core/Commands/Chat/im.cs
Normal file
32
Core/Commands/Chat/im.cs
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Linq;
|
||||
using OpenMetaverse;
|
||||
|
||||
namespace BSB.Commands.Chat
|
||||
{
|
||||
class IM : CoreCommand
|
||||
{
|
||||
public override string[] ArgTypes { get { return new[] { "Avatar", "Text" }; } }
|
||||
public override string[] ArgHints { get { return new[] { "Avatar [UUID or Firstname Lastname]","Message" }; } }
|
||||
public override string Helpfile { get { return "Makes the bot send a IM to an avatar<br/>Example: IM|||289c3e36-69b3-40c5-9229-0c6a5d230766~#~Hello Mad I am a bot"; } }
|
||||
public override int MinArgs { get { return 2; } }
|
||||
public override bool CallFunction(string[] args)
|
||||
{
|
||||
if (base.CallFunction(args) == true)
|
||||
{
|
||||
if (UUID.TryParse(args[0], out UUID target_av) == true)
|
||||
{
|
||||
bot.GetClient.Self.InstantMessage(target_av, args[1]);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return Failed("Not a vaild UUID");
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
32
Core/Commands/Chat/say.cs
Normal file
32
Core/Commands/Chat/say.cs
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Linq;
|
||||
using OpenMetaverse;
|
||||
|
||||
namespace BSB.Commands.Chat
|
||||
{
|
||||
class Say : CoreCommand
|
||||
{
|
||||
public override string[] ArgTypes { get { return new[] { "Mixed","Text" }; } }
|
||||
public override string[] ArgHints { get { return new[] { "Message or channel","Message" }; } }
|
||||
public override string Helpfile { get { return "Makes the bot talk via chat<br/>Example: say|||Hello<br/> Example: say|||12~#~Goodbye"; } }
|
||||
public override int MinArgs { get { return 1; } }
|
||||
public override bool CallFunction(string[] args)
|
||||
{
|
||||
if(base.CallFunction(args) == true)
|
||||
{
|
||||
string message = args[0];
|
||||
int channel = 0;
|
||||
if (args.Count() == 2)
|
||||
{
|
||||
message = args[1];
|
||||
int.TryParse(args[0], out channel);
|
||||
}
|
||||
bot.GetClient.Self.Chat(message, channel, ChatType.Normal);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
47
Core/Commands/Dialogs/DialogRelay.cs
Normal file
47
Core/Commands/Dialogs/DialogRelay.cs
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
using OpenMetaverse;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace BSB.Commands.Dialogs
|
||||
{
|
||||
class DialogRelay : CoreCommand
|
||||
{
|
||||
public override string[] ArgTypes { get { return new[] { "Smart" }; } }
|
||||
public override string[] ArgHints { get { return new[] { "Channel (Any number),Avatar UUID,Avatar name,HTTPurl<br/>Clear" }; } }
|
||||
public override string Helpfile { get { return "Updates the relay target (you can have 1 of each type)<br/>Clear will disable them all"; } }
|
||||
public override int MinArgs { get { return 1; } }
|
||||
public override bool CallFunction(string[] args)
|
||||
{
|
||||
if (base.CallFunction(args) == true)
|
||||
{
|
||||
if(args[0] != "Clear")
|
||||
{
|
||||
if (UUID.TryParse(args[0], out UUID avatar) == true)
|
||||
{
|
||||
bot.SetRelayDialogsAvatar(avatar);
|
||||
}
|
||||
else if (args[0].StartsWith("http") == true)
|
||||
{
|
||||
bot.SetRelayDialogsHTTP(args[0]);
|
||||
}
|
||||
else if (int.TryParse(args[0], out int channel) == true)
|
||||
{
|
||||
bot.SetRelayDialogsChannel(channel);
|
||||
}
|
||||
else return Failed("Not a vaild option");
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
bot.SetRelayDialogsAvatar(UUID.Zero);
|
||||
bot.SetRelayDialogsChannel(0);
|
||||
bot.SetRelayDialogsHTTP("");
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
28
Core/Commands/Dialogs/DialogResponce.cs
Normal file
28
Core/Commands/Dialogs/DialogResponce.cs
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
using OpenMetaverse;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace BSB.Commands.Dialogs
|
||||
{
|
||||
class DialogResponce : CoreCommand
|
||||
{
|
||||
public override string[] ArgTypes { get { return new[] { "Number","Text" }; } }
|
||||
public override string[] ArgHints { get { return new[] { "DialogID","Button to click" }; } }
|
||||
public override string Helpfile { get { return "Makes the bot interact with the dialog [ARG 1] with the button [ARG 2]"; } }
|
||||
public override int MinArgs { get { return 2; } }
|
||||
public override bool CallFunction(string[] args)
|
||||
{
|
||||
if (base.CallFunction(args) == true)
|
||||
{
|
||||
if (int.TryParse(args[0], out int dialogid) == true)
|
||||
{
|
||||
return bot.DialogReply(dialogid, args[1]);
|
||||
}
|
||||
else return Failed("Invaild dialog id");
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
27
Core/Commands/Dialogs/DialogTrack.cs
Normal file
27
Core/Commands/Dialogs/DialogTrack.cs
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace BSB.Commands.Dialogs
|
||||
{
|
||||
class DialogTrack : CoreCommand
|
||||
{
|
||||
public override string[] ArgTypes { get { return new[] { "True|False" }; } }
|
||||
public override string[] ArgHints { get { return new[] { "Status" }; } }
|
||||
public override string Helpfile { get { return "Should the bot track dialogs and send them to the relays setup?"; } }
|
||||
public override int MinArgs { get { return 1; } }
|
||||
public override bool CallFunction(string[] args)
|
||||
{
|
||||
if (base.CallFunction(args) == true)
|
||||
{
|
||||
if(bool.TryParse(args[0],out bool status) == true)
|
||||
{
|
||||
bot.SetTrackDialogs(status);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
111
Core/Commands/Group/GroupInvite.cs
Normal file
111
Core/Commands/Group/GroupInvite.cs
Normal file
|
|
@ -0,0 +1,111 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using OpenMetaverse;
|
||||
using BetterSecondBotShared.logs;
|
||||
|
||||
namespace BSB.Commands.Group
|
||||
{
|
||||
public class GroupInvite : CoreCommand
|
||||
{
|
||||
public override string[] ArgTypes { get { return new[] { "UUID", "Avatar", "UUID" }; } }
|
||||
public override string[] ArgHints { get { return new[] { "GROUP", "Avatar [UUID or Firstname Lastname]", "Role" }; } }
|
||||
public override string Helpfile { get { return "Invites the avatar [ARG 2] to the Group [ARG 1] {optional with the Role [ARG 3]} otherwise to role Everyone"; } }
|
||||
public override int MinArgs { get { return 2; } }
|
||||
|
||||
protected void ForRealGroupInvite(string[] args,UUID group,UUID avatar)
|
||||
{
|
||||
UUID target_role = UUID.Zero;
|
||||
if (args.Length == 3)
|
||||
{
|
||||
UUID.TryParse(args[2], out target_role);
|
||||
}
|
||||
List<UUID> invite_roles = new List<UUID>();
|
||||
if (target_role != UUID.Zero) invite_roles.Add(target_role);
|
||||
else invite_roles.Add(UUID.Zero);
|
||||
bot.GetClient.Groups.Invite(group, invite_roles, avatar);
|
||||
}
|
||||
public override void Callback(string[] args, EventArgs e)
|
||||
{
|
||||
GroupMembersReplyEventArgs reply = (GroupMembersReplyEventArgs)e;
|
||||
if (UUID.TryParse(args[0], out UUID target_group) == true)
|
||||
{
|
||||
if (UUID.TryParse(args[1], out UUID target_avatar) == true)
|
||||
{
|
||||
if (reply.GroupID == target_group)
|
||||
{
|
||||
if (reply.Members.ContainsKey(target_avatar) == false)
|
||||
{
|
||||
ForRealGroupInvite(args, target_group, target_avatar);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ConsoleLog.Crit("Callback sent for the wrong group as part of group invite!");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
public override bool CallFunction(string[] args)
|
||||
{
|
||||
if (base.CallFunction(args) == true)
|
||||
{
|
||||
if (UUID.TryParse(args[0], out UUID target_group) == true)
|
||||
{
|
||||
if (UUID.TryParse(args[1], out UUID target_avatar) == true)
|
||||
{
|
||||
if (bot.MyGroups.ContainsKey(target_group) == true)
|
||||
{
|
||||
if (bot.GetAllowGroupInvite(target_avatar) == true)
|
||||
{
|
||||
if (bot.FastCheckInGroup(target_group, target_avatar) == false)
|
||||
{
|
||||
if (bot.NeedReloadGroupData(target_group) == true)
|
||||
{
|
||||
if (bot.CreateAwaitEventReply("groupmembersreply", this, args) == true)
|
||||
{
|
||||
bot.GroupInviteLockoutArm(target_avatar); // enable 120 sec cooldown
|
||||
bot.GetClient.Groups.RequestGroupMembers(target_group);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return Failed("Unable to await reply");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
bot.GroupInviteLockoutArm(target_avatar); // enable 120 sec cooldown
|
||||
ForRealGroupInvite(args, target_group, target_avatar);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return true; // they are in the group (or we have old data) retry in like 2 mins
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return Failed("Group invite to this avatar is on 120sec cooldown");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return Failed("I am not a member of that group");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return Failed("Invaild avatar UUID");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return Failed("Invaild group UUID");
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
50
Core/Commands/Group/GroupNotice.cs
Normal file
50
Core/Commands/Group/GroupNotice.cs
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
using BetterSecondBotShared.Static;
|
||||
using OpenMetaverse;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace BSB.Commands.Group
|
||||
{
|
||||
class Groupnotice : CoreCommand
|
||||
{
|
||||
public override string[] ArgTypes { get { return new[] { "UUID", "TEXT","TEXT" }; } }
|
||||
public override string[] ArgHints { get { return new[] { "Group", "Message/Title", "Message" }; } }
|
||||
public override string Helpfile { get { return "Sends a group notice to [ARG 1] with the message [ARG 2]<hr/>if given 3 Args: Sends a group notice to [ARG 1] with the title [ARG 2] and the message [ARG 3]"; } }
|
||||
public override int MinArgs { get { return 2; } }
|
||||
public override bool CallFunction(string[] args)
|
||||
{
|
||||
if (base.CallFunction(args) == true)
|
||||
{
|
||||
if (UUID.TryParse(args[0], out UUID targetgroup) == true)
|
||||
{
|
||||
if (bot.MyGroups.ContainsKey(targetgroup) == true)
|
||||
{
|
||||
string Noticetitle = "GroupNotice@"+ helpers.UnixTimeNow().ToString()+"";
|
||||
string Noticemessage = "";
|
||||
if (args.Length == 3)
|
||||
{
|
||||
Noticetitle = args[1];
|
||||
}
|
||||
Noticemessage = args[^1];
|
||||
GroupNotice NewNotice = new GroupNotice();
|
||||
NewNotice.Subject = Noticetitle;
|
||||
NewNotice.Message = Noticemessage;
|
||||
NewNotice.OwnerID = bot.GetClient.Self.AgentID;
|
||||
bot.GetClient.Groups.SendGroupNotice(targetgroup, NewNotice);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return Failed("Unkown group");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return Failed("Invaild UUID");
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
26
Core/Commands/Group/getGroupList.cs
Normal file
26
Core/Commands/Group/getGroupList.cs
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using OpenMetaverse;
|
||||
|
||||
namespace BSB.Commands.Group
|
||||
{
|
||||
public class GetGroupList : CoreGroupCommand_SmartReply_auto
|
||||
{
|
||||
public override string Helpfile { get { return "Returns a csv of known groups NAME=UUID,NAME=UUID... "; } }
|
||||
protected override string RunFunction()
|
||||
{
|
||||
string reply = "";
|
||||
string addon = "";
|
||||
foreach (KeyValuePair<UUID, OpenMetaverse.Group> groupdata in bot.MyGroups)
|
||||
{
|
||||
reply += addon;
|
||||
reply += groupdata.Value.Name;
|
||||
reply += "=";
|
||||
reply += groupdata.Key;
|
||||
addon = ",";
|
||||
}
|
||||
return reply;
|
||||
}
|
||||
}
|
||||
}
|
||||
61
Core/Commands/Group/getGroupRoles.cs
Normal file
61
Core/Commands/Group/getGroupRoles.cs
Normal file
|
|
@ -0,0 +1,61 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using OpenMetaverse;
|
||||
|
||||
namespace BSB.Commands.Group
|
||||
{
|
||||
public class GetGroupRoles : CoreGroupCommand_SmartReply_Group
|
||||
{
|
||||
public override string Helpfile { get { return "Returns group=UUID@@@rolename=UUID,rolename=UUID ... "; } }
|
||||
|
||||
public override bool CallFunction(string[] args)
|
||||
{
|
||||
if (base.CallFunction(args) == true)
|
||||
{
|
||||
if (UUID.TryParse(args[1], out _) == true)
|
||||
{
|
||||
if (bot.GetCommandsInterface.SmartCommandReply(args[0], "Vaildate", CommandName, true) == true)
|
||||
{
|
||||
if (bot.CreateAwaitEventReply("grouproles", this, args) == true)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return Failed("Unable to await reply");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return Failed("Smart reply [ARG 1] is not vaild");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return Failed("Invaild group UUID");
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public override void Callback(string[] args, EventArgs e)
|
||||
{
|
||||
GroupRolesDataReplyEventArgs rolesData = (GroupRolesDataReplyEventArgs)e;
|
||||
string reply = "group=" + args[1] + "@@@";
|
||||
string addon = "";
|
||||
foreach(KeyValuePair<UUID,GroupRole> data in rolesData.Roles)
|
||||
{
|
||||
if (data.Key != UUID.Zero)
|
||||
{
|
||||
reply += addon;
|
||||
reply += data.Value.Name;
|
||||
reply += "=";
|
||||
reply += data.Key.ToString();
|
||||
addon = ",";
|
||||
}
|
||||
}
|
||||
bot.GetCommandsInterface.SmartCommandReply(args[0], reply, CommandName);
|
||||
}
|
||||
}
|
||||
}
|
||||
66
Core/Commands/Group/group.cs
Normal file
66
Core/Commands/Group/group.cs
Normal file
|
|
@ -0,0 +1,66 @@
|
|||
using OpenMetaverse;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace BSB.Commands.Group
|
||||
{
|
||||
public abstract class CoreGroupCommand_SmartReply : CoreCommand
|
||||
{
|
||||
public override string[] ArgTypes { get { return new[] { "Smart" }; } }
|
||||
public override string[] ArgHints { get { return new[] { "Mixed [Channel|Avatar uuid|Avatar name|http url]"}; } }
|
||||
public override int MinArgs { get { return 1; } }
|
||||
}
|
||||
public abstract class CoreGroupCommand_SmartReply_auto : CoreGroupCommand_SmartReply
|
||||
{
|
||||
protected virtual string RunFunction()
|
||||
{
|
||||
return "";
|
||||
}
|
||||
public override bool CallFunction(string[] args)
|
||||
{
|
||||
if (base.CallFunction(args) == true)
|
||||
{
|
||||
return bot.GetCommandsInterface.SmartCommandReply(args[0], RunFunction(), CommandName);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public abstract class CoreGroupCommand_SmartReply_Group : CoreCommand
|
||||
{
|
||||
public override string[] ArgTypes { get { return new[] { "Mixed", "UUID" }; } }
|
||||
public override string[] ArgHints { get { return new[] { "Smart reply [Channel|IM uuid|http url]", "Group" }; } }
|
||||
public override int MinArgs { get { return 2; } }
|
||||
}
|
||||
|
||||
public abstract class CoreGroupCommand_SmartReply_Group_auto : CoreGroupCommand_SmartReply_Group
|
||||
{
|
||||
protected virtual string RunFunction(UUID group)
|
||||
{
|
||||
return "";
|
||||
}
|
||||
public override bool CallFunction(string[] args)
|
||||
{
|
||||
if (base.CallFunction(args) == true)
|
||||
{
|
||||
if (UUID.TryParse(args[1], out UUID targetgroup) == true)
|
||||
{
|
||||
if (bot.MyGroups.ContainsKey(targetgroup) == true)
|
||||
{
|
||||
return bot.GetCommandsInterface.SmartCommandReply(args[0], RunFunction(targetgroup), CommandName);
|
||||
}
|
||||
else
|
||||
{
|
||||
return Failed("Unknown group");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return Failed("Invaild UUID");
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
60
Core/Commands/Group/groupchat.cs
Normal file
60
Core/Commands/Group/groupchat.cs
Normal file
|
|
@ -0,0 +1,60 @@
|
|||
using OpenMetaverse;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace BSB.Commands.Group
|
||||
{
|
||||
class Groupchat : CoreCommand
|
||||
{
|
||||
public override string[] ArgTypes { get { return new[] { "UUID","TEXT" }; } }
|
||||
public override string[] ArgHints { get { return new[] { "Group","Message" }; } }
|
||||
public override string Helpfile { get { return "Sends a message [ARG 2] to the group [ARG 1]"; } }
|
||||
public override int MinArgs { get { return 2; } }
|
||||
public override bool CallFunction(string[] args)
|
||||
{
|
||||
if (base.CallFunction(args) == true)
|
||||
{
|
||||
if (UUID.TryParse(args[0], out UUID targetgroup) == true)
|
||||
{
|
||||
if (bot.MyGroups.ContainsKey(targetgroup) == true)
|
||||
{
|
||||
if (bot.GetActiveGroupchatSessions.Contains(targetgroup) == true)
|
||||
{
|
||||
Callback(args, null);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (bot.CreateAwaitEventReply("groupchatjoin", this, args) == true)
|
||||
{
|
||||
bot.GetClient.Self.RequestJoinGroupChat(targetgroup);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return Failed("Unable to await reply");
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return Failed("Unkown group");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return Failed("Invaild UUID");
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
public override void Callback(string[] args, EventArgs e)
|
||||
{
|
||||
if (UUID.TryParse(args[0], out UUID targetgroup) == true)
|
||||
{
|
||||
bot.GetClient.Self.InstantMessageGroup(targetgroup, args[1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
15
Core/Commands/Group/groupchatAnyUnread.cs
Normal file
15
Core/Commands/Group/groupchatAnyUnread.cs
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace BSB.Commands.Group
|
||||
{
|
||||
class GroupchatAnyUnread : CoreGroupCommand_SmartReply_auto
|
||||
{
|
||||
public override string Helpfile { get { return "Returns True|False via the smart reply target if there are any unread group ims"; } }
|
||||
protected override string RunFunction()
|
||||
{
|
||||
return bot.HasUnreadGroupchats().ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
20
Core/Commands/Group/groupchatClearAll.cs
Normal file
20
Core/Commands/Group/groupchatClearAll.cs
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace BSB.Commands.Group
|
||||
{
|
||||
class GroupchatClearAll : CoreCommand
|
||||
{
|
||||
public override string Helpfile { get { return "Clears all group chat buffers at once"; } }
|
||||
public override bool CallFunction(string[] args)
|
||||
{
|
||||
if (base.CallFunction(args) == true)
|
||||
{
|
||||
bot.ClearAllGroupchat();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
18
Core/Commands/Group/groupchatGroupHasUnread.cs
Normal file
18
Core/Commands/Group/groupchatGroupHasUnread.cs
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
using OpenMetaverse;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace BSB.Commands.Group
|
||||
{
|
||||
class GroupchatGroupHasUnread : CoreGroupCommand_SmartReply_Group_auto
|
||||
{
|
||||
public override string Helpfile { get { return "Returns True|False via the smart reply target if there are any unread group ims for the group [ARG 2]"; } }
|
||||
|
||||
protected override string RunFunction(UUID targetgroup)
|
||||
{
|
||||
return bot.GroupHasUnread(targetgroup).ToString();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
17
Core/Commands/Group/groupchatHistory.cs
Normal file
17
Core/Commands/Group/groupchatHistory.cs
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Linq;
|
||||
using OpenMetaverse;
|
||||
|
||||
namespace BSB.Commands.Group
|
||||
{
|
||||
class GroupchatHistory : CoreGroupCommand_SmartReply_Group_auto
|
||||
{
|
||||
public override string Helpfile { get { return "Returns the chat history for the selected group [ARG 2] via smart reply [ARG 1]"; } }
|
||||
protected override string RunFunction(UUID targetgroup)
|
||||
{
|
||||
return String.Join("###", bot.GetGroupchat(targetgroup));
|
||||
}
|
||||
}
|
||||
}
|
||||
25
Core/Commands/Group/groupchatListAllUnreadGroups.cs
Normal file
25
Core/Commands/Group/groupchatListAllUnreadGroups.cs
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
using OpenMetaverse;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace BSB.Commands.Group
|
||||
{
|
||||
public class GroupchatListAllUnreadGroups : CoreGroupCommand_SmartReply_auto
|
||||
{
|
||||
public override string Helpfile { get { return "Returns a csv of groups with unread messages: UUID,UUID... "; } }
|
||||
|
||||
protected override string RunFunction()
|
||||
{
|
||||
string reply = "";
|
||||
string addon = "";
|
||||
foreach (UUID group in bot.UnreadGroupchatGroups())
|
||||
{
|
||||
reply += addon;
|
||||
reply += group;
|
||||
addon = ",";
|
||||
}
|
||||
return reply;
|
||||
}
|
||||
}
|
||||
}
|
||||
23
Core/Commands/Home/GoHome.cs
Normal file
23
Core/Commands/Home/GoHome.cs
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Linq;
|
||||
using OpenMetaverse;
|
||||
|
||||
|
||||
namespace BSB.Commands.Home
|
||||
{
|
||||
public class GoHome : CoreCommand
|
||||
{
|
||||
public override string Helpfile { get { return "Makes the bot teleport to its home region"; } }
|
||||
public override int MinArgs { get { return 0; } }
|
||||
public override bool CallFunction(string[] args)
|
||||
{
|
||||
if (base.CallFunction(args) == true)
|
||||
{
|
||||
bot.GotoNextHomeRegion();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
24
Core/Commands/Home/resetAtHome.cs
Normal file
24
Core/Commands/Home/resetAtHome.cs
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Linq;
|
||||
using OpenMetaverse;
|
||||
|
||||
|
||||
namespace BSB.Commands.Home
|
||||
{
|
||||
public class ResetAtHome : CoreCommand
|
||||
{
|
||||
public override string Helpfile { get { return "Resets the at home lockouts"; } }
|
||||
public override int MinArgs { get { return 0; } }
|
||||
public override bool CallFunction(string[] args)
|
||||
{
|
||||
if(base.CallFunction(args) == true)
|
||||
{
|
||||
bot.ResetAtHome();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
60
Core/Commands/Inventory/InventoryPurgeNotecards.cs
Normal file
60
Core/Commands/Inventory/InventoryPurgeNotecards.cs
Normal file
|
|
@ -0,0 +1,60 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Linq;
|
||||
using OpenMetaverse;
|
||||
using BSB.Static;
|
||||
using BetterSecondBotShared.Static;
|
||||
|
||||
namespace BSB.Commands.Inventory
|
||||
{
|
||||
public class InventoryPurgeNotecards : CoreCommand
|
||||
{
|
||||
public override string Helpfile { get { return "Searchs the notecards folder for notecards, any older than 31 days are deleted.<br/>Depending on the number of notecards this might require multiple calls!"; } }
|
||||
public override int MinArgs { get { return 0; } }
|
||||
public override bool CallFunction(string[] args)
|
||||
{
|
||||
if (base.CallFunction(args) == true)
|
||||
{
|
||||
List<InventoryBase> T = bot.GetClient.Inventory.Store.GetContents(bot.GetClient.Inventory.Store.RootFolder);
|
||||
InventoryBase NotecardFolder = null;
|
||||
foreach (InventoryBase R in T)
|
||||
{
|
||||
if(R.Name == "Notecards")
|
||||
{
|
||||
NotecardFolder = R;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(NotecardFolder != null)
|
||||
{
|
||||
DateTime Now = DateTime.Now;
|
||||
List<UUID> purge_notecards = new List<UUID>();
|
||||
List<InventoryBase> contents = bot.GetClient.Inventory.FolderContents(NotecardFolder.UUID, bot.GetClient.Self.AgentID, true, true, InventorySortOrder.ByDate, 40 * 1000);
|
||||
foreach(InventoryBase C in contents)
|
||||
{
|
||||
InventoryItem A = (InventoryItem)C;
|
||||
if(A.AssetType == AssetType.Notecard)
|
||||
{
|
||||
TimeSpan Dif = DateTime.Now - A.CreationDate;
|
||||
if(Dif.Days >= 31)
|
||||
{
|
||||
purge_notecards.Add(C.UUID);
|
||||
}
|
||||
}
|
||||
}
|
||||
if(purge_notecards.Count() > 0)
|
||||
{
|
||||
bot.GetClient.Inventory.Remove(purge_notecards, new List<UUID>());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return Failed("Unable to find notecard folder");
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
84
Core/Commands/Inventory/attach.cs
Normal file
84
Core/Commands/Inventory/attach.cs
Normal file
|
|
@ -0,0 +1,84 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Linq;
|
||||
using OpenMetaverse;
|
||||
|
||||
|
||||
namespace BSB.Commands.Inventory
|
||||
{
|
||||
public class Attach : CoreCommand
|
||||
{
|
||||
public override string[] ArgTypes { get { return new[] { "Text", "Text" }; } }
|
||||
public override string[] ArgHints { get { return new[] { "Sub folder", "Item name" }; } }
|
||||
public override string Helpfile { get { return "Attachs a item found inside the attachments / [ARG1] folder<br/>that matchs the item name [ARG2]"; } }
|
||||
public override int MinArgs { get { return 2; } }
|
||||
public override bool CallFunction(string[] args)
|
||||
{
|
||||
if (base.CallFunction(args) == true)
|
||||
{
|
||||
// attachments/[arg1]/[arg2]
|
||||
// arg1 = sub folder
|
||||
// arg2 = itemname
|
||||
InventoryFolder AA = bot.GetClient.Inventory.Store.RootFolder;
|
||||
List<InventoryBase> T = bot.GetClient.Inventory.Store.GetContents(AA);
|
||||
AA = null;
|
||||
foreach (InventoryBase R in T)
|
||||
{
|
||||
if (R.Name == "attachments")
|
||||
{
|
||||
AA = (InventoryFolder)R;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (AA != null)
|
||||
{
|
||||
T = bot.GetClient.Inventory.Store.GetContents(AA);
|
||||
AA = null;
|
||||
foreach (InventoryBase R in T)
|
||||
{
|
||||
if (R.Name == args[0])
|
||||
{
|
||||
AA = (InventoryFolder)R;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (AA != null)
|
||||
{
|
||||
List<InventoryItem> items = new List<InventoryItem>();
|
||||
List<InventoryBase> contents = bot.GetClient.Inventory.FolderContents(AA.UUID, bot.GetClient.Self.AgentID, true, true, InventorySortOrder.ByName, 20 * 1000);
|
||||
foreach (InventoryBase item in contents)
|
||||
{
|
||||
if ((item is InventoryWearable) || (item is InventoryObject))
|
||||
{
|
||||
if (item.Name == args[1])
|
||||
{
|
||||
items.Add((InventoryItem)item);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (items.Count() > 0)
|
||||
{
|
||||
bot.GetClient.Appearance.AddAttachments(items, false, false);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return Failed("Unable to find attachment: " + args[1] + " in sub folder " + args[0] + "");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return Failed("Unable to find subfolder " + args[0] + "");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return Failed("Unable to find attachements folder");
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
55
Core/Commands/Inventory/inventoryContents.cs
Normal file
55
Core/Commands/Inventory/inventoryContents.cs
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Linq;
|
||||
using OpenMetaverse;
|
||||
using BSB.Static;
|
||||
using BetterSecondBotShared.Static;
|
||||
|
||||
namespace BSB.Commands.Inventory
|
||||
{
|
||||
|
||||
public class InventoryContents : CoreCommand
|
||||
{
|
||||
public override string[] ArgTypes { get { return new[] { "Smart","UUID" }; } }
|
||||
public override string[] ArgHints { get { return new[] { "Smart reply target: Channel,Avatar,HTTP","Folder" }; } }
|
||||
public override string Helpfile { get { return "Maps the given inventory folder [ARG 2] for contents<br/>" +
|
||||
"Arg 1 *Avatar UUID* sends it via notecard to [ARG 1]<hr/>" +
|
||||
"Arg 1 *Anything else*<br/>as csv packed as follows folderinventory=UUID~|~entry~|~entry..." +
|
||||
"entry is formated as follows: itemname###uuid###type<br/>" +
|
||||
"sent to smart reply target"; } }
|
||||
public override int MinArgs { get { return 2; } }
|
||||
public override bool CallFunction(string[] args)
|
||||
{
|
||||
if (base.CallFunction(args) == true)
|
||||
{
|
||||
if (UUID.TryParse(args[1], out UUID targetfolder) == true)
|
||||
{
|
||||
string[] content = HelperInventory.MapFolderInventory(bot, targetfolder);
|
||||
if (UUID.TryParse(args[0], out UUID targetavatar) == true)
|
||||
{
|
||||
string notecardname = "InventoryContents" + helpers.UnixTimeNow().ToString() + "";
|
||||
if (content != null)
|
||||
{
|
||||
bot.SendNotecard(notecardname, String.Join("\n\r", content), targetavatar);
|
||||
}
|
||||
else
|
||||
{
|
||||
bot.GetClient.Self.InstantMessage(targetavatar, "Unable to load folder or it is empty");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return bot.GetCommandsInterface.SmartCommandReply(args[0], String.Join("~|~", content), CommandName);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return Failed("Invaild folder UUID");
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
42
Core/Commands/Inventory/inventoryFolders.cs
Normal file
42
Core/Commands/Inventory/inventoryFolders.cs
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Linq;
|
||||
using OpenMetaverse;
|
||||
using BSB.Static;
|
||||
using BetterSecondBotShared.Static;
|
||||
|
||||
namespace BSB.Commands.Inventory
|
||||
{
|
||||
public class InventoryFolders : CoreCommand
|
||||
{
|
||||
public override string[] ArgTypes { get { return new[] { "Smart" }; } }
|
||||
public override string[] ArgHints { get { return new[] { "Smart reply target: Channel,Avatar,HTTP url" }; } }
|
||||
public override string Helpfile { get { return "Fully maps the avatars inventory folders<br/>" +
|
||||
"*[Arg 1 UUID] sends you a notecard with it<br/>" +
|
||||
"*[Arg 1 Anything else] Sends it as a CSV via the smart target<br/>" +
|
||||
"Formated as follows<br>" +
|
||||
"entry,entry...<br/>" +
|
||||
"Where entry is formated foldername###level###UUID"; } }
|
||||
public override int MinArgs { get { return 1; } }
|
||||
public override bool CallFunction(string[] args)
|
||||
{
|
||||
if (base.CallFunction(args) == true)
|
||||
{
|
||||
if (UUID.TryParse(args[0], out UUID targetavatar) == true)
|
||||
{
|
||||
bot.GetClient.Self.InstantMessage(targetavatar, "Building inventory folder map now [This might take a while]");
|
||||
string reply = HelperInventory.MapFolder(bot, false);
|
||||
bot.SendNotecard("Inventory Folders", reply, targetavatar);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
string reply = HelperInventory.MapFolder(bot, true);
|
||||
return bot.GetCommandsInterface.SmartCommandReply(args[0], reply, CommandName);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
79
Core/Commands/Inventory/outfit.cs
Normal file
79
Core/Commands/Inventory/outfit.cs
Normal file
|
|
@ -0,0 +1,79 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Linq;
|
||||
using OpenMetaverse;
|
||||
|
||||
|
||||
namespace BSB.Commands.Inventory
|
||||
{
|
||||
public class Outfit : CoreCommand
|
||||
{
|
||||
public override string[] ArgTypes { get { return new[] { "Text" }; } }
|
||||
public override string[] ArgHints { get { return new[] { "Folder name" }; } }
|
||||
public override string Helpfile { get { return "Replaces the current avatar outfit with the Clothing/[ARG1] folder<br/>Please note: This does not use the outfits folder!"; } }
|
||||
public override int MinArgs { get { return 1; } }
|
||||
public override bool CallFunction(string[] args)
|
||||
{
|
||||
if (base.CallFunction(args) == true)
|
||||
{
|
||||
// uses the Clothing folder
|
||||
// must be a full outfit (shapes/eyes ect)
|
||||
InventoryFolder AA = bot.GetClient.Inventory.Store.RootFolder;
|
||||
List<InventoryBase> T = bot.GetClient.Inventory.Store.GetContents(AA);
|
||||
AA = null;
|
||||
foreach (InventoryBase R in T)
|
||||
{
|
||||
if (R.Name == "Clothing")
|
||||
{
|
||||
AA = (InventoryFolder)R;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (AA != null)
|
||||
{
|
||||
T = bot.GetClient.Inventory.Store.GetContents(AA);
|
||||
AA = null;
|
||||
foreach (InventoryBase R in T)
|
||||
{
|
||||
if (R.Name == args[0])
|
||||
{
|
||||
AA = (InventoryFolder)R;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (AA != null)
|
||||
{
|
||||
List<InventoryBase> contents = bot.GetClient.Inventory.FolderContents(AA.UUID, bot.GetClient.Self.AgentID, true, true, InventorySortOrder.ByName, 20 * 1000);
|
||||
List<InventoryItem> wareables = new List<InventoryItem>();
|
||||
if (contents != null)
|
||||
{
|
||||
foreach (InventoryBase item in contents)
|
||||
{
|
||||
if ((item is InventoryWearable) || (item is InventoryObject))
|
||||
{
|
||||
wareables.Add((InventoryItem)item);
|
||||
}
|
||||
}
|
||||
bot.GetClient.Appearance.ReplaceOutfit(wareables, false);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return Failed("target folder is empty or so full I cant get it in 20 secs...");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return Failed("Cant find target folder");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return Failed("Cant find Clothing folder");
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
47
Core/Commands/Inventory/sendFolder.cs
Normal file
47
Core/Commands/Inventory/sendFolder.cs
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
using BSB.Static;
|
||||
using OpenMetaverse;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace BSB.Commands.Inventory
|
||||
{
|
||||
public class SendFolder : CoreCommand
|
||||
{
|
||||
public override string[] ArgTypes { get { return new[] { "Avatar","UUID" }; } }
|
||||
public override string[] ArgHints { get { return new[] { "Avatar [UUID or Firstname Lastname]", "FOLDER" }; } }
|
||||
public override string Helpfile { get { return "Sends a folder [ARG 2] to an avatar [ARG 1]"; } }
|
||||
public override int MinArgs { get { return 2; } }
|
||||
public override bool CallFunction(string[] args)
|
||||
{
|
||||
if (base.CallFunction(args) == true)
|
||||
{
|
||||
if (UUID.TryParse(args[0], out UUID targetavatar) == true)
|
||||
{
|
||||
if (UUID.TryParse(args[1], out UUID targetfolder) == true)
|
||||
{
|
||||
InventoryBase FindFolderHelper = HelperInventory.FindFolder(bot, bot.GetClient.Inventory.Store.RootFolder, targetfolder);
|
||||
if (FindFolderHelper != null)
|
||||
{
|
||||
bot.GetClient.Inventory.GiveFolder(FindFolderHelper.UUID, FindFolderHelper.Name, targetavatar, false);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return Failed("Unable to find folder");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return Failed("Invaild folder UUID");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return Failed("Invaild avatar UUID");
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
52
Core/Commands/Inventory/sendItem.cs
Normal file
52
Core/Commands/Inventory/sendItem.cs
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
using BSB.Static;
|
||||
using OpenMetaverse;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace BSB.Commands.Inventory
|
||||
{
|
||||
public class SendItem : CoreCommand
|
||||
{
|
||||
public override string[] ArgTypes { get { return new[] { "Avatar", "UUID", "Number" }; } }
|
||||
public override string[] ArgHints { get { return new[] { "Avatar [UUID or Firstname Lastname]", "Item","Time to find item" }; } }
|
||||
public override string Helpfile { get { return "Sends a item [ARG 2] to an avatar [ARG 1]. (Optional arg 3: How long to wait to find the item in secs, Defaults to 6)"; } }
|
||||
public override int MinArgs { get { return 2; } }
|
||||
public override bool CallFunction(string[] args)
|
||||
{
|
||||
if (base.CallFunction(args) == true)
|
||||
{
|
||||
int search_delay_time = 6;
|
||||
if(args.Length == 3)
|
||||
{
|
||||
int.TryParse(args[2], out search_delay_time);
|
||||
}
|
||||
if (UUID.TryParse(args[0], out UUID targetavatar) == true)
|
||||
{
|
||||
if (UUID.TryParse(args[1], out UUID targetitem) == true)
|
||||
{
|
||||
InventoryItem itm = bot.GetClient.Inventory.FetchItem(targetitem, bot.GetClient.Self.AgentID, (search_delay_time * 1000));
|
||||
if (itm != null)
|
||||
{
|
||||
bot.GetClient.Inventory.GiveItem(itm.AssetUUID, itm.Name, itm.AssetType, targetavatar, false);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return Failed("Unable to find item");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return Failed("Invaild item UUID");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return Failed("Invaild avatar UUID");
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
51
Core/Commands/Movement/rotateTo.cs
Normal file
51
Core/Commands/Movement/rotateTo.cs
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using OpenMetaverse;
|
||||
namespace BSB.Commands.Movement
|
||||
{
|
||||
public class RotateTo : CoreCommand
|
||||
{
|
||||
public override string[] ArgTypes { get { return new[] { "Number" }; } }
|
||||
public override string[] ArgHints { get { return new[] { "0 to 360" }; } }
|
||||
public override string Helpfile { get { return "Rotates the avatar to face a rotation from north in Degrees"; } }
|
||||
public override int MinArgs { get { return 1; } }
|
||||
public override bool CallFunction(string[] args)
|
||||
{
|
||||
if (base.CallFunction(args) == true)
|
||||
{
|
||||
if (float.TryParse(args[0], out float target_yaw) == true)
|
||||
{
|
||||
float yaw = target_yaw;
|
||||
bot.GetClient.Self.Movement.BodyRotation.GetEulerAngles(out float roll, out float pitch, out _);
|
||||
roll *= 57.2958f;
|
||||
pitch *= 57.2958f;
|
||||
yaw *= 57.2958f;
|
||||
float rollOver2 = roll * 0.5f;
|
||||
float sinRollOver2 = (float)Math.Sin((double)rollOver2);
|
||||
float cosRollOver2 = (float)Math.Cos((double)rollOver2);
|
||||
float pitchOver2 = pitch * 0.5f;
|
||||
float sinPitchOver2 = (float)Math.Sin((double)pitchOver2);
|
||||
float cosPitchOver2 = (float)Math.Cos((double)pitchOver2);
|
||||
float yawOver2 = yaw * 0.5f;
|
||||
float sinYawOver2 = (float)Math.Sin((double)yawOver2);
|
||||
float cosYawOver2 = (float)Math.Cos((double)yawOver2);
|
||||
Quaternion result;
|
||||
result.W = cosYawOver2 * cosPitchOver2 * cosRollOver2 + sinYawOver2 * sinPitchOver2 * sinRollOver2;
|
||||
result.X = cosYawOver2 * sinPitchOver2 * cosRollOver2 + sinYawOver2 * cosPitchOver2 * sinRollOver2;
|
||||
result.Y = sinYawOver2 * cosPitchOver2 * cosRollOver2 - cosYawOver2 * sinPitchOver2 * sinRollOver2;
|
||||
result.Z = cosYawOver2 * cosPitchOver2 * sinRollOver2 - sinYawOver2 * sinPitchOver2 * cosRollOver2;
|
||||
bot.GetClient.Self.Movement.BodyRotation = result;
|
||||
bot.GetClient.Self.Movement.SendUpdate();
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return Failed("Unable to process rotation");
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
68
Core/Commands/Movement/teleport.cs
Normal file
68
Core/Commands/Movement/teleport.cs
Normal file
|
|
@ -0,0 +1,68 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Linq;
|
||||
using OpenMetaverse;
|
||||
|
||||
|
||||
namespace BSB.Commands.Movement
|
||||
{
|
||||
public class Teleport : CoreCommand
|
||||
{
|
||||
public override string[] ArgTypes { get { return new[] { "Mixed" }; } }
|
||||
public override string[] ArgHints { get { return new[] { "SLurl<br/>Region<br/>X/Y/Z<br/>Region/X/Y/Z" }; } }
|
||||
public override string Helpfile { get { return "Teleports the avatar<br/> " +
|
||||
"SLurl: http://maps.secondlife.com/secondlife/Bombalai/216/51/33 <br/> " +
|
||||
"Region: Bombalai [Defaults to 128,128,0]<br>" +
|
||||
"X/Y/Z: Stays in the sim just changes location <br/> " +
|
||||
"Region/X/Y/Z: Teleports to the given region and trys to goto X/Y/Z if no teleport hub (or has access)";
|
||||
} }
|
||||
|
||||
public override int MinArgs { get { return 1; } }
|
||||
public override bool CallFunction(string[] args)
|
||||
{
|
||||
if(base.CallFunction(args) == true)
|
||||
{
|
||||
if (args[0].Contains("http://maps.secondlife.com/secondlife/") == true)
|
||||
{
|
||||
bot.TeleportWithSLurl(args[0]);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
float posX = 128;
|
||||
float posY = 128;
|
||||
float posZ = 0;
|
||||
string regionName = bot.GetClient.Network.CurrentSim.Name;
|
||||
bool ok = true;
|
||||
int offset = 0;
|
||||
string[] tp_args = args[0].Split('/');
|
||||
if ((tp_args.Length == 4) || (tp_args.Length == 1))
|
||||
{
|
||||
regionName = tp_args[0];
|
||||
offset = 1;
|
||||
}
|
||||
if (tp_args.Length >= 3)
|
||||
{
|
||||
float.TryParse(tp_args[offset + 0], out posX);
|
||||
float.TryParse(tp_args[offset + 1], out posY);
|
||||
float.TryParse(tp_args[offset + 2], out posZ);
|
||||
}
|
||||
else if (tp_args.Length == 2) ok = false;
|
||||
if (ok == true)
|
||||
{
|
||||
bot.SetTeleported();
|
||||
bool status = bot.GetClient.Self.Teleport(regionName, new Vector3(posX, posY, posZ));
|
||||
bot.ResetAnimations();
|
||||
return status;
|
||||
}
|
||||
else
|
||||
{
|
||||
return Failed("Required args [Region or x/y/z or region/x/y/z not sent]");
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
25
Core/Commands/Notecard/notecardAdd.cs
Normal file
25
Core/Commands/Notecard/notecardAdd.cs
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using OpenMetaverse;
|
||||
|
||||
namespace BSB.Commands.Notecard
|
||||
{
|
||||
class NotecardAdd : CoreCommand
|
||||
{
|
||||
public override string[] ArgTypes { get { return new[] { "Text","Text" }; } }
|
||||
public override string[] ArgHints { get { return new[] { "Collection","Content" }; } }
|
||||
public override string Helpfile { get { return "Adds [ARG 2] to the Collection [ARG 1]<br/> Also creates the collection if it does not exist"; } }
|
||||
public override int MinArgs { get { return 2; } }
|
||||
|
||||
public override bool CallFunction(string[] args)
|
||||
{
|
||||
if (base.CallFunction(args) == true)
|
||||
{
|
||||
bot.NotecardAddContent(args[0], args[1]);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
25
Core/Commands/Notecard/notecardClear.cs
Normal file
25
Core/Commands/Notecard/notecardClear.cs
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using OpenMetaverse;
|
||||
|
||||
namespace BSB.Commands.Notecard
|
||||
{
|
||||
class NotecardClear : CoreCommand
|
||||
{
|
||||
public override string[] ArgTypes { get { return new[] { "Text" }; } }
|
||||
public override string[] ArgHints { get { return new[] { "Collection" }; } }
|
||||
public override string Helpfile { get { return "Clears Collection [ARG 1]"; } }
|
||||
public override int MinArgs { get { return 1; } }
|
||||
|
||||
public override bool CallFunction(string[] args)
|
||||
{
|
||||
if (base.CallFunction(args) == true)
|
||||
{
|
||||
bot.ClearNotecardStorage(args[0]);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
46
Core/Commands/Notecard/notecardSend.cs
Normal file
46
Core/Commands/Notecard/notecardSend.cs
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using BetterSecondBotShared.Static;
|
||||
using OpenMetaverse;
|
||||
|
||||
namespace BSB.Commands.Notecard
|
||||
{
|
||||
class NotecardSend : CoreCommand
|
||||
{
|
||||
public override string[] ArgTypes { get { return new[] { "Avatar","Text","Text" }; } }
|
||||
public override string[] ArgHints { get { return new[] { "Avatar [UUID or Firstname Lastname]", "Collection","Notecard name" }; } }
|
||||
public override string Helpfile { get { return "Creats and send a notecard to [ARG 1]<br/>" +
|
||||
" using the collection [ARG 2] as the content <br/>" +
|
||||
" Optional: You can name the notecard using [ARG 3]"; } }
|
||||
public override int MinArgs { get { return 2; } }
|
||||
|
||||
public override bool CallFunction(string[] args)
|
||||
{
|
||||
if (base.CallFunction(args) == true)
|
||||
{
|
||||
// target UUID,notecard storage id,["notecard title" <unixtime> or defaults to: New notecard for <UUID> <unixtime>]
|
||||
if (UUID.TryParse(args[0], out UUID target) == true)
|
||||
{
|
||||
string content = bot.GetNotecardContent(args[1]);
|
||||
if (content != null)
|
||||
{
|
||||
bot.ClearNotecardStorage(args[1]);
|
||||
string notecard_name = "New notecard for " + args[0] + " " + helpers.UnixTimeNow().ToString() + "";
|
||||
if (args.Length == 3) notecard_name = args[2] + " " + helpers.UnixTimeNow().ToString() + "";
|
||||
return bot.SendNotecard(notecard_name, content, target);
|
||||
}
|
||||
else
|
||||
{
|
||||
return Failed("No content in notecard storage " + args[1]);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return Failed("Arg 0 not a UUID");
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
82
Core/Commands/Parcel/GetParcelFlags.cs
Normal file
82
Core/Commands/Parcel/GetParcelFlags.cs
Normal file
|
|
@ -0,0 +1,82 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using BetterSecondBotShared.logs;
|
||||
using BetterSecondBotShared.Static;
|
||||
using OpenMetaverse;
|
||||
|
||||
namespace BSB.Commands.CMD_Parcel
|
||||
{
|
||||
public class GetParcelFlags : CoreCommand
|
||||
{
|
||||
public override string[] ArgTypes { get { return new[] { "Mixed","String" }; } }
|
||||
public override string[] ArgHints { get { return new[] { "Smart reply [Channel|IM uuid|http url]", "[Repeatable] flag name" }; } }
|
||||
public override int MinArgs { get { return 1; } }
|
||||
public override string Helpfile { get { return "Returns the value of the parcel flags (At the parcel on the bot is currently on)<br/>" +
|
||||
"requested on [ARG 2+] via [ARG 1] smart reply target<br/>" +
|
||||
"If you request multiple Flags they are split with CSV<br/>You can also get all the flags skipping [ARG 2]<br/><br/>" +
|
||||
"" + helpers.create_dirty_table(parcel_static.get_flag_names()) + "<br/><br/>Example: getparcelflag|||0~#~ForSale<br/>Example: getparcelflag|||12"; } }
|
||||
|
||||
public override bool CallFunction(string[] args)
|
||||
{
|
||||
if (base.CallFunction(args) == true)
|
||||
{
|
||||
Dictionary<string, ParcelFlags> flags = parcel_static.get_flags_list();
|
||||
List<string> get_flags = new List<string>();
|
||||
List<string> otherargs = new List<string>(args);
|
||||
string target = otherargs[0];
|
||||
otherargs.RemoveAt(0);
|
||||
if (otherargs.Count == 0)
|
||||
{
|
||||
otherargs.Add("ALL");
|
||||
}
|
||||
if (otherargs[0] == "ALL")
|
||||
{
|
||||
foreach (string A in flags.Keys)
|
||||
{
|
||||
get_flags.Add(A);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach (string a in otherargs)
|
||||
{
|
||||
if (flags.ContainsKey(a) == true)
|
||||
{
|
||||
get_flags.Add(a);
|
||||
}
|
||||
else
|
||||
{
|
||||
ConsoleLog.Warn("Flag: " + a + " is unknown");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (get_flags.Count > 0)
|
||||
{
|
||||
int localid = bot.GetClient.Parcels.GetParcelLocalID(bot.GetClient.Network.CurrentSim, bot.GetClient.Self.SimPosition);
|
||||
Parcel p = bot.GetClient.Network.CurrentSim.Parcels[localid];
|
||||
StringBuilder reply = new StringBuilder();
|
||||
string addon = "";
|
||||
foreach (string cfg in get_flags)
|
||||
{
|
||||
if (flags.ContainsKey(cfg) == true)
|
||||
{
|
||||
reply.Append(addon);
|
||||
reply.Append(cfg);
|
||||
reply.Append("=");
|
||||
reply.Append(p.Flags.HasFlag(flags[cfg]).ToString());
|
||||
if(addon != ",") addon = ",";
|
||||
}
|
||||
}
|
||||
return bot.GetCommandsInterface.SmartCommandReply(target, reply.ToString(), CommandName);
|
||||
}
|
||||
else
|
||||
{
|
||||
return Failed("No accepted flags");
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
89
Core/Commands/Parcel/SetParcelFlag.cs
Normal file
89
Core/Commands/Parcel/SetParcelFlag.cs
Normal file
|
|
@ -0,0 +1,89 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using BetterSecondBotShared.logs;
|
||||
using BetterSecondBotShared.Static;
|
||||
using OpenMetaverse;
|
||||
|
||||
namespace BSB.Commands.CMD_Parcel
|
||||
{
|
||||
|
||||
public class SetParcelFlag : CoreCommand
|
||||
{
|
||||
public override string[] ArgTypes { get { return new[] { "Text=True|False" }; } }
|
||||
public override string[] ArgHints { get { return new[] { "[Repeatable] flag args" }; } }
|
||||
public override int MinArgs { get { return 1; } }
|
||||
|
||||
public override string Helpfile { get { return "Sets the parcel flags of the parcel the bot is currently standing on<br/>" +
|
||||
"Example:AllowFly=False~#~AllowDamage=True<br/>" + helpers.create_dirty_table(parcel_static.get_flag_names()) +"<br/>"; } }
|
||||
|
||||
private void Dosetflag(ParcelFlags F, Parcel p, bool set)
|
||||
{
|
||||
ConsoleLog.Warn("Setting flag: " + F.ToString() + " To " + set.ToString() + " at " + p.Name + "");
|
||||
if (p.Flags.HasFlag(F))
|
||||
{
|
||||
p.Flags -= F;
|
||||
}
|
||||
if (set == true)
|
||||
{
|
||||
p.Flags |= F;
|
||||
}
|
||||
}
|
||||
public override bool CallFunction(string[] args)
|
||||
{
|
||||
if (base.CallFunction(args) == true)
|
||||
{
|
||||
List<string> acceptablewords = new List<string>();
|
||||
Dictionary<string, ParcelFlags> flags = parcel_static.get_flags_list();
|
||||
acceptablewords.AddRange(new[] { "True", "False" });
|
||||
|
||||
Dictionary<string, bool> setflags = new Dictionary<string, bool>();
|
||||
foreach (string a in args)
|
||||
{
|
||||
string[] parts = a.Split('=');
|
||||
if (flags.ContainsKey(parts[0]) == true)
|
||||
{
|
||||
if (acceptablewords.Contains(parts[1]))
|
||||
{
|
||||
setflags.Add(parts[0], Convert.ToBoolean(parts[1]));
|
||||
}
|
||||
else
|
||||
{
|
||||
ConsoleLog.Crit("Unable to set flag " + parts[0] + " to : " + parts[1] + "");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ConsoleLog.Warn("Flag: " + parts[0] + " is unknown");
|
||||
}
|
||||
}
|
||||
if (setflags.Count > 0)
|
||||
{
|
||||
int localid = bot.GetClient.Parcels.GetParcelLocalID(bot.GetClient.Network.CurrentSim, bot.GetClient.Self.SimPosition);
|
||||
Parcel p = bot.GetClient.Network.CurrentSim.Parcels[localid];
|
||||
if (p.OwnerID != bot.GetClient.Self.AgentID)
|
||||
{
|
||||
if (p.IsGroupOwned)
|
||||
{
|
||||
bot.GetClient.Groups.ActivateGroup(p.GroupID);
|
||||
}
|
||||
}
|
||||
foreach (KeyValuePair<string, bool> cfg in setflags)
|
||||
{
|
||||
if (flags.ContainsKey(cfg.Key) == true)
|
||||
{
|
||||
Dosetflag(flags[cfg.Key], p, cfg.Value);
|
||||
}
|
||||
}
|
||||
p.Update(bot.GetClient.Network.CurrentSim, false);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return Failed("No accepted flags");
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
36
Core/Commands/Parcel/eject.cs
Normal file
36
Core/Commands/Parcel/eject.cs
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
using OpenMetaverse;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace BSB.Commands.CMD_Parcel
|
||||
{
|
||||
public class ParcelEject : CoreCommand
|
||||
{
|
||||
public override string[] ArgTypes { get { return new[] { "Avatar", "True|False" }; } }
|
||||
public override string[] ArgHints { get { return new[] { "Avatar [UUID or Firstname Lastname]", "Also Ban" }; } }
|
||||
public override string Helpfile { get { return "Ejects an avatar [ARG 1] from a parcel<br/>You can also ban them at the same time if you wish"; } }
|
||||
public override int MinArgs { get { return 1; } }
|
||||
public override bool CallFunction(string[] args)
|
||||
{
|
||||
if (base.CallFunction(args) == true)
|
||||
{
|
||||
if (UUID.TryParse(args[0], out UUID target) == true)
|
||||
{
|
||||
bool banuser = false;
|
||||
if (args.Length == 2)
|
||||
{
|
||||
if (args[1] == "True") banuser = true;
|
||||
}
|
||||
bot.GetClient.Parcels.EjectUser(target, banuser);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return Failed("Arg 0 requires UUID");
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
37
Core/Commands/Self/PayAvatar.cs
Normal file
37
Core/Commands/Self/PayAvatar.cs
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Linq;
|
||||
using OpenMetaverse;
|
||||
|
||||
|
||||
namespace BSB.Commands.Self
|
||||
{
|
||||
public class PayAvatar : CoreCommand
|
||||
{
|
||||
public override string[] ArgTypes { get { return new[] { "Avatar", "Number" }; } }
|
||||
public override string[] ArgHints { get { return new[] { "Avatar [UUID or Firstname Lastname]", "Amount to pay"}; } }
|
||||
public override string Helpfile { get { return "Makes the bot pay a avatar"; } }
|
||||
public override int MinArgs { get { return 2; } }
|
||||
public override bool CallFunction(string[] args)
|
||||
{
|
||||
if (base.CallFunction(args) == true)
|
||||
{
|
||||
if (UUID.TryParse(args[0], out UUID avataruuid) == true)
|
||||
{
|
||||
if (int.TryParse(args[1], out int amount) == true)
|
||||
{
|
||||
if (amount > 0)
|
||||
{
|
||||
bot.GetClient.Self.GiveAvatarMoney(avataruuid, amount);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return Failed("Invaild amount");
|
||||
}
|
||||
return Failed("Invaild avatar UUID");
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
41
Core/Commands/Self/PayObject.cs
Normal file
41
Core/Commands/Self/PayObject.cs
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Linq;
|
||||
using OpenMetaverse;
|
||||
|
||||
|
||||
namespace BSB.Commands.Self
|
||||
{
|
||||
public class PayObject : CoreCommand
|
||||
{
|
||||
public override string[] ArgTypes { get { return new[] { "UUID","Number","Text" }; } }
|
||||
public override string[] ArgHints { get { return new[] { "Object UUID","Amount to pay","Object Name" }; } }
|
||||
public override string Helpfile { get { return "Makes the bot pay a object"; } }
|
||||
public override int MinArgs { get { return 3; } }
|
||||
public override bool CallFunction(string[] args)
|
||||
{
|
||||
if (base.CallFunction(args) == true)
|
||||
{
|
||||
if (UUID.TryParse(args[0], out UUID objectuuid) == true)
|
||||
{
|
||||
if (int.TryParse(args[1], out int amount) == true)
|
||||
{
|
||||
if (amount > 0)
|
||||
{
|
||||
if (args[2].Length > 0)
|
||||
{
|
||||
bot.GetClient.Self.GiveObjectMoney(objectuuid, amount, args[2]);
|
||||
return true;
|
||||
}
|
||||
return Failed("Invaild object name");
|
||||
}
|
||||
}
|
||||
return Failed("Invaild amount");
|
||||
}
|
||||
return Failed("Invaild object UUID");
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
26
Core/Commands/Self/addToAnimations.cs
Normal file
26
Core/Commands/Self/addToAnimations.cs
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Linq;
|
||||
using OpenMetaverse;
|
||||
|
||||
|
||||
namespace BSB.Commands.Self
|
||||
{
|
||||
public class AddToAllowAnimations : CoreCommand
|
||||
{
|
||||
public override string[] ArgTypes { get { return new[] { "Text" }; } }
|
||||
public override string[] ArgHints { get { return new[] { "Avatar name"}; } }
|
||||
public override string Helpfile { get { return "Toggles if animation requests from this avatar (used for remote poseballs) are accepted<br/>Case sensitive also requires Lastname"; } }
|
||||
public override int MinArgs { get { return 1; } }
|
||||
public override bool CallFunction(string[] args)
|
||||
{
|
||||
if(base.CallFunction(args) == true)
|
||||
{
|
||||
bot.ToggleAutoAcceptAnimations(args[0]);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
29
Core/Commands/Self/botVersion.cs
Normal file
29
Core/Commands/Self/botVersion.cs
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Linq;
|
||||
using OpenMetaverse;
|
||||
|
||||
namespace BSB.Commands.Self
|
||||
{
|
||||
class BotVersion : CoreCommand
|
||||
{
|
||||
public override string[] ArgTypes { get { return new[] { "Mixed" }; } }
|
||||
public override string[] ArgHints { get { return new[] { "Smart reply target: Channel,UUID,HTTP" }; } }
|
||||
public override string Helpfile { get { return "Returns the bots build version"; } }
|
||||
public override int MinArgs { get { return 0; } }
|
||||
public override bool CallFunction(string[] args)
|
||||
{
|
||||
if (base.CallFunction(args) == true)
|
||||
{
|
||||
string target = "0";
|
||||
if (args.Length > 0)
|
||||
{
|
||||
target = args[0];
|
||||
}
|
||||
return bot.GetCommandsInterface.SmartCommandReply(target, bot.MyVersion, CommandName);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
21
Core/Commands/Self/logout.cs
Normal file
21
Core/Commands/Self/logout.cs
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Linq;
|
||||
using OpenMetaverse;
|
||||
|
||||
|
||||
namespace BSB.Commands.Self
|
||||
{
|
||||
public class Logout : CoreCommand
|
||||
{
|
||||
public override string Helpfile { get { return "Makes the bot kill itself you monster"; } }
|
||||
public override int MinArgs { get { return 0; } }
|
||||
public override bool CallFunction(string[] args)
|
||||
{
|
||||
bot.GetClient.Self.Chat("I dont want to go :( ", 0, ChatType.Normal);
|
||||
bot.KillMePlease();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
46
Core/Commands/Self/pointAt.cs
Normal file
46
Core/Commands/Self/pointAt.cs
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Linq;
|
||||
using OpenMetaverse;
|
||||
|
||||
|
||||
namespace BSB.Commands.Self
|
||||
{
|
||||
public class PointAt : CoreCommand
|
||||
{
|
||||
public override string[] ArgTypes { get { return new[] { "Avatar" }; } }
|
||||
public override string[] ArgHints { get { return new[] { "Avatar [UUID or Firstname Lastname]" }; } }
|
||||
public override string Helpfile { get { return "Makes the bot turn to face [ARG 1] and point at them (if found)"; } }
|
||||
public override int MinArgs { get { return 1; } }
|
||||
public override bool CallFunction(string[] args)
|
||||
{
|
||||
if (base.CallFunction(args) == true)
|
||||
{
|
||||
if (UUID.TryParse(args[0], out UUID testavatar) == true)
|
||||
{
|
||||
if (bot.GetClient.Network.CurrentSim.AvatarPositions.ContainsKey(testavatar) == true)
|
||||
{
|
||||
bot.ResetAnimations();
|
||||
bot.GetClient.Self.Stand();
|
||||
bot.GetClient.Self.Movement.TurnToward(bot.GetClient.Network.CurrentSim.AvatarPositions[testavatar]);
|
||||
bot.GetClient.Self.Movement.SendUpdate();
|
||||
bot.GetClient.Self.AnimationStart(Animations.POINT_YOU, true);
|
||||
bot.GetClient.Self.PointAtEffect(bot.GetClient.Self.AgentID, testavatar, new Vector3d(0, 0, 0), PointAtType.Select, UUID.Random());
|
||||
bot.GetClient.Self.BeamEffect(bot.GetClient.Self.AgentID, testavatar, new Vector3d(0, 0, 2), new Color4(255, 255, 255, 1), (float)3.0, UUID.Random());
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return Failed("Cant find UUID in sim");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return Failed("UUID is not vaild");
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
43
Core/Commands/Self/sit.cs
Normal file
43
Core/Commands/Self/sit.cs
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Linq;
|
||||
using OpenMetaverse;
|
||||
|
||||
|
||||
namespace BSB.Commands.Self
|
||||
{
|
||||
public class BotSit : CoreCommand
|
||||
{
|
||||
public override string[] ArgTypes { get { return new[] { "Mixed" }; } }
|
||||
public override string[] ArgHints { get { return new[] { "Text \"ground\" or a object UUID" }; } }
|
||||
public override string Helpfile { get { return "Makes the bot sit on the ground or on a object if it can see it"; } }
|
||||
public override int MinArgs { get { return 1; } }
|
||||
public override bool CallFunction(string[] args)
|
||||
{
|
||||
if (base.CallFunction(args) == true)
|
||||
{
|
||||
bot.ResetAnimations();
|
||||
bot.GetClient.Self.Stand();
|
||||
if (args[0] == "ground")
|
||||
{
|
||||
bot.GetClient.Self.SitOnGround();
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (UUID.TryParse(args[0], out UUID arg_is_uuid) == true)
|
||||
{
|
||||
bot.GetClient.Self.RequestSit(arg_is_uuid, Vector3.Zero);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return Failed("UUID is not vaild");
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
21
Core/Commands/Self/stand.cs
Normal file
21
Core/Commands/Self/stand.cs
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Linq;
|
||||
using OpenMetaverse;
|
||||
|
||||
|
||||
namespace BSB.Commands.Self
|
||||
{
|
||||
public class Stand : CoreCommand
|
||||
{
|
||||
public override string Helpfile { get { return "Makes the bot stand up if sitting (also resets animations)"; } }
|
||||
public override int MinArgs { get { return 0; } }
|
||||
public override bool CallFunction(string[] args)
|
||||
{
|
||||
bot.GetClient.Self.Stand();
|
||||
bot.ResetAnimations();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
80
Core/Commands/StreamAdmin/FetchNextNotecard.cs
Normal file
80
Core/Commands/StreamAdmin/FetchNextNotecard.cs
Normal file
|
|
@ -0,0 +1,80 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Linq;
|
||||
using OpenMetaverse;
|
||||
using BetterSecondBotShared.Static;
|
||||
using RestSharp;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace BSB.Commands.StreamAdmin
|
||||
{
|
||||
public class FetchNextNotecard : CoreCommand
|
||||
{
|
||||
public override string[] ArgTypes { get { return new[] { "TEXT","TEXT" }; } }
|
||||
public override string[] ArgHints { get { return new[] { "Server endpoint","Server endpoint code" }; } }
|
||||
public override string Helpfile { get { return "[StreamAdmin]\nThis command is part of the streamadmin commands set\n No end user support will be given."; } }
|
||||
public override int MinArgs { get { return 2; } }
|
||||
public override bool CallFunction(string[] args)
|
||||
{
|
||||
if(base.CallFunction(args) == true)
|
||||
{
|
||||
string attempt_endpoint = "" + args[0] + "endpoint.php";
|
||||
string token = helpers.GetSHA1(helpers.UnixTimeNow().ToString()+"notecardnext" + args[1]);
|
||||
var client = new RestClient("" + args[0] + "endpoint.php");
|
||||
var request = new RestRequest("notecard/next", Method.POST);
|
||||
request.AddParameter("token", token);
|
||||
request.AddHeader("content-type", "application/x-www-form-urlencoded");
|
||||
IRestResponse endpoint_checks = client.Post(request);
|
||||
if (endpoint_checks.StatusCode == System.Net.HttpStatusCode.OK)
|
||||
{
|
||||
notecardendpoint server_reply = new notecardendpoint();
|
||||
bool server_reply_ok = true;
|
||||
|
||||
try
|
||||
{
|
||||
server_reply = JsonConvert.DeserializeObject<notecardendpoint>(endpoint_checks.Content);
|
||||
}
|
||||
catch
|
||||
{
|
||||
server_reply_ok = false;
|
||||
}
|
||||
if (server_reply_ok == true)
|
||||
{
|
||||
if (server_reply.status == true)
|
||||
{
|
||||
if (server_reply.NotecardTitle.Length > 3)
|
||||
{
|
||||
return bot.SendNotecard(server_reply.NotecardTitle, server_reply.NotecardContent, (UUID)server_reply.AvatarUUID);
|
||||
}
|
||||
else Failed("Notecard title is to short");
|
||||
}
|
||||
return Failed(server_reply.message);
|
||||
}
|
||||
else
|
||||
{
|
||||
return Failed("FetchNextNotecard - HTTP error: " + endpoint_checks.StatusCode.ToString() + " " + endpoint_checks.Content + "");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return Failed("FetchNextNotecard - HTTP error DataObject broken Status:"+ endpoint_checks.StatusCode.ToString()+" @ "+ attempt_endpoint+"");
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public class notecardendpoint : endpoint
|
||||
{
|
||||
public string AvatarUUID { get; set; }
|
||||
public string NotecardTitle { get; set; }
|
||||
public string NotecardContent { get; set; }
|
||||
}
|
||||
|
||||
public class endpoint
|
||||
{
|
||||
public bool status { get; set; }
|
||||
public string message { get; set; }
|
||||
}
|
||||
}
|
||||
287
Core/Commands/commandlib.cs
Normal file
287
Core/Commands/commandlib.cs
Normal file
|
|
@ -0,0 +1,287 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Linq;
|
||||
using OpenMetaverse;
|
||||
using System.Net.Http;
|
||||
using BSB.bottypes;
|
||||
using BetterSecondBotShared.API;
|
||||
using BetterSecondBotShared.Static;
|
||||
using BetterSecondBotShared.logs;
|
||||
|
||||
namespace BSB.Commands
|
||||
{
|
||||
public class pending_avatar_lookup
|
||||
{
|
||||
public pending_avatar_lookup(CoreCommandsInterface set_master,CoreCommand set_cmd,string[] set_args)
|
||||
{
|
||||
Master = set_master;
|
||||
Command = set_cmd;
|
||||
args = set_args.ToList();
|
||||
}
|
||||
public bool Callnow()
|
||||
{
|
||||
return Command.CallFunction(args.ToArray());
|
||||
}
|
||||
public bool needs_lookup()
|
||||
{
|
||||
List<int> need_lookup_on_indexs = new List<int>();
|
||||
int loop = 0;
|
||||
foreach (string atype in Command.ArgTypes)
|
||||
{
|
||||
if (loop < args.Count)
|
||||
{
|
||||
if (atype == "Avatar")
|
||||
{
|
||||
need_lookup_on_indexs.Add(loop);
|
||||
}
|
||||
else if(atype == "Smart")
|
||||
{
|
||||
if(args[loop].StartsWith("http") == false)
|
||||
{
|
||||
// not a url request
|
||||
if (int.TryParse(args[loop],out _) == false)
|
||||
{
|
||||
// Not a channel
|
||||
need_lookup_on_indexs.Add(loop);
|
||||
}
|
||||
}
|
||||
}
|
||||
loop++;
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
bool has_required_lookups = false;
|
||||
foreach (int A in need_lookup_on_indexs)
|
||||
{
|
||||
string value = args[A];
|
||||
if(UUID.TryParse(args[A],out _) == false)
|
||||
{
|
||||
// not a uuid
|
||||
string get_or_request_uuid = Master.GetBot.FindAvatarName2Key(args[A]);
|
||||
if(get_or_request_uuid == "lookup")
|
||||
{
|
||||
has_required_lookups = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
args[A] = get_or_request_uuid;
|
||||
}
|
||||
}
|
||||
}
|
||||
return has_required_lookups;
|
||||
}
|
||||
protected CoreCommand Command;
|
||||
protected List<string> args;
|
||||
protected CoreCommandsInterface Master;
|
||||
}
|
||||
public class CoreCommandsInterface : API_supported_interface
|
||||
{
|
||||
protected CommandsBot bot;
|
||||
public CommandsBot GetBot { get { return bot; } }
|
||||
|
||||
protected long giveup_waiting_for_lookup = 240;
|
||||
protected int next_lookup_id = 0;
|
||||
protected Dictionary<int, pending_avatar_lookup> commands_pending_avatar_lookups = new Dictionary<int, pending_avatar_lookup>();
|
||||
protected Dictionary<int, long> commands_pending_avatar_lookups_ages = new Dictionary<int, long>();
|
||||
|
||||
public void StatusTick()
|
||||
{
|
||||
List<int> purge_indexs = new List<int>();
|
||||
List<int> call_indexs = new List<int>();
|
||||
long now = helpers.UnixTimeNow();
|
||||
foreach (KeyValuePair<int,long> pair in commands_pending_avatar_lookups_ages)
|
||||
{
|
||||
if (commands_pending_avatar_lookups[pair.Key].needs_lookup() == true)
|
||||
{
|
||||
long dif = now - pair.Value;
|
||||
if (dif > giveup_waiting_for_lookup)
|
||||
{
|
||||
purge_indexs.Add(pair.Key);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
call_indexs.Add(pair.Key);
|
||||
}
|
||||
}
|
||||
foreach(int a in purge_indexs)
|
||||
{
|
||||
commands_pending_avatar_lookups_ages.Remove(a);
|
||||
commands_pending_avatar_lookups.Remove(a);
|
||||
}
|
||||
foreach(int a in call_indexs)
|
||||
{
|
||||
commands_pending_avatar_lookups[a].Callnow();
|
||||
commands_pending_avatar_lookups_ages.Remove(a);
|
||||
commands_pending_avatar_lookups.Remove(a);
|
||||
}
|
||||
}
|
||||
|
||||
public CoreCommandsInterface(CommandsBot linktobot)
|
||||
{
|
||||
bot = linktobot;
|
||||
API_type = typeof(CoreCommand);
|
||||
LoadCommandsList();
|
||||
}
|
||||
protected HttpClient HTTPclient = new HttpClient();
|
||||
|
||||
public bool SmartCommandReply(string target, string output)
|
||||
{
|
||||
return SmartCommandReply(target, output, "", false);
|
||||
}
|
||||
public bool SmartCommandReply(string target, string output, string command)
|
||||
{
|
||||
return SmartCommandReply(target, output, command, false);
|
||||
}
|
||||
public bool SmartCommandReply(string target,string output,string command,bool vaildate_only)
|
||||
{
|
||||
string mode = "CHAT";
|
||||
UUID target_avatar = UUID.Zero;
|
||||
int target_channel = 0;
|
||||
if (target.StartsWith("http://"))
|
||||
{
|
||||
mode = "HTTP";
|
||||
}
|
||||
else if (UUID.TryParse(target, out target_avatar) == true)
|
||||
{
|
||||
mode = "IM";
|
||||
}
|
||||
else
|
||||
{
|
||||
int.TryParse(target, out target_channel);
|
||||
}
|
||||
if (vaildate_only == false)
|
||||
{
|
||||
if (mode == "CHAT")
|
||||
{
|
||||
bot.GetClient.Self.Chat(output, target_channel, ChatType.Normal);
|
||||
}
|
||||
else if (mode == "IM")
|
||||
{
|
||||
bot.GetClient.Self.InstantMessage(target_avatar, output);
|
||||
}
|
||||
else if (mode == "HTTP")
|
||||
{
|
||||
Dictionary<string, string> values = new Dictionary<string, string>
|
||||
{
|
||||
{ "reply", output },
|
||||
{ "unixtime", helpers.UnixTimeNow().ToString() }
|
||||
};
|
||||
|
||||
if (command != "") values.Add("command", command);
|
||||
var content = new FormUrlEncodedContent(values);
|
||||
try
|
||||
{
|
||||
HTTPclient.PostAsync(target, content);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
ConsoleLog.Crit("[SmartReply] HTTP failed: " + e.Message + "");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((mode == "CHAT") || (mode == "IM") || (mode == "HTTP"))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
protected List<string> suppress_warnings = new List<string>();
|
||||
public bool Call(string command)
|
||||
{
|
||||
return Call(command, "");
|
||||
}
|
||||
public bool Call(string command,string arg)
|
||||
{
|
||||
command = command.ToLowerInvariant();
|
||||
CoreCommand cmd = (CoreCommand)GetCommand(command);
|
||||
if(cmd != null)
|
||||
{
|
||||
cmd.Setup(bot);
|
||||
if ((cmd.ArgTypes.Contains("Avatar") == true) || (cmd.ArgTypes.Contains("Smart") == true))
|
||||
{
|
||||
string[] args = arg.Split(new string[] { "~#~" }, StringSplitOptions.None);
|
||||
if (cmd.MinArgs <= args.Length)
|
||||
{
|
||||
pending_avatar_lookup pending = new pending_avatar_lookup(this, cmd, args);
|
||||
if (pending.needs_lookup() == true)
|
||||
{
|
||||
commands_pending_avatar_lookups.Add(next_lookup_id, pending);
|
||||
commands_pending_avatar_lookups_ages.Add(next_lookup_id, helpers.UnixTimeNow());
|
||||
next_lookup_id++;
|
||||
if (next_lookup_id == 13000)
|
||||
{
|
||||
next_lookup_id = 0;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return pending.Callnow();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return cmd.CallFunction(arg.Split(new string[] { "~#~" }, StringSplitOptions.None));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (suppress_warnings.Contains(command) == false)
|
||||
{
|
||||
suppress_warnings.Add(command);
|
||||
ConsoleLog.Debug("[CMD/Failed] " + command + " : I have no fucking idea what you are talking about");
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
public abstract class CoreCommand : API_interface
|
||||
{
|
||||
protected CommandsBot bot = null;
|
||||
public void Setup(CommandsBot setBot)
|
||||
{
|
||||
bot = setBot;
|
||||
}
|
||||
public virtual void Callback(string[] args, EventArgs e)
|
||||
{
|
||||
|
||||
}
|
||||
public virtual bool CallFunction(string[] args)
|
||||
{
|
||||
if (args.Length < MinArgs)
|
||||
{
|
||||
return Failed("Incorrect number of args");
|
||||
}
|
||||
else
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
public bool Failed(string why_failed)
|
||||
{
|
||||
ConsoleLog.Warn("[CMD/Failed] " + CommandName + ": " + why_failed);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
69
Core/RLV/Blacklist/getblacklist.cs
Normal file
69
Core/RLV/Blacklist/getblacklist.cs
Normal file
|
|
@ -0,0 +1,69 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace BSB.RLV.Blacklist
|
||||
{
|
||||
public class GetBlacklist : RLV_command_1arg
|
||||
{
|
||||
public override bool CallFunction(string[] args)
|
||||
{
|
||||
if (base.CallFunction(args) == true)
|
||||
{
|
||||
int channel;
|
||||
string filter = "";
|
||||
if(args.Length == 2)
|
||||
{
|
||||
if(int.TryParse(args[1], out channel) == true)
|
||||
{
|
||||
filter = args[0];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
int.TryParse(args[0], out channel);
|
||||
}
|
||||
if (channel >= 0)
|
||||
{
|
||||
string sendim = "";
|
||||
string recvim = "";
|
||||
if (filter == "")
|
||||
{
|
||||
sendim = String.Join('|', bot.Getblacklist_sendim);
|
||||
recvim = String.Join('|', bot.Getblacklist_recvim);
|
||||
}
|
||||
else
|
||||
{
|
||||
string addon = "";
|
||||
foreach (string a in bot.Getblacklist_sendim)
|
||||
{
|
||||
if (a.Contains(filter) == true)
|
||||
{
|
||||
sendim = "" + sendim + "" + addon + "" + a + "";
|
||||
addon = "|";
|
||||
}
|
||||
}
|
||||
addon = "";
|
||||
foreach (string a in bot.Getblacklist_recvim)
|
||||
{
|
||||
if (a.Contains(filter) == true)
|
||||
{
|
||||
recvim = "" + recvim + "" + addon + "" + a + "";
|
||||
addon = "|";
|
||||
}
|
||||
}
|
||||
}
|
||||
if (sendim == "") sendim = "#";
|
||||
if (recvim == "") recvim = "#";
|
||||
bot.GetClient.Self.Chat("" + sendim + "," + recvim + "", channel, OpenMetaverse.ChatType.Normal);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return Failed("Invaild channel given");
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
31
Core/RLV/Blacklist/versionnumbl.cs
Normal file
31
Core/RLV/Blacklist/versionnumbl.cs
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace BSB.RLV.Blacklist
|
||||
{
|
||||
public class VersionNumBL : RLV_command_1arg
|
||||
{
|
||||
public override bool CallFunction(string[] args)
|
||||
{
|
||||
if (base.CallFunction(args) == true)
|
||||
{
|
||||
_ = int.TryParse(args[0], out int channel);
|
||||
if (channel >= 0)
|
||||
{
|
||||
string sendim = String.Join('|', bot.Getblacklist_sendim);
|
||||
string recvim = String.Join('|', bot.Getblacklist_recvim);
|
||||
if (sendim == "") { sendim = "#"; }
|
||||
if (recvim == "") { recvim = "#"; }
|
||||
bot.GetClient.Self.Chat("209000," + sendim + "," + recvim + "", channel, OpenMetaverse.ChatType.Normal);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return Failed("Invaild channel given");
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
11
Core/RLV/Camera/camavdist.cs
Normal file
11
Core/RLV/Camera/camavdist.cs
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace BSB.RLV.Camera
|
||||
{
|
||||
public class CamAvDist : RLV_UUID_flag_arg_yn
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
10
Core/RLV/Camera/camdistmax.cs
Normal file
10
Core/RLV/Camera/camdistmax.cs
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace BSB.RLV.Camera
|
||||
{
|
||||
public class CamDistMax : RLV_UUID_flag_arg_yn
|
||||
{
|
||||
}
|
||||
}
|
||||
10
Core/RLV/Camera/camdistmin.cs
Normal file
10
Core/RLV/Camera/camdistmin.cs
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace BSB.RLV.Camera
|
||||
{
|
||||
public class CamDistMin : RLV_UUID_flag_arg_yn
|
||||
{
|
||||
}
|
||||
}
|
||||
10
Core/RLV/Camera/camdrawalphamax.cs
Normal file
10
Core/RLV/Camera/camdrawalphamax.cs
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace BSB.RLV.Camera
|
||||
{
|
||||
public class CamDrawAlphaMax : RLV_UUID_flag_arg_yn
|
||||
{
|
||||
}
|
||||
}
|
||||
10
Core/RLV/Camera/camdrawalphamin.cs
Normal file
10
Core/RLV/Camera/camdrawalphamin.cs
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace BSB.RLV.Camera
|
||||
{
|
||||
public class CamDrawAlphaMin : RLV_UUID_flag_arg_yn
|
||||
{
|
||||
}
|
||||
}
|
||||
10
Core/RLV/Camera/camdrawcolor.cs
Normal file
10
Core/RLV/Camera/camdrawcolor.cs
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace BSB.RLV.Camera
|
||||
{
|
||||
public class CamDrawColor : RLV_UUID_flag_4arg_yn
|
||||
{
|
||||
}
|
||||
}
|
||||
10
Core/RLV/Camera/camdrawmax.cs
Normal file
10
Core/RLV/Camera/camdrawmax.cs
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace BSB.RLV.Camera
|
||||
{
|
||||
public class CamDrawMax : RLV_UUID_flag_arg_yn
|
||||
{
|
||||
}
|
||||
}
|
||||
10
Core/RLV/Camera/camdrawmin.cs
Normal file
10
Core/RLV/Camera/camdrawmin.cs
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace BSB.RLV.Camera
|
||||
{
|
||||
public class CamDrawMin : RLV_UUID_flag_arg_yn
|
||||
{
|
||||
}
|
||||
}
|
||||
10
Core/RLV/Camera/camtextures.cs
Normal file
10
Core/RLV/Camera/camtextures.cs
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace BSB.RLV.Camera
|
||||
{
|
||||
public class CamTextures : RLV_UUID_flag_optional_arg_yn
|
||||
{
|
||||
}
|
||||
}
|
||||
10
Core/RLV/Camera/camunlock.cs
Normal file
10
Core/RLV/Camera/camunlock.cs
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace BSB.RLV.Camera
|
||||
{
|
||||
public class CamUnlock : RLV_UUID_flag_yn
|
||||
{
|
||||
}
|
||||
}
|
||||
10
Core/RLV/Camera/camzoommax.cs
Normal file
10
Core/RLV/Camera/camzoommax.cs
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace BSB.RLV.Camera
|
||||
{
|
||||
public class CamZoomMax : RLV_UUID_flag_arg_yn
|
||||
{
|
||||
}
|
||||
}
|
||||
10
Core/RLV/Camera/camzoommin.cs
Normal file
10
Core/RLV/Camera/camzoommin.cs
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace BSB.RLV.Camera
|
||||
{
|
||||
public class CamZoomMin : RLV_UUID_flag_arg_yn
|
||||
{
|
||||
}
|
||||
}
|
||||
11
Core/RLV/Camera/getcam_avdistmax.cs
Normal file
11
Core/RLV/Camera/getcam_avdistmax.cs
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace BSB.RLV.Camera
|
||||
{
|
||||
public class GetCam_AvDistMax : RLV_UUID_flag_get
|
||||
{
|
||||
public override string LookupFlag { get { return "camavdistmax"; } }
|
||||
}
|
||||
}
|
||||
12
Core/RLV/Camera/getcam_avdistmin.cs
Normal file
12
Core/RLV/Camera/getcam_avdistmin.cs
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace BSB.RLV.Camera
|
||||
{
|
||||
public class GetCam_AvDistMin : RLV_UUID_flag_get
|
||||
{
|
||||
public override string LookupFlag { get { return "camavdistmin"; } }
|
||||
|
||||
}
|
||||
}
|
||||
12
Core/RLV/Camera/getcam_fov.cs
Normal file
12
Core/RLV/Camera/getcam_fov.cs
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace BSB.RLV.Camera
|
||||
{
|
||||
public class GetCam_Fov : RLV_UUID_flag_get
|
||||
{
|
||||
public override string LookupFlag { get { return "camfov"; } }
|
||||
|
||||
}
|
||||
}
|
||||
12
Core/RLV/Camera/getcam_fovmax.cs
Normal file
12
Core/RLV/Camera/getcam_fovmax.cs
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace BSB.RLV.Camera
|
||||
{
|
||||
public class GetCam_FovMax : RLV_UUID_flag_get
|
||||
{
|
||||
public override string LookupFlag { get { return "camfovmax"; } }
|
||||
|
||||
}
|
||||
}
|
||||
11
Core/RLV/Camera/getcam_fovmin.cs
Normal file
11
Core/RLV/Camera/getcam_fovmin.cs
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace BSB.RLV.Camera
|
||||
{
|
||||
public class GetCam_FovMin : RLV_UUID_flag_get
|
||||
{
|
||||
public override string LookupFlag { get { return "camfovmin"; } }
|
||||
}
|
||||
}
|
||||
12
Core/RLV/Camera/getcam_zoommin.cs
Normal file
12
Core/RLV/Camera/getcam_zoommin.cs
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace BSB.RLV.Camera
|
||||
{
|
||||
public class GetCam_ZoomMin : RLV_UUID_flag_get
|
||||
{
|
||||
public override string LookupFlag { get { return "camzoommin"; } }
|
||||
|
||||
}
|
||||
}
|
||||
11
Core/RLV/Camera/setcam_avdistmax.cs
Normal file
11
Core/RLV/Camera/setcam_avdistmax.cs
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace BSB.RLV.Camera
|
||||
{
|
||||
public class SetCam_AvDistMax : RLV_UUID_flag_arg_yn
|
||||
{
|
||||
public override string SetFlagName { get { return "camavdistmax"; } }
|
||||
}
|
||||
}
|
||||
12
Core/RLV/Camera/setcam_avdistmin.cs
Normal file
12
Core/RLV/Camera/setcam_avdistmin.cs
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace BSB.RLV.Camera
|
||||
{
|
||||
public class SetCam_AvDistMin : RLV_UUID_flag_arg_yn
|
||||
{
|
||||
public override string SetFlagName { get { return "camavdistmin"; } }
|
||||
|
||||
}
|
||||
}
|
||||
11
Core/RLV/Camera/setcam_fov.cs
Normal file
11
Core/RLV/Camera/setcam_fov.cs
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace BSB.RLV.Camera
|
||||
{
|
||||
public class SetCam_Fov : RLV_UUID_flag_arg_yn
|
||||
{
|
||||
public override string SetFlagName { get { return "camfov"; } }
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue