Merge pull request #23 from Madpeterz/http-commands-as-core

Http commands as core
This commit is contained in:
Madpeterz 2021-02-18 10:34:44 +00:00 committed by GitHub
commit f324f9d707
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
236 changed files with 4726 additions and 9155 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

@ -25,7 +25,6 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="EmbedIO" Version="3.4.3" />
<PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.10.9" /> <PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.10.9" />
<PackageReference Include="MSBuildGitHash" Version="2.0.2"> <PackageReference Include="MSBuildGitHash" Version="2.0.2">
<PrivateAssets>all</PrivateAssets> <PrivateAssets>all</PrivateAssets>

View file

@ -18,7 +18,7 @@ namespace BetterSecondBot
LogFormater.Status("-> Getting config from Docker"); LogFormater.Status("-> Getting config from Docker");
JsonConfig Config = MakeJsonConfig.FromENV(); JsonConfig Config = MakeJsonConfig.FromENV();
Config = MakeJsonConfig.Http_config_check(Config); Config = MakeJsonConfig.Http_config_check(Config);
new DiscordTTS(Config,true); new Discord_super(Config,true);
} }
} }
} }

View file

@ -79,7 +79,7 @@ namespace BetterSecondBot
if(ok_to_try_start == true) if(ok_to_try_start == true)
{ {
Config = MakeJsonConfig.Http_config_check(Config); Config = MakeJsonConfig.Http_config_check(Config);
new DiscordTTS(Config, false); new Discord_super(Config, false);
} }
} }
} }

View file

@ -177,7 +177,7 @@ namespace BetterSecondBot.DiscordSupervisor
string display_topic = "" + channeltopictype + ":" + sender_id + ""; string display_topic = "" + channeltopictype + ":" + sender_id + "";
if (channelname == "interface") if (channelname == "interface")
{ {
display_topic = "Actions -> !clear, !commands, !help command or command"; display_topic = "Actions -> !clear, !commands";
} }
else if (channelname == "status") else if (channelname == "status")
{ {

View file

@ -1,77 +0,0 @@
using System;
using System.Collections.Generic;
using OpenMetaverse;
using Discord;
using BetterSecondBotShared.Static;
using Discord.WebSocket;
using System.Threading.Tasks;
using System.Linq;
using BetterSecondBotShared.Json;
namespace BetterSecondBot.DiscordSupervisor
{
public class DiscordTTS : Discord_super
{
public DiscordTTS(JsonConfig configfile, bool as_docker) : base(configfile, as_docker)
{
}
protected ITextChannel TTSchannel;
protected IGuild TTSDiscordServer;
protected override async Task<Task> DiscordClientReady()
{
await base.DiscordClientReady();
if (myconfig.DiscordTTS_Enable == true)
{
TTSDiscordServer = DiscordClient.GetGuild(myconfig.DiscordTTS_server_id);
if (TTSDiscordServer != null)
{
IGuildUser user = await TTSDiscordServer.GetCurrentUserAsync();
await user.ModifyAsync(x =>
{
x.Nickname = myconfig.DiscordTTS_Nickname;
});
FindTTsChannel();
}
}
return Task.CompletedTask;
}
protected async void FindTTsChannel()
{
if (myconfig.DiscordTTS_Enable == true)
{
TTSchannel = await FindTextChannel(TTSDiscordServer, myconfig.DiscordTTS_channel_name);
}
}
protected override async Task DiscordIMMessage(UUID sender_uuid, string sender_name, string message)
{
if (myconfig.DiscordTTS_Enable == true)
{
if ((helpers.notempty(sender_name) == true) && (helpers.notempty(message) == true))
{
if (sender_uuid.ToString() == myconfig.DiscordTTS_avatar_uuid)
{
if (TTSchannel == null)
{
FindTTsChannel();
}
if (TTSchannel != null)
{
await TTSchannel.SendMessageAsync(message, true);
}
}
else
{
await base.DiscordIMMessage(sender_uuid, sender_name, message);
}
}
}
else
{
await base.DiscordIMMessage(sender_uuid, sender_name, message);
}
}
}
}

View file

@ -92,64 +92,12 @@ namespace BetterSecondBot.DiscordSupervisor
{ {
if (message.Content == "!commands") if (message.Content == "!commands")
{ {
int counter = 0; string[] commands = controler.Bot.getFullListOfCommands();
string addon = ""; await SendMessageToChannelAsync("interface", string.Join("\n",commands)+ " \n For more details please see the wiki \n https://wiki.magicmadpeter.xyz/", "bot", UUID.Zero, "bot");
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)
{
string[] bits = message.Content.Split(' ');
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
{ {
await MarkMessage(message, "❌").ConfigureAwait(false);
output.Append("Unknown request: "); output.Append("Unknown request: ");
output.Append(message.Content); output.Append(message.Content);
await SendMessageToChannelAsync("interface", output.ToString(), "bot", UUID.Zero, "bot"); await SendMessageToChannelAsync("interface", output.ToString(), "bot", UUID.Zero, "bot");
@ -158,31 +106,16 @@ namespace BetterSecondBot.DiscordSupervisor
else else
{ {
string[] bits = message.Content.Split("|||"); string[] bits = message.Content.Split("|||");
string command = bits[0].ToLowerInvariant(); if(bits.Length >= 2)
bool known_command = controler.Bot.GetCommandsInterface.GetCommandsList().Contains(command);
if (known_command == false)
{ {
known_command = controler.Bot.getCustomCommands.ContainsKey(command); string target = "None";
if (bits.Length == 3)
{
target = bits[2];
} }
if (known_command == true) if (controler.Bot.getFullListOfCommands().Contains(bits[0].ToLowerInvariant()) == 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)
{ {
controler.Bot.CallAPI(bits[0], bits[1].Split("~#~"), target);
await MarkMessage(message, "✅").ConfigureAwait(false); await MarkMessage(message, "✅").ConfigureAwait(false);
} }
else else
@ -190,13 +123,7 @@ namespace BetterSecondBot.DiscordSupervisor
await MarkMessage(message, "❌").ConfigureAwait(false); await MarkMessage(message, "❌").ConfigureAwait(false);
} }
} }
else await MarkMessage(message, "❌").ConfigureAwait(false);
{
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");
}
} }
} }
} }
@ -217,7 +144,7 @@ namespace BetterSecondBot.DiscordSupervisor
else else
{ {
await MarkMessage(message, "⏳").ConfigureAwait(true); await MarkMessage(message, "⏳").ConfigureAwait(true);
Thread.Sleep(200); Thread.Sleep(400);
string[] bits = Chan.Topic.Split(':'); string[] bits = Chan.Topic.Split(':');
if (bits.Length >= 2) if (bits.Length >= 2)
{ {
@ -269,13 +196,13 @@ 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.CallAPI("Groupnotice", new string[] { Noticetitle, Noticemessage });
await MarkMessage(message, "✅"); await MarkMessage(message, "✅");
} }
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.CallAPI("Groupchat", new string[] { group.ToString(), message.Content });
await MarkMessage(message, "✅"); await MarkMessage(message, "✅");
} }
} }

View file

@ -60,32 +60,6 @@ namespace BetterSecondBot.DiscordSupervisor
{ {
if (fromme == false) if (fromme == false)
{ {
if (discord_group_relay == true)
{
// GroupChat Relay only
if (group == true)
{
if (myconfig.DiscordRelay_URL != "")
{
if ((myconfig.DiscordRelay_GroupUUID == group_uuid.ToString()) || (myconfig.DiscordRelay_GroupUUID == "*") || (myconfig.DiscordRelay_GroupUUID == "all"))
{
Group Gr = controler.Bot.MyGroups[group_uuid];
try
{
using var DWHclient = new DiscordWebhookClient(myconfig.DiscordRelay_URL);
string SendMessage = "(" + Gr.Name + ") @" + sender_name + ":" + message + "";
await DWHclient.SendMessageAsync(text: SendMessage).ConfigureAwait(false);
DWHclient.Dispose();
}
catch
{
controler.Bot.Info("Discord web hook has failed - marking as disabled untill next restart!");
myconfig.DiscordRelay_URL = "";
}
}
}
}
}
if (DiscordClientConnected == true) if (DiscordClientConnected == true)
{ {
if (avatar == true) if (avatar == true)

View file

@ -37,12 +37,9 @@ ENV Security_WebUIKey=''
ENV Setting_AllowRLV='false' ENV Setting_AllowRLV='false'
ENV Setting_AllowFunds='false' ENV Setting_AllowFunds='false'
ENV Setting_LogCommands='false' ENV Setting_LogCommands='false'
ENV Setting_RelayImToAvatarUUID=''
ENV Setting_DefaultSit_UUID='' ENV Setting_DefaultSit_UUID=''
ENV Setting_loginURI='secondlife' ENV Setting_loginURI='secondlife'
ENV DiscordRelay_URL=''
ENV DiscordRelay_GroupUUID=''
ENV DiscordFull_Enable='false' ENV DiscordFull_Enable='false'
ENV DiscordFull_Token='' ENV DiscordFull_Token=''
ENV DiscordFull_ServerID='' ENV DiscordFull_ServerID=''
@ -55,12 +52,6 @@ ENV Name2Key_Enable='false'
ENV Name2Key_Url='http://localhost:1234' ENV Name2Key_Url='http://localhost:1234'
ENV Name2Key_Key='magic' ENV Name2Key_Key='magic'
ENV DiscordTTS_Enable='false'
ENV DiscordTTS_server_id=''
ENV DiscordTTS_channel_name=''
ENV DiscordTTS_avatar_uuid=''
ENV DiscordTTS_Nickname=''
ENV Log2File_Enable='false' ENV Log2File_Enable='false'
ENV Log2File_Level=1 ENV Log2File_Level=1

View file

@ -1,47 +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;
namespace BetterSecondBot.HttpService
{
public class HttpApiLocalchat : WebApiControllerWithTokens
{
public HttpApiLocalchat(SecondBot mainbot, TokenStorage setuptokens) : base(mainbot, setuptokens) { }
[About("fetchs the last 20 localchat messages")]
[ReturnHints("array string")]
[Route(HttpVerbs.Get, "/localchathistory/{token}")]
public object localchatHistory(string token)
{
if (tokens.Allow(token, "chat", "localchathistory", getClientIP()) == true)
{
return BasicReply(JsonConvert.SerializeObject(bot.getLocalChatHistory()));
}
return BasicReply("Token not accepted");
}
[About("sends a message to localchat")]
[ArgHints("message", "URLARG", "the message to send")]
[ReturnHints("array string")]
[Route(HttpVerbs.Post, "/localchatsay/{token}")]
public object localchatSay(string token, [FormField] string message)
{
if (tokens.Allow(token, "chat", "localchatsay", getClientIP()) == true)
{
bot.GetCommandsInterface.Call("say", message);
return BasicReply(JsonConvert.SerializeObject(bot.getLocalChatHistory()));
}
return BasicReply("Token not accepted");
}
}
}

View file

@ -1,347 +0,0 @@
using BetterSecondBotShared.Json;
using BetterSecondBotShared.Static;
using BetterSecondBot.bottypes;
using OpenMetaverse;
using System.Threading.Tasks;
using EmbedIO;
using EmbedIO.Routing;
using EmbedIO.WebApi;
using System;
using System.Collections.Generic;
using Newtonsoft.Json;
namespace BetterSecondBot.HttpService
{
public class HttpApiCore : WebApiControllerWithTokens
{
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")]
[NeedsToken(false)]
[ReturnHints("A new token with full system scope")]
[ArgHints("authcode", "text", "the first 10 chars of SHA1(unixtime+WebUIkey)<br/>unixtime can be +- 30 of the bots time.")]
[ArgHints("unixtimegiven", "number", "the unixtime you made this request")]
[Route(HttpVerbs.Post, "/gettoken")]
public Object GetToken([FormField] string authcode, [FormField] string unixtimegiven)
{
long now = helpers.UnixTimeNow();
long dif = 0;
if(long.TryParse(unixtimegiven,out long given) == true)
{
dif = now - given;
now = given;
}
if((dif < 30) && (dif > -30))
{
var raw = now.ToString() + config.Security_WebUIKey;
string hash = helpers.GetSHA1(raw).Substring(0, 10);
if (hash == authcode)
{
string newtoken = tokens.CreateToken(getClientIP());
if(newtoken != null) return BasicReply(newtoken);
}
}
return BasicReply("Authcode not accepted");
}
[About("Gets the friendslist <br/>Formated as follows<br/>friendreplyobject<br/><ul><li>name: String</li><li>id: String</li><li>online: bool</li></ul>")]
[ReturnHints("array UUID = friendreplyobject")]
[Route(HttpVerbs.Get, "/friends/{token}")]
public object Friends(string token)
{
if (tokens.Allow(token, "core", "friends", getClientIP()) == true)
{
return BasicReply(bot.getJsonFriendlist());
}
return BasicReply("Token not accepted");
}
[About("uses the AutoPilot to move to a location")]
[ReturnHints("Error Unable to AutoPilot to location")]
[ReturnHints("Accepted")]
[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, "/walkto/{x}/{y}/{z}/{token}")]
public object WalkTo(string x, string y, string z, string token)
{
if (tokens.Allow(token, "core", "walkto", getClientIP()) == true)
{
bool status = bot.GetCommandsInterface.Call("AutoPilot", "<"+x+","+y+","+z+">");
if (status == true)
{
return BasicReply("Accepted");
}
return BasicReply("Error Unable to AutoPilot to location");
}
return BasicReply("Token not accepted");
}
[About("Attempts to play a gesture")]
[ReturnHints("Invaild gesture UUID for arg 1")]
[ReturnHints("Accepted")]
[ArgHints("gesture", "URLARG", "Inventory UUID of the gesture")]
[Route(HttpVerbs.Get, "/gesture/{gesture}/{token}")]
public object Gesture(string gesture, string token)
{
if (tokens.Allow(token, "core", "gesture", getClientIP()) == true)
{
bool status = bot.GetCommandsInterface.Call("PlayGesture", gesture);
if (status == true)
{
return BasicReply("Accepted");
}
return BasicReply("Error with gesture");
}
return BasicReply("Token not accepted");
}
[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 = bot.GetCommandsInterface.Call("Teleport", ""+region+"/" + x + "/" + y + "/" + z + "");
if (status == true)
{
return BasicReply("Accepted");
}
return BasicReply("Error Unable to Teleport to location");
}
return BasicReply("Token not accepted");
}
[About("Fetchs the regions map tile")]
[ReturnHints("Unable to find region")]
[ReturnHints("Texture UUID")]
[ArgHints("regionname", "URLARG", "the name of the region we are fetching")]
[Route(HttpVerbs.Get, "/regiontile/{regionname}/{token}")]
public object Regiontile(string regionname, string token)
{
if (tokens.Allow(token, "core", "regiontile", getClientIP()) == true)
{
if (bot.GetClient.Grid.GetGridRegion(regionname, GridLayerType.Objects, out GridRegion region))
{
return BasicReply(region.MapImageID.ToString());
}
else
{
return BasicReply("Unable to find region");
}
}
return BasicReply("Token not accepted");
}
[About("an improved version of near me with extra details<br/>NearMeDetails is a object formated as follows<br/><ul><li>id</li><li>name</li><li>x</li><li>y</li><li>z</li><li>range</li></ul>")]
[ReturnHints("array NearMeDetails")]
[ReturnHints("Error not in a sim")]
[Route(HttpVerbs.Get, "/nearmewithdetails/{token}")]
public object NearmeWithDetails(string token)
{
if (tokens.Allow(token, "core", "nearmewithdetails", getClientIP()) == true)
{
if (bot.GetClient.Network.CurrentSim != null)
{
List<NearMeDetails> BetterNearMe = new List<NearMeDetails>();
Dictionary<uint, Avatar> avcopy = bot.GetClient.Network.CurrentSim.ObjectsAvatars.Copy();
foreach (Avatar av in avcopy.Values)
{
if (av.ID != bot.GetClient.Self.AgentID)
{
NearMeDetails details = new NearMeDetails();
details.id = av.ID.ToString();
details.name = av.Name;
details.x = (int)Math.Round(av.Position.X);
details.y = (int)Math.Round(av.Position.Y);
details.z = (int)Math.Round(av.Position.Z);
details.range = (int)Math.Round(Vector3.Distance(av.Position, bot.GetClient.Self.SimPosition));
BetterNearMe.Add(details);
}
}
return BasicReply(JsonConvert.SerializeObject(BetterNearMe));
}
return BasicReply("Error not in a sim");
}
return BasicReply("Token not accepted");
}
[About("returns a list of all known avatars nearby")]
[ReturnHints("array UUID = Name")]
[ReturnHints("Error not in a sim")]
[Route(HttpVerbs.Get, "/nearme/{token}")]
public object Nearme(string token)
{
if (tokens.Allow(token, "core", "nearme", getClientIP()) == true)
{
if (bot.GetClient.Network.CurrentSim != null)
{
Dictionary<UUID, string> NearMe = new Dictionary<UUID, string>();
Dictionary<uint, Avatar> avcopy = bot.GetClient.Network.CurrentSim.ObjectsAvatars.Copy();
foreach (Avatar av in avcopy.Values)
{
if (av.ID != bot.GetClient.Self.AgentID)
{
NearMe.Add(av.ID, av.Name);
}
}
return BasicReply(JsonConvert.SerializeObject(NearMe));
}
return BasicReply("Error not in a sim");
}
return BasicReply("Token not accepted");
}
[About("Used to check HTTP connections")]
[ReturnHints("world")]
[NeedsToken(false)]
[Route(HttpVerbs.Get, "/hello")]
public object Hello()
{
return BasicReply("world");
}
[About("Removes the given token from the accepted token pool")]
[ReturnHints("Failed to remove token")]
[ReturnHints("ok")]
[Route(HttpVerbs.Get, "/logout/{token}")]
public object Logout(string token)
{
if (tokens.Allow(token, "core", "logout", getClientIP()) == true)
{
return tokens.Expire(token);
}
return BasicReply("Token not accepted");
}
[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, "core", "version", getClientIP()) == true)
{
return BasicReply(bot.MyVersion);
}
return BasicReply("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, "core", "name", getClientIP()) == true)
{
return BasicReply(bot.GetClient.Self.FirstName + " " + bot.GetClient.Self.LastName);
}
return BasicReply("Token not accepted");
}
[About("Fetchs the current region name")]
[ReturnHints("Regionname")]
[ReturnHints("Error not in a sim")]
[Route(HttpVerbs.Get, "/regionname/{token}")]
public object Regionname(string token)
{
if (tokens.Allow(token, "core", "regionname", getClientIP()) == true)
{
if(bot.GetClient.Network.CurrentSim != null)
{
return BasicReply(bot.GetClient.Network.CurrentSim.Name);
}
return BasicReply("Error not in a sim");
}
return BasicReply("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, "/location/{token}")]
public object Location(string token)
{
if (tokens.Allow(token, "core", "location", 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 BasicReply("Error not in a sim");
}
return BasicReply("Token not accepted");
}
[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 BasicReply("Failed");
}
return BasicReply("Auth not accepted");
}
return BasicReply("Token not accepted");
}
}
public class CommandLibCall
{
public string Command { get; set; }
public string[] Args { get; set; }
public string AuthCode { get; set; }
}
public class NearMeDetails
{
public string id { get; set; }
public string name { get; set; }
public int x { get; set; }
public int y { get; set; }
public int z { get; set; }
public int range { get; set; }
}
}

View file

@ -1,74 +0,0 @@
using BetterSecondBotShared.Json;
using BetterSecondBot.bottypes;
using EmbedIO;
using EmbedIO.Routing;
using System;
using Newtonsoft.Json;
using OpenMetaverse;
namespace BetterSecondBot.HttpService
{
public class HttpAPIEstate : WebApiControllerWithTokens
{
public HttpAPIEstate(SecondBot mainbot, TokenStorage setuptokens) : base(mainbot, setuptokens)
{
}
[About("Requests the estate banlist")]
[ReturnHints("")]
[Route(HttpVerbs.Get, "/banlist/{token}")]
public Object Banlist(string token)
{
if (tokens.Allow(token, "estate", "banlist", getClientIP()) == true)
{
return BasicReply(JsonConvert.SerializeObject(bot._lastUpdatedSimBlacklist));
}
return BasicReply("Token not accepted");
}
[About("Attempts to add/remove the avatar to/from the Estate banlist")]
[ReturnHints("Request accepted")]
[ReturnHints("Unable to find avatar UUID")]
[ReturnHints("Unable to process global value please use true or false")]
[ReturnHints("Not an estate manager on region {REGIONNAME}")]
[ArgHints("avatar", "URLARG", "the uuid avatar you wish to ban")]
[ArgHints("mode", "URLARG", "What action would you like to take<br/>Defaults to remove if not given \"add\"")]
[ArgHints("global", "URLARG", "if true this the ban/unban will be applyed to all estates the bot has access to")]
[Route(HttpVerbs.Get, "/update-banlist/{avatar}/{mode}/{global}/{token}")]
public Object UpdateBanlist(string avatar, string mode, string global, string token)
{
if (tokens.Allow(token, "estate", "banlist-add", getClientIP()) == true)
{
if(bot.GetClient.Network.CurrentSim.IsEstateManager == false)
{
return BasicReply("Not an estate manager on region "+ bot.GetClient.Network.CurrentSim.Name);
}
UUID avataruuid = UUID.Zero;
if(UUID.TryParse(avatar,out avataruuid) == false)
{
return BasicReply("Unable to find avatar UUID");
}
bool globalban = false;
if(bool.TryParse(global,out globalban) == false)
{
return BasicReply("Unable to process global value please use true or false");
}
if(mode != "add")
{
bot.GetClient.Estate.UnbanUser(avataruuid, globalban);
}
else
{
bot.GetClient.Estate.BanUser(avataruuid, globalban);
}
return BasicReply("Request accepted");
}
return BasicReply("Token not accepted");
}
}
}

View file

@ -1,201 +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 HttpApiGroup : WebApiControllerWithTokens
{
public HttpApiGroup(SecondBot mainbot, TokenStorage setuptokens) : base(mainbot, setuptokens) { }
[About("Checks if the given UUID is in the given group<br/>Note: if group membership data is more than 60 secs old this will return Updating<br/>Please wait and retry later")]
[ReturnHints("True|False")]
[ReturnHints("Updating")]
[ReturnHints("Unknown group")]
[ReturnHints("Invaild group UUID")]
[ReturnHints("Unable to find avatar UUID")]
[ArgHints("group", "URLARG", "the UUID of the group")]
[ArgHints("avatar", "URLARG", "the UUID of the avatar you wish to check with")]
[Route(HttpVerbs.Get, "/ismember/{group}/{avatar}/{token}")]
public object ismember(string group,string avatar,string token)
{
if (tokens.Allow(token, "groups", "ismember", getClientIP()) == true)
{
if (UUID.TryParse(group, out UUID groupuuid) == true)
{
if (bot.MyGroups.ContainsKey(groupuuid) == true)
{
if (bot.NeedReloadGroupData(groupuuid) == false)
{
UUID avataruuid = UUID.Zero;
if(UUID.TryParse(avatar,out avataruuid) == false)
{
string lookup = bot.FindAvatarName2Key(avatar);
if (UUID.TryParse(lookup, out avataruuid) == false)
{
return BasicReply("Unable to find avatar UUID");
}
}
bool status = bot.FastCheckInGroup(groupuuid, avataruuid);
return BasicReply(status.ToString());
}
bot.GetClient.Groups.RequestGroupMembers(groupuuid);
return BasicReply("Updating");
}
return BasicReply("Unknown group");
}
return BasicReply("Invaild group UUID");
}
return BasicReply("Token not accepted");
}
[About("fetchs a list of all groups known to the bot")]
[ReturnHints("array UUID=name")]
[Route(HttpVerbs.Get, "/listgroups/{token}")]
public object listgroups(string token)
{
if (tokens.Allow(token, "groups", "listgroups", getClientIP()) == true)
{
Dictionary<string, string> grouppackage = new Dictionary<string, string>();
foreach(KeyValuePair<UUID,Group> entry in bot.MyGroups)
{
grouppackage.Add(entry.Value.ID.ToString(), entry.Value.Name);
}
return BasicReply(JsonConvert.SerializeObject(grouppackage));
}
return BasicReply("Token not accepted");
}
[About("Requests the roles for the selected group<br/>Replys with GroupRoleDetails object formated as follows <ul><li>UpdateUnderway (Bool)</li><li>RoleDataAge (Int) [default -1]</li><li>Roles (KeyPair array of UUID=Name)</li></ul><br/>")]
[ReturnHints("GroupRoleDetails object")]
[ReturnHints("Group is not currently known")]
[ReturnHints("Invaild group UUID")]
[ReturnHints("Updating")]
[ArgHints("group", "URLARG", "the UUID of the group")]
[Route(HttpVerbs.Get, "/listgrouproles/{group}/{token}")]
public object listgrouproles(string group, string token)
{
if (tokens.Allow(token, "groups", "listgrouproles", getClientIP()) == true)
{
if (UUID.TryParse(group, out UUID groupuuid) == true)
{
if (bot.MyGroups.ContainsKey(groupuuid) == true)
{
GroupRoleDetails reply = new GroupRoleDetails();
reply.UpdateUnderway = false;
reply.RoleDataAge = -1;
reply.Roles = new Dictionary<string, string>();
if (bot.MyGroupRolesStorage.ContainsKey(groupuuid) == false)
{
reply.UpdateUnderway = true;
}
else
{
long dif = helpers.UnixTimeNow() - bot.MyGroupRolesStorage[groupuuid].Key;
reply.RoleDataAge = dif;
if (dif >= 120)
{
reply.UpdateUnderway = true;
}
foreach(GroupRole gr in bot.MyGroupRolesStorage[groupuuid].Value)
{
reply.Roles.Add(gr.ID.ToString(), gr.Name);
}
}
if(reply.UpdateUnderway == true)
{
bot.GetClient.Groups.RequestGroupRoles(groupuuid);
if (reply.Roles.Count == 0)
{
return BasicReply("Updating");
}
}
return BasicReply(JsonConvert.SerializeObject(reply));
}
return BasicReply("Group is not currently known");
}
return BasicReply("Invaild group UUID");
}
return BasicReply("Token not accepted");
}
[About("fetchs a list of all groups with unread messages")]
[ReturnHints("array UUID")]
[Route(HttpVerbs.Get, "/listgroupswithunread/{token}")]
public object listgroupswithunread(string token)
{
if (tokens.Allow(token, "groups", "listgroupswithunread", getClientIP()) == true)
{
return BasicReply(JsonConvert.SerializeObject(bot.UnreadGroupchatGroups()));
}
return BasicReply("Token not accepted");
}
[About("checks if there are any groups with unread messages")]
[ReturnHints("True|False")]
[Route(HttpVerbs.Get, "/haveunreadgroupchat/{token}")]
public object haveunreadgroupchat(string token)
{
if (tokens.Allow(token, "groups", "haveunreadgroupchat", getClientIP()) == true)
{
return BasicReply(bot.HasUnreadGroupchats().ToString());
}
return BasicReply("Token not accepted");
}
[About("fetchs the groupchat history")]
[ReturnHints("Group UUID invaild")]
[ReturnHints("Group Chat")]
[ArgHints("group", "URLARG", "the UUID of the group")]
[Route(HttpVerbs.Get, "/getgroupchat/{group}/{token}")]
public object getgroupchat(string group, string token)
{
if (tokens.Allow(token, "groups", "getgroupchat", getClientIP()) == true)
{
if (UUID.TryParse(group, out UUID groupUUID) == true)
{
return BasicReply(JsonConvert.SerializeObject(bot.GetGroupchat(groupUUID)));
}
return BasicReply("Group UUID invaild");
}
return BasicReply("Token not accepted");
}
[About("sends a message to the groupchat")]
[ArgHints("group", "URLARG", "UUID of the group")]
[ArgHints("message", "Text", "the message to send")]
[ReturnHints("Group UUID invaild")]
[ReturnHints("Processing")]
[Route(HttpVerbs.Post, "/sendgroupchat/{group}/{token}")]
public object sendgroupchat(string group, string token, [FormField] string message)
{
if (tokens.Allow(token, "groups", "sendgroupchat", getClientIP()) == true)
{
if (UUID.TryParse(group, out UUID groupUUID) == true)
{
bool status = bot.GetCommandsInterface.Call("Groupchat", group + "~#~" + message, UUID.Zero, "~#~");
return BasicReply("Processing");
}
return BasicReply("Group UUID invaild");
}
return BasicReply("Token not accepted");
}
}
public class GroupRoleDetails
{
public bool UpdateUnderway { get; set; }
public Dictionary<string,string> Roles { get; set; }
public long RoleDataAge = 0;
}
}

View file

@ -1,107 +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;
namespace BetterSecondBot.HttpService
{
public class HttpApiIM : WebApiControllerWithTokens
{
public HttpApiIM(SecondBot mainbot, TokenStorage setuptokens) : base(mainbot, setuptokens) { }
[About("gets a full list of all chat windows")]
[ReturnHints("array UUID = Name")]
[Route(HttpVerbs.Get, "/chatwindows/{token}")]
public object chatwindows(string token)
{
if (tokens.Allow(token, "im", "chatwindows", getClientIP()) == true)
{
return BasicReply(JsonConvert.SerializeObject(bot.GetIMChatWindowKeyNames()));
}
return BasicReply("Token not accepted");
}
[About("gets a list of chat windows with unread messages")]
[ReturnHints("array of UUID")]
[Route(HttpVerbs.Get, "/listwithunread/{token}")]
public object listwithunread(string group, string token)
{
if (tokens.Allow(token, "im", "listwithunread", getClientIP()) == true)
{
List<UUID> unreadimwindows = new List<UUID>();
foreach (UUID window in bot.IMChatWindows())
{
if (bot.ImChatWindowHasUnread(window) == true)
{
unreadimwindows.Add(window);
}
}
return BasicReply(JsonConvert.SerializeObject(unreadimwindows));
}
return BasicReply("Token not accepted");
}
[About("gets if there are any unread im messages at all")]
[ReturnHints("True|False")]
[Route(HttpVerbs.Get, "/haveunreadims/{token}")]
public object haveunreadims(string token)
{
if (tokens.Allow(token, "im", "haveunreadims", getClientIP()) == true)
{
bool reply = false;
foreach(UUID window in bot.IMChatWindows())
{
if(bot.ImChatWindowHasUnread(window) == true)
{
reply = true;
break;
}
}
return BasicReply(reply.ToString());
}
return BasicReply("Token not accepted");
}
[About("gets the chat from the selected window")]
[ArgHints("window", "URLARG", "the UUID of the chat window")]
[ReturnHints("Window UUID invaild")]
[ReturnHints("Array of text")]
[Route(HttpVerbs.Get, "/getimchat/{window}/{token}")]
public object getimchat(string window, string token)
{
if (tokens.Allow(token, "im", "getimchat", getClientIP()) == true)
{
if (UUID.TryParse(window, out UUID windowUUID) == true)
{
return BasicReply(JsonConvert.SerializeObject(bot.GetIMChatWindow(windowUUID)));
}
return BasicReply("Window UUID invaild");
}
return BasicReply("Token not accepted");
}
[About("sends a im to the selected avatar")]
[ArgHints("avatar", "URLARG", "a UUID or Firstname Lastname")]
[ArgHints("message", "Text", "the message to send")]
[ReturnHints("ok")]
[Route(HttpVerbs.Post, "/sendimchat/{avatar}/{token}")]
public object sendimchat(string avatar, string token, [FormField] string message)
{
if (tokens.Allow(token, "im", "sendimchat", getClientIP()) == true)
{
bot.GetCommandsInterface.Call("im", avatar + "~#~" + message, UUID.Zero, "~#~");
return BasicReply("ok");
}
return BasicReply("Token not accepted");
}
}
}

View file

@ -1,151 +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 HttpApiInventory : WebApiControllerWithTokens
{
public HttpApiInventory(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, [FormField] string newname)
{
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("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,50 +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 static OpenMetaverse.ParcelManager;
namespace BetterSecondBot.HttpService
{
class HttpApiParcel : WebApiControllerWithTokens
{
public HttpApiParcel(SecondBot mainbot, TokenStorage setuptokens) : base(mainbot, setuptokens) { }
[About("Fetchs the parcel ban list of the parcel the bot is currently on<br/>If the name returned is lookup the bot is currently requesting the avatar name")]
[ReturnHints("array of UUID=Name")]
[ReturnHints("Error not in a sim")]
[ReturnHints("Parcel data not ready")]
[Route(HttpVerbs.Get, "/banlist/{token}")]
public object parcelbanlist(string token)
{
if (tokens.Allow(token, "parcel", "banlist", getClientIP()) == true)
{
if (bot.GetClient.Network.CurrentSim != null)
{
int localid = bot.GetClient.Parcels.GetParcelLocalID(bot.GetClient.Network.CurrentSim, bot.GetClient.Self.SimPosition);
Parcel targetparcel = null;
if (bot.GetClient.Network.CurrentSim.Parcels.ContainsKey(localid) == true)
{
targetparcel = bot.GetClient.Network.CurrentSim.Parcels[localid];
Dictionary<string, string> reply = new Dictionary<string, string>();
foreach (ParcelAccessEntry e in targetparcel.AccessBlackList)
{
string name = bot.FindAvatarKey2Name(e.AgentID);
reply.Add(e.AgentID.ToString(), name);
}
return BasicReply(JsonConvert.SerializeObject(reply));
}
return BasicReply("Parcel data not ready");
}
return BasicReply("Error not in a sim");
}
return BasicReply("Token not accepted");
}
}
}

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,16 +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);
// RLVapi
BetterSecondBot.RLV.RLVcontrol RLVapi = new BetterSecondBot.RLV.RLVcontrol(null);
api_reports.Add("RLVapi", new KeyValuePair<int, string>(RLVapi.ApiCommandsCount, "Limited"));
InterfaceWiki("RLVapi", RLVapi, true);
// HTTP // HTTP
HTTPWiki(); HTTPWiki();
@ -310,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");
@ -355,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)
@ -418,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);
@ -457,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);
@ -467,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>");
@ -486,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();
@ -526,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)
@ -558,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(HttpApiInventory)); foreach (KeyValuePair<string, Type> entry in commandmodules)
createEndpoint("im", typeof(HttpApiIM)); {
createEndpoint("groups", typeof(HttpApiGroup)); createEndpoint(entry.Key, entry.Value);
createEndpoint("chat", typeof(HttpApiLocalchat)); }
createEndpoint("parcel", typeof(HttpApiParcel));
createEndpoint("estate", typeof(HttpAPIEstate));
} }
public string getCommandMethod(string endpoint, string command) public string getCommandMethod(string endpoint, string command)

View file

@ -0,0 +1,79 @@
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;
namespace BetterSecondBot.HttpService
{
public class HTTP_Animation : WebApiControllerWithTokens
{
public HTTP_Animation(SecondBot mainbot, TokenStorage setuptokens) : base(mainbot, setuptokens) { }
[About("Toggles if animation requests from this avatar (used for remote poseballs) are accepted")]
[ReturnHints("Granted perm animation")]
[ReturnHints("Removed perm animation")]
[ReturnHints("avatar lookup")]
[ArgHints("avatar", "URLARG", "UUID (or Firstname Lastname)")]
[Route(HttpVerbs.Get, "/AddToAllowAnimations/{avatar}/{token}")]
public object AddToAllowAnimations(string avatar, string token)
{
if (tokens.Allow(token, "animation", "addtoallowanimations", handleGetClientIP()) == false)
{
return BasicReply("Token not accepted");
}
ProcessAvatar(avatar);
if (avataruuid == UUID.Zero)
{
return BasicReply("avatar lookup");
}
if (bot.Accept_action_from("animation", avataruuid) == false)
{
bot.Add_action_from("animation", avataruuid);
return BasicReply("Granted perm animation");
}
bot.Remove_action_from("animation", avataruuid, true);
return BasicReply("Removed perm animation");
}
[About("Attempts to play a gesture")]
[ReturnHints("Error with gesture")]
[ReturnHints("Accepted")]
[ArgHints("gesture", "URLARG", "Inventory UUID of the gesture")]
[Route(HttpVerbs.Get, "/PlayGesture/{gesture}/{token}")]
public object PlayGesture(string gesture, string token)
{
if (tokens.Allow(token, "animation", "gesture", handleGetClientIP()) == false)
{
return BasicReply("Token not accepted");
}
if (UUID.TryParse(gesture, out UUID gestureUUID) == false)
{
return BasicReply("Error with gesture");
}
InventoryItem itm = bot.GetClient.Inventory.FetchItem(gestureUUID, bot.GetClient.Self.AgentID, (3 * 1000));
bot.GetClient.Self.PlayGesture(itm.AssetUUID);
return BasicReply("Accepted");
}
[About("Resets the animation stack for the bot")]
[ReturnHints("Accepted")]
[Route(HttpVerbs.Get, "/ResetAnimations/{token}")]
public object ResetAnimations(string token)
{
if (tokens.Allow(token, "animation", "resetanimations", handleGetClientIP()) == false)
{
return BasicReply("Token not accepted");
}
bot.ResetAnimations();
return BasicReply("Accepted");
}
}
}

View file

@ -1,25 +0,0 @@
using OpenMetaverse;
namespace BetterSecondBot.Commands.Animation
{
public class PlayGesture : CoreCommand_1arg
{
public override string[] ArgTypes { get { return new[] { "UUID" }; } }
public override string[] ArgHints { get { return new[] { "The UUID of the gesture to play" }; } }
public override string Helpfile { get { return "Triggers a gesture [once]"; } }
public override bool CallFunction(string[] args)
{
if (base.CallFunction(args) == true)
{
if (UUID.TryParse(args[0], out UUID gesture) == true)
{
InventoryItem itm = bot.GetClient.Inventory.FetchItem(gesture, bot.GetClient.Self.AgentID, (3 * 1000));
bot.GetClient.Self.PlayGesture(itm.AssetUUID);
return true;
}
return Failed("Invaild gesture UUID for arg 1");
}
return false;
}
}
}

View file

@ -1,33 +0,0 @@
using OpenMetaverse;
namespace BetterSecondBot.Commands.Animation
{
public class AddToAllowAnimations : 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 "Toggles if animation requests from this avatar (used for remote poseballs) are accepted<br/>Case sensitive also requires Lastname"; } }
public override bool CallFunction(string[] args)
{
if(base.CallFunction(args) == true)
{
if(UUID.TryParse(args[0],out UUID avatar) == true)
{
if(bot.Accept_action_from("animation",avatar) == false)
{
bot.Add_action_from("animation", avatar);
InfoBlob = "Granted perm animation";
}
else
{
bot.Remove_action_from("animation", avatar,true);
InfoBlob = "Removed perm animation";
}
return true;
}
return Failed("Invaild avatar for arg 1");
}
return false;
}
}
}

View file

@ -1,12 +0,0 @@
namespace BetterSecondBot.Commands.Animation
{
public class ResetAnimations : CoreCommand
{
public override string Helpfile { get { return "Resets the animation stack for the bot"; } }
public override bool CallFunction(string[] args)
{
bot.ResetAnimations();
return true;
}
}
}

81
Core/Commands/Avatars.cs Normal file
View file

@ -0,0 +1,81 @@
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;
namespace BetterSecondBot.HttpService
{
public class HTTP_Avatars : WebApiControllerWithTokens
{
public HTTP_Avatars(SecondBot mainbot, TokenStorage setuptokens) : base(mainbot, setuptokens) { }
[About("an improved version of near me with extra details<br/>NearMeDetails is a object formated as follows<br/><ul><li>id</li><li>name</li><li>x</li><li>y</li><li>z</li><li>range</li></ul>")]
[ReturnHints("array NearMeDetails")]
[ReturnHints("Error not in a sim")]
[Route(HttpVerbs.Get, "/NearmeWithDetails/{token}")]
public object NearmeWithDetails(string token)
{
if (tokens.Allow(token, "avatars", "nearmewithdetails", handleGetClientIP()) == false)
{
return BasicReply("Token not accepted");
}
if (bot.GetClient.Network.CurrentSim == null)
{
return BasicReply("Error not in a sim");
}
List<NearMeDetails> BetterNearMe = new List<NearMeDetails>();
Dictionary<uint, Avatar> avcopy = bot.GetClient.Network.CurrentSim.ObjectsAvatars.Copy();
foreach (Avatar av in avcopy.Values)
{
if (av.ID != bot.GetClient.Self.AgentID)
{
NearMeDetails details = new NearMeDetails();
details.id = av.ID.ToString();
details.name = av.Name;
details.x = (int)Math.Round(av.Position.X);
details.y = (int)Math.Round(av.Position.Y);
details.z = (int)Math.Round(av.Position.Z);
details.range = (int)Math.Round(Vector3.Distance(av.Position, bot.GetClient.Self.SimPosition));
BetterNearMe.Add(details);
}
}
return BasicReply(JsonConvert.SerializeObject(BetterNearMe));
}
[About("returns a list of all known avatars nearby")]
[ReturnHints("array UUID = Name")]
[ReturnHints("Error not in a sim")]
[Route(HttpVerbs.Get, "/Nearme/{token}")]
public object Nearme(string token)
{
if (tokens.Allow(token, "avatars", "nearme", handleGetClientIP()) == false)
{
return BasicReply("Token not accepted");
}
if (bot.GetClient.Network.CurrentSim == null)
{
return BasicReply("Error not in a sim");
}
Dictionary<UUID, string> NearMe = new Dictionary<UUID, string>();
Dictionary<uint, Avatar> avcopy = bot.GetClient.Network.CurrentSim.ObjectsAvatars.Copy();
foreach (Avatar av in avcopy.Values)
{
if (av.ID != bot.GetClient.Self.AgentID)
{
NearMe.Add(av.ID, av.Name);
}
}
return BasicReply(JsonConvert.SerializeObject(NearMe));
}
}
}

View file

@ -1,35 +0,0 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.Linq;
using OpenMetaverse;
using Newtonsoft.Json;
namespace BetterSecondBot.Commands.Avatars
{
class RoleCreate : CoreCommand_SmartReply_1arg
{
public override string Helpfile { get { return "Gets a list of avatars near the bot"; } }
public override bool CallFunction(string[] args)
{
if (base.CallFunction(args) == true)
{
Dictionary<string, string> collection = new Dictionary<string, string>();
foreach(Avatar av in bot.GetClient.Network.CurrentSim.ObjectsAvatars.Copy().Values)
{
Vector3 pos = new Vector3(1, 1, 1);
if(bot.GetClient.Network.CurrentSim.AvatarPositions.ContainsKey(av.ID) == true)
{
pos = bot.GetClient.Network.CurrentSim.AvatarPositions[av.ID];
}
Dictionary<string, string> entrys = new Dictionary<string, string>();
entrys.Add("Username",av.Name);
entrys.Add("Pos", pos.X.ToString() + "," + pos.Y.ToString() + "," + pos.Z.ToString());
collection.Add(av.ID.ToString(), JsonConvert.SerializeObject(entrys));
}
return bot.GetCommandsInterface.SmartCommandReply(true, args[0], "ok", CommandName, collection);
}
return false;
}
}
}

View file

@ -1,40 +0,0 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.Linq;
using OpenMetaverse;
namespace BetterSecondBot.Commands.Avatars
{
public class PayAvatar : CoreCommand_2arg
{
public override string[] ArgTypes { get { return new[] { "Avatar", "Number" }; } }
public override string[] ArgHints { get { return new[] { "Avatar [UUID or Firstname Lastname]", "Amount to pay"}; } }
public override string Helpfile { get { return "Makes the bot pay a avatar"; } }
public override bool CallFunction(string[] args)
{
if (base.CallFunction(args) == true)
{
if (bot.GetAllowFunds == true)
{
if (UUID.TryParse(args[0], out UUID avataruuid) == true)
{
if (int.TryParse(args[1], out int amount) == true)
{
if (amount > 0)
{
bot.GetClient.Self.GiveAvatarMoney(avataruuid, amount);
return true;
}
}
return Failed("Invaild amount");
}
return Failed("Invaild avatar UUID");
}
return Failed("Transfer funds to avatars disabled");
}
return false;
}
}
}

90
Core/Commands/Chat.cs Normal file
View file

@ -0,0 +1,90 @@
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_Chat : WebApiControllerWithTokens
{
public HTTP_Chat(SecondBot mainbot, TokenStorage setuptokens) : base(mainbot, setuptokens) { }
[About("fetchs the last 20 localchat messages")]
[ReturnHints("array string")]
[Route(HttpVerbs.Get, "/LocalChatHistory/{token}")]
public object LocalChatHistory(string token)
{
if (tokens.Allow(token, "chat", "localchathistory", handleGetClientIP()) == false)
{
return Failure("Token not accepted");
}
return BasicReply(JsonConvert.SerializeObject(bot.getLocalChatHistory()));
}
[About("sends a message to localchat")]
[ArgHints("channel", "URLARG", "the channel to output on (>=0)")]
[ArgHints("message", "Text", "the message to send")]
[ReturnHints("array string")]
[ReturnHints("Message empty")]
[ReturnHints("Invaild channel")]
[Route(HttpVerbs.Post, "/Say/{channel}/{token}")]
public object Say(string channel,[FormField] string message,string token)
{
if (tokens.Allow(token, "chat", "localchatsay", handleGetClientIP()) == false)
{
return BasicReply("Token not accepted");
}
if (helpers.notempty(message) == false)
{
return BasicReply("Message empty");
}
if(int.TryParse(channel,out int channelnum) == false)
{
return BasicReply("Invaild channel");
}
if(channelnum < 0)
{
return BasicReply("Invaild channel");
}
bot.GetClient.Self.Chat(message, channelnum, ChatType.Normal);
return BasicReply(JsonConvert.SerializeObject(bot.getLocalChatHistory()));
}
[About("sends a im to the selected avatar")]
[ArgHints("avatar", "URLARG", "a UUID or Firstname Lastname")]
[ArgHints("message", "Text", "the message to send")]
[ReturnHints("ok")]
[ReturnHints("Message empty")]
[ReturnHints("avatar lookup")]
[Route(HttpVerbs.Post, "/IM/{avatar}/{token}")]
public object IM(string avatar, [FormField] string message, string token)
{
if (tokens.Allow(token, "chat", "im", handleGetClientIP()) == false)
{
return BasicReply("Token not accepted");
}
ProcessAvatar(avatar);
if(avataruuid == UUID.Zero)
{
return BasicReply("avatar lookup");
}
if (helpers.notempty(message) == false)
{
return BasicReply("Message empty");
}
bot.SendIM(avataruuid, message);
return BasicReply("ok");
}
}
}

View file

@ -1,19 +0,0 @@
using System.Linq;
using Newtonsoft.Json;
using OpenMetaverse;
namespace BetterSecondBot.Commands.Chat
{
class LocalChatHistory : CoreCommand_SmartReply_1arg
{
public override string Helpfile { get { return "Gets the last 20 localchat messages the bot has."; } }
public override bool CallFunction(string[] args)
{
if(base.CallFunction(args) == true)
{
return bot.GetCommandsInterface.SmartCommandReply(true, args[0], JsonConvert.SerializeObject(bot.getLocalChatHistory()), CommandName);
}
return false;
}
}
}

View file

@ -1,35 +0,0 @@
using OpenMetaverse;
using BetterSecondBotShared.Static;
namespace BetterSecondBot.Commands.Chat
{
class IM : CoreCommand_2arg
{
public override string[] ArgTypes { get { return new[] { "Avatar", "Text" }; } }
public override string[] ArgHints { get { return new[] { "Avatar [UUID or Firstname Lastname]","Message" }; } }
public override string Helpfile { get { return "Makes the bot send a IM to an avatar<br/>Example: IM|||289c3e36-69b3-40c5-9229-0c6a5d230766~#~Hello Mad I am a bot"; } }
public override bool CallFunction(string[] args)
{
if (base.CallFunction(args) == true)
{
if (UUID.TryParse(args[0], out UUID target_av) == true)
{
if (helpers.notempty(args[1]) == true)
{
bot.SendIM(target_av, args[1]);
return true;
}
else
{
return Failed("Arg 2 is empty");
}
}
else
{
return Failed("Not a vaild UUID");
}
}
return false;
}
}
}

View file

@ -1,44 +0,0 @@
using System.Linq;
using OpenMetaverse;
namespace BetterSecondBot.Commands.Chat
{
class Say : CoreCommand_1arg
{
public override string[] ArgTypes { get { return new[] { "Mixed","Text","Text" }; } }
public override string[] ArgHints { get { return new[] { "Message or channel","Message","Chat level" }; } }
public override string Helpfile { get { return "Makes the bot talk via chat<br/>Example: say|||Hello<br/>Example: say|||12~#~Goodbye<br/>Example: say|||12~#~Goodbye~#~Shout<br/>Chat levels [Arg 3]:<br/> Whisper<br/> Shout"; } }
public override bool CallFunction(string[] args)
{
if(base.CallFunction(args) == true)
{
string message = args[0];
int channel = 0;
ChatType ChatLevel = ChatType.Normal;
if (args.Count() >= 2)
{
message = args[1];
int.TryParse(args[0], out channel);
if (args.Count() == 3)
{
if (args[2] == "Shout")
{
ChatLevel = ChatType.Shout;
}
else if (args[2] == "Whisper")
{
ChatLevel = ChatType.Whisper;
}
}
}
if (channel == 0)
{
bot.AddToLocalChat(bot.GetClient.Self.Name, message);
}
bot.GetClient.Self.Chat(message, channel, ChatLevel);
return true;
}
return false;
}
}
}

108
Core/Commands/Core.cs Normal file
View file

@ -0,0 +1,108 @@
using BetterSecondBotShared.Json;
using BetterSecondBotShared.Static;
using BetterSecondBot.bottypes;
using OpenMetaverse;
using System.Threading.Tasks;
using EmbedIO;
using EmbedIO.Routing;
using EmbedIO.WebApi;
using System;
using System.Collections.Generic;
using Newtonsoft.Json;
using System.Threading;
namespace BetterSecondBot.HttpService
{
public class HTTP_Core : WebApiControllerWithTokens
{
public HTTP_Core(SecondBot mainbot, TokenStorage setuptokens) : base(mainbot, setuptokens) { }
[About("Requests a new token (Vaild for 10 mins) <br/>to use with all other requests")]
[NeedsToken(false)]
[ReturnHints("A new token with full system scope")]
[ArgHints("authcode", "text", "the first 10 chars of SHA1(unixtime+WebUIkey)<br/>unixtime can be +- 30 of the bots time.")]
[ArgHints("unixtimegiven", "number", "the unixtime you made this request")]
[Route(HttpVerbs.Post, "/GetToken")]
public Object GetToken([FormField] string authcode, [FormField] string unixtimegiven)
{
long now = helpers.UnixTimeNow();
long dif = 0;
if(long.TryParse(unixtimegiven,out long given) == true)
{
dif = now - given;
now = given;
}
if((dif < 30) && (dif > -30))
{
var raw = now.ToString() + bot.getMyConfig.Security_WebUIKey;
string hash = helpers.GetSHA1(raw).Substring(0, 10);
if (hash == authcode)
{
string newtoken = tokens.CreateToken(handleGetClientIP());
if(newtoken != null) return BasicReply(newtoken);
}
}
return Failure("Authcode not accepted");
}
[About("Used to check HTTP connections")]
[ReturnHints("world")]
[NeedsToken(false)]
[Route(HttpVerbs.Get, "/Hello")]
public object Hello()
{
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")]
[ReturnHints("Failed to remove token")]
[ReturnHints("ok")]
[Route(HttpVerbs.Get, "/LogoutUI/{token}")]
public object LogoutUI(string token)
{
if (tokens.Allow(token, "core", "LogoutUI", handleGetClientIP()) == false)
{
return Failure("Token not accepted");
}
return tokens.Expire(token);
}
}
public class CommandLibCall
{
public string Command { get; set; }
public string[] Args { get; set; }
public string AuthCode { get; set; }
}
public class NearMeDetails
{
public string id { get; set; }
public string name { get; set; }
public int x { get; set; }
public int y { get; set; }
public int z { get; set; }
public int range { get; set; }
}
}

99
Core/Commands/Dialogs.cs Normal file
View file

@ -0,0 +1,99 @@
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;
namespace BetterSecondBot.HttpService
{
public class HTTP_Dialogs : WebApiControllerWithTokens
{
public HTTP_Dialogs(SecondBot mainbot, TokenStorage setuptokens) : base(mainbot, setuptokens) { }
[About("Updates the relay target (you can have 1 of each type)<br/>Clear will disable them all")]
[ReturnHints("cleared")]
[ReturnHints("set/avatar")]
[ReturnHints("set/http")]
[ReturnHints("set/channel")]
[ReturnHints("Not a vaild option")]
[ArgHints("target","URLARG", "Options: Channel (Any number),Avatar UUID,HTTPurl<br/>Clear")]
[Route(HttpVerbs.Get, "/DialogRelay/{target}/{token}")]
public object DialogRelay(string target,string token)
{
if (tokens.Allow(token, "dialogs", "DialogRelay", handleGetClientIP()) == false)
{
return BasicReply("Token not accepted");
}
if (target == "clear")
{
bot.SetRelayDialogsAvatar(UUID.Zero);
bot.SetRelayDialogsChannel(0);
bot.SetRelayDialogsHTTP("");
return BasicReply("cleared");
}
ProcessAvatar(target);
if (avataruuid != UUID.Zero)
{
bot.SetRelayDialogsAvatar(avataruuid);
return BasicReply("set/avatar");
}
if (target.StartsWith("http") == true)
{
bot.SetRelayDialogsHTTP(target);
return BasicReply("set/http");
}
if (int.TryParse(target, out int channel) == true)
{
bot.SetRelayDialogsChannel(channel);
return BasicReply("set/channel");
}
return BasicReply("Not a vaild option");
}
[About("Makes the bot interact with the dialog [dialogid] with the button [buttontext]")]
[ReturnHints("true")]
[ReturnHints("false")]
[ReturnHints("bad dialog id")]
[ArgHints("target", "URLARG", "Options: Channel (Any number),Avatar UUID,HTTPurl<br/>Clear")]
[Route(HttpVerbs.Get, "/DialogResponce/{dialogid}/{buttontext}/{token}")]
public object DialogResponce(string dialogid, string buttontext, string token)
{
if (tokens.Allow(token, "dialogs", "DialogResponce", handleGetClientIP()) == false)
{
return BasicReply("Token not accepted");
}
if (int.TryParse(dialogid, out int dialogidnum) == false)
{
return BasicReply("bad dialog id");
}
return BasicReply(bot.DialogReply(dialogidnum, buttontext).ToString());
}
[About("Should the bot track dialogs and send them to the relays setup?")]
[ReturnHints("updated")]
[ReturnHints("bad status")]
[ArgHints("status", "URLARG", "true or false")]
[Route(HttpVerbs.Get, "/DialogTrack/{status}/{token}")]
public object DialogTrack(string status, string token)
{
if (tokens.Allow(token, "dialogs", "DialogTrack", handleGetClientIP()) == false)
{
return BasicReply("Token not accepted");
}
if (bool.TryParse(status, out bool statuscode) == false)
{
return BasicReply("bad status");
}
bot.SetTrackDialogs(statuscode);
return BasicReply("updated");
}
}
}

View file

@ -1,46 +0,0 @@
using OpenMetaverse;
namespace BetterSecondBot.Commands.Dialogs
{
class DialogRelay : CoreCommand_1arg
{
public override string[] ArgTypes { get { return new[] { "Smart" }; } }
public override string[] ArgHints { get { return new[] { "Channel (Any number),Avatar UUID,Avatar name,HTTPurl<br/>Clear" }; } }
public override string Helpfile { get { return "Updates the relay target (you can have 1 of each type)<br/>Clear will disable them all"; } }
public override bool CallFunction(string[] args)
{
if (base.CallFunction(args) == true)
{
if(args[0] != "Clear")
{
if (UUID.TryParse(args[0], out UUID avatar) == true)
{
bot.SetRelayDialogsAvatar(avatar);
}
else if (args[0].StartsWith("http") == true)
{
bot.SetRelayDialogsHTTP(args[0]);
}
else if (int.TryParse(args[0], out int channel) == true)
{
bot.SetRelayDialogsChannel(channel);
}
else
{
return Failed("Not a vaild option");
}
return true;
}
else
{
bot.SetRelayDialogsAvatar(UUID.Zero);
bot.SetRelayDialogsChannel(0);
bot.SetRelayDialogsHTTP("");
return true;
}
}
return false;
}
}
}

View file

@ -1,25 +0,0 @@
namespace BetterSecondBot.Commands.Dialogs
{
class DialogResponce : CoreCommand_2arg
{
public override string[] ArgTypes { get { return new[] { "Number","Text" }; } }
public override string[] ArgHints { get { return new[] { "DialogID","Button to click" }; } }
public override string Helpfile { get { return "Makes the bot interact with the dialog [ARG 1] with the button [ARG 2]"; } }
public override bool CallFunction(string[] args)
{
if (base.CallFunction(args) == true)
{
if (int.TryParse(args[0], out int dialogid) == true)
{
return bot.DialogReply(dialogid, args[1]);
}
else
{
return Failed("Invaild dialog id");
}
}
return false;
}
}
}

View file

@ -1,22 +0,0 @@
namespace BetterSecondBot.Commands.Dialogs
{
class DialogTrack : CoreCommand_1arg
{
public override string[] ArgTypes { get { return new[] { "True|False" }; } }
public override string[] ArgHints { get { return new[] { "Status" }; } }
public override string Helpfile { get { return "Should the bot track dialogs and send them to the relays setup?"; } }
public override bool CallFunction(string[] args)
{
if (base.CallFunction(args) == true)
{
if(bool.TryParse(args[0],out bool status) == true)
{
bot.SetTrackDialogs(status);
return true;
}
}
return false;
}
}
}

713
Core/Commands/Discord.cs Normal file
View file

@ -0,0 +1,713 @@
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 Discord.WebSocket;
using System.Threading.Tasks;
using Discord;
using BetterSecondBotShared.Static;
using Discord.Rest;
namespace BetterSecondBot.HttpService
{
public class HTTP_Discord : WebApiControllerWithTokens
{
public HTTP_Discord(SecondBot mainbot, TokenStorage setuptokens) : base(mainbot, setuptokens) { }
[About("Adds a discord server role to the selected member")]
[ReturnHints("Discord client not ready")]
[ReturnHints("true|false")]
[ArgHints("serverid","URLARG","the server id to apply this action to")]
[ArgHints("roleid", "URLARG", "the role id we are giving")]
[ArgHints("memberid", "URLARG", "who we are giving it to")]
[Route(HttpVerbs.Get, "/Discord_AddRole/{serverid}/{roleid}/{memberid}/{token}")]
public object Discord_AddRole(string serverid,string roleid,string memberid,string token)
{
if (tokens.Allow(token, "discord", "Discord_AddRole", handleGetClientIP()) == false)
{
return Failure("Token not accepted");
}
if (bot.discordReady() == false)
{
return Failure("Discord client not ready");
}
return BasicReply(addRoleToMember(serverid, roleid, memberid).Result.ToString());
}
[About("Adds the selected user to the ban list - Disallows rejoining untill they are removed from the list")]
[ReturnHints("Discord client not ready")]
[ReturnHints("Why empty")]
[ReturnHints("true|false")]
[ArgHints("serverid", "URLARG", "the server id to apply this action to")]
[ArgHints("memberid", "URLARG", "who we are giving it to")]
[ArgHints("why", "string", "why they are being banned")]
[Route(HttpVerbs.Post, "/Discord_BanMember/{serverid}/{memberid}/{token}")]
public object Discord_BanMember(string serverid, string memberid, [FormField] string why, string token)
{
if (tokens.Allow(token, "discord", "Discord_BanMember", handleGetClientIP()) == false)
{
return Failure("Token not accepted");
}
if (bot.discordReady() == false)
{
return Failure("Discord client not ready");
}
if (helpers.notempty(why) == false)
{
return Failure("Why empty");
}
return BasicReply(BanMember(serverid, memberid, why).Result.ToString());
}
[About("Clears messages on the server sent by the member in the last 13 days, 22hours 59mins")]
[ReturnHints("Discord client not ready")]
[ReturnHints("true|false")]
[ArgHints("serverid", "URLARG", "the server id to apply this action to")]
[ArgHints("memberid", "URLARG", "who we are giving it to")]
[Route(HttpVerbs.Get, "/Discord_BulkClear_Messages/{serverid}/{memberid}/{token}")]
public object Discord_BulkClear_Messages(string serverid, string memberid, string token)
{
if (tokens.Allow(token, "discord", "Discord_BulkClear_Messages", handleGetClientIP()) == false)
{
return Failure("Token not accepted");
}
if (bot.discordReady() == false)
{
return Failure("Discord client not ready");
}
return ClearMessages(serverid, memberid).Result;
}
[About("Sends a message directly to the user [They must be in the server]\n This command requires the SERVER MEMBERS INTENT found in discord app dev")]
[ReturnHints("Discord client not ready")]
[ReturnHints("true|false")]
[ArgHints("serverid", "URLARG", "the server id to apply this action to")]
[ArgHints("memberid", "URLARG", "who we are giving it to")]
[ArgHints("message", "Text", "what we are sending")]
[Route(HttpVerbs.Post, "/Discord_Dm_Member/{serverid}/{memberid}/{token}")]
public object Discord_Dm_Member(string serverid, string memberid, [FormField] string message, string token)
{
if (tokens.Allow(token, "discord", "Discord_Dm_Member", handleGetClientIP()) == false)
{
return Failure("Token not accepted");
}
if (bot.discordReady() == false)
{
return Failure("Discord client not ready");
}
return BasicReply(MessageMember(serverid, memberid, message).Result.ToString());
}
[About("Returns a list of members in a server \n collection is userid: username \n if the user has set a nickname: userid: nickname|username \n" +
" This command requires Discord full client mode enabled and connected\n !!!! This command also requires: Privileged Gateway Intents / " +
"SERVER MEMBERS INTENT set to true on the discord bot api area !!!")]
[ReturnHints("Discord client not ready")]
[ReturnHints("mixed array of userid: nickname|username or userid:username")]
[ArgHints("serverid", "URLARG", "the server id to apply this action to")]
[Route(HttpVerbs.Get, "/Discord_MembersList/{serverid}/{token}")]
public object Discord_MembersList(string serverid, string token)
{
if (tokens.Allow(token, "discord", "Discord_MembersList", handleGetClientIP()) == false)
{
return Failure("Token not accepted");
}
if (bot.discordReady() == false)
{
return Failure("Discord client not ready");
}
return ListMembers(serverid).Result;
}
[About("Sends a message to the selected channel - Optional TTS usage")]
[ReturnHints("Discord client not ready")]
[ReturnHints("true|false")]
[ArgHints("serverid", "URLARG", "the server id to apply this action to")]
[ArgHints("channelid", "URLARG", "the channel id to apply this action to")]
[ArgHints("tts", "URLARG", "shoud tts be enabled true or false")]
[ArgHints("message", "Text", "what we are sending")]
[Route(HttpVerbs.Post, "/Discord_MembersList/{serverid}/{tts}/{token}")]
public object Discord_MessageChannel(string serverid, string channelid, string tts, [FormField] string message, string token)
{
if (tokens.Allow(token, "discord", "Discord_MessageChannel", handleGetClientIP()) == false)
{
return Failure("Token not accepted");
}
if (bot.discordReady() == false)
{
return Failure("Discord client not ready");
}
if (helpers.notempty(message) == false)
{
return Failure("message empty");
}
return BasicReply(MessageChannel(serverid, channelid, message, tts).Result.ToString());
}
[About("Sends a message to the selected channel - Optional TTS usage")]
[ReturnHints("mixed array of userid: nickname|username or userid:username")]
[ReturnHints("Discord client not ready")]
[ArgHints("serverid", "URLARG", "the server id to apply this action to")]
[ArgHints("memberid", "URLARG", "who we are giving it to")]
[ArgHints("mode", "URLARG", "should we mute them \"true\" or unmute \"false\"")]
[Route(HttpVerbs.Get, "/Discord_MuteMember/{serverid}/{memberid}/{mode}/{token}")]
public object Discord_MuteMember(string serverid, string memberid, string mode, string token)
{
if (tokens.Allow(token, "discord", "Discord_MuteMember", handleGetClientIP()) == false)
{
return Failure("Token not accepted");
}
if (bot.discordReady() == false)
{
return Failure("Discord client not ready");
}
return BasicReply(MuteMember(serverid, memberid, mode).Result.ToString());
}
[About("returns a collection of settings for the given role \n This command requires Discord full client mode enabled and connected")]
[ReturnHints("KeyPair of status: KeyPair[] item = value")]
[ReturnHints("Discord client not ready")]
[ArgHints("serverid", "URLARG", "the server id to apply this action to")]
[ArgHints("memberid", "URLARG", "who we are giving it to")]
[ArgHints("mode", "URLARG", "should we mute them \"true\" or unmute \"false\"")]
[Route(HttpVerbs.Get, "/Discord_Role_GetSettings/{serverid}/{roleid}/{token}")]
public object Discord_Role_GetSettings(string serverid, string roleid, string token)
{
if (tokens.Allow(token, "discord", "Discord_Role_GetSettings", handleGetClientIP()) == false)
{
return Failure("Token not accepted");
}
if (bot.discordReady() == false)
{
return Failure("Discord client not ready");
}
return RoleSettings(serverid,roleid);
}
[About("Updates perm flags for the selected role \n example CSV format: Speak=True,SendMessages=False \n for a full list of perms see output of Discord_Role_GetSettings \n" +
" This command requires Discord full client mode enabled and connected")]
[ReturnHints("true|false")]
[ReturnHints("Discord client not ready")]
[ArgHints("serverid", "URLARG", "the server id to apply this action to")]
[ArgHints("roleid", "URLARG", "who we are giving it to")]
[ArgHints("flagscsv", "Text", "what we are setting")]
[Route(HttpVerbs.Post, "/Discord_Role_UpdatePerms/{serverid}/{roleid}/{token}")]
public object Discord_Role_UpdatePerms(string serverid, string roleid, [FormField] string flagscsv, string token)
{
if (tokens.Allow(token, "discord", "Discord_Role_UpdatePerms", handleGetClientIP()) == false)
{
return Failure("Token not accepted");
}
if (bot.discordReady() == false)
{
return Failure("Discord client not ready");
}
return BasicReply(UpdateRolePerms(serverid, roleid, flagscsv).Result.ToString());
}
[About("Updates perm flags for the selected role \n example CSV format: Speak=True,SendMessages=False \n for a full list of perms see output of Discord_Role_GetSettings \n" +
" This command requires Discord full client mode enabled and connected")]
[ReturnHints("KeyPair of statusmessage=roleid or 0")]
[ReturnHints("Discord client not ready")]
[ArgHints("serverid", "URLARG", "the server id to apply this action to")]
[ArgHints("role", "URLARG", "the name of the role we are creating")]
[Route(HttpVerbs.Get, "/Discord_RoleCreate/{serverid}/{role}/{token}")]
public object Discord_RoleCreate(string serverid, string role, string token)
{
if (tokens.Allow(token, "discord", "Discord_RoleCreate", handleGetClientIP()) == false)
{
return Failure("Token not accepted");
}
if (bot.discordReady() == false)
{
return Failure("Discord client not ready");
}
return CreateRole(serverid,role).Result;
}
[About("Returns a list of roles and their ids in collection \n This command requires Discord full client mode enabled and connected")]
[ReturnHints("KeyPair of status: KeyPair of roleid: rolename")]
[ReturnHints("Discord client not ready")]
[ArgHints("serverid", "URLARG", "the server id to apply this action to")]
[Route(HttpVerbs.Get, "/Discord_RoleList/{serverid}/{token}")]
public object Discord_RoleList(string serverid, string token)
{
if (tokens.Allow(token, "discord", "Discord_RoleList", handleGetClientIP()) == false)
{
return Failure("Token not accepted");
}
if (bot.discordReady() == false)
{
return Failure("Discord client not ready");
}
return BasicReply(ListRoles(serverid).ToString());
}
[About("Remove a role from a server \n This command requires Discord full client mode enabled and connected")]
[ReturnHints("true|false")]
[ReturnHints("Discord client not ready")]
[ArgHints("serverid", "URLARG", "the server id to apply this action to")]
[Route(HttpVerbs.Get, "/Discord_RoleRemove/{serverid}/{roleid}/{token}")]
public object Discord_RoleRemove(string serverid, string roleid, string token)
{
if (tokens.Allow(token, "discord", "Discord_RoleRemove", handleGetClientIP()) == false)
{
return Failure("Token not accepted");
}
if (bot.discordReady() == false)
{
return Failure("Discord client not ready");
}
return BasicReply(RemoveRole(serverid, roleid).Result.ToString());
}
[About("Returns a list of text channels in a server")]
[ReturnHints("array of channelid: name")]
[ReturnHints("Discord client not ready")]
[ArgHints("serverid", "URLARG", "the server id to apply this action to")]
[Route(HttpVerbs.Get, "/Discord_TextChannels_List/{serverid}/{roleid}/{token}")]
public object Discord_TextChannels_List(string serverid, string token)
{
if (tokens.Allow(token, "discord", "Discord_TextChannels_List", handleGetClientIP()) == false)
{
return Failure("Token not accepted");
}
if (bot.discordReady() == false)
{
return Failure("Discord client not ready");
}
return ListTextChannels(serverid);
}
#region discord helper functions
protected KeyValuePair<bool, Dictionary<string, string>> ListTextChannels(string givenserverid)
{
DiscordSocketClient Discord = bot.getDiscordClient();
if (ulong.TryParse(givenserverid, out ulong serverid) == true)
{
return new KeyValuePair<bool, Dictionary<string, string>>(false, new Dictionary<string, string>());
}
SocketGuild server = Discord.GetGuild(serverid);
Dictionary<string, string> textChannels = new Dictionary<string, string>();
foreach (SocketTextChannel channel in server.TextChannels)
{
textChannels.Add(channel.Id.ToString(), channel.Name);
}
return new KeyValuePair<bool, Dictionary<string, string>>(true, textChannels);
}
protected async Task<bool> RemoveRole(string givenserverid, string givenroleid)
{
DiscordSocketClient Discord = bot.getDiscordClient();
if (ulong.TryParse(givenserverid, out ulong serverid) == false)
{
return false;
}
if (ulong.TryParse(givenroleid, out ulong roleid) == false)
{
return false;
}
SocketGuild server = Discord.GetGuild(serverid);
SocketRole role = server.GetRole(roleid);
await role.DeleteAsync().ConfigureAwait(true);
return true;
}
protected KeyValuePair<bool, Dictionary<string, string>> ListRoles(string givenserverid)
{
DiscordSocketClient Discord = bot.getDiscordClient();
if (ulong.TryParse(givenserverid, out ulong serverid) == false)
{
return new KeyValuePair<bool, Dictionary<string, string>>(false, new Dictionary<string, string>());
}
SocketGuild server = Discord.GetGuild(serverid);
Dictionary<string, string> rolesList = new Dictionary<string, string>();
foreach (SocketRole role in server.Roles)
{
rolesList.Add(role.Id.ToString(), role.Name);
}
return new KeyValuePair<bool, Dictionary<string, string>>(true, rolesList);
}
protected async Task<KeyValuePair<string, ulong>> CreateRole(string givenserverid, string givenrole)
{
DiscordSocketClient Discord = bot.getDiscordClient();
if (ulong.TryParse(givenserverid, out ulong serverid) == true)
{
return new KeyValuePair<string, ulong>("Unable to process server id", 0);
}
SocketGuild server = Discord.GetGuild(serverid);
RestRole role = await server.CreateRoleAsync(givenrole, new GuildPermissions(), Color.DarkRed, false, null).ConfigureAwait(true);
return new KeyValuePair<string, ulong>("ok", role.Id);
}
protected async Task<bool> UpdateRolePerms(string givenserverid,string givenroleid,string givenflagscsv)
{
DiscordSocketClient Discord = bot.getDiscordClient();
if (ulong.TryParse(givenserverid, out ulong serverid) == false)
{
return false;
}
if (ulong.TryParse(givenroleid, out ulong roleid) == true)
{
return false;
}
SocketGuild server = Discord.GetGuild(serverid);
SocketRole role = server.GetRole(roleid);
string[] bits = givenflagscsv.Split(',');
GuildPermissions NewPerms = role.Permissions;
foreach (String bit in bits)
{
string[] subbits = bit.Split('=');
if (subbits.Length == 2)
{
if (bool.TryParse(subbits[1], out bool flagValue) == true)
{
NewPerms = UpdateFlag(NewPerms, subbits[0], flagValue);
}
}
}
await role.ModifyAsync(Rp =>
{
Rp.Permissions = NewPerms;
}).ConfigureAwait(true);
return true;
}
protected GuildPermissions UpdateFlag(GuildPermissions NewPerms, string flag, bool flagValue)
{
switch (flag)
{
case "CreateInstantInvite":
NewPerms = NewPerms.Modify(flagValue);
break;
case "KickMembers":
NewPerms = NewPerms.Modify(null, flagValue);
break;
case "BanMembers":
NewPerms = NewPerms.Modify(null, null, flagValue);
break;
case "Administrator":
NewPerms = NewPerms.Modify(null, null, null, flagValue);
break;
case "ManageChannels":
NewPerms = NewPerms.Modify(null, null, null, null, flagValue);
break;
case "ManageGuild":
NewPerms = NewPerms.Modify(null, null, null, null, null, flagValue);
break;
case "AddReactions":
NewPerms = NewPerms.Modify(null, null, null, null, null, null, flagValue);
break;
case "ViewAuditLog":
NewPerms = NewPerms.Modify(null, null, null, null, null, null, null, flagValue);
break;
case "SendTTSMessages":
NewPerms = NewPerms.Modify(null, null, null, null, null, null, null, null, null, null, null, flagValue);
break;
case "AttachFiles":
NewPerms = NewPerms.Modify(null, null, null, null, null, null, null, null, null, null, null, null, null, null, flagValue);
break;
case "ReadMessageHistory":
NewPerms = NewPerms.Modify(null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, flagValue);
break;
case "MentionEveryone":
NewPerms = NewPerms.Modify(null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, flagValue);
break;
case "UseExternalEmojis":
NewPerms = NewPerms.Modify(null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, flagValue);
break;
case "Connect":
NewPerms = NewPerms.Modify(null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, flagValue);
break;
case "Speak":
NewPerms = NewPerms.Modify(null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, flagValue);
break;
case "MuteMembers":
NewPerms = NewPerms.Modify(null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, flagValue);
break;
case "UseVAD":
NewPerms = NewPerms.Modify(null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, flagValue);
break;
case "MoveMembers":
NewPerms = NewPerms.Modify(null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, flagValue);
break;
case "EmbedLinks":
NewPerms = NewPerms.Modify(null, null, null, null, null, null, null, null, null, null, null, null, null, flagValue);
break;
case "PrioritySpeaker":
NewPerms = NewPerms.Modify(null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, flagValue);
break;
case "Stream":
NewPerms = NewPerms.Modify(null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, flagValue);
break;
case "ChangeNickname":
NewPerms = NewPerms.Modify(null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, flagValue);
break;
case "ManageNicknames":
NewPerms = NewPerms.Modify(null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, flagValue);
break;
case "ManageRoles":
NewPerms = NewPerms.Modify(null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, flagValue);
break;
case "DeafenMembers":
NewPerms = NewPerms.Modify(null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, flagValue);
break;
case "ManageMessages":
NewPerms = NewPerms.Modify(null, null, null, null, null, null, null, null, null, null, null, null, flagValue);
break;
case "ViewChannel":
NewPerms = NewPerms.Modify(null, null, null, null, null, null, null, null, null, flagValue);
break;
case "SendMessages":
NewPerms = NewPerms.Modify(null, null, null, null, null, null, null, null, null, null, flagValue);
break;
case "ManageWebhooks":
NewPerms = NewPerms.Modify(null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, flagValue);
break;
case "ManageEmojis":
NewPerms = NewPerms.Modify(null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, flagValue);
break;
default:
break;
}
return NewPerms;
}
protected KeyValuePair<bool, Dictionary<string, string>> RoleSettings(string givenserverid, string givenroleid)
{
DiscordSocketClient Discord = bot.getDiscordClient();
if (ulong.TryParse(givenserverid, out ulong serverid) == false)
{
return new KeyValuePair<bool, Dictionary<string, string>>(false, new Dictionary<string, string>());
}
if (ulong.TryParse(givenroleid, out ulong roleid) == false)
{
return new KeyValuePair<bool, Dictionary<string, string>>(false, new Dictionary<string, string>());
}
SocketGuild server = Discord.GetGuild(serverid);
SocketRole role = server.GetRole(roleid);
Dictionary<string, string> settings = new Dictionary<string, string>
{
{ "Config|Color", String.Join(",", new byte[3] { role.Color.R, role.Color.G, role.Color.B }) },
{ "Config|Name", role.Name },
{ "Info|AssignedCount", role.Members.ToString() },
{ "Perm|AttachFiles", role.Permissions.AttachFiles.ToString() },
{ "Perm|ReadMessageHistory", role.Permissions.ReadMessageHistory.ToString() },
{ "Perm|MentionEveryone", role.Permissions.MentionEveryone.ToString() },
{ "Perm|UseExternalEmojis", role.Permissions.UseExternalEmojis.ToString() },
{ "Perm|Connect", role.Permissions.Connect.ToString() },
{ "Perm|Speak", role.Permissions.Speak.ToString() },
{ "Perm|MuteMembers", role.Permissions.MuteMembers.ToString() },
{ "Perm|UseVAD", role.Permissions.UseVAD.ToString() },
{ "Perm|MoveMembers", role.Permissions.MoveMembers.ToString() },
{ "Perm|EmbedLinks", role.Permissions.EmbedLinks.ToString() },
{ "Perm|PrioritySpeaker", role.Permissions.PrioritySpeaker.ToString() },
{ "Perm|Stream", role.Permissions.Stream.ToString() },
{ "Perm|ChangeNickname", role.Permissions.ChangeNickname.ToString() },
{ "Perm|ManageNicknames", role.Permissions.ManageNicknames.ToString() },
{ "Perm|ManageRoles", role.Permissions.ManageRoles.ToString() },
{ "Perm|DeafenMembers", role.Permissions.DeafenMembers.ToString() },
{ "Perm|ManageMessages", role.Permissions.ManageMessages.ToString() },
{ "Perm|ViewChannel", role.Permissions.ViewChannel.ToString() },
{ "Perm|SendMessages", role.Permissions.SendMessages.ToString() },
{ "Perm|CreateInstantInvite", role.Permissions.CreateInstantInvite.ToString() },
{ "Perm|BanMembers", role.Permissions.BanMembers.ToString() },
{ "Perm|SendTTSMessages", role.Permissions.SendTTSMessages.ToString() },
{ "Perm|Administrator", role.Permissions.Administrator.ToString() },
{ "Perm|ManageChannels", role.Permissions.ManageChannels.ToString() },
{ "Perm|KickMembers", role.Permissions.KickMembers.ToString() },
{ "Perm|AddReactions", role.Permissions.AddReactions.ToString() },
{ "Perm|ViewAuditLog", role.Permissions.ViewAuditLog.ToString() },
{ "Perm|ManageWebhooks", role.Permissions.ManageWebhooks.ToString() },
{ "Perm|ManageGuild", role.Permissions.ManageGuild.ToString() },
{ "Perm|ManageEmojis", role.Permissions.ManageEmojis.ToString() }
};
return new KeyValuePair<bool, Dictionary<string, string>>(true, settings);
}
protected async Task<bool> MuteMember(string givenserverid, string givenmemberid, string mode)
{
DiscordSocketClient Discord = bot.getDiscordClient();
if (ulong.TryParse(givenserverid, out ulong serverid) == true)
{
return false;
}
if (ulong.TryParse(givenmemberid, out ulong memberid) == true)
{
return false;
}
SocketGuild server = Discord.GetGuild(serverid);
SocketGuildUser user = server.GetUser(memberid);
bool.TryParse(mode, out bool status);
await user.ModifyAsync(pr =>
{
pr.Mute = status;
});
return true;
}
protected async Task<bool> MessageChannel(string givenserverid, string givenchannelid, string givenmessage, string tts)
{
if (bool.TryParse(tts, out bool useTTS) == false)
{
return false;
}
return await bot.SendMessageToDiscord(givenserverid, givenchannelid, givenmessage, useTTS);
}
protected async Task<KeyValuePair<bool, Dictionary<string, string>>> ListMembers(string givenserverid)
{
DiscordSocketClient Discord = bot.getDiscordClient();
if (ulong.TryParse(givenserverid, out ulong serverid) == false)
{
return new KeyValuePair<bool, Dictionary<string, string>>(false, new Dictionary<string, string>());
}
SocketGuild server = Discord.GetGuild(serverid);
IEnumerable<IGuildUser> users = await server.GetUsersAsync().FlattenAsync().ConfigureAwait(true);
Dictionary<string, string> membersList = new Dictionary<string, string>();
foreach (IGuildUser user in users)
{
if (user.Nickname != null)
{
membersList.Add(user.Id.ToString(), user.Nickname + "|" + user.Username);
}
else
{
membersList.Add(user.Id.ToString(), user.Username);
}
}
return new KeyValuePair<bool, Dictionary<string, string>>(true, membersList);
}
protected async Task<bool> MessageMember(string givenserverid, string givenmemberid, string givenmessage)
{
DiscordSocketClient Discord = bot.getDiscordClient();
if (ulong.TryParse(givenserverid, out ulong serverid) == false)
{
return false;
}
if (ulong.TryParse(givenmemberid, out ulong memberid) == false)
{
return false;
}
try
{
SocketGuild server = Discord.GetGuild(serverid);
IEnumerable<IGuildUser> users = await server.GetUsersAsync().FlattenAsync().ConfigureAwait(true);
bool sent = false;
foreach (IGuildUser user in users)
{
if (user.Id == memberid)
{
sent = true;
await user.SendMessageAsync(givenmessage);
break;
}
}
return sent;
}
catch
{
return false;
}
}
protected async Task<KeyValuePair<bool, int>> ClearMessages(string givenserverid, string givenmemberid)
{
int messagesDeleted = 0;
DiscordSocketClient Discord = bot.getDiscordClient();
if (ulong.TryParse(givenserverid, out ulong serverid) == false)
{
return new KeyValuePair<bool, int>(false, 0);
}
if (ulong.TryParse(givenmemberid, out ulong memberid) == false)
{
return new KeyValuePair<bool, int>(false, 0);
}
SocketGuild server = Discord.GetGuild(serverid);
SocketGuildUser user = server.GetUser(memberid);
TimeSpan somedays = new TimeSpan(13, 22, 59, 59, 0);
DateTimeOffset justundertwosweeks = DateTimeOffset.Now;
justundertwosweeks = justundertwosweeks.Subtract(somedays);
long unixtimelimit = justundertwosweeks.ToUnixTimeSeconds();
foreach (SocketTextChannel channel in server.TextChannels)
{
List<IMessage> DeleteMessages = new List<IMessage>();
IEnumerable<IMessage> messages = await channel.GetMessagesAsync(100).FlattenAsync();
foreach (IMessage message in messages)
{
if (message.CreatedAt.ToUnixTimeSeconds() > unixtimelimit)
{
if (message.Author.Id == user.Id)
{
DeleteMessages.Add(message);
}
}
}
if (DeleteMessages.Count > 0)
{
messagesDeleted += DeleteMessages.Count;
await channel.DeleteMessagesAsync(DeleteMessages);
}
}
return new KeyValuePair<bool, int>(true, messagesDeleted);
}
protected async Task<bool> BanMember(string givenserverid, string givenmemberid, string why)
{
DiscordSocketClient Discord = bot.getDiscordClient();
if (ulong.TryParse(givenserverid, out ulong serverid) == false)
{
return false;
}
if (ulong.TryParse(givenmemberid, out ulong memberid) == false)
{
return false;
}
SocketGuild server = Discord.GetGuild(serverid);
SocketGuildUser user = server.GetUser(memberid);
await user.BanAsync(7, why);
return true;
}
protected async Task<bool> addRoleToMember(string givenserverid, string givenroleid, string givenmemberid)
{
DiscordSocketClient Discord = bot.getDiscordClient();
if (ulong.TryParse(givenserverid, out ulong serverid) == false)
{
return false;
}
if (ulong.TryParse(givenroleid, out ulong roleid) == false)
{
return false;
}
if (ulong.TryParse(givenmemberid, out ulong memberid) == false)
{
return false;
}
SocketGuild server = Discord.GetGuild(serverid);
SocketRole role = server.GetRole(roleid);
SocketGuildUser user = server.GetUser(memberid);
await user.AddRoleAsync(role); // ? Irole seems to accept SocketRole ?
return true;
}
#endregion
}
}

View file

@ -1,53 +0,0 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.Linq;
using OpenMetaverse;
using Newtonsoft.Json;
using Discord.WebSocket;
using Discord;
using Discord.Rest;
using System.Threading.Tasks;
namespace BetterSecondBot.Commands.DiscordAPI
{
class Discord_AddRole : CoreCommand_4arg
{
public override string[] ArgTypes { get { return new[] { "Smart", "Number", "Number", "Number" }; } }
public override string[] ArgHints { get { return new[] { "Mixed [Channel|Avatar uuid|Avatar name|http url]", "Discord server id", "Role id", "Member id" }; } }
public override string Helpfile { get { return "Adds the selected role to the member"; } }
public override bool CallFunction(string[] args)
{
if (base.CallFunction(args) == true)
{
if (bot.discordReady() == false)
{
return bot.GetCommandsInterface.SmartCommandReply(false, args[0], bot.getDiscordWhyFailed(), CommandName);
}
bool reply = addRoleToMember(args).Result;
return bot.GetCommandsInterface.SmartCommandReply(reply, args[0], "see status for state", CommandName);
}
return bot.GetCommandsInterface.SmartCommandReply(false, args[0], "incorrect args", CommandName);
}
protected async Task<bool> addRoleToMember(string[] args)
{
DiscordSocketClient Discord = bot.getDiscordClient();
if (ulong.TryParse(args[1], out ulong serverid) == true)
{
if(ulong.TryParse(args[2], out ulong roleid) == true)
{
if (ulong.TryParse(args[3], out ulong memberid) == true)
{
SocketGuild server = Discord.GetGuild(serverid);
SocketRole role = server.GetRole(roleid);
SocketGuildUser user = server.GetUser(memberid);
await user.AddRoleAsync(role); // ? Irole seems to accept SocketRole ?
return true;
}
}
}
return false;
}
}
}

View file

@ -1,54 +0,0 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.Linq;
using OpenMetaverse;
using Newtonsoft.Json;
using Discord.WebSocket;
using Discord;
using Discord.Rest;
using System.Threading.Tasks;
namespace BetterSecondBot.Commands.DiscordAPI
{
class Discord_BanMember : CoreCommand_3arg
{
public override string[] ArgTypes { get { return new[] { "Smart", "Number", "Number","Text" }; } }
public override string[] ArgHints { get { return new[] { "Mixed [Channel|Avatar uuid|Avatar name|http url]", "Discord server id", "Member id","Optional why message" }; } }
public override string Helpfile { get { return "Adds the selected user to the ban list - Disallows rejoining untill they are removed from the list "; } }
public override bool CallFunction(string[] args)
{
if (base.CallFunction(args) == true)
{
if (bot.discordReady() == false)
{
return bot.GetCommandsInterface.SmartCommandReply(false, args[0], bot.getDiscordWhyFailed(), CommandName);
}
bool reply = BanMember(args).Result;
return bot.GetCommandsInterface.SmartCommandReply(reply, args[0], "see status for state", CommandName);
}
return bot.GetCommandsInterface.SmartCommandReply(false, args[0], "incorrect args", CommandName);
}
protected async Task<bool> BanMember(string[] args)
{
DiscordSocketClient Discord = bot.getDiscordClient();
if (ulong.TryParse(args[1], out ulong serverid) == true)
{
if (ulong.TryParse(args[2], out ulong memberid) == true)
{
SocketGuild server = Discord.GetGuild(serverid);
SocketGuildUser user = server.GetUser(memberid);
string why = "Secondbot API ban - see your own logs";
if (args.Length == 4)
{
why = args[3];
}
await user.BanAsync(7, why);
return true;
}
}
return false;
}
}
}

View file

@ -1,75 +0,0 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.Linq;
using OpenMetaverse;
using Newtonsoft.Json;
using Discord.WebSocket;
using Discord;
using Discord.Rest;
using System.Threading.Tasks;
namespace BetterSecondBot.Commands.DiscordAPI
{
class Discord_BulkClear_Messages : CoreCommand_3arg
{
public override string[] ArgTypes { get { return new[] { "Smart", "Number", "Number" }; } }
public override string[] ArgHints { get { return new[] { "Mixed [Channel|Avatar uuid|Avatar name|http url]", "Discord server id", "Member id" }; } }
public override string Helpfile { get { return "Clears messages on the server sent by the member in the last 13 days, 22hours 59mins"; } }
public override bool CallFunction(string[] args)
{
if (base.CallFunction(args) == true)
{
if (bot.discordReady() == false)
{
return bot.GetCommandsInterface.SmartCommandReply(false, args[0], bot.getDiscordWhyFailed(), CommandName);
}
KeyValuePair<bool, int> reply = ClearMessages(args).Result;
Dictionary<string, string> collection = new Dictionary<string, string>();
collection.Add("Deleted", reply.Value.ToString());
return bot.GetCommandsInterface.SmartCommandReply(reply.Key, args[0], "See status for state, see collection for total deleted", CommandName, collection);
}
return bot.GetCommandsInterface.SmartCommandReply(false, args[0], "incorrect args", CommandName);
}
protected async Task<KeyValuePair<bool,int>> ClearMessages(string[] args)
{
int messagesDeleted = 0;
DiscordSocketClient Discord = bot.getDiscordClient();
if (ulong.TryParse(args[1], out ulong serverid) == true)
{
if (ulong.TryParse(args[2], out ulong memberid) == true)
{
SocketGuild server = Discord.GetGuild(serverid);
SocketGuildUser user = server.GetUser(memberid);
TimeSpan somedays = new TimeSpan(13, 22, 59, 59, 0);
DateTimeOffset justundertwosweeks = DateTimeOffset.Now;
justundertwosweeks = justundertwosweeks.Subtract(somedays);
long unixtimelimit = justundertwosweeks.ToUnixTimeSeconds();
foreach (SocketTextChannel channel in server.TextChannels)
{
List<IMessage> DeleteMessages = new List<IMessage>();
IEnumerable<IMessage> messages = await channel.GetMessagesAsync(100).FlattenAsync();
foreach (IMessage message in messages)
{
if (message.CreatedAt.ToUnixTimeSeconds() > unixtimelimit)
{
if (message.Author.Id == user.Id)
{
DeleteMessages.Add(message);
}
}
}
if(DeleteMessages.Count() > 0)
{
messagesDeleted += DeleteMessages.Count();
await channel.DeleteMessagesAsync(DeleteMessages);
}
}
return new KeyValuePair<bool, int>(true, messagesDeleted);
}
}
return new KeyValuePair<bool, int>(false,0);
}
}
}

View file

@ -1,65 +0,0 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.Linq;
using OpenMetaverse;
using Newtonsoft.Json;
using Discord.WebSocket;
using Discord;
using Discord.Rest;
using System.Threading.Tasks;
namespace BetterSecondBot.Commands.DiscordAPI
{
class Discord_Dm_Member : CoreCommand_4arg
{
public override string[] ArgTypes { get { return new[] { "Smart", "Number", "Number", "Text" }; } }
public override string[] ArgHints { get { return new[] { "Mixed [Channel|Avatar uuid|Avatar name|http url]", "Server id", "Member id", "Message" }; } }
public override string Helpfile { get { return "Sends a message directly to the user [They must be in the server]\n This command requires the SERVER MEMBERS INTENT found in discord app dev"; } }
public override bool CallFunction(string[] args)
{
if (base.CallFunction(args) == true)
{
if (bot.discordReady() == false)
{
return bot.GetCommandsInterface.SmartCommandReply(false, args[0], bot.getDiscordWhyFailed(), CommandName);
}
bool reply = MessageMember(args).Result;
return bot.GetCommandsInterface.SmartCommandReply(reply, args[0], "see status for state", CommandName);
}
return bot.GetCommandsInterface.SmartCommandReply(false, args[0], "incorrect args", CommandName);
}
protected async Task<bool> MessageMember(string[] args)
{
DiscordSocketClient Discord = bot.getDiscordClient();
if (ulong.TryParse(args[1], out ulong serverid) == true)
{
if (ulong.TryParse(args[2], out ulong memberid) == true)
{
try
{
SocketGuild server = Discord.GetGuild(serverid);
IEnumerable<IGuildUser> users = await server.GetUsersAsync().FlattenAsync().ConfigureAwait(true);
bool sent = false;
foreach(IGuildUser user in users)
{
if(user.Id == memberid)
{
sent = true;
await user.SendMessageAsync(args[3]);
break;
}
}
return sent;
}
catch
{
return false;
}
}
}
return false;
}
}
}

View file

@ -1,58 +0,0 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.Linq;
using OpenMetaverse;
using Newtonsoft.Json;
using Discord.WebSocket;
using Discord;
using Discord.Rest;
using System.Threading.Tasks;
namespace BetterSecondBot.Commands.DiscordAPI
{
class Discord_MembersList : CoreCommand_SmartReply_2arg
{
public override string[] ArgTypes { get { return new[] { "Smart", "Number" }; } }
public override string[] ArgHints { get { return new[] { "Mixed [Channel|Avatar uuid|Avatar name|http url]", "Discord server id" }; } }
public override string Helpfile { get { return "Returns a list of members in a server \n collection is userid: username \n if the user has set a nickname: userid: nickname|username \n This command requires Discord full client mode enabled and connected\n !!!! This command also requires: Privileged Gateway Intents / SERVER MEMBERS INTENT set to true on the discord bot api area !!!"; } }
public override bool CallFunction(string[] args)
{
if (base.CallFunction(args) == true)
{
if (bot.discordReady() == false)
{
return bot.GetCommandsInterface.SmartCommandReply(false, args[0], bot.getDiscordWhyFailed(), CommandName);
}
KeyValuePair<bool, Dictionary<string, string>> reply = ListMembers(args).Result;
return bot.GetCommandsInterface.SmartCommandReply(reply.Key, args[0], "see status for state", CommandName, reply.Value);
}
return bot.GetCommandsInterface.SmartCommandReply(false, args[0], "incorrect args", CommandName);
}
protected async Task<KeyValuePair<bool, Dictionary<string, string>>> ListMembers(string[] args)
{
DiscordSocketClient Discord = bot.getDiscordClient();
if (ulong.TryParse(args[1], out ulong serverid) == true)
{
SocketGuild server = Discord.GetGuild(serverid);
IEnumerable<IGuildUser> users = await server.GetUsersAsync().FlattenAsync().ConfigureAwait(true);
Dictionary<string, string> membersList = new Dictionary<string, string>();
foreach (IGuildUser user in users)
{
if (user.Nickname != null)
{
membersList.Add(user.Id.ToString(), user.Nickname+"|"+user.Username);
}
else
{
membersList.Add(user.Id.ToString(), user.Username);
}
}
return new KeyValuePair<bool, Dictionary<string, string>>(true, membersList);
}
return new KeyValuePair<bool, Dictionary<string, string>>(false, new Dictionary<string, string>());
}
}
}

View file

@ -1,43 +0,0 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.Linq;
using OpenMetaverse;
using Newtonsoft.Json;
using Discord.WebSocket;
using Discord;
using Discord.Rest;
using System.Threading.Tasks;
namespace BetterSecondBot.Commands.DiscordAPI
{
class Discord_MessageChannel : CoreCommand_4arg
{
public override string[] ArgTypes { get { return new[] { "Smart", "Number", "Number", "Message", "True|False" }; } }
public override string[] ArgHints { get { return new[] { "Mixed [Channel|Avatar uuid|Avatar name|http url]", "Discord server id", "channel id", "Message to send", "Use TTS defaults to False" }; } }
public override string Helpfile { get { return "Sends a message to the selected channel - Optional TTS usage"; } }
public override bool CallFunction(string[] args)
{
if (base.CallFunction(args) == true)
{
if (bot.discordReady() == false)
{
return bot.GetCommandsInterface.SmartCommandReply(false, args[0], bot.getDiscordWhyFailed(), CommandName);
}
bool reply = MessageChannel(args).Result;
return bot.GetCommandsInterface.SmartCommandReply(reply, args[0], "see status for state", CommandName);
}
return bot.GetCommandsInterface.SmartCommandReply(false, args[0], "incorrect args", CommandName);
}
protected async Task<bool> MessageChannel(string[] args)
{
bool useTTS = false;
if (args.Length == 5)
{
bool.TryParse(args[4], out useTTS);
}
return await bot.SendMessageToDiscord(args[1], args[2], args[3], useTTS);
}
}
}

View file

@ -1,57 +0,0 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.Linq;
using OpenMetaverse;
using Newtonsoft.Json;
using Discord.WebSocket;
using Discord;
using Discord.Rest;
using System.Threading.Tasks;
namespace BetterSecondBot.Commands.DiscordAPI
{
class Discord_MuteMember : CoreCommand_3arg
{
public override string[] ArgTypes { get { return new[] { "Smart", "Number", "Number", "True|False" }; } }
public override string[] ArgHints { get { return new[] { "Mixed [Channel|Avatar uuid|Avatar name|http url]", "Discord server id", "Member id", "{Optional} Mute status (defaults to true) set this to False to unmute" }; } }
public override string Helpfile { get { return "Updates the Mute status of the member"; } }
public override bool CallFunction(string[] args)
{
if (base.CallFunction(args) == true)
{
if (bot.discordReady() == false)
{
return bot.GetCommandsInterface.SmartCommandReply(false, args[0], bot.getDiscordWhyFailed(), CommandName);
}
bool reply = MuteMember(args).Result;
return bot.GetCommandsInterface.SmartCommandReply(reply, args[0], "see status for state", CommandName);
}
return bot.GetCommandsInterface.SmartCommandReply(false, args[0], "incorrect args", CommandName);
}
protected async Task<bool> MuteMember(string[] args)
{
DiscordSocketClient Discord = bot.getDiscordClient();
if (ulong.TryParse(args[1], out ulong serverid) == true)
{
if (ulong.TryParse(args[2], out ulong memberid) == true)
{
SocketGuild server = Discord.GetGuild(serverid);
SocketGuildUser user = server.GetUser(memberid);
bool status = true;
if (args.Length == 4)
{
bool.TryParse(args[3], out status);
}
await user.ModifyAsync(pr =>
{
pr.Mute = status;
});
return true;
}
}
return false;
}
}
}

View file

@ -1,47 +0,0 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.Linq;
using OpenMetaverse;
using Newtonsoft.Json;
using Discord.WebSocket;
using Discord;
using Discord.Rest;
using System.Threading.Tasks;
namespace BetterSecondBot.Commands.DiscordAPI
{
class Discord_RoleCreate : CoreCommand_SmartReply_3arg
{
public override string[] ArgTypes { get { return new[] { "Smart","Number","Text" }; } }
public override string[] ArgHints { get { return new[] { "Mixed [Channel|Avatar uuid|Avatar name|http url]","Discord server id","Role name" }; } }
public override string Helpfile { get { return "Creates a new role and returns its role ID via smart target\n This command requires Discord full client mode enabled and connected"; } }
public override bool CallFunction(string[] args)
{
if (base.CallFunction(args) == true)
{
if(bot.discordReady() == false)
{
return bot.GetCommandsInterface.SmartCommandReply(false, args[0], bot.getDiscordWhyFailed(), CommandName);
}
KeyValuePair<string, ulong> reply = CreateRole(args).Result;
Dictionary<string, string> collection = new Dictionary<string, string>();
collection.Add("roleid", reply.Value.ToString());
return bot.GetCommandsInterface.SmartCommandReply(true, args[0], "ok", CommandName, collection);
}
return bot.GetCommandsInterface.SmartCommandReply(false, args[0], "incorrect args", CommandName);
}
protected async Task<KeyValuePair<string,ulong>> CreateRole(string[] args)
{
DiscordSocketClient Discord = bot.getDiscordClient();
if (ulong.TryParse(args[1], out ulong serverid) == true)
{
SocketGuild server = Discord.GetGuild(serverid);
RestRole role = await server.CreateRoleAsync(args[2], new GuildPermissions(), Color.DarkRed, false, null).ConfigureAwait(true);
return new KeyValuePair<string, ulong>("ok", role.Id);
}
return new KeyValuePair<string, ulong>("Unable to process server id", 0);
}
}
}

View file

@ -1,49 +0,0 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.Linq;
using OpenMetaverse;
using Newtonsoft.Json;
using Discord.WebSocket;
using Discord;
using Discord.Rest;
using System.Threading.Tasks;
namespace BetterSecondBot.Commands.DiscordAPI
{
class Discord_RoleList: CoreCommand_SmartReply_2arg
{
public override string[] ArgTypes { get { return new[] { "Smart", "Number" }; } }
public override string[] ArgHints { get { return new[] { "Mixed [Channel|Avatar uuid|Avatar name|http url]", "Discord server id" }; } }
public override string Helpfile { get { return "Returns a list of roles and their ids in collection \n This command requires Discord full client mode enabled and connected"; } }
public override bool CallFunction(string[] args)
{
if (base.CallFunction(args) == true)
{
if (bot.discordReady() == false)
{
return bot.GetCommandsInterface.SmartCommandReply(false, args[0], bot.getDiscordWhyFailed(), CommandName);
}
KeyValuePair<bool, Dictionary<string, string>> reply = ListRoles(args);
return bot.GetCommandsInterface.SmartCommandReply(reply.Key, args[0], "see status for state", CommandName, reply.Value);
}
return bot.GetCommandsInterface.SmartCommandReply(false, args[0], "incorrect args", CommandName);
}
protected KeyValuePair<bool,Dictionary<string,string>> ListRoles(string[] args)
{
DiscordSocketClient Discord = bot.getDiscordClient();
if (ulong.TryParse(args[1], out ulong serverid) == true)
{
SocketGuild server = Discord.GetGuild(serverid);
Dictionary<string, string> rolesList = new Dictionary<string, string>();
foreach (SocketRole role in server.Roles)
{
rolesList.Add(role.Id.ToString(), role.Name);
}
return new KeyValuePair<bool, Dictionary<string, string>>(true, rolesList);
}
return new KeyValuePair<bool, Dictionary<string, string>>(false,new Dictionary<string, string>());
}
}
}

View file

@ -1,49 +0,0 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.Linq;
using OpenMetaverse;
using Newtonsoft.Json;
using Discord.WebSocket;
using Discord;
using Discord.Rest;
using System.Threading.Tasks;
namespace BetterSecondBot.Commands.DiscordAPI
{
class Discord_RoleRemove: CoreCommand_SmartReply_3arg
{
public override string[] ArgTypes { get { return new[] { "Smart", "Number", "Number" }; } }
public override string[] ArgHints { get { return new[] { "Mixed [Channel|Avatar uuid|Avatar name|http url]", "Discord server id", "Role id" }; } }
public override string Helpfile { get { return "Remove a new role from a server \n This command requires Discord full client mode enabled and connected"; } }
public override bool CallFunction(string[] args)
{
if (base.CallFunction(args) == true)
{
if (bot.discordReady() == false)
{
return bot.GetCommandsInterface.SmartCommandReply(false, args[0], bot.getDiscordWhyFailed(), CommandName);
}
bool status = RemoveRole(args).Result;
return bot.GetCommandsInterface.SmartCommandReply(status, args[0], "see status for removal state", CommandName);
}
return bot.GetCommandsInterface.SmartCommandReply(false, args[0], "incorrect args", CommandName);
}
protected async Task<bool> RemoveRole(string[] args)
{
DiscordSocketClient Discord = bot.getDiscordClient();
if (ulong.TryParse(args[1], out ulong serverid) == true)
{
if (ulong.TryParse(args[2], out ulong roleid) == true)
{
SocketGuild server = Discord.GetGuild(serverid);
SocketRole role = server.GetRole(roleid);
await role.DeleteAsync().ConfigureAwait(true);
return true;
}
}
return false;
}
}
}

View file

@ -1,84 +0,0 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.Linq;
using OpenMetaverse;
using Newtonsoft.Json;
using Discord.WebSocket;
using Discord;
using Discord.Rest;
using System.Threading.Tasks;
namespace BetterSecondBot.Commands.DiscordAPI
{
class Discord_Role_GetSettings : CoreCommand_SmartReply_3arg
{
public override string[] ArgTypes { get { return new[] { "Smart", "Number", "Number" }; } }
public override string[] ArgHints { get { return new[] { "Mixed [Channel|Avatar uuid|Avatar name|http url]", "Discord server id", "Role id" }; } }
public override string Helpfile { get { return "returns a collection of settings for the given role \n This command requires Discord full client mode enabled and connected"; } }
public override bool CallFunction(string[] args)
{
if (base.CallFunction(args) == true)
{
if (bot.discordReady() == false)
{
return bot.GetCommandsInterface.SmartCommandReply(false, args[0], bot.getDiscordWhyFailed(), CommandName);
}
KeyValuePair<bool, Dictionary<string, string>> reply = RoleSettings(args);
return bot.GetCommandsInterface.SmartCommandReply(reply.Key, args[0], "see status for state", CommandName,reply.Value);
}
return bot.GetCommandsInterface.SmartCommandReply(false, args[0], "incorrect args", CommandName);
}
protected KeyValuePair<bool, Dictionary<string, string>> RoleSettings(string[] args)
{
DiscordSocketClient Discord = bot.getDiscordClient();
if (ulong.TryParse(args[1], out ulong serverid) == true)
{
if (ulong.TryParse(args[2], out ulong roleid) == true)
{
SocketGuild server = Discord.GetGuild(serverid);
SocketRole role = server.GetRole(roleid);
Dictionary<string, string> settings = new Dictionary<string, string>
{
{ "Config|Color", String.Join(",", new byte[3] { role.Color.R, role.Color.G, role.Color.B }) },
{ "Config|Name", role.Name },
{ "Info|AssignedCount", role.Members.Count().ToString() },
{ "Perm|AttachFiles", role.Permissions.AttachFiles.ToString() },
{ "Perm|ReadMessageHistory", role.Permissions.ReadMessageHistory.ToString() },
{ "Perm|MentionEveryone", role.Permissions.MentionEveryone.ToString() },
{ "Perm|UseExternalEmojis", role.Permissions.UseExternalEmojis.ToString() },
{ "Perm|Connect", role.Permissions.Connect.ToString() },
{ "Perm|Speak", role.Permissions.Speak.ToString() },
{ "Perm|MuteMembers", role.Permissions.MuteMembers.ToString() },
{ "Perm|UseVAD", role.Permissions.UseVAD.ToString() },
{ "Perm|MoveMembers", role.Permissions.MoveMembers.ToString() },
{ "Perm|EmbedLinks", role.Permissions.EmbedLinks.ToString() },
{ "Perm|PrioritySpeaker", role.Permissions.PrioritySpeaker.ToString() },
{ "Perm|Stream", role.Permissions.Stream.ToString() },
{ "Perm|ChangeNickname", role.Permissions.ChangeNickname.ToString() },
{ "Perm|ManageNicknames", role.Permissions.ManageNicknames.ToString() },
{ "Perm|ManageRoles", role.Permissions.ManageRoles.ToString() },
{ "Perm|DeafenMembers", role.Permissions.DeafenMembers.ToString() },
{ "Perm|ManageMessages", role.Permissions.ManageMessages.ToString() },
{ "Perm|ViewChannel", role.Permissions.ViewChannel.ToString() },
{ "Perm|SendMessages", role.Permissions.SendMessages.ToString() },
{ "Perm|CreateInstantInvite", role.Permissions.CreateInstantInvite.ToString() },
{ "Perm|BanMembers", role.Permissions.BanMembers.ToString() },
{ "Perm|SendTTSMessages", role.Permissions.SendTTSMessages.ToString() },
{ "Perm|Administrator", role.Permissions.Administrator.ToString() },
{ "Perm|ManageChannels", role.Permissions.ManageChannels.ToString() },
{ "Perm|KickMembers", role.Permissions.KickMembers.ToString() },
{ "Perm|AddReactions", role.Permissions.AddReactions.ToString() },
{ "Perm|ViewAuditLog", role.Permissions.ViewAuditLog.ToString() },
{ "Perm|ManageWebhooks", role.Permissions.ManageWebhooks.ToString() },
{ "Perm|ManageGuild", role.Permissions.ManageGuild.ToString() },
{ "Perm|ManageEmojis", role.Permissions.ManageEmojis.ToString() }
};
return new KeyValuePair<bool, Dictionary<string, string>>(true, settings);
}
}
return new KeyValuePair<bool, Dictionary<string, string>>(false, new Dictionary<string, string>());
}
}
}

View file

@ -1,165 +0,0 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.Linq;
using OpenMetaverse;
using Newtonsoft.Json;
using Discord.WebSocket;
using Discord;
using Discord.Rest;
using System.Threading.Tasks;
namespace BetterSecondBot.Commands.DiscordAPI
{
class Discord_Role_UpdatePerms : CoreCommand_4arg
{
public override string[] ArgTypes { get { return new[] { "Smart", "Number", "Number","Text" }; } }
public override string[] ArgHints { get { return new[] { "Mixed [Channel|Avatar uuid|Avatar name|http url]", "Discord server id", "Role id","CSV list of PermFlag=Bool" }; } }
public override string Helpfile { get { return "Updates perm flags for the selected role \n example CSV format: Speak=True,SendMessages=False \n for a full list of perms see output of DiscordRoleGetSettings \n This command requires Discord full client mode enabled and connected"; } }
public override bool CallFunction(string[] args)
{
if (base.CallFunction(args) == true)
{
if (bot.discordReady() == false)
{
return bot.GetCommandsInterface.SmartCommandReply(false, args[0], bot.getDiscordWhyFailed(), CommandName);
}
bool status = UpdateRolePerms(args).Result;
return bot.GetCommandsInterface.SmartCommandReply(status, args[0], "see status for update state", CommandName);
}
return bot.GetCommandsInterface.SmartCommandReply(false, args[0], "incorrect args", CommandName);
}
protected GuildPermissions UpdateFlag(GuildPermissions NewPerms,string flag, bool flagValue)
{
switch (flag)
{
case "CreateInstantInvite":
NewPerms = NewPerms.Modify(flagValue);
break;
case "KickMembers":
NewPerms = NewPerms.Modify(null, flagValue);
break;
case "BanMembers":
NewPerms = NewPerms.Modify(null, null, flagValue);
break;
case "Administrator":
NewPerms = NewPerms.Modify(null, null, null, flagValue);
break;
case "ManageChannels":
NewPerms = NewPerms.Modify(null, null, null, null, flagValue);
break;
case "ManageGuild":
NewPerms = NewPerms.Modify(null, null, null, null, null, flagValue);
break;
case "AddReactions":
NewPerms = NewPerms.Modify(null, null, null, null, null, null, flagValue);
break;
case "ViewAuditLog":
NewPerms = NewPerms.Modify(null, null, null, null, null, null, null, flagValue);
break;
case "SendTTSMessages":
NewPerms = NewPerms.Modify(null, null, null, null, null, null, null, null, null, null, null, flagValue);
break;
case "AttachFiles":
NewPerms = NewPerms.Modify(null, null, null, null, null, null, null, null, null, null, null, null, null, null, flagValue);
break;
case "ReadMessageHistory":
NewPerms = NewPerms.Modify(null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, flagValue);
break;
case "MentionEveryone":
NewPerms = NewPerms.Modify(null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, flagValue);
break;
case "UseExternalEmojis":
NewPerms = NewPerms.Modify(null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, flagValue);
break;
case "Connect":
NewPerms = NewPerms.Modify(null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, flagValue);
break;
case "Speak":
NewPerms = NewPerms.Modify(null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, flagValue);
break;
case "MuteMembers":
NewPerms = NewPerms.Modify(null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, flagValue);
break;
case "UseVAD":
NewPerms = NewPerms.Modify(null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, flagValue);
break;
case "MoveMembers":
NewPerms = NewPerms.Modify(null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, flagValue);
break;
case "EmbedLinks":
NewPerms = NewPerms.Modify(null, null, null, null, null, null, null, null, null, null, null, null, null, flagValue);
break;
case "PrioritySpeaker":
NewPerms = NewPerms.Modify(null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, flagValue);
break;
case "Stream":
NewPerms = NewPerms.Modify(null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, flagValue);
break;
case "ChangeNickname":
NewPerms = NewPerms.Modify(null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, flagValue);
break;
case "ManageNicknames":
NewPerms = NewPerms.Modify(null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, flagValue);
break;
case "ManageRoles":
NewPerms = NewPerms.Modify(null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, flagValue);
break;
case "DeafenMembers":
NewPerms = NewPerms.Modify(null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, flagValue);
break;
case "ManageMessages":
NewPerms = NewPerms.Modify(null, null, null, null, null, null, null, null, null, null, null, null, flagValue);
break;
case "ViewChannel":
NewPerms = NewPerms.Modify(null, null, null, null, null, null, null, null, null, flagValue);
break;
case "SendMessages":
NewPerms = NewPerms.Modify(null, null, null, null, null, null, null, null, null, null, flagValue);
break;
case "ManageWebhooks":
NewPerms = NewPerms.Modify(null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, flagValue);
break;
case "ManageEmojis":
NewPerms = NewPerms.Modify(null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, flagValue);
break;
default:
break;
}
return NewPerms;
}
protected async Task<bool> UpdateRolePerms(string[] args)
{
DiscordSocketClient Discord = bot.getDiscordClient();
if (ulong.TryParse(args[1], out ulong serverid) == true)
{
if (ulong.TryParse(args[2], out ulong roleid) == true)
{
SocketGuild server = Discord.GetGuild(serverid);
SocketRole role = server.GetRole(roleid);
string[] bits = args[3].Split(',');
GuildPermissions NewPerms = role.Permissions;
foreach (String bit in bits)
{
string[] subbits = bit.Split('=');
if(subbits.Length == 2)
{
if(bool.TryParse(subbits[1],out bool flagValue) == true)
{
NewPerms = UpdateFlag(NewPerms, subbits[0], flagValue);
}
}
}
await role.ModifyAsync(Rp =>
{
Rp.Permissions = NewPerms;
}).ConfigureAwait(true);
return true;
}
}
return false;
}
}
}

View file

@ -1,49 +0,0 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.Linq;
using OpenMetaverse;
using Newtonsoft.Json;
using Discord.WebSocket;
using Discord;
using Discord.Rest;
using System.Threading.Tasks;
namespace BetterSecondBot.Commands.DiscordAPI
{
class Discord_TextChannels_List : CoreCommand_SmartReply_2arg
{
public override string[] ArgTypes { get { return new[] { "Smart", "Number" }; } }
public override string[] ArgHints { get { return new[] { "Mixed [Channel|Avatar uuid|Avatar name|http url]", "Discord server id" }; } }
public override string Helpfile { get { return "Returns a list of text channels in a server \n collection is channelid: name"; } }
public override bool CallFunction(string[] args)
{
if (base.CallFunction(args) == true)
{
if (bot.discordReady() == false)
{
return bot.GetCommandsInterface.SmartCommandReply(false, args[0], bot.getDiscordWhyFailed(), CommandName);
}
KeyValuePair<bool, Dictionary<string, string>> reply = ListTextChannels(args);
return bot.GetCommandsInterface.SmartCommandReply(reply.Key, args[0], "see status for state", CommandName, reply.Value);
}
return bot.GetCommandsInterface.SmartCommandReply(false, args[0], "incorrect args", CommandName);
}
protected KeyValuePair<bool, Dictionary<string, string>> ListTextChannels(string[] args)
{
DiscordSocketClient Discord = bot.getDiscordClient();
if (ulong.TryParse(args[1], out ulong serverid) == true)
{
SocketGuild server = Discord.GetGuild(serverid);
Dictionary<string, string> textChannels = new Dictionary<string, string>();
foreach(SocketTextChannel channel in server.TextChannels)
{
textChannels.Add(channel.Id.ToString(), channel.Name);
}
return new KeyValuePair<bool, Dictionary<string, string>>(true, textChannels);
}
return new KeyValuePair<bool, Dictionary<string, string>>(false, new Dictionary<string, string>());
}
}
}

192
Core/Commands/Estate.cs Normal file
View file

@ -0,0 +1,192 @@
using BetterSecondBotShared.Json;
using BetterSecondBot.bottypes;
using EmbedIO;
using EmbedIO.Routing;
using System;
using Newtonsoft.Json;
using OpenMetaverse;
using System.Collections.Generic;
using EmbedIO.WebApi;
using BetterSecondBotShared.Static;
namespace BetterSecondBot.HttpService
{
public class HTTP_Estate : WebApiControllerWithTokens
{
public HTTP_Estate(SecondBot mainbot, TokenStorage setuptokens) : base(mainbot, setuptokens)
{
}
[About("Sends the message to the current sim")]
[ReturnHints("Not an estate manager here")]
[ReturnHints("restarting")]
[ReturnHints("canceled")]
[ArgHints("delay", "URLARG", "How long to delay the restart for (30 to 240 secs) - defaults to 240 if out of bounds \n" +
"set to 0 if your canceling!")]
[ArgHints("mode", "URLARG", "true to start a restart, false to cancel")]
[Route(HttpVerbs.Get, "/SimRestart/{delay}/{mode}/{token}")]
public object SimRestart(string delay, string mode, string token)
{
if (tokens.Allow(token, "estate", "SimMessage", handleGetClientIP()) == false)
{
return Failure("Token not accepted");
}
if (bot.GetClient.Network.CurrentSim.IsEstateManager == false)
{
return Failure("Not an estate manager here");
}
bool.TryParse(mode, out bool modeflag);
if (modeflag == false)
{
bot.GetClient.Estate.CancelRestart();
return BasicReply("canceled");
}
int delay_restart = 60;
int.TryParse(delay, out delay_restart);
if((delay_restart < 30) || (delay_restart > 240))
{
delay_restart = 240;
}
bot.GetClient.Estate.RestartRegion(delay_restart);
return BasicReply("restarting");
}
[About("Sends the message to the current sim")]
[ReturnHints("Not an estate manager here")]
[ReturnHints("Message empty")]
[ReturnHints("ok")]
[ArgHints("message", "Text", "What the message is")]
[Route(HttpVerbs.Post, "/SimMessage/{token}")]
public object SimMessage([FormField] string message, string token)
{
if (tokens.Allow(token, "estate", "SimMessage", handleGetClientIP()) == false)
{
return Failure("Token not accepted");
}
if (helpers.notempty(message) == false)
{
return Failure("Message empty");
}
if (bot.GetClient.Network.CurrentSim.IsEstateManager == false)
{
return Failure("Not an estate manager here");
}
bot.GetClient.Estate.SimulatorMessage(message);
return BasicReply("ok");
}
[About("Fetchs the regions map tile")]
[ReturnHints("Unable to find region")]
[ReturnHints("Texture UUID")]
[ArgHints("regionname", "URLARG", "the name of the region we are fetching")]
[Route(HttpVerbs.Get, "/GetSimTexture/{regionname}/{token}")]
public object GetSimTexture(string regionname, string token)
{
if (tokens.Allow(token, "estate", "GetSimTexture", handleGetClientIP()) == false)
{
return Failure("Token not accepted");
}
if (bot.GetClient.Grid.GetGridRegion(regionname, GridLayerType.Objects, out GridRegion region) == false)
{
return Failure("Unable to find region");
}
return BasicReply(region.MapImageID.ToString());
}
[About("Reclaims ownership of the current parcel")]
[ReturnHints("Not an estate manager here")]
[ReturnHints("ok")]
[Route(HttpVerbs.Get, "/EstateParcelReclaim/{token}")]
public Object EstateParcelReclaim(string token)
{
if (tokens.Allow(token, "estate", "EstateParcelReclaim", handleGetClientIP()) == false)
{
return Failure("Token not accepted");
}
if (bot.GetClient.Network.CurrentSim.IsEstateManager == false)
{
return Failure("Not an estate manager here");
}
int localid = bot.GetClient.Parcels.GetParcelLocalID(bot.GetClient.Network.CurrentSim, bot.GetClient.Self.SimPosition);
bot.GetClient.Parcels.Reclaim(bot.GetClient.Network.CurrentSim, localid);
return BasicReply("ok");
}
[About("Reclaims ownership of the current parcel")]
[ReturnHints("Not an estate manager here")]
[ReturnHints("ok")]
[Route(HttpVerbs.Get, "/GetSimGlobalPos/{regionname}/{token}")]
public Object GetSimGlobalPos(string regionname, string token)
{
if (tokens.Allow(token, "estate", "GetSimGlobalPos", handleGetClientIP()) == false)
{
return Failure("Token not accepted");
}
if (bot.GetClient.Grid.GetGridRegion(regionname, GridLayerType.Objects, out GridRegion region) == false)
{
return Failure("Unable to find region");
}
Dictionary<string, string> reply = new Dictionary<string, string>();
reply.Add("region", regionname);
reply.Add("X", region.X.ToString());
reply.Add("Y", region.Y.ToString());
return reply;
}
[About("Requests the estate banlist")]
[ReturnHints("")]
[Route(HttpVerbs.Get, "/GetEstateBanList/{token}")]
public Object GetEstateBanList(string token)
{
if (tokens.Allow(token, "estate", "banlist", handleGetClientIP()) == false)
{
return Failure("Token not accepted");
}
return BasicReply(JsonConvert.SerializeObject(bot._lastUpdatedSimBlacklist));
}
[About("Attempts to add/remove the avatar to/from the Estate banlist")]
[ReturnHints("Unban request accepted")]
[ReturnHints("Ban request accepted")]
[ReturnHints("Unable to find avatar UUID")]
[ReturnHints("Unable to process global value please use true or false")]
[ReturnHints("Not an estate manager on region {REGIONNAME}")]
[ArgHints("avatar", "URLARG", "the uuid avatar you wish to ban")]
[ArgHints("mode", "URLARG", "What action would you like to take<br/>Defaults to remove if not given \"add\"")]
[ArgHints("global", "URLARG", "if true this the ban/unban will be applyed to all estates the bot has access to")]
[Route(HttpVerbs.Get, "/UpdateEstateBanlist/{avatar}/{mode}/{global}/{token}")]
public Object UpdateEstateBanlist(string avatar, string mode, string global, string token)
{
if (tokens.Allow(token, "estate", "banlist-add", handleGetClientIP()) == false)
{
return Failure("Token not accepted");
}
if (bot.GetClient.Network.CurrentSim.IsEstateManager == false)
{
return Failure("Not an estate manager on region " + bot.GetClient.Network.CurrentSim.Name);
}
UUID avataruuid = UUID.Zero;
if (UUID.TryParse(avatar, out avataruuid) == false)
{
return Failure("Unable to find avatar UUID");
}
bool globalban = false;
if (bool.TryParse(global, out globalban) == false)
{
return Failure("Unable to process global value please use true or false");
}
if (mode != "add")
{
bot.GetClient.Estate.UnbanUser(avataruuid, globalban);
return BasicReply("Unban request accepted");
}
bot.GetClient.Estate.BanUser(avataruuid, globalban);
return BasicReply("Ban request accepted");
}
}
}

View file

@ -1,25 +0,0 @@
namespace BetterSecondBot.Commands.Estate
{
public class EstateParcelReclaim : CoreCommand
{
public override string Helpfile { get { return "Reclaims ownership of the current parcel"; } }
public override bool CallFunction(string[] args)
{
if (base.CallFunction(args) == true)
{
if (bot.GetClient.Network.CurrentSim.IsEstateManager == true)
{
int localid = bot.GetClient.Parcels.GetParcelLocalID(bot.GetClient.Network.CurrentSim, bot.GetClient.Self.SimPosition);
bot.GetClient.Parcels.Reclaim(bot.GetClient.Network.CurrentSim, localid);
return true;
}
else
{
return Failed("Not an estate manager here");
}
}
return false;
}
}
}

View file

@ -1,27 +0,0 @@
using OpenMetaverse;
namespace BetterSecondBot.Commands.Estate
{
public class GetSimGlobalPos : CoreCommand_SmartReply_2arg
{
public override string Helpfile { get { return "Fetchs a region and returns its global X,Y"; } }
public override bool CallFunction(string[] args)
{
if (base.CallFunction(args) == true)
{
if (bot.GetClient.Grid.GetGridRegion(args[1], GridLayerType.Objects, out GridRegion region))
{
collection.Add("X", region.X.ToString());
collection.Add("Y", region.Y.ToString());
return bot.GetCommandsInterface.SmartCommandReply(true, args[0], "ok", CommandName,collection);
}
else
{
return Failed("Unable to find region");
}
}
return false;
}
}
}

View file

@ -1,25 +0,0 @@
using OpenMetaverse;
namespace BetterSecondBot.Commands.Estate
{
public class GetSimTexture : CoreCommand_SmartReply_2arg
{
public override string Helpfile { get { return "Fetchs a region and returns its tile texture UUID - Expect this to die at some point!"; } }
public override bool CallFunction(string[] args)
{
if (base.CallFunction(args) == true)
{
if (bot.GetClient.Grid.GetGridRegion(args[1], GridLayerType.Objects, out GridRegion region))
{
return bot.GetCommandsInterface.SmartCommandReply(true, args[0], region.MapImageID.ToString(),CommandName);
}
else
{
return bot.GetCommandsInterface.SmartCommandReply(false, args[0], "Unable to find region", CommandName);
}
}
return false;
}
}
}

View file

@ -1,26 +0,0 @@
namespace BetterSecondBot.Commands.Estate
{
public class SimMessage : CoreCommand_1arg
{
public override string[] ArgTypes { get { return new[] { "Text" }; } }
public override string[] ArgHints { get { return new[] { "Message to send" }; } }
public override string Helpfile { get { return "Sends the message [ARG 1] to the current sim"; } }
public override bool CallFunction(string[] args)
{
if (base.CallFunction(args) == true)
{
if (bot.GetClient.Network.CurrentSim.IsEstateManager == true)
{
bot.GetClient.Estate.SimulatorMessage(args[0]);
return true;
}
else
{
return Failed("Not an estate manager here");
}
}
return false;
}
}
}

View file

@ -1,45 +0,0 @@
namespace BetterSecondBot.Commands.Estate
{
public class SimRestart : CoreCommand_1arg
{
public override string[] ArgTypes { get { return new[] { "True|False","Number" }; } }
public override string[] ArgHints { get { return new[] { "Restart mode: True=Restart sim,False=Cancel restart","delay in secs to restart (Min 30 - max 240) defaults to 60 if not given" }; } }
public override string Helpfile { get { return "Sends the message [ARG 1] to the current sim"; } }
public override bool CallFunction(string[] args)
{
if (base.CallFunction(args) == true)
{
if (bot.GetClient.Network.CurrentSim.IsEstateManager == true)
{
if(bool.TryParse(args[0],out bool mode) == true)
{
if(mode == false)
{
bot.GetClient.Estate.CancelRestart();
}
else
{
int delay_restart = 60;
if(args.Length == 2)
{
int.TryParse(args[1], out delay_restart);
}
bot.GetClient.Estate.RestartRegion(delay_restart);
}
}
else
{
return Failed("True or False request for arg 1");
}
}
else
{
return Failed("Not an estate manager here");
}
}
return false;
}
}
}

114
Core/Commands/Friends.cs Normal file
View file

@ -0,0 +1,114 @@
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;
namespace BetterSecondBot.HttpService
{
public class HTTP_Friends : WebApiControllerWithTokens
{
public HTTP_Friends(SecondBot mainbot, TokenStorage setuptokens) : base(mainbot, setuptokens) { }
[About("Gets the friendslist <br/>Formated as follows<br/>friendreplyobject<br/><ul><li>name: String</li><li>id: String</li><li>online: bool</li></ul>")]
[ReturnHints("array UUID = friendreplyobject")]
[Route(HttpVerbs.Get, "/Friendslist/{token}")]
public object Friendslist(string token)
{
if (tokens.Allow(token, "friends", "Friendslist", handleGetClientIP()) == false)
{
return Failure("Token not accepted");
}
return BasicReply(bot.getJsonFriendlist());
}
[About("Updates the friend perms for avatar avatar to State \n if true grants (Online/Map/Modify) perms")]
[ArgHints("avatar", "URLARG", "A avatar uuid or Firstname Lastname")]
[ArgHints("state", "URLARG", "true: Grant perms, false: Remove perms")]
[ReturnHints("granted")]
[ReturnHints("removed")]
[ReturnHints("Not A friend")]
[ReturnHints("state invaild")]
[ReturnHints("avatar lookup")]
[Route(HttpVerbs.Get, "/FriendFullPerms/{avatar}/{state}/{token}")]
public object FriendFullPerms(string avatar, string state, string token)
{
if (tokens.Allow(token, "friends", "FriendFullPerms", handleGetClientIP()) == false)
{
return Failure("Token not accepted");
}
ProcessAvatar(avatar);
if (avataruuid == UUID.Zero)
{
return Failure("avatar lookup");
}
bool status = false;
if (bool.TryParse(state, out status) == false)
{
return Failure("state invaild");
}
if (bot.GetClient.Friends.FriendList.ContainsKey(avataruuid) == false)
{
return Failure("Not A friend");
}
if (status == true)
{
bot.GetClient.Friends.GrantRights(avataruuid, FriendRights.CanSeeOnline | FriendRights.CanSeeOnMap | FriendRights.CanModifyObjects);
return BasicReply("granted");
}
bot.GetClient.Friends.GrantRights(avataruuid, FriendRights.None);
return BasicReply("removed");
}
[About("Updates the friend perms for avatar avatar to State \n if true grants (Online/Map/Modify) perms")]
[ReturnHints("Request sent")]
[ReturnHints("Removed")]
[ReturnHints("Already a friend")]
[ReturnHints("Not in friendslist")]
[ReturnHints("state invaild")]
[ReturnHints("avatar lookup")]
[ArgHints("avatar", "URLARG", "A avatar uuid or Firstname Lastname")]
[ArgHints("state", "URLARG", "true: Send invite, false: Remove from friendslist")]
[Route(HttpVerbs.Get, "/FriendRequest/{avatar}/{state}/{token}")]
public object FriendRequest(string avatar, string state, string token)
{
if (tokens.Allow(token, "friends", "FriendRequest", handleGetClientIP()) == false)
{
return Failure("Token not accepted");
}
ProcessAvatar(avatar);
if (avataruuid == UUID.Zero)
{
return Failure("avatar lookup");
}
bool status = false;
if (bool.TryParse(state, out status) == false)
{
return Failure("state invaild");
}
if (bot.GetClient.Friends.FriendList.ContainsKey(avataruuid) == true)
{
if (status == false)
{
bot.GetClient.Friends.TerminateFriendship(avataruuid);
return BasicReply("Removed");
}
}
if (status == false)
{
return Failure("Not in friendslist");
}
bot.GetClient.Friends.OfferFriendship(avataruuid);
return BasicReply("Request sent");
}
}
}

View file

@ -1,42 +0,0 @@
using System;
using OpenMetaverse;
namespace BetterSecondBot.Commands.Friends
{
public class FriendFullPerms : CoreCommand_2arg
{
public override string[] ArgTypes { get { return new[] { "Avatar","True|False" }; } }
public override string[] ArgHints { get { return new[] { "Avatar UUID or Firstname Lastname","What status should it be" }; } }
public override string Helpfile { get { return "Updates the friend perms for avatar [Arg 1] to [Arg 2] (Online/Map/Modify)"; } }
public override bool CallFunction(string[] args)
{
if (base.CallFunction(args) == true)
{
if(UUID.TryParse(args[0],out UUID avatar) == true)
{
if(bool.TryParse(args[1],out bool status) == true)
{
if (bot.GetClient.Friends.FriendList.ContainsKey(avatar) == true)
{
if (status == true)
{
bot.GetClient.Friends.GrantRights(avatar, FriendRights.CanSeeOnline | FriendRights.CanSeeOnMap | FriendRights.CanModifyObjects);
InfoBlob = "Friendship rights granted";
}
else
{
bot.GetClient.Friends.GrantRights(avatar, FriendRights.None);
InfoBlob = "Friendship rights removed";
}
return true;
}
return Failed("Avatar not on friends list or friends list has not updated yet");
}
return Failed("Unable to process arg 2");
}
return Failed("Unable to process avatar on arg 1");
}
return false;
}
}
}

View file

@ -1,28 +0,0 @@
using System;
using OpenMetaverse;
namespace BetterSecondBot.Commands.Friends
{
public class FriendRequest : 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 friend request to the target avatar"; } }
public override bool CallFunction(string[] args)
{
if (base.CallFunction(args) == true)
{
if (UUID.TryParse(args[0], out UUID avatar) == true)
{
if (bot.GetClient.Friends.FriendList.ContainsKey(avatar) == false)
{
bot.GetClient.Friends.OfferFriendship(avatar);
}
return true;
}
return Failed("Unable to process avatar on arg 1");
}
return false;
}
}
}

View file

@ -1,18 +0,0 @@
using System;
using OpenMetaverse;
namespace BetterSecondBot.Commands.Friends
{
public class Friendslist : CoreCommand_SmartReply_1arg
{
public override string Helpfile { get { return "Returns a copy of the friends list"; } }
public override bool CallFunction(string[] args)
{
if (base.CallFunction(args) == true)
{
return bot.GetCommandsInterface.SmartCommandReply(true, args[0], bot.getJsonFriendlist(), CommandName);
}
return false;
}
}
}

112
Core/Commands/Funds.cs Normal file
View file

@ -0,0 +1,112 @@
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_Funds : WebApiControllerWithTokens
{
public Http_Funds(SecondBot mainbot, TokenStorage setuptokens) : base(mainbot, setuptokens) { }
[About("Requests the current balance and requests the balance to update.")]
[ReturnHints("Current fund level")]
[ReturnHints("Funds commands are disabled")]
[Route(HttpVerbs.Get, "/Balance/{token}")]
public object Balance(string token)
{
if (tokens.Allow(token, "funds", "Balance", handleGetClientIP()) == false)
{
return Failure("Token not accepted");
}
if (bot.GetAllowFunds == false)
{
return Failure("Funds commands are disabled");
}
bot.GetClient.Self.RequestBalance();
return BasicReply(bot.GetClient.Self.Balance.ToString());
}
[About("Makes the bot pay a avatar")]
[ReturnHints("Accepted")]
[ReturnHints("avatar lookup")]
[ReturnHints("Invaild amount")]
[ReturnHints("Transfer funds to avatars disabled")]
[Route(HttpVerbs.Get, "/PayAvatar/{avatar}/{amount}/{token}")]
public object PayAvatar(string avatar, string amount, string token)
{
if (tokens.Allow(token, "funds", "PayAvatar", handleGetClientIP()) == false)
{
return BasicReply("Token not accepted");
}
if (bot.GetAllowFunds == false)
{
return BasicReply("Transfer funds to avatars disabled");
}
ProcessAvatar(avatar);
if (avataruuid == UUID.Zero)
{
return BasicReply("avatar lookup");
}
if (int.TryParse(amount, out int amountvalue) == false)
{
return BasicReply("Invaild amount");
}
if (amountvalue < 1)
{
return BasicReply("Invaild amount");
}
bot.GetClient.Self.GiveAvatarMoney(avataruuid, amountvalue);
return BasicReply("Accepted");
}
[About("Makes the bot pay a object")]
[ReturnHints("ok")]
[ReturnHints("Primname is empty")]
[ReturnHints("Current fund level")]
[ReturnHints("Invaild object UUID")]
[ReturnHints("Invaild amount")]
[ReturnHints("Amount out of range")]
[ReturnHints("Funds commands are disabled")]
[ArgHints("object", "URLARG", "UUID of the object to pay")]
[ArgHints("primname", "URLARG", "The name of the prim on the object to pay")]
[ArgHints("amount", "URLARG", "the amount to pay (from 1 to current balance)")]
[Route(HttpVerbs.Get, "/PayObject/{object}/{primname}/{amount}/{token}")]
public object PayObject(string objectuuid,string primname,string amount,string token)
{
if (tokens.Allow(token, "funds", "PayObject", handleGetClientIP()) == false)
{
return Failure("Token not accepted");
}
if (bot.GetAllowFunds == false)
{
return Failure("Funds commands are disabled");
}
if (UUID.TryParse(objectuuid, out UUID objectUUID) == false)
{
return Failure("Invaild object UUID");
}
if (int.TryParse(amount, out int amountvalue) == false)
{
return Failure("Invaild amount");
}
if((amountvalue < 0) || (amountvalue > bot.GetClient.Self.Balance))
{
return Failure("Amount out of range");
}
if(helpers.notempty(primname) == false)
{
return Failure("Primname is empty");
}
bot.GetClient.Self.GiveObjectMoney(objectUUID, amountvalue, primname);
return BasicReply("ok");
}
}
}

564
Core/Commands/Group.cs Normal file
View file

@ -0,0 +1,564 @@
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_Group : WebApiControllerWithTokens
{
public HTTP_Group(SecondBot mainbot, TokenStorage setuptokens) : base(mainbot, setuptokens) { }
[About("Checks if the given UUID is in the given group<br/>Note: if group membership data is more than 60 secs old this will return Updating<br/>Please wait and retry later")]
[ReturnHints("True|False")]
[ReturnHints("Updating")]
[ReturnHints("Unknown group")]
[ReturnHints("Invaild group UUID")]
[ReturnHints("avatar lookup")]
[ArgHints("group", "URLARG", "the UUID of the group")]
[ArgHints("avatar", "URLARG", "the UUID of the avatar you wish to check with")]
[Route(HttpVerbs.Get, "/IsGroupMember/{group}/{avatar}/{token}")]
public object IsGroupMember(string group, string avatar, string token)
{
if (tokens.Allow(token, "groups", "IsGroupMember", handleGetClientIP()) == false)
{
return Failure("Token not accepted");
}
if (UUID.TryParse(group, out UUID groupuuid) == false)
{
return Failure("Invaild group UUID");
}
if (bot.MyGroups.ContainsKey(groupuuid) == false)
{
return Failure("Unknown group");
}
if (bot.NeedReloadGroupData(groupuuid) == true)
{
bot.GetClient.Groups.RequestGroupMembers(groupuuid);
return Failure("Updating");
}
ProcessAvatar(avatar);
if (avataruuid == UUID.Zero)
{
return Failure("avatar lookup");
}
bool status = bot.FastCheckInGroup(groupuuid, avataruuid);
return BasicReply(status.ToString());
}
[About("Gets membership of a group")]
[ReturnHints("list of UUIDS of group members")]
[ReturnHints("Updating")]
[ReturnHints("Unknown group")]
[ReturnHints("Invaild group UUID")]
[ReturnHints("avatar lookup")]
[ArgHints("group", "URLARG", "the UUID of the group")]
[Route(HttpVerbs.Get, "/GetGroupMembers/{group}/{token}")]
public object GetGroupMembers(string group, string token)
{
if (tokens.Allow(token, "groups", "GetGroupMembers", handleGetClientIP()) == false)
{
return Failure("Token not accepted");
}
if (UUID.TryParse(group, out UUID groupuuid) == false)
{
return Failure("Invaild group UUID");
}
if (bot.MyGroups.ContainsKey(groupuuid) == false)
{
return Failure("Unknown group");
}
if (bot.NeedReloadGroupData(groupuuid) == true)
{
bot.GetClient.Groups.RequestGroupMembers(groupuuid);
return Failure("Updating");
}
return bot.GetGroupMembers(groupuuid);
}
[About("Eject selected avatar from group")]
[ReturnHints("Requested")]
[ReturnHints("Updating")]
[ReturnHints("Unknown group")]
[ReturnHints("Invaild group UUID")]
[ReturnHints("Not in group")]
[ReturnHints("avatar lookup")]
[ArgHints("group", "URLARG", "the UUID of the group")]
[ArgHints("avatar", "URLARG", "the UUID of the avatar you wish to check with")]
[Route(HttpVerbs.Get, "/GroupEject/{group}/{avatar}/{token}")]
public object GroupEject(string group, string avatar, string token)
{
if (tokens.Allow(token, "groups", "GroupEject", handleGetClientIP()) == false)
{
return Failure("Token not accepted");
}
if (UUID.TryParse(group, out UUID groupuuid) == false)
{
return Failure("Invaild group UUID");
}
if (bot.MyGroups.ContainsKey(groupuuid) == false)
{
return Failure("Unknown group");
}
if (bot.NeedReloadGroupData(groupuuid) == true)
{
bot.GetClient.Groups.RequestGroupMembers(groupuuid);
return Failure("Updating");
}
ProcessAvatar(avatar);
if (avataruuid == UUID.Zero)
{
return Failure("avatar lookup");
}
bool status = bot.FastCheckInGroup(groupuuid, avataruuid);
if(status == false)
{
return BasicReply("Not in group");
}
bot.GetClient.Groups.EjectUser(groupuuid, avataruuid);
return BasicReply("Requested");
}
[About("Adds the avatar to the Group with the role \n if they are not in the group then it invites them aswell")]
[ReturnHints("Roles updated")]
[ReturnHints("Invite sent")]
[ReturnHints("Updating")]
[ReturnHints("Unknown group")]
[ReturnHints("Invaild group UUID")]
[ReturnHints("Invaild role UUID")]
[ReturnHints("Not in group")]
[ReturnHints("avatar lookup")]
[ArgHints("group", "URLARG", "the UUID of the group")]
[ArgHints("avatar", "URLARG", "the UUID of the avatar you wish to check with")]
[Route(HttpVerbs.Get, "/GroupAddRole/{group}/{avatar}/{role}/{token}")]
public object GroupAddRole(string group, string avatar, string role, string token)
{
if (tokens.Allow(token, "groups", "GroupAddRole", handleGetClientIP()) == false)
{
return Failure("Token not accepted");
}
if (UUID.TryParse(group, out UUID groupuuid) == false)
{
return Failure("Invaild group UUID");
}
if (UUID.TryParse(role, out UUID roleuuid) == false)
{
return Failure("Invaild role UUID");
}
if (bot.MyGroups.ContainsKey(groupuuid) == false)
{
return Failure("Unknown group");
}
if (bot.NeedReloadGroupData(groupuuid) == true)
{
bot.GetClient.Groups.RequestGroupMembers(groupuuid);
return Failure("Updating");
}
ProcessAvatar(avatar);
if (avataruuid == UUID.Zero)
{
return Failure("avatar lookup");
}
bool status = bot.FastCheckInGroup(groupuuid, avataruuid);
if (status == false)
{
bot.GetClient.Groups.Invite(groupuuid, new List<UUID>() { roleuuid }, avataruuid);
return BasicReply("Invite sent");
}
bot.GetClient.Groups.AddToRole(groupuuid, roleuuid, avataruuid);
return BasicReply("Roles updated");
}
[About("Eject selected avatar from group")]
[ReturnHints("Invite sent")]
[ReturnHints("Updating")]
[ReturnHints("Unknown group")]
[ReturnHints("Invaild group UUID")]
[ReturnHints("Already in group")]
[ReturnHints("avatar lookup")]
[ArgHints("group", "URLARG", "the UUID of the group")]
[ArgHints("avatar", "URLARG", "the UUID of the avatar you wish to check with")]
[ArgHints("role", "URLARG", "the UUID of the role to invite them at the word \"everyone\"")]
[Route(HttpVerbs.Get, "/GroupInvite/{group}/{avatar}/{role}/{token}")]
public object GroupInvite(string group, string avatar, string role, string token)
{
if (tokens.Allow(token, "groups", "GroupInvite", handleGetClientIP()) == false)
{
return Failure("Token not accepted");
}
if (UUID.TryParse(group, out UUID groupuuid) == false)
{
return Failure("Invaild group UUID");
}
if (bot.MyGroups.ContainsKey(groupuuid) == false)
{
return Failure("Unknown group");
}
if (bot.NeedReloadGroupData(groupuuid) == true)
{
bot.GetClient.Groups.RequestGroupMembers(groupuuid);
return Failure("Updating");
}
ProcessAvatar(avatar);
if (avataruuid == UUID.Zero)
{
return Failure("avatar lookup");
}
bool status = bot.FastCheckInGroup(groupuuid, avataruuid);
if (status == true)
{
return Failure("Already in group");
}
if(role == "everyone")
{
role = UUID.Zero.ToString();
}
if(UUID.TryParse(role,out UUID roleuuid) == false)
{
return Failure("Unable to process role UUID");
}
bot.GetClient.Groups.Invite(groupuuid, new List<UUID>() { roleuuid }, avataruuid);
return BasicReply("Invite sent");
}
[About("Sends a group notice (No attachments please use GroupnoticeWithAttachment to attach items!)")]
[ReturnHints("Sending notice")]
[ReturnHints("Unknown group")]
[ReturnHints("Invaild group UUID")]
[ReturnHints("Title empty")]
[ReturnHints("Message empty")]
[ArgHints("group", "URLARG", "the UUID of the group")]
[ArgHints("title", "Text", "The title of the group notice")]
[ArgHints("message", "Text", "The body of the group notice")]
[Route(HttpVerbs.Post, "/Groupnotice/{group}/{token}")]
public object Groupnotice(string group, [FormField] string title, [FormField] string message, string token)
{
if (tokens.Allow(token, "groups", "Groupnotice", handleGetClientIP()) == false)
{
return Failure("Token not accepted");
}
if (UUID.TryParse(group, out UUID groupuuid) == false)
{
return Failure("Invaild group UUID");
}
if (bot.MyGroups.ContainsKey(groupuuid) == false)
{
return Failure("Unknown group");
}
if (helpers.notempty(title) == false)
{
return Failure("Title empty");
}
if (helpers.notempty(message) == false)
{
return Failure("Message empty");
}
GroupNotice NewNotice = new GroupNotice();
NewNotice.Subject = title;
NewNotice.Message = message;
NewNotice.OwnerID = bot.GetClient.Self.AgentID;
bot.GetClient.Groups.SendGroupNotice(groupuuid, NewNotice);
return BasicReply("Sending notice");
}
[About("Activates the selected title")]
[ReturnHints("Switching title")]
[ReturnHints("Unknown group")]
[ReturnHints("Invaild group UUID")]
[ReturnHints("Invaild role UUID")]
[ArgHints("group", "URLARG", "the UUID of the group")]
[ArgHints("role", "URLARG", "tje UUID of the role")]
[Route(HttpVerbs.Get, "/GroupActiveTitle/{group}/{token}")]
public object GroupActiveTitle(string group, string role, string token)
{
if (tokens.Allow(token, "groups", "GroupActiveTitle", handleGetClientIP()) == false)
{
return Failure("Token not accepted");
}
if (UUID.TryParse(group, out UUID groupuuid) == false)
{
return Failure("Invaild group UUID");
}
if (UUID.TryParse(role, out UUID roleuuid) == false)
{
return Failure("Invaild role UUID");
}
if (bot.MyGroups.ContainsKey(groupuuid) == false)
{
return Failure("Unknown group");
}
bot.GetClient.Groups.ActivateTitle(groupuuid, roleuuid);
return BasicReply("Switching title");
}
[About("Sets the selected group to the active group")]
[ReturnHints("Switching active group")]
[ReturnHints("Unknown group")]
[ReturnHints("Invaild group UUID")]
[ArgHints("group", "URLARG", "the UUID of the group")]
[Route(HttpVerbs.Get, "/GroupActiveGroup/{group}/{token}")]
public object GroupActiveGroup(string group, string role, string token)
{
if (tokens.Allow(token, "groups", "GroupActiveTitle", handleGetClientIP()) == false)
{
return Failure("Token not accepted");
}
if (UUID.TryParse(group, out UUID groupuuid) == false)
{
return Failure("Invaild group UUID");
}
if (bot.MyGroups.ContainsKey(groupuuid) == false)
{
return Failure("Unknown group");
}
bot.GetClient.Groups.ActivateGroup(groupuuid);
return BasicReply("Switching active group");
}
[About("Sends a group notice with an attachment")]
[ReturnHints("Sending notice with attachment")]
[ReturnHints("Unknown group")]
[ReturnHints("Invaild group UUID")]
[ReturnHints("Invaild inventory UUID")]
[ReturnHints("Title empty")]
[ReturnHints("Message empty")]
[ArgHints("group", "URLARG", "the UUID of the group")]
[ArgHints("attachment", "URLARG", "the UUID of inventory you wish to attach")]
[ArgHints("title", "Text", "The title of the group notice")]
[ArgHints("message", "Text", "The body of the group notice")]
[Route(HttpVerbs.Post, "/Groupnotice/{group}/{attachment}/{token}")]
public object GroupnoticeWithAttachment(string group, [FormField] string title, [FormField] string message, string attachment, string token)
{
if (tokens.Allow(token, "groups", "GroupnoticeWithAttachment", handleGetClientIP()) == false)
{
return Failure("Token not accepted");
}
if (UUID.TryParse(group, out UUID groupuuid) == false)
{
return Failure("Invaild group UUID");
}
if (UUID.TryParse(attachment, out UUID inventoryuuid) == false)
{
return Failure("Invaild inventory UUID");
}
if (bot.MyGroups.ContainsKey(groupuuid) == false)
{
return Failure("Unknown group");
}
if (helpers.notempty(title) == false)
{
return Failure("Title empty");
}
if (helpers.notempty(message) == false)
{
return Failure("Message empty");
}
GroupNotice NewNotice = new GroupNotice();
NewNotice.Subject = title;
NewNotice.Message = message;
NewNotice.OwnerID = bot.GetClient.Self.AgentID;
NewNotice.AttachmentID = inventoryuuid;
bot.GetClient.Groups.SendGroupNotice(groupuuid, NewNotice);
return BasicReply("Sending notice with attachment");
}
[About("fetchs a list of all groups known to the bot")]
[ReturnHints("array UUID=name")]
[Route(HttpVerbs.Get, "/GetGroupList/{token}")]
public object GetGroupList(string token)
{
if (tokens.Allow(token, "groups", "GetGroupList", handleGetClientIP()) == false)
{
return Failure("Token not accepted");
}
Dictionary<string, string> grouppackage = new Dictionary<string, string>();
foreach (KeyValuePair<UUID, Group> entry in bot.MyGroups)
{
grouppackage.Add(entry.Value.ID.ToString(), entry.Value.Name);
}
return BasicReply(JsonConvert.SerializeObject(grouppackage));
}
[About("Requests the roles for the selected group<br/>Replys with GroupRoleDetails object formated as follows <ul><li>UpdateUnderway (Bool)</li><li>RoleDataAge (Int) [default -1]</li><li>Roles (KeyPair array of UUID=Name)</li></ul><br/>")]
[ReturnHints("GroupRoleDetails object")]
[ReturnHints("Group is not currently known")]
[ReturnHints("Invaild group UUID")]
[ReturnHints("Updating")]
[ArgHints("group", "URLARG", "the UUID of the group")]
[Route(HttpVerbs.Get, "/GetGroupRoles/{group}/{token}")]
public object GetGroupRoles(string group, string token)
{
if (tokens.Allow(token, "groups", "GetGroupRoles", handleGetClientIP()) == false)
{
return Failure("Token not accepted");
}
if (UUID.TryParse(group, out UUID groupuuid) == false)
{
return Failure("Invaild group UUID");
}
if (bot.MyGroups.ContainsKey(groupuuid) == false)
{
return Failure("Unknown group");
}
GroupRoleDetails reply = new GroupRoleDetails();
reply.UpdateUnderway = false;
reply.RoleDataAge = -1;
reply.Roles = new Dictionary<string, string>();
if (bot.MyGroupRolesStorage.ContainsKey(groupuuid) == false)
{
reply.UpdateUnderway = true;
}
else
{
long dif = helpers.UnixTimeNow() - bot.MyGroupRolesStorage[groupuuid].Key;
reply.RoleDataAge = dif;
if (dif >= 120)
{
reply.UpdateUnderway = true;
}
foreach (GroupRole gr in bot.MyGroupRolesStorage[groupuuid].Value)
{
reply.Roles.Add(gr.ID.ToString(), gr.Name);
}
}
if (reply.UpdateUnderway == true)
{
bot.GetClient.Groups.RequestGroupRoles(groupuuid);
if (reply.Roles.Count == 0)
{
return Failure("Updating");
}
}
return BasicReply(JsonConvert.SerializeObject(reply));
}
[About("fetchs a list of all groups with unread messages")]
[ReturnHints("array UUID")]
[Route(HttpVerbs.Get, "/GroupchatListAllUnreadGroups/{token}")]
public object GroupchatListAllUnreadGroups(string token)
{
if (tokens.Allow(token, "groups", "GroupchatListAllUnreadGroups", handleGetClientIP()) == false)
{
return Failure("Token not accepted");
}
return BasicReply(JsonConvert.SerializeObject(bot.UnreadGroupchatGroups()));
}
[About("fetchs a list of all groups with unread messages")]
[ReturnHints("true")]
[ReturnHints("false")]
[ReturnHints("Unknown group")]
[ReturnHints("group value is invaild")]
[ArgHints("group", "URLARG", "the UUID of the group")]
[Route(HttpVerbs.Get, "/GroupchatGroupHasUnread/{group}/{token}")]
public object GroupchatGroupHasUnread(string group,string token)
{
if (tokens.Allow(token, "groups", "GroupchatListAllUnreadGroups", handleGetClientIP()) == false)
{
return Failure("Token not accepted");
}
UUID groupUUID = UUID.Zero;
if(UUID.TryParse(group,out groupUUID) == false)
{
return Failure("group value is invaild");
}
if(bot.MyGroups.ContainsKey(groupUUID) == false)
{
return Failure("Unknown group");
}
return BasicReply(bot.GroupHasUnread(groupUUID).ToString());
}
[About("checks if there are any groups with unread messages")]
[ReturnHints("True|False")]
[Route(HttpVerbs.Get, "/GroupchatAnyUnread/{token}")]
public object haveunreadgroupchat(string token)
{
if (tokens.Allow(token, "groups", "GroupchatAnyUnread", handleGetClientIP()) == false)
{
return Failure("Token not accepted");
}
return BasicReply(bot.HasUnreadGroupchats().ToString());
}
[About("Clears all group chat buffers at once")]
[ReturnHints("ok")]
[Route(HttpVerbs.Get, "/GroupchatClearAll/{token}")]
public object GroupchatClearAll(string token)
{
if (tokens.Allow(token, "groups", "GroupchatClearAll", handleGetClientIP()) == false)
{
return Failure("Token not accepted");
}
bot.ClearAllGroupchat();
return BasicReply("ok");
}
[About("fetchs the groupchat history")]
[ReturnHints("Group UUID invaild")]
[ReturnHints("Group Chat")]
[ArgHints("group", "URLARG", "the UUID of the group")]
[Route(HttpVerbs.Get, "/GroupchatHistory/{group}/{token}")]
public object GroupchatHistory(string group, string token)
{
if (tokens.Allow(token, "groups", "GroupchatHistory", handleGetClientIP()) == false)
{
return Failure("Token not accepted");
}
if (UUID.TryParse(group, out UUID groupUUID) == false)
{
return Failure("Group UUID invaild");
}
return BasicReply(JsonConvert.SerializeObject(bot.GetGroupchat(groupUUID)));
}
[About("sends a message to the groupchat")]
[ArgHints("group", "URLARG", "UUID of the group")]
[ArgHints("message", "Text", "the message to send")]
[ReturnHints("Group UUID invaild")]
[ReturnHints("Processing")]
[ReturnHints("Opening groupchat")]
[ReturnHints("Sending")]
[Route(HttpVerbs.Post, "/Groupchat/{group}/{token}")]
public object Groupchat(string group, [FormField] string message, string token)
{
if (tokens.Allow(token, "groups", "Groupchat", handleGetClientIP()) == false)
{
return Failure("Token not accepted");
}
UUID groupUUID = UUID.Zero;
if (UUID.TryParse(group, out groupUUID) == false)
{
return Failure("group value is invaild");
}
if (bot.MyGroups.ContainsKey(groupUUID) == false)
{
return Failure("Unknown group");
}
if (bot.GetActiveGroupchatSessions.Contains(groupUUID) == false)
{
bot.GetClient.Self.RequestJoinGroupChat(groupUUID);
return Failure("Opening groupchat");
}
bot.GetClient.Self.InstantMessageGroup(groupUUID, message);
return BasicReply("Sending");
}
}
public class GroupRoleDetails
{
public bool UpdateUnderway { get; set; }
public Dictionary<string,string> Roles { get; set; }
public long RoleDataAge = 0;
}
}

View file

@ -1,38 +0,0 @@
using OpenMetaverse;
using System;
using System.Collections.Generic;
using System.Text;
namespace BetterSecondBot.Commands.Group
{
class GroupActiveGroup : CoreCommand_1arg
{
public override string[] ArgTypes { get { return new[] { "Group"}; } }
public override string[] ArgHints { get { return new[] { "Group UUID or Name" }; } }
public override string Helpfile { get { return "Sets the selected group to the active group"; } }
public override bool CallFunction(string[] args)
{
if (base.CallFunction(args) == true)
{
if (UUID.TryParse(args[0], out UUID group_uuid) != true)
{
foreach (KeyValuePair<UUID, OpenMetaverse.Group> G in bot.MyGroups)
{
if (G.Value.Name == args[0])
{
group_uuid = G.Key;
break;
}
}
}
if (group_uuid != UUID.Zero)
{
bot.GetClient.Groups.ActivateGroup(group_uuid);
return true;
}
return Failed("Unable to find group");
}
return false;
}
}
}

View file

@ -1,31 +0,0 @@
using OpenMetaverse;
using System;
using System.Collections.Generic;
using System.Text;
namespace BetterSecondBot.Commands.Group
{
class GroupActiveTitle : CoreCommand_2arg
{
public override string[] ArgTypes { get { return new[] { "UUID", "UUID"}; } }
public override string[] ArgHints { get { return new[] { "UUID of the group","UUID of the role" }; } }
public override string Helpfile { get { return "Activates the selected title"; } }
public override bool CallFunction(string[] args)
{
if (base.CallFunction(args) == true)
{
if(UUID.TryParse(args[0],out UUID group_uuid) == true)
{
if (UUID.TryParse(args[1], out UUID group_role) == true)
{
bot.GetClient.Groups.ActivateTitle(group_uuid, group_role);
return true;
}
return Failed("Unable to process group Role on arg 1");
}
return Failed("Unable to process group UUID on arg 1");
}
return false;
}
}
}

View file

@ -1,108 +0,0 @@
using System;
using OpenMetaverse;
using BetterSecondBotShared.logs;
namespace BetterSecondBot.Commands.Group
{
class GroupAddRole : CoreCommand_3arg
{
public override string[] ArgTypes { get { return new[] { "UUID", "Avatar", "UUID" }; } }
public override string[] ArgHints { get { return new[] { "GROUP", "Avatar [UUID or Firstname Lastname]", "Role" }; } }
public override string Helpfile { get { return "Adds the avatar [ARG 2] to the Group [ARG 1] with the role [ARG 3] if they are not in the group then it invites them"; } }
public override void Callback(string[] args, EventArgs e)
{
GroupMembersReplyEventArgs reply = (GroupMembersReplyEventArgs)e;
if (UUID.TryParse(args[0], out UUID target_group) == true)
{
if (reply.GroupID == target_group)
{
if (UUID.TryParse(args[1], out UUID target_avatar) == true)
{
if (UUID.TryParse(args[2], out UUID target_role) == true)
{
if(reply.Members.ContainsKey(target_avatar) == true)
{
bot.GetClient.Groups.AddToRole(target_group, target_role, target_avatar);
InfoBlob = "Role added to avatar: " + target_avatar.ToString() + "";
base.Callback(args, e, true);
}
else
{
InfoBlob = "{GroupAddRole} Member not in group to get role, passing to invite";
bot.GetCommandsInterface.Call("GroupInvite", String.Join("~#~", args), caller, "~#~");
base.Callback(args, e, true);
}
}
else
{
InfoBlob = "{ GroupAddRole} Unable to unpack role as part of the callback";
base.Callback(args, e, false);
}
}
else
{
InfoBlob = "{GroupAddRole} Unable to unpack avatar as part of the callback";
base.Callback(args, e, false);
}
}
else
{
InfoBlob = "Callback sent for the wrong group as part of GroupAddRole!";
base.Callback(args, e, false);
}
}
else
{
InfoBlob = "{GroupAddRole} Unable to unpack group as part of the callback";
base.Callback(args, e, false);
}
}
public override bool CallFunction(string[] args)
{
if (base.CallFunction(args) == true)
{
if (UUID.TryParse(args[0], out UUID target_group) == true)
{
if (UUID.TryParse(args[1], out UUID _) == true)
{
if (UUID.TryParse(args[2], out UUID _) == true)
{
if (bot.MyGroups.ContainsKey(target_group) == true)
{
if (bot.CreateAwaitEventReply("groupmembersreply", this, args) == true)
{
bot.GetClient.Groups.RequestGroupMembers(target_group);
InfoBlob = "Requesting group membership";
return true;
}
else
{
return Failed("Unable to await reply");
}
}
else
{
return Failed("I am not a member of that group");
}
}
else
{
return Failed("Invaild role UUID");
}
}
else
{
return Failed("Invaild avatar UUID");
}
}
else
{
return Failed("Invaild group UUID");
}
}
return false;
}
}
}

View file

@ -1,45 +0,0 @@
using System;
using System.Collections.Generic;
using OpenMetaverse;
using BetterSecondBotShared.logs;
namespace BetterSecondBot.Commands.Group
{
public class GroupEject : CoreCommand_2arg
{
public override string[] ArgTypes { get { return new[] { "UUID", "Avatar" }; } }
public override string[] ArgHints { get { return new[] { "GROUP", "Avatar [UUID or Firstname Lastname]"}; } }
public override string Helpfile { get { return "Eject selected avatar from group"; } }
public override bool CallFunction(string[] args)
{
if (base.CallFunction(args) == true)
{
if (UUID.TryParse(args[0], out UUID target_group) == true)
{
if (UUID.TryParse(args[1], out UUID target_avatar) == true)
{
if (bot.MyGroups.ContainsKey(target_group) == true)
{
bot.GetClient.Groups.EjectUser(target_group, target_avatar);
return true;
}
else
{
return Failed("I am not a member of that group");
}
}
else
{
return Failed("Invaild avatar UUID");
}
}
else
{
return Failed("Invaild group UUID");
}
}
return false;
}
}
}

View file

@ -1,65 +0,0 @@
using System;
using System.Collections.Generic;
using OpenMetaverse;
using BetterSecondBotShared.logs;
namespace BetterSecondBot.Commands.Group
{
public class GroupInvite : CoreCommand_2arg
{
public override string[] ArgTypes { get { return new[] { "UUID", "Avatar", "UUID" }; } }
public override string[] ArgHints { get { return new[] { "GROUP", "Avatar [UUID or Firstname Lastname]", "Role" }; } }
public override string Helpfile { get { return "Invites the avatar [ARG 2] to the Group [ARG 1] {optional with the Role [ARG 3]} otherwise to role Everyone"; } }
protected void ForRealGroupInvite(string[] args,UUID group,UUID avatar)
{
UUID target_role = UUID.Zero;
if (args.Length == 3)
{
if(UUID.TryParse(args[2], out target_role) == false)
{
LogFormater.Warn("GroupInvite: Role uuid not vaild using everyone");
}
}
bot.GetClient.Groups.Invite(group, new List<UUID>() { target_role }, avatar);
}
public override bool CallFunction(string[] args)
{
if (base.CallFunction(args) == true)
{
if (UUID.TryParse(args[0], out UUID target_group) == true)
{
if (UUID.TryParse(args[1], out UUID target_avatar) == true)
{
if (bot.MyGroups.ContainsKey(target_group) == true)
{
if (bot.GetAllowGroupInvite(target_avatar, target_group) == true)
{
bot.GroupInviteLockoutArm(target_avatar,target_group); // enable 120 sec cooldown
ForRealGroupInvite(args, target_group, target_avatar);
return true;
}
else
{
return Failed("Group invite to this avatar is on 120sec cooldown");
}
}
else
{
return Failed("I am not a member of that group");
}
}
else
{
return Failed("Invaild avatar UUID");
}
}
else
{
return Failed("Invaild group UUID");
}
}
return false;
}
}
}

View file

@ -1,58 +0,0 @@
using BetterSecondBotShared.logs;
using OpenMetaverse;
using System;
using System.Collections.Generic;
using System.Text;
namespace BetterSecondBot.Commands.Group
{
class GroupInviteNoLimiter: CoreCommand_2arg
{
public override string[] ArgTypes { get { return new[] { "UUID", "Avatar", "UUID" }; } }
public override string[] ArgHints { get { return new[] { "GROUP", "Avatar [UUID or Firstname Lastname]", "Role" }; } }
public override string Helpfile { get { return "see GroupInvite, note: This command bypasses the limiter use at your own risk!"; } }
protected void ForRealGroupInvite(string[] args, UUID group, UUID avatar)
{
UUID target_role = UUID.Zero;
if (args.Length == 3)
{
if (UUID.TryParse(args[2], out target_role) == false)
{
LogFormater.Warn("GroupInviteNoLimiter: Role uuid not vaild using everyone");
}
}
bot.GetClient.Groups.Invite(group, new List<UUID>() { target_role }, avatar);
}
public override bool CallFunction(string[] args)
{
if (base.CallFunction(args) == true)
{
if (UUID.TryParse(args[0], out UUID target_group) == true)
{
if (UUID.TryParse(args[1], out UUID target_avatar) == true)
{
if (bot.MyGroups.ContainsKey(target_group) == true)
{
ForRealGroupInvite(args, target_group, target_avatar);
return true;
}
else
{
return Failed("I am not a member of that group");
}
}
else
{
return Failed("Invaild avatar UUID");
}
}
else
{
return Failed("Invaild group UUID");
}
}
return false;
}
}
}

View file

@ -1,53 +0,0 @@
using BetterSecondBotShared.Static;
using OpenMetaverse;
namespace BetterSecondBot.Commands.Group
{
class Groupnotice : CoreCommand_2arg
{
public override string[] ArgTypes { get { return new[] { "UUID", "TEXT","TEXT","TEXT" }; } }
public override string[] ArgHints { get { return new[] { "Group", "Message/Title", "Message","Inventory UUID" }; } }
public override string Helpfile { get { return "Sends a group notice to [ARG 1] with the message [ARG 2]<hr/>if given 3 Args: Sends a group notice to [ARG 1] with the title [ARG 2] and the message [ARG 3]<br/>if [ARG 4] is given then it also sends the notice with an attachment"; } }
public override bool CallFunction(string[] args)
{
if (base.CallFunction(args) == true)
{
if (UUID.TryParse(args[0], out UUID targetgroup) == true)
{
if (bot.MyGroups.ContainsKey(targetgroup) == true)
{
string Noticetitle = "GroupNotice@"+ helpers.UnixTimeNow().ToString()+"";
string Noticemessage = args[1];
if (args.Length >= 3)
{
Noticetitle = args[1];
Noticemessage = args[2];
}
GroupNotice NewNotice = new GroupNotice();
NewNotice.Subject = Noticetitle;
NewNotice.Message = Noticemessage;
NewNotice.OwnerID = bot.GetClient.Self.AgentID;
if (args.Length == 4)
{
if (UUID.TryParse(args[3], out UUID result) == true)
{
NewNotice.AttachmentID = result;
}
}
bot.GetClient.Groups.SendGroupNotice(targetgroup, NewNotice);
return true;
}
else
{
return Failed("Unkown group");
}
}
else
{
return Failed("Invaild UUID");
}
}
return false;
}
}
}

View file

@ -1,92 +0,0 @@
using System;
using System.Collections.Generic;
using System.Text;
using Newtonsoft.Json;
using OpenMetaverse;
namespace BetterSecondBot.Commands.Group
{
public class IsGroupMember : CoreCommand_3arg
{
public override string[] ArgTypes { get { return new[] { "UUID", "Mixed", "Avatar" }; } }
public override string[] ArgHints { get { return new[] { "Group", "Smart reply [Channel|IM uuid|http url]", "Avatar [UUID or Firstname Lastname]" }; } }
public override string Helpfile { get { return "Returns if the selected user is in the group or not"; } }
public override bool CallFunction(string[] args)
{
if (base.CallFunction(args) == true)
{
if (UUID.TryParse(args[0], out UUID targetgroup) == true)
{
if (UUID.TryParse(args[2], out UUID testavatar) == true)
{
if (bot.FastCheckInGroup(targetgroup, testavatar) == true)
{
Dictionary<string, string> reply = new Dictionary<string, string>
{
{ "group", args[0] },
{ "avatar", args[2] },
{ "ingroup", "1" }
};
return bot.GetCommandsInterface.SmartCommandReply(true, args[1], JsonConvert.SerializeObject(reply), CommandName);
}
else
{
if (bot.MyGroups.ContainsKey(targetgroup) == true)
{
if (bot.CreateAwaitEventReply("groupmembersreply", this, args) == true)
{
bot.GetClient.Groups.RequestGroupMembers(targetgroup);
InfoBlob = "Requesting group membership";
return true;
}
else
{
return Failed("Unable to await reply");
}
}
else
{
return Failed("Unknown group");
}
}
}
else
{
return Failed("Unable to find avatar");
}
}
else
{
return Failed("Invaild UUID");
}
}
return false;
}
public override void Callback(string[] args, EventArgs e)
{
if (UUID.TryParse(args[2], out UUID testavatar) == true)
{
GroupMembersReplyEventArgs members_reply = (GroupMembersReplyEventArgs)e;
string return_status = "0";
foreach (KeyValuePair<UUID, GroupMember> data in members_reply.Members)
{
if (data.Value.ID == testavatar)
{
return_status = "1";
break;
}
}
Dictionary<string, string> reply = new Dictionary<string, string>
{
{ "group", args[0] },
{ "avatar", args[2] },
{ "ingroup", return_status }
};
bot.GetCommandsInterface.SmartCommandReply(true, args[1], JsonConvert.SerializeObject(reply), CommandName);
}
base.Callback(args, e);
}
}
}

View file

@ -1,20 +0,0 @@
using System;
using System.Collections.Generic;
using System.Text;
using OpenMetaverse;
namespace BetterSecondBot.Commands.Group
{
public class GetGroupList : CoreGroupCommand_SmartReply_auto
{
public override string Helpfile { get { return "Gets a list of groups Json encoded"; } }
protected override string RunFunction()
{
foreach (KeyValuePair<UUID, OpenMetaverse.Group> groupdata in bot.MyGroups)
{
collection.Add(groupdata.Value.Name, groupdata.Key.ToString());
}
return "grouplist=loaded";
}
}
}

View file

@ -1,58 +0,0 @@
using System;
using System.Collections.Generic;
using System.Text;
using OpenMetaverse;
namespace BetterSecondBot.Commands.Group
{
public class GetGroupMembers : CoreCommand_2arg
{
public override string[] ArgTypes { get { return new[] { "UUID", "Mixed" }; } }
public override string[] ArgHints { get { return new[] { "Group", "Smart reply [Channel|IM uuid|http url]" }; } }
public override string Helpfile { get { return "Gets membership of a group plus online status "; } }
public override bool CallFunction(string[] args)
{
if (base.CallFunction(args) == true)
{
if (UUID.TryParse(args[0], out UUID targetgroup) == true)
{
if (bot.MyGroups.ContainsKey(targetgroup) == true)
{
if (bot.CreateAwaitEventReply("groupmembersreply", this, args) == true)
{
bot.GetClient.Groups.RequestGroupMembers(targetgroup);
InfoBlob = "Requesting group membership";
return true;
}
else
{
return Failed("Unable to await reply");
}
}
else
{
return Failed("Unknown group");
}
}
else
{
return Failed("Invaild UUID");
}
}
return false;
}
public override void Callback(string[] args, EventArgs e)
{
GroupMembersReplyEventArgs members_reply = (GroupMembersReplyEventArgs)e;
Dictionary<string, string> collection = new Dictionary<string, string>();
foreach (KeyValuePair<UUID, GroupMember> data in members_reply.Members)
{
collection.Add(data.Key.ToString(), data.Value.OnlineStatus);
}
bot.GetCommandsInterface.SmartCommandReply(true, args[1], "group=" + args[0], CommandName, collection);
base.Callback(args, e);
}
}
}

View file

@ -1,50 +0,0 @@
using System;
using System.Collections.Generic;
using System.Text;
using OpenMetaverse;
namespace BetterSecondBot.Commands.Group
{
public class GetGroupRoles : CoreGroupCommand_SmartReply_Group
{
public override string Helpfile { get { return "Gets a list of group roles Json encoded "; } }
public override bool CallFunction(string[] args)
{
if (base.CallFunction(args) == true)
{
if (UUID.TryParse(args[1], out UUID group) == true)
{
if (bot.CreateAwaitEventReply("grouproles", this, args) == true)
{
InfoBlob = "Requesting now";
bot.GetClient.Groups.RequestGroupRoles(group);
return true;
}
else
{
return Failed("Unable to await reply");
}
}
else
{
return Failed("Invaild group UUID");
}
}
return false;
}
public override void Callback(string[] args, EventArgs e)
{
GroupRolesDataReplyEventArgs rolesData = (GroupRolesDataReplyEventArgs)e;
foreach(KeyValuePair<UUID,GroupRole> data in rolesData.Roles)
{
if (data.Key != UUID.Zero)
{
collection.Add(data.Value.Name, data.Value.ID.ToString());
}
}
bot.GetCommandsInterface.SmartCommandReply(true,args[0], "group=" + args[1], CommandName,collection);
base.Callback(args, e);
}
}
}

View file

@ -1,58 +0,0 @@
using OpenMetaverse;
using System.Collections.Generic;
namespace BetterSecondBot.Commands.Group
{
public abstract class CoreGroupCommand_SmartReply_auto : CoreCommand_SmartReply_1arg
{
protected virtual string RunFunction()
{
return "";
}
public override bool CallFunction(string[] args)
{
if (base.CallFunction(args) == true)
{
return bot.GetCommandsInterface.SmartCommandReply(true, args[0], RunFunction(), CommandName, collection);
}
return bot.GetCommandsInterface.SmartCommandReply(false, args[0], "", CommandName);
}
}
public abstract class CoreGroupCommand_SmartReply_Group : CoreCommand_2arg
{
protected Dictionary<string, string> collection = new Dictionary<string, string>();
public override string[] ArgTypes { get { return new[] { "Mixed", "UUID" }; } }
public override string[] ArgHints { get { return new[] { "Smart reply [Channel|IM uuid|http url]", "Group" }; } }
}
public abstract class CoreGroupCommand_SmartReply_Group_auto : CoreGroupCommand_SmartReply_Group
{
protected virtual string RunFunction(UUID group)
{
return "";
}
public override bool CallFunction(string[] args)
{
if (base.CallFunction(args) == true)
{
if (UUID.TryParse(args[1], out UUID targetgroup) == true)
{
if (bot.MyGroups.ContainsKey(targetgroup) == true)
{
return bot.GetCommandsInterface.SmartCommandReply(true,args[0], RunFunction(targetgroup), CommandName);
}
else
{
return Failed("Unknown group");
}
}
else
{
return Failed("Invaild UUID");
}
}
return false;
}
}
}

View file

@ -1,62 +0,0 @@
using OpenMetaverse;
using System;
namespace BetterSecondBot.Commands.Group
{
class Groupchat : CoreCommand_2arg
{
public override string[] ArgTypes { get { return new[] { "UUID","TEXT" }; } }
public override string[] ArgHints { get { return new[] { "Group","Message" }; } }
public override string Helpfile { get { return "Sends a message [ARG 2] to the group [ARG 1]"; } }
public override bool CallFunction(string[] args)
{
if (base.CallFunction(args) == true)
{
if (UUID.TryParse(args[0], out UUID targetgroup) == true)
{
if (bot.MyGroups.ContainsKey(targetgroup) == true)
{
if (bot.GetActiveGroupchatSessions.Contains(targetgroup) == true)
{
Callback(args, null);
return true;
}
else
{
if (bot.CreateAwaitEventReply("groupchatjoin", this, args) == true)
{
bot.GetClient.Self.RequestJoinGroupChat(targetgroup);
return true;
}
else
{
return Failed("Unable to await reply");
}
}
}
else
{
return Failed("Unkown group");
}
}
else
{
return Failed("Invaild UUID");
}
}
return false;
}
public override void Callback(string[] args, EventArgs e)
{
if (UUID.TryParse(args[0], out UUID targetgroup) == true)
{
bot.GetClient.Self.InstantMessageGroup(targetgroup, args[1]);
base.Callback(args, e);
}
else
{
base.Callback(args, e,false);
}
}
}
}

View file

@ -1,11 +0,0 @@
namespace BetterSecondBot.Commands.Group
{
class GroupchatAnyUnread : CoreGroupCommand_SmartReply_auto
{
public override string Helpfile { get { return "Returns True|False via the smart reply target if there are any unread group ims"; } }
protected override string RunFunction()
{
return "groupchatunread="+bot.HasUnreadGroupchats().ToString();
}
}
}

View file

@ -1,16 +0,0 @@
namespace BetterSecondBot.Commands.Group
{
class GroupchatClearAll : CoreCommand
{
public override string Helpfile { get { return "Clears all group chat buffers at once"; } }
public override bool CallFunction(string[] args)
{
if (base.CallFunction(args) == true)
{
bot.ClearAllGroupchat();
return true;
}
return false;
}
}
}

View file

@ -1,15 +0,0 @@
using OpenMetaverse;
namespace BetterSecondBot.Commands.Group
{
class GroupchatGroupHasUnread : CoreGroupCommand_SmartReply_Group_auto
{
public override string Helpfile { get { return "Returns True|False via the smart reply target if there are any unread group ims for the group [ARG 2]"; } }
protected override string RunFunction(UUID targetgroup)
{
return ""+targetgroup.ToString()+"=" + bot.GroupHasUnread(targetgroup).ToString();
}
}
}

View file

@ -1,22 +0,0 @@
using System;
using System.Linq;
using Microsoft.VisualBasic.CompilerServices;
using OpenMetaverse;
namespace BetterSecondBot.Commands.Group
{
class GroupchatHistory : CoreGroupCommand_SmartReply_Group_auto
{
public override string Helpfile { get { return "Returns the chat history for the selected group [ARG 2] via smart reply [ARG 1]"; } }
protected override string RunFunction(UUID targetgroup)
{
int entry = 1;
foreach(string A in bot.GetGroupchat(targetgroup))
{
collection.Add(entry.ToString(),A);
entry++;
}
return "group="+targetgroup.ToString()+"";
}
}
}

View file

@ -1,21 +0,0 @@
using OpenMetaverse;
using System.Text;
namespace BetterSecondBot.Commands.Group
{
public class GroupchatListAllUnreadGroups : CoreGroupCommand_SmartReply_auto
{
public override string Helpfile { get { return "Returns what groups have unread messages "; } }
protected override string RunFunction()
{
int entry = 1;
foreach (UUID group in bot.UnreadGroupchatGroups())
{
collection.Add(entry.ToString(),group.ToString());
entry++;
}
return "count="+collection.Count.ToString();
}
}
}

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;
}
}
}

33
Core/Commands/Home.cs Normal file
View file

@ -0,0 +1,33 @@
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_Home : WebApiControllerWithTokens
{
public HTTP_Home(SecondBot mainbot, TokenStorage setuptokens) : base(mainbot, setuptokens) { }
[About("Makes the bot teleport to its home region")]
[ReturnHints("ok")]
[Route(HttpVerbs.Get, "/GoHome/{token}")]
public object GoHome(string group, string token)
{
if (tokens.Allow(token, "groups", "GetGroupMembers", handleGetClientIP()) == false)
{
return Failure("Token not accepted");
}
bot.GotoNextHomeRegion();
return BasicReply("ok");
}
}
}

View file

@ -1,16 +0,0 @@
namespace BetterSecondBot.Commands.Home
{
public class GoHome : CoreCommand
{
public override string Helpfile { get { return "Makes the bot teleport to its home region"; } }
public override bool CallFunction(string[] args)
{
if (base.CallFunction(args) == true)
{
bot.GotoNextHomeRegion();
return true;
}
return false;
}
}
}

View file

@ -1,16 +0,0 @@
namespace BetterSecondBot.Commands.Home
{
public class ResetAtHome : CoreCommand
{
public override string Helpfile { get { return "Resets the at home lockouts"; } }
public override bool CallFunction(string[] args)
{
if(base.CallFunction(args) == true)
{
bot.ResetAtHome();
return true;
}
return false;
}
}
}

89
Core/Commands/Im.cs Normal file
View file

@ -0,0 +1,89 @@
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;
namespace BetterSecondBot.HttpService
{
public class HTTP_IM : WebApiControllerWithTokens
{
public HTTP_IM(SecondBot mainbot, TokenStorage setuptokens) : base(mainbot, setuptokens) { }
[About("gets a full list of all chat windows")]
[ReturnHints("array UUID = Name")]
[Route(HttpVerbs.Get, "/chatwindows/{token}")]
public object chatwindows(string token)
{
if (tokens.Allow(token, "im", "chatwindows", handleGetClientIP()) == false)
{
return BasicReply("Token not accepted");
}
return BasicReply(JsonConvert.SerializeObject(bot.GetIMChatWindowKeyNames()));
}
[About("gets a list of chat windows with unread messages")]
[ReturnHints("array of UUID")]
[Route(HttpVerbs.Get, "/listwithunread/{token}")]
public object listwithunread(string group, string token)
{
if (tokens.Allow(token, "im", "listwithunread", handleGetClientIP()) == false)
{
return BasicReply("Token not accepted");
}
List<UUID> unreadimwindows = new List<UUID>();
foreach (UUID window in bot.IMChatWindows())
{
if (bot.ImChatWindowHasUnread(window) == true)
{
unreadimwindows.Add(window);
}
}
return BasicReply(JsonConvert.SerializeObject(unreadimwindows));
}
[About("gets if there are any unread im messages at all")]
[ReturnHints("True|False")]
[Route(HttpVerbs.Get, "/haveunreadims/{token}")]
public object haveunreadims(string token)
{
if (tokens.Allow(token, "im", "haveunreadims", handleGetClientIP()) == false)
{
return BasicReply("Token not accepted");
}
bool reply = false;
foreach (UUID window in bot.IMChatWindows())
{
if (bot.ImChatWindowHasUnread(window) == true)
{
reply = true;
break;
}
}
return BasicReply(reply.ToString());
}
[About("gets the chat from the selected window")]
[ArgHints("window", "URLARG", "the UUID of the chat window")]
[ReturnHints("Window UUID invaild")]
[ReturnHints("Array of text")]
[Route(HttpVerbs.Get, "/getimchat/{window}/{token}")]
public object getimchat(string window, string token)
{
if (tokens.Allow(token, "im", "getimchat", handleGetClientIP()) == false)
{
return BasicReply("Token not accepted");
}
if (UUID.TryParse(window, out UUID windowUUID) == false)
{
return BasicReply("Window UUID invaild");
}
return BasicReply(JsonConvert.SerializeObject(bot.GetIMChatWindow(windowUUID)));
}
}
}

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));
}
}
}

View file

@ -1,21 +0,0 @@
namespace BetterSecondBot.Commands.Info
{
public class Balance : CoreCommand_SmartReply_1arg
{
public override string Helpfile { get { return "Requests the current balance and sends that via the smart reply target and then requests the balance to update."; } }
public override bool CallFunction(string[] args)
{
if (base.CallFunction(args) == true)
{
if (bot.GetAllowFunds == true)
{
bool status = bot.GetCommandsInterface.SmartCommandReply(true,args[0], bot.GetClient.Self.Balance.ToString(), CommandName);
bot.GetClient.Self.RequestBalance();
return status;
}
return bot.GetCommandsInterface.SmartCommandReply(false,args[0], "0", CommandName);
}
return false;
}
}
}

View file

@ -1,15 +0,0 @@
namespace BetterSecondBot.Commands.Info
{
public class GetPosition : CoreCommand_SmartReply_1arg
{
public override string Helpfile { get { return "Requests the Position and sends that via the smart reply target"; } }
public override bool CallFunction(string[] args)
{
if (base.CallFunction(args) == true)
{
return bot.GetCommandsInterface.SmartCommandReply(true,args[0], bot.GetClient.Self.RelativePosition.ToString(), CommandName);
}
return false;
}
}
}

View file

@ -1,16 +0,0 @@
namespace BetterSecondBot.Commands.Info
{
public class ParcelName : ParcelCommand_CheckParcel_1arg_smart
{
public override string Helpfile { get { return "Fetchs the current parcels name and sends it to the smart reply target on [ARG 1]"; } }
public override bool CallFunction(string[] args)
{
if (base.CallFunction(args) == true)
{
return bot.GetCommandsInterface.SmartCommandReply(true,args[0], targetparcel.Name, CommandName);
}
return false;
}
}
}

View file

@ -1,15 +0,0 @@
namespace BetterSecondBot.Commands.Info
{
public class SimName : CoreCommand_SmartReply_1arg
{
public override string Helpfile { get { return "Requests the current Sim Position and sends that via the smart reply target"; } }
public override bool CallFunction(string[] args)
{
if (base.CallFunction(args) == true)
{
return bot.GetCommandsInterface.SmartCommandReply(true,args[0], bot.GetClient.Network.CurrentSim.Name, CommandName);
}
return false;
}
}
}

View file

@ -1,17 +0,0 @@
using BetterSecondBotShared.Static;
namespace BetterSecondBot.Commands.Info
{
public class UnixTimeNow : CoreCommand_SmartReply_1arg
{
public override string Helpfile { get { return "Requests the current unixtime at the bot and sends that via the smart reply target"; } }
public override bool CallFunction(string[] args)
{
if (base.CallFunction(args) == true)
{
return bot.GetCommandsInterface.SmartCommandReply(true,args[0], helpers.UnixTimeNow().ToString(), CommandName);
}
return false;
}
}
}

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;
}
}
}

Some files were not shown because too many files have changed in this diff Show more