From b70ef7c18655623046d44a9289fbff94a6a46fff Mon Sep 17 00:00:00 2001 From: Madpeterz <57852827+Madpeterz@users.noreply.github.com> Date: Wed, 17 Feb 2021 13:25:27 +0000 Subject: [PATCH] Move http into core getting ready to replace the old commands system --- BetterSecondbot/BetterSecondbot.csproj | 1 - BetterSecondbot/HttpService/Parcel.cs | 50 -- BetterSecondbot/WikiMake/wikimake.cs | 10 +- Core/Commands/Movement/AutoPilot.cs | 56 -- Core/Commands/Movement/teleport.cs | 66 -- Core/Commands/Parcel/AbandonLand.cs | 17 - Core/Commands/Parcel/GetParcelBanlist.cs | 27 - Core/Commands/Parcel/GetParcelDesc.cs | 16 - Core/Commands/Parcel/GetParcelFlags.cs | 82 --- Core/Commands/Parcel/ParcelBan.cs | 91 --- Core/Commands/Parcel/ParcelBuy.cs | 33 - Core/Commands/Parcel/ParcelCleanAndSell.cs | 92 --- Core/Commands/Parcel/ParcelCommandHelper.cs | 99 --- Core/Commands/Parcel/ParcelDeedToGroup.cs | 22 - Core/Commands/Parcel/ParcelFreeze.cs | 35 - Core/Commands/Parcel/ParcelPrimCountAvatar.cs | 77 --- Core/Commands/Parcel/ParcelPrimCountTotal.cs | 51 -- Core/Commands/Parcel/ParcelReturnObjects.cs | 71 -- Core/Commands/Parcel/ParcelReturnTargeted.cs | 29 - Core/Commands/Parcel/ParcelSetMedia.cs | 170 ----- Core/Commands/Parcel/SetParcelDesc.cs | 20 - Core/Commands/Parcel/SetParcelFlag.cs | 89 --- Core/Commands/Parcel/SetParcelMusic.cs | 32 - Core/Commands/Parcel/SetParcelName.cs | 20 - Core/Commands/Parcel/SetParcelSale.cs | 56 -- Core/Commands/Parcel/eject.cs | 35 - Core/Commands/Prims/RezObject.cs | 47 -- .../Prims/TransferInventoryToObject.cs | 74 --- Core/Commands/Prims/UnRezObject.cs | 45 -- Core/Commands/Script/scriptHttp.cs | 85 --- Core/Commands/Script/scriptSend.cs | 45 -- Core/Commands/Self/GetLastCommands.cs | 24 - Core/Commands/Self/SetPermFlag.cs | 51 -- Core/Commands/Self/logout.cs | 34 - .../Commands/StreamAdmin/FetchNextNotecard.cs | 69 -- Core/Core.csproj | 1 + .../HttpService/Animation.cs | 4 +- .../HttpService/Avatars.cs | 0 {BetterSecondbot => Core}/HttpService/Chat.cs | 11 +- {BetterSecondbot => Core}/HttpService/Core.cs | 43 -- .../HttpService/Dialogs.cs | 0 .../HttpService/Discord.cs | 0 .../HttpService/Estate.cs | 4 +- .../HttpService/Friends.cs | 0 .../HttpService/Funds.cs | 0 .../HttpService/Group.cs | 4 +- {BetterSecondbot => Core}/HttpService/Home.cs | 4 +- .../HttpService/HttpAsService.cs | 29 +- {BetterSecondbot => Core}/HttpService/Im.cs | 0 {BetterSecondbot => Core}/HttpService/Info.cs | 4 +- .../HttpService/Inventory.cs | 83 ++- Core/HttpService/Movement.cs | 131 ++++ Core/HttpService/Parcel.cs | 620 ++++++++++++++++++ {BetterSecondbot => Core}/HttpService/Self.cs | 98 ++- Core/HttpService/StreamAdmin.cs | 90 +++ Shared/Staic/Helpers.cs | 11 + 56 files changed, 1070 insertions(+), 1888 deletions(-) delete mode 100644 BetterSecondbot/HttpService/Parcel.cs delete mode 100644 Core/Commands/Movement/AutoPilot.cs delete mode 100644 Core/Commands/Movement/teleport.cs delete mode 100644 Core/Commands/Parcel/AbandonLand.cs delete mode 100644 Core/Commands/Parcel/GetParcelBanlist.cs delete mode 100644 Core/Commands/Parcel/GetParcelDesc.cs delete mode 100644 Core/Commands/Parcel/GetParcelFlags.cs delete mode 100644 Core/Commands/Parcel/ParcelBan.cs delete mode 100644 Core/Commands/Parcel/ParcelBuy.cs delete mode 100644 Core/Commands/Parcel/ParcelCleanAndSell.cs delete mode 100644 Core/Commands/Parcel/ParcelCommandHelper.cs delete mode 100644 Core/Commands/Parcel/ParcelDeedToGroup.cs delete mode 100644 Core/Commands/Parcel/ParcelFreeze.cs delete mode 100644 Core/Commands/Parcel/ParcelPrimCountAvatar.cs delete mode 100644 Core/Commands/Parcel/ParcelPrimCountTotal.cs delete mode 100644 Core/Commands/Parcel/ParcelReturnObjects.cs delete mode 100644 Core/Commands/Parcel/ParcelReturnTargeted.cs delete mode 100644 Core/Commands/Parcel/ParcelSetMedia.cs delete mode 100644 Core/Commands/Parcel/SetParcelDesc.cs delete mode 100644 Core/Commands/Parcel/SetParcelFlag.cs delete mode 100644 Core/Commands/Parcel/SetParcelMusic.cs delete mode 100644 Core/Commands/Parcel/SetParcelName.cs delete mode 100644 Core/Commands/Parcel/SetParcelSale.cs delete mode 100644 Core/Commands/Parcel/eject.cs delete mode 100644 Core/Commands/Prims/RezObject.cs delete mode 100644 Core/Commands/Prims/TransferInventoryToObject.cs delete mode 100644 Core/Commands/Prims/UnRezObject.cs delete mode 100644 Core/Commands/Script/scriptHttp.cs delete mode 100644 Core/Commands/Script/scriptSend.cs delete mode 100644 Core/Commands/Self/GetLastCommands.cs delete mode 100644 Core/Commands/Self/SetPermFlag.cs delete mode 100644 Core/Commands/Self/logout.cs delete mode 100644 Core/Commands/StreamAdmin/FetchNextNotecard.cs rename {BetterSecondbot => Core}/HttpService/Animation.cs (91%) rename {BetterSecondbot => Core}/HttpService/Avatars.cs (100%) rename {BetterSecondbot => Core}/HttpService/Chat.cs (84%) rename {BetterSecondbot => Core}/HttpService/Core.cs (66%) rename {BetterSecondbot => Core}/HttpService/Dialogs.cs (100%) rename {BetterSecondbot => Core}/HttpService/Discord.cs (100%) rename {BetterSecondbot => Core}/HttpService/Estate.cs (95%) rename {BetterSecondbot => Core}/HttpService/Friends.cs (100%) rename {BetterSecondbot => Core}/HttpService/Funds.cs (100%) rename {BetterSecondbot => Core}/HttpService/Group.cs (96%) rename {BetterSecondbot => Core}/HttpService/Home.cs (84%) rename {BetterSecondbot => Core}/HttpService/HttpAsService.cs (89%) rename {BetterSecondbot => Core}/HttpService/Im.cs (100%) rename {BetterSecondbot => Core}/HttpService/Info.cs (94%) rename {BetterSecondbot => Core}/HttpService/Inventory.cs (62%) create mode 100644 Core/HttpService/Movement.cs create mode 100644 Core/HttpService/Parcel.cs rename {BetterSecondbot => Core}/HttpService/Self.cs (55%) create mode 100644 Core/HttpService/StreamAdmin.cs diff --git a/BetterSecondbot/BetterSecondbot.csproj b/BetterSecondbot/BetterSecondbot.csproj index ccc4cd3..b4c29db 100644 --- a/BetterSecondbot/BetterSecondbot.csproj +++ b/BetterSecondbot/BetterSecondbot.csproj @@ -25,7 +25,6 @@ - all diff --git a/BetterSecondbot/HttpService/Parcel.cs b/BetterSecondbot/HttpService/Parcel.cs deleted file mode 100644 index 0145e01..0000000 --- a/BetterSecondbot/HttpService/Parcel.cs +++ /dev/null @@ -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
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 reply = new Dictionary(); - 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"); - } - } -} diff --git a/BetterSecondbot/WikiMake/wikimake.cs b/BetterSecondbot/WikiMake/wikimake.cs index fcb9b60..832274c 100644 --- a/BetterSecondbot/WikiMake/wikimake.cs +++ b/BetterSecondbot/WikiMake/wikimake.cs @@ -554,12 +554,12 @@ namespace BetterSecondBot.WikiMake public HTTPendpoint() { createEndpoint("core", typeof(HttpApiCore)); - createEndpoint("inventory", typeof(HttpApiInventory)); + createEndpoint("inventory", typeof(HTTP_Inventory)); createEndpoint("im", typeof(HttpApiIM)); - createEndpoint("groups", typeof(HttpApiGroup)); - createEndpoint("chat", typeof(HttpApiLocalchat)); - createEndpoint("parcel", typeof(HttpApiParcel)); - createEndpoint("estate", typeof(HttpAPIEstate)); + createEndpoint("groups", typeof(HTTP_Group)); + createEndpoint("chat", typeof(HTTP_Chat)); + createEndpoint("parcel", typeof(HTTP_Parcel)); + createEndpoint("estate", typeof(HTTP_Estate)); } public string getCommandMethod(string endpoint, string command) diff --git a/Core/Commands/Movement/AutoPilot.cs b/Core/Commands/Movement/AutoPilot.cs deleted file mode 100644 index ca2a761..0000000 --- a/Core/Commands/Movement/AutoPilot.cs +++ /dev/null @@ -1,56 +0,0 @@ -using BetterSecondBotShared.Static; -using OpenMetaverse; -using System.Threading; - -namespace BetterSecondBot.Commands.Movement -{ - public class AutoPilot : CoreCommand_1arg - { - public override string[] ArgTypes { get { return new[] { "Vector" }; } } - public override string[] ArgHints { get { return new[] { "<0,0,0>" }; } } - public override string Helpfile { get { return "Make the bot auto pilot to
Example AutoPilot|||<124,55,22>"; } } - public override bool CallFunction(string[] args) - { - if (base.CallFunction(args) == true) - { - if (Vector3.TryParse(args[0], out Vector3 pos) == true) - { - if (helpers.inrange(pos.X, 0, 255) == true) - { - if (helpers.inrange(pos.Y, 0, 255) == true) - { - if (helpers.inrange(pos.Z, 0, 5000) == true) - { - bot.GetClient.Self.AutoPilotCancel(); - bot.GetClient.Self.Movement.TurnToward(pos, true); - Thread.Sleep(500); - uint Globalx, Globaly; - Utils.LongToUInts(bot.GetClient.Network.CurrentSim.Handle, out Globalx, out Globaly); - bot.GetClient.Self.AutoPilot((ulong)(Globalx + pos.X), (ulong)(Globaly + pos.Y), pos.Z); - return true; - } - else - { - return Failed("Z cord is out of range"); - } - } - else - { - return Failed("Y cord is out of range"); - } - } - else - { - return Failed("X cord is out of range"); - } - } - else - { - return Failed("Unable to process vector"); - } - } - return false; - } - } - -} diff --git a/Core/Commands/Movement/teleport.cs b/Core/Commands/Movement/teleport.cs deleted file mode 100644 index 7875e22..0000000 --- a/Core/Commands/Movement/teleport.cs +++ /dev/null @@ -1,66 +0,0 @@ -using OpenMetaverse; - -namespace BetterSecondBot.Commands.Movement -{ - public class Teleport : CoreCommand_1arg - { - public override string[] ArgTypes { get { return new[] { "Mixed" }; } } - public override string[] ArgHints { get { return new[] { "SLurl
Region
X/Y/Z
Region/X/Y/Z" }; } } - public override string Helpfile { get { return "Teleports the avatar
" + - "SLurl: http://maps.secondlife.com/secondlife/Bombalai/216/51/33
" + - "Region: Bombalai [Defaults to 128,128,0]
" + - "X/Y/Z: Stays in the sim just changes location
" + - "Region/X/Y/Z: Teleports to the given region and trys to goto X/Y/Z if no teleport hub (or has access)"; - } } - - public override bool CallFunction(string[] args) - { - if(base.CallFunction(args) == true) - { - bot.GetClient.Self.AutoPilotCancel(); - if (args[0].Contains("http://maps.secondlife.com/secondlife/") == true) - { - bot.TeleportWithSLurl(args[0]); - return true; - } - else - { - float posX = 128; - float posY = 128; - float posZ = 0; - string regionName = bot.GetClient.Network.CurrentSim.Name; - bool ok = true; - int offset = 0; - string[] tp_args = args[0].Split('/'); - if ((tp_args.Length == 4) || (tp_args.Length == 1)) - { - regionName = tp_args[0]; - offset = 1; - } - if (tp_args.Length >= 3) - { - float.TryParse(tp_args[offset + 0], out posX); - float.TryParse(tp_args[offset + 1], out posY); - float.TryParse(tp_args[offset + 2], out posZ); - } - else if (tp_args.Length == 2) - { - ok = false; - } - if (ok == true) - { - bot.SetTeleported(); - bool status = bot.GetClient.Self.Teleport(regionName, new Vector3(posX, posY, posZ)); - bot.ResetAnimations(); - return status; - } - else - { - return Failed("Required args [Region or x/y/z or region/x/y/z not sent]"); - } - } - } - return false; - } - } -} diff --git a/Core/Commands/Parcel/AbandonLand.cs b/Core/Commands/Parcel/AbandonLand.cs deleted file mode 100644 index 6934361..0000000 --- a/Core/Commands/Parcel/AbandonLand.cs +++ /dev/null @@ -1,17 +0,0 @@ -namespace BetterSecondBot.Commands.CMD_Parcel -{ - public class AbandonLand : ParcelCommand_RequirePerms - { - public override string Helpfile { get { return "Abandons the parcel the bot is currently on, returning it to Linden's or Estate owner"; } } - - public override bool CallFunction(string[] args) - { - if (base.CallFunction(args) == true) - { - bot.GetClient.Parcels.ReleaseParcel(bot.GetClient.Network.CurrentSim, targetparcel.LocalID); - return true; - } - return false; - } - } -} diff --git a/Core/Commands/Parcel/GetParcelBanlist.cs b/Core/Commands/Parcel/GetParcelBanlist.cs deleted file mode 100644 index 660a83e..0000000 --- a/Core/Commands/Parcel/GetParcelBanlist.cs +++ /dev/null @@ -1,27 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Text; -using static OpenMetaverse.ParcelManager; - -namespace BetterSecondBot.Commands.Parcel -{ - class GetParcelBanlist : ParcelCommand_CheckParcel_1arg_smart - { - public override string Helpfile { get { return "Fetchs the current parcels banlist and sends it to the smart reply target on [ARG 1]"; } } - - public override bool CallFunction(string[] args) - { - if (base.CallFunction(args) == true) - { - Dictionary reply = new Dictionary(); - foreach(ParcelAccessEntry e in targetparcel.AccessBlackList) - { - string name = bot.FindAvatarKey2Name(e.AgentID); - reply.Add(e.AgentID.ToString(), name); - } - return bot.GetCommandsInterface.SmartCommandReply(true, args[0], targetparcel.Name, CommandName, reply); - } - return false; - } - } -} diff --git a/Core/Commands/Parcel/GetParcelDesc.cs b/Core/Commands/Parcel/GetParcelDesc.cs deleted file mode 100644 index ece327b..0000000 --- a/Core/Commands/Parcel/GetParcelDesc.cs +++ /dev/null @@ -1,16 +0,0 @@ -namespace BetterSecondBot.Commands.CMD_Parcel -{ - public class GetParcelDesc : ParcelCommand_CheckParcel_1arg_smart - { - public override string Helpfile { get { return "Fetchs the current parcels desc 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.Desc, CommandName); - } - return false; - } - } -} diff --git a/Core/Commands/Parcel/GetParcelFlags.cs b/Core/Commands/Parcel/GetParcelFlags.cs deleted file mode 100644 index 9405808..0000000 --- a/Core/Commands/Parcel/GetParcelFlags.cs +++ /dev/null @@ -1,82 +0,0 @@ -using System.Collections.Generic; -using System.Text; -using BetterSecondBotShared.logs; -using BetterSecondBotShared.Static; -using OpenMetaverse; - -namespace BetterSecondBot.Commands.CMD_Parcel -{ - public class GetParcelFlags : CoreCommand_1arg - { - public override string[] ArgTypes { get { return new[] { "Smart", "String" }; } } - public override string[] ArgHints { get { return new[] { "Smart reply [Channel|Avatar|http url]", "[Repeatable] flag name" }; } } - public override string Helpfile { get { return "Returns the value of the parcel flags (At the parcel on the bot is currently on)
" + - "requested on [ARG 2+] via [ARG 1] smart reply target
" + - "If you request multiple Flags they are split with CSV
You can also get all the flags skipping [ARG 2]

" + - "" + helpers.create_dirty_table(parcel_static.get_flag_names()) + "

Example: getparcelflag|||0~#~ForSale
Example: getparcelflag|||12"; } } - - public override bool CallFunction(string[] args) - { - if (base.CallFunction(args) == true) - { - Dictionary flags = parcel_static.get_flags_list(); - List get_flags = new List(); - List otherargs = new List(args); - string target = otherargs[0]; - otherargs.RemoveAt(0); - if (otherargs.Count == 0) - { - otherargs.Add("ALL"); - } - if (otherargs[0] == "ALL") - { - foreach (string A in flags.Keys) - { - get_flags.Add(A); - } - } - else - { - foreach (string a in otherargs) - { - if (flags.ContainsKey(a) == true) - { - get_flags.Add(a); - } - else - { - LogFormater.Warn("Flag: " + a + " is unknown"); - } - } - } - - if (get_flags.Count > 0) - { - int localid = bot.GetClient.Parcels.GetParcelLocalID(bot.GetClient.Network.CurrentSim, bot.GetClient.Self.SimPosition); - if (bot.GetClient.Network.CurrentSim.Parcels.ContainsKey(localid) == true) - { - OpenMetaverse.Parcel p = bot.GetClient.Network.CurrentSim.Parcels[localid]; - Dictionary collection = new Dictionary(); - foreach (string cfg in get_flags) - { - if (flags.ContainsKey(cfg) == true) - { - collection.Add(cfg, p.Flags.HasFlag(flags[cfg]).ToString()); - } - } - return bot.GetCommandsInterface.SmartCommandReply(true,target, p.Name, CommandName, collection); - } - else - { - return Failed("Unable to find parcel in memory, please wait and try again"); - } - } - else - { - return Failed("No accepted flags"); - } - } - return false; - } - } -} diff --git a/Core/Commands/Parcel/ParcelBan.cs b/Core/Commands/Parcel/ParcelBan.cs deleted file mode 100644 index 40e036f..0000000 --- a/Core/Commands/Parcel/ParcelBan.cs +++ /dev/null @@ -1,91 +0,0 @@ -using OpenMetaverse; -using static OpenMetaverse.ParcelManager; - -namespace BetterSecondBot.Commands.CMD_Parcel -{ - public class ParcelBan : CoreCommand_1arg - { - public override string[] ArgTypes { get { return new[] { "Avatar", "True|False" }; } } - public override string[] ArgHints { get { return new[] { "Avatar [UUID or Firstname Lastname]", "Type" }; } } - public override string Helpfile { get { return "Bans an avatar [ARG 1] from a parcel
by setting Type to False you can unban"; } } - - protected bool ban_target(OpenMetaverse.Parcel p, UUID target) - { - bool alreadyBanned = false; - foreach (ParcelAccessEntry E in p.AccessBlackList) - { - if (E.AgentID == target) - { - alreadyBanned = true; - break; - } - } - if (alreadyBanned == true) - { - return Failed("Target is in the blacklist"); - } - ParcelAccessEntry entry = new ParcelAccessEntry(); - entry.AgentID = target; - entry.Flags = AccessList.Ban; - entry.Time = new System.DateTime(3030, 03, 03); - p.AccessBlackList.Add(entry); - p.Update(bot.GetClient.Network.CurrentSim, false); - return true; - } - - protected bool unban_target(OpenMetaverse.Parcel p, UUID target) - { - bool alreadyBanned = false; - ParcelAccessEntry removeme = new ParcelAccessEntry(); - foreach (ParcelAccessEntry E in p.AccessBlackList) - { - if (E.AgentID == target) - { - alreadyBanned = true; - removeme = E; - break; - } - } - if (alreadyBanned == false) - { - return Failed("Target is NOT in the blacklist"); - } - p.AccessBlackList.Remove(removeme); - p.Update(bot.GetClient.Network.CurrentSim, false); - return true; - } - - - - public override bool CallFunction(string[] args) - { - if (base.CallFunction(args) == false) - { - return false; - } - if (UUID.TryParse(args[0], out UUID target) == false) - { - return Failed("Arg 0 requires UUID"); - } - bool banuser = true; - if (args.Length == 2) - { - if (args[1] == "False") - { - banuser = false; - } - } - int localid = bot.GetClient.Parcels.GetParcelLocalID(bot.GetClient.Network.CurrentSim, bot.GetClient.Self.SimPosition); - if (bot.GetClient.Network.CurrentSim.Parcels.ContainsKey(localid) == false) - { - return Failed("Unable to get parcel details"); - } - OpenMetaverse.Parcel p = bot.GetClient.Network.CurrentSim.Parcels[localid]; - if (banuser == true) - { - return ban_target(p, target); - } - return unban_target(p, target); - } - } -} diff --git a/Core/Commands/Parcel/ParcelBuy.cs b/Core/Commands/Parcel/ParcelBuy.cs deleted file mode 100644 index 666df1d..0000000 --- a/Core/Commands/Parcel/ParcelBuy.cs +++ /dev/null @@ -1,33 +0,0 @@ -using OpenMetaverse; - -namespace BetterSecondBot.Commands.CMD_Parcel -{ - class ParcelBuy : ParcelCommand_CheckParcel - { - public override string[] ArgTypes { get { return new[] { "Number" }; } } - public override string[] ArgHints { get { return new[] { "expected price to pay" }; } } - public override string Helpfile { get { return "Attempts to buy the parcel the bot is standing on, note: if no price expected price is set it will pay the listed price"; } } - - public override bool CallFunction(string[] args) - { - if (base.CallFunction(args) == true) - { - int expected_price = -1; - if (args.Length == 1) - { - int.TryParse(args[0], out expected_price); - } - if ((targetparcel.SalePrice == expected_price) || (expected_price == -1)) - { - bot.GetClient.Parcels.Buy(bot.GetClient.Network.CurrentSim, targetparcel.LocalID, false, UUID.Zero, false, targetparcel.Area, targetparcel.SalePrice); - return true; - } - else - { - return Failed("Expected price is not -1 or matchs: " + expected_price.ToString() + ""); - } - } - return false; - } - } -} diff --git a/Core/Commands/Parcel/ParcelCleanAndSell.cs b/Core/Commands/Parcel/ParcelCleanAndSell.cs deleted file mode 100644 index a116ec4..0000000 --- a/Core/Commands/Parcel/ParcelCleanAndSell.cs +++ /dev/null @@ -1,92 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Threading; -using OpenMetaverse; - -namespace BetterSecondBot.Commands.CMD_Parcel -{ - public class ParcelCleanAndSell : ParcelCommand_RequirePerms_1arg - { - public override string[] ArgTypes { get { return new[] { "Number" }; } } - public override string[] ArgHints { get { return new[] { "L$ amount to mark the parcel for sale as" }; } } - - public override string Helpfile { get { return "Sets the current parcel for sale for L$[ARG 1] (Also marks the parcel for sale)"; } } - - public override void Callback(string[] args, EventArgs e) - { - if (base.CallFunction(args) == true) - { - ParcelObjectOwnersReplyEventArgs ObjectOwners = (ParcelObjectOwnersReplyEventArgs)e; - List owner_uuids = new List(); - foreach (ParcelManager.ParcelPrimOwners owner in ObjectOwners.PrimOwners) - { - owner_uuids.Add(owner.OwnerID); - } - if (owner_uuids.Count > 0) - { - bot.GetClient.Parcels.ReturnObjects(bot.GetClient.Network.CurrentSim, targetparcel.LocalID, ObjectReturnType.List, owner_uuids); - } - int.TryParse(args[0], out int price); - bot.GetClient.Parcels.ReleaseParcel(bot.GetClient.Network.CurrentSim, targetparcel.LocalID); - targetparcel.SalePrice = price; - targetparcel.AuthBuyerID = UUID.Zero; - targetparcel.OwnerID = UUID.Zero; - parcel_static.ParcelSetFlag(ParcelFlags.ForSale, targetparcel, true); - parcel_static.ParcelSetFlag(ParcelFlags.ForSaleObjects, targetparcel, false); - targetparcel.Update(bot.GetClient.Network.CurrentSim, false); - base.Callback(args, e, true); - } - else - { - base.Callback(args, e, false); - } - } - - public override bool CallFunction(string[] args) - { - if (base.CallFunction(args) == true) - { - if (int.TryParse(args[0], out int price) == true) - { - if (price >= 1) - { - if (price <= 99999) - { - bot.GetClient.Parcels.ReleaseParcel(bot.GetClient.Network.CurrentSim, targetparcel.LocalID); - targetparcel.AuthBuyerID = bot.GetClient.Self.AgentID; - targetparcel.SalePrice = 0; - parcel_static.ParcelSetFlag(ParcelFlags.ForSale, targetparcel, true); - parcel_static.ParcelSetFlag(ParcelFlags.ForSaleObjects, targetparcel, false); - targetparcel.Update(bot.GetClient.Network.CurrentSim, false); - Thread.Sleep(200); - bot.GetClient.Parcels.Buy(bot.GetClient.Network.CurrentSim, targetparcel.LocalID, false, UUID.Zero, false, targetparcel.Area, 0); - Thread.Sleep(1000); - if (bot.CreateAwaitEventReply("parcelobjectowners", this, args) == true) - { - bot.GetClient.Parcels.RequestObjectOwners(bot.GetClient.Network.CurrentSim, targetparcel.LocalID); - return true; - } - else - { - return Failed("Unable to send request for parcel object owners"); - } - } - else - { - return Failed("Price must be 99999 or less"); - } - } - else - { - return Failed("Price must be 1 or more"); - } - } - else - { - return Failed("Unable to process price"); - } - } - return false; - } - } -} diff --git a/Core/Commands/Parcel/ParcelCommandHelper.cs b/Core/Commands/Parcel/ParcelCommandHelper.cs deleted file mode 100644 index 5d68f47..0000000 --- a/Core/Commands/Parcel/ParcelCommandHelper.cs +++ /dev/null @@ -1,99 +0,0 @@ -using OpenMetaverse; - -namespace BetterSecondBot.Commands -{ - public abstract class ParcelCommand_RequirePerms_1arg_Group : ParcelCommand_RequirePerms_1arg - { - protected UUID groupuuid = UUID.Zero; - public override string[] ArgTypes { get { return new[] { "UUID" }; } } - public override string[] ArgHints { get { return new[] { "Group UUID" }; } } - public override bool CallFunction(string[] args) - { - if (base.CallFunction(args) == true) - { - if (UUID.TryParse(args[0], out groupuuid) == true) - { - return true; - } - else - { - return Failed("Unable to process group uuid"); - } - } - else - { - return false; - } - } - } - - public abstract class ParcelCommand_RequirePerms_1arg : ParcelCommand_RequirePerms - { - public override int Min_Required_args { get { return 1; } } - } - - public abstract class ParcelCommand_CheckParcel_1arg : ParcelCommand_CheckParcel - { - public override int Min_Required_args { get { return 1; } } - } - - public abstract class ParcelCommand_RequirePerms : ParcelCommand_CheckParcel - { - public override bool CallFunction(string[] args) - { - if (base.CallFunction(args) == true) - { - if (targetparcel != null) - { - if (parcel_static.has_parcel_perm(targetparcel, bot) == true) - { - return true; - } - else - { - return Failed("Incorrect perms to control parcel"); - } - } - else - { - return Failed("No parcel targeted."); - } - } - else - { - return false; - } - } - } - public abstract class ParcelCommand_CheckParcel_1arg_smart : ParcelCommand_CheckParcel_1arg - { - public override string[] ArgTypes { get { return new[] { "Smart" }; } } - public override string[] ArgHints { get { return new[] { "Smart reply [Channel|Avatar|http url]" }; } } - } - - public abstract class ParcelCommand_CheckParcel : CoreCommand - { - protected OpenMetaverse.Parcel targetparcel; - public OpenMetaverse.Parcel GetTargetParcel { get { return targetparcel; } } - public override bool CallFunction(string[] args) - { - if (base.CallFunction(args) == true) - { - int localid = bot.GetClient.Parcels.GetParcelLocalID(bot.GetClient.Network.CurrentSim, bot.GetClient.Self.SimPosition); - if (bot.GetClient.Network.CurrentSim.Parcels.ContainsKey(localid) == true) - { - targetparcel = bot.GetClient.Network.CurrentSim.Parcels[localid]; - return true; - } - else - { - return Failed("Unable to find parcel in memory, please wait and try again"); - } - } - else - { - return false; - } - } - } -} diff --git a/Core/Commands/Parcel/ParcelDeedToGroup.cs b/Core/Commands/Parcel/ParcelDeedToGroup.cs deleted file mode 100644 index b9894bc..0000000 --- a/Core/Commands/Parcel/ParcelDeedToGroup.cs +++ /dev/null @@ -1,22 +0,0 @@ -using System.Threading; - -namespace BetterSecondBot.Commands.CMD_Parcel -{ - public class ParcelDeedToGroup : ParcelCommand_RequirePerms_1arg_Group - { - public override string Helpfile { get { return "transfers the current parcel ownership to a group"; } } - - public override bool CallFunction(string[] args) - { - if (base.CallFunction(args) == true) - { - targetparcel.GroupID = groupuuid; - targetparcel.Update(bot.GetClient.Network.CurrentSim, false); - Thread.Sleep(1000); - bot.GetClient.Parcels.DeedToGroup(bot.GetClient.Network.CurrentSim, targetparcel.LocalID, groupuuid); - return true; - } - return false; - } - } -} diff --git a/Core/Commands/Parcel/ParcelFreeze.cs b/Core/Commands/Parcel/ParcelFreeze.cs deleted file mode 100644 index 13ad8e1..0000000 --- a/Core/Commands/Parcel/ParcelFreeze.cs +++ /dev/null @@ -1,35 +0,0 @@ -using OpenMetaverse; - -namespace BetterSecondBot.Commands.CMD_Parcel -{ - public class ParcelFreeze : CoreCommand_1arg - { - public override string[] ArgTypes { get { return new[] { "Avatar", "True|False" }; } } - public override string[] ArgHints { get { return new[] { "Avatar [UUID or Firstname Lastname]", "Status (defaults to True)" }; } } - public override string Helpfile { get { return "Freezes an avatar [ARG 1]
Set to False to unfreeze"; } } - public override bool CallFunction(string[] args) - { - if (base.CallFunction(args) == true) - { - if (UUID.TryParse(args[0], out UUID target) == true) - { - bool freezethem = true; - if (args.Length == 2) - { - if (args[1] == "False") - { - freezethem = false; - } - } - bot.GetClient.Parcels.FreezeUser(target, freezethem); - return true; - } - else - { - return Failed("Arg 0 requires UUID"); - } - } - return false; - } - } -} diff --git a/Core/Commands/Parcel/ParcelPrimCountAvatar.cs b/Core/Commands/Parcel/ParcelPrimCountAvatar.cs deleted file mode 100644 index 7ee79ce..0000000 --- a/Core/Commands/Parcel/ParcelPrimCountAvatar.cs +++ /dev/null @@ -1,77 +0,0 @@ -using OpenMetaverse; -using System; -using System.Collections.Generic; -using System.Text; - -namespace BetterSecondBot.Commands.CMD_Parcel -{ - class ParcelPrimCountAvatar : CoreCommand_SmartReply_2arg - { - public override string[] ArgTypes { get { return new[] { "Smart","Avatar" }; } } - public override string[] ArgHints { get { return new[] { "Smart reply target: Channel,Avatar,HTTP url","the avatar (UUID or Firstname Lastname) we want the count of back" }; } } - public override string Helpfile { get { return "Returns the number of prims owned by the selected avatar on the current parcel as follows: DATA=SIMNAME,PARCELID,AVATAR UUID,COUNT"; } } - - public override void Callback(string[] args, EventArgs e) - { - ParcelObjectOwnersReplyEventArgs ObjectOwners = (ParcelObjectOwnersReplyEventArgs)e; - List owner_uuids = new List(); - List owner_counts = new List(); - foreach (ParcelManager.ParcelPrimOwners owner in ObjectOwners.PrimOwners) - { - owner_uuids.Add(owner.OwnerID); - owner_counts.Add(owner.Count); - } - if (owner_uuids.Count > 0) - { - if (UUID.TryParse(args[1], out UUID avatar) == true) - { - int localid = bot.GetClient.Parcels.GetParcelLocalID(bot.GetClient.Network.CurrentSim, bot.GetClient.Self.SimPosition); - collection.Add("sim", bot.GetClient.Network.CurrentSim.Name); - if (owner_uuids.Contains(avatar) == true) - { - int owner_count = owner_counts[owner_uuids.IndexOf(avatar)]; - collection.Add("count", owner_count.ToString()); - } - else - { - collection.Add("count", "0"); - } - base.Callback(args, e, bot.GetCommandsInterface.SmartCommandReply(true,args[0], "avatar="+ avatar.ToString(), CommandName,collection)); - } - else - { - base.Callback(args, e, false); - } - } - else - { - base.Callback(args, e, false); - } - } - - public override bool CallFunction(string[] args) - { - if (base.CallFunction(args) == true) - { - if (UUID.TryParse(args[1], out _) == true) - { - int localid = bot.GetClient.Parcels.GetParcelLocalID(bot.GetClient.Network.CurrentSim, bot.GetClient.Self.SimPosition); - if (bot.CreateAwaitEventReply("parcelobjectowners", this, args) == true) - { - bot.GetClient.Parcels.RequestObjectOwners(bot.GetClient.Network.CurrentSim, localid); - return true; - } - else - { - return Failed("Unable to await reply"); - } - } - else - { - return Failed("Arg 2 is not a vaild avatar"); - } - } - return false; - } - } -} diff --git a/Core/Commands/Parcel/ParcelPrimCountTotal.cs b/Core/Commands/Parcel/ParcelPrimCountTotal.cs deleted file mode 100644 index d41c5f8..0000000 --- a/Core/Commands/Parcel/ParcelPrimCountTotal.cs +++ /dev/null @@ -1,51 +0,0 @@ -using OpenMetaverse; -using System; -using System.Text; - -namespace BetterSecondBot.Commands.CMD_Parcel -{ - class ParcelPrimCountTotal : CoreCommand_SmartReply_1arg - { - public override string Helpfile { get { return "Returns the total number of prims on the current parcel as follows: DATA=SIMNAME,PARCELID,COUNT"; } } - - public override void Callback(string[] args, EventArgs e) - { - ParcelObjectOwnersReplyEventArgs ObjectOwners = (ParcelObjectOwnersReplyEventArgs)e; - int total_count = 0; - foreach (ParcelManager.ParcelPrimOwners owner in ObjectOwners.PrimOwners) - { - total_count += owner.Count; - } - int localid = bot.GetClient.Parcels.GetParcelLocalID(bot.GetClient.Network.CurrentSim, bot.GetClient.Self.SimPosition); - collection.Add("sim", bot.GetClient.Network.CurrentSim.Name); - collection.Add("parcelid", localid.ToString()); - collection.Add("count", total_count.ToString()); - base.Callback(args, e, bot.GetCommandsInterface.SmartCommandReply(true,args[0], "ok", CommandName,collection)); - } - - public override bool CallFunction(string[] args) - { - if (base.CallFunction(args) == true) - { - int localid = bot.GetClient.Parcels.GetParcelLocalID(bot.GetClient.Network.CurrentSim, bot.GetClient.Self.SimPosition); - if (bot.GetClient.Network.CurrentSim.Parcels.ContainsKey(localid) == true) - { - if (bot.CreateAwaitEventReply("parcelobjectowners", this, args) == true) - { - bot.GetClient.Parcels.RequestObjectOwners(bot.GetClient.Network.CurrentSim, localid); - return true; - } - else - { - return Failed("Unable to await reply"); - } - } - else - { - return Failed("Unable to find parcel in memory, please wait and try again"); - } - } - return false; - } - } -} diff --git a/Core/Commands/Parcel/ParcelReturnObjects.cs b/Core/Commands/Parcel/ParcelReturnObjects.cs deleted file mode 100644 index 9eff62b..0000000 --- a/Core/Commands/Parcel/ParcelReturnObjects.cs +++ /dev/null @@ -1,71 +0,0 @@ -using OpenMetaverse; -using System; -using System.Collections.Generic; - -namespace BetterSecondBot.Commands.CMD_Parcel -{ - class ParcelReturnObjects : CoreCommand - { - public override string Helpfile { get { return "Returns all object from the current parcel to their owners"; } } - - public override void Callback(string[] args, EventArgs e) - { - ParcelObjectOwnersReplyEventArgs ObjectOwners = (ParcelObjectOwnersReplyEventArgs)e; - List owner_uuids = new List(); - foreach(ParcelManager.ParcelPrimOwners owner in ObjectOwners.PrimOwners) - { - owner_uuids.Add(owner.OwnerID); - } - if (owner_uuids.Count > 0) - { - int localid = bot.GetClient.Parcels.GetParcelLocalID(bot.GetClient.Network.CurrentSim, bot.GetClient.Self.SimPosition); - OpenMetaverse.Parcel p = bot.GetClient.Network.CurrentSim.Parcels[localid]; - if (bot.GetClient.Network.CurrentSim.Parcels.ContainsKey(localid) == true) - { - if (parcel_static.has_parcel_perm(p, bot) == true) - { - bot.GetClient.Parcels.ReturnObjects(bot.GetClient.Network.CurrentSim, localid, ObjectReturnType.List, owner_uuids); - base.Callback(args, e, true); - } - else - { - base.Callback(args, e, false); - } - } - else - { - base.Callback(args, e, false); - } - } - else - { - base.Callback(args, e, false); - } - } - - public override bool CallFunction(string[] args) - { - if (base.CallFunction(args) == true) - { - int localid = bot.GetClient.Parcels.GetParcelLocalID(bot.GetClient.Network.CurrentSim, bot.GetClient.Self.SimPosition); - if (bot.GetClient.Network.CurrentSim.Parcels.ContainsKey(localid) == true) - { - if (bot.CreateAwaitEventReply("parcelobjectowners", this, args) == true) - { - bot.GetClient.Parcels.RequestObjectOwners(bot.GetClient.Network.CurrentSim, localid); - return true; - } - else - { - return Failed("Unable to await reply"); - } - } - else - { - return Failed("Unable to find parcel in memory, please wait and try again"); - } - } - return false; - } - } -} diff --git a/Core/Commands/Parcel/ParcelReturnTargeted.cs b/Core/Commands/Parcel/ParcelReturnTargeted.cs deleted file mode 100644 index 0dcbe2d..0000000 --- a/Core/Commands/Parcel/ParcelReturnTargeted.cs +++ /dev/null @@ -1,29 +0,0 @@ -using OpenMetaverse; -using System.Collections.Generic; - -namespace BetterSecondBot.Commands.CMD_Parcel -{ - class ParcelReturnTargeted : ParcelCommand_RequirePerms_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 "Returns all objects from the current parcel for the selected avatar"; } } - - public override bool CallFunction(string[] args) - { - if (base.CallFunction(args) == true) - { - if (UUID.TryParse(args[0], out UUID avatarUUID) == true) - { - bot.GetClient.Parcels.ReturnObjects(bot.GetClient.Network.CurrentSim, targetparcel.LocalID, ObjectReturnType.None, new List() { avatarUUID }); - return true; - } - else - { - return Failed("Invaild avatar UUID"); - } - } - return false; - } - } -} diff --git a/Core/Commands/Parcel/ParcelSetMedia.cs b/Core/Commands/Parcel/ParcelSetMedia.cs deleted file mode 100644 index 46e9d55..0000000 --- a/Core/Commands/Parcel/ParcelSetMedia.cs +++ /dev/null @@ -1,170 +0,0 @@ -using BetterSecondBotShared.Static; -using OpenMetaverse; - -namespace BetterSecondBot.Commands.CMD_Parcel -{ - class ParcelSetMedia : ParcelCommand_RequirePerms_1arg - { - public override string[] ArgTypes { get { return new[] { "Flag [Repeatable]" }; } } - public override string[] ArgHints { get { return new[] { "See flags table" }; } } - public override string Helpfile { get { return "Supports updating one or multiple media options for the current parcel
Example: ParcelSetMedia|||MediaURL=http://google.com~#~MediaDesc=Google.com website
Flags: " + helpers.create_dirty_table(parcel_static.get_flag_names()) + "
"; } } - - public override bool CallFunction(string[] args) - { - if (base.CallFunction(args) == true) - { - bool all_flags_ok = true; - string why_failed = ""; - int loop = 1; - foreach (string A in args) - { - bool format_failed = false; - string[] bits = A.Split('='); - if (bits.Length == 2) - { - switch (bits[0]) - { - case "MediaType": - { - if (bits[1] == "IMG-PNG") - { - targetparcel.Media.MediaType = "image/png"; - } - else if (bits[1] == "IMG-JPG") - { - targetparcel.Media.MediaType = "image/jpeg"; - } - else if (bits[1] == "VID-MP4") - { - targetparcel.Media.MediaType = "video/mp4"; - } - else if (bits[1] == "VID-AVI") - { - targetparcel.Media.MediaType = "video/x-msvideo"; - } - else if (bits[1].StartsWith("Custom-") == true) - { - string mime = bits[1]; - mime = mime.Replace("Custom-", ""); - targetparcel.Media.MediaType = mime; - } - else - { - format_failed = true; - } - break; - } - case "MediaWidth": - case "MediaHeight": - { - if (int.TryParse(bits[1], out int size) == true) - { - if ((size >= 256) || (size <= 1024)) - { - if (bits[0] == "MediaHeight") - { - targetparcel.Media.MediaHeight = size; - } - else if (bits[0] == "MediaWidth") - { - targetparcel.Media.MediaWidth = size; - } - else - { - format_failed = true; // not sure how this happened - } - } - else - { - format_failed = true; - } - } - else - { - format_failed = true; - } - break; - } - case "MediaID": - { - if (UUID.TryParse(bits[1], out UUID texture) == true) - { - targetparcel.Media.MediaID = texture; - } - else - { - format_failed = true; - } - break; - } - case "MediaURL": - { - targetparcel.Media.MediaURL = bits[1]; - break; - } - case "MediaDesc": - { - targetparcel.Media.MediaDesc = bits[1]; - break; - } - case "MediaAutoScale": - { - if (bool.TryParse(bits[1], out bool output) == true) - { - targetparcel.Media.MediaAutoScale = output; - } - else - { - format_failed = true; - } - break; - } - case "MediaLoop": - { - if (bool.TryParse(bits[1], out bool output) == true) - { - targetparcel.Media.MediaLoop = output; - } - else - { - format_failed = true; - } - break; - } - default: - { - why_failed = "Arg:" + loop.ToString() + " is not a supported media option!"; - all_flags_ok = false; - break; - } - } - } - else - { - format_failed = true; - } - if (format_failed == true) - { - why_failed = "Arg:" + loop.ToString() + " Not formated correctly"; - all_flags_ok = false; - } - if (all_flags_ok == false) - { - break; - } - loop++; - } - if (all_flags_ok == true) - { - targetparcel.Update(bot.GetClient.Network.CurrentSim, false); - return true; - } - else - { - return Failed(why_failed); - } - } - return false; - } - } -} diff --git a/Core/Commands/Parcel/SetParcelDesc.cs b/Core/Commands/Parcel/SetParcelDesc.cs deleted file mode 100644 index 3788caa..0000000 --- a/Core/Commands/Parcel/SetParcelDesc.cs +++ /dev/null @@ -1,20 +0,0 @@ -namespace BetterSecondBot.Commands.CMD_Parcel -{ - public class SetParcelDesc : ParcelCommand_RequirePerms_1arg - { - public override string[] ArgTypes { get { return new[] { "String" }; } } - public override string[] ArgHints { get { return new[] { "The new desc" }; } } - public override string Helpfile { get { return "Updates the current parcels desc"; } } - - public override bool CallFunction(string[] args) - { - if (base.CallFunction(args) == true) - { - targetparcel.Desc = args[0]; - targetparcel.Update(bot.GetClient.Network.CurrentSim, false); - return true; - } - return false; - } - } -} diff --git a/Core/Commands/Parcel/SetParcelFlag.cs b/Core/Commands/Parcel/SetParcelFlag.cs deleted file mode 100644 index f772987..0000000 --- a/Core/Commands/Parcel/SetParcelFlag.cs +++ /dev/null @@ -1,89 +0,0 @@ -using System; -using System.Collections.Generic; -using BetterSecondBotShared.logs; -using BetterSecondBotShared.Static; -using OpenMetaverse; - -namespace BetterSecondBot.Commands.CMD_Parcel -{ - public class SetParcelFlag : ParcelCommand_RequirePerms_1arg - { - public override string[] ArgTypes { get { return new[] { "Text=True|False" }; } } - public override string[] ArgHints { get { return new[] { "[Repeatable] flag args" }; } } - - public override string Helpfile { get { return "Sets the parcel flags of the parcel the bot is currently standing on
" + - "Example:AllowFly=False~#~AllowDamage=True
" + helpers.create_dirty_table(parcel_static.get_flag_names()) +"
"; } } - - - public override bool CallFunction(string[] args) - { - if (base.CallFunction(args) == true) - { - List acceptablewords = new List(); - Dictionary flags = parcel_static.get_flags_list(); - acceptablewords.AddRange(new[] { "True", "False" }); - - Dictionary setflags = new Dictionary(); - foreach (string a in args) - { - string[] parts = a.Split('=',StringSplitOptions.RemoveEmptyEntries); - if (parts.Length == 2) - { - if (flags.ContainsKey(parts[0]) == true) - { - if (acceptablewords.Contains(parts[1])) - { - setflags.Add(parts[0], Convert.ToBoolean(parts[1])); - } - else - { - LogFormater.Crit("Unable to set flag " + parts[0] + " to : " + parts[1] + ""); - } - } - else - { - LogFormater.Warn("Flag: " + parts[0] + " is unknown"); - } - } - else - { - LogFormater.Warn("Flag: " + a + " missing = True|False"); - } - } - if (setflags.Count > 0) - { - int localid = bot.GetClient.Parcels.GetParcelLocalID(bot.GetClient.Network.CurrentSim, bot.GetClient.Self.SimPosition); - if (bot.GetClient.Network.CurrentSim.Parcels.ContainsKey(localid) == true) - { - OpenMetaverse.Parcel p = bot.GetClient.Network.CurrentSim.Parcels[localid]; - if (parcel_static.has_parcel_perm(p, bot) == true) - { - foreach (KeyValuePair cfg in setflags) - { - if (flags.ContainsKey(cfg.Key) == true) - { - parcel_static.ParcelSetFlag(flags[cfg.Key], p, cfg.Value); - } - } - p.Update(bot.GetClient.Network.CurrentSim, false); - return true; - } - else - { - return Failed("Incorrect perms to control parcel"); - } - } - else - { - return Failed("Unable to find parcel in memory, please wait and try again"); - } - } - else - { - return Failed("No accepted flags"); - } - } - return false; - } - } -} diff --git a/Core/Commands/Parcel/SetParcelMusic.cs b/Core/Commands/Parcel/SetParcelMusic.cs deleted file mode 100644 index 849d55a..0000000 --- a/Core/Commands/Parcel/SetParcelMusic.cs +++ /dev/null @@ -1,32 +0,0 @@ -namespace BetterSecondBot.Commands.CMD_Parcel -{ - class SetParcelMusic : ParcelCommand_RequirePerms - { - public override string[] ArgTypes { get { return new[] { "String" }; } } - public override string[] ArgHints { get { return new[] { "A vaild url" }; } } - public override string Helpfile { get { return "Updates the current parcels music url"; } } - - public override bool CallFunction(string[] args) - { - if (base.CallFunction(args) == true) - { - if (args.Length == 0) - { - return parcel_static.set_parcel_music(bot,targetparcel,""); - } - else - { - if (args[0].StartsWith("http") == true) - { - return parcel_static.set_parcel_music(bot, targetparcel, args[0]); - } - else - { - return Failed("Invaild url"); - } - } - } - return false; - } - } -} diff --git a/Core/Commands/Parcel/SetParcelName.cs b/Core/Commands/Parcel/SetParcelName.cs deleted file mode 100644 index 614c045..0000000 --- a/Core/Commands/Parcel/SetParcelName.cs +++ /dev/null @@ -1,20 +0,0 @@ -namespace BetterSecondBot.Commands.CMD_Parcel -{ - public class SetParcelName : ParcelCommand_RequirePerms_1arg - { - public override string[] ArgTypes { get { return new[] { "String" }; } } - public override string[] ArgHints { get { return new[] { "The new name" }; } } - public override string Helpfile { get { return "Updates the current parcels name"; } } - - public override bool CallFunction(string[] args) - { - if (base.CallFunction(args) == true) - { - targetparcel.Name = args[0]; - targetparcel.Update(bot.GetClient.Network.CurrentSim, false); - return true; - } - return false; - } - } -} diff --git a/Core/Commands/Parcel/SetParcelSale.cs b/Core/Commands/Parcel/SetParcelSale.cs deleted file mode 100644 index dfd0402..0000000 --- a/Core/Commands/Parcel/SetParcelSale.cs +++ /dev/null @@ -1,56 +0,0 @@ -using OpenMetaverse; - -namespace BetterSecondBot.Commands.CMD_Parcel -{ - public class SetParcelSale : ParcelCommand_RequirePerms_1arg - { - public override string[] ArgTypes { get { return new[] { "Number","Avatar" }; } } - public override string[] ArgHints { get { return new[] { "L$ amount to mark the parcel for sale as (Range: 1 to 99999 unless [ARG 2] is set)", "Avatar who can buy the land (If set allows you to set the sell price to zero)" }; } } - - public override string Helpfile { get { return "Sets the current parcel for sale for L$[ARG 1] (Also marks the parcel for sale)"; } } - - public override bool CallFunction(string[] args) - { - if (base.CallFunction(args) == true) - { - if (int.TryParse(args[0], out int price) == true) - { - UUID target_buyer = UUID.Zero; - int low_limit = 1; - if (args.Length == 2) - { - if (UUID.TryParse(args[1], out target_buyer) == true) - { - low_limit = 0; - } - } - if (price >= low_limit) - { - if (price <= 99999) - { - targetparcel.SalePrice = price; - targetparcel.AuthBuyerID = target_buyer; - parcel_static.ParcelSetFlag(ParcelFlags.ForSale, targetparcel, true); - parcel_static.ParcelSetFlag(ParcelFlags.ForSaleObjects, targetparcel, false); - targetparcel.Update(bot.GetClient.Network.CurrentSim, false); - return true; - } - else - { - return Failed("Price must be 99999 or less"); - } - } - else - { - return Failed("Price must be " + low_limit.ToString() + " or more"); - } - } - else - { - return Failed("Unable to process price"); - } - } - return false; - } - } -} diff --git a/Core/Commands/Parcel/eject.cs b/Core/Commands/Parcel/eject.cs deleted file mode 100644 index 86ca5b9..0000000 --- a/Core/Commands/Parcel/eject.cs +++ /dev/null @@ -1,35 +0,0 @@ -using OpenMetaverse; - -namespace BetterSecondBot.Commands.CMD_Parcel -{ - public class ParcelEject : CoreCommand_1arg - { - public override string[] ArgTypes { get { return new[] { "Avatar", "True|False" }; } } - public override string[] ArgHints { get { return new[] { "Avatar [UUID or Firstname Lastname]", "Also Ban" }; } } - public override string Helpfile { get { return "Ejects an avatar [ARG 1] from a parcel
You can also ban them at the same time if you wish"; } } - public override bool CallFunction(string[] args) - { - if (base.CallFunction(args) == true) - { - if (UUID.TryParse(args[0], out UUID target) == true) - { - bool banuser = false; - if (args.Length == 2) - { - if (args[1] == "True") - { - banuser = true; - } - } - bot.GetClient.Parcels.EjectUser(target, banuser); - return true; - } - else - { - return Failed("Arg 0 requires UUID"); - } - } - return false; - } - } -} diff --git a/Core/Commands/Prims/RezObject.cs b/Core/Commands/Prims/RezObject.cs deleted file mode 100644 index b42fec7..0000000 --- a/Core/Commands/Prims/RezObject.cs +++ /dev/null @@ -1,47 +0,0 @@ -using OpenMetaverse; -using System; -using System.Collections.Generic; -using System.Text; - -namespace BetterSecondBot.Commands.Prims -{ - class RezObject : CoreCommand_1arg - { - public override string[] ArgTypes { get { return new[] { "UUID", "Vector" }; } } - public override string[] ArgHints { get { return new[] { "The object to rez", "The location to rez at: Example \"<123,32,18>\"" }; } } - public override string Helpfile { get { return "Rez a object [ARG 1] from inventory at [ARG 2] (Or current pos if not given)"; } } - - public override bool CallFunction(string[] args) - { - if (base.CallFunction(args) == true) - { - if (UUID.TryParse(args[0], out UUID targetitem) == true) - { - InventoryItem itm = bot.GetClient.Inventory.FetchItem(targetitem, bot.GetClient.Self.AgentID, (5 * 1000)); - if (itm != null) - { - Vector3 pos = bot.GetClient.Self.RelativePosition; - if (args.Length == 2) - { - if(Vector3.TryParse(args[1], out pos) == false) - { - return Failed("Unable to process pos"); - } - } - bot.GetClient.Inventory.RequestRezFromInventory(bot.GetClient.Network.CurrentSim, bot.GetClient.Self.SimRotation, pos, itm); - return true; - } - else - { - return Failed("Unable to find item"); - } - } - else - { - return Failed("Invaild item UUID"); - } - } - return false; - } - } -} diff --git a/Core/Commands/Prims/TransferInventoryToObject.cs b/Core/Commands/Prims/TransferInventoryToObject.cs deleted file mode 100644 index 74c3594..0000000 --- a/Core/Commands/Prims/TransferInventoryToObject.cs +++ /dev/null @@ -1,74 +0,0 @@ -using OpenMetaverse; -using System; -using System.Collections.Generic; -using System.Text; - -namespace BetterSecondBot.Commands.Prims -{ - class TransferInventoryToObject : CoreCommand_2arg - { - public override string[] ArgTypes { get { return new[] { "UUID", "UUID","True" }; } } - public override string[] ArgHints { get { return new[] { "Object we are sending to", "The item we are sending","Running script (Optional)" }; } } - public override string Helpfile { get { return "Transfers a item [ARG 2] to a objects inventory [ARG 1] (And if set with the script running state [ARG 3])"; } } - - public override bool CallFunction(string[] args) - { - if (base.CallFunction(args) == true) - { - if (UUID.TryParse(args[1], out UUID targetitem) == true) - { - if (UUID.TryParse(args[0], out UUID targetobject) == true) - { - InventoryItem itm = bot.GetClient.Inventory.FetchItem(targetitem, bot.GetClient.Self.AgentID, (5 * 1000)); - if (itm != null) - { - Dictionary objects_copy = bot.GetClient.Network.CurrentSim.ObjectsPrimitives.Copy(); - bool found = false; - foreach (KeyValuePair Obj in objects_copy) - { - if (Obj.Value.ID == targetobject) - { - bool script_state = false; - if (args.Length == 3) - { - if (itm.AssetType != AssetType.LSLText) - { - script_state = false; - InfoBlob = "Please omit the 3rd arg if not sending a script!"; - } - else - { - if (bool.TryParse(args[2], out script_state) == false) - { - return Failed("Unable to process arg 3"); - } - } - } - if (script_state == false) - { - bot.GetClient.Inventory.UpdateTaskInventory(Obj.Key, itm); - } - else - { - bot.GetClient.Inventory.CopyScriptToTask(Obj.Key, itm, true); - } - found = true; - break; - } - } - if (found == false) - { - return true; - } - return Failed("Unable to see object (Please wait and try again)"); - } - return Failed("Unable to find item"); - } - return Failed("Invaild object UUID"); - } - return Failed("Invaild item UUID"); - } - return false; - } - } -} diff --git a/Core/Commands/Prims/UnRezObject.cs b/Core/Commands/Prims/UnRezObject.cs deleted file mode 100644 index f6b0edd..0000000 --- a/Core/Commands/Prims/UnRezObject.cs +++ /dev/null @@ -1,45 +0,0 @@ -using OpenMetaverse; -using System; -using System.Collections.Generic; -using System.Text; - -namespace BetterSecondBot.Commands.Prims -{ - class UnRezObject : CoreCommand_1arg - { - public override string[] ArgTypes { get { return new[] { "UUID" }; } } - public override string[] ArgHints { get { return new[] { "The object to unrez"}; } } - public override string Helpfile { get { return "Returns a rezzed object"; } } - - public override bool CallFunction(string[] args) - { - if (base.CallFunction(args) == true) - { - if (UUID.TryParse(args[0], out UUID targetobject) == true) - { - bool found = false; - Dictionary objects_copy = bot.GetClient.Network.CurrentSim.ObjectsPrimitives.Copy(); - foreach (KeyValuePair Obj in objects_copy) - { - if (Obj.Value.ID == targetobject) - { - bot.GetClient.Inventory.RequestDeRezToInventory(Obj.Key); - found = true; - break; - } - } - if(found == true) - { - return true; - } - return Failed("Unable to see object"); - } - else - { - return Failed("Invaild object UUID"); - } - } - return false; - } - } -} diff --git a/Core/Commands/Script/scriptHttp.cs b/Core/Commands/Script/scriptHttp.cs deleted file mode 100644 index 98ce28d..0000000 --- a/Core/Commands/Script/scriptHttp.cs +++ /dev/null @@ -1,85 +0,0 @@ -using System; -using System.Linq; -using OpenMetaverse; -using RestSharp; - -namespace BetterSecondBot.Commands.Script -{ - public class ScriptHttp : CoreCommand_2arg - { - public override string[] ArgTypes { get { return new[] { "TEXT", "Avatar" }; } } - public override string[] ArgHints { get { return new[] { "File endpoint", "Avatar Name/UUID to recive script" }; } } - public override string Helpfile { get { return "[StreamAdmin]\nThis command is part of the streamadmin commands set\n No end user support will be given."; } } - public override bool CallFunction(string[] args) - { - if (base.CallFunction(args) == true) - { - string attempt_endpoint = args[0]; - - Uri uriResult; - bool urlValid = Uri.TryCreate(attempt_endpoint, UriKind.Absolute, out uriResult) - && (uriResult.Scheme == Uri.UriSchemeHttp || uriResult.Scheme == Uri.UriSchemeHttps); - if(urlValid == false) - { - return Failed("Url >" + attempt_endpoint + "< is not a valid URL"); - } - if (attempt_endpoint.Contains("https://github.com/")) - { - attempt_endpoint = attempt_endpoint.Replace("https://github.com/", "https://raw.githubusercontent.com/"); - } - - var client = new RestClient(attempt_endpoint); - var request = new RestRequest("", Method.GET); - request.AddHeader("content-type", "application/x-www-form-urlencoded"); - IRestResponse endpoint_checks = client.Get(request); - if (endpoint_checks.StatusCode == System.Net.HttpStatusCode.OK) - { - try - { - if (endpoint_checks.IsSuccessful == true) - { - if (endpoint_checks.Content.Length > 3) - { - if (UUID.TryParse(args[1], out UUID Avatar)) - { - return bot.SendScript(attempt_endpoint.Split('/').LastOrDefault().Replace("%20", " "), endpoint_checks.Content, Avatar); - } - else - { - Failed("Avatar UUID not valid"); - } - } - else - { - Failed("script title is to short"); - } - } - return Failed(endpoint_checks.ErrorMessage); - } - catch (Exception e) - { - return Failed("Error: " + e.Message + ""); - } - } - else - { - return Failed("HTTP error DataObject broken Status:" + endpoint_checks.StatusCode.ToString() + " @ " + attempt_endpoint + ""); - } - } - return false; - } - } - - public class scriptendpoint : endpoint - { - public string AvatarUUID { get; set; } - public string scriptTitle { get; set; } - public string scriptContent { get; set; } - } - - public class endpoint - { - public bool status { get; set; } - public string message { get; set; } - } -} diff --git a/Core/Commands/Script/scriptSend.cs b/Core/Commands/Script/scriptSend.cs deleted file mode 100644 index 39bc488..0000000 --- a/Core/Commands/Script/scriptSend.cs +++ /dev/null @@ -1,45 +0,0 @@ -using BetterSecondBotShared.Static; -using OpenMetaverse; - -namespace BetterSecondBot.Commands.Script -{ - class ScriptSend : CoreCommand_2arg - { - public override string[] ArgTypes { get { return new[] { "Avatar","Text","Text" }; } } - public override string[] ArgHints { get { return new[] { "Avatar [UUID or Firstname Lastname]", "Collection","Script name" }; } } - public override string Helpfile { get { return "Creats and send a Script to [ARG 1]
" + - " using the collection [ARG 2] as the content
" + - " Optional: You can name the Script using [ARG 3]"; } } - - public override bool CallFunction(string[] args) - { - if (base.CallFunction(args) == true) - { - // target UUID,Script storage id,["Script title" or defaults to: New Script for ] - if (UUID.TryParse(args[0], out UUID target) == true) - { - string content = bot.GetScriptContent(args[1]); - if (content != null) - { - bot.ClearScriptStorage(args[1]); - string Script_name = "New Script for " + args[0] + " " + helpers.UnixTimeNow().ToString() + ""; - if (args.Length == 3) - { - Script_name = args[2] + " " + helpers.UnixTimeNow().ToString() + ""; - } - return bot.SendScript(Script_name, content, target); - } - else - { - return Failed("No content in Script storage " + args[1]); - } - } - else - { - return Failed("Arg 0 not a UUID"); - } - } - return false; - } - } -} diff --git a/Core/Commands/Self/GetLastCommands.cs b/Core/Commands/Self/GetLastCommands.cs deleted file mode 100644 index f19b51c..0000000 --- a/Core/Commands/Self/GetLastCommands.cs +++ /dev/null @@ -1,24 +0,0 @@ -using System; - -namespace BetterSecondBot.Commands.Self -{ - public class GetLastCommands : CoreCommand_SmartReply_1arg - { - public override string Helpfile { get { return "Gets the last 5 commands issued to the bot and returns them via the smart target"; } } - - public override bool CallFunction(string[] args) - { - if (base.CallFunction(args) == true) - { - int entry = 1; - foreach(string a in bot.GetLastCommands(5)) - { - collection.Add(entry.ToString(), a); - entry++; - } - return bot.GetCommandsInterface.SmartCommandReply(true,args[0], "last=5", CommandName,collection); - } - return false; - } - } -} diff --git a/Core/Commands/Self/SetPermFlag.cs b/Core/Commands/Self/SetPermFlag.cs deleted file mode 100644 index c0e4649..0000000 --- a/Core/Commands/Self/SetPermFlag.cs +++ /dev/null @@ -1,51 +0,0 @@ -using OpenMetaverse; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; - -namespace BetterSecondBot.Commands.Self -{ - public class SetPermFlag : CoreCommand_3arg - { - public override string[] ArgTypes { get { return new[] { "Avatar", "Text","Text (True|Flase)", "Text (True|Flase)" }; } } - public override string[] ArgHints { get { return new[] { "Avatar [UUID or Firstname Lastname]", "Flag: friend, group, animation, teleport or command", "State to set the flag to","Make the permission sticky" }; } } - public override string Helpfile { get { return "Makes the bot set/clear a permission flag for a selected action, sticky permissions are kept untill they are removed or the bot restarts"; } } - public override bool CallFunction(string[] args) - { - if (base.CallFunction(args) == true) - { - if(UUID.TryParse(args[0],out UUID targetUUID) == true) - { - string[] AcceptedFlags = new string[] { "friend", "group", "animation", "teleport", "command" }; - if(AcceptedFlags.Contains(args[1]) == true) - { - if(bool.TryParse(args[2],out bool stateflag) == true) - { - bool sticky = false; - if(args.Length == 4) - { - bool.TryParse(args[3], out sticky); - } - if(stateflag == true) - { - bot.Add_action_from(args[1], targetUUID, sticky); - InfoBlob = "Added perm: "+args[1]+" Sticky: " + sticky.ToString(); - } - else - { - bot.Remove_action_from(args[1], targetUUID, sticky); - InfoBlob = "Removed perm: " + args[1] + " Sticky: " + sticky.ToString(); - } - return true; - } - return Failed("Failed to process state flag value"); - } - return Failed("Not an accepted flag"); - } - return Failed("Unable to process UUID"); - } - return false; - } - } -} diff --git a/Core/Commands/Self/logout.cs b/Core/Commands/Self/logout.cs deleted file mode 100644 index d80ec02..0000000 --- a/Core/Commands/Self/logout.cs +++ /dev/null @@ -1,34 +0,0 @@ -using OpenMetaverse; - -namespace BetterSecondBot.Commands.Self -{ - public class Bye : Logout - { - public override string Helpfile { get { return "Makes the bot kill itself you monster, without saying anything"; } } - public override bool CallFunction(string[] args) - { - bot.KillMePlease(); - return true; - } - } - public class Logout : CoreCommand - { - public override string Helpfile { get { return "Makes the bot kill itself you monster"; } } - public override bool CallFunction(string[] args) - { - bot.GetClient.Self.Chat("I dont want to go :( ", 0, ChatType.Normal); - bot.KillMePlease(); - return true; - } - } - - public class Logoff : CoreCommand - { - public override string Helpfile { get { return "Makes the bot kill itself you monster"; } } - public override bool CallFunction(string[] args) - { - - return true; - } - } -} diff --git a/Core/Commands/StreamAdmin/FetchNextNotecard.cs b/Core/Commands/StreamAdmin/FetchNextNotecard.cs deleted file mode 100644 index c480af4..0000000 --- a/Core/Commands/StreamAdmin/FetchNextNotecard.cs +++ /dev/null @@ -1,69 +0,0 @@ -using System; -using OpenMetaverse; -using BetterSecondBotShared.Static; -using RestSharp; -using Newtonsoft.Json; - -namespace BetterSecondBot.Commands.StreamAdmin -{ - public class FetchNextNotecard : CoreCommand_2arg - { - public override string[] ArgTypes { get { return new[] { "TEXT","TEXT" }; } } - public override string[] ArgHints { get { return new[] { "Server endpoint","Server endpoint code" }; } } - public override string Helpfile { get { return "[StreamAdmin]\nThis command is part of the streamadmin commands set\n No end user support will be given."; } } - public override bool CallFunction(string[] args) - { - if(base.CallFunction(args) == true) - { - string attempt_endpoint = "" + args[0] + "endpoint.php"; - string token = helpers.GetSHA1(helpers.UnixTimeNow().ToString()+"notecardnext" + args[1]); - var client = new RestClient("" + args[0] + "endpoint.php"); - var request = new RestRequest("notecard/next", Method.POST); - request.AddParameter("token", token); - request.AddHeader("content-type", "application/x-www-form-urlencoded"); - IRestResponse endpoint_checks = client.Post(request); - if (endpoint_checks.StatusCode == System.Net.HttpStatusCode.OK) - { - try - { - notecardendpoint server_reply = JsonConvert.DeserializeObject(endpoint_checks.Content); - if (server_reply.status == true) - { - if (server_reply.NotecardTitle.Length > 3) - { - return bot.SendNotecard(server_reply.NotecardTitle, server_reply.NotecardContent, (UUID)server_reply.AvatarUUID); - } - else - { - return Failed("Notecard title is to short - "+ endpoint_checks.Content); - } - } - return Failed(server_reply.message); - } - catch (Exception e) - { - return Failed("Error: "+e.Message+""); - } - } - else - { - return Failed("HTTP error DataObject broken Status:"+ endpoint_checks.StatusCode.ToString()+" @ "+ attempt_endpoint+"\n Message given (if any): "+endpoint_checks.Content); - } - } - return Failed("incorrect number of args"); - } - } - - public class notecardendpoint : endpoint - { - public string AvatarUUID { get; set; } - public string NotecardTitle { get; set; } - public string NotecardContent { get; set; } - } - - public class endpoint - { - public bool status { get; set; } - public string message { get; set; } - } -} diff --git a/Core/Core.csproj b/Core/Core.csproj index 4a60d50..dc285be 100644 --- a/Core/Core.csproj +++ b/Core/Core.csproj @@ -8,6 +8,7 @@ + diff --git a/BetterSecondbot/HttpService/Animation.cs b/Core/HttpService/Animation.cs similarity index 91% rename from BetterSecondbot/HttpService/Animation.cs rename to Core/HttpService/Animation.cs index c503689..b5dcec8 100644 --- a/BetterSecondbot/HttpService/Animation.cs +++ b/Core/HttpService/Animation.cs @@ -12,9 +12,9 @@ using System.Reflection; namespace BetterSecondBot.HttpService { - public class HttpApiAnimation : WebApiControllerWithTokens + public class HTTP_Animation : WebApiControllerWithTokens { - public HttpApiAnimation(SecondBot mainbot, TokenStorage setuptokens) : base(mainbot, setuptokens) { } + 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")] diff --git a/BetterSecondbot/HttpService/Avatars.cs b/Core/HttpService/Avatars.cs similarity index 100% rename from BetterSecondbot/HttpService/Avatars.cs rename to Core/HttpService/Avatars.cs diff --git a/BetterSecondbot/HttpService/Chat.cs b/Core/HttpService/Chat.cs similarity index 84% rename from BetterSecondbot/HttpService/Chat.cs rename to Core/HttpService/Chat.cs index 1ddf9bc..db58aab 100644 --- a/BetterSecondbot/HttpService/Chat.cs +++ b/Core/HttpService/Chat.cs @@ -12,9 +12,9 @@ using BetterSecondBotShared.Static; namespace BetterSecondBot.HttpService { - public class HttpApiLocalchat : WebApiControllerWithTokens + public class HTTP_Chat : WebApiControllerWithTokens { - public HttpApiLocalchat(SecondBot mainbot, TokenStorage setuptokens) : base(mainbot, setuptokens) { } + public HTTP_Chat(SecondBot mainbot, TokenStorage setuptokens) : base(mainbot, setuptokens) { } [About("fetchs the last 20 localchat messages")] [ReturnHints("array string")] @@ -29,7 +29,8 @@ namespace BetterSecondBot.HttpService } [About("sends a message to localchat")] - [ArgHints("message", "URLARG", "the message to send")] + [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")] @@ -48,6 +49,10 @@ namespace BetterSecondBot.HttpService { 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())); diff --git a/BetterSecondbot/HttpService/Core.cs b/Core/HttpService/Core.cs similarity index 66% rename from BetterSecondbot/HttpService/Core.cs rename to Core/HttpService/Core.cs index 4b08816..ac83d88 100644 --- a/BetterSecondbot/HttpService/Core.cs +++ b/Core/HttpService/Core.cs @@ -53,52 +53,9 @@ namespace BetterSecondBot.HttpService - [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 Failure("Error Unable to AutoPilot to location"); - } - return Failure("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 Failure("Error Unable to Teleport to location"); - } - return Failure("Token not accepted"); - } - - [About("Used to check HTTP connections")] [ReturnHints("world")] [NeedsToken(false)] diff --git a/BetterSecondbot/HttpService/Dialogs.cs b/Core/HttpService/Dialogs.cs similarity index 100% rename from BetterSecondbot/HttpService/Dialogs.cs rename to Core/HttpService/Dialogs.cs diff --git a/BetterSecondbot/HttpService/Discord.cs b/Core/HttpService/Discord.cs similarity index 100% rename from BetterSecondbot/HttpService/Discord.cs rename to Core/HttpService/Discord.cs diff --git a/BetterSecondbot/HttpService/Estate.cs b/Core/HttpService/Estate.cs similarity index 95% rename from BetterSecondbot/HttpService/Estate.cs rename to Core/HttpService/Estate.cs index 9445e7f..9b84b46 100644 --- a/BetterSecondbot/HttpService/Estate.cs +++ b/Core/HttpService/Estate.cs @@ -14,9 +14,9 @@ namespace BetterSecondBot.HttpService - public class HttpAPIEstate : WebApiControllerWithTokens + public class HTTP_Estate : WebApiControllerWithTokens { - public HttpAPIEstate(SecondBot mainbot, TokenStorage setuptokens) : base(mainbot, setuptokens) + public HTTP_Estate(SecondBot mainbot, TokenStorage setuptokens) : base(mainbot, setuptokens) { } diff --git a/BetterSecondbot/HttpService/Friends.cs b/Core/HttpService/Friends.cs similarity index 100% rename from BetterSecondbot/HttpService/Friends.cs rename to Core/HttpService/Friends.cs diff --git a/BetterSecondbot/HttpService/Funds.cs b/Core/HttpService/Funds.cs similarity index 100% rename from BetterSecondbot/HttpService/Funds.cs rename to Core/HttpService/Funds.cs diff --git a/BetterSecondbot/HttpService/Group.cs b/Core/HttpService/Group.cs similarity index 96% rename from BetterSecondbot/HttpService/Group.cs rename to Core/HttpService/Group.cs index 8a6ddf6..f44b764 100644 --- a/BetterSecondbot/HttpService/Group.cs +++ b/Core/HttpService/Group.cs @@ -12,9 +12,9 @@ using BetterSecondBotShared.Static; namespace BetterSecondBot.HttpService { - public class HttpApiGroup : WebApiControllerWithTokens + public class HTTP_Group : WebApiControllerWithTokens { - public HttpApiGroup(SecondBot mainbot, TokenStorage setuptokens) : base(mainbot, setuptokens) { } + public HTTP_Group(SecondBot mainbot, TokenStorage setuptokens) : base(mainbot, setuptokens) { } [About("Checks if the given UUID is in the given group
Note: if group membership data is more than 60 secs old this will return Updating
Please wait and retry later")] diff --git a/BetterSecondbot/HttpService/Home.cs b/Core/HttpService/Home.cs similarity index 84% rename from BetterSecondbot/HttpService/Home.cs rename to Core/HttpService/Home.cs index c0ee1ec..c8104a2 100644 --- a/BetterSecondbot/HttpService/Home.cs +++ b/Core/HttpService/Home.cs @@ -12,9 +12,9 @@ using BetterSecondBotShared.Static; namespace BetterSecondBot.HttpService { - public class Http_Home : WebApiControllerWithTokens + public class HTTP_Home : WebApiControllerWithTokens { - public Http_Home(SecondBot mainbot, TokenStorage setuptokens) : base(mainbot, setuptokens) { } + public HTTP_Home(SecondBot mainbot, TokenStorage setuptokens) : base(mainbot, setuptokens) { } [About("Makes the bot teleport to its home region")] [ReturnHints("ok")] diff --git a/BetterSecondbot/HttpService/HttpAsService.cs b/Core/HttpService/HttpAsService.cs similarity index 89% rename from BetterSecondbot/HttpService/HttpAsService.cs rename to Core/HttpService/HttpAsService.cs index 07c0948..f300c37 100644 --- a/BetterSecondbot/HttpService/HttpAsService.cs +++ b/Core/HttpService/HttpAsService.cs @@ -178,13 +178,13 @@ namespace BetterSecondBot.HttpService // .WithRegexRules("HTTP exception 404") //) .WithWebApi("/inventory", m => m - .WithController(() => new HttpApiInventory(Bot, Tokens)) + .WithController(() => new HTTP_Inventory(Bot, Tokens)) ) .WithWebApi("/chat", m => m - .WithController(() => new HttpApiLocalchat(Bot, Tokens)) + .WithController(() => new HTTP_Chat(Bot, Tokens)) ) .WithWebApi("/groups", m => m - .WithController(() => new HttpApiGroup(Bot, Tokens)) + .WithController(() => new HTTP_Group(Bot, Tokens)) ) .WithWebApi("/ims", m => m .WithController(() => new HttpApiIM(Bot, Tokens)) @@ -193,10 +193,10 @@ namespace BetterSecondBot.HttpService .WithController(() => new HttpApiCore(Config, Bot, Tokens)) ) .WithWebApi("/parcel", m => m - .WithController(() => new HttpApiParcel(Bot,Tokens)) + .WithController(() => new HTTP_Parcel(Bot,Tokens)) ) .WithWebApi("/estate", m => m - .WithController(() => new HttpAPIEstate(Bot, Tokens)) + .WithController(() => new HTTP_Estate(Bot, Tokens)) ) .WithModule(new ActionModule("/", HttpVerbs.Any, ctx => ctx.SendDataAsync(new { Message = "Error" }))); return server; @@ -397,6 +397,7 @@ namespace BetterSecondBot.HttpService protected SecondBot bot; public bool needsToken { get; set; } protected UUID avataruuid = UUID.Zero; + protected Parcel targetparcel = null; protected string CallMethod(string name,string[] args) { @@ -423,6 +424,24 @@ namespace BetterSecondBot.HttpService string reply = (string)found.Invoke(this, settings.Cast().ToArray()); return "Passed:"+ reply; } + protected KeyValuePair SetupCurrentParcel(string token,string usenamespace,string command) + { + if (tokens.Allow(token, usenamespace, command, getClientIP()) == false) + { + return new KeyValuePair(false, "Token not accepted"); + } + if (bot.GetClient.Network.CurrentSim == null) + { + return new KeyValuePair(false, "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 new KeyValuePair(false, "Parcel data not ready"); + } + Parcel targetparcel = bot.GetClient.Network.CurrentSim.Parcels[localid]; + return new KeyValuePair(true, ""); + } protected void ProcessAvatar(string avatar) { string[] bits = avatar.Split(' '); diff --git a/BetterSecondbot/HttpService/Im.cs b/Core/HttpService/Im.cs similarity index 100% rename from BetterSecondbot/HttpService/Im.cs rename to Core/HttpService/Im.cs diff --git a/BetterSecondbot/HttpService/Info.cs b/Core/HttpService/Info.cs similarity index 94% rename from BetterSecondbot/HttpService/Info.cs rename to Core/HttpService/Info.cs index 9f00532..8d56528 100644 --- a/BetterSecondbot/HttpService/Info.cs +++ b/Core/HttpService/Info.cs @@ -12,9 +12,9 @@ using BetterSecondBotShared.Static; namespace BetterSecondBot.HttpService { - public class Http_Info : WebApiControllerWithTokens + public class HTTP_Info : WebApiControllerWithTokens { - public Http_Info(SecondBot mainbot, TokenStorage setuptokens) : base(mainbot, setuptokens) { } + public HTTP_Info(SecondBot mainbot, TokenStorage setuptokens) : base(mainbot, setuptokens) { } [About("Fetchs the current bot")] [ReturnHints("The build ID of the bot")] diff --git a/BetterSecondbot/HttpService/Inventory.cs b/Core/HttpService/Inventory.cs similarity index 62% rename from BetterSecondbot/HttpService/Inventory.cs rename to Core/HttpService/Inventory.cs index b87c908..1a6ae67 100644 --- a/BetterSecondbot/HttpService/Inventory.cs +++ b/Core/HttpService/Inventory.cs @@ -10,17 +10,17 @@ using OpenMetaverse; namespace BetterSecondBot.HttpService { - public class HttpApiInventory : WebApiControllerWithTokens + public class HTTP_Inventory : WebApiControllerWithTokens { - public HttpApiInventory(SecondBot mainbot, TokenStorage setuptokens) : base(mainbot, setuptokens) { } + 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, [FormField] string newname) + [Route(HttpVerbs.Get, "/RezObject/{item}/{token}")] + public object RezObject(string item, string token) { - if (tokens.Allow(token, "inventory", "rezobject", getClientIP()) == true) + if (tokens.Allow(token, "inventory", "RezObject", getClientIP()) == true) { bool status = bot.GetCommandsInterface.Call("RezObject", item); return BasicReply(status.ToString()); @@ -28,14 +28,15 @@ namespace BetterSecondBot.HttpService 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) + [Route(HttpVerbs.Post, "/Rename/{item}/{token}")] + public object Rename(string item, string token, [FormField] string newname) { - if (tokens.Allow(token, "inventory", "rename", getClientIP()) == true) + if (tokens.Allow(token, "inventory", "Rename", getClientIP()) == true) { bool status = bot.GetCommandsInterface.Call("RenameInventory", "12~#~" + item + "~#~" + newname); return BasicReply(status.ToString()); @@ -85,6 +86,72 @@ namespace BetterSecondBot.HttpService return BasicReply("Token not accepted"); } + [About("Transfers a item [ARG 2] to a objects inventory [ARG 1] (And if set with the script running state [ARG 3])")] + [ReturnHints("Transfering running script")] + [ReturnHints("Transfering inventory")] + [ReturnHints("Invaild item uuid")] + [ReturnHints("Invaild object uuid")] + [ReturnHints("Unable to find inventory")] + [ReturnHints("Unable to find object")] + [ReturnHints("Invaild running")] + [ArgHints("item", "URLARG", "UUID of item")] + [ArgHints("object", "URLARG", "the uuid of the object")] + [ArgHints("running", "URLARG", "true if you wish the transfered script to be running otherwise false")] + + [Route(HttpVerbs.Get, "/TransferInventoryToObject/{item}/{objectuuid}/{running}/{token}")] + public object TransferInventoryToObject(string item, string objectuuid, string running, string token) + { + if (tokens.Allow(token, "inventory", "TransferInventoryToObject", getClientIP()) == true) + { + return Failure("Token not accepted"); + } + if (UUID.TryParse(item, out UUID itemuuid) == false) + { + return Failure("Invaild item uuid"); + } + if (UUID.TryParse(objectuuid, out UUID objectUUID) == false) + { + return Failure("Invaild object uuid"); + } + if (bool.TryParse(running, out bool runscript) == false) + { + return Failure("Invaild running"); + } + + InventoryItem itm = bot.GetClient.Inventory.FetchItem(itemuuid, bot.GetClient.Self.AgentID, (3 * 1000)); + if (itm == null) + { + return Failure("Unable to find inventory"); + } + Dictionary objects_copy = bot.GetClient.Network.CurrentSim.ObjectsPrimitives.Copy(); + KeyValuePair RealObject = new KeyValuePair(0,null); + foreach (KeyValuePair Obj in objects_copy) + { + if (Obj.Value.ID == objectUUID) + { + RealObject = Obj; + break; + } + } + if (RealObject.Value == null) + { + return Failure("Unable to find object"); + } + bool scriptState = runscript; + if (itm.AssetType != AssetType.LSLText) + { + scriptState = false; + } + if (itm.AssetType == AssetType.LSLText) + { + bot.GetClient.Inventory.CopyScriptToTask(RealObject.Key, itm, scriptState); + return BasicReply("Transfering script [state: "+scriptState.ToString()+"]"); + } + bot.GetClient.Inventory.UpdateTaskInventory(RealObject.Key, itm); + return BasicReply("Transfering inventory"); + } + + [About("Removes a item/folder from inventory (Make sure you set the isfolder flag correctly!)")] [ReturnHints("True|False")] [ReturnHints("Failed - isfolder must be True or False")] diff --git a/Core/HttpService/Movement.cs b/Core/HttpService/Movement.cs new file mode 100644 index 0000000..096979d --- /dev/null +++ b/Core/HttpService/Movement.cs @@ -0,0 +1,131 @@ +using BetterSecondBot.bottypes; +using BetterSecondBot.Static; +using EmbedIO; +using EmbedIO.Routing; +using EmbedIO.WebApi; +using System; +using System.Collections.Generic; +using System.Text; +using OpenMetaverse; +using Newtonsoft.Json; +using System.Reflection; +using System.Threading; +using BetterSecondBotShared.Static; + +namespace BetterSecondBot.HttpService +{ + public class HTTP_Movement : WebApiControllerWithTokens + { + public HTTP_Movement(SecondBot mainbot, TokenStorage setuptokens) : base(mainbot, setuptokens) { } + + [About("uses the AutoPilot to move to a location")] + [ReturnHints("Error Unable to AutoPilot to location")] + [ReturnHints("Accepted")] + [ReturnHints("Convert to vector has failed")] + [ReturnHints("? value out of range 0-?")] + [ArgHints("x", "URLARG", "X location to AutoPilot to")] + [ArgHints("y", "URLARG", "y location to AutoPilot to")] + [ArgHints("z", "URLARG", "z location to AutoPilot to")] + [Route(HttpVerbs.Get, "/AutoPilot/{x}/{y}/{z}/{token}")] + public object AutoPilot(string x, string y, string z, string token) + { + if (tokens.Allow(token, "movement", "AutoPilot", getClientIP()) == false) + { + return Failure("Token not accepted"); + } + if (Vector3.TryParse("<" + x + "," + y + "," + z + ">", out Vector3 pos) == false) + { + return Failure("Convert to vector has failed"); + } + if (helpers.inrange(pos.X, 0, 255) == false) + { + return Failure("x value out of range 0-255"); + } + if (helpers.inrange(pos.Y, 0, 255) == false) + { + return Failure("y value out of range 0-255"); + } + if (helpers.inrange(pos.Z, 0, 5000) == false) + { + return Failure("z value out of range 0-5000"); + } + bot.GetClient.Self.AutoPilotCancel(); + bot.GetClient.Self.Movement.TurnToward(pos, true); + Thread.Sleep(500); + uint Globalx, Globaly; + Utils.LongToUInts(bot.GetClient.Network.CurrentSim.Handle, out Globalx, out Globaly); + bot.GetClient.Self.AutoPilot((ulong)(Globalx + pos.X), (ulong)(Globaly + pos.Y), pos.Z); + return true; + } + + [About("Attempt to teleport to a new region")] + [ReturnHints("Error Unable to Teleport to location")] + [ReturnHints("Accepted")] + [ArgHints("region", "URLARG", "the name of the region we are going to")] + [ArgHints("x", "URLARG", "X location to teleport to")] + [ArgHints("y", "URLARG", "y location to teleport to")] + [ArgHints("z", "URLARG", "z location to teleport to")] + [Route(HttpVerbs.Get, "/Teleport/{region}/{x}/{y}/{z}/{token}")] + public object Teleport(string region, string x, string y, string z, string token) + { + if (tokens.Allow(token, "core", "Teleport", getClientIP()) == true) + { + bool status = TeleportRequest(new string[] { region, x, y, z }); + if (status == true) + { + return BasicReply("Accepted"); + } + return Failure("Error Unable to Teleport to location"); + } + return Failure("Token not accepted"); + } + + + + protected bool TeleportRequest(string[] args) + { + bot.GetClient.Self.AutoPilotCancel(); + if (args[0].Contains("http://maps.secondlife.com/secondlife/") == true) + { + bot.TeleportWithSLurl(args[0]); + return true; + } + else + { + float posX = 128; + float posY = 128; + float posZ = 0; + string regionName = bot.GetClient.Network.CurrentSim.Name; + bool ok = true; + int offset = 0; + string[] tp_args = args[0].Split('/'); + if ((tp_args.Length == 4) || (tp_args.Length == 1)) + { + regionName = tp_args[0]; + offset = 1; + } + if (tp_args.Length >= 3) + { + float.TryParse(tp_args[offset + 0], out posX); + float.TryParse(tp_args[offset + 1], out posY); + float.TryParse(tp_args[offset + 2], out posZ); + } + else if (tp_args.Length == 2) + { + ok = false; + } + if (ok == true) + { + bot.SetTeleported(); + bool status = bot.GetClient.Self.Teleport(regionName, new Vector3(posX, posY, posZ)); + bot.ResetAnimations(); + return status; + } + else + { + return false; + } + } + } + } +} diff --git a/Core/HttpService/Parcel.cs b/Core/HttpService/Parcel.cs new file mode 100644 index 0000000..67e68f8 --- /dev/null +++ b/Core/HttpService/Parcel.cs @@ -0,0 +1,620 @@ +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; +using BetterSecondBotShared.Static; +using BetterSecondBotShared.logs; +using System.Threading; + +namespace BetterSecondBot.HttpService +{ + public partial class HTTP_Parcel : WebApiControllerWithTokens + { + public HTTP_Parcel(SecondBot mainbot, TokenStorage setuptokens) : base(mainbot, setuptokens) { } + + [About("Sets the current parcel for sale Also marks the parcel for sale")] + [ReturnHints("ok")] + [ReturnHints("Error not in a sim")] + [ReturnHints("Parcel data not ready")] + [ReturnHints("Invaild amount")] + [ArgHints("amount", "URLARG", "The amount to sell the parcel for from 1 to 9999999")] + [ArgHints("avatar", "URLARG", "Avatar uuid or Firstname Lastname or \"none\" who we are locking the sale to")] + [Route(HttpVerbs.Get, "/SetParcelSale/{amount}/{avatar}/{token}")] + public object SetParcelSale(string amount,string avatar,string token) + { + KeyValuePair tests = SetupCurrentParcel(token, "parcel", "SetParcelSale"); + if(tests.Key == false) + { + return Failure(tests.Value); + } + if (int.TryParse(amount,out int amountvalue) == false) + { + return Failure("Invaild amount"); + } + if((amountvalue < 1) || (amountvalue > 9999999)) + { + return Failure("Invaild amount"); + } + ProcessAvatar(avatar); + targetparcel.SalePrice = amountvalue; + targetparcel.AuthBuyerID = avataruuid; + parcel_static.ParcelSetFlag(ParcelFlags.ForSale, targetparcel, true); + parcel_static.ParcelSetFlag(ParcelFlags.ForSaleObjects, targetparcel, false); + targetparcel.Update(bot.GetClient.Network.CurrentSim, false); + return Failure("ok"); + } + + [About("Updates the current parcels name")] + [ReturnHints("ok")] + [ReturnHints("Error not in a sim")] + [ReturnHints("Parcel data not ready")] + [ReturnHints("Parcel name is empty")] + [ArgHints("name", "URLARG", "The new name of the parcel")] + [Route(HttpVerbs.Get, "/SetParcelName/{name}/{token}")] + public object SetParcelName(string name, string token) + { + KeyValuePair tests = SetupCurrentParcel(token, "parcel", "SetParcelName"); + if (tests.Key == false) + { + return Failure(tests.Value); + } + if (helpers.notempty(name) == false) + { + return Failure("Parcel name is empty"); + } + targetparcel.Name = name; + targetparcel.Update(bot.GetClient.Network.CurrentSim, false); + return Failure("ok"); + } + + [About("Updates the current parcels description")] + [ReturnHints("ok")] + [ReturnHints("Error not in a sim")] + [ReturnHints("Parcel data not ready")] + [ArgHints("desc", "Text", "The new desc of the parcel")] + [Route(HttpVerbs.Post, "/SetParcelDesc/{token}")] + public object SetParcelDesc([FormField] string desc, string token) + { + KeyValuePair tests = SetupCurrentParcel(token, "parcel", "SetParcelDesc"); + if (tests.Key == false) + { + return Failure(tests.Value); + } + targetparcel.Desc = desc; + targetparcel.Update(bot.GetClient.Network.CurrentSim, false); + return Failure("ok"); + } + + [About("Fetchs the current parcels desc")] + [ReturnHints("ok")] + [ReturnHints("Error not in a sim")] + [ReturnHints("Parcel data not ready")] + [Route(HttpVerbs.Get, "/GetParcelDesc/{token}")] + public object GetParcelDesc(string token) + { + KeyValuePair tests = SetupCurrentParcel(token, "parcel", "GetParcelDesc"); + if (tests.Key == false) + { + return Failure(tests.Value); + } + return Failure(targetparcel.Desc); + } + + [About("gets the flags for the parcel")] + [ReturnHints("ok")] + [ReturnHints("Error not in a sim")] + [ReturnHints("Parcel data not ready")] + [Route(HttpVerbs.Get, "/GetParcelFlags/{token}")] + public object GetParcelFlags(string token) + { + KeyValuePair tests = SetupCurrentParcel(token, "parcel", "GetParcelFlags"); + if (tests.Key == false) + { + return Failure(tests.Value); + } + Dictionary flags = parcel_static.get_flags_list(); + Dictionary collection = new Dictionary(); + foreach (ParcelFlags cfg in flags.Values) + { + collection.Add(cfg.ToString(), targetparcel.Flags.HasFlag(cfg).ToString()); + } + return collection; + } + + [About("Ejects an avatar")] + [ReturnHints("ok")] + [ReturnHints("Invaild avatar")] + [ArgHints("avatar", "URLARG", "uuid of the avatar or Firstname Lastname")] + [Route(HttpVerbs.Get, "/ParcelEject/{avatar}/{token}")] + public object ParcelEject(string avatar,string token) + { + if (tokens.Allow(token, "parcel", "ParcelEject", getClientIP()) == false) + { + return BasicReply("Token not accepted"); + } + ProcessAvatar(avatar); + if(avataruuid == UUID.Zero) + { + return Failure("Invaild avatar"); + } + bot.GetClient.Parcels.EjectUser(avataruuid, false); + return BasicReply("ok"); + } + + [About("Abandons the parcel the bot is currently on, returning it to Linden's or Estate owner")] + [ReturnHints("ok")] + [Route(HttpVerbs.Get, "/AbandonLand/{token}")] + public object AbandonLand(string token) + { + KeyValuePair tests = SetupCurrentParcel(token, "parcel", "AbandonLand"); + if (tests.Key == false) + { + return Failure(tests.Value); + } + bot.GetClient.Parcels.ReleaseParcel(bot.GetClient.Network.CurrentSim, targetparcel.LocalID); + return BasicReply("ok"); + } + + + [About("Bans an avatar from a parcel")] + [ReturnHints("ok")] + [ReturnHints("Error not in a sim")] + [ReturnHints("Parcel data not ready")] + [ReturnHints("Invaild avatar")] + [ReturnHints("Avatar is in the blacklist")] + [ArgHints("avatar", "URLARG", "uuid of the avatar or Firstname Lastname")] + [Route(HttpVerbs.Get, "/ParcelBan/{avatar}/{token}")] + public object ParcelBan(string avatar, string token) + { + KeyValuePair tests = SetupCurrentParcel(token, "parcel", "ParcelBan"); + if (tests.Key == false) + { + return Failure(tests.Value); + } + ProcessAvatar(avatar); + if (avataruuid == UUID.Zero) + { + return Failure("Invaild avatar"); + } + bool alreadyBanned = false; + foreach (ParcelAccessEntry E in targetparcel.AccessBlackList) + { + if (E.AgentID == avataruuid) + { + alreadyBanned = true; + break; + } + } + if (alreadyBanned == true) + { + return BasicReply("Avatar is in the blacklist"); + } + ParcelAccessEntry entry = new ParcelAccessEntry(); + entry.AgentID = avataruuid; + entry.Flags = AccessList.Ban; + entry.Time = new System.DateTime(3030, 03, 03); + targetparcel.AccessBlackList.Add(entry); + targetparcel.Update(bot.GetClient.Network.CurrentSim, false); + return BasicReply("ok"); + } + + [About("Unbans an avatar from a parcel")] + [ReturnHints("ok")] + [ReturnHints("Error not in a sim")] + [ReturnHints("Parcel data not ready")] + [ReturnHints("Invaild avatar")] + [ReturnHints("Avatar is already unbanned")] + [ArgHints("avatar", "URLARG", "uuid of the avatar or Firstname Lastname")] + [Route(HttpVerbs.Get, "/ParcelUnBan/{avatar}/{token}")] + public object ParcelUnBan(string avatar, string token) + { + KeyValuePair tests = SetupCurrentParcel(token, "parcel", "ParcelUnBan"); + if (tests.Key == false) + { + return Failure(tests.Value); + } + ProcessAvatar(avatar); + if (avataruuid == UUID.Zero) + { + return Failure("Invaild avatar"); + } + bool alreadyBanned = false; + ParcelAccessEntry removeentry = new ParcelAccessEntry(); + foreach (ParcelAccessEntry E in targetparcel.AccessBlackList) + { + if (E.AgentID == avataruuid) + { + alreadyBanned = true; + removeentry = E; + break; + } + } + if (alreadyBanned == false) + { + return BasicReply("Avatar is already unbanned"); + } + targetparcel.AccessBlackList.Remove(removeentry); + targetparcel.Update(bot.GetClient.Network.CurrentSim, false); + return BasicReply("ok"); + } + + + [About("Updates the current parcels name")] + [ReturnHints("true|false")] + [ReturnHints("Error not in a sim")] + [ReturnHints("Parcel data not ready")] + [ArgHints("musicurl", "URLARG", "The new name of the parcel")] + [Route(HttpVerbs.Get, "/SetParcelMusic/{musicurl}/{token}")] + public object SetParcelMusic(string musicurl, string token) + { + KeyValuePair tests = SetupCurrentParcel(token, "parcel", "SetParcelMusic"); + if (tests.Key == false) + { + return Failure(tests.Value); + } + bool status = parcel_static.set_parcel_music(bot, targetparcel, musicurl); + return Failure(status.ToString()); + } + + [About("Updates the current parcels name")] + [ReturnHints("true|false")] + [ReturnHints("Error not in a sim")] + [ReturnHints("Parcel data not ready")] + [ReturnHints("Incorrect perms to control parcel")] + [ReturnHints("No accepted flags")] + [ReturnHints("Unable to set flag ...")] + [ReturnHints("Flag: ? is unknown")] + [ReturnHints("Flag: ? missing \"=\"")] + [ArgHints("escapedflagdata", "Text", "repeatable flag data split by ::: formated Flag=True|False")] + [Route(HttpVerbs.Post, "/SetParcelFlag/{escapedflagdata}/{token}")] + public object SetParcelFlag([FormField] string escapedflagdata, string token) + { + KeyValuePair tests = SetupCurrentParcel(token, "parcel", "SetParcelFlag"); + if (tests.Key == false) + { + return Failure(tests.Value); + } + List acceptablewords = new List(); + Dictionary flags = parcel_static.get_flags_list(); + acceptablewords.AddRange(new[] { "True", "False" }); + + Dictionary setflags = new Dictionary(); + string[] args = escapedflagdata.Split(":::"); + foreach (string a in args) + { + string[] parts = a.Split('=', StringSplitOptions.RemoveEmptyEntries); + if (parts.Length != 2) + { + LogFormater.Warn("Flag: " + a + " missing \"=\""); + continue; + } + if (flags.ContainsKey(parts[0]) == false) + { + LogFormater.Warn("Flag: " + parts[0] + " is unknown"); + continue; + } + if (acceptablewords.Contains(parts[1]) == false) + { + LogFormater.Crit("Unable to set flag " + parts[0] + " to : " + parts[1] + ""); + } + setflags.Add(parts[0], Convert.ToBoolean(parts[1])); + } + if (setflags.Count == 0) + { + return Failure("No accepted flags"); + } + if (parcel_static.has_parcel_perm(targetparcel, bot) == false) + { + return Failure("Incorrect perms to control parcel"); + } + foreach (KeyValuePair cfg in setflags) + { + if (flags.ContainsKey(cfg.Key) == true) + { + parcel_static.ParcelSetFlag(flags[cfg.Key], targetparcel, cfg.Value); + } + } + targetparcel.Update(bot.GetClient.Network.CurrentSim, false); + return BasicReply("Applying perms"); + } + + [About("Returns all objects from the current parcel for the selected avatar")] + [ReturnHints("ok")] + [ReturnHints("Error not in a sim")] + [ReturnHints("Parcel data not ready")] + [ReturnHints("Invaild avatar UUID")] + [ArgHints("avatar", "URLARG", "avatar uuid or Firstname Lastname")] + [Route(HttpVerbs.Get, "/ParcelReturnTargeted/{avatar}/{token}")] + public object ParcelReturnTargeted(string avatar, string token) + { + KeyValuePair tests = SetupCurrentParcel(token, "parcel", "ParcelReturnTargeted"); + if (tests.Key == false) + { + return Failure(tests.Value); + } + ProcessAvatar(avatar); + if (avataruuid == UUID.Zero) + { + return Failure("Invaild avatar UUID"); + } + bot.GetClient.Parcels.ReturnObjects(bot.GetClient.Network.CurrentSim, targetparcel.LocalID, ObjectReturnType.None, new List() { avataruuid }); + return BasicReply("ok"); + } + + + [About("transfers the current parcel ownership to the assigned group")] + [ReturnHints("ok")] + [ReturnHints("Error not in a sim")] + [ReturnHints("Parcel data not ready")] + [ReturnHints("Invaild group uuid")] + [ReturnHints("Not in group")] + [Route(HttpVerbs.Get, "/ParcelDeedToGroup/{group}/{token}")] + public object ParcelDeedToGroup(string group, string token) + { + KeyValuePair tests = SetupCurrentParcel(token, "parcel", "ParcelReturnTargeted"); + if (tests.Key == false) + { + return Failure(tests.Value); + } + if (UUID.TryParse(group, out UUID groupuuid) == false) + { + return Failure("Invaild group uuid"); + } + if (bot.MyGroups.ContainsKey(groupuuid) == false) + { + return Failure("Not in group"); + } + targetparcel.GroupID = groupuuid; + targetparcel.Update(bot.GetClient.Network.CurrentSim, false); + Thread.Sleep(500); + bot.GetClient.Parcels.DeedToGroup(bot.GetClient.Network.CurrentSim, targetparcel.LocalID, groupuuid); + return BasicReply("ok"); + } + + [About("Attempts to buy the parcel the bot is standing on, the amount must match the sale price for the land!")] + [ReturnHints("ok")] + [ReturnHints("Error not in a sim")] + [ReturnHints("Parcel data not ready")] + [ReturnHints("Parcel not for sale")] + [ReturnHints("Parcel not for sale")] + [ReturnHints("Parcel sale locked to other avatars")] + [ReturnHints("Parcel sale price and amount do not match")] + [ReturnHints("Invaild amount")] + [ArgHints("amount", "URLARG", "amount to pay for the parcel (min 1)")] + [Route(HttpVerbs.Get, "/ParcelBuy/{amount}/{token}")] + public object ParcelBuy(string amount, string token) + { + KeyValuePair tests = SetupCurrentParcel(token, "parcel", "ParcelBuy"); + if (tests.Key == false) + { + return Failure(tests.Value); + } + if (int.TryParse(amount, out int amountvalue) == false) + { + return Failure("Invaild amount"); + } + if (amountvalue < 1) + { + return Failure("Invaild amount"); + }; + if (targetparcel.Flags.HasFlag(ParcelFlags.ForSale) == false) + { + return Failure("Parcel not for sale"); + } + if ((targetparcel.AuthBuyerID != UUID.Zero) && (targetparcel.AuthBuyerID != bot.GetClient.Self.AgentID)) + { + return Failure("Parcel sale locked to other avatars"); + } + if (targetparcel.SalePrice != amountvalue) + { + return Failure("Parcel sale price and amount do not match"); + } + bot.GetClient.Parcels.Buy(bot.GetClient.Network.CurrentSim, targetparcel.LocalID, false, UUID.Zero, false, targetparcel.Area, amountvalue); + return BasicReply("ok"); + } + + [About("Freezes an avatar")] + [ReturnHints("ok")] + [ReturnHints("Invaild avatar UUID")] + [ReturnHints("Invaild state")] + [ArgHints("avatar", "URLARG", "avatar uuid or Firstname Lastname")] + [ArgHints("state", "URLARG", "setting state to false will unfreeze or true to freeze")] + [Route(HttpVerbs.Get, "/ParcelFreeze/{avatar}/{state}/{token}")] + public object ParcelFreeze(string avatar, string state, string token) + { + if (tokens.Allow(token, "parcel", "ParcelFreeze", getClientIP()) == false) + { + return Failure("Token not accepted"); + } + if(bool.TryParse(state, out bool freezestate) == false) + { + return Failure("Invaild state"); + } + ProcessAvatar(avatar); + if (avataruuid == UUID.Zero) + { + return Failure("Invaild avatar UUID"); + } + bot.GetClient.Parcels.FreezeUser(avataruuid, freezestate); + return BasicReply("ok"); + } + + + [About("Fetchs the parcel ban list of the parcel the bot is currently on
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, "/GetParcelBanlist/{token}")] + public object GetParcelBanlist(string token) + { + KeyValuePair tests = SetupCurrentParcel(token, "parcel", "GetParcelBanlist"); + if (tests.Key == false) + { + return Failure(tests.Value); + } + Dictionary reply = new Dictionary(); + foreach (ParcelAccessEntry e in targetparcel.AccessBlackList) + { + string name = bot.FindAvatarKey2Name(e.AgentID); + reply.Add(e.AgentID.ToString(), name); + } + return BasicReply(JsonConvert.SerializeObject(reply)); + } + + [About("Returns a rezzed object")] + [ReturnHints("ok")] + [ReturnHints("Invaild object uuid")] + [ReturnHints("Unable to find object")] + [ArgHints("objectuuid", "URLARG", "object UUID to unrez")] + [Route(HttpVerbs.Get, "/UnRezObject/{objectuuid}/{token}")] + public object UnRezObject(string objectuuid,string token) + { + if (tokens.Allow(token, "parcel", "UnRezObject", getClientIP()) == false) + { + return Failure("Token not accepted"); + } + if (UUID.TryParse(objectuuid, out UUID targetobject) == false) + { + return Failure("Invaild object uuid"); + } + bool found = false; + Dictionary objects_copy = bot.GetClient.Network.CurrentSim.ObjectsPrimitives.Copy(); + foreach (KeyValuePair Obj in objects_copy) + { + if (Obj.Value.ID == targetobject) + { + bot.GetClient.Inventory.RequestDeRezToInventory(Obj.Key); + found = true; + break; + } + } + if(found == false) + { + return Failure("Unable to find object"); + } + return BasicReply("ok"); + } + + [About("Updates the current parcels media settings \n" + + "MediaAutoScale=Bool (True|False)\n" + + "MediaLoop=Bool (True|False)\n" + + "MediaID=UUID (Texture)\n" + + "MediaURL=String\n" + + "MediaDesc=String\n" + + "MediaHeight=Int (256 to 1024)\n" + + "MediaWidth=Int (256 to 1024)\n" + + "MediaType=String [\"IMG-PNG\",\"IMG-JPG\",\"VID-MP4\",\"VID-AVI\" or \"Custom-MIME_TYPE_CODE\"]" + )] + [ReturnHints("ok")] + [ReturnHints("Error not in a sim")] + [ReturnHints("Parcel data not ready")] + [ArgHints("escapedflagdata", "Text", "repeatable flag data split by ::: formated Flag=True|False")] + [Route(HttpVerbs.Get, "/ParcelSetMedia/{token}")] + public object ParcelSetMedia([FormField] string escapedflagdata, string token) + { + KeyValuePair tests = SetupCurrentParcel(token, "parcel", "ParcelSetMedia"); + if (tests.Key == false) + { + return Failure(tests.Value); + } + string[] args = escapedflagdata.Split(":::"); + foreach (string A in args) + { + string[] bits = A.Split('='); + if (bits.Length == 2) + { + if (bits[0] == "MediaType") + { + UpdateParcel_MediaType(targetparcel, bits[1]); + } + else if ((bits[0] == "MediaWidth") || (bits[0] == "MediaHeight")) + { + if (int.TryParse(bits[1], out int size) == true) + { + if ((size >= 256) || (size <= 1024)) + { + if (bits[0] == "MediaHeight") + { + targetparcel.Media.MediaHeight = size; + } + else if (bits[0] == "MediaWidth") + { + targetparcel.Media.MediaWidth = size; + } + } + } + } + else if (bits[0] == "MediaID") + { + if (UUID.TryParse(bits[1], out UUID texture) == true) + { + targetparcel.Media.MediaID = texture; + } + } + else if (bits[0] == "MediaURL") + { + targetparcel.Media.MediaURL = bits[1]; + } + else if (bits[0] == "MediaDesc") + { + targetparcel.Media.MediaDesc = bits[1]; + } + else if (bits[0] == "MediaAutoScale") + { + if (bool.TryParse(bits[1], out bool output) == true) + { + targetparcel.Media.MediaAutoScale = output; + } + } + else if (bits[0] == "MediaLoop") + { + if (bool.TryParse(bits[1], out bool output) == true) + { + targetparcel.Media.MediaLoop = output; + } + } + } + } + targetparcel.Update(bot.GetClient.Network.CurrentSim, false); + return BasicReply("ok"); + } + + protected bool UpdateParcel_MediaType(Parcel targetparcel, string value) + { + if (value == "IMG-PNG") + { + targetparcel.Media.MediaType = "image/png"; + } + else if (value == "IMG-JPG") + { + targetparcel.Media.MediaType = "image/jpeg"; + } + else if (value == "VID-MP4") + { + targetparcel.Media.MediaType = "video/mp4"; + } + else if (value == "VID-AVI") + { + targetparcel.Media.MediaType = "video/x-msvideo"; + } + else if (value.StartsWith("Custom-") == true) + { + string mime = value; + mime = mime.Replace("Custom-", ""); + targetparcel.Media.MediaType = mime; + } + else + { + return false; + } + return true; + } + } +} diff --git a/BetterSecondbot/HttpService/Self.cs b/Core/HttpService/Self.cs similarity index 55% rename from BetterSecondbot/HttpService/Self.cs rename to Core/HttpService/Self.cs index f08016f..b55cb6e 100644 --- a/BetterSecondbot/HttpService/Self.cs +++ b/Core/HttpService/Self.cs @@ -9,12 +9,13 @@ using System.Text; using OpenMetaverse; using Newtonsoft.Json; using BetterSecondBotShared.Static; +using System.Linq; namespace BetterSecondBot.HttpService { - public class Http_Self : WebApiControllerWithTokens + public class HTTP_Self : WebApiControllerWithTokens { - public Http_Self(SecondBot mainbot, TokenStorage setuptokens) : base(mainbot, setuptokens) { } + public HTTP_Self(SecondBot mainbot, TokenStorage setuptokens) : base(mainbot, setuptokens) { } [About("Makes the bot turn to face avatar and point at them (if found)")] [ReturnHints("ok")] @@ -109,7 +110,7 @@ namespace BetterSecondBot.HttpService return BasicReply(found_object.ToString()); } - [About("Makes the bot sit on the ground or on a object if it can see it")] + [About("Makes the bot kill itself you monster")] [ReturnHints("ok")] [Route(HttpVerbs.Get, "/Logoff/{token}")] public object Logoff(string token) @@ -126,6 +127,97 @@ namespace BetterSecondBot.HttpService return BasicReply("ok"); } + [About("Makes the bot kill itself you monster")] + [ReturnHints("ok")] + [Route(HttpVerbs.Get, "/Logout/{token}")] + public object Logout(string token) + { + if (tokens.Allow(token, "self", "Logout", getClientIP()) == false) + { + return Failure("Token not accepted"); + } + if (bot.KillMe == false) + { + bot.GetClient.Self.Chat("Laters im out", 0, ChatType.Normal); + bot.KillMePlease(); + } + return BasicReply("ok"); + } + + [About("Makes the bot kill itself you monster - without making a sound")] + [ReturnHints("ok")] + [Route(HttpVerbs.Get, "/Bye/{token}")] + public object Bye(string token) + { + if (tokens.Allow(token, "self", "Bye", getClientIP()) == false) + { + return Failure("Token not accepted"); + } + if (bot.KillMe == false) + { + bot.KillMePlease(); + } + return BasicReply("ok"); + } + + [About("Gets the last 5 commands issued to the bot")] + [ReturnHints("list of commands")] + [Route(HttpVerbs.Get, "/GetLastCommands/{token}")] + public object GetLastCommands(string token) + { + if (tokens.Allow(token, "self", "GetLastCommands", getClientIP()) == false) + { + return Failure("Token not accepted"); + } + return bot.GetLastCommands(5); + } + + [About("Gets the last 5 commands issued to the bot")] + [ReturnHints("avatar lookup")] + [ReturnHints("Invaild state")] + [ReturnHints("Invaild sticky")] + [ReturnHints("Invaild flag")] + [ArgHints("avatar", "URLARG", "avatar uuid or Firstname Lastname")] + [ArgHints("flag", "URLARG", "friend, group, animation, teleport or command")] + [ArgHints("state", "URLARG", "State to set the flag to true or false")] + [ArgHints("sticky", "URLARG", "if true the permissing will not expire after the first use otherwise false")] + [Route(HttpVerbs.Get, "/SetPermFlag/{avatar}/{flag}/{state}/{sticky}/{token}")] + public object SetPermFlag(string avatar, string flag, string state, string sticky, string token) + { + if (tokens.Allow(token, "self", "SetPermFlag", getClientIP()) == false) + { + return Failure("Token not accepted"); + } + ProcessAvatar(avatar); + if (avataruuid == UUID.Zero) + { + return Failure("avatar lookup"); + } + bool stateflag = false; + bool stickyflag = false; + if(bool.TryParse(state,out stateflag) == false) + { + return Failure("Invaild state"); + } + if (bool.TryParse(sticky, out stickyflag) == false) + { + return Failure("Invaild sticky"); + } + string[] AcceptedFlags = new string[] { "friend", "group", "animation", "teleport", "command" }; + if (AcceptedFlags.Contains(flag) == true) + { + return Failure("Invaild flag"); + } + if (stateflag == true) + { + bot.Add_action_from(flag, avataruuid, stickyflag); + return BasicReply("Added perm: " + flag + " Sticky: " + stickyflag.ToString()); + } + bot.Remove_action_from(flag, avataruuid, stickyflag); + return BasicReply("Removed perm: " + flag + " Sticky: " + stickyflag.ToString()); + } + + } } diff --git a/Core/HttpService/StreamAdmin.cs b/Core/HttpService/StreamAdmin.cs new file mode 100644 index 0000000..cb1ab9f --- /dev/null +++ b/Core/HttpService/StreamAdmin.cs @@ -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 System.Reflection; +using BetterSecondBotShared.Static; +using RestSharp; + +namespace BetterSecondBot.HttpService +{ + public class HTTP_StreamAdmin : WebApiControllerWithTokens + { + public HTTP_StreamAdmin(SecondBot mainbot, TokenStorage setuptokens) : base(mainbot, setuptokens) { } + + [About("an improved version of near me with extra details
NearMeDetails is a object formated as follows
  • id
  • name
  • x
  • y
  • z
  • range
")] + [ReturnHints("True|False")] + [ReturnHints("Bad reply: ...")] + [ReturnHints("Endpoint is empty")] + [ReturnHints("Endpointcode is empty")] + [ReturnHints("HTTP status code: ...")] + [ReturnHints("Error: ...")] + [ReturnHints("Notecard title is to short")] + [ArgHints("endpoint","Text","The end point")] + [ArgHints("endpointcode", "Text", "The end point code")] + [Route(HttpVerbs.Post, "/FetchNextNotecard/{token}")] + public object FetchNextNotecard([FormField] string endpoint, [FormField] string endpointcode, string token) + { + if (tokens.Allow(token, "avatars", "FetchNextNotecard", getClientIP()) == false) + { + return Failure("Token not accepted"); + } + if(helpers.notempty(endpoint) == false) + { + return Failure("Endpoint is empty"); + } + if (helpers.notempty(endpointcode) == false) + { + return Failure("Endpointcode is empty"); + } + + string attempt_endpoint = endpoint + "endpoint.php"; + token = helpers.GetSHA1(helpers.UnixTimeNow().ToString() + "notecardnext" + endpointcode); + var client = new RestClient(attempt_endpoint); + var request = new RestRequest("notecard/next", Method.POST); + request.AddParameter("token", token); + request.AddHeader("content-type", "application/x-www-form-urlencoded"); + IRestResponse endpoint_checks = client.Post(request); + if (endpoint_checks.StatusCode != System.Net.HttpStatusCode.OK) + { + return Failure("HTTP status code: " + endpoint_checks.StatusCode.ToString()); + } + try + { + notecardendpoint server_reply = JsonConvert.DeserializeObject(endpoint_checks.Content); + if (server_reply.status == false) + { + return Failure("Bad reply: " + server_reply.message); + } + if (server_reply.NotecardTitle.Length < 3) + { + return Failure("Notecard title is to short"); + } + return BasicReply(bot.SendNotecard(server_reply.NotecardTitle, server_reply.NotecardContent, (UUID)server_reply.AvatarUUID).ToString()); + } + catch (Exception e) + { + return Failure("Error: " + e.Message + ""); + } + } + + public class notecardendpoint : endpoint + { + public string AvatarUUID { get; set; } + public string NotecardTitle { get; set; } + public string NotecardContent { get; set; } + } + + public class endpoint + { + public bool status { get; set; } + public string message { get; set; } + } + } +} diff --git a/Shared/Staic/Helpers.cs b/Shared/Staic/Helpers.cs index 45e9f82..b5682b0 100644 --- a/Shared/Staic/Helpers.cs +++ b/Shared/Staic/Helpers.cs @@ -184,6 +184,17 @@ namespace BetterSecondBotShared.Static } return false; } + } + + public static string create_dirty_table(Dictionary entrys) + { + List items = new List(); + foreach(KeyValuePair e in entrys) + { + items.Add(e.Key); + items.Add(e.Value); + } + return create_dirty_table(items.ToArray(), 2); } public static string create_dirty_table(string[] items) {