Joined the HTTP commands and Core commands into one system

There is no limit to my evil!!!!
This commit is contained in:
Madpeterz 2021-02-18 09:42:48 +00:00
parent b70ef7c186
commit fd1ca6626f
60 changed files with 1521 additions and 2482 deletions

View file

@ -4,6 +4,7 @@ using BetterSecondBotShared.Static;
using BetterSecondBot.bottypes; using BetterSecondBot.bottypes;
using OpenMetaverse; using OpenMetaverse;
using System.Collections.Generic; using System.Collections.Generic;
using BetterSecondBotShared.logs;
namespace BetterSecondbot.BetterAtHome namespace BetterSecondbot.BetterAtHome
{ {
@ -20,6 +21,7 @@ namespace BetterSecondbot.BetterAtHome
protected int homeregionIndexer = 0; protected int homeregionIndexer = 0;
protected long LastTeleportEvent = 0; protected long LastTeleportEvent = 0;
protected List<string> homeRegions = new List<string>(); protected List<string> homeRegions = new List<string>();
protected string LastLoginStatus = "None";
public BetterAtHome(Cli setcontroler, JsonConfig configfile) public BetterAtHome(Cli setcontroler, JsonConfig configfile)
{ {
@ -62,20 +64,23 @@ namespace BetterSecondbot.BetterAtHome
protected void LoginProcess(object o, LoginProgressEventArgs e) protected void LoginProcess(object o, LoginProgressEventArgs e)
{ {
resetSwitchs(); LastLoginStatus = e.Status.ToString();
if(e.Status == LoginStatus.Failed) if (e.Status == LoginStatus.Failed)
{ {
resetSwitchs();
LoginFailed = true; LoginFailed = true;
} }
else if(e.Status == LoginStatus.ConnectingToLogin) else if(e.Status == LoginStatus.ConnectingToLogin)
{ {
resetSwitchs();
LoggingIn = true; LoggingIn = true;
SetBetterAtHomeAction("Waiting for login to finish"); SetBetterAtHomeAction("Waiting for login to finish");
} }
else if(e.Status == LoginStatus.Success) else if(e.Status == LoginStatus.Success)
{ {
LoggedIn = true; resetSwitchs();
controler.Bot.AfterBotLoginHandler(); controler.Bot.AfterBotLoginHandler();
LoggedIn = true;
} }
} }
@ -115,6 +120,10 @@ namespace BetterSecondbot.BetterAtHome
{ {
return false; return false;
} }
if(hasBasicBot() == false)
{
return false;
}
if(LoggingIn == true) if(LoggingIn == true)
{ {
return false; return false;
@ -154,6 +163,7 @@ namespace BetterSecondbot.BetterAtHome
} }
protected string simname = ""; protected string simname = "";
protected int void_counter = 0;
protected void ChangedSim(object o, SimChangedEventArgs e) protected void ChangedSim(object o, SimChangedEventArgs e)
{ {
simname = ""; simname = "";
@ -180,13 +190,13 @@ namespace BetterSecondbot.BetterAtHome
return; return;
} }
long dif = helpers.UnixTimeNow() - LastLoginEvent; long dif = helpers.UnixTimeNow() - LastLoginEvent;
if (dif < 60) if (dif < 15)
{ {
SetBetterAtHomeAction("[DC] Waiting for login lockout"); SetBetterAtHomeAction("[DC] Waiting for login lockout");
return; return;
} }
dif = helpers.UnixTimeNow() - LastTeleportEvent; dif = helpers.UnixTimeNow() - LastTeleportEvent;
if (dif < 60) if (dif < 15)
{ {
SetBetterAtHomeAction("[DC] Waiting for Teleport lockout"); SetBetterAtHomeAction("[DC] Waiting for Teleport lockout");
return; return;
@ -209,6 +219,19 @@ namespace BetterSecondbot.BetterAtHome
protected void LoggedInAction() protected void LoggedInAction()
{ {
if((simname == "") || (controler.Bot.GetClient.Self.SimPosition.Z == 0))
{
ChangedSim(null, null);
void_counter++;
SetBetterAtHomeAction("Void counter: "+ void_counter.ToString());
if (void_counter == 10)
{
resetSwitchs();
SetBetterAtHomeAction("Void detected - Resetting switchs");
}
return;
}
void_counter = 0;
SetBetterAtHomeAction("Logged In Actions"); SetBetterAtHomeAction("Logged In Actions");
if (controler.Bot.KillMe == true) if (controler.Bot.KillMe == true)
{ {
@ -227,7 +250,7 @@ namespace BetterSecondbot.BetterAtHome
SetBetterAtHomeAction("Waiting for Teleport lockout"); SetBetterAtHomeAction("Waiting for Teleport lockout");
return; return;
} }
if(homeRegions.Count == 0) if (homeRegions.Count == 0)
{ {
SetBetterAtHomeAction("No home regions"); SetBetterAtHomeAction("No home regions");
return; return;

View file

@ -248,7 +248,8 @@ namespace BetterSecondBot.BetterRelayService
{ {
if (cfg.targetvalue != filtervalue) if (cfg.targetvalue != filtervalue)
{ {
bool status = controler.Bot.GetCommandsInterface.Call("groupchat", cfg.targetvalue + "~#~" + sendmessage, UUID.Zero, "~#~"); bool status = false;
//bool status = controler.Bot.GetCommandsInterface.Call("groupchat", cfg.targetvalue + "~#~" + sendmessage, UUID.Zero, "~#~");
if(status == false) if(status == false)
{ {
LogFormater.Info("sending via groupchat to group: " + cfg.targetvalue + " [Failed]"); LogFormater.Info("sending via groupchat to group: " + cfg.targetvalue + " [Failed]");

View file

@ -92,61 +92,11 @@ namespace BetterSecondBot.DiscordSupervisor
{ {
if (message.Content == "!commands") if (message.Content == "!commands")
{ {
int counter = 0; await SendMessageToChannelAsync("interface", "broken", "bot", UUID.Zero, "bot");
string addon = "";
foreach (string a in controler.Bot.GetCommandsInterface.GetCommandsList())
{
output.Append(addon);
addon = " , ";
output.Append(a);
counter++;
if (counter == 5)
{
output.Append("\n");
addon = "";
counter = 0;
}
}
await SendMessageToChannelAsync("interface", output.ToString(), "bot", UUID.Zero, "bot");
} }
else if (message.Content.StartsWith("!help") == true) else if (message.Content.StartsWith("!help") == true)
{ {
string[] bits = message.Content.Split(' '); await SendMessageToChannelAsync("interface", "broken", "bot", UUID.Zero, "bot");
if (bits.Length == 2)
{
string command = bits[1].ToLowerInvariant();
if (controler.Bot.GetCommandsInterface.GetCommandsList().Contains(command) == true)
{
output.Append("\n=========================\nCommand:");
output.Append(command);
output.Append("\n");
output.Append("Workspace: ");
output.Append(controler.Bot.GetCommandsInterface.GetCommandWorkspace(command));
output.Append("\n");
output.Append("Min args: ");
output.Append(controler.Bot.GetCommandsInterface.GetCommandArgs(command).ToString());
output.Append("\n");
output.Append("Arg types: ");
output.Append(String.Join(",", controler.Bot.GetCommandsInterface.GetCommandArgTypes(command)));
output.Append("\n");
output.Append("\n");
output.Append("About: ");
output.Append(controler.Bot.GetCommandsInterface.GetCommandHelp(command));
await SendMessageToChannelAsync("interface", output.ToString(), "bot", UUID.Zero, "bot");
}
else
{
output.Append("Unable to find command: ");
output.Append(command);
output.Append(" please use !commands for a full list");
await SendMessageToChannelAsync("interface", output.ToString(), "bot", UUID.Zero, "bot");
}
}
else
{
await SendMessageToChannelAsync("interface", "Please format help request as follows: !help commandname", "bot", UUID.Zero, "bot");
}
} }
else else
{ {
@ -157,46 +107,7 @@ namespace BetterSecondBot.DiscordSupervisor
} }
else else
{ {
string[] bits = message.Content.Split("|||"); await MarkMessage(message, "❌").ConfigureAwait(false);
string command = bits[0].ToLowerInvariant();
bool known_command = controler.Bot.GetCommandsInterface.GetCommandsList().Contains(command);
if (known_command == false)
{
known_command = controler.Bot.getCustomCommands.ContainsKey(command);
}
if (known_command == true)
{
bool process_status = false;
if (bits.Length == 1)
{
bits = new string[] { bits[0], "" };
}
if (controler.Bot.getCustomCommands.ContainsKey(command) == false)
{
process_status = controler.Bot.GetCommandsInterface.Call(command, bits[1], UUID.Zero);
}
else
{
process_status = true;
Thread t = new Thread(() => controler.Bot.custom_commands_loop(command, bits[1], UUID.Zero));
t.Start();
}
if (process_status == true)
{
await MarkMessage(message, "✅").ConfigureAwait(false);
}
else
{
await MarkMessage(message, "❌").ConfigureAwait(false);
}
}
else
{
output.Append("Unable to find command: ");
output.Append(command);
output.Append(" please use !commands for a full list");
await SendMessageToChannelAsync("interface", output.ToString(), "bot", UUID.Zero, "bot");
}
} }
} }
} }
@ -269,14 +180,16 @@ namespace BetterSecondBot.DiscordSupervisor
} }
Noticetitle = Noticetitle.Replace("!notice ", ""); Noticetitle = Noticetitle.Replace("!notice ", "");
Noticetitle = Noticetitle.Trim(); Noticetitle = Noticetitle.Trim();
controler.Bot.GetCommandsInterface.Call("GroupNotice", "" + group.ToString() + "~#~" + Noticetitle + "~#~" + Noticemessage, UUID.Zero); //controler.Bot.GetCommandsInterface.Call("GroupNotice", "" + group.ToString() + "~#~" + Noticetitle + "~#~" + Noticemessage, UUID.Zero);
await MarkMessage(message, "✅"); //await MarkMessage(message, "✅");
await MarkMessage((IUserMessage)message, "❌").ConfigureAwait(false);
} }
else else
{ {
IGuildUser user = (IGuildUser)message.Author; IGuildUser user = (IGuildUser)message.Author;
controler.Bot.GetCommandsInterface.Call("Groupchat", "" + group.ToString() + "~#~" + message.Content, UUID.Zero); //controler.Bot.GetCommandsInterface.Call("Groupchat", "" + group.ToString() + "~#~" + message.Content, UUID.Zero);
await MarkMessage(message, "✅"); //await MarkMessage(message, "✅");
await MarkMessage((IUserMessage)message, "❌").ConfigureAwait(false);
} }
} }
} }

View file

@ -13,13 +13,11 @@
</button> </button>
<div class="collapse navbar-collapse" id="navbarCollapse"> <div class="collapse navbar-collapse" id="navbarCollapse">
<div class="navbar-nav"> <div class="navbar-nav">
<a href="[[SUBFOLDER]]Core.html" class="nav-item nav-link [[CoreActive]]">Main commands [Core]</a>
<a href="[[SUBFOLDER]]JSON.html" class="nav-item nav-link [[JSONActive]]">JSON [Bot Config file]</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]]Commands.html" class="nav-item nav-link [[CommandsActive]]">Commands</a>
<a href="[[SUBFOLDER]]HTTP.html" class="nav-item nav-link [[HTTPActive]]">WebLink [HTTP]</a>
</div> </div>
<div class="navbar-nav ml-auto"> <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="https://github.com/Madpeterz/SecondBot" 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> <a href="secondlife:///app/group/cbda0f35-1c0b-2a45-e693-62a63a8f9d88/about" target="_BLANK" class="nav-item nav-link">SL group</a>
</div> </div>
</div> </div>

View file

@ -4,6 +4,7 @@ using BetterSecondBotShared.IO;
using BetterSecondBotShared.Json; using BetterSecondBotShared.Json;
using BetterSecondBotShared.logs; using BetterSecondBotShared.logs;
using BetterSecondBotShared.Static; using BetterSecondBotShared.Static;
using Core.Static;
using EmbedIO; using EmbedIO;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
@ -288,11 +289,6 @@ namespace BetterSecondBot.WikiMake
api_reports.Add("JSON", new KeyValuePair<int, string>(defaultJson.ApiCommandsCount, "Ready")); api_reports.Add("JSON", new KeyValuePair<int, string>(defaultJson.ApiCommandsCount, "Ready"));
InterfaceWiki("JSON", defaultJson); InterfaceWiki("JSON", defaultJson);
// CMD
BetterSecondBot.Commands.CoreCommandsInterface cmd = new BetterSecondBot.Commands.CoreCommandsInterface(null);
api_reports.Add("Core", new KeyValuePair<int, string>(cmd.ApiCommandsCount, "Good"));
InterfaceWiki("Core", cmd, true);
// HTTP // HTTP
HTTPWiki(); HTTPWiki();
@ -305,13 +301,13 @@ namespace BetterSecondBot.WikiMake
LogFormater.Info("[WIKI] Starting area HTTP endpoint"); LogFormater.Info("[WIKI] Starting area HTTP endpoint");
HTTPendpoint HTTP = new HTTPendpoint(); HTTPendpoint HTTP = new HTTPendpoint();
HTTPmenu("HTTP", HTTP); HTTPmenu("Commands", HTTP);
// create workspaces // create workspaces
HTTPWorkspaces("HTTP", HTTP); HTTPWorkspaces("Commands", HTTP);
// create commands // create commands
HTTPCommands("HTTP", HTTP); HTTPCommands("Commands", HTTP);
HTTP = null; HTTP = null;
LogFormater.Info("[WIKI] Done with area"); LogFormater.Info("[WIKI] Done with area");
@ -350,9 +346,27 @@ namespace BetterSecondBot.WikiMake
sb.Append("</h4><hr/><h3>[[COMMAND]]</h3>"); sb.Append("</h4><hr/><h3>[[COMMAND]]</h3>");
sb.Append("[[URLENDPOINT]]/[[WORKSPACE]]/[[COMMAND]]/[[URLADDON]]<br/>"); sb.Append("[[URLENDPOINT]]/[[WORKSPACE]]/[[COMMAND]]/[[URLADDON]]<br/>");
sb.Append("Method: [[APIMETHOD]]"); sb.Append("Method: [[APIMETHOD]]");
sb.Append("<hr style='border-top: 1px dashed #dcdcdc;'>"); sb.Append("<br/> OR <br/>");
sb.Append("[[HELP]]");
Dictionary<string, KeyValuePair<string, string>> values = HTTP.getCommandArgs(workspace, c); Dictionary<string, KeyValuePair<string, string>> values = HTTP.getCommandArgs(workspace, c);
sb.Append("[[COMMAND]]");
string addon = "";
List<string> argsim = new List<string>(values.Keys);
argsim.Remove("token");
if(argsim.Count > 0)
{
sb.Append("|||");
}
foreach (string entry in argsim)
{
sb.Append(addon);
sb.Append("{");
sb.Append(entry);
sb.Append("}");
addon = "~#~";
}
sb.Append("<br/><br/>");
sb.Append("[[HELP]]");
int ValueCount = values.Count; int ValueCount = values.Count;
if (ValueCount > 0) if (ValueCount > 0)
@ -413,7 +427,7 @@ namespace BetterSecondBot.WikiMake
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
sb.Append(html_header); sb.Append(html_header);
sb.Append("<h3>Interface:"); sb.Append("<h3>Interface:");
sb.Append("HTTP"); sb.Append("Commands");
sb.Append("</h3><br/>"); sb.Append("</h3><br/>");
sb.Append("<h4>Build: "); sb.Append("<h4>Build: ");
sb.Append(buildVersion); sb.Append(buildVersion);
@ -452,7 +466,7 @@ namespace BetterSecondBot.WikiMake
sb.Append("<h4>Build: "); sb.Append("<h4>Build: ");
sb.Append(buildVersion); sb.Append(buildVersion);
sb.Append("</h4><br/>"); 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>"); sb.Append("<table class='datatable table table-striped table-bordered'><thead><tr><th>Command</th><th>Min args (+1 for HTTP)</th></tr></thead><tbody>");
foreach (string c in HTTP.getEndpointCommands(workspace)) foreach (string c in HTTP.getEndpointCommands(workspace))
{ {
int args = HTTP.getCommandArgCount(workspace, c); int args = HTTP.getCommandArgCount(workspace, c);
@ -462,7 +476,7 @@ namespace BetterSecondBot.WikiMake
sb.Append(".html'>"); sb.Append(".html'>");
sb.Append(c); sb.Append(c);
sb.Append("</a></td><td>"); sb.Append("</a></td><td>");
sb.Append(args.ToString()); sb.Append((args-1).ToString());
sb.Append("</td></tr>"); sb.Append("</td></tr>");
} }
sb.Append("</tbody></table>"); sb.Append("</tbody></table>");
@ -481,8 +495,6 @@ namespace BetterSecondBot.WikiMake
public class HTTPendpoint public class HTTPendpoint
{ {
protected List<Endpoint> endpoints = new List<Endpoint>(); protected List<Endpoint> endpoints = new List<Endpoint>();
public void createEndpoint(string name, Type Api) public void createEndpoint(string name, Type Api)
{ {
Endpoint Endpoint = new Endpoint(); Endpoint Endpoint = new Endpoint();
@ -521,7 +533,7 @@ namespace BetterSecondBot.WikiMake
} }
if (httpverb != null) if (httpverb != null)
{ {
C.name = M.Name.ToLowerInvariant(); C.name = M.Name;
C.type = "Post"; C.type = "Post";
C.about = "Http interface command about missing"; C.about = "Http interface command about missing";
if (About != null) if (About != null)
@ -553,13 +565,11 @@ namespace BetterSecondBot.WikiMake
} }
public HTTPendpoint() public HTTPendpoint()
{ {
createEndpoint("core", typeof(HttpApiCore)); Dictionary<string, Type> commandmodules = http_commands_helper.getCommandModules();
createEndpoint("inventory", typeof(HTTP_Inventory)); foreach (KeyValuePair<string, Type> entry in commandmodules)
createEndpoint("im", typeof(HttpApiIM)); {
createEndpoint("groups", typeof(HTTP_Group)); createEndpoint(entry.Key, entry.Value);
createEndpoint("chat", typeof(HTTP_Chat)); }
createEndpoint("parcel", typeof(HTTP_Parcel));
createEndpoint("estate", typeof(HTTP_Estate));
} }
public string getCommandMethod(string endpoint, string command) public string getCommandMethod(string endpoint, string command)

View file

@ -24,7 +24,7 @@ namespace BetterSecondBot.HttpService
[Route(HttpVerbs.Get, "/AddToAllowAnimations/{avatar}/{token}")] [Route(HttpVerbs.Get, "/AddToAllowAnimations/{avatar}/{token}")]
public object AddToAllowAnimations(string avatar, string token) public object AddToAllowAnimations(string avatar, string token)
{ {
if (tokens.Allow(token, "animation", "addtoallowanimations", getClientIP()) == false) if (tokens.Allow(token, "animation", "addtoallowanimations", handleGetClientIP()) == false)
{ {
return BasicReply("Token not accepted"); return BasicReply("Token not accepted");
} }
@ -49,7 +49,7 @@ namespace BetterSecondBot.HttpService
[Route(HttpVerbs.Get, "/PlayGesture/{gesture}/{token}")] [Route(HttpVerbs.Get, "/PlayGesture/{gesture}/{token}")]
public object PlayGesture(string gesture, string token) public object PlayGesture(string gesture, string token)
{ {
if (tokens.Allow(token, "animation", "gesture", getClientIP()) == false) if (tokens.Allow(token, "animation", "gesture", handleGetClientIP()) == false)
{ {
return BasicReply("Token not accepted"); return BasicReply("Token not accepted");
} }
@ -67,7 +67,7 @@ namespace BetterSecondBot.HttpService
[Route(HttpVerbs.Get, "/ResetAnimations/{token}")] [Route(HttpVerbs.Get, "/ResetAnimations/{token}")]
public object ResetAnimations(string token) public object ResetAnimations(string token)
{ {
if (tokens.Allow(token, "animation", "resetanimations", getClientIP()) == false) if (tokens.Allow(token, "animation", "resetanimations", handleGetClientIP()) == false)
{ {
return BasicReply("Token not accepted"); return BasicReply("Token not accepted");
} }

View file

@ -22,7 +22,7 @@ namespace BetterSecondBot.HttpService
[Route(HttpVerbs.Get, "/NearmeWithDetails/{token}")] [Route(HttpVerbs.Get, "/NearmeWithDetails/{token}")]
public object NearmeWithDetails(string token) public object NearmeWithDetails(string token)
{ {
if (tokens.Allow(token, "avatars", "nearmewithdetails", getClientIP()) == false) if (tokens.Allow(token, "avatars", "nearmewithdetails", handleGetClientIP()) == false)
{ {
return BasicReply("Token not accepted"); return BasicReply("Token not accepted");
} }
@ -55,7 +55,7 @@ namespace BetterSecondBot.HttpService
[Route(HttpVerbs.Get, "/Nearme/{token}")] [Route(HttpVerbs.Get, "/Nearme/{token}")]
public object Nearme(string token) public object Nearme(string token)
{ {
if (tokens.Allow(token, "avatars", "nearme", getClientIP()) == false) if (tokens.Allow(token, "avatars", "nearme", handleGetClientIP()) == false)
{ {
return BasicReply("Token not accepted"); return BasicReply("Token not accepted");
} }

View file

@ -21,11 +21,11 @@ namespace BetterSecondBot.HttpService
[Route(HttpVerbs.Get, "/LocalChatHistory/{token}")] [Route(HttpVerbs.Get, "/LocalChatHistory/{token}")]
public object LocalChatHistory(string token) public object LocalChatHistory(string token)
{ {
if (tokens.Allow(token, "chat", "localchathistory", getClientIP()) == true) if (tokens.Allow(token, "chat", "localchathistory", handleGetClientIP()) == false)
{ {
return BasicReply(JsonConvert.SerializeObject(bot.getLocalChatHistory())); return Failure("Token not accepted");
} }
return BasicReply("Token not accepted"); return BasicReply(JsonConvert.SerializeObject(bot.getLocalChatHistory()));
} }
[About("sends a message to localchat")] [About("sends a message to localchat")]
@ -37,7 +37,7 @@ namespace BetterSecondBot.HttpService
[Route(HttpVerbs.Post, "/Say/{channel}/{token}")] [Route(HttpVerbs.Post, "/Say/{channel}/{token}")]
public object Say(string channel,[FormField] string message,string token) public object Say(string channel,[FormField] string message,string token)
{ {
if (tokens.Allow(token, "chat", "localchatsay", getClientIP()) == false) if (tokens.Allow(token, "chat", "localchatsay", handleGetClientIP()) == false)
{ {
return BasicReply("Token not accepted"); return BasicReply("Token not accepted");
} }
@ -67,7 +67,7 @@ namespace BetterSecondBot.HttpService
[Route(HttpVerbs.Post, "/IM/{avatar}/{token}")] [Route(HttpVerbs.Post, "/IM/{avatar}/{token}")]
public object IM(string avatar, [FormField] string message, string token) public object IM(string avatar, [FormField] string message, string token)
{ {
if (tokens.Allow(token, "chat", "im", getClientIP()) == false) if (tokens.Allow(token, "chat", "im", handleGetClientIP()) == false)
{ {
return BasicReply("Token not accepted"); return BasicReply("Token not accepted");
} }

View file

@ -9,18 +9,13 @@ using EmbedIO.WebApi;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using Newtonsoft.Json; using Newtonsoft.Json;
using System.Threading;
namespace BetterSecondBot.HttpService namespace BetterSecondBot.HttpService
{ {
public class HttpApiCore : WebApiControllerWithTokens public class HTTP_Core : WebApiControllerWithTokens
{ {
public HTTP_Core(SecondBot mainbot, TokenStorage setuptokens) : base(mainbot, setuptokens) { }
protected JsonConfig config;
public HttpApiCore(JsonConfig myconfig, SecondBot mainbot, TokenStorage setuptokens) : base(mainbot, setuptokens)
{
config = myconfig;
}
[About("Requests a new token (Vaild for 10 mins) <br/>to use with all other requests")] [About("Requests a new token (Vaild for 10 mins) <br/>to use with all other requests")]
[NeedsToken(false)] [NeedsToken(false)]
@ -39,23 +34,17 @@ namespace BetterSecondBot.HttpService
} }
if((dif < 30) && (dif > -30)) if((dif < 30) && (dif > -30))
{ {
var raw = now.ToString() + config.Security_WebUIKey; var raw = now.ToString() + bot.getMyConfig.Security_WebUIKey;
string hash = helpers.GetSHA1(raw).Substring(0, 10); string hash = helpers.GetSHA1(raw).Substring(0, 10);
if (hash == authcode) if (hash == authcode)
{ {
string newtoken = tokens.CreateToken(getClientIP()); string newtoken = tokens.CreateToken(handleGetClientIP());
if(newtoken != null) return BasicReply(newtoken); if(newtoken != null) return BasicReply(newtoken);
} }
} }
return Failure("Authcode not accepted"); return Failure("Authcode not accepted");
} }
[About("Used to check HTTP connections")] [About("Used to check HTTP connections")]
[ReturnHints("world")] [ReturnHints("world")]
[NeedsToken(false)] [NeedsToken(false)]
@ -65,6 +54,23 @@ namespace BetterSecondBot.HttpService
return BasicReply("world"); return BasicReply("world");
} }
[About("Delays a thead by X ms<br/>Mostly pointless but good if your doing custom commands")]
[ReturnHints("Invaild amount")]
[ReturnHints("ok")]
[Route(HttpVerbs.Get, "/Delay/{amount}/{token}")]
public object Delay(string amount,string token)
{
if (tokens.Allow(token, "core", "Delay", handleGetClientIP()) == false)
{
return Failure("Token not accepted");
}
if(int.TryParse(amount,out int amountvalue) == false)
{
return Failure("Invaild amount");
}
Thread.Sleep(amountvalue);
return BasicReply("Ok");
}
[About("Removes the given token from the accepted token pool")] [About("Removes the given token from the accepted token pool")]
[ReturnHints("Failed to remove token")] [ReturnHints("Failed to remove token")]
@ -72,44 +78,11 @@ namespace BetterSecondBot.HttpService
[Route(HttpVerbs.Get, "/LogoutUI/{token}")] [Route(HttpVerbs.Get, "/LogoutUI/{token}")]
public object LogoutUI(string token) public object LogoutUI(string token)
{ {
if (tokens.Allow(token, "core", "LogoutUI", getClientIP()) == true) if (tokens.Allow(token, "core", "LogoutUI", handleGetClientIP()) == false)
{ {
return tokens.Expire(token); return Failure("Token not accepted");
} }
return Failure("Token not accepted"); return tokens.Expire(token);
}
[About("Makes a request to the core commands lib<br/>See LSL example on how to create a core command auth code")]
[ArgHints("Request Body", "JsonObject", "Command: string<br/>Args: string[]<br/>AuthCode: string")]
[ReturnHints("accepted")]
[ReturnHints("Auth not accepted")]
[ReturnHints("Failed")]
[Route(HttpVerbs.Post, "/Command/{token}")]
public async Task<object> Command(string token)
{
if (tokens.Allow(token, "core", "command", getClientIP()) == true)
{
CommandLibCall data = await HttpContext.GetRequestDataAsync<CommandLibCall>();
string compressedArgs = string.Join("~#~", data.Args);
string raw = data.Command + compressedArgs;
string cooked = helpers.GetSHA1(raw + config.Security_SignedCommandkey);
if (cooked == data.AuthCode)
{
bool status = bot.GetCommandsInterface.Call(data.Command.ToLowerInvariant(), compressedArgs, UUID.Zero, "~#~");
if (status == true)
{
return BasicReply("accepted");
}
return Failure("Failed");
}
return Failure("Auth not accepted");
}
return Failure("Token not accepted");
} }
} }

View file

@ -26,7 +26,7 @@ namespace BetterSecondBot.HttpService
[Route(HttpVerbs.Get, "/DialogRelay/{target}/{token}")] [Route(HttpVerbs.Get, "/DialogRelay/{target}/{token}")]
public object DialogRelay(string target,string token) public object DialogRelay(string target,string token)
{ {
if (tokens.Allow(token, "dialogs", "DialogRelay", getClientIP()) == false) if (tokens.Allow(token, "dialogs", "DialogRelay", handleGetClientIP()) == false)
{ {
return BasicReply("Token not accepted"); return BasicReply("Token not accepted");
} }
@ -65,7 +65,7 @@ namespace BetterSecondBot.HttpService
[Route(HttpVerbs.Get, "/DialogResponce/{dialogid}/{buttontext}/{token}")] [Route(HttpVerbs.Get, "/DialogResponce/{dialogid}/{buttontext}/{token}")]
public object DialogResponce(string dialogid, string buttontext, string token) public object DialogResponce(string dialogid, string buttontext, string token)
{ {
if (tokens.Allow(token, "dialogs", "DialogResponce", getClientIP()) == false) if (tokens.Allow(token, "dialogs", "DialogResponce", handleGetClientIP()) == false)
{ {
return BasicReply("Token not accepted"); return BasicReply("Token not accepted");
} }
@ -83,7 +83,7 @@ namespace BetterSecondBot.HttpService
[Route(HttpVerbs.Get, "/DialogTrack/{status}/{token}")] [Route(HttpVerbs.Get, "/DialogTrack/{status}/{token}")]
public object DialogTrack(string status, string token) public object DialogTrack(string status, string token)
{ {
if (tokens.Allow(token, "dialogs", "DialogTrack", getClientIP()) == false) if (tokens.Allow(token, "dialogs", "DialogTrack", handleGetClientIP()) == false)
{ {
return BasicReply("Token not accepted"); return BasicReply("Token not accepted");
} }

View file

@ -30,7 +30,7 @@ namespace BetterSecondBot.HttpService
[Route(HttpVerbs.Get, "/Discord_AddRole/{serverid}/{roleid}/{memberid}/{token}")] [Route(HttpVerbs.Get, "/Discord_AddRole/{serverid}/{roleid}/{memberid}/{token}")]
public object Discord_AddRole(string serverid,string roleid,string memberid,string token) public object Discord_AddRole(string serverid,string roleid,string memberid,string token)
{ {
if (tokens.Allow(token, "discord", "Discord_AddRole", getClientIP()) == false) if (tokens.Allow(token, "discord", "Discord_AddRole", handleGetClientIP()) == false)
{ {
return Failure("Token not accepted"); return Failure("Token not accepted");
} }
@ -51,7 +51,7 @@ namespace BetterSecondBot.HttpService
[Route(HttpVerbs.Post, "/Discord_BanMember/{serverid}/{memberid}/{token}")] [Route(HttpVerbs.Post, "/Discord_BanMember/{serverid}/{memberid}/{token}")]
public object Discord_BanMember(string serverid, string memberid, [FormField] string why, string token) public object Discord_BanMember(string serverid, string memberid, [FormField] string why, string token)
{ {
if (tokens.Allow(token, "discord", "Discord_BanMember", getClientIP()) == false) if (tokens.Allow(token, "discord", "Discord_BanMember", handleGetClientIP()) == false)
{ {
return Failure("Token not accepted"); return Failure("Token not accepted");
} }
@ -74,7 +74,7 @@ namespace BetterSecondBot.HttpService
[Route(HttpVerbs.Get, "/Discord_BulkClear_Messages/{serverid}/{memberid}/{token}")] [Route(HttpVerbs.Get, "/Discord_BulkClear_Messages/{serverid}/{memberid}/{token}")]
public object Discord_BulkClear_Messages(string serverid, string memberid, string token) public object Discord_BulkClear_Messages(string serverid, string memberid, string token)
{ {
if (tokens.Allow(token, "discord", "Discord_BulkClear_Messages", getClientIP()) == false) if (tokens.Allow(token, "discord", "Discord_BulkClear_Messages", handleGetClientIP()) == false)
{ {
return Failure("Token not accepted"); return Failure("Token not accepted");
} }
@ -94,7 +94,7 @@ namespace BetterSecondBot.HttpService
[Route(HttpVerbs.Post, "/Discord_Dm_Member/{serverid}/{memberid}/{token}")] [Route(HttpVerbs.Post, "/Discord_Dm_Member/{serverid}/{memberid}/{token}")]
public object Discord_Dm_Member(string serverid, string memberid, [FormField] string message, string token) public object Discord_Dm_Member(string serverid, string memberid, [FormField] string message, string token)
{ {
if (tokens.Allow(token, "discord", "Discord_Dm_Member", getClientIP()) == false) if (tokens.Allow(token, "discord", "Discord_Dm_Member", handleGetClientIP()) == false)
{ {
return Failure("Token not accepted"); return Failure("Token not accepted");
} }
@ -114,7 +114,7 @@ namespace BetterSecondBot.HttpService
[Route(HttpVerbs.Get, "/Discord_MembersList/{serverid}/{token}")] [Route(HttpVerbs.Get, "/Discord_MembersList/{serverid}/{token}")]
public object Discord_MembersList(string serverid, string token) public object Discord_MembersList(string serverid, string token)
{ {
if (tokens.Allow(token, "discord", "Discord_MembersList", getClientIP()) == false) if (tokens.Allow(token, "discord", "Discord_MembersList", handleGetClientIP()) == false)
{ {
return Failure("Token not accepted"); return Failure("Token not accepted");
} }
@ -135,7 +135,7 @@ namespace BetterSecondBot.HttpService
[Route(HttpVerbs.Post, "/Discord_MembersList/{serverid}/{tts}/{token}")] [Route(HttpVerbs.Post, "/Discord_MembersList/{serverid}/{tts}/{token}")]
public object Discord_MessageChannel(string serverid, string channelid, string tts, [FormField] string message, string token) public object Discord_MessageChannel(string serverid, string channelid, string tts, [FormField] string message, string token)
{ {
if (tokens.Allow(token, "discord", "Discord_MessageChannel", getClientIP()) == false) if (tokens.Allow(token, "discord", "Discord_MessageChannel", handleGetClientIP()) == false)
{ {
return Failure("Token not accepted"); return Failure("Token not accepted");
} }
@ -159,7 +159,7 @@ namespace BetterSecondBot.HttpService
[Route(HttpVerbs.Get, "/Discord_MuteMember/{serverid}/{memberid}/{mode}/{token}")] [Route(HttpVerbs.Get, "/Discord_MuteMember/{serverid}/{memberid}/{mode}/{token}")]
public object Discord_MuteMember(string serverid, string memberid, string mode, string token) public object Discord_MuteMember(string serverid, string memberid, string mode, string token)
{ {
if (tokens.Allow(token, "discord", "Discord_MuteMember", getClientIP()) == false) if (tokens.Allow(token, "discord", "Discord_MuteMember", handleGetClientIP()) == false)
{ {
return Failure("Token not accepted"); return Failure("Token not accepted");
} }
@ -179,7 +179,7 @@ namespace BetterSecondBot.HttpService
[Route(HttpVerbs.Get, "/Discord_Role_GetSettings/{serverid}/{roleid}/{token}")] [Route(HttpVerbs.Get, "/Discord_Role_GetSettings/{serverid}/{roleid}/{token}")]
public object Discord_Role_GetSettings(string serverid, string roleid, string token) public object Discord_Role_GetSettings(string serverid, string roleid, string token)
{ {
if (tokens.Allow(token, "discord", "Discord_Role_GetSettings", getClientIP()) == false) if (tokens.Allow(token, "discord", "Discord_Role_GetSettings", handleGetClientIP()) == false)
{ {
return Failure("Token not accepted"); return Failure("Token not accepted");
} }
@ -200,7 +200,7 @@ namespace BetterSecondBot.HttpService
[Route(HttpVerbs.Post, "/Discord_Role_UpdatePerms/{serverid}/{roleid}/{token}")] [Route(HttpVerbs.Post, "/Discord_Role_UpdatePerms/{serverid}/{roleid}/{token}")]
public object Discord_Role_UpdatePerms(string serverid, string roleid, [FormField] string flagscsv, string token) public object Discord_Role_UpdatePerms(string serverid, string roleid, [FormField] string flagscsv, string token)
{ {
if (tokens.Allow(token, "discord", "Discord_Role_UpdatePerms", getClientIP()) == false) if (tokens.Allow(token, "discord", "Discord_Role_UpdatePerms", handleGetClientIP()) == false)
{ {
return Failure("Token not accepted"); return Failure("Token not accepted");
} }
@ -220,7 +220,7 @@ namespace BetterSecondBot.HttpService
[Route(HttpVerbs.Get, "/Discord_RoleCreate/{serverid}/{role}/{token}")] [Route(HttpVerbs.Get, "/Discord_RoleCreate/{serverid}/{role}/{token}")]
public object Discord_RoleCreate(string serverid, string role, string token) public object Discord_RoleCreate(string serverid, string role, string token)
{ {
if (tokens.Allow(token, "discord", "Discord_RoleCreate", getClientIP()) == false) if (tokens.Allow(token, "discord", "Discord_RoleCreate", handleGetClientIP()) == false)
{ {
return Failure("Token not accepted"); return Failure("Token not accepted");
} }
@ -238,7 +238,7 @@ namespace BetterSecondBot.HttpService
[Route(HttpVerbs.Get, "/Discord_RoleList/{serverid}/{token}")] [Route(HttpVerbs.Get, "/Discord_RoleList/{serverid}/{token}")]
public object Discord_RoleList(string serverid, string token) public object Discord_RoleList(string serverid, string token)
{ {
if (tokens.Allow(token, "discord", "Discord_RoleList", getClientIP()) == false) if (tokens.Allow(token, "discord", "Discord_RoleList", handleGetClientIP()) == false)
{ {
return Failure("Token not accepted"); return Failure("Token not accepted");
} }
@ -256,7 +256,7 @@ namespace BetterSecondBot.HttpService
[Route(HttpVerbs.Get, "/Discord_RoleRemove/{serverid}/{roleid}/{token}")] [Route(HttpVerbs.Get, "/Discord_RoleRemove/{serverid}/{roleid}/{token}")]
public object Discord_RoleRemove(string serverid, string roleid, string token) public object Discord_RoleRemove(string serverid, string roleid, string token)
{ {
if (tokens.Allow(token, "discord", "Discord_RoleRemove", getClientIP()) == false) if (tokens.Allow(token, "discord", "Discord_RoleRemove", handleGetClientIP()) == false)
{ {
return Failure("Token not accepted"); return Failure("Token not accepted");
} }
@ -274,7 +274,7 @@ namespace BetterSecondBot.HttpService
[Route(HttpVerbs.Get, "/Discord_TextChannels_List/{serverid}/{roleid}/{token}")] [Route(HttpVerbs.Get, "/Discord_TextChannels_List/{serverid}/{roleid}/{token}")]
public object Discord_TextChannels_List(string serverid, string token) public object Discord_TextChannels_List(string serverid, string token)
{ {
if (tokens.Allow(token, "discord", "Discord_TextChannels_List", getClientIP()) == false) if (tokens.Allow(token, "discord", "Discord_TextChannels_List", handleGetClientIP()) == false)
{ {
return Failure("Token not accepted"); return Failure("Token not accepted");
} }

View file

@ -31,7 +31,7 @@ namespace BetterSecondBot.HttpService
[Route(HttpVerbs.Get, "/SimRestart/{delay}/{mode}/{token}")] [Route(HttpVerbs.Get, "/SimRestart/{delay}/{mode}/{token}")]
public object SimRestart(string delay, string mode, string token) public object SimRestart(string delay, string mode, string token)
{ {
if (tokens.Allow(token, "estate", "SimMessage", getClientIP()) == false) if (tokens.Allow(token, "estate", "SimMessage", handleGetClientIP()) == false)
{ {
return Failure("Token not accepted"); return Failure("Token not accepted");
} }
@ -63,7 +63,7 @@ namespace BetterSecondBot.HttpService
[Route(HttpVerbs.Post, "/SimMessage/{token}")] [Route(HttpVerbs.Post, "/SimMessage/{token}")]
public object SimMessage([FormField] string message, string token) public object SimMessage([FormField] string message, string token)
{ {
if (tokens.Allow(token, "estate", "SimMessage", getClientIP()) == false) if (tokens.Allow(token, "estate", "SimMessage", handleGetClientIP()) == false)
{ {
return Failure("Token not accepted"); return Failure("Token not accepted");
} }
@ -86,7 +86,7 @@ namespace BetterSecondBot.HttpService
[Route(HttpVerbs.Get, "/GetSimTexture/{regionname}/{token}")] [Route(HttpVerbs.Get, "/GetSimTexture/{regionname}/{token}")]
public object GetSimTexture(string regionname, string token) public object GetSimTexture(string regionname, string token)
{ {
if (tokens.Allow(token, "estate", "GetSimTexture", getClientIP()) == false) if (tokens.Allow(token, "estate", "GetSimTexture", handleGetClientIP()) == false)
{ {
return Failure("Token not accepted"); return Failure("Token not accepted");
} }
@ -103,7 +103,7 @@ namespace BetterSecondBot.HttpService
[Route(HttpVerbs.Get, "/EstateParcelReclaim/{token}")] [Route(HttpVerbs.Get, "/EstateParcelReclaim/{token}")]
public Object EstateParcelReclaim(string token) public Object EstateParcelReclaim(string token)
{ {
if (tokens.Allow(token, "estate", "EstateParcelReclaim", getClientIP()) == false) if (tokens.Allow(token, "estate", "EstateParcelReclaim", handleGetClientIP()) == false)
{ {
return Failure("Token not accepted"); return Failure("Token not accepted");
} }
@ -122,7 +122,7 @@ namespace BetterSecondBot.HttpService
[Route(HttpVerbs.Get, "/GetSimGlobalPos/{regionname}/{token}")] [Route(HttpVerbs.Get, "/GetSimGlobalPos/{regionname}/{token}")]
public Object GetSimGlobalPos(string regionname, string token) public Object GetSimGlobalPos(string regionname, string token)
{ {
if (tokens.Allow(token, "estate", "GetSimGlobalPos", getClientIP()) == false) if (tokens.Allow(token, "estate", "GetSimGlobalPos", handleGetClientIP()) == false)
{ {
return Failure("Token not accepted"); return Failure("Token not accepted");
} }
@ -142,7 +142,7 @@ namespace BetterSecondBot.HttpService
[Route(HttpVerbs.Get, "/GetEstateBanList/{token}")] [Route(HttpVerbs.Get, "/GetEstateBanList/{token}")]
public Object GetEstateBanList(string token) public Object GetEstateBanList(string token)
{ {
if (tokens.Allow(token, "estate", "banlist", getClientIP()) == false) if (tokens.Allow(token, "estate", "banlist", handleGetClientIP()) == false)
{ {
return Failure("Token not accepted"); return Failure("Token not accepted");
} }
@ -162,7 +162,7 @@ namespace BetterSecondBot.HttpService
public Object UpdateEstateBanlist(string avatar, string mode, string global, string token) public Object UpdateEstateBanlist(string avatar, string mode, string global, string token)
{ {
if (tokens.Allow(token, "estate", "banlist-add", getClientIP()) == false) if (tokens.Allow(token, "estate", "banlist-add", handleGetClientIP()) == false)
{ {
return Failure("Token not accepted"); return Failure("Token not accepted");
} }

View file

@ -21,7 +21,7 @@ namespace BetterSecondBot.HttpService
[Route(HttpVerbs.Get, "/Friendslist/{token}")] [Route(HttpVerbs.Get, "/Friendslist/{token}")]
public object Friendslist(string token) public object Friendslist(string token)
{ {
if (tokens.Allow(token, "friends", "Friendslist", getClientIP()) == true) if (tokens.Allow(token, "friends", "Friendslist", handleGetClientIP()) == false)
{ {
return Failure("Token not accepted"); return Failure("Token not accepted");
} }
@ -39,7 +39,7 @@ namespace BetterSecondBot.HttpService
[Route(HttpVerbs.Get, "/FriendFullPerms/{avatar}/{state}/{token}")] [Route(HttpVerbs.Get, "/FriendFullPerms/{avatar}/{state}/{token}")]
public object FriendFullPerms(string avatar, string state, string token) public object FriendFullPerms(string avatar, string state, string token)
{ {
if (tokens.Allow(token, "friends", "FriendFullPerms", getClientIP()) == true) if (tokens.Allow(token, "friends", "FriendFullPerms", handleGetClientIP()) == false)
{ {
return Failure("Token not accepted"); return Failure("Token not accepted");
} }
@ -78,7 +78,7 @@ namespace BetterSecondBot.HttpService
[Route(HttpVerbs.Get, "/FriendRequest/{avatar}/{state}/{token}")] [Route(HttpVerbs.Get, "/FriendRequest/{avatar}/{state}/{token}")]
public object FriendRequest(string avatar, string state, string token) public object FriendRequest(string avatar, string state, string token)
{ {
if (tokens.Allow(token, "friends", "FriendRequest", getClientIP()) == true) if (tokens.Allow(token, "friends", "FriendRequest", handleGetClientIP()) == false)
{ {
return Failure("Token not accepted"); return Failure("Token not accepted");
} }

View file

@ -22,7 +22,7 @@ namespace BetterSecondBot.HttpService
[Route(HttpVerbs.Get, "/Balance/{token}")] [Route(HttpVerbs.Get, "/Balance/{token}")]
public object Balance(string token) public object Balance(string token)
{ {
if (tokens.Allow(token, "funds", "Balance", getClientIP()) == true) if (tokens.Allow(token, "funds", "Balance", handleGetClientIP()) == false)
{ {
return Failure("Token not accepted"); return Failure("Token not accepted");
} }
@ -42,7 +42,7 @@ namespace BetterSecondBot.HttpService
[Route(HttpVerbs.Get, "/PayAvatar/{avatar}/{amount}/{token}")] [Route(HttpVerbs.Get, "/PayAvatar/{avatar}/{amount}/{token}")]
public object PayAvatar(string avatar, string amount, string token) public object PayAvatar(string avatar, string amount, string token)
{ {
if (tokens.Allow(token, "funds", "PayAvatar", getClientIP()) == false) if (tokens.Allow(token, "funds", "PayAvatar", handleGetClientIP()) == false)
{ {
return BasicReply("Token not accepted"); return BasicReply("Token not accepted");
} }
@ -81,7 +81,7 @@ namespace BetterSecondBot.HttpService
[Route(HttpVerbs.Get, "/PayObject/{object}/{primname}/{amount}/{token}")] [Route(HttpVerbs.Get, "/PayObject/{object}/{primname}/{amount}/{token}")]
public object PayObject(string objectuuid,string primname,string amount,string token) public object PayObject(string objectuuid,string primname,string amount,string token)
{ {
if (tokens.Allow(token, "funds", "PayObject", getClientIP()) == true) if (tokens.Allow(token, "funds", "PayObject", handleGetClientIP()) == false)
{ {
return Failure("Token not accepted"); return Failure("Token not accepted");
} }

View file

@ -28,7 +28,7 @@ namespace BetterSecondBot.HttpService
[Route(HttpVerbs.Get, "/IsGroupMember/{group}/{avatar}/{token}")] [Route(HttpVerbs.Get, "/IsGroupMember/{group}/{avatar}/{token}")]
public object IsGroupMember(string group, string avatar, string token) public object IsGroupMember(string group, string avatar, string token)
{ {
if (tokens.Allow(token, "groups", "IsGroupMember", getClientIP()) == true) if (tokens.Allow(token, "groups", "IsGroupMember", handleGetClientIP()) == false)
{ {
return Failure("Token not accepted"); return Failure("Token not accepted");
} }
@ -64,7 +64,7 @@ namespace BetterSecondBot.HttpService
[Route(HttpVerbs.Get, "/GetGroupMembers/{group}/{token}")] [Route(HttpVerbs.Get, "/GetGroupMembers/{group}/{token}")]
public object GetGroupMembers(string group, string token) public object GetGroupMembers(string group, string token)
{ {
if (tokens.Allow(token, "groups", "GetGroupMembers", getClientIP()) == true) if (tokens.Allow(token, "groups", "GetGroupMembers", handleGetClientIP()) == false)
{ {
return Failure("Token not accepted"); return Failure("Token not accepted");
} }
@ -96,7 +96,7 @@ namespace BetterSecondBot.HttpService
[Route(HttpVerbs.Get, "/GroupEject/{group}/{avatar}/{token}")] [Route(HttpVerbs.Get, "/GroupEject/{group}/{avatar}/{token}")]
public object GroupEject(string group, string avatar, string token) public object GroupEject(string group, string avatar, string token)
{ {
if (tokens.Allow(token, "groups", "GroupEject", getClientIP()) == true) if (tokens.Allow(token, "groups", "GroupEject", handleGetClientIP()) == false)
{ {
return Failure("Token not accepted"); return Failure("Token not accepted");
} }
@ -141,7 +141,7 @@ namespace BetterSecondBot.HttpService
[Route(HttpVerbs.Get, "/GroupAddRole/{group}/{avatar}/{role}/{token}")] [Route(HttpVerbs.Get, "/GroupAddRole/{group}/{avatar}/{role}/{token}")]
public object GroupAddRole(string group, string avatar, string role, string token) public object GroupAddRole(string group, string avatar, string role, string token)
{ {
if (tokens.Allow(token, "groups", "GroupAddRole", getClientIP()) == true) if (tokens.Allow(token, "groups", "GroupAddRole", handleGetClientIP()) == false)
{ {
return Failure("Token not accepted"); return Failure("Token not accepted");
} }
@ -190,7 +190,7 @@ namespace BetterSecondBot.HttpService
[Route(HttpVerbs.Get, "/GroupInvite/{group}/{avatar}/{role}/{token}")] [Route(HttpVerbs.Get, "/GroupInvite/{group}/{avatar}/{role}/{token}")]
public object GroupInvite(string group, string avatar, string role, string token) public object GroupInvite(string group, string avatar, string role, string token)
{ {
if (tokens.Allow(token, "groups", "GroupInvite", getClientIP()) == true) if (tokens.Allow(token, "groups", "GroupInvite", handleGetClientIP()) == false)
{ {
return Failure("Token not accepted"); return Failure("Token not accepted");
} }
@ -241,7 +241,7 @@ namespace BetterSecondBot.HttpService
[Route(HttpVerbs.Post, "/Groupnotice/{group}/{token}")] [Route(HttpVerbs.Post, "/Groupnotice/{group}/{token}")]
public object Groupnotice(string group, [FormField] string title, [FormField] string message, string token) public object Groupnotice(string group, [FormField] string title, [FormField] string message, string token)
{ {
if (tokens.Allow(token, "groups", "Groupnotice", getClientIP()) == true) if (tokens.Allow(token, "groups", "Groupnotice", handleGetClientIP()) == false)
{ {
return Failure("Token not accepted"); return Failure("Token not accepted");
} }
@ -279,7 +279,7 @@ namespace BetterSecondBot.HttpService
[Route(HttpVerbs.Get, "/GroupActiveTitle/{group}/{token}")] [Route(HttpVerbs.Get, "/GroupActiveTitle/{group}/{token}")]
public object GroupActiveTitle(string group, string role, string token) public object GroupActiveTitle(string group, string role, string token)
{ {
if (tokens.Allow(token, "groups", "GroupActiveTitle", getClientIP()) == true) if (tokens.Allow(token, "groups", "GroupActiveTitle", handleGetClientIP()) == false)
{ {
return Failure("Token not accepted"); return Failure("Token not accepted");
} }
@ -307,7 +307,7 @@ namespace BetterSecondBot.HttpService
[Route(HttpVerbs.Get, "/GroupActiveGroup/{group}/{token}")] [Route(HttpVerbs.Get, "/GroupActiveGroup/{group}/{token}")]
public object GroupActiveGroup(string group, string role, string token) public object GroupActiveGroup(string group, string role, string token)
{ {
if (tokens.Allow(token, "groups", "GroupActiveTitle", getClientIP()) == true) if (tokens.Allow(token, "groups", "GroupActiveTitle", handleGetClientIP()) == false)
{ {
return Failure("Token not accepted"); return Failure("Token not accepted");
} }
@ -337,7 +337,7 @@ namespace BetterSecondBot.HttpService
[Route(HttpVerbs.Post, "/Groupnotice/{group}/{attachment}/{token}")] [Route(HttpVerbs.Post, "/Groupnotice/{group}/{attachment}/{token}")]
public object GroupnoticeWithAttachment(string group, [FormField] string title, [FormField] string message, string attachment, string token) public object GroupnoticeWithAttachment(string group, [FormField] string title, [FormField] string message, string attachment, string token)
{ {
if (tokens.Allow(token, "groups", "GroupnoticeWithAttachment", getClientIP()) == true) if (tokens.Allow(token, "groups", "GroupnoticeWithAttachment", handleGetClientIP()) == false)
{ {
return Failure("Token not accepted"); return Failure("Token not accepted");
} }
@ -376,7 +376,7 @@ namespace BetterSecondBot.HttpService
[Route(HttpVerbs.Get, "/GetGroupList/{token}")] [Route(HttpVerbs.Get, "/GetGroupList/{token}")]
public object GetGroupList(string token) public object GetGroupList(string token)
{ {
if (tokens.Allow(token, "groups", "GetGroupList", getClientIP()) == true) if (tokens.Allow(token, "groups", "GetGroupList", handleGetClientIP()) == false)
{ {
return Failure("Token not accepted"); return Failure("Token not accepted");
} }
@ -397,7 +397,7 @@ namespace BetterSecondBot.HttpService
[Route(HttpVerbs.Get, "/GetGroupRoles/{group}/{token}")] [Route(HttpVerbs.Get, "/GetGroupRoles/{group}/{token}")]
public object GetGroupRoles(string group, string token) public object GetGroupRoles(string group, string token)
{ {
if (tokens.Allow(token, "groups", "GetGroupRoles", getClientIP()) == true) if (tokens.Allow(token, "groups", "GetGroupRoles", handleGetClientIP()) == false)
{ {
return Failure("Token not accepted"); return Failure("Token not accepted");
} }
@ -446,7 +446,7 @@ namespace BetterSecondBot.HttpService
[Route(HttpVerbs.Get, "/GroupchatListAllUnreadGroups/{token}")] [Route(HttpVerbs.Get, "/GroupchatListAllUnreadGroups/{token}")]
public object GroupchatListAllUnreadGroups(string token) public object GroupchatListAllUnreadGroups(string token)
{ {
if (tokens.Allow(token, "groups", "GroupchatListAllUnreadGroups", getClientIP()) == true) if (tokens.Allow(token, "groups", "GroupchatListAllUnreadGroups", handleGetClientIP()) == false)
{ {
return Failure("Token not accepted"); return Failure("Token not accepted");
} }
@ -462,7 +462,7 @@ namespace BetterSecondBot.HttpService
[Route(HttpVerbs.Get, "/GroupchatGroupHasUnread/{group}/{token}")] [Route(HttpVerbs.Get, "/GroupchatGroupHasUnread/{group}/{token}")]
public object GroupchatGroupHasUnread(string group,string token) public object GroupchatGroupHasUnread(string group,string token)
{ {
if (tokens.Allow(token, "groups", "GroupchatListAllUnreadGroups", getClientIP()) == true) if (tokens.Allow(token, "groups", "GroupchatListAllUnreadGroups", handleGetClientIP()) == false)
{ {
return Failure("Token not accepted"); return Failure("Token not accepted");
} }
@ -484,11 +484,11 @@ namespace BetterSecondBot.HttpService
[Route(HttpVerbs.Get, "/GroupchatAnyUnread/{token}")] [Route(HttpVerbs.Get, "/GroupchatAnyUnread/{token}")]
public object haveunreadgroupchat(string token) public object haveunreadgroupchat(string token)
{ {
if (tokens.Allow(token, "groups", "GroupchatAnyUnread", getClientIP()) == true) if (tokens.Allow(token, "groups", "GroupchatAnyUnread", handleGetClientIP()) == false)
{ {
return BasicReply(bot.HasUnreadGroupchats().ToString()); return Failure("Token not accepted");
} }
return Failure("Token not accepted"); return BasicReply(bot.HasUnreadGroupchats().ToString());
} }
[About("Clears all group chat buffers at once")] [About("Clears all group chat buffers at once")]
@ -496,12 +496,12 @@ namespace BetterSecondBot.HttpService
[Route(HttpVerbs.Get, "/GroupchatClearAll/{token}")] [Route(HttpVerbs.Get, "/GroupchatClearAll/{token}")]
public object GroupchatClearAll(string token) public object GroupchatClearAll(string token)
{ {
if (tokens.Allow(token, "groups", "GroupchatClearAll", getClientIP()) == true) if (tokens.Allow(token, "groups", "GroupchatClearAll", handleGetClientIP()) == false)
{ {
bot.ClearAllGroupchat(); return Failure("Token not accepted");
return BasicReply("ok");
} }
return Failure("Token not accepted"); bot.ClearAllGroupchat();
return BasicReply("ok");
} }
[About("fetchs the groupchat history")] [About("fetchs the groupchat history")]
@ -511,15 +511,15 @@ namespace BetterSecondBot.HttpService
[Route(HttpVerbs.Get, "/GroupchatHistory/{group}/{token}")] [Route(HttpVerbs.Get, "/GroupchatHistory/{group}/{token}")]
public object GroupchatHistory(string group, string token) public object GroupchatHistory(string group, string token)
{ {
if (tokens.Allow(token, "groups", "GroupchatHistory", getClientIP()) == true) if (tokens.Allow(token, "groups", "GroupchatHistory", handleGetClientIP()) == false)
{
return Failure("Token not accepted");
}
if (UUID.TryParse(group, out UUID groupUUID) == false)
{ {
if (UUID.TryParse(group, out UUID groupUUID) == true)
{
return BasicReply(JsonConvert.SerializeObject(bot.GetGroupchat(groupUUID)));
}
return Failure("Group UUID invaild"); return Failure("Group UUID invaild");
} }
return Failure("Token not accepted"); return BasicReply(JsonConvert.SerializeObject(bot.GetGroupchat(groupUUID)));
} }
[About("sends a message to the groupchat")] [About("sends a message to the groupchat")]
@ -532,7 +532,7 @@ namespace BetterSecondBot.HttpService
[Route(HttpVerbs.Post, "/Groupchat/{group}/{token}")] [Route(HttpVerbs.Post, "/Groupchat/{group}/{token}")]
public object Groupchat(string group, [FormField] string message, string token) public object Groupchat(string group, [FormField] string message, string token)
{ {
if (tokens.Allow(token, "groups", "Groupchat", getClientIP()) == true) if (tokens.Allow(token, "groups", "Groupchat", handleGetClientIP()) == false)
{ {
return Failure("Token not accepted"); return Failure("Token not accepted");
} }

View file

@ -1,29 +0,0 @@
using System.Text;
using System.Threading;
using OpenMetaverse;
namespace BetterSecondBot.Commands.Helpers
{
public class Delay : CoreCommand_1arg
{
public override string[] ArgTypes { get { return new[] { "Number" }; } }
public override string[] ArgHints { get { return new[] { "Delay in MS" }; } }
public override string Helpfile { get { return "Delays a thead by X ms<br/>Mostly pointless but good if your doing custom commands"; } }
public override bool CallFunction(string[] args)
{
if (base.CallFunction(args) == true)
{
if (int.TryParse(args[0], out int delayms) == true)
{
Thread.Sleep(delayms);
return true;
}
else
{
return Failed("Delay is not vaild");
}
}
return false;
}
}
}

View file

@ -21,7 +21,7 @@ namespace BetterSecondBot.HttpService
[Route(HttpVerbs.Get, "/GoHome/{token}")] [Route(HttpVerbs.Get, "/GoHome/{token}")]
public object GoHome(string group, string token) public object GoHome(string group, string token)
{ {
if (tokens.Allow(token, "groups", "GetGroupMembers", getClientIP()) == true) if (tokens.Allow(token, "groups", "GetGroupMembers", handleGetClientIP()) == false)
{ {
return Failure("Token not accepted"); return Failure("Token not accepted");
} }

View file

@ -11,16 +11,16 @@ using Newtonsoft.Json;
namespace BetterSecondBot.HttpService namespace BetterSecondBot.HttpService
{ {
public class HttpApiIM : WebApiControllerWithTokens public class HTTP_IM : WebApiControllerWithTokens
{ {
public HttpApiIM(SecondBot mainbot, TokenStorage setuptokens) : base(mainbot, setuptokens) { } public HTTP_IM(SecondBot mainbot, TokenStorage setuptokens) : base(mainbot, setuptokens) { }
[About("gets a full list of all chat windows")] [About("gets a full list of all chat windows")]
[ReturnHints("array UUID = Name")] [ReturnHints("array UUID = Name")]
[Route(HttpVerbs.Get, "/chatwindows/{token}")] [Route(HttpVerbs.Get, "/chatwindows/{token}")]
public object chatwindows(string token) public object chatwindows(string token)
{ {
if (tokens.Allow(token, "im", "chatwindows", getClientIP()) == false) if (tokens.Allow(token, "im", "chatwindows", handleGetClientIP()) == false)
{ {
return BasicReply("Token not accepted"); return BasicReply("Token not accepted");
} }
@ -32,7 +32,7 @@ namespace BetterSecondBot.HttpService
[Route(HttpVerbs.Get, "/listwithunread/{token}")] [Route(HttpVerbs.Get, "/listwithunread/{token}")]
public object listwithunread(string group, string token) public object listwithunread(string group, string token)
{ {
if (tokens.Allow(token, "im", "listwithunread", getClientIP()) == false) if (tokens.Allow(token, "im", "listwithunread", handleGetClientIP()) == false)
{ {
return BasicReply("Token not accepted"); return BasicReply("Token not accepted");
} }
@ -52,7 +52,7 @@ namespace BetterSecondBot.HttpService
[Route(HttpVerbs.Get, "/haveunreadims/{token}")] [Route(HttpVerbs.Get, "/haveunreadims/{token}")]
public object haveunreadims(string token) public object haveunreadims(string token)
{ {
if (tokens.Allow(token, "im", "haveunreadims", getClientIP()) == false) if (tokens.Allow(token, "im", "haveunreadims", handleGetClientIP()) == false)
{ {
return BasicReply("Token not accepted"); return BasicReply("Token not accepted");
} }
@ -75,7 +75,7 @@ namespace BetterSecondBot.HttpService
[Route(HttpVerbs.Get, "/getimchat/{window}/{token}")] [Route(HttpVerbs.Get, "/getimchat/{window}/{token}")]
public object getimchat(string window, string token) public object getimchat(string window, string token)
{ {
if (tokens.Allow(token, "im", "getimchat", getClientIP()) == false) if (tokens.Allow(token, "im", "getimchat", handleGetClientIP()) == false)
{ {
return BasicReply("Token not accepted"); return BasicReply("Token not accepted");
} }

117
Core/Commands/Info.cs Normal file
View file

@ -0,0 +1,117 @@
using BetterSecondBot.bottypes;
using BetterSecondBot.Static;
using EmbedIO;
using EmbedIO.Routing;
using EmbedIO.WebApi;
using System;
using System.Collections.Generic;
using System.Text;
using OpenMetaverse;
using Newtonsoft.Json;
using BetterSecondBotShared.Static;
namespace BetterSecondBot.HttpService
{
public class HTTP_Info : WebApiControllerWithTokens
{
public HTTP_Info(SecondBot mainbot, TokenStorage setuptokens) : base(mainbot, setuptokens) { }
[About("Fetchs the current bot")]
[ReturnHints("The build ID of the bot")]
[Route(HttpVerbs.Get, "/Version/{token}")]
public object Version(string token)
{
if (tokens.Allow(token, "info", "Version", handleGetClientIP()) == false)
{
return Failure("Token not accepted");
}
return BasicReply(bot.MyVersion);
}
[About("Fetchs the name of the bot")]
[ReturnHints("Firstname Lastname")]
[Route(HttpVerbs.Get, "/Name/{token}")]
public object Name(string token)
{
if (tokens.Allow(token, "info", "Name", handleGetClientIP()) == false)
{
return Failure("Token not accepted");
}
return BasicReply(bot.GetClient.Self.FirstName + " " + bot.GetClient.Self.LastName);
}
[About("Fetchs the current parcels name")]
[ReturnHints("Parcelname")]
[ReturnHints("Error parcel not found")]
[ReturnHints("Error not in a sim")]
[Route(HttpVerbs.Get, "/ParcelName/{token}")]
public object ParcelName(string token)
{
if (tokens.Allow(token, "info", "ParcelName", handleGetClientIP()) == false)
{
return Failure("Token not accepted");
}
if (bot.GetClient.Network.CurrentSim == null)
{
return Failure("Error not in a sim");
}
int localid = bot.GetClient.Parcels.GetParcelLocalID(bot.GetClient.Network.CurrentSim, bot.GetClient.Self.SimPosition);
if (bot.GetClient.Network.CurrentSim.Parcels.ContainsKey(localid) == false)
{
return Failure("Error parcel not found");
}
return BasicReply(bot.GetClient.Network.CurrentSim.Parcels[localid].Name);
}
[About("Requests the current unixtime at the bot")]
[ReturnHints("Unixtime")]
[Route(HttpVerbs.Get, "/UnixTimeNow/{token}")]
public object UnixTimeNow(string token)
{
if (tokens.Allow(token, "info", "UnixTimeNow", handleGetClientIP()) == false)
{
return Failure("Token not accepted");
}
return BasicReply(helpers.UnixTimeNow().ToString());
}
[About("Fetchs the current region name")]
[ReturnHints("Regionname")]
[ReturnHints("Error not in a sim")]
[Route(HttpVerbs.Get, "/SimName/{token}")]
public object SimName(string token)
{
if (tokens.Allow(token, "info", "SimName", handleGetClientIP()) == false)
{
return Failure("Token not accepted");
}
if (bot.GetClient.Network.CurrentSim == null)
{
return Failure("Error not in a sim");
}
return BasicReply(bot.GetClient.Network.CurrentSim.Name);
}
[About("Fetchs the current location of the bot")]
[ReturnHints("array of X,Y,Z values")]
[ReturnHints("Error not in a sim")]
[Route(HttpVerbs.Get, "/GetPosition/{token}")]
public object GetPosition(string token)
{
if (tokens.Allow(token, "info", "GetPosition", handleGetClientIP()) == false)
{
return Failure("Token not accepted");
}
if (bot.GetClient.Network.CurrentSim == null)
{
return Failure("Error not in a sim");
}
Dictionary<string, int> pos = new Dictionary<string, int>();
pos.Add("x", (int)Math.Round(bot.GetClient.Self.SimPosition.X));
pos.Add("y", (int)Math.Round(bot.GetClient.Self.SimPosition.Y));
pos.Add("z", (int)Math.Round(bot.GetClient.Self.SimPosition.Z));
return BasicReply(JsonConvert.SerializeObject(pos));
}
}
}

441
Core/Commands/Inventory.cs Normal file
View file

@ -0,0 +1,441 @@
using BetterSecondBot.bottypes;
using BetterSecondBot.Static;
using EmbedIO;
using EmbedIO.Routing;
using EmbedIO.WebApi;
using System;
using System.Collections.Generic;
using System.Text;
using OpenMetaverse;
using System.Linq;
using BetterSecondBotShared.Static;
namespace BetterSecondBot.HttpService
{
public class HTTP_Inventory : WebApiControllerWithTokens
{
public HTTP_Inventory(SecondBot mainbot, TokenStorage setuptokens) : base(mainbot, setuptokens) { }
[About("rezs the item at the bots current location")]
[ReturnHints("True|False")]
[ArgHints("item", "URLARG", "UUID of item to rez")]
[Route(HttpVerbs.Get, "/RezObject/{item}/{token}")]
public object RezObject(string item, string token)
{
if (tokens.Allow(token, "inventory", "RezObject", handleGetClientIP()) == false)
{
return Failure("Token not accepted");
}
return Failure("Broken awaiting repairs");
}
[About("renames a folder or inventory item")]
[ReturnHints("ok")]
[ReturnHints("invaild item uuid")]
[ReturnHints("Item name is to short")]
[ReturnHints("Unable to find inventory item")]
[ArgHints("item", "URLARG", "UUID of item/folder to name")]
[ArgHints("newname", "Text", "What we are changing it to")]
[Route(HttpVerbs.Post, "/RenameInventory/{item}/{token}")]
public object RenameInventory(string item, string token, [FormField] string newname)
{
if (tokens.Allow(token, "inventory", "RenameInventory", handleGetClientIP()) == false)
{
return Failure("Token not accepted");
}
if (UUID.TryParse(item, out UUID target) == false)
{
return Failure("invaild item uuid");
}
if (newname.Length < 3)
{
return Failure("Item name is to short");
}
InventoryItem realitem = HelperInventory.getItemByInventoryUUID(bot, target);
if (realitem == null)
{
return Failure("Unable to find inventory item");
}
realitem.Name = newname;
bot.GetClient.Inventory.RequestUpdateItem(realitem);
return BasicReply("Ok");
}
[About("Attempts to Remove the given inventory item")]
[ReturnHints("ok")]
[ReturnHints("invaild item uuid")]
[ArgHints("item", "URLARG", "UUID of item")]
[Route(HttpVerbs.Get, "/DeleteInventoryItem/{item}/{token}")]
public object DeleteInventoryItem(string item, string token)
{
if (tokens.Allow(token, "inventory", "DeleteInventoryItem", handleGetClientIP()) == false)
{
return Failure("Token not accepted");
}
if (UUID.TryParse(item, out UUID target) == false)
{
return Failure("invaild item uuid");
}
bot.GetClient.Inventory.Remove(new List<UUID>() { target }, new List<UUID>());
return BasicReply("Ok");
}
[About("Attempts to Remove the given inventory folder")]
[ReturnHints("ok")]
[ReturnHints("invaild folder uuid")]
[ArgHints("folder", "URLARG", "UUID of folder")]
[Route(HttpVerbs.Get, "/DeleteInventoryFolder/{folder}/{token}")]
public object DeleteInventoryFolder(string folder, string token)
{
if (tokens.Allow(token, "inventory", "DeleteInventoryFolder", handleGetClientIP()) == false)
{
return Failure("Token not accepted");
}
if (UUID.TryParse(folder, out UUID target) == false)
{
return Failure("invaild folder uuid");
}
bot.GetClient.Inventory.Remove(new List<UUID>(), new List<UUID>() { target });
return BasicReply("Ok");
}
[About("Attempts to attach the given inventory item")]
[ReturnHints("ok")]
[ReturnHints("invaild item uuid")]
[ArgHints("item", "URLARG", "UUID of item")]
[Route(HttpVerbs.Get, "/Attach/{item}/{token}")]
public object Attach(string item, string token)
{
if (tokens.Allow(token, "inventory", "Attach", handleGetClientIP()) == false)
{
return Failure("Token not accepted");
}
if(UUID.TryParse(item,out UUID itemuuid) == false)
{
return Failure("invaild item uuid");
}
InventoryItem realitem = HelperInventory.getItemByInventoryUUID(bot, itemuuid);
bot.GetClient.Appearance.AddAttachments(new List<InventoryItem>() { realitem }, false, false);
return BasicReply("Ok");
}
[About("Attempts to Remove the given inventory folder")]
[ReturnHints("ok")]
[ReturnHints("invaild item uuid")]
[ArgHints("item", "URLARG", "UUID of item")]
[Route(HttpVerbs.Get, "/Detach/{item}/{token}")]
public object Detach(string item, string token)
{
if (tokens.Allow(token, "inventory", "Detach", handleGetClientIP()) == false)
{
return Failure("Token not accepted");
}
if (UUID.TryParse(item, out UUID itemuuid) == false)
{
return Failure("invaild item uuid");
}
InventoryItem realitem = HelperInventory.getItemByInventoryUUID(bot, itemuuid);
bot.GetClient.Appearance.RemoveFromOutfit(realitem);
return BasicReply("Ok");
}
[About("Replaces the current avatar outfit with the Clothing/[NAME] folder<br/>Please note: This does not use the outfits folder!<br/>Please do not use links in the folder!")]
[ReturnHints("ok")]
[ReturnHints("Named folder value is empty")]
[ReturnHints("Cant find Clothing folder")]
[ReturnHints("Cant find target folder")]
[ReturnHints("target folder is empty or so full I cant get it in 5 secs...")]
[ArgHints("name", "URLARG", "Name of the folder")]
[Route(HttpVerbs.Get, "/Outfit/{name}/{token}")]
public object Outfit(string name, string token)
{
if (tokens.Allow(token, "inventory", "Outfit", handleGetClientIP()) == false)
{
return Failure("Token not accepted");
}
if (helpers.notempty(name) == false)
{
return Failure("Named folder value is empty");
}
// 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)
{
return Failure("Cant find Clothing folder");
}
T = bot.GetClient.Inventory.Store.GetContents(AA);
AA = null;
foreach (InventoryBase R in T)
{
if (R.Name == name)
{
AA = (InventoryFolder)R;
break;
}
}
if (AA == null)
{
return Failure("Cant find target folder");
}
List<InventoryBase> contents = bot.GetClient.Inventory.FolderContents(AA.UUID, bot.GetClient.Self.AgentID, true, true, InventorySortOrder.ByName, 5 * 1000);
List<InventoryItem> wareables = new List<InventoryItem>();
if (contents == null)
{
return Failure("target folder is empty or so full I cant get it in 5 secs...");
}
foreach (InventoryBase item in contents)
{
if ((item is InventoryWearable) || (item is InventoryObject))
{
wareables.Add((InventoryItem)item);
}
}
bot.GetClient.Appearance.ReplaceOutfit(wareables, false);
return BasicReply("ok");
}
[About("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!")]
[ReturnHints("ok")]
[ReturnHints("Unable to find notecard folder")]
[Route(HttpVerbs.Get, "/InventoryPurgeNotecards/{token}")]
public object InventoryPurgeNotecards(string token)
{
if (tokens.Allow(token, "inventory", "InventoryPurgeNotecards", handleGetClientIP()) == false)
{
return Failure("Token not accepted");
}
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)
{
return Failure("Unable to find notecard folder");
}
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 BasicReply("Ok");
}
[About("converts a inventory uuid to a realworld uuid<br/>Needed for texture preview")]
[ReturnHints("Asset UUID or UUID zero")]
[ReturnHints("Invaild item uuid")]
[ArgHints("item", "URLARG", "inventory level UUID of item")]
[Route(HttpVerbs.Get, "/getRealUUID/{item}/{token}")]
public object getRealUUID(string item, string token)
{
if (tokens.Allow(token, "inventory", "getRealUUID", handleGetClientIP()) == false)
{
return Failure("Token not accepted");
}
if (UUID.TryParse(item, out UUID itemUUID) == false)
{
return Failure("Invaild item uuid");
}
UUID reply = HelperInventory.GetAssetUUID(bot, itemUUID);
return BasicReply(reply.ToString());
}
[About("sends a item to an avatar")]
[ReturnHints("ok")]
[ReturnHints("Failed")]
[ReturnHints("Invaild avatar uuid")]
[ReturnHints("Invaild item uuid")]
[ReturnHints("Unable to find item")]
[ArgHints("item", "URLARG", "UUID of item")]
[ArgHints("avatar", "URLARG", "a UUID or Firstname Lastname")]
[Route(HttpVerbs.Get, "/SendItem/{item}/{avatar}/{token}")]
public object SendItem(string item, string avatar, string token)
{
if (tokens.Allow(token, "inventory", "SendItem", handleGetClientIP()) == false)
{
return Failure("Token not accepted");
}
ProcessAvatar(avatar);
if(avataruuid == UUID.Zero)
{
return Failure("Invaild avatar uuid");
}
if (UUID.TryParse(item, out UUID targetitem) == true)
{
return Failure("Invaild item uuid");
}
InventoryItem itm = bot.GetClient.Inventory.FetchItem(targetitem, bot.GetClient.Self.AgentID, (3 * 1000));
if (itm == null)
{
return Failure("Unable to find item");
}
bot.GetClient.Inventory.GiveItem(itm.UUID, itm.Name, itm.AssetType, avataruuid, false);
return BasicReply("ok");
}
[About("Sends a folder to an avatar")]
[ReturnHints("ok")]
[ReturnHints("Failed")]
[ReturnHints("Invaild avatar uuid")]
[ReturnHints("Invaild folter uuid")]
[ReturnHints("Unable to find folder")]
[ArgHints("item", "URLARG", "UUID of item")]
[ArgHints("avatar", "URLARG", "a UUID or Firstname Lastname")]
[Route(HttpVerbs.Get, "/SendFolder/{folder}/{avatar}/{token}")]
public object SendFolder(string folder, string avatar, string token)
{
if (tokens.Allow(token, "inventory", "SendFolder", handleGetClientIP()) == false)
{
return Failure("Token not accepted");
}
ProcessAvatar(avatar);
if (avataruuid == UUID.Zero)
{
return Failure("Invaild avatar uuid");
}
if (UUID.TryParse(folder, out UUID targetfolder) == true)
{
return Failure("Invaild folder uuid");
}
InventoryBase FindFolderHelper = HelperInventory.FindFolder(bot, bot.GetClient.Inventory.Store.RootFolder, targetfolder);
if (FindFolderHelper == null)
{
return Failure("Unable to find folder");
}
bot.GetClient.Inventory.GiveFolder(FindFolderHelper.UUID, FindFolderHelper.Name, avataruuid, false);
return BasicReply("ok");
}
[About("Transfers a item [ARG 2] to a objects inventory [ARG 1] (And if set with the script running state [ARG 3])")]
[ReturnHints("Transfering running script")]
[ReturnHints("Transfering inventory")]
[ReturnHints("Invaild item uuid")]
[ReturnHints("Invaild object uuid")]
[ReturnHints("Unable to find inventory")]
[ReturnHints("Unable to find object")]
[ReturnHints("Invaild running")]
[ArgHints("item", "URLARG", "UUID of item")]
[ArgHints("object", "URLARG", "the uuid of the object")]
[ArgHints("running", "URLARG", "true if you wish the transfered script to be running otherwise false")]
[Route(HttpVerbs.Get, "/TransferInventoryToObject/{item}/{objectuuid}/{running}/{token}")]
public object TransferInventoryToObject(string item, string objectuuid, string running, string token)
{
if (tokens.Allow(token, "inventory", "TransferInventoryToObject", handleGetClientIP()) == false)
{
return Failure("Token not accepted");
}
if (UUID.TryParse(item, out UUID itemuuid) == false)
{
return Failure("Invaild item uuid");
}
if (UUID.TryParse(objectuuid, out UUID objectUUID) == false)
{
return Failure("Invaild object uuid");
}
if (bool.TryParse(running, out bool runscript) == false)
{
return Failure("Invaild running");
}
InventoryItem itm = bot.GetClient.Inventory.FetchItem(itemuuid, bot.GetClient.Self.AgentID, (3 * 1000));
if (itm == null)
{
return Failure("Unable to find inventory");
}
Dictionary<uint, Primitive> objects_copy = bot.GetClient.Network.CurrentSim.ObjectsPrimitives.Copy();
KeyValuePair<uint, Primitive> RealObject = new KeyValuePair<uint, Primitive>(0,null);
foreach (KeyValuePair<uint, Primitive> Obj in objects_copy)
{
if (Obj.Value.ID == objectUUID)
{
RealObject = Obj;
break;
}
}
if (RealObject.Value == null)
{
return Failure("Unable to find object");
}
bool scriptState = runscript;
if (itm.AssetType != AssetType.LSLText)
{
scriptState = false;
}
if (itm.AssetType == AssetType.LSLText)
{
bot.GetClient.Inventory.CopyScriptToTask(RealObject.Key, itm, scriptState);
return BasicReply("Transfering script [state: "+scriptState.ToString()+"]");
}
bot.GetClient.Inventory.UpdateTaskInventory(RealObject.Key, itm);
return BasicReply("Transfering inventory");
}
[About("Requests the inventory folder layout as a json object InventoryMapFolder<br/>Formated as follows<br/>InventoryMapItem<br/><ul><li>id: UUID</li><li>name: String</li><li>subfolders: InventoryMapFolder[]</li></ul>")]
[ReturnHints("array of InventoryMapFolder")]
[ReturnHints("Error")]
[Route(HttpVerbs.Get, "/InventoryFolders/{token}")]
public object InventoryFolders(string token)
{
if (tokens.Allow(token, "inventory", "InventoryFolders", handleGetClientIP()) == false)
{
return Failure("Token not accepted");
}
string reply = HelperInventory.MapFolderJson(bot);
if (reply != null) return BasicReply(reply);
return Failure("Error");
}
[About("Requests the contents of a folder as an array of InventoryMapItem<br/>Formated as follows<br/>InventoryMapItem<br/><ul><li>id: UUID</li><li>name: String</li><li>typename: String</li></ul>")]
[ReturnHints("array of InventoryMapItem")]
[ReturnHints("Invaild folder UUID")]
[ArgHints("folderUUID", "URLARG", "the folder to fetch (Found via: inventory/folders)")]
[Route(HttpVerbs.Get, "/InventoryContents/{folderUUID}/{token}")]
public object InventoryContents(string folderUUID, string token)
{
if (tokens.Allow(token, "inventory", "InventoryContents", handleGetClientIP()) == false)
{
return Failure("Token not accepted");
}
if (UUID.TryParse(folderUUID, out UUID folder) == false)
{
return Failure("Invaild folder UUID");
}
return BasicReply(HelperInventory.MapFolderInventoryJson(bot, folder));
}
}
}

View file

@ -1,47 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using OpenMetaverse;
namespace BetterSecondBot.Commands.Inventory
{
public class DeleteInventoryItem : CoreCommand_1arg
{
public override string[] ArgTypes { get { return new[] { "UUID" }; } }
public override string[] ArgHints { get { return new[] { "inventory UUID" }; } }
public override string Helpfile { get { return "Attempts to Remove the given inventory item"; } }
public override bool CallFunction(string[] args)
{
if (base.CallFunction(args) == true)
{
if (UUID.TryParse(args[0], out UUID removeme) == true)
{
bot.GetClient.Inventory.Remove(new List<UUID>() { removeme }, new List<UUID>());
return true;
}
return Failed("Invaild inventory UUID");
}
return false;
}
}
public class DeleteInventoryFolder : CoreCommand_1arg
{
public override string[] ArgTypes { get { return new[] { "UUID" }; } }
public override string[] ArgHints { get { return new[] { "inventory UUID" }; } }
public override string Helpfile { get { return "Attempts to Remove the given inventory folder"; } }
public override bool CallFunction(string[] args)
{
if (base.CallFunction(args) == true)
{
if (UUID.TryParse(args[0], out UUID removeme) == true)
{
bot.GetClient.Inventory.Remove(new List<UUID>(), new List<UUID>() { removeme });
return true;
}
return Failed("Invaild inventory UUID");
}
return false;
}
}
}

View file

@ -1,55 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using OpenMetaverse;
namespace BetterSecondBot.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 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)
{
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;
}
}
}

View file

@ -1,41 +0,0 @@
using BetterSecondBot.Static;
using OpenMetaverse;
namespace BetterSecondBot.Commands.Inventory
{
public class RenameInventory : CoreCommand_3arg
{
public override string[] ArgTypes { get { return new[] { "Smart", "UUID", "Text" }; } }
public override string[] ArgHints { get { return new[] { "Smart reply target: Channel,Avatar,HTTP", "Inventory UUID", "New name" }; } }
public override string Helpfile
{
get
{
return "Renames an inventory item to something else.";
}
}
public override bool CallFunction(string[] args)
{
if (base.CallFunction(args) == true)
{
if (UUID.TryParse(args[1], out UUID target) == true)
{
if (args[2].Length >= 1)
{
InventoryItem item = HelperInventory.getItemByInventoryUUID(bot, target);
if (item != null)
{
item.Name = args[2];
bot.GetClient.Inventory.RequestUpdateItem(item);
return true;
}
return Failed("Unable to get base item");
}
return Failed("Item name is to short");
}
return Failed("Unable to get UUID from target");
}
return false;
}
}
}

View file

@ -1,80 +0,0 @@
using System.Collections.Generic;
using System.Linq;
using OpenMetaverse;
namespace BetterSecondBot.Commands.Inventory
{
public class Attach : CoreCommand_2arg
{
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 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;
}
}
}

View file

@ -1,35 +0,0 @@
using BetterSecondBot.Static;
using OpenMetaverse;
namespace BetterSecondBot.Commands.Inventory
{
public class getRealUUID : CoreCommand_2arg
{
public override string[] ArgTypes { get { return new[] { "Smart", "UUID" }; } }
public override string[] ArgHints { get { return new[] { "Smart reply target: Channel,Avatar,HTTP", "Inventory UUID" }; } }
public override string Helpfile
{
get
{
return "Converts a Inventory UUID into an asset UUID used to send? im not sure yet";
}
}
public override bool CallFunction(string[] args)
{
if (base.CallFunction(args) == true)
{
if(UUID.TryParse(args[1],out UUID target) == true)
{
UUID reply = HelperInventory.GetAssetUUID(bot, target);
if(reply != UUID.Zero)
{
return bot.GetCommandsInterface.SmartCommandReply(true, args[0], reply.ToString(), CommandName);
}
return bot.GetCommandsInterface.SmartCommandReply(false, args[0], "Unable to fetch asset UUID", CommandName);
}
return bot.GetCommandsInterface.SmartCommandReply(false, args[0], "Unable to process target UUID", CommandName);
}
return false;
}
}
}

View file

@ -1,52 +0,0 @@
using System;
using OpenMetaverse;
using BetterSecondBot.Static;
using BetterSecondBotShared.Static;
using System.Collections.Generic;
namespace BetterSecondBot.Commands.Inventory
{
public class InventoryContents : CoreCommand_2arg
{
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 bool CallFunction(string[] args)
{
if (base.CallFunction(args) == true)
{
if (UUID.TryParse(args[1], out UUID targetfolder) == true)
{
if (UUID.TryParse(args[0], out UUID targetavatar) == true)
{
KeyValuePair<string,string> content = HelperInventory.MapFolderInventoryHumanReadable(bot, targetfolder);
if (content.Value != null)
{
string notecardname = ""+content.Key+" Contents @" + helpers.UnixTimeNow().ToString() + "";
bot.SendNotecard(notecardname, content.Value, targetavatar);
}
else
{
bot.GetClient.Self.InstantMessage(targetavatar, "Unable to load folder or it is empty");
}
return true;
}
else
{
return bot.GetCommandsInterface.SmartCommandReply(true, args[0], HelperInventory.MapFolderInventoryJson(bot,targetfolder), CommandName);
}
}
else
{
return Failed("Invaild folder UUID");
}
}
return false;
}
}
}

View file

@ -1,36 +0,0 @@
using OpenMetaverse;
using BetterSecondBot.Static;
namespace BetterSecondBot.Commands.Inventory
{
public class InventoryFolders : CoreCommand_1arg
{
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 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.MapFolderHumanReadable(bot);
bot.SendNotecard("Inventory Folders", reply, targetavatar);
return true;
}
else
{
string reply = HelperInventory.MapFolderJson(bot);
return bot.GetCommandsInterface.SmartCommandReply(true,args[0], reply, CommandName);
}
}
return false;
}
}
}

View file

@ -1,74 +0,0 @@
using System.Collections.Generic;
using OpenMetaverse;
namespace BetterSecondBot.Commands.Inventory
{
public class Outfit : CoreCommand_1arg
{
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 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;
}
}
}

View file

@ -1,43 +0,0 @@
using BetterSecondBot.Static;
using OpenMetaverse;
namespace BetterSecondBot.Commands.Inventory
{
public class SendFolder : CoreCommand_2arg
{
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 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;
}
}
}

View file

@ -1,47 +0,0 @@
using OpenMetaverse;
namespace BetterSecondBot.Commands.Inventory
{
public class SendItem : CoreCommand_2arg
{
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 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.UUID, 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;
}
}
}

304
Core/Commands/Movement.cs Normal file
View file

@ -0,0 +1,304 @@
using BetterSecondBot.bottypes;
using BetterSecondBot.Static;
using EmbedIO;
using EmbedIO.Routing;
using EmbedIO.WebApi;
using System;
using System.Collections.Generic;
using System.Text;
using OpenMetaverse;
using Newtonsoft.Json;
using System.Reflection;
using System.Threading;
using BetterSecondBotShared.Static;
namespace BetterSecondBot.HttpService
{
public class HTTP_Movement : WebApiControllerWithTokens
{
public HTTP_Movement(SecondBot mainbot, TokenStorage setuptokens) : base(mainbot, setuptokens) { }
[About("uses the AutoPilot to move to a location")]
[ReturnHints("Error Unable to AutoPilot to location")]
[ReturnHints("Accepted")]
[ReturnHints("Convert to vector has failed")]
[ReturnHints("? value out of range 0-?")]
[ArgHints("x", "URLARG", "X location to AutoPilot to")]
[ArgHints("y", "URLARG", "y location to AutoPilot to")]
[ArgHints("z", "URLARG", "z location to AutoPilot to")]
[Route(HttpVerbs.Get, "/AutoPilot/{x}/{y}/{z}/{token}")]
public object AutoPilot(string x, string y, string z, string token)
{
if (tokens.Allow(token, "movement", "AutoPilot", handleGetClientIP()) == false)
{
return Failure("Token not accepted");
}
if (Vector3.TryParse("<" + x + "," + y + "," + z + ">", out Vector3 pos) == false)
{
return Failure("Convert to vector has failed");
}
if (helpers.inrange(pos.X, 0, 255) == false)
{
return Failure("x value out of range 0-255");
}
if (helpers.inrange(pos.Y, 0, 255) == false)
{
return Failure("y value out of range 0-255");
}
if (helpers.inrange(pos.Z, 0, 5000) == false)
{
return Failure("z value out of range 0-5000");
}
bot.GetClient.Self.AutoPilotCancel();
bot.GetClient.Self.Movement.TurnToward(pos, true);
Thread.Sleep(500);
uint Globalx, Globaly;
Utils.LongToUInts(bot.GetClient.Network.CurrentSim.Handle, out Globalx, out Globaly);
bot.GetClient.Self.AutoPilot((ulong)(Globalx + pos.X), (ulong)(Globaly + pos.Y), pos.Z);
return true;
}
[About("Attempt to teleport to a new region")]
[ReturnHints("ok")]
[Route(HttpVerbs.Get, "/AutoPilotStop/{token}")]
public object AutoPilotStop(string token)
{
if (tokens.Allow(token, "movement", "AutoPilotStop", handleGetClientIP()) == false)
{
return Failure("Token not accepted");
}
bot.GetClient.Self.AutoPilotCancel();
return BasicReply("ok");
}
[About("Make the bot request the target avatar teleport to the bot")]
[ReturnHints("ok")]
[ReturnHints("Invaild avatar UUID")]
[ArgHints("avatar", "URLARG", "Avatar UUID or Firstname Lastname")]
[Route(HttpVerbs.Get, "/SendTeleportLure/{avatar}/{token}")]
public object SendTeleportLure(string avatar,string token)
{
if (tokens.Allow(token, "movement", "SendTeleportLure", handleGetClientIP()) == false)
{
return Failure("Token not accepted");
}
ProcessAvatar(avatar);
if(avataruuid == UUID.Zero)
{
return Failure("Invaild avatar UUID");
}
bot.GetClient.Self.SendTeleportLure(avataruuid);
return BasicReply("ok");
}
[About("Sends a teleport request (Move the bot to the avatar)")]
[ReturnHints("ok")]
[ReturnHints("Invaild avatar UUID")]
[ArgHints("avatar", "URLARG", "Avatar UUID or Firstname Lastname")]
[Route(HttpVerbs.Get, "/RequestTeleport/{avatar}/{token}")]
public object RequestTeleport(string avatar, string token)
{
if (tokens.Allow(token, "movement", "RequestTeleport", handleGetClientIP()) == false)
{
return Failure("Token not accepted");
}
ProcessAvatar(avatar);
if (avataruuid == UUID.Zero)
{
return Failure("Invaild avatar UUID");
}
bot.Add_action_from("teleport", avataruuid);
bot.GetClient.Self.SendTeleportLureRequest(avataruuid, "I would like to teleport to you");
return BasicReply("ok");
}
[About("Makes the bot fly (or not)")]
[ReturnHints("ok")]
[ReturnHints("Invaild mode")]
[ArgHints("mode", "URLARG", "true: Start flying, false: stop flying (super fun at height)")]
[Route(HttpVerbs.Get, "/Fly/{mode}/{token}")]
public object Fly(string mode, string token)
{
if (tokens.Allow(token, "movement", "Fly", handleGetClientIP()) == false)
{
return Failure("Token not accepted");
}
if (bool.TryParse(mode, out bool flymode) == false)
{
return Failure("Invaild mode");
}
bot.GetClient.Self.Movement.Fly = flymode;
bot.GetClient.Self.Movement.SendUpdate();
return BasicReply("ok");
}
[About("Rotates the bot to face a vector from its current location")]
[ReturnHints("true|false")]
[ReturnHints("Invaild vector")]
[ReturnHints("Vector ? value is out of range 0-?")]
[ArgHints("vector", "Text", "a vector to face eg <123,45,44>")]
[Route(HttpVerbs.Post, "/RotateToFaceVector/{token}")]
public object RotateToFaceVector([FormField] string vector, string token)
{
if (tokens.Allow(token, "movement", "RotateToFaceVector", handleGetClientIP()) == false)
{
return Failure("Token not accepted");
}
if (Vector3.TryParse(vector, out Vector3 pos) == false)
{
return Failure("Invaild vector");
}
if (helpers.inrange(pos.X, 0, 255) == false)
{
return Failure("Vector x value is out of range 0-255");
}
if (helpers.inrange(pos.Y, 0, 255) == false)
{
return Failure("Vector y value is out of range 0-255");
}
if (helpers.inrange(pos.Z, 0, 5000) == false)
{
return Failure("Vector z value is out of range 0-5000");
}
return BasicReply(bot.GetClient.Self.Movement.TurnToward(pos, true).ToString());
}
[About("Rotates the bot to face a avatar")]
[ReturnHints("true|false")]
[ReturnHints("Invaild avatar UUID")]
[ReturnHints("Unable to see avatar")]
[ArgHints("avatar", "URLARG", "An avatar UUID or Firstname Lastname")]
[Route(HttpVerbs.Post, "/RotateToFace/{avatar}/{token}")]
public object RotateToFace(string avatar, string token)
{
if (tokens.Allow(token, "movement", "RotateToFace", handleGetClientIP()) == false)
{
return Failure("Token not accepted");
}
ProcessAvatar(avatar);
if(avataruuid == UUID.Zero)
{
return Failure("Invaild avatar UUID");
}
if (bot.GetClient.Network.CurrentSim.AvatarPositions.ContainsKey(avataruuid) == false)
{
return Failure("Unable to see avatar");
}
return BasicReply(bot.GetClient.Self.Movement.TurnToward(bot.GetClient.Network.CurrentSim.AvatarPositions[avataruuid], true).ToString());
}
[About("Rotates the avatar to face a rotation from north in Degrees")]
[ReturnHints("ok")]
[ReturnHints("Unable to process rotation")]
[ArgHints("deg", "URLARG", "0 to 360")]
[Route(HttpVerbs.Post, "/RotateTo/{deg}/{token}")]
public object RotateTo(string deg, string token)
{
if (tokens.Allow(token, "movement", "RotateTo", handleGetClientIP()) == false)
{
return Failure("Token not accepted");
}
if (float.TryParse(deg, out float target_yaw) == true)
{
return Failure("Unable to process rotation");
}
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 BasicReply("ok");
}
[About("Attempt to teleport to a new region")]
[ReturnHints("Error Unable to Teleport to location")]
[ReturnHints("Accepted")]
[ArgHints("region", "URLARG", "the name of the region we are going to")]
[ArgHints("x", "URLARG", "X location to teleport to")]
[ArgHints("y", "URLARG", "y location to teleport to")]
[ArgHints("z", "URLARG", "z location to teleport to")]
[Route(HttpVerbs.Get, "/Teleport/{region}/{x}/{y}/{z}/{token}")]
public object Teleport(string region, string x, string y, string z, string token)
{
if (tokens.Allow(token, "movement", "Teleport", handleGetClientIP()) == false)
{
return Failure("Token not accepted");
}
bool status = TeleportRequest(new string[] { region, x, y, z });
if (status == false)
{
return Failure("Error Unable to Teleport to location");
}
return BasicReply("Accepted");
}
protected bool TeleportRequest(string[] args)
{
bot.GetClient.Self.AutoPilotCancel();
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 false;
}
}
}
}
}

View file

@ -1,13 +0,0 @@
namespace BetterSecondBot.Commands.Movement
{
public class AutoPilotStop : CoreCommand
{
public override string Helpfile { get { return "Stops any current AutoPilot"; } }
public override bool CallFunction(string[] args)
{
bot.GetClient.Self.AutoPilotCancel();
return true;
}
}
}

View file

@ -1,35 +0,0 @@
using System.Threading;
namespace BetterSecondBot.Commands.Movement
{
public class BotFly : CoreCommand_1arg
{
public override string[] ArgTypes { get { return new[] { "True|False" }; } }
public override string[] ArgHints { get { return new[] { "Should the bot be flying" }; } }
public override string Helpfile { get { return "Makes the bot fly (or not)"; } }
public override bool CallFunction(string[] args)
{
if (base.CallFunction(args) == true)
{
if (bool.TryParse(args[0], out bool status) == true)
{
if(status == false)
{
bot.GetClient.Self.Movement.Fly = true;
bot.GetClient.Self.Movement.SendUpdate();
Thread.Sleep(200);
}
bot.GetClient.Self.Movement.Fly = status;
bot.GetClient.Self.Movement.SendUpdate();
return true;
}
else
{
return Failed("Unable to process rotation");
}
}
return false;
}
}
}

View file

@ -1,26 +0,0 @@
using OpenMetaverse;
namespace BetterSecondBot.Commands.Movement
{
public class RequestTeleport : CoreCommand_1arg
{
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 "Sends a teleport lure request (Move the bot to the avatar)"; } }
public override bool CallFunction(string[] args)
{
if(base.CallFunction(args) == true)
{
if(UUID.TryParse(args[0],out UUID avatar) == true)
{
bot.Add_action_from("teleport", avatar);
bot.GetClient.Self.SendTeleportLureRequest(avatar, "I would like to teleport to you");
return true;
}
return Failed("Unable to process avatar on arg 1");
}
return false;
}
}
}

View file

@ -1,28 +0,0 @@
using System;
using OpenMetaverse;
namespace BetterSecondBot.Commands.Movement
{
public class RotateToFace : CoreCommand_1arg
{
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 "Rotates the bot to face an avatar"; } }
public override bool CallFunction(string[] args)
{
if (base.CallFunction(args) == true)
{
if(UUID.TryParse(args[0],out UUID avatar) == true)
{
if (bot.GetClient.Network.CurrentSim.AvatarPositions.ContainsKey(avatar) == true)
{
return bot.GetClient.Self.Movement.TurnToward(bot.GetClient.Network.CurrentSim.AvatarPositions[avatar], true);
}
Failed("Unable to find avatar in local sim memory");
}
return Failed("Unable to process avatar on arg 1");
}
return false;
}
}
}

View file

@ -1,37 +0,0 @@
using System;
using BetterSecondBotShared.Static;
using OpenMetaverse;
namespace BetterSecondBot.Commands.Movement
{
public class RotateToFaceVector : CoreCommand_1arg
{
public override string[] ArgTypes { get { return new[] { "Vector" }; } }
public override string[] ArgHints { get { return new[] { "The location to face Example: <25,123,33>" }; } }
public override string Helpfile { get { return "Rotates the bot to face a vector from its current location"; } }
public override bool CallFunction(string[] args)
{
if (base.CallFunction(args) == true)
{
if(Vector3.TryParse(args[0],out Vector3 pos) == true)
{
if (helpers.inrange(pos.X, 0, 255) == true)
{
if (helpers.inrange(pos.Y, 0, 255) == true)
{
if (helpers.inrange(pos.Z, 0, 5000) == true)
{
return bot.GetClient.Self.Movement.TurnToward(pos, true);
}
return Failed("Arg 1 - Vector Z is out of range");
}
return Failed("Arg 2 - Vector Y is out of range");
}
return Failed("Arg 1 - Vector X is out of range");
}
return Failed("Unable to process vector on arg 1");
}
return false;
}
}
}

View file

@ -1,25 +0,0 @@
using OpenMetaverse;
namespace BetterSecondBot.Commands.Movement
{
public class SendTeleportLure : CoreCommand_1arg
{
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 "Make the bot request the target avatar teleport to the bot"; } }
public override bool CallFunction(string[] args)
{
if(base.CallFunction(args) == true)
{
if(UUID.TryParse(args[0],out UUID avatar) == true)
{
bot.GetClient.Self.SendTeleportLure(avatar);
return true;
}
return Failed("Unable to process avatar on arg 1");
}
return false;
}
}
}

View file

@ -1,48 +0,0 @@
using System;
using OpenMetaverse;
namespace BetterSecondBot.Commands.Movement
{
public class RotateTo : CoreCommand_1arg
{
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 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;
}
}
}

97
Core/Commands/Notecard.cs Normal file
View file

@ -0,0 +1,97 @@
using BetterSecondBot.bottypes;
using BetterSecondBot.Static;
using EmbedIO;
using EmbedIO.Routing;
using EmbedIO.WebApi;
using System;
using System.Collections.Generic;
using System.Text;
using OpenMetaverse;
using Newtonsoft.Json;
using System.Reflection;
using BetterSecondBotShared.Static;
namespace BetterSecondBot.HttpService
{
public class HTTP_Notecard : WebApiControllerWithTokens
{
public HTTP_Notecard(SecondBot mainbot, TokenStorage setuptokens) : base(mainbot, setuptokens) { }
[About("Adds content to the Collection<br/> Also creates the Collection if it does not exist")]
[ReturnHints("Collection value is empty")]
[ReturnHints("Content value is empty")]
[ReturnHints("ok")]
[Route(HttpVerbs.Post, "/NotecardAdd/{collection}/{token}")]
public object NotecardAdd(string collection, [FormField] string content, string token)
{
if (tokens.Allow(token, "notecard", "NotecardAdd", handleGetClientIP()) == false)
{
return Failure("Token not accepted");
}
if (helpers.notempty(collection) == false)
{
return Failure("Collection value is empty");
}
if (helpers.notempty(content) == false)
{
return Failure("Content value is empty");
}
bot.NotecardAddContent(collection, content);
return BasicReply("ok");
}
[About("Adds content to the Collection<br/> Also creates the Collection if it does not exist")]
[ReturnHints("Collection value is empty")]
[ReturnHints("ok")]
[Route(HttpVerbs.Get, "/NotecardClear/{collection}/{token}")]
public object NotecardClear(string collection, string token)
{
if (tokens.Allow(token, "notecard", "NotecardClear", handleGetClientIP()) == false)
{
return Failure("Token not accepted");
}
if (helpers.notempty(collection) == false)
{
return Failure("Collection value is empty");
}
bot.ClearNotecardStorage(collection);
return BasicReply("ok");
}
[About("Adds content to the Collection<br/> Also creates the Collection if it does not exist")]
[ReturnHints("True|False")]
[ReturnHints("Collection value is empty")]
[ReturnHints("Notecardname value is empty")]
[ReturnHints("Invaild avatar uuid")]
[ReturnHints("No content in notecard storage ?")]
[ReturnHints("ok")]
[Route(HttpVerbs.Get, "/NotecardSend/{avatar}/{collection}/{notecardname}/{token}")]
public object NotecardSend(string avatar, string collection, string notecardname, string token)
{
if (tokens.Allow(token, "notecard", "NotecardSend", handleGetClientIP()) == false)
{
return Failure("Token not accepted");
}
if (helpers.notempty(collection) == false)
{
return Failure("Collection value is empty");
}
if (helpers.notempty(notecardname) == false)
{
return Failure("Notecardname value is empty");
}
ProcessAvatar(avatar);
if(avataruuid == UUID.Zero)
{
return Failure("Invaild avatar uuid");
}
string content = bot.GetNotecardContent(collection);
if (content == null)
{
return Failure("No content in notecard storage " + collection);
}
bot.ClearNotecardStorage(collection);
return BasicReply(bot.SendNotecard(notecardname, content, avataruuid).ToString());
}
}
}

View file

@ -1,19 +0,0 @@
namespace BetterSecondBot.Commands.Notecard
{
class NotecardAdd : CoreCommand_2arg
{
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 bool CallFunction(string[] args)
{
if (base.CallFunction(args) == true)
{
bot.NotecardAddContent(args[0], args[1]);
return true;
}
return false;
}
}
}

View file

@ -1,19 +0,0 @@
namespace BetterSecondBot.Commands.Notecard
{
class NotecardClear : CoreCommand_1arg
{
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 bool CallFunction(string[] args)
{
if (base.CallFunction(args) == true)
{
bot.ClearNotecardStorage(args[0]);
return true;
}
return false;
}
}
}

View file

@ -1,45 +0,0 @@
using BetterSecondBotShared.Static;
using OpenMetaverse;
namespace BetterSecondBot.Commands.Notecard
{
class NotecardSend : CoreCommand_2arg
{
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 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;
}
}
}

View file

@ -135,7 +135,7 @@ namespace BetterSecondBot.HttpService
[Route(HttpVerbs.Get, "/ParcelEject/{avatar}/{token}")] [Route(HttpVerbs.Get, "/ParcelEject/{avatar}/{token}")]
public object ParcelEject(string avatar,string token) public object ParcelEject(string avatar,string token)
{ {
if (tokens.Allow(token, "parcel", "ParcelEject", getClientIP()) == false) if (tokens.Allow(token, "parcel", "ParcelEject", handleGetClientIP()) == false)
{ {
return BasicReply("Token not accepted"); return BasicReply("Token not accepted");
} }
@ -429,7 +429,7 @@ namespace BetterSecondBot.HttpService
[Route(HttpVerbs.Get, "/ParcelFreeze/{avatar}/{state}/{token}")] [Route(HttpVerbs.Get, "/ParcelFreeze/{avatar}/{state}/{token}")]
public object ParcelFreeze(string avatar, string state, string token) public object ParcelFreeze(string avatar, string state, string token)
{ {
if (tokens.Allow(token, "parcel", "ParcelFreeze", getClientIP()) == false) if (tokens.Allow(token, "parcel", "ParcelFreeze", handleGetClientIP()) == false)
{ {
return Failure("Token not accepted"); return Failure("Token not accepted");
} }
@ -476,7 +476,7 @@ namespace BetterSecondBot.HttpService
[Route(HttpVerbs.Get, "/UnRezObject/{objectuuid}/{token}")] [Route(HttpVerbs.Get, "/UnRezObject/{objectuuid}/{token}")]
public object UnRezObject(string objectuuid,string token) public object UnRezObject(string objectuuid,string token)
{ {
if (tokens.Allow(token, "parcel", "UnRezObject", getClientIP()) == false) if (tokens.Allow(token, "parcel", "UnRezObject", handleGetClientIP()) == false)
{ {
return Failure("Token not accepted"); return Failure("Token not accepted");
} }

View file

@ -23,7 +23,7 @@ namespace BetterSecondBot.HttpService
[Route(HttpVerbs.Get, "/PointAt/{avatar}/{token}")] [Route(HttpVerbs.Get, "/PointAt/{avatar}/{token}")]
public object PointAt(string avatar, string token) public object PointAt(string avatar, string token)
{ {
if (tokens.Allow(token, "self", "PointAt", getClientIP()) == false) if (tokens.Allow(token, "self", "PointAt", handleGetClientIP()) == false)
{ {
return Failure("Token not accepted"); return Failure("Token not accepted");
} }
@ -49,7 +49,7 @@ namespace BetterSecondBot.HttpService
[Route(HttpVerbs.Get, "/Sit/{target}/{token}")] [Route(HttpVerbs.Get, "/Sit/{target}/{token}")]
public object Sit(string target, string token) public object Sit(string target, string token)
{ {
if (tokens.Allow(token, "self", "Sit", getClientIP()) == false) if (tokens.Allow(token, "self", "Sit", handleGetClientIP()) == false)
{ {
return Failure("Token not accepted"); return Failure("Token not accepted");
} }
@ -71,7 +71,7 @@ namespace BetterSecondBot.HttpService
[Route(HttpVerbs.Get, "/Stand/{token}")] [Route(HttpVerbs.Get, "/Stand/{token}")]
public object Stand(string target, string token) public object Stand(string target, string token)
{ {
if (tokens.Allow(token, "self", "Stand", getClientIP()) == false) if (tokens.Allow(token, "self", "Stand", handleGetClientIP()) == false)
{ {
return Failure("Token not accepted"); return Failure("Token not accepted");
} }
@ -88,7 +88,7 @@ namespace BetterSecondBot.HttpService
[Route(HttpVerbs.Get, "/ClickObject/{object}/{token}")] [Route(HttpVerbs.Get, "/ClickObject/{object}/{token}")]
public object ClickObject(string target, string token) public object ClickObject(string target, string token)
{ {
if (tokens.Allow(token, "self", "ClickObject", getClientIP()) == false) if (tokens.Allow(token, "self", "ClickObject", handleGetClientIP()) == false)
{ {
return Failure("Token not accepted"); return Failure("Token not accepted");
} }
@ -115,7 +115,7 @@ namespace BetterSecondBot.HttpService
[Route(HttpVerbs.Get, "/Logoff/{token}")] [Route(HttpVerbs.Get, "/Logoff/{token}")]
public object Logoff(string token) public object Logoff(string token)
{ {
if (tokens.Allow(token, "self", "Logoff", getClientIP()) == false) if (tokens.Allow(token, "self", "Logoff", handleGetClientIP()) == false)
{ {
return Failure("Token not accepted"); return Failure("Token not accepted");
} }
@ -132,7 +132,7 @@ namespace BetterSecondBot.HttpService
[Route(HttpVerbs.Get, "/Logout/{token}")] [Route(HttpVerbs.Get, "/Logout/{token}")]
public object Logout(string token) public object Logout(string token)
{ {
if (tokens.Allow(token, "self", "Logout", getClientIP()) == false) if (tokens.Allow(token, "self", "Logout", handleGetClientIP()) == false)
{ {
return Failure("Token not accepted"); return Failure("Token not accepted");
} }
@ -149,7 +149,7 @@ namespace BetterSecondBot.HttpService
[Route(HttpVerbs.Get, "/Bye/{token}")] [Route(HttpVerbs.Get, "/Bye/{token}")]
public object Bye(string token) public object Bye(string token)
{ {
if (tokens.Allow(token, "self", "Bye", getClientIP()) == false) if (tokens.Allow(token, "self", "Bye", handleGetClientIP()) == false)
{ {
return Failure("Token not accepted"); return Failure("Token not accepted");
} }
@ -165,7 +165,7 @@ namespace BetterSecondBot.HttpService
[Route(HttpVerbs.Get, "/GetLastCommands/{token}")] [Route(HttpVerbs.Get, "/GetLastCommands/{token}")]
public object GetLastCommands(string token) public object GetLastCommands(string token)
{ {
if (tokens.Allow(token, "self", "GetLastCommands", getClientIP()) == false) if (tokens.Allow(token, "self", "GetLastCommands", handleGetClientIP()) == false)
{ {
return Failure("Token not accepted"); return Failure("Token not accepted");
} }
@ -184,7 +184,7 @@ namespace BetterSecondBot.HttpService
[Route(HttpVerbs.Get, "/SetPermFlag/{avatar}/{flag}/{state}/{sticky}/{token}")] [Route(HttpVerbs.Get, "/SetPermFlag/{avatar}/{flag}/{state}/{sticky}/{token}")]
public object SetPermFlag(string avatar, string flag, string state, string sticky, string token) public object SetPermFlag(string avatar, string flag, string state, string sticky, string token)
{ {
if (tokens.Allow(token, "self", "SetPermFlag", getClientIP()) == false) if (tokens.Allow(token, "self", "SetPermFlag", handleGetClientIP()) == false)
{ {
return Failure("Token not accepted"); return Failure("Token not accepted");
} }

View file

@ -31,7 +31,7 @@ namespace BetterSecondBot.HttpService
[Route(HttpVerbs.Post, "/FetchNextNotecard/{token}")] [Route(HttpVerbs.Post, "/FetchNextNotecard/{token}")]
public object FetchNextNotecard([FormField] string endpoint, [FormField] string endpointcode, string token) public object FetchNextNotecard([FormField] string endpoint, [FormField] string endpointcode, string token)
{ {
if (tokens.Allow(token, "avatars", "FetchNextNotecard", getClientIP()) == false) if (tokens.Allow(token, "avatars", "FetchNextNotecard", handleGetClientIP()) == false)
{ {
return Failure("Token not accepted"); return Failure("Token not accepted");
} }

View file

@ -1,398 +0,0 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.Linq;
using OpenMetaverse;
using System.Net.Http;
using BetterSecondBot.bottypes;
using BetterSecondBotShared.API;
using BetterSecondBotShared.Static;
using BetterSecondBotShared.logs;
using Newtonsoft.Json;
namespace BetterSecondBot.Commands
{
public class pending_avatar_lookup
{
public CoreCommand GetCommand { get { return Command; } }
public List<string> Getargs { get { return args; } }
public pending_avatar_lookup(CoreCommandsInterface set_master,CoreCommand set_cmd,string[] set_args)
{
Master = set_master;
Command = set_cmd;
args = set_args.ToList();
}
public KeyValuePair<bool,string> Callnow()
{
bool result = Command.CallFunction(args.ToArray());
return new KeyValuePair<bool, string>(result, Command.GetInfoBlob);
}
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)
{
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;
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)
{
KeyValuePair<bool, string> result = commands_pending_avatar_lookups[a].Callnow();
bot.CommandHistoryAdd(commands_pending_avatar_lookups[a].GetCommand.CommandName, String.Join("~#~", commands_pending_avatar_lookups[a].Getargs), result.Key, result.Value);
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(bool run_status, string target, string output, string command)
{
return SmartCommandReply(run_status, target, output, command, null);
}
public bool SmartCommandReply(bool run_status, string target, string output, string command, Dictionary<string,string> collection)
{
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
{
if (int.TryParse(target, out target_channel) == false)
{
run_status = false;
}
}
if (collection != null)
{
var reply_object = new CoreCommand_json_reply_wit_collection();
reply_object.status = run_status;
reply_object.command = command;
reply_object.output = output;
reply_object.collection = collection;
output = JsonConvert.SerializeObject(reply_object);
}
else
{
var reply_object = new CoreCommand_json_reply();
reply_object.status = run_status;
reply_object.command = command;
reply_object.output = output;
output = JsonConvert.SerializeObject(reply_object);
}
if (mode == "CHAT")
{
if (target_channel >= 0)
{
bot.GetClient.Self.Chat(output, target_channel, ChatType.Normal);
}
else
{
run_status = false;
LogFormater.Crit("[SmartReply] output Channel must be zero or higher");
}
}
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 },
};
var content = new FormUrlEncodedContent(values);
try
{
HTTPclient.PostAsync(target, content);
}
catch (Exception e)
{
run_status = false;
LogFormater.Crit("[SmartReply] HTTP failed: " + e.Message + "");
}
}
else
{
LogFormater.Crit("[SmartReply] Unsupported output target");
return false;
}
return run_status;
}
protected List<string> suppress_warnings = new List<string>();
public bool Call(string command)
{
return Call(command, "");
}
public bool Call(string command, string arg)
{
return Call(command, arg, UUID.Zero);
}
public bool Call(string command, string arg, UUID caller)
{
return Call(command, arg, caller, "~#~");
}
public bool Call(string command, string arg, UUID caller, string split_args_on)
{
KeyValuePair<bool, string> result = CallCommand(command, arg, caller, split_args_on);
bot.CommandHistoryAdd(command, arg, result.Key, result.Value);
return result.Key;
}
protected KeyValuePair<bool,string> CallCommand(string command, string arg, UUID caller, string split_args_on)
{
command = command.ToLowerInvariant();
CoreCommand cmd = (CoreCommand)GetCommand(command);
if (cmd != null)
{
cmd.Setup(bot, caller);
string[] args = new string[] { };
if (helpers.notempty(arg) == true)
{
args = arg.Split(new[] { split_args_on }, StringSplitOptions.RemoveEmptyEntries);
}
if ((cmd.ArgTypes.Contains("Avatar") == true) || (cmd.ArgTypes.Contains("Smart") == true))
{
if (cmd.Min_Required_args <= 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 new KeyValuePair<bool, string>(true,"Lookup underway");
}
else
{
return pending.Callnow();
}
}
else
{
return new KeyValuePair<bool, string>(false, "Required args count not sent! expected: "+ cmd.Min_Required_args.ToString()+" but got "+ args.Length.ToString()+ "");
}
}
else
{
bool result = cmd.CallFunction(args);
return new KeyValuePair<bool, string>(result, cmd.GetInfoBlob);
}
}
else
{
if (suppress_warnings.Contains(command) == false)
{
suppress_warnings.Add(command);
return new KeyValuePair<bool, string>(false, "unknown");
}
}
return new KeyValuePair<bool, string>(false, "--");
}
}
class CoreCommand_json_reply_wit_collection : CoreCommand_json_reply
{
public Dictionary<string, string> collection = new Dictionary<string, string>();
}
class CoreCommand_json_reply
{
public bool status;
public string command;
public string output;
}
public abstract class CoreCommand_1arg : CoreCommand
{
public override int Min_Required_args { get { return 1; } }
}
public abstract class CoreCommand_2arg : CoreCommand
{
public override int Min_Required_args { get { return 2; } }
}
public abstract class CoreCommand_3arg : CoreCommand
{
public override int Min_Required_args { get { return 3; } }
}
public abstract class CoreCommand_4arg : CoreCommand
{
public override int Min_Required_args { get { return 4; } }
}
public abstract class CoreCommand_SmartReply_1arg : CoreCommand_1arg
{
protected Dictionary<string, string> collection = new Dictionary<string, string>();
public override string[] ArgTypes { get { return new[] { "Smart" }; } }
public override string[] ArgHints { get { return new[] { "Mixed [Channel|Avatar uuid|Avatar name|http url]" }; } }
}
public abstract class CoreCommand_SmartReply_2arg : CoreCommand_SmartReply_1arg
{
public override int Min_Required_args { get { return 2; } }
}
public abstract class CoreCommand_SmartReply_3arg : CoreCommand_SmartReply_1arg
{
public override int Min_Required_args { get { return 3; } }
}
public abstract class CoreCommand : API_interface
{
protected CommandsBot bot;
/// <summary>
/// The UUID of the object/Avatar that called this function, you should still test if its not UUID zero and is a avatar
/// </summary>
protected UUID caller = UUID.Zero;
public void Setup(CommandsBot setBot,UUID setCaller)
{
bot = setBot;
caller = setCaller;
}
public virtual void Callback(string[] args, EventArgs e,bool status)
{
bot.CommandHistoryAdd("Callback finished-> " + this.GetType().Name, String.Join(",", args), status, GetInfoBlob);
}
public virtual void Callback(string[] args, EventArgs e)
{
bot.CommandHistoryAdd("Callback finished-> " + this.GetType().Name, String.Join(",", args), true, GetInfoBlob);
}
public virtual bool CallFunction(string[] args)
{
if (helpers.notempty(args) == true)
{
if (args.Length < Min_Required_args)
{
return Failed("Incorrect number of args");
}
else
{
return true;
}
}
else
{
if(Min_Required_args == 0)
{
return true;
}
else
{
return Failed("Incorrect number of args");
}
}
}
public bool Failed(string why_failed)
{
InfoBlob = why_failed;
LogFormater.Warn("Called failed because: " + why_failed);
return false;
}
}
}

View file

@ -17,6 +17,8 @@ using Newtonsoft.Json;
using OpenMetaverse; using OpenMetaverse;
using System.Reflection; using System.Reflection;
using System.Linq; using System.Linq;
using System.Threading.Tasks;
using Core.Static;
namespace BetterSecondBot.HttpService namespace BetterSecondBot.HttpService
{ {
@ -173,32 +175,14 @@ namespace BetterSecondBot.HttpService
.WithUrlPrefix(url) .WithUrlPrefix(url)
.WithMode(HttpListenerMode.EmbedIO)) .WithMode(HttpListenerMode.EmbedIO))
.WithCors() .WithCors()
//.WithIPBanning(o => o
// .WithMaxRequestsPerSecond(30)
// .WithRegexRules("HTTP exception 404")
//)
.WithWebApi("/inventory", m => m
.WithController(() => new HTTP_Inventory(Bot, Tokens))
)
.WithWebApi("/chat", m => m
.WithController(() => new HTTP_Chat(Bot, Tokens))
)
.WithWebApi("/groups", m => m
.WithController(() => new HTTP_Group(Bot, Tokens))
)
.WithWebApi("/ims", m => m
.WithController(() => new HttpApiIM(Bot, Tokens))
)
.WithWebApi("/core", m => m
.WithController(() => new HttpApiCore(Config, Bot, Tokens))
)
.WithWebApi("/parcel", m => m
.WithController(() => new HTTP_Parcel(Bot,Tokens))
)
.WithWebApi("/estate", m => m
.WithController(() => new HTTP_Estate(Bot, Tokens))
)
.WithModule(new ActionModule("/", HttpVerbs.Any, ctx => ctx.SendDataAsync(new { Message = "Error" }))); .WithModule(new ActionModule("/", HttpVerbs.Any, ctx => ctx.SendDataAsync(new { Message = "Error" })));
Dictionary<string, Type> commandmodules = http_commands_helper.getCommandModules();
foreach (KeyValuePair<string, Type> entry in commandmodules)
{
server.WithWebApi("/" + entry.Key, m => m
.WithController(() => (WebApiControllerWithTokens)Activator.CreateInstance(entry.Value, args: new object[] { Bot, Tokens }))
);
}
return server; return server;
} }
@ -262,6 +246,8 @@ namespace BetterSecondBot.HttpService
protected Dictionary<string, scopedTokenInfo> scopedtokens = new Dictionary<string, scopedTokenInfo>(); protected Dictionary<string, scopedTokenInfo> scopedtokens = new Dictionary<string, scopedTokenInfo>();
protected List<string> OneTimeTokens = new List<string>(); protected List<string> OneTimeTokens = new List<string>();
public string OneTimeToken() public string OneTimeToken()
@ -395,38 +381,34 @@ namespace BetterSecondBot.HttpService
{ {
protected TokenStorage tokens; protected TokenStorage tokens;
protected SecondBot bot; protected SecondBot bot;
public bool needsToken { get; set; } public bool needsToken { get; set; }
protected UUID avataruuid = UUID.Zero; protected UUID avataruuid = UUID.Zero;
protected Parcel targetparcel = null; protected Parcel targetparcel = null;
protected string CallMethod(string name,string[] args) protected bool disableIPchecks = false;
public void disableIPlockout()
{ {
MethodInfo[] methods = this.GetType().GetMethods(); disableIPchecks = true;
MethodInfo found = null;
foreach(MethodInfo M in methods)
{
if(M.Name == name)
{
found = M;
break;
}
}
if(found == null)
{
return "Failed:Not Found";
}
List<string> settings = new List<string>(args);
settings.Add(tokens.OneTimeToken());
if(found.GetParameters().Length != settings.Count)
{
return "Failed:Incorrect args";
}
string reply = (string)found.Invoke(this, settings.Cast<object>().ToArray());
return "Passed:"+ reply;
} }
public IPAddress handleGetClientIP()
{
if(disableIPchecks == true)
{
return IPAddress.Parse("127.0.0.1");
}
else
{
return HttpContext.Request.RemoteEndPoint.Address;
}
}
protected KeyValuePair<bool,string> SetupCurrentParcel(string token,string usenamespace,string command) protected KeyValuePair<bool,string> SetupCurrentParcel(string token,string usenamespace,string command)
{ {
if (tokens.Allow(token, usenamespace, command, getClientIP()) == false) if (tokens.Allow(token, usenamespace, command, handleGetClientIP()) == false)
{ {
return new KeyValuePair<bool, string>(false, "Token not accepted"); return new KeyValuePair<bool, string>(false, "Token not accepted");
} }
@ -437,11 +419,18 @@ namespace BetterSecondBot.HttpService
int localid = bot.GetClient.Parcels.GetParcelLocalID(bot.GetClient.Network.CurrentSim, bot.GetClient.Self.SimPosition); int localid = bot.GetClient.Parcels.GetParcelLocalID(bot.GetClient.Network.CurrentSim, bot.GetClient.Self.SimPosition);
if (bot.GetClient.Network.CurrentSim.Parcels.ContainsKey(localid) == false) if (bot.GetClient.Network.CurrentSim.Parcels.ContainsKey(localid) == false)
{ {
return new KeyValuePair<bool, string>(false, "Parcel data not ready"); Thread.Sleep(2000);
localid = bot.GetClient.Parcels.GetParcelLocalID(bot.GetClient.Network.CurrentSim, bot.GetClient.Self.SimPosition);
if (bot.GetClient.Network.CurrentSim.Parcels.ContainsKey(localid) == false)
{
return new KeyValuePair<bool, string>(false, "Parcel data not ready");
}
} }
Parcel targetparcel = bot.GetClient.Network.CurrentSim.Parcels[localid]; Parcel targetparcel = bot.GetClient.Network.CurrentSim.Parcels[localid];
return new KeyValuePair<bool, string>(true, ""); return new KeyValuePair<bool, string>(true, "");
} }
protected void ProcessAvatar(string avatar) protected void ProcessAvatar(string avatar)
{ {
string[] bits = avatar.Split(' '); string[] bits = avatar.Split(' ');
@ -449,6 +438,11 @@ namespace BetterSecondBot.HttpService
if (bits.Length == 2) if (bits.Length == 2)
{ {
avatar = bot.FindAvatarName2Key(avatar); avatar = bot.FindAvatarName2Key(avatar);
if(avatar == "lookup")
{
Thread.Sleep(2000);
avatar = bot.FindAvatarName2Key(avatar);
}
} }
UUID.TryParse(avatar, out avataruuid); UUID.TryParse(avatar, out avataruuid);
} }
@ -468,6 +462,7 @@ namespace BetterSecondBot.HttpService
{ {
bot = mainbot; bot = mainbot;
tokens = setuptokens; tokens = setuptokens;
} }
/* /*
@ -479,13 +474,10 @@ namespace BetterSecondBot.HttpService
} }
*/ */
public IPAddress getClientIP()
{
return HttpContext.Request.RemoteEndPoint.Address;
}
} }
public class tokenInfo public class tokenInfo
{ {
public long Expires = 0; public long Expires = 0;

View file

@ -1,116 +0,0 @@
using BetterSecondBot.bottypes;
using BetterSecondBot.Static;
using EmbedIO;
using EmbedIO.Routing;
using EmbedIO.WebApi;
using System;
using System.Collections.Generic;
using System.Text;
using OpenMetaverse;
using Newtonsoft.Json;
using BetterSecondBotShared.Static;
namespace BetterSecondBot.HttpService
{
public class HTTP_Info : WebApiControllerWithTokens
{
public HTTP_Info(SecondBot mainbot, TokenStorage setuptokens) : base(mainbot, setuptokens) { }
[About("Fetchs the current bot")]
[ReturnHints("The build ID of the bot")]
[Route(HttpVerbs.Get, "/Version/{token}")]
public object Version(string token)
{
if (tokens.Allow(token, "info", "Version", getClientIP()) == true)
{
return BasicReply(bot.MyVersion);
}
return Failure("Token not accepted");
}
[About("Fetchs the name of the bot")]
[ReturnHints("Firstname Lastname")]
[Route(HttpVerbs.Get, "/Name/{token}")]
public object Name(string token)
{
if (tokens.Allow(token, "info", "Name", getClientIP()) == true)
{
return BasicReply(bot.GetClient.Self.FirstName + " " + bot.GetClient.Self.LastName);
}
return Failure("Token not accepted");
}
[About("Fetchs the current parcels name")]
[ReturnHints("Parcelname")]
[ReturnHints("Error parcel not found")]
[ReturnHints("Error not in a sim")]
[Route(HttpVerbs.Get, "/ParcelName/{token}")]
public object ParcelName(string token)
{
if (tokens.Allow(token, "info", "ParcelName", getClientIP()) == true)
{
if (bot.GetClient.Network.CurrentSim != null)
{
int localid = bot.GetClient.Parcels.GetParcelLocalID(bot.GetClient.Network.CurrentSim, bot.GetClient.Self.SimPosition);
if (bot.GetClient.Network.CurrentSim.Parcels.ContainsKey(localid) == true)
{
return BasicReply(bot.GetClient.Network.CurrentSim.Parcels[localid].Name);
}
return Failure("Error parcel not found");
}
return Failure("Error not in a sim");
}
return Failure("Token not accepted");
}
[About("Requests the current unixtime at the bot")]
[ReturnHints("Unixtime")]
[Route(HttpVerbs.Get, "/UnixTimeNow/{token}")]
public object UnixTimeNow(string token)
{
if (tokens.Allow(token, "info", "UnixTimeNow", getClientIP()) == true)
{
return BasicReply(helpers.UnixTimeNow().ToString());
}
return Failure("Token not accepted");
}
[About("Fetchs the current region name")]
[ReturnHints("Regionname")]
[ReturnHints("Error not in a sim")]
[Route(HttpVerbs.Get, "/SimName/{token}")]
public object SimName(string token)
{
if (tokens.Allow(token, "info", "SimName", getClientIP()) == true)
{
if (bot.GetClient.Network.CurrentSim != null)
{
return BasicReply(bot.GetClient.Network.CurrentSim.Name);
}
return Failure("Error not in a sim");
}
return Failure("Token not accepted");
}
[About("Fetchs the current location of the bot")]
[ReturnHints("array of X,Y,Z values")]
[ReturnHints("Error not in a sim")]
[Route(HttpVerbs.Get, "/GetPosition/{token}")]
public object GetPosition(string token)
{
if (tokens.Allow(token, "info", "GetPosition", getClientIP()) == true)
{
if (bot.GetClient.Network.CurrentSim != null)
{
Dictionary<string, int> pos = new Dictionary<string, int>();
pos.Add("x", (int)Math.Round(bot.GetClient.Self.SimPosition.X));
pos.Add("y", (int)Math.Round(bot.GetClient.Self.SimPosition.Y));
pos.Add("z", (int)Math.Round(bot.GetClient.Self.SimPosition.Z));
return BasicReply(JsonConvert.SerializeObject(pos));
}
return Failure("Error not in a sim");
}
return Failure("Token not accepted");
}
}
}

View file

@ -1,218 +0,0 @@
using BetterSecondBot.bottypes;
using BetterSecondBot.Static;
using EmbedIO;
using EmbedIO.Routing;
using EmbedIO.WebApi;
using System;
using System.Collections.Generic;
using System.Text;
using OpenMetaverse;
namespace BetterSecondBot.HttpService
{
public class HTTP_Inventory : WebApiControllerWithTokens
{
public HTTP_Inventory(SecondBot mainbot, TokenStorage setuptokens) : base(mainbot, setuptokens) { }
[About("rezs the item at the bots current location")]
[ReturnHints("True|False")]
[ArgHints("item", "URLARG", "UUID of item to rez")]
[Route(HttpVerbs.Get, "/RezObject/{item}/{token}")]
public object RezObject(string item, string token)
{
if (tokens.Allow(token, "inventory", "RezObject", getClientIP()) == true)
{
bool status = bot.GetCommandsInterface.Call("RezObject", item);
return BasicReply(status.ToString());
}
return BasicReply("Token not accepted");
}
[About("renames a folder or inventory item")]
[ReturnHints("True|False")]
[ArgHints("item", "URLARG", "UUID of item/folder to name")]
[ArgHints("newname", "Text", "What we are changing it to")]
[Route(HttpVerbs.Post, "/Rename/{item}/{token}")]
public object Rename(string item, string token, [FormField] string newname)
{
if (tokens.Allow(token, "inventory", "Rename", getClientIP()) == true)
{
bool status = bot.GetCommandsInterface.Call("RenameInventory", "12~#~" + item + "~#~" + newname);
return BasicReply(status.ToString());
}
return BasicReply("Token not accepted");
}
[About("converts a inventory uuid to a realworld uuid<br/>Needed for texture preview")]
[ReturnHints("Asset UUID")]
[ReturnHints("Failed")]
[ArgHints("item", "URLARG", "inventory level UUID of item")]
[Route(HttpVerbs.Get, "/realuuid/{item}/{token}")]
public object realuuid(string item, string token)
{
if (tokens.Allow(token, "inventory", "realuuid", getClientIP()) == true)
{
if (UUID.TryParse(item, out UUID itemUUID) == true)
{
UUID reply = HelperInventory.GetAssetUUID(bot, itemUUID);
if (reply != UUID.Zero)
{
return BasicReply(reply.ToString());
}
}
return BasicReply("Failed");
}
return BasicReply("Token not accepted");
}
[About("sends a item to an avatar")]
[ReturnHints("True|False")]
[ReturnHints("Failed")]
[ArgHints("item", "URLARG", "UUID of item")]
[ArgHints("avatar", "URLARG", "a UUID or Firstname Lastname")]
[Route(HttpVerbs.Get, "/send/{item}/{avatar}/{token}")]
public object send(string item, string avatar, string token)
{
if (tokens.Allow(token, "inventory", "send", getClientIP()) == true)
{
if (UUID.TryParse(item, out UUID itemUUID) == true)
{
bool status = bot.GetCommandsInterface.Call("SendItem", avatar+"~#~"+item);
return BasicReply(status.ToString());
}
return BasicReply("Failed - item must be a vaild UUID");
}
return BasicReply("Token not accepted");
}
[About("Transfers a item [ARG 2] to a objects inventory [ARG 1] (And if set with the script running state [ARG 3])")]
[ReturnHints("Transfering running script")]
[ReturnHints("Transfering inventory")]
[ReturnHints("Invaild item uuid")]
[ReturnHints("Invaild object uuid")]
[ReturnHints("Unable to find inventory")]
[ReturnHints("Unable to find object")]
[ReturnHints("Invaild running")]
[ArgHints("item", "URLARG", "UUID of item")]
[ArgHints("object", "URLARG", "the uuid of the object")]
[ArgHints("running", "URLARG", "true if you wish the transfered script to be running otherwise false")]
[Route(HttpVerbs.Get, "/TransferInventoryToObject/{item}/{objectuuid}/{running}/{token}")]
public object TransferInventoryToObject(string item, string objectuuid, string running, string token)
{
if (tokens.Allow(token, "inventory", "TransferInventoryToObject", getClientIP()) == true)
{
return Failure("Token not accepted");
}
if (UUID.TryParse(item, out UUID itemuuid) == false)
{
return Failure("Invaild item uuid");
}
if (UUID.TryParse(objectuuid, out UUID objectUUID) == false)
{
return Failure("Invaild object uuid");
}
if (bool.TryParse(running, out bool runscript) == false)
{
return Failure("Invaild running");
}
InventoryItem itm = bot.GetClient.Inventory.FetchItem(itemuuid, bot.GetClient.Self.AgentID, (3 * 1000));
if (itm == null)
{
return Failure("Unable to find inventory");
}
Dictionary<uint, Primitive> objects_copy = bot.GetClient.Network.CurrentSim.ObjectsPrimitives.Copy();
KeyValuePair<uint, Primitive> RealObject = new KeyValuePair<uint, Primitive>(0,null);
foreach (KeyValuePair<uint, Primitive> Obj in objects_copy)
{
if (Obj.Value.ID == objectUUID)
{
RealObject = Obj;
break;
}
}
if (RealObject.Value == null)
{
return Failure("Unable to find object");
}
bool scriptState = runscript;
if (itm.AssetType != AssetType.LSLText)
{
scriptState = false;
}
if (itm.AssetType == AssetType.LSLText)
{
bot.GetClient.Inventory.CopyScriptToTask(RealObject.Key, itm, scriptState);
return BasicReply("Transfering script [state: "+scriptState.ToString()+"]");
}
bot.GetClient.Inventory.UpdateTaskInventory(RealObject.Key, itm);
return BasicReply("Transfering inventory");
}
[About("Removes a item/folder from inventory (Make sure you set the isfolder flag correctly!)")]
[ReturnHints("True|False")]
[ReturnHints("Failed - isfolder must be True or False")]
[ReturnHints("Failed - item must be a vaild UUID")]
[ArgHints("item", "URLARG", "UUID of item")]
[ArgHints("isfolder", "URLARG", "True or False if this is a folder")]
[Route(HttpVerbs.Get, "/delete/{item}/{isfolder}/{token}")]
public object delete(string item,string isfolder, string token)
{
if (tokens.Allow(token, "inventory", "delete", getClientIP()) == true)
{
if (UUID.TryParse(item, out UUID itemUUID) == true)
{
if (bool.TryParse(isfolder, out bool asfolder) == true)
{
bool status = false;
if (asfolder == true) status = bot.GetCommandsInterface.Call("DeleteInventoryFolder", item);
else status = bot.GetCommandsInterface.Call("DeleteInventoryItem", item);
return BasicReply(status.ToString());
}
return BasicReply("Failed - isfolder must be True or False");
}
return BasicReply("Failed - item must be a vaild UUID");
}
return BasicReply("Token not accepted");
}
[About("Requests the inventory folder layout as a json object InventoryMapFolder<br/>Formated as follows<br/>InventoryMapItem<br/><ul><li>id: UUID</li><li>name: String</li><li>subfolders: InventoryMapFolder[]</li></ul>")]
[ReturnHints("array of InventoryMapFolder")]
[ReturnHints("Error")]
[Route(HttpVerbs.Get, "/folders/{token}")]
public object folders(string token)
{
if(tokens.Allow(token, "inventory", "folders", getClientIP()) == true)
{
string reply = HelperInventory.MapFolderJson(bot);
if(reply != null) return BasicReply(reply);
return BasicReply("Error");
}
return BasicReply("Token not accepted");
}
[About("Requests the contents of a folder as an array of InventoryMapItem<br/>Formated as follows<br/>InventoryMapItem<br/><ul><li>id: UUID</li><li>name: String</li><li>typename: String</li></ul>")]
[ReturnHints("array of InventoryMapItem")]
[ReturnHints("Invaild folder UUID")]
[ArgHints("folderUUID", "URLARG", "the folder to fetch (Found via: inventory/folders)")]
[Route(HttpVerbs.Get, "/contents/{folderUUID}/{token}")]
public object Contents(string folderUUID, string token)
{
if (tokens.Allow(token, "inventory", "contents", getClientIP()) == true)
{
if (UUID.TryParse(folderUUID, out UUID folder) == true)
{
return BasicReply(HelperInventory.MapFolderInventoryJson(bot, folder));
}
return BasicReply("Invaild folder UUID");
}
return BasicReply("Token not accepted");
}
}
}

View file

@ -1,131 +0,0 @@
using BetterSecondBot.bottypes;
using BetterSecondBot.Static;
using EmbedIO;
using EmbedIO.Routing;
using EmbedIO.WebApi;
using System;
using System.Collections.Generic;
using System.Text;
using OpenMetaverse;
using Newtonsoft.Json;
using System.Reflection;
using System.Threading;
using BetterSecondBotShared.Static;
namespace BetterSecondBot.HttpService
{
public class HTTP_Movement : WebApiControllerWithTokens
{
public HTTP_Movement(SecondBot mainbot, TokenStorage setuptokens) : base(mainbot, setuptokens) { }
[About("uses the AutoPilot to move to a location")]
[ReturnHints("Error Unable to AutoPilot to location")]
[ReturnHints("Accepted")]
[ReturnHints("Convert to vector has failed")]
[ReturnHints("? value out of range 0-?")]
[ArgHints("x", "URLARG", "X location to AutoPilot to")]
[ArgHints("y", "URLARG", "y location to AutoPilot to")]
[ArgHints("z", "URLARG", "z location to AutoPilot to")]
[Route(HttpVerbs.Get, "/AutoPilot/{x}/{y}/{z}/{token}")]
public object AutoPilot(string x, string y, string z, string token)
{
if (tokens.Allow(token, "movement", "AutoPilot", getClientIP()) == false)
{
return Failure("Token not accepted");
}
if (Vector3.TryParse("<" + x + "," + y + "," + z + ">", out Vector3 pos) == false)
{
return Failure("Convert to vector has failed");
}
if (helpers.inrange(pos.X, 0, 255) == false)
{
return Failure("x value out of range 0-255");
}
if (helpers.inrange(pos.Y, 0, 255) == false)
{
return Failure("y value out of range 0-255");
}
if (helpers.inrange(pos.Z, 0, 5000) == false)
{
return Failure("z value out of range 0-5000");
}
bot.GetClient.Self.AutoPilotCancel();
bot.GetClient.Self.Movement.TurnToward(pos, true);
Thread.Sleep(500);
uint Globalx, Globaly;
Utils.LongToUInts(bot.GetClient.Network.CurrentSim.Handle, out Globalx, out Globaly);
bot.GetClient.Self.AutoPilot((ulong)(Globalx + pos.X), (ulong)(Globaly + pos.Y), pos.Z);
return true;
}
[About("Attempt to teleport to a new region")]
[ReturnHints("Error Unable to Teleport to location")]
[ReturnHints("Accepted")]
[ArgHints("region", "URLARG", "the name of the region we are going to")]
[ArgHints("x", "URLARG", "X location to teleport to")]
[ArgHints("y", "URLARG", "y location to teleport to")]
[ArgHints("z", "URLARG", "z location to teleport to")]
[Route(HttpVerbs.Get, "/Teleport/{region}/{x}/{y}/{z}/{token}")]
public object Teleport(string region, string x, string y, string z, string token)
{
if (tokens.Allow(token, "core", "Teleport", getClientIP()) == true)
{
bool status = TeleportRequest(new string[] { region, x, y, z });
if (status == true)
{
return BasicReply("Accepted");
}
return Failure("Error Unable to Teleport to location");
}
return Failure("Token not accepted");
}
protected bool TeleportRequest(string[] args)
{
bot.GetClient.Self.AutoPilotCancel();
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 false;
}
}
}
}
}

View file

@ -0,0 +1,33 @@
using BetterSecondBot.HttpService;
using System;
using System.Collections.Generic;
using System.Text;
namespace Core.Static
{
public static class http_commands_helper
{
public static Dictionary<string, Type> getCommandModules()
{
Dictionary<string, Type> reply = new Dictionary<string, Type>();
reply.Add("animation", typeof(HTTP_Animation));
reply.Add("avatars", typeof(HTTP_Avatars));
reply.Add("chat", typeof(HTTP_Chat));
reply.Add("core", typeof(HTTP_Core));
reply.Add("dialogs", typeof(HTTP_Dialogs));
reply.Add("estate", typeof(HTTP_Estate));
reply.Add("friends", typeof(HTTP_Friends));
reply.Add("group", typeof(HTTP_Group));
reply.Add("home", typeof(HTTP_Home));
reply.Add("im", typeof(HTTP_IM));
reply.Add("info", typeof(HTTP_Info));
reply.Add("inventory", typeof(HTTP_Inventory));
reply.Add("movement", typeof(HTTP_Movement));
reply.Add("notecard", typeof(HTTP_Notecard));
reply.Add("parcel", typeof(HTTP_Parcel));
reply.Add("self", typeof(HTTP_Self));
reply.Add("streamadmin", typeof(HTTP_StreamAdmin));
return reply;
}
}
}

View file

@ -226,6 +226,7 @@ namespace BetterSecondBot.bottypes
FindAvatarName2Key(myconfig.Security_MasterUsername); FindAvatarName2Key(myconfig.Security_MasterUsername);
} }
} }
base.AfterBotLoginHandler(); base.AfterBotLoginHandler();
} }

View file

@ -14,8 +14,8 @@ namespace BetterSecondBot.bottypes
if (reconnect == false) if (reconnect == false)
{ {
Client.Avatars.AvatarAnimation += AvatarAnimationHandler; Client.Avatars.AvatarAnimation += AvatarAnimationHandler;
} }
base.AfterBotLoginHandler(); reconnect = true;
} }
public override void ResetAnimations() public override void ResetAnimations()

View file

@ -1,5 +1,4 @@
using BetterSecondBot.Commands; using System;
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Text; using System.Text;
using OpenMetaverse; using OpenMetaverse;
@ -25,31 +24,6 @@ namespace BetterSecondBot.bottypes
protected override void GroupMembersReplyHandler(object sender, GroupMembersReplyEventArgs e) protected override void GroupMembersReplyHandler(object sender, GroupMembersReplyEventArgs e)
{ {
base.GroupMembersReplyHandler(sender, e); base.GroupMembersReplyHandler(sender, e);
if (await_events.ContainsKey("groupmembersreply") == true)
{
List<string> PurgeAwaiters = new List<string>();
foreach (KeyValuePair<string, KeyValuePair<CoreCommand, string[]>> await_reply in await_events["groupmembersreply"])
{
// eventid
// KeyValuePair<CommandLink,Args>
// Args: Group, args, args
if (UUID.TryParse(await_reply.Value.Value[0], out UUID test_group) == true)
{
if (test_group == e.GroupID)
{
// oh shit its for me
PurgeAwaiters.Add(await_reply.Key);
await_reply.Value.Key.Callback(await_reply.Value.Value, e);
}
}
}
foreach (string eventid in PurgeAwaiters)
{
await_event_ages.Remove(eventid);
await_event_idtolistener.Remove(eventid);
await_events["groupmembersreply"].Remove(eventid);
}
}
} }
protected virtual void GroupchatJoinHandler(object sender, GroupChatJoinedEventArgs e) protected virtual void GroupchatJoinHandler(object sender, GroupChatJoinedEventArgs e)
@ -61,52 +35,10 @@ namespace BetterSecondBot.bottypes
active_group_chat_sessions.Add(e.SessionID); active_group_chat_sessions.Add(e.SessionID);
} }
} }
if (await_events.ContainsKey("groupchatjoin") == true)
{
List<string> PurgeAwaiters = new List<string>();
foreach (KeyValuePair<string, KeyValuePair<CoreCommand, string[]>> await_reply in await_events["groupchatjoin"])
{
// eventid
// KeyValuePair<CommandLink,Args>
// Args: Group, Message
if (await_reply.Value.Value.Length == 2)
{
if (UUID.TryParse(await_reply.Value.Value[0], out UUID test_group) == true)
{
if (test_group == e.SessionID)
{
// oh shit its for me
PurgeAwaiters.Add(await_reply.Key);
await_reply.Value.Key.Callback(await_reply.Value.Value, e);
}
}
}
}
foreach (string eventid in PurgeAwaiters)
{
await_event_ages.Remove(eventid);
await_event_idtolistener.Remove(eventid);
await_events["groupchatjoin"].Remove(eventid);
}
}
} }
protected virtual void ObjectOwnersHandler(object sender, ParcelObjectOwnersReplyEventArgs e) protected virtual void ObjectOwnersHandler(object sender, ParcelObjectOwnersReplyEventArgs e)
{ {
if (await_events.ContainsKey("parcelobjectowners") == true)
{
List<string> PurgeAwaiters = new List<string>();
foreach (KeyValuePair<string, KeyValuePair<CoreCommand, string[]>> await_reply in await_events["parcelobjectowners"])
{
PurgeAwaiters.Add(await_reply.Key);
await_reply.Value.Key.Callback(await_reply.Value.Value, e);
}
foreach (string eventid in PurgeAwaiters)
{
await_event_ages.Remove(eventid);
await_event_idtolistener.Remove(eventid);
await_events["parcelobjectowners"].Remove(eventid);
}
}
} }
protected void GroupRolesData(object sender,GroupRolesDataReplyEventArgs e) protected void GroupRolesData(object sender,GroupRolesDataReplyEventArgs e)
{ {
@ -126,38 +58,6 @@ namespace BetterSecondBot.bottypes
{ {
mygrouprolesstorage[e.GroupID] = storage; mygrouprolesstorage[e.GroupID] = storage;
} }
// trigger events
if (await_events.ContainsKey("grouproles") == true)
{
List<string> PurgeAwaiters = new List<string>();
foreach(KeyValuePair<string, KeyValuePair<CoreCommand, string[]>> await_reply in await_events["grouproles"])
{
// eventid
// KeyValuePair<CommandLink,Args>
// Args: ReplyConfig, GroupUUID
if (await_reply.Value.Value.Length == 2)
{
if(UUID.TryParse(await_reply.Value.Value[1], out UUID test_group) == true)
{
if(test_group == e.GroupID)
{
// oh shit its for me
PurgeAwaiters.Add(await_reply.Key);
await_reply.Value.Key.Callback(await_reply.Value.Value,e);
}
}
}
}
foreach(string eventid in PurgeAwaiters)
{
await_event_ages.Remove(eventid);
await_event_idtolistener.Remove(eventid);
await_events["grouproles"].Remove(eventid);
}
}
} }
} }
} }

View file

@ -7,16 +7,16 @@ using OpenMetaverse.Assets;
using BetterSecondBotShared.Static; using BetterSecondBotShared.Static;
using BetterSecondBotShared.logs; using BetterSecondBotShared.logs;
using System.Threading; using System.Threading;
using BetterSecondBot.HttpService;
using Core.Static;
using System.Reflection;
using Newtonsoft.Json;
using System.Net.Http;
namespace BetterSecondBot.bottypes namespace BetterSecondBot.bottypes
{ {
public abstract class CommandsBot : AVstorageBot public abstract class CommandsBot : AVstorageBot
{ {
protected CommandsBot()
{
CommandsInterface = new Commands.CoreCommandsInterface(this);
}
protected List<string> CommandHistory = new List<string>(); protected List<string> CommandHistory = new List<string>();
protected int commandid = 1; protected int commandid = 1;
public virtual string CommandHistoryAdd(string command, string arg, bool status,string infomessage) public virtual string CommandHistoryAdd(string command, string arg, bool status,string infomessage)
@ -84,9 +84,6 @@ namespace BetterSecondBot.bottypes
Client.Self.InstantMessage(avatar, message); Client.Self.InstantMessage(avatar, message);
} }
public Commands.CoreCommandsInterface GetCommandsInterface { get { return CommandsInterface; } }
protected Commands.CoreCommandsInterface CommandsInterface;
protected Dictionary<string, string> Scripts_content = new Dictionary<string, string>(); protected Dictionary<string, string> Scripts_content = new Dictionary<string, string>();
protected Dictionary<string, string> notecards_content = new Dictionary<string, string>(); protected Dictionary<string, string> notecards_content = new Dictionary<string, string>();
protected Dictionary<UUID, Dictionary<UUID, long>> group_invite_lockout_timer = new Dictionary<UUID, Dictionary<UUID, long>>(); protected Dictionary<UUID, Dictionary<UUID, long>> group_invite_lockout_timer = new Dictionary<UUID, Dictionary<UUID, long>>();
@ -100,7 +97,6 @@ namespace BetterSecondBot.bottypes
last_cleanup_commands = helpers.UnixTimeNow(); last_cleanup_commands = helpers.UnixTimeNow();
PurgeOldGroupinviteLockouts(); PurgeOldGroupinviteLockouts();
} }
CommandsInterface.StatusTick();
return base.GetStatus(); return base.GetStatus();
} }
public bool GetAllowGroupInvite(UUID avatar, UUID group) public bool GetAllowGroupInvite(UUID avatar, UUID group)
@ -112,18 +108,6 @@ namespace BetterSecondBot.bottypes
return true; return true;
} }
public void GroupInviteLockoutArm(UUID avatar, UUID group)
{
if (group_invite_lockout_timer.ContainsKey(group) == false)
{
group_invite_lockout_timer.Add(group, new Dictionary<UUID, long>());
}
if (group_invite_lockout_timer[group].ContainsKey(avatar) == false)
{
group_invite_lockout_timer[group].Add(avatar,0);
}
group_invite_lockout_timer[group][avatar] = helpers.UnixTimeNow();
}
protected void PurgeOldGroupinviteLockouts() protected void PurgeOldGroupinviteLockouts()
{ {
long now = helpers.UnixTimeNow(); long now = helpers.UnixTimeNow();
@ -145,80 +129,17 @@ namespace BetterSecondBot.bottypes
} }
} }
public void custom_commands_loop(string command,string arg,UUID caller)
{
List<string> customargs = arg.Split(new[] { "~#~" }, StringSplitOptions.RemoveEmptyEntries).ToList();
while(customargs.Count < 5)
{
customargs.Add("notset");
}
foreach (string A in custom_commands[command])
{
List<string> command_args_split = A.Split(new[] { "|||" }, StringSplitOptions.RemoveEmptyEntries).ToList();
int loop = 1;
string args_passed = "";
if (command_args_split.Count() == 2)
{
args_passed = command_args_split[1];
while (loop <= 5)
{
args_passed = args_passed.Replace("[C_ARG_"+loop.ToString()+"]", customargs[loop-1]);
loop++;
}
}
CommandsInterface.Call(command_args_split[0], args_passed, caller, "~#~");
}
}
protected virtual void CallCommandLib(string command, string arg)
{
CallCommandLib(command, arg, UUID.Zero);
}
protected virtual void CallCommandLib(string command, string arg, UUID caller)
{
CallCommandLib(command, arg, caller, "~#~");
}
protected virtual void CallCommandLib(string command, string arg, UUID caller,string signed_with)
{
if(custom_commands.ContainsKey(command) == false)
{
CommandsInterface.Call(command, arg, caller, signed_with);
}
else
{
Thread t = new Thread(() => custom_commands_loop(command, arg, caller));
t.Start();
}
}
public override void AfterBotLoginHandler() public override void AfterBotLoginHandler()
{ {
if (reconnect == false) if (reconnect == false)
{ {
CommandsInterface = new Commands.CoreCommandsInterface(this); loadCommands();
LoadCustomCommands();
} }
Client.Self.RequestBalance(); Client.Self.RequestBalance();
base.AfterBotLoginHandler(); base.AfterBotLoginHandler();
} }
protected override void CoreCommandLib(UUID fromUUID, bool from_accepted_avatar, string command, string arg, string signing_code, string signed_with)
{
if (CommandsInterface != null)
{
if (from_accepted_avatar == true)
{
CallCommandLib(command, arg, fromUUID, signed_with);
}
else if (signing_code != "")
{
string raw = "" + command + "" + arg + "" + myconfig.Security_SignedCommandkey + "";
string hashcheck = helpers.GetSHA1(raw);
if (hashcheck == signing_code)
{
CallCommandLib(command, arg, fromUUID, signed_with);
}
}
}
}
public void NotecardAddContent(string target_notecard_storage_id, string content) public void NotecardAddContent(string target_notecard_storage_id, string content)
{ {
NotecardAddContent(target_notecard_storage_id, content, true, "\n\r"); NotecardAddContent(target_notecard_storage_id, content, true, "\n\r");
@ -313,92 +234,234 @@ namespace BetterSecondBot.bottypes
); );
return returnstatus; return returnstatus;
} }
public void ScriptAddContent(string target_Script_storage_id, string content)
{
ScriptAddContent(target_Script_storage_id, content, true, "\n\r");
}
public void ScriptAddContent(string target_Script_storage_id, string content, bool add_newline)
{
ScriptAddContent(target_Script_storage_id, content, add_newline, "\n\r");
}
public void ScriptAddContent(string target_Script_storage_id, string content, bool add_newline, string newlinevalue)
{
if (Scripts_content.ContainsKey(target_Script_storage_id) == false)
{
Scripts_content.Add(target_Script_storage_id, "");
}
if (add_newline == true)
{
content = "" + newlinevalue + "" + content;
}
Scripts_content[target_Script_storage_id] = Scripts_content[target_Script_storage_id] + "" + content;
}
public string GetScriptContent(string target_Script_storage_id)
{
if (Scripts_content.ContainsKey(target_Script_storage_id) == true)
{
return Scripts_content[target_Script_storage_id];
}
return null;
}
public void ClearScriptStorage(string target_Script_storage_id)
{
if (Scripts_content.ContainsKey(target_Script_storage_id) == true)
{
Scripts_content.Remove(target_Script_storage_id);
}
}
public bool SendScript(string name, string content, UUID sendToUUID) protected Dictionary<string, WebApiControllerWithTokens> commandEndpoints = new Dictionary<string, WebApiControllerWithTokens>();
protected Dictionary<string, string> endpointcommandmap = new Dictionary<string, string>(); // command = endpoint
protected Dictionary<string, string> commandnameLowerToReal = new Dictionary<string, string>();
protected TokenStorage Tokens = new TokenStorage();
protected bool commandsLoaded = false;
protected override void BotChatControler(string message, string sender_name, UUID sender_uuid, bool avatar, bool group, UUID group_uuid, bool localchat, bool fromme)
{ {
bool returnstatus = true; base.BotChatControler(message, sender_name, sender_uuid, avatar, group, group_uuid, localchat, fromme);
Client.Inventory.RequestCreateItem( if ((group == false) && (localchat == false) && (fromme == false))
Client.Inventory.FindFolderForType(AssetType.LSLText), {
name, string signing_code = "";
name, string[] input = message.Split(new[] { "@@@" }, StringSplitOptions.RemoveEmptyEntries);
AssetType.LSLText, if (input.Count() == 2)
UUID.Random(), {
InventoryType.LSL, message = input[0];
PermissionMask.All, signing_code = input[1];
(bool Success, InventoryItem item) => }
List<string> bits = message.Split(new[] { "|||" }, StringSplitOptions.RemoveEmptyEntries).ToList();
if (bits.Count == 1)
{
bits.Add("");
}
if (bits.Count == 2)
{
bits.Add("none");
}
bool frommaster = false;
if ((avatar == true) && ((sender_uuid == master_uuid) || (SubMasters.Contains(sender_name) == true)))
{
frommaster = true;
}
CoreCommandLib(sender_uuid, frommaster, bits[0], bits[1].Split("~#~"), signing_code,bits[2]);
}
}
protected KeyValuePair<bool,string> callAPIcommand(string command, string[] args)
{
command = commandnameLowerToReal[command.ToLowerInvariant()];
try
{
string ott = Tokens.OneTimeToken();
WebApiControllerWithTokens Endpoint = commandEndpoints[endpointcommandmap[command]];
MethodInfo theMethod = Endpoint.GetType().GetMethod(command);
List<string> argsList = args.ToList();
argsList.Add(ott);
string reply = "Inconnect number of args";
bool status = false;
if (argsList.Count == theMethod.GetParameters().Count())
{
status = true;
object processed = theMethod.Invoke(Endpoint, argsList.ToArray<object>());
reply = JsonConvert.SerializeObject(processed);
}
return new KeyValuePair<bool, string>(status, reply);
}
catch (Exception e)
{
return new KeyValuePair<bool, string>(false, e.Message);
}
}
protected void CoreCommandLib(UUID sender, bool Master, string command, string[] args, string signingcode, string targetreply)
{
bool accepted = Master;
if(accepted == false)
{
string raw = "" + command + "" + string.Join("~#~", args) + "" + myconfig.Security_SignedCommandkey + "";
string hashcheck = helpers.GetSHA1(raw);
if (hashcheck == signingcode)
{
accepted = true;
}
}
if (accepted == true)
{
CallAPI(command, args, targetreply);
}
}
public void CallAPI(string command, string[] args)
{
CallAPI(command, args, "None");
}
public void CallAPI(string command, string[] args, string replyvia)
{
CallAPI(command, args, replyvia, false);
}
public void CallAPI(string command, string[] args, string replyvia, bool customcommand)
{
if(commandnameLowerToReal.ContainsKey(command.ToLowerInvariant()) == false)
{
if (custom_commands.ContainsKey(command) == false)
{
SmartCommandReply(false, replyvia, "Unknown command", command);
return;
}
if(customcommand == true)
{
SmartCommandReply(false, replyvia, "Custom command lockout", command);
return;
}
foreach (string A in custom_commands[command])
{
List<string> command_args_split = A.Split(new[] { "|||" }, StringSplitOptions.RemoveEmptyEntries).ToList();
int loop = 1;
string args_passed = "";
if (command_args_split.Count() == 2)
{
args_passed = command_args_split[1];
while ((loop <= 5) && (loop <= args.Length))
{
args_passed = args_passed.Replace("[C_ARG_" + loop.ToString() + "]", args[loop - 1]);
loop++;
}
}
CallAPI(command_args_split[0], args_passed.Split("~#~"),"None",true);
}
return;
}
KeyValuePair<bool, string> statusreply = callAPIcommand(command, args);
SmartCommandReply(statusreply.Key, replyvia, statusreply.Value, command);
}
protected HttpClient HTTPclient = new HttpClient();
protected void SmartCommandReply(bool run_status, string target, string output, string command)
{
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
{
if (int.TryParse(target, out target_channel) == false)
{ {
if (Success) mode = "None";
{
AssetScriptText empty = new AssetScriptText { Source = "\n" };
empty.Encode();
Client.Inventory.RequestUpdateScriptAgentInventory(new byte[] { }, item.UUID, true,
(bool uploadSuccess, string uploadStatus, bool compileSuccess, List<string> compileMessages, UUID itemID, UUID assetID) =>
{
if (uploadSuccess)
{
empty.AssetData = Encoding.ASCII.GetBytes(content);
Client.Inventory.RequestUpdateScriptAgentInventory(empty.AssetData, itemID,true,
(bool finaluploadSuccess, string finaluploadStatus, bool finalcompileSuccess, List<string> finalcompileMessages, UUID finalitemID, UUID finalassetID) =>
{
if (finalcompileSuccess == false)
{
Warn("Script failed to compile, sending anyway.");
}
Client.Inventory.GiveItem(finalitemID, name, AssetType.LSLText, sendToUUID, false);
});
}
else
{
Crit("The fuck empty success Script create");
returnstatus = false;
}
});
}
else
{
Warn("Unable to find default Scripts folder");
returnstatus = false;
}
} }
); }
return returnstatus; if (mode == "CHAT")
{
if (target_channel >= 0)
{
Client.Self.Chat(output, target_channel, ChatType.Normal);
}
else
{
run_status = false;
LogFormater.Crit("[SmartReply] output Channel must be zero or higher");
}
}
else if (mode == "IM")
{
Client.Self.InstantMessage(target_avatar, output);
}
else if (mode == "HTTP")
{
Dictionary<string, string> values = new Dictionary<string, string>
{
{ "reply", output },
{ "command", command },
};
var content = new FormUrlEncodedContent(values);
try
{
HTTPclient.PostAsync(target, content);
}
catch (Exception e)
{
LogFormater.Crit("[SmartReply] HTTP failed: " + e.Message + "");
}
}
}
protected void loadCommands()
{
commandsLoaded = true;
Dictionary<string, Type> commandmodules = http_commands_helper.getCommandModules();
foreach (Type entry in commandmodules.Values)
{
LoadCommandEndpoint(entry);
}
}
protected virtual void LoadCommandEndpoint(Type endpointtype)
{
WebApiControllerWithTokens controler = (WebApiControllerWithTokens)Activator.CreateInstance(endpointtype, args: new object[] { this, Tokens });
controler.disableIPlockout();
commandEndpoints.Add(endpointtype.Name, controler);
foreach (MethodInfo M in endpointtype.GetMethods())
{
bool isCallable = false;
foreach (CustomAttributeData At in M.CustomAttributes)
{
if (At.AttributeType.Name == "RouteAttribute")
{
isCallable = true;
break;
}
}
if (isCallable == true)
{
if (endpointcommandmap.ContainsKey(M.Name) == true)
{
Warn("Namespace: "+endpointtype.Name+" / Command: " + M.Name + " already found in " + endpointcommandmap[M.Name]);
continue;
}
if(commandnameLowerToReal.ContainsKey(M.Name.ToLowerInvariant()) == true)
{
Warn("Namespace: " + endpointtype.Name + " / Command: " + M.Name + " already found in " + endpointcommandmap[M.Name]);
continue;
}
endpointcommandmap.Add(M.Name, endpointtype.Name);
commandnameLowerToReal.Add(M.Name.ToLowerInvariant(), M.Name);
}
}
} }
} }
} }

View file

@ -97,17 +97,17 @@ namespace BetterSecondBot.bottypes
string DialogMessage = "NewDialog###" + dialogID.ToString() + "###"+ Dmess + "###" + String.Join("~|~",e.ButtonLabels) + ""; string DialogMessage = "NewDialog###" + dialogID.ToString() + "###"+ Dmess + "###" + String.Join("~|~",e.ButtonLabels) + "";
if (RelayDialogsToChannel != 0) if (RelayDialogsToChannel != 0)
{ {
CommandsInterface.SmartCommandReply(true,RelayDialogsToChannel.ToString(), DialogMessage,"NewDialogNotice"); SmartCommandReply(true, RelayDialogsToChannel.ToString(), DialogMessage, "NewDialogNotice");
} }
if(RelayDialogsToAvatar != UUID.Zero) if(RelayDialogsToAvatar != UUID.Zero)
{ {
CommandsInterface.SmartCommandReply(true, RelayDialogsToAvatar.ToString(), DialogMessage, "NewDialogNotice"); SmartCommandReply(true, RelayDialogsToAvatar.ToString(), DialogMessage, "NewDialogNotice");
} }
if(RelayDialogsToHttp != null) if(RelayDialogsToHttp != null)
{ {
if (RelayDialogsToHttp.StartsWith("http") == true) if (RelayDialogsToHttp.StartsWith("http") == true)
{ {
CommandsInterface.SmartCommandReply(true, RelayDialogsToAvatar.ToString(), DialogMessage, "NewDialogNotice"); SmartCommandReply(true, RelayDialogsToHttp, DialogMessage, "NewDialogNotice");
} }
} }
} }

View file

@ -2,7 +2,6 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Text; using System.Text;
using BetterSecondBotShared.Static; using BetterSecondBotShared.Static;
using BetterSecondBot.Commands;
using OpenMetaverse; using OpenMetaverse;
using OpenMetaverse.Imaging; using OpenMetaverse.Imaging;
using OpenMetaverse.Packets; using OpenMetaverse.Packets;
@ -288,6 +287,8 @@ namespace BetterSecondBot.bottypes
return result; return result;
} }
long last_cleanup = 0;
protected void Cleanup_group_member_storage() protected void Cleanup_group_member_storage()
{ {
lock (group_members_storage) lock (group_members_storage)
@ -325,7 +326,6 @@ namespace BetterSecondBot.bottypes
if (dif > 30) if (dif > 30)
{ {
last_cleanup = helpers.UnixTimeNow(); last_cleanup = helpers.UnixTimeNow();
Cleanup_await_events();
Cleanup_group_member_storage(); Cleanup_group_member_storage();
} }
if (delay_group_fetch > 0) if (delay_group_fetch > 0)
@ -533,58 +533,5 @@ namespace BetterSecondBot.bottypes
Client.Groups.RequestCurrentGroups(); Client.Groups.RequestCurrentGroups();
} }
} }
protected void Cleanup_await_events()
{
long dif;
List<string> purge_event_ids = new List<string>();
foreach (KeyValuePair<string, long> CheckEvent in await_event_ages)
{
dif = last_cleanup - CheckEvent.Value;
if (dif > 240)
{
purge_event_ids.Add(CheckEvent.Key);
}
}
foreach (string eventid in purge_event_ids)
{
string listener = await_event_idtolistener[eventid];
await_event_idtolistener.Remove(eventid);
await_event_ages.Remove(eventid);
await_events[listener].Remove(eventid);
}
}
protected long last_cleanup;
protected Dictionary<string, Dictionary<string, KeyValuePair<CoreCommand, string[]>>> await_events = new Dictionary<string, Dictionary<string, KeyValuePair<CoreCommand, string[]>>>();
protected Dictionary<string, long> await_event_ages = new Dictionary<string, long>();
protected Dictionary<string, string> await_event_idtolistener = new Dictionary<string, string>();
protected int next_await_id = 1;
public bool CreateAwaitEventReply(string event_listener, CoreCommand command, string[] args)
{
string eventid = "" + event_listener + "" + next_await_id.ToString() + "";
next_await_id++;
if (await_events.ContainsKey(event_listener) == false)
{
await_events.Add(event_listener, new Dictionary<string, KeyValuePair<CoreCommand, string[]>>());
}
if (await_events[event_listener].ContainsKey(eventid) == false)
{
if (await_event_ages.ContainsKey(eventid) == false)
{
if (await_event_idtolistener.ContainsKey(eventid) == false)
{
await_events[event_listener].Add(eventid, new KeyValuePair<CoreCommand, string[]>(command, args));
await_event_ages.Add(eventid, helpers.UnixTimeNow());
await_event_idtolistener.Add(eventid, event_listener);
return true;
}
}
}
return false;
}
} }
} }

View file

@ -98,64 +98,6 @@ namespace BetterSecondBot.bottypes
} }
} }
} }
string signing_code = "";
string[] input = message.Split(new[] { "@@@" }, StringSplitOptions.RemoveEmptyEntries);
if (input.Count() == 2)
{
message = input[0];
signing_code = input[1];
}
List<string> bits = message.Split(new[] { "|||" }, StringSplitOptions.RemoveEmptyEntries).ToList();
if (bits.Count == 1)
{
bits.Add("");
}
string arg_signed_with = "~#~";
if (bits.Count > 2)
{
arg_signed_with = "|||";
List<string> newbits = new List<string>
{
bits[0]
};
StringBuilder B = new StringBuilder();
int loop = 1;
string addon = "";
while (loop < bits.Count)
{
B.Append(addon);
B.Append(bits[loop]);
addon = arg_signed_with;
loop++;
}
newbits.Add(B.ToString());
bits = newbits;
}
if (avatar == false)
{
CoreCommandLib(sender_uuid, false, bits.ElementAt(0), bits.ElementAt(1), signing_code, arg_signed_with);
}
else
{
bool run_command;
if (Is_avatar_master(sender_name) == true)
{
run_command = true;
}
else
{
run_command = Accept_action_from("command", sender_uuid);
if (run_command == true)
{
Remove_action_from("command", sender_uuid);
}
}
if (run_command == true)
{
CoreCommandLib(sender_uuid, true, bits.ElementAt(0), bits.ElementAt(1), signing_code, arg_signed_with);
}
}
} }
} }
} }

View file

@ -29,9 +29,10 @@ namespace BetterSecondBot.bottypes
started_friendship_hug = true; started_friendship_hug = true;
if (Client.Friends.FriendList.ContainsKey(master_uuid) == false) if (Client.Friends.FriendList.ContainsKey(master_uuid) == false)
{ {
CommandsInterface.Call("IM", String.Join("~#~", new string[] { myconfig.Security_MasterUsername, "Hello master, I am sending you a friend request now!" })); CallAPI("IM", new string[] { myconfig.Security_MasterUsername, "Hello master, I am sending you a friend request now!" });
} }
CommandsInterface.Call("FriendFullPerms", String.Join("~#~", new string[] { master_uuid.ToString(), "true" }), Client.Self.AgentID); CallAPI("FriendRequest", new string[] { master_uuid.ToString(), "true" });
CallAPI("FriendFullPerms", new string[] { master_uuid.ToString(), "true" });
} }
} }
@ -60,7 +61,7 @@ namespace BetterSecondBot.bottypes
{ {
if(E.AgentName == myconfig.Security_MasterUsername) if(E.AgentName == myconfig.Security_MasterUsername)
{ {
CommandsInterface.Call("FriendFullPerms", String.Join("~#~", new string[] { myconfig.Security_MasterUsername, "true" }), Client.Self.AgentID); CallAPI("FriendFullPerms", new string[] { myconfig.Security_MasterUsername, "true" });
} }
} }
} }

View file

@ -12,10 +12,21 @@ namespace BetterSecondBotShared.bottypes
{ {
public abstract class BasicBot public abstract class BasicBot
{ {
protected BasicBot() protected BasicBot()
{ {
LastStatusMessage = "No status"; LastStatusMessage = "No status";
} }
protected Dictionary<UUID, Group> mygroups = new Dictionary<UUID, Group>();
protected Dictionary<UUID, KeyValuePair<long, List<GroupRole>>> mygrouprolesstorage = new Dictionary<UUID, KeyValuePair<long, List<GroupRole>>>();
public Dictionary<UUID, Group> MyGroups { get { return mygroups; } }
public Dictionary<UUID, KeyValuePair<long, List<GroupRole>>> MyGroupRolesStorage { get { return mygrouprolesstorage; } }
protected GridClient Client;
public GridClient GetClient { get { return Client; } }
protected List<string> SubMasters = new List<string>(); protected List<string> SubMasters = new List<string>();
public bool Is_avatar_master(string name) public bool Is_avatar_master(string name)
{ {
@ -29,6 +40,33 @@ namespace BetterSecondBotShared.bottypes
} }
} }
protected bool running_in_docker = false;
public void AsDocker()
{
running_in_docker = true;
}
protected bool killMe;
protected JsonConfig myconfig;
public JsonConfig getMyConfig { get { return myconfig; } }
protected string version = "NotSet V1.0.0.0";
protected bool reconnect;
public string MyVersion { get { return version; } }
public string Name { get { return myconfig.Basic_BotUserName; } }
public string OwnerName { get { return myconfig.Security_MasterUsername; } }
public bool GetAllowFunds { get { return myconfig.Setting_AllowFunds; } }
public string LastStatusMessage { get; set; }
public virtual bool KillMe { get { return killMe; } }
protected bool teleported;
public void SetTeleported()
{
teleported = true;
}
protected Dictionary<string, string[]> custom_commands = new Dictionary<string, string[]>(); protected Dictionary<string, string[]> custom_commands = new Dictionary<string, string[]>();
public Dictionary<string, string[]> getCustomCommands { get { return custom_commands; } } public Dictionary<string, string[]> getCustomCommands { get { return custom_commands; } }
protected bool loaded_custom_commands = false; protected bool loaded_custom_commands = false;
@ -68,7 +106,7 @@ namespace BetterSecondBotShared.bottypes
try try
{ {
LoadedCommands = JsonConvert.DeserializeObject<JsonCommandsfile>(json); LoadedCommands = JsonConvert.DeserializeObject<JsonCommandsfile>(json);
foreach(string loaded in LoadedCommands.CustomCommands) foreach (string loaded in LoadedCommands.CustomCommands)
{ {
string[] bits = loaded.Split(new string[] { "!!!" }, StringSplitOptions.None); string[] bits = loaded.Split(new string[] { "!!!" }, StringSplitOptions.None);
if (bits.Length == 2) if (bits.Length == 2)
@ -99,49 +137,16 @@ namespace BetterSecondBotShared.bottypes
io.WriteJsonCommands(LoadedCommands, CommandsFile); io.WriteJsonCommands(LoadedCommands, CommandsFile);
} }
} }
if(custom_commands.Count > 0) if (custom_commands.Count > 0)
{ {
Info("Custom commands: " + custom_commands.Count.ToString()); Info("Custom commands: " + custom_commands.Count.ToString());
} }
} }
protected bool running_in_docker = false;
public void AsDocker()
{
running_in_docker = true;
}
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.Basic_BotUserName; } }
public string OwnerName { get { return myconfig.Security_MasterUsername; } }
public bool GetAllowFunds { get { return myconfig.Setting_AllowFunds; } }
public string LastStatusMessage { get; set; }
public virtual bool KillMe { get { return killMe; } }
protected bool teleported;
public void SetTeleported()
{
teleported = true;
}
protected Dictionary<UUID, Group> mygroups = new Dictionary<UUID, Group>();
protected Dictionary<UUID, KeyValuePair<long, List<GroupRole>>> mygrouprolesstorage = new Dictionary<UUID, KeyValuePair<long, List<GroupRole>>>();
public Dictionary<UUID, Group> MyGroups { get { return mygroups; } }
public Dictionary<UUID, KeyValuePair<long, List<GroupRole>>> MyGroupRolesStorage { get { return mygrouprolesstorage; } }
protected GridClient Client;
public GridClient GetClient { get { return Client; } }
public virtual void KillMePlease() public virtual void KillMePlease()
{ {
killMe = true; killMe = true;
Client.Network.BeginLogout(); Client.Network.BeginLogout();
} }
public virtual void Setup(JsonConfig config, string Version) public virtual void Setup(JsonConfig config, string Version)
{ {
@ -266,7 +271,7 @@ namespace BetterSecondBotShared.bottypes
{ {
Info("Recovery login: using home location"); Info("Recovery login: using home location");
Lp.Start = "home"; Lp.Start = "home";
} }
Lp.Start = myconfig.Basic_LoginLocation; Lp.Start = myconfig.Basic_LoginLocation;
@ -301,11 +306,6 @@ namespace BetterSecondBotShared.bottypes
protected string BasicBot_laststatus = ""; protected string BasicBot_laststatus = "";
public virtual string GetStatus() public virtual string GetStatus()
{ {
if (loaded_custom_commands == false)
{
loaded_custom_commands = true;
LoadCustomCommands();
}
string reply = "Info: No client"; string reply = "Info: No client";
if (Client != null) if (Client != null)
{ {
@ -322,14 +322,9 @@ namespace BetterSecondBotShared.bottypes
} }
} }
} }
} }
BasicBot_laststatus = reply;
if (reply != BasicBot_laststatus) return reply;
{
BasicBot_laststatus = reply;
return reply;
}
return "";
} }
protected virtual void LoginHandler(object o, LoginProgressEventArgs e) protected virtual void LoginHandler(object o, LoginProgressEventArgs e)
@ -379,29 +374,14 @@ namespace BetterSecondBotShared.bottypes
Debug("ChatInputHandler proc not overridden"); Debug("ChatInputHandler proc not overridden");
} }
protected virtual void CoreCommandLib(UUID fromUUID, bool from_accepted_avatar, string command, string arg)
{
CoreCommandLib(fromUUID, from_accepted_avatar, command, arg, "");
}
protected virtual void CoreCommandLib(UUID fromUUID, bool from_accepted_avatar, string command, string arg, string signing_code)
{
CoreCommandLib(fromUUID, from_accepted_avatar, command, arg, signing_code, "~#~");
}
protected virtual void CoreCommandLib(UUID fromUUID,bool from_accepted_avatar,string command,string arg,string signing_code,string signed_with)
{
Debug("CoreCommandLib proc not overridden");
}
public virtual void ResetAnimations() public virtual void ResetAnimations()
{ {
Debug("reset_animations not enabled at this level"); Debug("reset_animations not enabled at this level");
} }
public virtual void Warn(string message) public virtual void Warn(string message)
{ {
Log2File(LogFormater.Warn(message,false), ConsoleLogLogLevel.Warn); Log2File(LogFormater.Warn(message, false), ConsoleLogLogLevel.Warn);
} }
public virtual void Crit(string message) public virtual void Crit(string message)
{ {