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