From d5853dd4de386bbb98425396588661041dde1b24 Mon Sep 17 00:00:00 2001 From: Madpeter <57852827+Madpeterz@users.noreply.github.com> Date: Sat, 13 Nov 2021 13:41:50 +0000 Subject: [PATCH] Multiple improvements Merged IM and Chat command groups. Changed return hints for failures to ReturnHintsFailure so the wiki make can mark errors. Added missing arg hints for Notecard commands. Added new NotecardDirectSend command for speed runners. Improved About info for GroupAddRole command. Corrected About info for GroupInvite command. GoHome command moved to self workgroup. --- BetterSecondBot.sln | 94 +++++++++++- BetterSecondbot/BetterSecondbot.csproj | 2 +- BetterSecondbot/OnEvents/onevent.cs | 123 +++++---------- BetterSecondbot/WikiMake/wikimake.cs | 43 +++++- Core/Commands/Animation.cs | 4 +- Core/Commands/Avatars.cs | 4 +- Core/Commands/Chat.cs | 79 +++++++++- Core/Commands/Core.cs | 11 +- Core/Commands/Dialogs.cs | 18 +-- Core/Commands/Discord.cs | 29 ++-- Core/Commands/Estate.cs | 22 +-- Core/Commands/Friends.cs | 14 +- Core/Commands/Funds.cs | 21 ++- Core/Commands/Group.cs | 122 ++++++++------- Core/Commands/Home.cs | 33 ---- Core/Commands/Im.cs | 89 ----------- Core/Commands/Info.cs | 8 +- Core/Commands/Inventory.cs | 39 +++++ Core/Commands/Movement.cs | 24 +-- Core/Commands/Notecard.cs | 63 ++++++-- Core/Commands/Parcel.cs | 112 +++++++------- Core/Commands/Self.cs | 60 ++++++-- Core/Commands/StreamAdmin.cs | 12 +- Core/Core.csproj | 8 +- Core/HttpService/HttpAsService.cs | 12 +- Core/Static/http_commands_helper.cs | 2 - .../Assets/AssetTypes/AssetSound.cs | 145 +++++++++++++++++- LibreMetaverse/InventoryManager.cs | 4 +- LibreMetaverse/LibreMetaverse.csproj | 1 + LibreMetaverse/Settings.cs | 2 +- Shared/Shared.csproj | 2 +- Shared/{Staic => Static}/Helpers.cs | 12 +- Shared/{Staic => Static}/LogFormater.cs | 0 33 files changed, 735 insertions(+), 479 deletions(-) delete mode 100644 Core/Commands/Home.cs delete mode 100644 Core/Commands/Im.cs rename Shared/{Staic => Static}/Helpers.cs (99%) rename Shared/{Staic => Static}/LogFormater.cs (100%) diff --git a/BetterSecondBot.sln b/BetterSecondBot.sln index 4d4edb7..77f0c86 100644 --- a/BetterSecondBot.sln +++ b/BetterSecondBot.sln @@ -22,54 +22,132 @@ EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BetterSecondbot", "BetterSecondbot\BetterSecondbot.csproj", "{452CA177-FFD1-4248-93C0-09AFF1060E34}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LibreMetaverse.Types", "LibreMetaverseTypes\LibreMetaverse.Types.csproj", "{B37B02AD-0000-0000-0000-000000000000}" -EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LibreMetaverse.StructuredData", "LibreMetaverse.StructuredData\LibreMetaverse.StructuredData.csproj", "{89D7A3E5-0000-0000-0000-000000000000}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LibreMetaverse", "LibreMetaverse\LibreMetaverse.csproj", "{27C70F3A-0000-0000-0000-000000000000}" EndProject +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 DockerBuild|Any CPU = DockerBuild|Any CPU + DockerBuild|x64 = DockerBuild|x64 + DockerBuild|x86 = DockerBuild|x86 Release|Any CPU = Release|Any CPU + Release|x64 = Release|x64 + Release|x86 = Release|x86 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {554DA151-71C4-4C1D-97D5-F89F13D31299}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {554DA151-71C4-4C1D-97D5-F89F13D31299}.Debug|Any CPU.Build.0 = Debug|Any CPU + {554DA151-71C4-4C1D-97D5-F89F13D31299}.Debug|x64.ActiveCfg = Debug|Any CPU + {554DA151-71C4-4C1D-97D5-F89F13D31299}.Debug|x64.Build.0 = Debug|Any CPU + {554DA151-71C4-4C1D-97D5-F89F13D31299}.Debug|x86.ActiveCfg = Debug|Any CPU + {554DA151-71C4-4C1D-97D5-F89F13D31299}.Debug|x86.Build.0 = Debug|Any CPU {554DA151-71C4-4C1D-97D5-F89F13D31299}.DockerBuild|Any CPU.ActiveCfg = Debug|Any CPU {554DA151-71C4-4C1D-97D5-F89F13D31299}.DockerBuild|Any CPU.Build.0 = Debug|Any CPU + {554DA151-71C4-4C1D-97D5-F89F13D31299}.DockerBuild|x64.ActiveCfg = Debug|Any CPU + {554DA151-71C4-4C1D-97D5-F89F13D31299}.DockerBuild|x64.Build.0 = Debug|Any CPU + {554DA151-71C4-4C1D-97D5-F89F13D31299}.DockerBuild|x86.ActiveCfg = Debug|Any CPU + {554DA151-71C4-4C1D-97D5-F89F13D31299}.DockerBuild|x86.Build.0 = Debug|Any CPU {554DA151-71C4-4C1D-97D5-F89F13D31299}.Release|Any CPU.ActiveCfg = Release|Any CPU {554DA151-71C4-4C1D-97D5-F89F13D31299}.Release|Any CPU.Build.0 = Release|Any CPU + {554DA151-71C4-4C1D-97D5-F89F13D31299}.Release|x64.ActiveCfg = Release|Any CPU + {554DA151-71C4-4C1D-97D5-F89F13D31299}.Release|x64.Build.0 = Release|Any CPU + {554DA151-71C4-4C1D-97D5-F89F13D31299}.Release|x86.ActiveCfg = Release|Any CPU + {554DA151-71C4-4C1D-97D5-F89F13D31299}.Release|x86.Build.0 = Release|Any CPU {BED23EA8-0E8F-4B4C-BFA4-74DFDFD05859}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {BED23EA8-0E8F-4B4C-BFA4-74DFDFD05859}.Debug|Any CPU.Build.0 = Debug|Any CPU + {BED23EA8-0E8F-4B4C-BFA4-74DFDFD05859}.Debug|x64.ActiveCfg = Debug|Any CPU + {BED23EA8-0E8F-4B4C-BFA4-74DFDFD05859}.Debug|x64.Build.0 = Debug|Any CPU + {BED23EA8-0E8F-4B4C-BFA4-74DFDFD05859}.Debug|x86.ActiveCfg = Debug|Any CPU + {BED23EA8-0E8F-4B4C-BFA4-74DFDFD05859}.Debug|x86.Build.0 = Debug|Any CPU {BED23EA8-0E8F-4B4C-BFA4-74DFDFD05859}.DockerBuild|Any CPU.ActiveCfg = Debug|Any CPU {BED23EA8-0E8F-4B4C-BFA4-74DFDFD05859}.DockerBuild|Any CPU.Build.0 = Debug|Any CPU + {BED23EA8-0E8F-4B4C-BFA4-74DFDFD05859}.DockerBuild|x64.ActiveCfg = Debug|Any CPU + {BED23EA8-0E8F-4B4C-BFA4-74DFDFD05859}.DockerBuild|x64.Build.0 = Debug|Any CPU + {BED23EA8-0E8F-4B4C-BFA4-74DFDFD05859}.DockerBuild|x86.ActiveCfg = Debug|Any CPU + {BED23EA8-0E8F-4B4C-BFA4-74DFDFD05859}.DockerBuild|x86.Build.0 = Debug|Any CPU {BED23EA8-0E8F-4B4C-BFA4-74DFDFD05859}.Release|Any CPU.ActiveCfg = Release|Any CPU {BED23EA8-0E8F-4B4C-BFA4-74DFDFD05859}.Release|Any CPU.Build.0 = Release|Any CPU + {BED23EA8-0E8F-4B4C-BFA4-74DFDFD05859}.Release|x64.ActiveCfg = Release|Any CPU + {BED23EA8-0E8F-4B4C-BFA4-74DFDFD05859}.Release|x64.Build.0 = Release|Any CPU + {BED23EA8-0E8F-4B4C-BFA4-74DFDFD05859}.Release|x86.ActiveCfg = Release|Any CPU + {BED23EA8-0E8F-4B4C-BFA4-74DFDFD05859}.Release|x86.Build.0 = Release|Any CPU {452CA177-FFD1-4248-93C0-09AFF1060E34}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {452CA177-FFD1-4248-93C0-09AFF1060E34}.Debug|Any CPU.Build.0 = Debug|Any CPU + {452CA177-FFD1-4248-93C0-09AFF1060E34}.Debug|x64.ActiveCfg = Debug|Any CPU + {452CA177-FFD1-4248-93C0-09AFF1060E34}.Debug|x64.Build.0 = Debug|Any CPU + {452CA177-FFD1-4248-93C0-09AFF1060E34}.Debug|x86.ActiveCfg = Debug|Any CPU + {452CA177-FFD1-4248-93C0-09AFF1060E34}.Debug|x86.Build.0 = Debug|Any CPU {452CA177-FFD1-4248-93C0-09AFF1060E34}.DockerBuild|Any CPU.ActiveCfg = Debug|Any CPU {452CA177-FFD1-4248-93C0-09AFF1060E34}.DockerBuild|Any CPU.Build.0 = Debug|Any CPU + {452CA177-FFD1-4248-93C0-09AFF1060E34}.DockerBuild|x64.ActiveCfg = Debug|Any CPU + {452CA177-FFD1-4248-93C0-09AFF1060E34}.DockerBuild|x64.Build.0 = Debug|Any CPU + {452CA177-FFD1-4248-93C0-09AFF1060E34}.DockerBuild|x86.ActiveCfg = Debug|Any CPU + {452CA177-FFD1-4248-93C0-09AFF1060E34}.DockerBuild|x86.Build.0 = Debug|Any CPU {452CA177-FFD1-4248-93C0-09AFF1060E34}.Release|Any CPU.ActiveCfg = Release|Any CPU {452CA177-FFD1-4248-93C0-09AFF1060E34}.Release|Any CPU.Build.0 = Release|Any CPU - {B37B02AD-0000-0000-0000-000000000000}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {B37B02AD-0000-0000-0000-000000000000}.Debug|Any CPU.Build.0 = Debug|Any CPU - {B37B02AD-0000-0000-0000-000000000000}.DockerBuild|Any CPU.ActiveCfg = DockerBuild|Any CPU - {B37B02AD-0000-0000-0000-000000000000}.DockerBuild|Any CPU.Build.0 = DockerBuild|Any CPU - {B37B02AD-0000-0000-0000-000000000000}.Release|Any CPU.ActiveCfg = Release|Any CPU - {B37B02AD-0000-0000-0000-000000000000}.Release|Any CPU.Build.0 = Release|Any CPU + {452CA177-FFD1-4248-93C0-09AFF1060E34}.Release|x64.ActiveCfg = Release|Any CPU + {452CA177-FFD1-4248-93C0-09AFF1060E34}.Release|x64.Build.0 = Release|Any CPU + {452CA177-FFD1-4248-93C0-09AFF1060E34}.Release|x86.ActiveCfg = Release|Any CPU + {452CA177-FFD1-4248-93C0-09AFF1060E34}.Release|x86.Build.0 = Release|Any CPU {89D7A3E5-0000-0000-0000-000000000000}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {89D7A3E5-0000-0000-0000-000000000000}.Debug|Any CPU.Build.0 = Debug|Any CPU + {89D7A3E5-0000-0000-0000-000000000000}.Debug|x64.ActiveCfg = Debug|x64 + {89D7A3E5-0000-0000-0000-000000000000}.Debug|x64.Build.0 = Debug|x64 + {89D7A3E5-0000-0000-0000-000000000000}.Debug|x86.ActiveCfg = Debug|x86 + {89D7A3E5-0000-0000-0000-000000000000}.Debug|x86.Build.0 = Debug|x86 {89D7A3E5-0000-0000-0000-000000000000}.DockerBuild|Any CPU.ActiveCfg = DockerBuild|Any CPU {89D7A3E5-0000-0000-0000-000000000000}.DockerBuild|Any CPU.Build.0 = DockerBuild|Any CPU + {89D7A3E5-0000-0000-0000-000000000000}.DockerBuild|x64.ActiveCfg = DockerBuild|Any CPU + {89D7A3E5-0000-0000-0000-000000000000}.DockerBuild|x64.Build.0 = DockerBuild|Any CPU + {89D7A3E5-0000-0000-0000-000000000000}.DockerBuild|x86.ActiveCfg = DockerBuild|Any CPU + {89D7A3E5-0000-0000-0000-000000000000}.DockerBuild|x86.Build.0 = DockerBuild|Any CPU {89D7A3E5-0000-0000-0000-000000000000}.Release|Any CPU.ActiveCfg = Release|Any CPU {89D7A3E5-0000-0000-0000-000000000000}.Release|Any CPU.Build.0 = Release|Any CPU + {89D7A3E5-0000-0000-0000-000000000000}.Release|x64.ActiveCfg = Release|x64 + {89D7A3E5-0000-0000-0000-000000000000}.Release|x64.Build.0 = Release|x64 + {89D7A3E5-0000-0000-0000-000000000000}.Release|x86.ActiveCfg = Release|x86 + {89D7A3E5-0000-0000-0000-000000000000}.Release|x86.Build.0 = Release|x86 {27C70F3A-0000-0000-0000-000000000000}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {27C70F3A-0000-0000-0000-000000000000}.Debug|Any CPU.Build.0 = Debug|Any CPU + {27C70F3A-0000-0000-0000-000000000000}.Debug|x64.ActiveCfg = Debug|x64 + {27C70F3A-0000-0000-0000-000000000000}.Debug|x64.Build.0 = Debug|x64 + {27C70F3A-0000-0000-0000-000000000000}.Debug|x86.ActiveCfg = Debug|x86 + {27C70F3A-0000-0000-0000-000000000000}.Debug|x86.Build.0 = Debug|x86 {27C70F3A-0000-0000-0000-000000000000}.DockerBuild|Any CPU.ActiveCfg = DockerBuild|Any CPU {27C70F3A-0000-0000-0000-000000000000}.DockerBuild|Any CPU.Build.0 = DockerBuild|Any CPU + {27C70F3A-0000-0000-0000-000000000000}.DockerBuild|x64.ActiveCfg = DockerBuild|Any CPU + {27C70F3A-0000-0000-0000-000000000000}.DockerBuild|x64.Build.0 = DockerBuild|Any CPU + {27C70F3A-0000-0000-0000-000000000000}.DockerBuild|x86.ActiveCfg = DockerBuild|Any CPU + {27C70F3A-0000-0000-0000-000000000000}.DockerBuild|x86.Build.0 = DockerBuild|Any CPU {27C70F3A-0000-0000-0000-000000000000}.Release|Any CPU.ActiveCfg = Release|Any CPU {27C70F3A-0000-0000-0000-000000000000}.Release|Any CPU.Build.0 = Release|Any CPU + {27C70F3A-0000-0000-0000-000000000000}.Release|x64.ActiveCfg = Release|x64 + {27C70F3A-0000-0000-0000-000000000000}.Release|x64.Build.0 = Release|x64 + {27C70F3A-0000-0000-0000-000000000000}.Release|x86.ActiveCfg = Release|x86 + {27C70F3A-0000-0000-0000-000000000000}.Release|x86.Build.0 = Release|x86 + {B37B02AD-0000-0000-0000-000000000000}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {B37B02AD-0000-0000-0000-000000000000}.Debug|Any CPU.Build.0 = Debug|Any CPU + {B37B02AD-0000-0000-0000-000000000000}.Debug|x64.ActiveCfg = Debug|x64 + {B37B02AD-0000-0000-0000-000000000000}.Debug|x64.Build.0 = Debug|x64 + {B37B02AD-0000-0000-0000-000000000000}.Debug|x86.ActiveCfg = Debug|x86 + {B37B02AD-0000-0000-0000-000000000000}.Debug|x86.Build.0 = Debug|x86 + {B37B02AD-0000-0000-0000-000000000000}.DockerBuild|Any CPU.ActiveCfg = Debug|Any CPU + {B37B02AD-0000-0000-0000-000000000000}.DockerBuild|Any CPU.Build.0 = Debug|Any CPU + {B37B02AD-0000-0000-0000-000000000000}.DockerBuild|x64.ActiveCfg = Debug|x64 + {B37B02AD-0000-0000-0000-000000000000}.DockerBuild|x64.Build.0 = Debug|x64 + {B37B02AD-0000-0000-0000-000000000000}.DockerBuild|x86.ActiveCfg = Debug|x86 + {B37B02AD-0000-0000-0000-000000000000}.DockerBuild|x86.Build.0 = Debug|x86 + {B37B02AD-0000-0000-0000-000000000000}.Release|Any CPU.ActiveCfg = Release|Any CPU + {B37B02AD-0000-0000-0000-000000000000}.Release|Any CPU.Build.0 = Release|Any CPU + {B37B02AD-0000-0000-0000-000000000000}.Release|x64.ActiveCfg = Release|x64 + {B37B02AD-0000-0000-0000-000000000000}.Release|x64.Build.0 = Release|x64 + {B37B02AD-0000-0000-0000-000000000000}.Release|x86.ActiveCfg = Release|x86 + {B37B02AD-0000-0000-0000-000000000000}.Release|x86.Build.0 = Release|x86 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -78,9 +156,9 @@ Global {554DA151-71C4-4C1D-97D5-F89F13D31299} = {4388BA41-F3FC-4A0E-AA00-50E9ED45A027} {BED23EA8-0E8F-4B4C-BFA4-74DFDFD05859} = {4388BA41-F3FC-4A0E-AA00-50E9ED45A027} {452CA177-FFD1-4248-93C0-09AFF1060E34} = {4388BA41-F3FC-4A0E-AA00-50E9ED45A027} - {B37B02AD-0000-0000-0000-000000000000} = {E9B97D05-D5FB-4CA9-99C3-839248621C21} {89D7A3E5-0000-0000-0000-000000000000} = {E9B97D05-D5FB-4CA9-99C3-839248621C21} {27C70F3A-0000-0000-0000-000000000000} = {E9B97D05-D5FB-4CA9-99C3-839248621C21} + {B37B02AD-0000-0000-0000-000000000000} = {E9B97D05-D5FB-4CA9-99C3-839248621C21} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {EC43F382-FAF2-49CC-8E23-5DDF87592DFA} diff --git a/BetterSecondbot/BetterSecondbot.csproj b/BetterSecondbot/BetterSecondbot.csproj index 8fe5491..fe558ec 100644 --- a/BetterSecondbot/BetterSecondbot.csproj +++ b/BetterSecondbot/BetterSecondbot.csproj @@ -26,7 +26,7 @@ - + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/BetterSecondbot/OnEvents/onevent.cs b/BetterSecondbot/OnEvents/onevent.cs index e61080e..70ff820 100644 --- a/BetterSecondbot/OnEvents/onevent.cs +++ b/BetterSecondbot/OnEvents/onevent.cs @@ -519,6 +519,7 @@ namespace BetterSecondbot.OnEvents public onevent(Cli master, bool LoadFromDocker) { controler = master; + LogFormater.Info("{onEvents} starting", true); if (LoadFromDocker == true) { loadFromDockerEnv(); @@ -528,58 +529,8 @@ namespace BetterSecondbot.OnEvents loadFromDisk(); } controler.getBot().StatusMessageEvent += statusMessage; -#if DEBUG - testCron(); -#endif + LogFormater.Info("{onEvents} ready", true); - } - - protected void testCron() - { - string[] crontests = new string[] - { - "* * * * *", - "* * * * "+dayOfWeek(DateTime.Now.DayOfWeek).ToString(), - "* * * "+DateTime.Now.Month.ToString()+" *", - "* * "+DateTime.Now.Day.ToString()+" * *", - "* "+DateTime.Now.Hour.ToString()+" * * *", - ""+DateTime.Now.Minute.ToString()+" * * * *", - "* * * * /"+dayOfWeek(DateTime.Now.DayOfWeek).ToString(), - "* * * /"+DateTime.Now.Month.ToString()+" *", - "* * /"+DateTime.Now.Day.ToString()+" * *", - "* /"+DateTime.Now.Hour.ToString()+" * * *", - "/"+DateTime.Now.Minute.ToString()+" * * * *", - "61 25 77 44 8", - "E O E O E", - }; - bool[] expected = new bool[] - { - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - false, - false, - }; - int loop = 1; - foreach(string a in crontests) - { - bool result = cronMagic(a, "true"); - if (result != expected[loop - 1]) - { - LogFormater.Info("failed test \"" + a + "\" " + loop.ToString() + " " + result.ToString(), true); - } - loop++; - } - - } protected void SetupMonitor() @@ -685,42 +636,48 @@ namespace BetterSecondbot.OnEvents protected void loadFromDisk() { LogFormater.Info("Loading onEvents from Disk", true); - OnEventBlob DemoloadedEvents = new OnEventBlob(); - OnEvent demoEvent = new OnEvent(); - demoEvent.Enabled = false; - demoEvent.Actions = new string[] { "Say|||0~#~hi mom im on TV!"}; - demoEvent.title = "demo"; - demoEvent.On = "Clock"; - demoEvent.Where = new string[] { "59 23 * * 7 {CRON} true"}; - demoEvent.Monitor = "None"; - DemoloadedEvents.listEvents = new OnEvent[] { demoEvent }; + try + { + OnEventBlob DemoloadedEvents = new OnEventBlob(); + OnEvent demoEvent = new OnEvent(); + demoEvent.Enabled = false; + demoEvent.Actions = new string[] { "Say|||0~#~hi mom im on TV!" }; + demoEvent.title = "demo"; + demoEvent.On = "Clock"; + demoEvent.Where = new string[] { "59 23 * * 7 {CRON} true" }; + demoEvent.Monitor = "None"; + DemoloadedEvents.listEvents = new OnEvent[] { demoEvent }; - string targetfile = "events.json"; - SimpleIO io = new SimpleIO(); - io.ChangeRoot(controler.getFolderUsed()); - if (io.Exists(targetfile) == false) - { - LogFormater.Status("Creating new events file", true); - io.WriteJsonEvents(DemoloadedEvents, targetfile); - return; - } - string json = io.ReadFile(targetfile); - if (json.Length > 0) - { - try + string targetfile = "events.json"; + SimpleIO io = new SimpleIO(); + io.ChangeRoot(controler.getFolderUsed()); + if (io.Exists(targetfile) == false) { - OnEventBlob loadedEvents = JsonConvert.DeserializeObject(json); - foreach (OnEvent loaded in loadedEvents.listEvents) - { - Events.Add(loaded); - } - } - catch - { - io.MarkOld(targetfile); + LogFormater.Status("Creating new events file", true); io.WriteJsonEvents(DemoloadedEvents, targetfile); + return; } - return; + string json = io.ReadFile(targetfile); + if (json.Length > 0) + { + try + { + OnEventBlob loadedEvents = JsonConvert.DeserializeObject(json); + foreach (OnEvent loaded in loadedEvents.listEvents) + { + Events.Add(loaded); + } + } + catch + { + LogFormater.Info("error loading events from "+targetfile+" skipping", true); + } + return; + } + } + catch + { + } } diff --git a/BetterSecondbot/WikiMake/wikimake.cs b/BetterSecondbot/WikiMake/wikimake.cs index f6b5609..75a5ad7 100644 --- a/BetterSecondbot/WikiMake/wikimake.cs +++ b/BetterSecondbot/WikiMake/wikimake.cs @@ -391,13 +391,18 @@ namespace BetterSecondBot.WikiMake } string[] returnvalues = HTTP.getReturnsValues(workspace, c); - if (returnvalues.Length > 0) + string[] returnvaluesfailure = HTTP.getReturnsFailureValues(workspace, c); + if ((returnvalues.Length > 0) || (returnvaluesfailure.Length > 0)) { - sb.Append("

Possible replys

"); - sb.Append("
    "); + sb.Append("

    Replys

    "); + sb.Append("
      "); foreach (string entry in returnvalues) { - sb.Append("
    • "+entry+"
    • "); + sb.Append("
    • ☑ " + entry+"
    • "); + } + foreach (string entry in returnvaluesfailure) + { + sb.Append("
    • ❌ " + entry + "
    • "); } sb.Append("
    "); } @@ -512,6 +517,7 @@ namespace BetterSecondBot.WikiMake CustomAttributeData About = null; List ArgHints = new List(); List ReturnValues = new List(); + List ReturnValuesFailures = new List(); foreach (CustomAttributeData At in M.CustomAttributes) { @@ -535,6 +541,10 @@ namespace BetterSecondBot.WikiMake { ReturnValues.Add(At); } + else if (At.AttributeType.Name == "ReturnHintsFailure") + { + ReturnValuesFailures.Add(At); + } } if (httpverb != null) { @@ -562,6 +572,10 @@ namespace BetterSecondBot.WikiMake { C.returns.Add(cad.ConstructorArguments[0].Value.ToString()); } + foreach (CustomAttributeData cad in ReturnValuesFailures) + { + C.returnsFailure.Add(cad.ConstructorArguments[0].Value.ToString()); + } C.Setup(); Endpoint.callable.Add(C); } @@ -631,7 +645,23 @@ namespace BetterSecondBot.WikiMake return new string[] { }; } - + public string[] getReturnsFailureValues(string endpoint, string command) + { + foreach (Endpoint End in endpoints) + { + if (End.name == endpoint) + { + foreach (APIcall api in End.callable) + { + if (api.name == command) + { + return api.returnsFailure.ToArray(); + } + } + } + } + return new string[] { }; + } public int getCommandArgCount(string endpoint, string command) { @@ -734,13 +764,14 @@ namespace BetterSecondBot.WikiMake public string about = "A API call that is missing its about value"; public Dictionary> values = new Dictionary>(); public List returns = new List(); + public List returnsFailure = new List(); public bool RequiresToken = true; public virtual void Setup() { if (RequiresToken == true) { - returns.Add("Token not accepted"); + returnsFailure.Add("Token not accepted"); values.Add( "token", new KeyValuePair( diff --git a/Core/Commands/Animation.cs b/Core/Commands/Animation.cs index 2dba806..25aff77 100644 --- a/Core/Commands/Animation.cs +++ b/Core/Commands/Animation.cs @@ -19,7 +19,7 @@ namespace BetterSecondBot.HttpService [About("Toggles if animation requests from this avatar (used for remote poseballs) are accepted")] [ReturnHints("Granted perm animation")] [ReturnHints("Removed perm animation")] - [ReturnHints("avatar lookup")] + [ReturnHintsFailure("avatar lookup")] [ArgHints("avatar", "URLARG", "UUID (or Firstname Lastname)")] [Route(HttpVerbs.Get, "/AddToAllowAnimations/{avatar}/{token}")] public object AddToAllowAnimations(string avatar, string token) @@ -43,7 +43,7 @@ namespace BetterSecondBot.HttpService } [About("Attempts to play a gesture")] - [ReturnHints("Error with gesture")] + [ReturnHintsFailure("Error with gesture")] [ReturnHints("Accepted")] [ArgHints("gesture", "URLARG", "Inventory UUID of the gesture")] [Route(HttpVerbs.Get, "/PlayGesture/{gesture}/{token}")] diff --git a/Core/Commands/Avatars.cs b/Core/Commands/Avatars.cs index 7837d68..f21775b 100644 --- a/Core/Commands/Avatars.cs +++ b/Core/Commands/Avatars.cs @@ -18,7 +18,7 @@ namespace BetterSecondBot.HttpService [About("an improved version of near me with extra details
    NearMeDetails is a object formated as follows
    • id
    • name
    • x
    • y
    • z
    • range
    ")] [ReturnHints("array NearMeDetails")] - [ReturnHints("Error not in a sim")] + [ReturnHintsFailure("Error not in a sim")] [Route(HttpVerbs.Get, "/NearmeWithDetails/{token}")] public object NearmeWithDetails(string token) { @@ -51,7 +51,7 @@ namespace BetterSecondBot.HttpService [About("returns a list of all known avatars nearby")] [ReturnHints("array UUID = Name")] - [ReturnHints("Error not in a sim")] + [ReturnHintsFailure("Error not in a sim")] [Route(HttpVerbs.Get, "/Nearme/{token}")] public object Nearme(string token) { diff --git a/Core/Commands/Chat.cs b/Core/Commands/Chat.cs index 4b01085..6f62a4c 100644 --- a/Core/Commands/Chat.cs +++ b/Core/Commands/Chat.cs @@ -32,8 +32,8 @@ namespace BetterSecondBot.HttpService [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")] + [ReturnHintsFailure("Message empty")] + [ReturnHintsFailure("Invaild channel")] [Route(HttpVerbs.Post, "/Say/{channel}/{token}")] public object Say(string channel,[FormField] string message,string token) { @@ -66,8 +66,8 @@ namespace BetterSecondBot.HttpService [ArgHints("avatar", "URLARG", "a UUID or Firstname Lastname")] [ArgHints("message", "Text", "the message to send")] [ReturnHints("ok")] - [ReturnHints("Message empty")] - [ReturnHints("avatar lookup")] + [ReturnHintsFailure("Message empty")] + [ReturnHintsFailure("avatar lookup")] [Route(HttpVerbs.Post, "/IM/{avatar}/{token}")] public object IM(string avatar, [FormField] string message, string token) { @@ -88,6 +88,77 @@ namespace BetterSecondBot.HttpService return BasicReply("ok", "IM", new [] { avatar, message }); } + [About("gets a full list of all chat windows")] + [ReturnHints("array UUID = Name")] + [Route(HttpVerbs.Get, "/chatwindows/{token}")] + public object chatwindows(string token) + { + if (tokens.Allow(token, "chat", "chatwindows", handleGetClientIP()) == false) + { + return BasicReply("Token not accepted", "chatwindows"); + } + return BasicReply(JsonConvert.SerializeObject(bot.GetIMChatWindowKeyNames()), "chatwindows"); + } + + [About("gets a list of chat windows with unread messages")] + [ReturnHints("array of UUID")] + [Route(HttpVerbs.Get, "/listwithunread/{token}")] + public object listwithunread(string token) + { + if (tokens.Allow(token, "chat", "listwithunread", handleGetClientIP()) == false) + { + return BasicReply("Token not accepted", "listwithunread"); + } + List unreadimwindows = new List(); + foreach (UUID window in bot.IMChatWindows()) + { + if (bot.ImChatWindowHasUnread(window) == true) + { + unreadimwindows.Add(window); + } + } + return BasicReply(JsonConvert.SerializeObject(unreadimwindows), "listwithunread"); + } + + [About("gets if there are any unread im messages at all")] + [ReturnHints("True|False")] + [Route(HttpVerbs.Get, "/haveunreadims/{token}")] + public object haveunreadims(string token) + { + if (tokens.Allow(token, "chat", "haveunreadims", handleGetClientIP()) == false) + { + return BasicReply("Token not accepted", "haveunreadims"); + } + bool reply = false; + foreach (UUID window in bot.IMChatWindows()) + { + if (bot.ImChatWindowHasUnread(window) == true) + { + reply = true; + break; + } + } + return BasicReply(reply.ToString(), "haveunreadims"); + } + + [About("gets the chat from the selected window")] + [ArgHints("window", "URLARG", "the UUID of the chat window")] + [ReturnHintsFailure("Window UUID invaild")] + [ReturnHints("Array of text")] + [Route(HttpVerbs.Get, "/getimchat/{window}/{token}")] + public object getimchat(string window, string token) + { + if (tokens.Allow(token, "chat", "getimchat", handleGetClientIP()) == false) + { + return Failure("Token not accepted", "getimchat", new[] { window }); + } + if (UUID.TryParse(window, out UUID windowUUID) == false) + { + return Failure("Window UUID invaild", "getimchat", new[] { window }); + } + return BasicReply(JsonConvert.SerializeObject(bot.GetIMChatWindow(windowUUID)), "getimchat", new[] { window }); + } + } diff --git a/Core/Commands/Core.cs b/Core/Commands/Core.cs index 9762345..f0dd2a9 100644 --- a/Core/Commands/Core.cs +++ b/Core/Commands/Core.cs @@ -1,14 +1,9 @@ -using BetterSecondBotShared.Json; -using BetterSecondBotShared.Static; +using BetterSecondBotShared.Static; using BetterSecondBot.bottypes; -using OpenMetaverse; -using System.Threading.Tasks; using EmbedIO; using EmbedIO.Routing; using EmbedIO.WebApi; using System; -using System.Collections.Generic; -using Newtonsoft.Json; using System.Threading; namespace BetterSecondBot.HttpService @@ -20,6 +15,7 @@ namespace BetterSecondBot.HttpService [About("Requests a new token (Vaild for 10 mins)
    to use with all other requests")] [NeedsToken(false)] [ReturnHints("A new token with full system scope")] + [ReturnHintsFailure("Authcode not accepted")] [ArgHints("authcode", "text", "the first 10 chars of SHA1(unixtime+WebUIkey)
    unixtime can be +- 30 of the bots time.")] [ArgHints("unixtimegiven", "number", "the unixtime you made this request")] [Route(HttpVerbs.Post, "/GetToken")] @@ -55,7 +51,7 @@ namespace BetterSecondBot.HttpService } [About("Delays a thead by X ms
    Mostly pointless but good if your doing custom commands")] - [ReturnHints("Invaild amount")] + [ReturnHintsFailure("Invaild amount")] [ReturnHints("ok")] [Route(HttpVerbs.Get, "/Delay/{amount}/{token}")] public object Delay(string amount,string token) @@ -73,7 +69,6 @@ namespace BetterSecondBot.HttpService } [About("Removes the given token from the accepted token pool")] - [ReturnHints("Failed to remove token")] [ReturnHints("ok")] [Route(HttpVerbs.Get, "/LogoutUI/{token}")] public object LogoutUI(string token) diff --git a/Core/Commands/Dialogs.cs b/Core/Commands/Dialogs.cs index f2cd7a4..498cd11 100644 --- a/Core/Commands/Dialogs.cs +++ b/Core/Commands/Dialogs.cs @@ -18,10 +18,10 @@ namespace BetterSecondBot.HttpService [About("Updates the relay target (you can have 1 of each type)
    Clear will disable them all")] [ReturnHints("cleared")] - [ReturnHints("set/avatar")] - [ReturnHints("set/http")] - [ReturnHints("set/channel")] - [ReturnHints("Not a vaild option")] + [ReturnHints("set/avatar [ok]")] + [ReturnHints("set/http [ok]")] + [ReturnHints("set/channel [ok]")] + [ReturnHintsFailure("Not a vaild option")] [ArgHints("target","URLARG", "Options: Channel (Any number),Avatar UUID,HTTPurl
    Clear")] [Route(HttpVerbs.Get, "/DialogRelay/{target}/{token}")] public object DialogRelay(string target,string token) @@ -41,17 +41,17 @@ namespace BetterSecondBot.HttpService if (avataruuid != UUID.Zero) { bot.SetRelayDialogsAvatar(avataruuid); - return BasicReply("set/avatar", "DialogRelay", new [] { target }); + return BasicReply("set/avatar [ok]", "DialogRelay", new [] { target }); } if (target.StartsWith("http") == true) { bot.SetRelayDialogsHTTP(target); - return BasicReply("set/http", "DialogRelay", new [] { target }); + return BasicReply("set/http [ok]", "DialogRelay", new [] { target }); } if (int.TryParse(target, out int channel) == true) { bot.SetRelayDialogsChannel(channel); - return BasicReply("set/channel", "DialogRelay", new [] { target }); + return BasicReply("set/channel [ok]", "DialogRelay", new [] { target }); } return Failure("Not a vaild option", "DialogRelay", new [] { target }); @@ -60,7 +60,7 @@ namespace BetterSecondBot.HttpService [About("Makes the bot interact with the dialog [dialogid] with the button [buttontext]")] [ReturnHints("true")] [ReturnHints("false")] - [ReturnHints("bad dialog id")] + [ReturnHintsFailure("bad dialog id")] [ArgHints("dialogid", "URLARG", "The ID for the dialog")] [ArgHints("buttontext", "URLARG", "The button text to push")] [Route(HttpVerbs.Get, "/DialogResponce/{dialogid}/{buttontext}/{token}")] @@ -79,7 +79,7 @@ namespace BetterSecondBot.HttpService [About("Should the bot track dialogs and send them to the relays setup?")] [ReturnHints("updated")] - [ReturnHints("bad status")] + [ReturnHintsFailure("bad status")] [ArgHints("status", "URLARG", "true or false")] [Route(HttpVerbs.Get, "/DialogTrack/{status}/{token}")] public object DialogTrack(string status, string token) diff --git a/Core/Commands/Discord.cs b/Core/Commands/Discord.cs index 4f85b67..d430e8c 100644 --- a/Core/Commands/Discord.cs +++ b/Core/Commands/Discord.cs @@ -22,7 +22,7 @@ namespace BetterSecondBot.HttpService public HTTP_Discord(SecondBot mainbot, TokenStorage setuptokens) : base(mainbot, setuptokens) { } [About("Adds a discord server role to the selected member")] - [ReturnHints("Discord client not ready")] + [ReturnHintsFailure("Discord client not ready")] [ReturnHints("true|false")] [ArgHints("serverid","URLARG","the server id to apply this action to")] [ArgHints("roleid", "URLARG", "the role id we are giving")] @@ -42,8 +42,8 @@ namespace BetterSecondBot.HttpService } [About("Adds the selected user to the ban list - Disallows rejoining untill they are removed from the list")] - [ReturnHints("Discord client not ready")] - [ReturnHints("Why empty")] + [ReturnHintsFailure("Discord client not ready")] + [ReturnHintsFailure("Why empty")] [ReturnHints("true|false")] [ArgHints("serverid", "URLARG", "the server id to apply this action to")] [ArgHints("memberid", "URLARG", "who we are giving it to")] @@ -67,7 +67,7 @@ namespace BetterSecondBot.HttpService } [About("Clears messages on the server sent by the member in the last 13 days, 22hours 59mins")] - [ReturnHints("Discord client not ready")] + [ReturnHintsFailure("Discord client not ready")] [ReturnHints("true|false")] [ArgHints("serverid", "URLARG", "the server id to apply this action to")] [ArgHints("memberid", "URLARG", "who we are giving it to")] @@ -87,7 +87,7 @@ namespace BetterSecondBot.HttpService } [About("Sends a message directly to the user [They must be in the server]\n This command requires the SERVER MEMBERS INTENT found in discord app dev")] - [ReturnHints("Discord client not ready")] + [ReturnHintsFailure("Discord client not ready")] [ReturnHints("true|false")] [ArgHints("serverid", "URLARG", "the server id to apply this action to")] [ArgHints("memberid", "URLARG", "who we are giving it to")] @@ -109,7 +109,7 @@ namespace BetterSecondBot.HttpService [About("Returns a list of members in a server \n collection is userid: username \n if the user has set a nickname: userid: nickname|username \n" + " This command requires Discord full client mode enabled and connected\n !!!! This command also requires: Privileged Gateway Intents / " + "SERVER MEMBERS INTENT set to true on the discord bot api area !!!")] - [ReturnHints("Discord client not ready")] + [ReturnHintsFailure("Discord client not ready")] [ReturnHints("mixed array of userid: nickname|username or userid:username")] [ArgHints("serverid", "URLARG", "the server id to apply this action to")] [Route(HttpVerbs.Get, "/Discord_MembersList/{serverid}/{token}")] @@ -128,7 +128,8 @@ namespace BetterSecondBot.HttpService } [About("Sends a message to the selected channel - Optional TTS usage")] - [ReturnHints("Discord client not ready")] + [ReturnHintsFailure("Discord client not ready")] + [ReturnHintsFailure("message empty")] [ReturnHints("true|false")] [ArgHints("serverid", "URLARG", "the server id to apply this action to")] [ArgHints("channelid", "URLARG", "the channel id to apply this action to")] @@ -154,7 +155,7 @@ namespace BetterSecondBot.HttpService [About("Sends a message to the selected channel - Optional TTS usage")] [ReturnHints("mixed array of userid: nickname|username or userid:username")] - [ReturnHints("Discord client not ready")] + [ReturnHintsFailure("Discord client not ready")] [ArgHints("serverid", "URLARG", "the server id to apply this action to")] [ArgHints("memberid", "URLARG", "who we are giving it to")] [ArgHints("mode", "URLARG", "should we mute them \"true\" or unmute \"false\"")] @@ -174,7 +175,7 @@ namespace BetterSecondBot.HttpService [About("returns a collection of settings for the given role \n This command requires Discord full client mode enabled and connected")] [ReturnHints("KeyPair of status: KeyPair[] item = value")] - [ReturnHints("Discord client not ready")] + [ReturnHintsFailure("Discord client not ready")] [ArgHints("serverid", "URLARG", "the server id to apply this action to")] [ArgHints("memberid", "URLARG", "who we are giving it to")] [ArgHints("mode", "URLARG", "should we mute them \"true\" or unmute \"false\"")] @@ -196,7 +197,7 @@ namespace BetterSecondBot.HttpService [About("Updates perm flags for the selected role \n example CSV format: Speak=True,SendMessages=False \n for a full list of perms see output of Discord_Role_GetSettings \n" + " This command requires Discord full client mode enabled and connected")] [ReturnHints("true|false")] - [ReturnHints("Discord client not ready")] + [ReturnHintsFailure("Discord client not ready")] [ArgHints("serverid", "URLARG", "the server id to apply this action to")] [ArgHints("roleid", "URLARG", "who we are giving it to")] [ArgHints("flagscsv", "Text", "what we are setting")] @@ -217,7 +218,7 @@ namespace BetterSecondBot.HttpService [About("Updates perm flags for the selected role \n example CSV format: Speak=True,SendMessages=False \n for a full list of perms see output of Discord_Role_GetSettings \n" + " This command requires Discord full client mode enabled and connected")] [ReturnHints("KeyPair of statusmessage=roleid or 0")] - [ReturnHints("Discord client not ready")] + [ReturnHintsFailure("Discord client not ready")] [ArgHints("serverid", "URLARG", "the server id to apply this action to")] [ArgHints("role", "URLARG", "the name of the role we are creating")] [Route(HttpVerbs.Get, "/Discord_RoleCreate/{serverid}/{role}/{token}")] @@ -237,7 +238,7 @@ namespace BetterSecondBot.HttpService [About("Returns a list of roles and their ids in collection \n This command requires Discord full client mode enabled and connected")] [ReturnHints("KeyPair of status: KeyPair of roleid: rolename")] - [ReturnHints("Discord client not ready")] + [ReturnHintsFailure("Discord client not ready")] [ArgHints("serverid", "URLARG", "the server id to apply this action to")] [Route(HttpVerbs.Get, "/Discord_RoleList/{serverid}/{token}")] public object Discord_RoleList(string serverid, string token) @@ -255,7 +256,7 @@ namespace BetterSecondBot.HttpService [About("Remove a role from a server \n This command requires Discord full client mode enabled and connected")] [ReturnHints("true|false")] - [ReturnHints("Discord client not ready")] + [ReturnHintsFailure("Discord client not ready")] [ArgHints("serverid", "URLARG", "the server id to apply this action to")] [Route(HttpVerbs.Get, "/Discord_RoleRemove/{serverid}/{roleid}/{token}")] public object Discord_RoleRemove(string serverid, string roleid, string token) @@ -273,7 +274,7 @@ namespace BetterSecondBot.HttpService [About("Returns a list of text channels in a server")] [ReturnHints("array of channelid: name")] - [ReturnHints("Discord client not ready")] + [ReturnHintsFailure("Discord client not ready")] [ArgHints("serverid", "URLARG", "the server id to apply this action to")] [Route(HttpVerbs.Get, "/Discord_TextChannels_List/{serverid}/{roleid}/{token}")] public object Discord_TextChannels_List(string serverid, string token) diff --git a/Core/Commands/Estate.cs b/Core/Commands/Estate.cs index cf241df..37b2ee4 100644 --- a/Core/Commands/Estate.cs +++ b/Core/Commands/Estate.cs @@ -19,9 +19,9 @@ namespace BetterSecondBot.HttpService public HTTP_Estate(SecondBot mainbot, TokenStorage setuptokens) : base(mainbot, setuptokens) { } [About("Sends the message to the current sim")] - [ReturnHints("Not an estate manager here")] [ReturnHints("restarting")] - [ReturnHints("canceled")] + [ReturnHintsFailure("Not an estate manager here")] + [ReturnHintsFailure("canceled")] [ArgHints("delay", "URLARG", "How long to delay the restart for (30 to 240 secs) - defaults to 240 if out of bounds \n" + "set to 0 if your canceling!")] [ArgHints("mode", "URLARG", "true to start a restart, false to cancel")] @@ -53,8 +53,8 @@ namespace BetterSecondBot.HttpService } [About("Sends the message to the current sim")] - [ReturnHints("Not an estate manager here")] - [ReturnHints("Message empty")] + [ReturnHintsFailure("Not an estate manager here")] + [ReturnHintsFailure("Message empty")] [ReturnHints("ok")] [ArgHints("message", "Text", "What the message is")] [Route(HttpVerbs.Post, "/SimMessage/{token}")] @@ -77,7 +77,7 @@ namespace BetterSecondBot.HttpService } [About("Fetchs the regions map tile")] - [ReturnHints("Unable to find region")] + [ReturnHintsFailure("Unable to find region")] [ReturnHints("Texture UUID")] [ArgHints("regionname", "URLARG", "the name of the region we are fetching")] [Route(HttpVerbs.Get, "/GetSimTexture/{regionname}/{token}")] @@ -95,7 +95,7 @@ namespace BetterSecondBot.HttpService } [About("Reclaims ownership of the current parcel")] - [ReturnHints("Not an estate manager here")] + [ReturnHintsFailure("Not an estate manager here")] [ReturnHints("ok")] [Route(HttpVerbs.Get, "/EstateParcelReclaim/{token}")] public Object EstateParcelReclaim(string token) @@ -114,7 +114,7 @@ namespace BetterSecondBot.HttpService } [About("Reclaims ownership of the current parcel")] - [ReturnHints("Not an estate manager here")] + [ReturnHintsFailure("Not an estate manager here")] [ReturnHints("ok")] [Route(HttpVerbs.Get, "/GetSimGlobalPos/{regionname}/{token}")] public Object GetSimGlobalPos(string regionname, string token) @@ -136,7 +136,7 @@ namespace BetterSecondBot.HttpService } [About("Requests the estate banlist")] - [ReturnHints("")] + [ReturnHints("ban list json")] [Route(HttpVerbs.Get, "/GetEstateBanList/{token}")] public Object GetEstateBanList(string token) { @@ -150,9 +150,9 @@ namespace BetterSecondBot.HttpService [About("Attempts to add/remove the avatar to/from the Estate banlist")] [ReturnHints("Unban request accepted")] [ReturnHints("Ban request accepted")] - [ReturnHints("Unable to find avatar UUID")] - [ReturnHints("Unable to process global value please use true or false")] - [ReturnHints("Not an estate manager on region {REGIONNAME}")] + [ReturnHintsFailure("Unable to find avatar UUID")] + [ReturnHintsFailure("Unable to process global value please use true or false")] + [ReturnHintsFailure("Not an estate manager on region {REGIONNAME}")] [ArgHints("avatar", "URLARG", "the uuid avatar you wish to ban")] [ArgHints("mode", "URLARG", "What action would you like to take
    Defaults to remove if not given \"add\"")] [ArgHints("global", "URLARG", "if true this the ban/unban will be applyed to all estates the bot has access to")] diff --git a/Core/Commands/Friends.cs b/Core/Commands/Friends.cs index da531c1..51e6732 100644 --- a/Core/Commands/Friends.cs +++ b/Core/Commands/Friends.cs @@ -33,9 +33,9 @@ namespace BetterSecondBot.HttpService [ArgHints("state", "URLARG", "true: Grant perms, false: Remove perms")] [ReturnHints("granted")] [ReturnHints("removed")] - [ReturnHints("Not A friend")] - [ReturnHints("state invaild")] - [ReturnHints("avatar lookup")] + [ReturnHintsFailure("Not A friend")] + [ReturnHintsFailure("state invaild")] + [ReturnHintsFailure("avatar lookup")] [Route(HttpVerbs.Get, "/FriendFullPerms/{avatar}/{state}/{token}")] public object FriendFullPerms(string avatar, string state, string token) { @@ -69,10 +69,10 @@ namespace BetterSecondBot.HttpService [About("Updates the friend perms for avatar avatar to State \n if true grants (Online/Map/Modify) perms")] [ReturnHints("Request sent")] [ReturnHints("Removed")] - [ReturnHints("Already a friend")] - [ReturnHints("Not in friendslist")] - [ReturnHints("state invaild")] - [ReturnHints("avatar lookup")] + [ReturnHintsFailure("Already a friend")] + [ReturnHintsFailure("Not in friendslist")] + [ReturnHintsFailure("state invaild")] + [ReturnHintsFailure("avatar lookup")] [ArgHints("avatar", "URLARG", "A avatar uuid or Firstname Lastname")] [ArgHints("state", "URLARG", "true: Send invite, false: Remove from friendslist")] [Route(HttpVerbs.Get, "/FriendRequest/{avatar}/{state}/{token}")] diff --git a/Core/Commands/Funds.cs b/Core/Commands/Funds.cs index d997353..3f4dc31 100644 --- a/Core/Commands/Funds.cs +++ b/Core/Commands/Funds.cs @@ -18,7 +18,7 @@ namespace BetterSecondBot.HttpService [About("Requests the current balance and requests the balance to update.")] [ReturnHints("Current fund level")] - [ReturnHints("Funds commands are disabled")] + [ReturnHintsFailure("Funds commands are disabled")] [Route(HttpVerbs.Get, "/Balance/{token}")] public object Balance(string token) { @@ -36,10 +36,10 @@ namespace BetterSecondBot.HttpService [About("Makes the bot pay a avatar")] [ReturnHints("Accepted")] - [ReturnHints("avatar lookup")] - [ReturnHints("Amount out of range")] - [ReturnHints("Invaild amount")] - [ReturnHints("Transfer funds to avatars disabled")] + [ReturnHintsFailure("avatar lookup")] + [ReturnHintsFailure("Amount out of range")] + [ReturnHintsFailure("Invaild amount")] + [ReturnHintsFailure("Transfer funds to avatars disabled")] [ArgHints("avatar", "URLARG", "the avatars UUID or Firstname Lastname")] [ArgHints("amount", "URLARG", "the amount to pay (from 1 to current balance)")] [Route(HttpVerbs.Get, "/PayAvatar/{avatar}/{amount}/{token}")] @@ -72,12 +72,11 @@ namespace BetterSecondBot.HttpService [About("Makes the bot pay a object")] [ReturnHints("ok")] - [ReturnHints("Primname is empty")] - [ReturnHints("Current fund level")] - [ReturnHints("Invaild object UUID")] - [ReturnHints("Invaild amount")] - [ReturnHints("Amount out of range")] - [ReturnHints("Funds commands are disabled")] + [ReturnHintsFailure("Primname is empty")] + [ReturnHintsFailure("Invaild object UUID")] + [ReturnHintsFailure("Invaild amount")] + [ReturnHintsFailure("Amount out of range")] + [ReturnHintsFailure("Funds commands are disabled")] [ArgHints("object", "URLARG", "UUID of the object to pay")] [ArgHints("primname", "URLARG", "The name of the prim on the object to pay")] [ArgHints("amount", "URLARG", "the amount to pay (from 1 to current balance)")] diff --git a/Core/Commands/Group.cs b/Core/Commands/Group.cs index ba34e57..7ef8b16 100644 --- a/Core/Commands/Group.cs +++ b/Core/Commands/Group.cs @@ -20,10 +20,10 @@ namespace BetterSecondBot.HttpService [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")] [ReturnHints("Membership reply with [membershipStatus,AvatarUUID,AvatarnameIfKnown,GroupUUID]")] - [ReturnHints("Updating")] - [ReturnHints("Unknown group")] - [ReturnHints("Invaild group UUID")] - [ReturnHints("avatar lookup")] + [ReturnHintsFailure("Updating")] + [ReturnHintsFailure("Unknown group")] + [ReturnHintsFailure("Invaild group UUID")] + [ReturnHintsFailure("avatar lookup")] [ArgHints("group", "URLARG", "the UUID of the group")] [ArgHints("avatar", "URLARG", "the UUID of the avatar you wish to check with")] [Route(HttpVerbs.Get, "/IsGroupMember/{group}/{avatar}/{token}")] @@ -61,10 +61,10 @@ namespace BetterSecondBot.HttpService [About("Gets membership of a group")] [ReturnHints("list of UUIDS of group members")] - [ReturnHints("Updating")] - [ReturnHints("Unknown group")] - [ReturnHints("Invaild group UUID")] - [ReturnHints("avatar lookup")] + [ReturnHintsFailure("Updating")] + [ReturnHintsFailure("Unknown group")] + [ReturnHintsFailure("Invaild group UUID")] + [ReturnHintsFailure("avatar lookup")] [ArgHints("group", "URLARG", "the UUID of the group")] [Route(HttpVerbs.Get, "/GetGroupMembers/{group}/{token}")] public object GetGroupMembers(string group, string token) @@ -96,11 +96,11 @@ namespace BetterSecondBot.HttpService [About("Attempts to ban/unban a given avatar from a group")] [ReturnHints("? request accepted")] - [ReturnHints("Updating")] - [ReturnHints("Unknown group")] - [ReturnHints("Invaild group UUID")] - [ReturnHints("avatar lookup")] - [ReturnHints("Missing group GroupBanAccess power")] + [ReturnHintsFailure("Updating")] + [ReturnHintsFailure("Unknown group")] + [ReturnHintsFailure("Invaild group UUID")] + [ReturnHintsFailure("avatar lookup")] + [ReturnHintsFailure("Missing group GroupBanAccess power")] [ArgHints("group", "URLARG", "the UUID of the group")] [ArgHints("avatar", "URLARG", "the UUID of the avatar or Firstname Lastname")] [ArgHints("state", "URLARG", "true to ban false to unban")] @@ -148,12 +148,12 @@ namespace BetterSecondBot.HttpService [About("Eject selected avatar from group")] [ReturnHints("Requested")] - [ReturnHints("Updating")] - [ReturnHints("Unknown group")] - [ReturnHints("Invaild group UUID")] - [ReturnHints("Not in group")] - [ReturnHints("avatar lookup")] - [ReturnHints("Missing group Eject power")] + [ReturnHintsFailure("Updating")] + [ReturnHintsFailure("Unknown group")] + [ReturnHintsFailure("Invaild group UUID")] + [ReturnHintsFailure("Not in group")] + [ReturnHintsFailure("avatar lookup")] + [ReturnHintsFailure("Missing group Eject power")] [ArgHints("group", "URLARG", "the UUID of the group")] [ArgHints("avatar", "URLARG", "the UUID of the avatar you wish to check with")] [Route(HttpVerbs.Get, "/GroupEject/{group}/{avatar}/{token}")] @@ -185,15 +185,15 @@ namespace BetterSecondBot.HttpService return BasicReply("Requested", "GroupEject", new [] { group, avatar }); } - [About("Adds the avatar to the Group with the role \n if they are not in the group then it invites them aswell")] + [About("Adds the avatar to the Group with the role \n if they are not in the group then it invites them at that role")] [ReturnHints("Roles updated")] [ReturnHints("Invite sent")] - [ReturnHints("Updating")] - [ReturnHints("Unknown group")] - [ReturnHints("Invaild group UUID")] - [ReturnHints("Invaild role UUID")] - [ReturnHints("Not in group")] - [ReturnHints("avatar lookup")] + [ReturnHintsFailure("Updating")] + [ReturnHintsFailure("Unknown group")] + [ReturnHintsFailure("Invaild group UUID")] + [ReturnHintsFailure("Invaild role UUID")] + [ReturnHintsFailure("Not in group")] + [ReturnHintsFailure("avatar lookup")] [ArgHints("group", "URLARG", "the UUID of the group")] [ArgHints("avatar", "URLARG", "the UUID of the avatar you wish to check with")] [Route(HttpVerbs.Get, "/GroupAddRole/{group}/{avatar}/{role}/{token}")] @@ -235,14 +235,14 @@ namespace BetterSecondBot.HttpService return BasicReply("Roles updated", "GroupAddRole", new [] { group, avatar }); } - [About("Eject selected avatar from group")] + [About("Invites selected avatar to the group with the selected role")] [ReturnHints("Invite sent")] - [ReturnHints("Updating")] - [ReturnHints("Unknown group")] - [ReturnHints("Invaild group UUID")] [ReturnHints("Already in group")] - [ReturnHints("avatar lookup")] - [ReturnHints("Missing group Invite power")] + [ReturnHintsFailure("Updating")] + [ReturnHintsFailure("Unknown group")] + [ReturnHintsFailure("Invaild group UUID")] + [ReturnHintsFailure("avatar lookup")] + [ReturnHintsFailure("Missing group Invite power")] [ArgHints("group", "URLARG", "the UUID of the group")] [ArgHints("avatar", "URLARG", "the UUID of the avatar you wish to check with")] [ArgHints("role", "URLARG", "the UUID of the role to invite them at the word \"everyone\"")] @@ -273,7 +273,7 @@ namespace BetterSecondBot.HttpService bool status = bot.FastCheckInGroup(groupuuid, avataruuid); if (status == true) { - return Failure("Already in group", "GroupInvite", new [] { group, avatar, role }); + return BasicReply("Already in group", "GroupInvite", new[] { group, avatar, role }); } if(role == "everyone") { @@ -294,11 +294,11 @@ namespace BetterSecondBot.HttpService [About("Sends a group notice (No attachments please use GroupnoticeWithAttachment to attach items!)")] [ReturnHints("Sending notice")] - [ReturnHints("Unknown group")] - [ReturnHints("Invaild group UUID")] - [ReturnHints("Title empty")] - [ReturnHints("Message empty")] - [ReturnHints("Missing group Notice power")] + [ReturnHintsFailure("Unknown group")] + [ReturnHintsFailure("Invaild group UUID")] + [ReturnHintsFailure("Title empty")] + [ReturnHintsFailure("Message empty")] + [ReturnHintsFailure("Missing group Notice power")] [ArgHints("group", "URLARG", "the UUID of the group")] [ArgHints("title", "Text", "The title of the group notice")] [ArgHints("message", "Text", "The body of the group notice")] @@ -340,9 +340,9 @@ namespace BetterSecondBot.HttpService [About("Activates the selected title")] [ReturnHints("Switching title")] - [ReturnHints("Unknown group")] - [ReturnHints("Invaild group UUID")] - [ReturnHints("Invaild role UUID")] + [ReturnHintsFailure("Unknown group")] + [ReturnHintsFailure("Invaild group UUID")] + [ReturnHintsFailure("Invaild role UUID")] [ArgHints("group", "URLARG", "the UUID of the group")] [ArgHints("role", "URLARG", "tje UUID of the role")] [Route(HttpVerbs.Get, "/GroupActiveTitle/{group}/{token}")] @@ -370,8 +370,8 @@ namespace BetterSecondBot.HttpService [About("Sets the selected group to the active group")] [ReturnHints("Switching active group")] - [ReturnHints("Unknown group")] - [ReturnHints("Invaild group UUID")] + [ReturnHintsFailure("Unknown group")] + [ReturnHintsFailure("Invaild group UUID")] [ArgHints("group", "URLARG", "the UUID of the group")] [Route(HttpVerbs.Get, "/GroupActiveGroup/{group}/{token}")] public object GroupActiveGroup(string group, string token) @@ -394,12 +394,12 @@ namespace BetterSecondBot.HttpService [About("Sends a group notice with an attachment")] [ReturnHints("Sending notice with attachment")] - [ReturnHints("Unknown group")] - [ReturnHints("Invaild group UUID")] - [ReturnHints("Invaild inventory UUID")] - [ReturnHints("Title empty")] - [ReturnHints("Message empty")] - [ReturnHints("Missing group Notice power")] + [ReturnHintsFailure("Unknown group")] + [ReturnHintsFailure("Invaild group UUID")] + [ReturnHintsFailure("Invaild inventory UUID")] + [ReturnHintsFailure("Title empty")] + [ReturnHintsFailure("Message empty")] + [ReturnHintsFailure("Missing group Notice power")] [ArgHints("group", "URLARG", "the UUID of the group")] [ArgHints("title", "Text", "The title of the group notice")] [ArgHints("message", "Text", "The body of the group notice")] @@ -465,9 +465,9 @@ namespace BetterSecondBot.HttpService [About("Requests the roles for the selected group
    Replys with GroupRoleDetails object formated as follows
    • UpdateUnderway (Bool)
    • RoleDataAge (Int) [default -1]
    • Roles (KeyPair array of UUID=Name)

    ")] [ReturnHints("GroupRoleDetails object")] - [ReturnHints("Group is not currently known")] - [ReturnHints("Invaild group UUID")] - [ReturnHints("Updating")] + [ReturnHintsFailure("Group is not currently known")] + [ReturnHintsFailure("Invaild group UUID")] + [ReturnHintsFailure("Updating")] [ArgHints("group", "URLARG", "the UUID of the group")] [Route(HttpVerbs.Get, "/GetGroupRoles/{group}/{token}")] public object GetGroupRoles(string group, string token) @@ -529,10 +529,9 @@ namespace BetterSecondBot.HttpService } [About("fetchs a list of all groups with unread messages")] - [ReturnHints("true")] - [ReturnHints("false")] - [ReturnHints("Unknown group")] - [ReturnHints("group value is invaild")] + [ReturnHints("true|false")] + [ReturnHintsFailure("Unknown group")] + [ReturnHintsFailure("group value is invaild")] [ArgHints("group", "URLARG", "the UUID of the group")] [Route(HttpVerbs.Get, "/GroupchatGroupHasUnread/{group}/{token}")] public object GroupchatGroupHasUnread(string group,string token) @@ -580,7 +579,7 @@ namespace BetterSecondBot.HttpService } [About("fetchs the groupchat history")] - [ReturnHints("Group UUID invaild")] + [ReturnHintsFailure("Group UUID invaild")] [ReturnHints("Group Chat")] [ArgHints("group", "URLARG", "the UUID of the group")] [Route(HttpVerbs.Get, "/GroupchatHistory/{group}/{token}")] @@ -600,11 +599,10 @@ namespace BetterSecondBot.HttpService [About("sends a message to the groupchat")] [ArgHints("group", "URLARG", "UUID of the group")] [ArgHints("message", "Text", "the message to send")] - [ReturnHints("Group UUID invaild")] - [ReturnHints("Processing")] - [ReturnHints("Opening groupchat")] [ReturnHints("Sending")] - [ReturnHints("Missing group JoinChat power")] + [ReturnHintsFailure("Group UUID invaild")] + [ReturnHintsFailure("Opening groupchat - Please retry later")] + [ReturnHintsFailure("Missing group JoinChat power")] [Route(HttpVerbs.Post, "/Groupchat/{group}/{token}")] public object Groupchat(string group, [FormField] string message, string token) { @@ -629,7 +627,7 @@ namespace BetterSecondBot.HttpService if (bot.GetActiveGroupchatSessions.Contains(groupUUID) == false) { bot.GetClient.Self.RequestJoinGroupChat(groupUUID); - return Failure("Opening groupchat", "Groupchat", new [] { group, message }); + return Failure("Opening groupchat - Please retry later", "Groupchat", new [] { group, message }); } bot.GetClient.Self.InstantMessageGroup(groupUUID, message); return BasicReply("Sending", "Groupchat", new [] { group, message }); diff --git a/Core/Commands/Home.cs b/Core/Commands/Home.cs deleted file mode 100644 index 57cc97d..0000000 --- a/Core/Commands/Home.cs +++ /dev/null @@ -1,33 +0,0 @@ -using BetterSecondBot.bottypes; -using BetterSecondBot.Static; -using EmbedIO; -using EmbedIO.Routing; -using EmbedIO.WebApi; -using System; -using System.Collections.Generic; -using System.Text; -using OpenMetaverse; -using Newtonsoft.Json; -using BetterSecondBotShared.Static; - -namespace BetterSecondBot.HttpService -{ - public class HTTP_Home : WebApiControllerWithTokens - { - public HTTP_Home(SecondBot mainbot, TokenStorage setuptokens) : base(mainbot, setuptokens) { } - - [About("Makes the bot teleport to its home region")] - [ReturnHints("ok")] - [Route(HttpVerbs.Get, "/GoHome/{token}")] - public object GoHome(string token) - { - if (tokens.Allow(token, "home", "GoHome", handleGetClientIP()) == false) - { - return Failure("Token not accepted", "GoHome"); - } - bot.GotoNextHomeRegion(); - return BasicReply("ok", "GoHome"); - } - - } -} diff --git a/Core/Commands/Im.cs b/Core/Commands/Im.cs deleted file mode 100644 index ca85c70..0000000 --- a/Core/Commands/Im.cs +++ /dev/null @@ -1,89 +0,0 @@ -using BetterSecondBot.bottypes; -using BetterSecondBot.Static; -using EmbedIO; -using EmbedIO.Routing; -using EmbedIO.WebApi; -using System; -using System.Collections.Generic; -using System.Text; -using OpenMetaverse; -using Newtonsoft.Json; - -namespace BetterSecondBot.HttpService -{ - public class HTTP_IM : WebApiControllerWithTokens - { - public HTTP_IM(SecondBot mainbot, TokenStorage setuptokens) : base(mainbot, setuptokens) { } - - [About("gets a full list of all chat windows")] - [ReturnHints("array UUID = Name")] - [Route(HttpVerbs.Get, "/chatwindows/{token}")] - public object chatwindows(string token) - { - if (tokens.Allow(token, "im", "chatwindows", handleGetClientIP()) == false) - { - return BasicReply("Token not accepted", "chatwindows"); - } - return BasicReply(JsonConvert.SerializeObject(bot.GetIMChatWindowKeyNames()), "chatwindows"); - } - - [About("gets a list of chat windows with unread messages")] - [ReturnHints("array of UUID")] - [Route(HttpVerbs.Get, "/listwithunread/{token}")] - public object listwithunread(string token) - { - if (tokens.Allow(token, "im", "listwithunread", handleGetClientIP()) == false) - { - return BasicReply("Token not accepted", "listwithunread"); - } - List unreadimwindows = new List(); - foreach (UUID window in bot.IMChatWindows()) - { - if (bot.ImChatWindowHasUnread(window) == true) - { - unreadimwindows.Add(window); - } - } - return BasicReply(JsonConvert.SerializeObject(unreadimwindows), "listwithunread"); - } - - [About("gets if there are any unread im messages at all")] - [ReturnHints("True|False")] - [Route(HttpVerbs.Get, "/haveunreadims/{token}")] - public object haveunreadims(string token) - { - if (tokens.Allow(token, "im", "haveunreadims", handleGetClientIP()) == false) - { - return BasicReply("Token not accepted", "haveunreadims"); - } - bool reply = false; - foreach (UUID window in bot.IMChatWindows()) - { - if (bot.ImChatWindowHasUnread(window) == true) - { - reply = true; - break; - } - } - return BasicReply(reply.ToString(), "haveunreadims"); - } - - [About("gets the chat from the selected window")] - [ArgHints("window", "URLARG", "the UUID of the chat window")] - [ReturnHints("Window UUID invaild")] - [ReturnHints("Array of text")] - [Route(HttpVerbs.Get, "/getimchat/{window}/{token}")] - public object getimchat(string window, string token) - { - if (tokens.Allow(token, "im", "getimchat", handleGetClientIP()) == false) - { - return Failure("Token not accepted", "getimchat", new [] { window }); - } - if (UUID.TryParse(window, out UUID windowUUID) == false) - { - return Failure("Window UUID invaild", "getimchat", new [] { window }); - } - return BasicReply(JsonConvert.SerializeObject(bot.GetIMChatWindow(windowUUID)), "getimchat", new [] { window }); - } - } -} diff --git a/Core/Commands/Info.cs b/Core/Commands/Info.cs index 95a207d..83d938f 100644 --- a/Core/Commands/Info.cs +++ b/Core/Commands/Info.cs @@ -43,8 +43,8 @@ namespace BetterSecondBot.HttpService [About("Fetchs the current parcels name")] [ReturnHints("Parcelname")] - [ReturnHints("Error parcel not found")] - [ReturnHints("Error not in a sim")] + [ReturnHintsFailure("Error parcel not found")] + [ReturnHintsFailure("Error not in a sim")] [Route(HttpVerbs.Get, "/ParcelName/{token}")] public object ParcelName(string token) { @@ -78,7 +78,7 @@ namespace BetterSecondBot.HttpService [About("Fetchs the current region name")] [ReturnHints("Regionname")] - [ReturnHints("Error not in a sim")] + [ReturnHintsFailure("Error not in a sim")] [Route(HttpVerbs.Get, "/SimName/{token}")] public object SimName(string token) { @@ -95,7 +95,7 @@ namespace BetterSecondBot.HttpService [About("Fetchs the current location of the bot")] [ReturnHints("array of X,Y,Z values")] - [ReturnHints("Error not in a sim")] + [ReturnHintsFailure("Error not in a sim")] [Route(HttpVerbs.Get, "/GetPosition/{token}")] public object GetPosition(string token) { diff --git a/Core/Commands/Inventory.cs b/Core/Commands/Inventory.cs index d3d47f0..f1311c5 100644 --- a/Core/Commands/Inventory.cs +++ b/Core/Commands/Inventory.cs @@ -9,6 +9,8 @@ using System.Text; using OpenMetaverse; using System.Linq; using BetterSecondBotShared.Static; +using System.IO; +using OpenMetaverse.Assets; namespace BetterSecondBot.HttpService { @@ -16,6 +18,43 @@ namespace BetterSecondBot.HttpService { public HTTP_Inventory(SecondBot mainbot, TokenStorage setuptokens) : base(mainbot, setuptokens) { } + + [About("Does a thing")] + [ReturnHints("ok")] + [ArgHints("sourcePath", "Text", "The path to the wavefile")] + [ArgHints("inventoryName", "URLARG", "the name in secondlife")] + [Route(HttpVerbs.Post, "/UploadMediaWave/{inventoryName}/{token}")] + public object UploadMediaWave([FormField] string sourcePath, string inventoryName, string token) + { + if (tokens.Allow(token, "inventory", "UploadMediaWave", handleGetClientIP()) == false) + { + return Failure("Token not accepted", "UploadMediaWave"); + } + byte[] audioData = File.ReadAllBytes(sourcePath); + InventoryFolder AA = bot.GetClient.Inventory.Store.RootFolder; + List T = bot.GetClient.Inventory.Store.GetContents(AA); + AA = null; + foreach (InventoryBase R in T) + { + if (R.Name == "Sounds") + { + AA = (InventoryFolder)R; + break; + } + } + AssetSound S = new AssetSound(); + S.AssetData = audioData; + S.Encode(); + + bot.GetClient.Inventory.RequestCreateItemFromAsset(S.AssetData, inventoryName, "", AssetType.Sound, InventoryType.Sound, AA.UUID, uploadFinished); + return BasicReply("ok", "UploadMediaWave"); + } + private void uploadFinished(bool success, string status, UUID itemID, UUID assetID) + { + bot.GetClient.Self.Chat("Success: " + success + " status:" + status + " Inv: " + itemID.ToString() + " Ass:" + assetID.ToString(), 0, ChatType.Normal); + } + + [About("rezs the item at the bots current location")] [ReturnHints("UUID of rezzed item")] [ReturnHints("Invaild item UUID")] diff --git a/Core/Commands/Movement.cs b/Core/Commands/Movement.cs index 40f6248..d077b71 100644 --- a/Core/Commands/Movement.cs +++ b/Core/Commands/Movement.cs @@ -21,8 +21,8 @@ namespace BetterSecondBot.HttpService [About("uses the AutoPilot to move to a location")] [ReturnHints("Error Unable to AutoPilot to location")] [ReturnHints("ok")] - [ReturnHints("Convert to vector has failed")] - [ReturnHints("? value out of range 0-?")] + [ReturnHintsFailure("Convert to vector has failed")] + [ReturnHintsFailure("? 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")] @@ -73,7 +73,7 @@ namespace BetterSecondBot.HttpService [About("Make the bot request the target avatar teleport to the bot")] [ReturnHints("ok")] - [ReturnHints("Invaild avatar UUID")] + [ReturnHintsFailure("Invaild avatar UUID")] [ArgHints("avatar", "URLARG", "Avatar UUID or Firstname Lastname")] [Route(HttpVerbs.Get, "/SendTeleportLure/{avatar}/{token}")] public object SendTeleportLure(string avatar,string token) @@ -93,7 +93,7 @@ namespace BetterSecondBot.HttpService [About("Sends a teleport request (Move the bot to the avatar)")] [ReturnHints("ok")] - [ReturnHints("Invaild avatar UUID")] + [ReturnHintsFailure("Invaild avatar UUID")] [ArgHints("avatar", "URLARG", "Avatar UUID or Firstname Lastname")] [Route(HttpVerbs.Get, "/RequestTeleport/{avatar}/{token}")] public object RequestTeleport(string avatar, string token) @@ -114,7 +114,7 @@ namespace BetterSecondBot.HttpService [About("Makes the bot fly (or not)")] [ReturnHints("ok")] - [ReturnHints("Invaild mode")] + [ReturnHintsFailure("Invaild mode")] [ArgHints("mode", "URLARG", "true: Start flying, false: stop flying (super fun at height)")] [Route(HttpVerbs.Get, "/Fly/{mode}/{token}")] public object Fly(string mode, string token) @@ -136,8 +136,8 @@ namespace BetterSecondBot.HttpService [About("Rotates the bot to face a vector from its current location")] [ReturnHints("true|false")] - [ReturnHints("Invaild vector")] - [ReturnHints("Vector ? value is out of range 0-?")] + [ReturnHintsFailure("Invaild vector")] + [ReturnHintsFailure("Vector ? value is out of range 0-?")] [ArgHints("vector", "Text", "a vector to face eg <123,45,44>")] [Route(HttpVerbs.Post, "/RotateToFaceVector/{token}")] public object RotateToFaceVector([FormField] string vector, string token) @@ -167,8 +167,8 @@ namespace BetterSecondBot.HttpService [About("Rotates the bot to face a avatar")] [ReturnHints("true|false")] - [ReturnHints("Invaild avatar UUID")] - [ReturnHints("Unable to see avatar")] + [ReturnHintsFailure("Invaild avatar UUID")] + [ReturnHintsFailure("Unable to see avatar")] [ArgHints("avatar", "URLARG", "An avatar UUID or Firstname Lastname")] [Route(HttpVerbs.Post, "/RotateToFace/{avatar}/{token}")] public object RotateToFace(string avatar, string token) @@ -192,7 +192,7 @@ namespace BetterSecondBot.HttpService [About("Rotates the avatar to face a rotation from north in Degrees")] [ReturnHints("ok")] - [ReturnHints("Unable to process rotation")] + [ReturnHintsFailure("Unable to process rotation")] [ArgHints("deg", "URLARG", "0 to 360")] [Route(HttpVerbs.Post, "/RotateTo/{deg}/{token}")] public object RotateTo(string deg, string token) @@ -232,7 +232,7 @@ namespace BetterSecondBot.HttpService [About("Attempt to teleport to a new region")] - [ReturnHints("Error Unable to Teleport to location")] + [ReturnHintsFailure("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")] @@ -256,7 +256,7 @@ namespace BetterSecondBot.HttpService [About("Attempt to teleport to a new region via a SL url")] - [ReturnHints("slurl is empty")] + [ReturnHintsFailure("slurl is empty")] [ReturnHints("True|False")] [ArgHints("slurl", "Text", "a full SLurl")] [Route(HttpVerbs.Post, "/TeleportSLURL/{token}")] diff --git a/Core/Commands/Notecard.cs b/Core/Commands/Notecard.cs index 3768b93..43f99c6 100644 --- a/Core/Commands/Notecard.cs +++ b/Core/Commands/Notecard.cs @@ -1,15 +1,10 @@ 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 System; namespace BetterSecondBot.HttpService { @@ -18,9 +13,11 @@ namespace BetterSecondBot.HttpService public HTTP_Notecard(SecondBot mainbot, TokenStorage setuptokens) : base(mainbot, setuptokens) { } [About("Adds content to the Collection
    Also creates the Collection if it does not exist")] - [ReturnHints("Collection value is empty")] - [ReturnHints("Content value is empty")] + [ReturnHintsFailure("Collection value is empty")] + [ReturnHintsFailure("Content value is empty")] [ReturnHints("ok")] + [ArgHints("collection", "URLARG", "The name of the collection")] + [ArgHints("content", "String", "The text to add to the collection")] [Route(HttpVerbs.Post, "/NotecardAdd/{collection}/{token}")] public object NotecardAdd(string collection, [FormField] string content, string token) { @@ -40,9 +37,10 @@ namespace BetterSecondBot.HttpService return BasicReply("ok", "NotecardAdd", new [] { collection, content }); } - [About("Adds content to the Collection
    Also creates the Collection if it does not exist")] - [ReturnHints("Collection value is empty")] + [About("Clears the contents of a collection")] + [ReturnHintsFailure("Collection value is empty")] [ReturnHints("ok")] + [ArgHints("collection", "URLARG", "The name of the collection")] [Route(HttpVerbs.Get, "/NotecardClear/{collection}/{token}")] public object NotecardClear(string collection, string token) { @@ -58,13 +56,15 @@ namespace BetterSecondBot.HttpService return BasicReply("ok", "NotecardClear", new [] { collection }); } - [About("Adds content to the Collection
    Also creates the Collection if it does not exist")] - [ReturnHints("True|False")] - [ReturnHints("Collection value is empty")] - [ReturnHints("Notecardname value is empty")] - [ReturnHints("Invaild avatar uuid")] - [ReturnHints("No content in notecard storage ?")] + [About("Sends a notecard to a avatar using the text in the prebuilt collection [see NotecardAdd] and also clears the collection just before sending [see NotecardClear]")] + [ReturnHintsFailure("Collection value is empty")] + [ReturnHintsFailure("Notecardname value is empty")] + [ReturnHintsFailure("Invaild avatar uuid")] + [ReturnHintsFailure("No content in notecard storage ?")] [ReturnHints("ok")] + [ArgHints("avatar", "URLARG", "The UUID or Name of an avatar")] + [ArgHints("collection", "URLARG", "The name of the collection")] + [ArgHints("notecardname", "URLARG", "What to call the created notecard")] [Route(HttpVerbs.Get, "/NotecardSend/{avatar}/{collection}/{notecardname}/{token}")] public object NotecardSend(string avatar, string collection, string notecardname, string token) { @@ -93,5 +93,36 @@ namespace BetterSecondBot.HttpService bot.ClearNotecardStorage(collection); return BasicReply(bot.SendNotecard(notecardname, content, avataruuid).ToString(), "NotecardSend", new [] { avatar, collection, notecardname }); } + + [About("Creates and sends a notecard in one command good if you are using HTTP otherwise see [NotecardSend]")] + [ReturnHintsFailure("notecardname value is empty")] + [ReturnHintsFailure("Content value is empty")] + [ReturnHintsFailure("Invaild avatar uuid")] + [ReturnHints("ok")] + [ArgHints("avatar", "URLARG", "The UUID or Name of an avatar")] + [ArgHints("content", "String", "The text to add to the collection")] + [ArgHints("notecardname", "URLARG", "What to call the created notecard")] + [Route(HttpVerbs.Post, "/NotecardDirectSend/{avatar}/{notecardname}/{token}")] + public object NotecardDirectSend(string avatar, [FormField] string content, string notecardname, string token) + { + if (tokens.Allow(token, "notecard", "NotecardSend", handleGetClientIP()) == false) + { + return Failure("Token not accepted", "NotecardDirectSend", new[] { avatar, content, notecardname }); + } + if (helpers.notempty(notecardname) == false) + { + return Failure("notecardname value is empty", "NotecardDirectSend", new[] { avatar, content, notecardname }); + } + if (helpers.notempty(content) == false) + { + return Failure("content value is empty", "NotecardDirectSend", new[] { avatar, content, notecardname }); + } + ProcessAvatar(avatar); + if (avataruuid == UUID.Zero) + { + return Failure("Invaild avatar uuid", "NotecardDirectSend", new[] { avatar, content, notecardname }); + } + return BasicReply(bot.SendNotecard(notecardname, content, avataruuid).ToString(), "NotecardDirectSend", new[] { avatar, content, notecardname }); + } } } diff --git a/Core/Commands/Parcel.cs b/Core/Commands/Parcel.cs index fa9205f..66c26a7 100644 --- a/Core/Commands/Parcel.cs +++ b/Core/Commands/Parcel.cs @@ -21,9 +21,9 @@ namespace BetterSecondBot.HttpService [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")] + [ReturnHintsFailure("Error not in a sim")] + [ReturnHintsFailure("Parcel data not ready")] + [ReturnHintsFailure("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}")] @@ -53,9 +53,9 @@ namespace BetterSecondBot.HttpService [About("Changes the parcel landing mode to point and sets the landing point")] [ReturnHints("ok")] - [ReturnHints("Error not in a sim")] - [ReturnHints("Parcel data not ready")] - [ReturnHints("Invaild amount")] + [ReturnHintsFailure("Error not in a sim")] + [ReturnHintsFailure("Parcel data not ready")] + [ReturnHintsFailure("Invaild amount")] [ArgHints("x", "URLARG", "X point for landing")] [ArgHints("y", "URLARG", "Y point for landing")] [ArgHints("z", "URLARG", "Z point for landing")] @@ -88,9 +88,9 @@ namespace BetterSecondBot.HttpService [About("Updates the current parcels name")] [ReturnHints("ok")] - [ReturnHints("Error not in a sim")] - [ReturnHints("Parcel data not ready")] - [ReturnHints("Parcel name is empty")] + [ReturnHintsFailure("Error not in a sim")] + [ReturnHintsFailure("Parcel data not ready")] + [ReturnHintsFailure("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) @@ -111,8 +111,8 @@ namespace BetterSecondBot.HttpService [About("Updates the current parcels description")] [ReturnHints("ok")] - [ReturnHints("Error not in a sim")] - [ReturnHints("Parcel data not ready")] + [ReturnHintsFailure("Error not in a sim")] + [ReturnHintsFailure("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) @@ -129,8 +129,8 @@ namespace BetterSecondBot.HttpService [About("Fetchs the current parcels desc")] [ReturnHints("ok")] - [ReturnHints("Error not in a sim")] - [ReturnHints("Parcel data not ready")] + [ReturnHintsFailure("Error not in a sim")] + [ReturnHintsFailure("Parcel data not ready")] [Route(HttpVerbs.Get, "/GetParcelDesc/{token}")] public object GetParcelDesc(string token) { @@ -144,8 +144,8 @@ namespace BetterSecondBot.HttpService [About("gets the flags for the parcel")] [ReturnHints("ok")] - [ReturnHints("Error not in a sim")] - [ReturnHints("Parcel data not ready")] + [ReturnHintsFailure("Error not in a sim")] + [ReturnHintsFailure("Parcel data not ready")] [Route(HttpVerbs.Get, "/GetParcelFlags/{token}")] public object GetParcelFlags(string token) { @@ -166,7 +166,7 @@ namespace BetterSecondBot.HttpService [About("Ejects an avatar")] [ReturnHints("ok")] - [ReturnHints("Invaild avatar")] + [ReturnHintsFailure("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) @@ -201,10 +201,10 @@ namespace BetterSecondBot.HttpService [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")] + [ReturnHintsFailure("Error not in a sim")] + [ReturnHintsFailure("Parcel data not ready")] + [ReturnHintsFailure("Invaild avatar")] + [ReturnHintsFailure("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) @@ -243,10 +243,10 @@ namespace BetterSecondBot.HttpService [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")] + [ReturnHintsFailure("Error not in a sim")] + [ReturnHintsFailure("Parcel data not ready")] + [ReturnHintsFailure("Invaild avatar")] + [ReturnHintsFailure("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) @@ -284,8 +284,8 @@ namespace BetterSecondBot.HttpService [About("Updates the current parcels name")] [ReturnHints("true|false")] - [ReturnHints("Error not in a sim")] - [ReturnHints("Parcel data not ready")] + [ReturnHintsFailure("Error not in a sim")] + [ReturnHintsFailure("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) @@ -301,13 +301,13 @@ namespace BetterSecondBot.HttpService [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 \"=\"")] + [ReturnHintsFailure("Error not in a sim")] + [ReturnHintsFailure("Parcel data not ready")] + [ReturnHintsFailure("Incorrect perms to control parcel")] + [ReturnHintsFailure("No accepted flags")] + [ReturnHintsFailure("Unable to set flag ...")] + [ReturnHintsFailure("Flag: ? is unknown")] + [ReturnHintsFailure("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) @@ -363,9 +363,9 @@ namespace BetterSecondBot.HttpService [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")] + [ReturnHintsFailure("Error not in a sim")] + [ReturnHintsFailure("Parcel data not ready")] + [ReturnHintsFailure("Invaild avatar UUID")] [ArgHints("avatar", "URLARG", "avatar uuid or Firstname Lastname")] [Route(HttpVerbs.Get, "/ParcelReturnTargeted/{avatar}/{token}")] public object ParcelReturnTargeted(string avatar, string token) @@ -387,10 +387,10 @@ namespace BetterSecondBot.HttpService [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")] + [ReturnHintsFailure("Error not in a sim")] + [ReturnHintsFailure("Parcel data not ready")] + [ReturnHintsFailure("Invaild group uuid")] + [ReturnHintsFailure("Not in group")] [Route(HttpVerbs.Get, "/ParcelDeedToGroup/{group}/{token}")] public object ParcelDeedToGroup(string group, string token) { @@ -416,13 +416,13 @@ namespace BetterSecondBot.HttpService [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")] + [ReturnHintsFailure("Error not in a sim")] + [ReturnHintsFailure("Parcel data not ready")] + [ReturnHintsFailure("Parcel not for sale")] + [ReturnHintsFailure("Parcel not for sale")] + [ReturnHintsFailure("Parcel sale locked to other avatars")] + [ReturnHintsFailure("Parcel sale price and amount do not match")] + [ReturnHintsFailure("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) @@ -458,8 +458,8 @@ namespace BetterSecondBot.HttpService [About("Freezes an avatar")] [ReturnHints("ok")] - [ReturnHints("Invaild avatar UUID")] - [ReturnHints("Invaild state")] + [ReturnHintsFailure("Invaild avatar UUID")] + [ReturnHintsFailure("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}")] @@ -484,9 +484,9 @@ namespace BetterSecondBot.HttpService [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("json object: GetParcelBanlistObject")] - [ReturnHints("Error not in a sim")] - [ReturnHints("Parcel data not ready")] + [ReturnHintsFailure("json object: GetParcelBanlistObject")] + [ReturnHintsFailure("Error not in a sim")] + [ReturnHintsFailure("Parcel data not ready")] [Route(HttpVerbs.Get, "/GetParcelBanlist/{token}")] public object GetParcelBanlist(string token) { @@ -531,8 +531,8 @@ namespace BetterSecondBot.HttpService [About("Returns a rezzed object")] [ReturnHints("ok")] - [ReturnHints("Invaild object uuid")] - [ReturnHints("Unable to find object")] + [ReturnHintsFailure("Invaild object uuid")] + [ReturnHintsFailure("Unable to find object")] [ArgHints("objectuuid", "URLARG", "object UUID to unrez")] [Route(HttpVerbs.Get, "/UnRezObject/{objectuuid}/{token}")] public object UnRezObject(string objectuuid,string token) @@ -574,8 +574,8 @@ namespace BetterSecondBot.HttpService "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")] + [ReturnHintsFailure("Error not in a sim")] + [ReturnHintsFailure("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) diff --git a/Core/Commands/Self.cs b/Core/Commands/Self.cs index 6a66104..f8a74d0 100644 --- a/Core/Commands/Self.cs +++ b/Core/Commands/Self.cs @@ -1,15 +1,12 @@ using BetterSecondBot.bottypes; -using BetterSecondBot.Static; using EmbedIO; using EmbedIO.Routing; using EmbedIO.WebApi; using System; using System.Collections.Generic; -using System.Text; using OpenMetaverse; -using Newtonsoft.Json; -using BetterSecondBotShared.Static; using System.Linq; +using BetterSecondBotShared.Static; namespace BetterSecondBot.HttpService { @@ -17,9 +14,22 @@ namespace BetterSecondBot.HttpService { public HTTP_Self(SecondBot mainbot, TokenStorage setuptokens) : base(mainbot, setuptokens) { } + [About("Makes the bot teleport to its home region")] + [ReturnHints("ok")] + [Route(HttpVerbs.Get, "/GoHome/{token}")] + public object GoHome(string token) + { + if (tokens.Allow(token, "self", "GoHome", handleGetClientIP()) == false) + { + return Failure("Token not accepted", "GoHome"); + } + bot.GotoNextHomeRegion(); + return BasicReply("ok", "GoHome"); + } + [About("Makes the bot turn to face avatar and point at them (if found)")] [ReturnHints("ok")] - [ReturnHints("Cant find UUID in sim")] + [ReturnHintsFailure("Cant find UUID in sim")] [Route(HttpVerbs.Get, "/PointAt/{avatar}/{token}")] public object PointAt(string avatar, string token) { @@ -44,7 +54,7 @@ namespace BetterSecondBot.HttpService [About("Reads a value from the KeyValue storage (temp unless SQL is enabled)")] [ReturnHints("value")] - [ReturnHints("Unknown Key: KeyName")] + [ReturnHintsFailure("Unknown Key: KeyName")] [ArgHints("Key", "URLARG", "the key we are trying to read from")] [Route(HttpVerbs.Get, "/ReadKeyValue/{Key}/{token}")] public object ReadKeyValue(string Key, string token) @@ -62,6 +72,8 @@ namespace BetterSecondBot.HttpService [About("sets a value for KeyValue storage (temp unless SQL is enabled)")] [ReturnHints("ok")] + [ReturnHintsFailure("Key is empty")] + [ReturnHintsFailure("Value is empty")] [ArgHints("Key", "URLARG", "the key we are trying to set")] [ArgHints("Value", "string", "the value we are tring to put on the key")] [Route(HttpVerbs.Post, "/SetKeyValue/{Key}/{token}")] @@ -69,7 +81,15 @@ namespace BetterSecondBot.HttpService { if (tokens.Allow(token, "self", "SetKeyValue", handleGetClientIP()) == false) { - return Failure("Token not accepted", "SetKeyValue", new[] { Key }); + return Failure("Token not accepted", "SetKeyValue", new[] { Key, Value }); + } + if (helpers.isempty(Key) == false) + { + return Failure("Key is empty", "SetKeyValue", new[] { Key, Value }); + } + if (helpers.isempty(Value) == false) + { + return Failure("Value is empty", "SetKeyValue", new[] { Key, Value }); } bot.setLocalKeyStorage(Key, Value); return BasicReply("ok", "SetKeyValue"); @@ -77,7 +97,7 @@ namespace BetterSecondBot.HttpService [About("Reads a value from the KeyValue storage (temp unless SQL is enabled)")] [ReturnHints("ok")] - [ReturnHints("Unknown Key: KeyName")] + [ReturnHintsFailure("Key is empty")] [ArgHints("Key", "URLARG", "the key we are trying to clear")] [Route(HttpVerbs.Get, "/ClearKeyValue/{Key}/{token}")] public object ClearKeyValue(string Key, string token) @@ -86,13 +106,17 @@ namespace BetterSecondBot.HttpService { return Failure("Token not accepted", "ClearKeyValue", new[] { Key }); } + if (helpers.isempty(Key) == false) + { + return Failure("Key is empty", "SetKeyValue", new[] { Key }); + } bot.clearLocalKeyStorage(Key); return BasicReply("ok", "SetKeyValue"); } [About("Makes the bot sit on the ground or on a object if it can see it")] [ReturnHints("ok")] - [ReturnHints("Invaild object UUID")] + [ReturnHintsFailure("Invaild object UUID")] [ArgHints("target", "URLARG", "ground or a object UUID")] [Route(HttpVerbs.Get, "/Sit/{target}/{token}")] public object Sit(string target, string token) @@ -130,8 +154,8 @@ namespace BetterSecondBot.HttpService [About("Makes the bot sit on the ground or on a object if it can see it")] [ReturnHints("true|false")] - [ReturnHints("Invaild object UUID")] - [ReturnHints("Unable to see object")] + [ReturnHintsFailure("Invaild object UUID")] + [ReturnHintsFailure("Unable to see object")] [ArgHints("target", "URLARG", "object UUID")] [Route(HttpVerbs.Get, "/ClickObject/{object}/{token}")] public object ClickObject(string target, string token) @@ -144,7 +168,11 @@ namespace BetterSecondBot.HttpService { return Failure("Invaild object UUID", "ClickObject", new [] { target }); } + + bot.GetClient.Self.PointAtEffect(bot.GetClient.Self.AgentID, objectuuid, new Vector3d(0, 0, 0), PointAtType.Select, new UUID("1df9eb92-62fa-15e5-4bfb-5931f1525274")); + Dictionary objectsentrys = bot.GetClient.Network.CurrentSim.ObjectsPrimitives.Copy(); + bool found_object = false; foreach (KeyValuePair entry in objectsentrys) { @@ -192,6 +220,8 @@ namespace BetterSecondBot.HttpService return BasicReply("ok", "Logout"); } + + [About("Makes the bot kill itself you monster - without making a sound")] [ReturnHints("ok")] [Route(HttpVerbs.Get, "/Bye/{token}")] @@ -222,10 +252,10 @@ namespace BetterSecondBot.HttpService } [About("Gets the last 5 commands issued to the bot")] - [ReturnHints("avatar lookup")] - [ReturnHints("Invaild state")] - [ReturnHints("Invaild sticky")] - [ReturnHints("Invaild flag")] + [ReturnHintsFailure("avatar lookup")] + [ReturnHintsFailure("Invaild state")] + [ReturnHintsFailure("Invaild sticky")] + [ReturnHintsFailure("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")] diff --git a/Core/Commands/StreamAdmin.cs b/Core/Commands/StreamAdmin.cs index bbfc9fb..63e1765 100644 --- a/Core/Commands/StreamAdmin.cs +++ b/Core/Commands/StreamAdmin.cs @@ -20,12 +20,12 @@ namespace BetterSecondBot.HttpService [About("A streamadin command")] [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")] + [ReturnHintsFailure("Bad reply: ...")] + [ReturnHintsFailure("Endpoint is empty")] + [ReturnHintsFailure("Endpointcode is empty")] + [ReturnHintsFailure("HTTP status code: ...")] + [ReturnHintsFailure("Error: ...")] + [ReturnHintsFailure("Notecard title is to short")] [ArgHints("endpoint","Text","The end point")] [ArgHints("endpointcode", "Text", "The end point code")] [Route(HttpVerbs.Post, "/FetchNextNotecard/{token}")] diff --git a/Core/Core.csproj b/Core/Core.csproj index 87a8ab2..91b62d6 100644 --- a/Core/Core.csproj +++ b/Core/Core.csproj @@ -6,11 +6,11 @@ - - + + - - + + diff --git a/Core/HttpService/HttpAsService.cs b/Core/HttpService/HttpAsService.cs index 469c036..9b6d731 100644 --- a/Core/HttpService/HttpAsService.cs +++ b/Core/HttpService/HttpAsService.cs @@ -184,8 +184,6 @@ namespace BetterSecondBot.HttpService .WithWebApi("/friends", m => m.WithController(() => new HTTP_Friends(Bot, Tokens))) .WithWebApi("/funds", m => m.WithController(() => new Http_Funds(Bot, Tokens))) .WithWebApi("/group", m => m.WithController(() => new HTTP_Group(Bot, Tokens))) - .WithWebApi("/home", m => m.WithController(() => new HTTP_Home(Bot, Tokens))) - .WithWebApi("/im", m => m.WithController(() => new HTTP_IM(Bot, Tokens))) .WithWebApi("/info", m => m.WithController(() => new HTTP_Info(Bot, Tokens))) .WithWebApi("/inventory", m => m.WithController(() => new HTTP_Inventory(Bot, Tokens))) .WithWebApi("/movement", m => m.WithController(() => new HTTP_Movement(Bot, Tokens))) @@ -226,12 +224,22 @@ namespace BetterSecondBot.HttpService public class ReturnHints : Attribute { public string hint = ""; + public bool good = true; public ReturnHints(string hint) { this.hint = hint; } } + [AttributeUsage(AttributeTargets.Method, AllowMultiple = true)] + public class ReturnHintsFailure : ReturnHints + { + public ReturnHintsFailure(string hint): base(hint) + { + this.good = false; + } + } + [AttributeUsage(AttributeTargets.Method, AllowMultiple = true)] public class ArgHints : Attribute { diff --git a/Core/Static/http_commands_helper.cs b/Core/Static/http_commands_helper.cs index 3479928..91b4969 100644 --- a/Core/Static/http_commands_helper.cs +++ b/Core/Static/http_commands_helper.cs @@ -20,8 +20,6 @@ namespace Core.Static reply.Add("friends", typeof(HTTP_Friends)); reply.Add("funds", typeof(Http_Funds)); reply.Add("group", typeof(HTTP_Group)); - reply.Add("home", typeof(HTTP_Home)); - reply.Add("im", typeof(HTTP_IM)); reply.Add("info", typeof(HTTP_Info)); reply.Add("inventory", typeof(HTTP_Inventory)); reply.Add("movement", typeof(HTTP_Movement)); diff --git a/LibreMetaverse/Assets/AssetTypes/AssetSound.cs b/LibreMetaverse/Assets/AssetTypes/AssetSound.cs index b5d3de4..00bbf60 100644 --- a/LibreMetaverse/Assets/AssetTypes/AssetSound.cs +++ b/LibreMetaverse/Assets/AssetTypes/AssetSound.cs @@ -25,7 +25,8 @@ */ using System; -using OpenMetaverse; +using System.IO; +using OggVorbisEncoder; namespace OpenMetaverse.Assets { @@ -51,12 +52,152 @@ namespace OpenMetaverse.Assets /// /// TODO: Encodes a sound file /// - public override void Encode() { } + bool encodedAudio = false; + public override void Encode() + { + if (encodedAudio == false) + { + encodedAudio = true; + AssetData = ConvertRawPCMFile(44100, 1, AssetData, PcmSample.SixteenBit, 44100, 2); + } + } /// /// TODO: Decode a sound file /// /// true public override bool Decode() { return true; } + + + private static byte[] ConvertRawPCMFile(int outputSampleRate, int outputChannels, byte[] pcmSamples, PcmSample pcmSampleSize, int pcmSampleRate, int pcmChannels) + { + int numPcmSamples = (pcmSamples.Length / (int)pcmSampleSize / pcmChannels); + float pcmDuraton = numPcmSamples / (float)pcmSampleRate; + + int numOutputSamples = (int)(pcmDuraton * outputSampleRate); + //Ensure that samble buffer is aligned to write chunk size + numOutputSamples = (numOutputSamples / WriteBufferSize) * WriteBufferSize; + + float[][] outSamples = new float[outputChannels][]; + + for (int ch = 0; ch < outputChannels; ch++) + { + outSamples[ch] = new float[numOutputSamples]; + } + + for (int sampleNumber = 0; sampleNumber < numOutputSamples; sampleNumber++) + { + float rawSample = 0.0f; + + for (int ch = 0; ch < outputChannels; ch++) + { + int sampleIndex = (sampleNumber * pcmChannels) * (int)pcmSampleSize; + + if (ch < pcmChannels) sampleIndex += (ch * (int)pcmSampleSize); + + switch (pcmSampleSize) + { + case PcmSample.EightBit: + rawSample = ByteToSample(pcmSamples[sampleIndex]); + break; + case PcmSample.SixteenBit: + rawSample = ShortToSample((short)(pcmSamples[sampleIndex + 1] << 8 | pcmSamples[sampleIndex])); + break; + } + + outSamples[ch][sampleNumber] = rawSample; + } + } + + return GenerateFile(outSamples, outputSampleRate, outputChannels); + } + + private static float ByteToSample(short pcmValue) + { + return pcmValue / 128f; + } + + private static float ShortToSample(short pcmValue) + { + return pcmValue / 32768f; + } + + private static readonly int WriteBufferSize = 512; + private static byte[] GenerateFile(float[][] floatSamples, int sampleRate, int channels) + { + using MemoryStream outputData = new MemoryStream(); + + // Stores all the static vorbis bitstream settings + var info = VorbisInfo.InitVariableBitRate(channels, sampleRate, 0.5f); + + // set up our packet->stream encoder + var serial = new Random().Next(); + var oggStream = new OggStream(serial); + + // ========================================================= + // HEADER + // ========================================================= + // Vorbis streams begin with three headers; the initial header (with + // most of the codec setup parameters) which is mandated by the Ogg + // bitstream spec. The second header holds any comment fields. The + // third header holds the bitstream codebook. + + var comments = new Comments(); + comments.AddTag("ARTIST", "TEST"); + + var infoPacket = HeaderPacketBuilder.BuildInfoPacket(info); + var commentsPacket = HeaderPacketBuilder.BuildCommentsPacket(comments); + var booksPacket = HeaderPacketBuilder.BuildBooksPacket(info); + + oggStream.PacketIn(infoPacket); + oggStream.PacketIn(commentsPacket); + oggStream.PacketIn(booksPacket); + + // Flush to force audio data onto its own page per the spec + FlushPages(oggStream, outputData, true); + + // ========================================================= + // BODY (Audio Data) + // ========================================================= + var processingState = ProcessingState.Create(info); + + for (int readIndex = 0; readIndex <= floatSamples[0].Length; readIndex += WriteBufferSize) + { + if (readIndex == floatSamples[0].Length) + { + processingState.WriteEndOfStream(); + } + else + { + processingState.WriteData(floatSamples, WriteBufferSize, readIndex); + } + + while (!oggStream.Finished && processingState.PacketOut(out OggPacket packet)) + { + oggStream.PacketIn(packet); + + FlushPages(oggStream, outputData, false); + } + } + + FlushPages(oggStream, outputData, true); + + return outputData.ToArray(); + } + + private static void FlushPages(OggStream oggStream, Stream output, bool force) + { + while (oggStream.PageOut(out OggPage page, force)) + { + output.Write(page.Header, 0, page.Header.Length); + output.Write(page.Body, 0, page.Body.Length); + } + } + + enum PcmSample : int + { + EightBit = 1, + SixteenBit = 2 + } } } diff --git a/LibreMetaverse/InventoryManager.cs b/LibreMetaverse/InventoryManager.cs index 0b74232..6abfb7b 100644 --- a/LibreMetaverse/InventoryManager.cs +++ b/LibreMetaverse/InventoryManager.cs @@ -1771,7 +1771,7 @@ namespace OpenMetaverse /// (EveryoneMask, GroupMask, and NextOwnerMask of Permissions struct are supported) /// Delegate that will receive feedback on success or failure public void RequestCreateItemFromAsset(byte[] data, string name, string description, AssetType assetType, - InventoryType invType, UUID folderID, Permissions permissions, ItemCreatedFromAssetCallback callback) + InventoryType invType, UUID folderID, Permissions permissions, ItemCreatedFromAssetCallback callback, int uploadCost=10) { if (Client.Network.CurrentSim == null || Client.Network.CurrentSim.Caps == null) throw new Exception("NewFileAgentInventory capability is not currently available"); @@ -1790,7 +1790,7 @@ namespace OpenMetaverse {"everyone_mask", OSD.FromInteger((int) permissions.EveryoneMask)}, {"group_mask", OSD.FromInteger((int) permissions.GroupMask)}, {"next_owner_mask", OSD.FromInteger((int) permissions.NextOwnerMask)}, - {"expected_upload_cost", OSD.FromInteger(Client.Settings.UPLOAD_COST)} + {"expected_upload_cost", uploadCost} }; // Make the request diff --git a/LibreMetaverse/LibreMetaverse.csproj b/LibreMetaverse/LibreMetaverse.csproj index 2031524..6205789 100644 --- a/LibreMetaverse/LibreMetaverse.csproj +++ b/LibreMetaverse/LibreMetaverse.csproj @@ -63,6 +63,7 @@ + diff --git a/LibreMetaverse/Settings.cs b/LibreMetaverse/Settings.cs index d1a2613..b3e9945 100644 --- a/LibreMetaverse/Settings.cs +++ b/LibreMetaverse/Settings.cs @@ -362,7 +362,7 @@ namespace OpenMetaverse #region Private Fields private GridClient Client; - private int priceUpload = 0; + private int priceUpload = 10; public static bool SORT_INVENTORY = false; /// Constructor diff --git a/Shared/Shared.csproj b/Shared/Shared.csproj index 9314555..ba8fe1d 100644 --- a/Shared/Shared.csproj +++ b/Shared/Shared.csproj @@ -6,7 +6,7 @@ - + diff --git a/Shared/Staic/Helpers.cs b/Shared/Static/Helpers.cs similarity index 99% rename from Shared/Staic/Helpers.cs rename to Shared/Static/Helpers.cs index a034397..cb6608f 100644 --- a/Shared/Staic/Helpers.cs +++ b/Shared/Static/Helpers.cs @@ -184,15 +184,15 @@ 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); + foreach(KeyValuePair e in entrys) + { + items.Add(e.Key); + items.Add(e.Value); } return create_dirty_table(items.ToArray(), 2); } diff --git a/Shared/Staic/LogFormater.cs b/Shared/Static/LogFormater.cs similarity index 100% rename from Shared/Staic/LogFormater.cs rename to Shared/Static/LogFormater.cs