Core update and HTTP updates, plus some new core commands

Core commands
Friendslist
DeleteInventory
getRealUUID
RenameInventory

fixed: sendItem
This commit is contained in:
Madpeterz 2021-02-02 23:20:04 +00:00
parent e3bb28ff8e
commit bf20250b8f
58 changed files with 1447 additions and 445 deletions

View file

@ -15,8 +15,8 @@
<ItemGroup> <ItemGroup>
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" /> <PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\libremetaverse-core\Libremetaverse\LibreMetaverse-core.csproj" /> <ProjectReference Include="..\libremetaverse-core\LibreMetaverse\LibreMetaverse.csproj" />
</ItemGroup> </ItemGroup>
</Project> </Project>

View file

@ -10,12 +10,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BSBshared", "BSBshared\BSBs
EndProject EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Libmeta-core", "Libmeta-core", "{7538B15D-152B-4A0F-A24D-A89EDC382564}" Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Libmeta-core", "Libmeta-core", "{7538B15D-152B-4A0F-A24D-A89EDC382564}"
EndProject EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LibreMetaverse-core.Types", "libremetaverse-core\Libremetaverse.types\LibreMetaverse-core.Types.csproj", "{EF718593-1FC7-433A-8495-5B1A7106CAF3}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LibreMetaverse-core.StructuredData", "libremetaverse-core\Libremetaverse.structureddata\LibreMetaverse-core.StructuredData.csproj", "{3928AB19-219D-4284-BFE9-6C0E779F98A3}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LibreMetaverse-core", "libremetaverse-core\Libremetaverse\LibreMetaverse-core.csproj", "{97198293-1B92-4FD2-811E-AE1F33D4B2B2}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{B861AB1B-8F09-41A9-8817-CB8A2E961E4C}" Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{B861AB1B-8F09-41A9-8817-CB8A2E961E4C}"
ProjectSection(SolutionItems) = preProject ProjectSection(SolutionItems) = preProject
Dockerfile = Dockerfile Dockerfile = Dockerfile
@ -23,6 +17,12 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
README.md = README.md README.md = README.md
EndProjectSection EndProjectSection
EndProject EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LibreMetaverse", "libremetaverse-core\LibreMetaverse\LibreMetaverse.csproj", "{27C70F3A-0000-0000-0000-000000000000}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LibreMetaverse.StructuredData", "libremetaverse-core\LibreMetaverse.StructuredData\LibreMetaverse.StructuredData.csproj", "{89D7A3E5-0000-0000-0000-000000000000}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LibreMetaverse.Types", "libremetaverse-core\LibreMetaverseTypes\LibreMetaverse.Types.csproj", "{B37B02AD-0000-0000-0000-000000000000}"
EndProject
Global Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU Debug|Any CPU = Debug|Any CPU
@ -66,41 +66,50 @@ Global
{42075C8C-8055-4178-8C12-AE97DAFE8484}.Release|Any CPU.ActiveCfg = Release|x64 {42075C8C-8055-4178-8C12-AE97DAFE8484}.Release|Any CPU.ActiveCfg = Release|x64
{42075C8C-8055-4178-8C12-AE97DAFE8484}.Release|x64.ActiveCfg = Release|x64 {42075C8C-8055-4178-8C12-AE97DAFE8484}.Release|x64.ActiveCfg = Release|x64
{42075C8C-8055-4178-8C12-AE97DAFE8484}.Release|x64.Build.0 = Release|x64 {42075C8C-8055-4178-8C12-AE97DAFE8484}.Release|x64.Build.0 = Release|x64
{EF718593-1FC7-433A-8495-5B1A7106CAF3}.Debug|Any CPU.ActiveCfg = Debug|x64 {27C70F3A-0000-0000-0000-000000000000}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{EF718593-1FC7-433A-8495-5B1A7106CAF3}.Debug|x64.ActiveCfg = Debug|x64 {27C70F3A-0000-0000-0000-000000000000}.Debug|Any CPU.Build.0 = Debug|Any CPU
{EF718593-1FC7-433A-8495-5B1A7106CAF3}.Debug|x64.Build.0 = Debug|x64 {27C70F3A-0000-0000-0000-000000000000}.Debug|x64.ActiveCfg = Debug|Any CPU
{EF718593-1FC7-433A-8495-5B1A7106CAF3}.DockerBuild|Any CPU.ActiveCfg = DockerBuild|x64 {27C70F3A-0000-0000-0000-000000000000}.Debug|x64.Build.0 = Debug|Any CPU
{EF718593-1FC7-433A-8495-5B1A7106CAF3}.DockerBuild|x64.ActiveCfg = DockerBuild|x64 {27C70F3A-0000-0000-0000-000000000000}.DockerBuild|Any CPU.ActiveCfg = Debug|Any CPU
{EF718593-1FC7-433A-8495-5B1A7106CAF3}.DockerBuild|x64.Build.0 = DockerBuild|x64 {27C70F3A-0000-0000-0000-000000000000}.DockerBuild|Any CPU.Build.0 = Debug|Any CPU
{EF718593-1FC7-433A-8495-5B1A7106CAF3}.Release|Any CPU.ActiveCfg = Release|x64 {27C70F3A-0000-0000-0000-000000000000}.DockerBuild|x64.ActiveCfg = Debug|Any CPU
{EF718593-1FC7-433A-8495-5B1A7106CAF3}.Release|x64.ActiveCfg = Release|x64 {27C70F3A-0000-0000-0000-000000000000}.DockerBuild|x64.Build.0 = Debug|Any CPU
{EF718593-1FC7-433A-8495-5B1A7106CAF3}.Release|x64.Build.0 = Release|x64 {27C70F3A-0000-0000-0000-000000000000}.Release|Any CPU.ActiveCfg = Release|Any CPU
{3928AB19-219D-4284-BFE9-6C0E779F98A3}.Debug|Any CPU.ActiveCfg = Debug|x64 {27C70F3A-0000-0000-0000-000000000000}.Release|Any CPU.Build.0 = Release|Any CPU
{3928AB19-219D-4284-BFE9-6C0E779F98A3}.Debug|x64.ActiveCfg = Debug|x64 {27C70F3A-0000-0000-0000-000000000000}.Release|x64.ActiveCfg = Release|Any CPU
{3928AB19-219D-4284-BFE9-6C0E779F98A3}.Debug|x64.Build.0 = Debug|x64 {27C70F3A-0000-0000-0000-000000000000}.Release|x64.Build.0 = Release|Any CPU
{3928AB19-219D-4284-BFE9-6C0E779F98A3}.DockerBuild|Any CPU.ActiveCfg = DockerBuild|x64 {89D7A3E5-0000-0000-0000-000000000000}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{3928AB19-219D-4284-BFE9-6C0E779F98A3}.DockerBuild|x64.ActiveCfg = DockerBuild|x64 {89D7A3E5-0000-0000-0000-000000000000}.Debug|Any CPU.Build.0 = Debug|Any CPU
{3928AB19-219D-4284-BFE9-6C0E779F98A3}.DockerBuild|x64.Build.0 = DockerBuild|x64 {89D7A3E5-0000-0000-0000-000000000000}.Debug|x64.ActiveCfg = Debug|Any CPU
{3928AB19-219D-4284-BFE9-6C0E779F98A3}.Release|Any CPU.ActiveCfg = Release|x64 {89D7A3E5-0000-0000-0000-000000000000}.Debug|x64.Build.0 = Debug|Any CPU
{3928AB19-219D-4284-BFE9-6C0E779F98A3}.Release|x64.ActiveCfg = Release|x64 {89D7A3E5-0000-0000-0000-000000000000}.DockerBuild|Any CPU.ActiveCfg = Debug|Any CPU
{3928AB19-219D-4284-BFE9-6C0E779F98A3}.Release|x64.Build.0 = Release|x64 {89D7A3E5-0000-0000-0000-000000000000}.DockerBuild|Any CPU.Build.0 = Debug|Any CPU
{97198293-1B92-4FD2-811E-AE1F33D4B2B2}.Debug|Any CPU.ActiveCfg = Debug|x64 {89D7A3E5-0000-0000-0000-000000000000}.DockerBuild|x64.ActiveCfg = Debug|Any CPU
{97198293-1B92-4FD2-811E-AE1F33D4B2B2}.Debug|x64.ActiveCfg = Debug|x64 {89D7A3E5-0000-0000-0000-000000000000}.DockerBuild|x64.Build.0 = Debug|Any CPU
{97198293-1B92-4FD2-811E-AE1F33D4B2B2}.Debug|x64.Build.0 = Debug|x64 {89D7A3E5-0000-0000-0000-000000000000}.Release|Any CPU.ActiveCfg = Release|Any CPU
{97198293-1B92-4FD2-811E-AE1F33D4B2B2}.DockerBuild|Any CPU.ActiveCfg = DockerBuild|x64 {89D7A3E5-0000-0000-0000-000000000000}.Release|Any CPU.Build.0 = Release|Any CPU
{97198293-1B92-4FD2-811E-AE1F33D4B2B2}.DockerBuild|x64.ActiveCfg = DockerBuild|x64 {89D7A3E5-0000-0000-0000-000000000000}.Release|x64.ActiveCfg = Release|Any CPU
{97198293-1B92-4FD2-811E-AE1F33D4B2B2}.DockerBuild|x64.Build.0 = DockerBuild|x64 {89D7A3E5-0000-0000-0000-000000000000}.Release|x64.Build.0 = Release|Any CPU
{97198293-1B92-4FD2-811E-AE1F33D4B2B2}.Release|Any CPU.ActiveCfg = Release|x64 {B37B02AD-0000-0000-0000-000000000000}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{97198293-1B92-4FD2-811E-AE1F33D4B2B2}.Release|x64.ActiveCfg = Release|x64 {B37B02AD-0000-0000-0000-000000000000}.Debug|Any CPU.Build.0 = Debug|Any CPU
{97198293-1B92-4FD2-811E-AE1F33D4B2B2}.Release|x64.Build.0 = Release|x64 {B37B02AD-0000-0000-0000-000000000000}.Debug|x64.ActiveCfg = Debug|Any CPU
{B37B02AD-0000-0000-0000-000000000000}.Debug|x64.Build.0 = Debug|Any CPU
{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|Any CPU
{B37B02AD-0000-0000-0000-000000000000}.DockerBuild|x64.Build.0 = Debug|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
{B37B02AD-0000-0000-0000-000000000000}.Release|x64.ActiveCfg = Release|Any CPU
{B37B02AD-0000-0000-0000-000000000000}.Release|x64.Build.0 = Release|Any CPU
EndGlobalSection EndGlobalSection
GlobalSection(SolutionProperties) = preSolution GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE HideSolutionNode = FALSE
EndGlobalSection EndGlobalSection
GlobalSection(NestedProjects) = preSolution GlobalSection(NestedProjects) = preSolution
{EF718593-1FC7-433A-8495-5B1A7106CAF3} = {7538B15D-152B-4A0F-A24D-A89EDC382564} {27C70F3A-0000-0000-0000-000000000000} = {7538B15D-152B-4A0F-A24D-A89EDC382564}
{3928AB19-219D-4284-BFE9-6C0E779F98A3} = {7538B15D-152B-4A0F-A24D-A89EDC382564} {89D7A3E5-0000-0000-0000-000000000000} = {7538B15D-152B-4A0F-A24D-A89EDC382564}
{97198293-1B92-4FD2-811E-AE1F33D4B2B2} = {7538B15D-152B-4A0F-A24D-A89EDC382564} {B37B02AD-0000-0000-0000-000000000000} = {7538B15D-152B-4A0F-A24D-A89EDC382564}
EndGlobalSection EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {39A7E333-AFC1-4BA8-9EBC-9298791FDC78} SolutionGuid = {39A7E333-AFC1-4BA8-9EBC-9298791FDC78}

View file

@ -51,7 +51,10 @@ namespace BetterSecondBot
SecondBotHttpServer my_http_server = new SecondBotHttpServer(); SecondBotHttpServer my_http_server = new SecondBotHttpServer();
my_http_server.StartHttpServer(Bot, Config); my_http_server.StartHttpServer(Bot, Config);
*/ */
new HttpAsService(Bot, Config); new Thread(() =>
{
new HttpAsService(Bot, Config);
}).Start();
} }
if(use_self_keep_alive == true) if(use_self_keep_alive == true)
{ {

42
CLI/HttpService/Chat.cs Normal file
View file

@ -0,0 +1,42 @@
using BSB.bottypes;
using BSB.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 SecondbotChat : WebApiControllerWithTokens
{
public SecondbotChat(SecondBot mainbot, TokenStorage setuptokens) : base(mainbot, setuptokens) { }
[Route(HttpVerbs.Get, "/localchathistory/{token}")]
public object localchatHistory(string token)
{
if (tokens.Allow(token, getClientIP()) == true)
{
return BasicReply(JsonConvert.SerializeObject(bot.getLocalChatHistory()));
}
return BasicReply("Token not accepted");
}
[Route(HttpVerbs.Post, "/localchatsay/{token}")]
public object localchatSay(string token, [FormField] string message)
{
if (tokens.Allow(token, getClientIP()) == true)
{
bot.GetCommandsInterface.Call("say", message);
return BasicReply(JsonConvert.SerializeObject(bot.getLocalChatHistory()));
}
return BasicReply("Token not accepted");
}
}
}

84
CLI/HttpService/Group.cs Normal file
View file

@ -0,0 +1,84 @@
using BSB.bottypes;
using BSB.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 SecondbotGroup : WebApiControllerWithTokens
{
public SecondbotGroup(SecondBot mainbot, TokenStorage setuptokens) : base(mainbot, setuptokens) { }
[Route(HttpVerbs.Get, "/listgroups/{token}")]
public object listgroups(string token)
{
if (tokens.Allow(token, getClientIP()) == true)
{
Dictionary<string, string> grouppackage = new Dictionary<string, string>();
foreach(KeyValuePair<UUID,Group> entry in bot.MyGroups)
{
grouppackage.Add(entry.Value.ID.ToString(), entry.Value.Name);
}
return BasicReply(JsonConvert.SerializeObject(grouppackage));
}
return BasicReply("Token not accepted");
}
[Route(HttpVerbs.Get, "/listgroupswithunread/{token}")]
public object listgroupswithunread(string group, string token)
{
if (tokens.Allow(token, getClientIP()) == true)
{
return BasicReply(JsonConvert.SerializeObject(bot.UnreadGroupchatGroups()));
}
return BasicReply("Token not accepted");
}
[Route(HttpVerbs.Get, "/haveunreadgroupchat/{token}")]
public object haveunreadgroupchat(string token)
{
if (tokens.Allow(token, getClientIP()) == true)
{
return BasicReply(bot.HasUnreadGroupchats().ToString());
}
return BasicReply("Token not accepted");
}
[Route(HttpVerbs.Get, "/getgroupchat/{group}/{token}")]
public object getgroupchat(string group, string token)
{
if (tokens.Allow(token, getClientIP()) == true)
{
if (UUID.TryParse(group, out UUID groupUUID) == true)
{
return BasicReply(JsonConvert.SerializeObject(bot.GetGroupchat(groupUUID)));
}
return BasicReply("Group UUID invaild");
}
return BasicReply("Token not accepted");
}
[Route(HttpVerbs.Post, "/sendgroupchat/{group}/{token}")]
public object sendgroupchat(string group, string token, [FormField] string message)
{
if (tokens.Allow(token, getClientIP()) == true)
{
if (UUID.TryParse(group, out UUID groupUUID) == true)
{
bool status = bot.GetCommandsInterface.Call("Groupchat", group + "~#~" + message, UUID.Zero, "~#~");
return BasicReply("Processing");
}
return BasicReply("Group UUID invaild");
}
return BasicReply("Token not accepted");
}
}
}

View file

@ -32,7 +32,7 @@ namespace BetterSecondBot.HttpService
server.RunAsync(); server.RunAsync();
while(Bot.KillMe == false) while(Bot.KillMe == false)
{ {
Thread.Sleep(1000); Thread.Sleep(3000);
} }
} }
} }
@ -43,14 +43,26 @@ namespace BetterSecondBot.HttpService
var server = new WebServer(o => o var server = new WebServer(o => o
.WithUrlPrefix(url) .WithUrlPrefix(url)
.WithMode(HttpListenerMode.EmbedIO)) .WithMode(HttpListenerMode.EmbedIO))
.WithIPBanning(o => o .WithCors()
.WithMaxRequestsPerSecond(10) //.WithIPBanning(o => o
.WithRegexRules("HTTP exception 404") // .WithMaxRequestsPerSecond(30)
) // .WithRegexRules("HTTP exception 404")
//)
.WithWebApi("/inventory", m => m .WithWebApi("/inventory", m => m
.WithController(() => new SecondbotInventory(Bot, Tokens))) .WithController(() => new SecondbotInventory(Bot, Tokens))
)
.WithWebApi("/chat", m => m
.WithController(() => new SecondbotChat(Bot, Tokens))
)
.WithWebApi("/groups", m => m
.WithController(() => new SecondbotGroup(Bot, Tokens))
)
.WithWebApi("/ims", m => m
.WithController(() => new SecondbotIm(Bot, Tokens))
)
.WithWebApi("/core", m => m .WithWebApi("/core", m => m
.WithController(() => new SecondbotCoreWebAPi(Config, Bot, Tokens))) .WithController(() => new SecondbotCoreWebAPi(Config, Bot, Tokens)))
.WithModule(new ActionModule("/", HttpVerbs.Any, ctx => ctx.SendDataAsync(new { Message = "Error" }))); .WithModule(new ActionModule("/", HttpVerbs.Any, ctx => ctx.SendDataAsync(new { Message = "Error" })));
return server; return server;
} }
@ -100,7 +112,7 @@ namespace BetterSecondBot.HttpService
PurgeExpired(); PurgeExpired();
return false; return false;
} }
if (info.IP == IPaddress) if (IPaddress.Equals(info.IP) == true)
{ {
return true; return true;
} }
@ -110,21 +122,27 @@ namespace BetterSecondBot.HttpService
public string CreateToken(IPAddress IP) public string CreateToken(IPAddress IP)
{ {
PurgeExpired(); if (IP != null)
bool used = true;
string last = "";
while(used == true)
{ {
last = helpers.GetSHA1(last + helpers.UnixTimeNow() + new Random().Next(13256).ToString()).Substring(0, 10); PurgeExpired();
used = tokens.ContainsKey(last); bool used = true;
if (used == false) string last = "";
while (used == true)
{ {
tokenInfo Info = new tokenInfo(); last = helpers.GetSHA1(last + helpers.UnixTimeNow() + new Random().Next(13256).ToString()).Substring(0, 10);
Info.IP = IP; used = tokens.ContainsKey(last);
Info.Expires = helpers.UnixTimeNow() + (60 * 10); if (used == false)
{
tokenInfo Info = new tokenInfo();
Info.IP = IP;
Info.Expires = helpers.UnixTimeNow() + (60 * 10);
tokens.Add(last, Info);
break;
}
} }
return last;
} }
return last; return null;
} }
} }
@ -132,7 +150,11 @@ namespace BetterSecondBot.HttpService
{ {
protected TokenStorage tokens; protected TokenStorage tokens;
protected SecondBot bot; protected SecondBot bot;
protected Object BasicReply(string input)
{
return new { reply = input };
}
public WebApiControllerWithTokens(SecondBot mainbot, TokenStorage setuptokens) public WebApiControllerWithTokens(SecondBot mainbot, TokenStorage setuptokens)
{ {
bot = mainbot; bot = mainbot;

92
CLI/HttpService/Im.cs Normal file
View file

@ -0,0 +1,92 @@
using BSB.bottypes;
using BSB.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 SecondbotIm : WebApiControllerWithTokens
{
public SecondbotIm(SecondBot mainbot, TokenStorage setuptokens) : base(mainbot, setuptokens) { }
[Route(HttpVerbs.Get, "/chatwindows/{token}")]
public object chatwindows(string token)
{
if (tokens.Allow(token, getClientIP()) == true)
{
return BasicReply(JsonConvert.SerializeObject(bot.GetIMChatWindowKeyNames()));
}
return BasicReply("Token not accepted");
}
[Route(HttpVerbs.Get, "/listwithunread/{token}")]
public object listwithunread(string group, string token)
{
if (tokens.Allow(token, getClientIP()) == true)
{
List<UUID> unreadimwindows = new List<UUID>();
foreach (UUID window in bot.IMChatWindows())
{
if (bot.ImChatWindowHasUnread(window) == true)
{
unreadimwindows.Add(window);
}
}
return BasicReply(JsonConvert.SerializeObject(unreadimwindows));
}
return BasicReply("Token not accepted");
}
[Route(HttpVerbs.Get, "/haveunreadims/{token}")]
public object haveunreadims(string token)
{
if (tokens.Allow(token, getClientIP()) == true)
{
bool reply = false;
foreach(UUID window in bot.IMChatWindows())
{
if(bot.ImChatWindowHasUnread(window) == true)
{
reply = true;
break;
}
}
return BasicReply(reply.ToString());
}
return BasicReply("Token not accepted");
}
[Route(HttpVerbs.Get, "/getimchat/{window}/{token}")]
public object getimchat(string window, string token)
{
if (tokens.Allow(token, getClientIP()) == true)
{
if (UUID.TryParse(window, out UUID windowUUID) == true)
{
return BasicReply(JsonConvert.SerializeObject(bot.GetIMChatWindow(windowUUID)));
}
return BasicReply("Window UUID invaild");
}
return BasicReply("Token not accepted");
}
[Route(HttpVerbs.Post, "/sendimchat/{avatar}/{token}")]
public object sendgroupchat(string avatar, string token, [FormField] string message)
{
if (tokens.Allow(token, getClientIP()) == true)
{
bot.GetCommandsInterface.Call("im", avatar + "~#~" + message, UUID.Zero, "~#~");
return BasicReply("ok");
}
return BasicReply("Token not accepted");
}
}
}

View file

@ -14,30 +14,100 @@ namespace BetterSecondBot.HttpService
{ {
public SecondbotInventory(SecondBot mainbot, TokenStorage setuptokens) : base(mainbot, setuptokens) { } public SecondbotInventory(SecondBot mainbot, TokenStorage setuptokens) : base(mainbot, setuptokens) { }
[Route(HttpVerbs.Post, "/rename/{item}/{token}")]
public object rename(string item, string token, [FormField] string newname)
{
if (tokens.Allow(token, getClientIP()) == true)
{
bool status = bot.GetCommandsInterface.Call("RenameInventory", "12~#~" + item + "~#~" + newname);
return BasicReply(status.ToString());
}
return BasicReply("Token not accepted");
}
[Route(HttpVerbs.Get, "/realuuid/{item}/{token}")]
public object realuuid(string item, string token)
{
if (tokens.Allow(token, getClientIP()) == true)
{
if (UUID.TryParse(item, out UUID itemUUID) == true)
{
UUID reply = HelperInventory.GetAssetUUID(bot, itemUUID);
if (reply != UUID.Zero)
{
return BasicReply(reply.ToString());
}
}
return BasicReply("Failed");
}
return BasicReply("Token not accepted");
}
[Route(HttpVerbs.Get, "/send/{item}/{avatar}/{token}")]
public object send(string item, string avatar, string token)
{
if (tokens.Allow(token, getClientIP()) == true)
{
if (UUID.TryParse(item, out UUID itemUUID) == true)
{
bool status = bot.GetCommandsInterface.Call("SendItem", avatar+"~#~"+item);
return BasicReply(status.ToString());
}
return BasicReply("Failed - item must be a vaild UUID");
}
return BasicReply("Token not accepted");
}
[Route(HttpVerbs.Get, "/delete/{item}/{isfolder}/{token}")]
public object delete(string item,string isfolder, string token)
{
if (tokens.Allow(token, getClientIP()) == true)
{
if (UUID.TryParse(item, out UUID itemUUID) == true)
{
if (bool.TryParse(isfolder, out bool asfolder) == true)
{
bool status = false;
if (asfolder == true) status = bot.GetCommandsInterface.Call("DeleteInventoryFolder", item);
else status = bot.GetCommandsInterface.Call("DeleteInventoryItem", item);
return BasicReply(status.ToString());
}
return BasicReply("Failed - isfolder must be True or False");
}
return BasicReply("Failed - item must be a vaild UUID");
}
return BasicReply("Token not accepted");
}
[Route(HttpVerbs.Get, "/folders/{token}")] [Route(HttpVerbs.Get, "/folders/{token}")]
public string folders(string token) public object folders(string token)
{ {
if(tokens.Allow(token, getClientIP()) == true) if(tokens.Allow(token, getClientIP()) == true)
{ {
return HelperInventory.MapFolderJson(bot); string reply = HelperInventory.MapFolderJson(bot);
if(reply != null) return BasicReply(reply);
return BasicReply("error");
} }
return "Token not accepted"; return BasicReply("Token not accepted");
} }
[Route(HttpVerbs.Get, "/contents/{folderUUID}/{token}")] [Route(HttpVerbs.Get, "/contents/{folderUUID}/{token}")]
public string Contents(string folderUUID, string token) public object Contents(string folderUUID, string token)
{ {
if (tokens.Allow(token, getClientIP()) == true) if (tokens.Allow(token, getClientIP()) == true)
{ {
if (UUID.TryParse(folderUUID, out UUID folder) == true) if (UUID.TryParse(folderUUID, out UUID folder) == true)
{ {
return HelperInventory.MapFolderInventoryJson(bot, folder); return BasicReply(HelperInventory.MapFolderInventoryJson(bot, folder));
} }
return "Invaild folder UUID"; return BasicReply("Invaild folder UUID");
} }
return "Token not accepted"; return BasicReply("Token not accepted");
} }
} }

View file

@ -3,14 +3,16 @@ using BetterSecondBotShared.Static;
using BSB.bottypes; using BSB.bottypes;
using OpenMetaverse; using OpenMetaverse;
using System.Threading.Tasks; using System.Threading.Tasks;
using EmbedIO; using EmbedIO;
using EmbedIO.Routing; using EmbedIO.Routing;
using EmbedIO.WebApi; using EmbedIO.WebApi;
using System;
using System.Collections.Generic;
using Newtonsoft.Json;
namespace BetterSecondBot.HttpService namespace BetterSecondBot.HttpService
{ {
public class SecondbotCoreWebAPi : WebApiControllerWithTokens public class SecondbotCoreWebAPi : WebApiControllerWithTokens
{ {
@ -21,61 +23,92 @@ namespace BetterSecondBot.HttpService
} }
[Route(HttpVerbs.Post, "/gettoken")] [Route(HttpVerbs.Post, "/gettoken")]
public string GetToken([FormField] string authcode) public Object GetToken([FormField] string authcode, [FormField] string unixtimegiven)
{ {
long now = helpers.UnixTimeNow() + 120; long now = helpers.UnixTimeNow();
int loop = 0; long dif = 0;
bool accepted = false; if(long.TryParse(unixtimegiven,out long given) == true)
while(loop <= 30)
{ {
string hashA = helpers.GetSHA1((now + loop) + "" + config.Security_WebUIKey).Substring(0, 10); dif = now - given;
string hashB = helpers.GetSHA1((now - loop) + "" + config.Security_WebUIKey).Substring(0, 10); now = given;
if ((authcode == hashA) || (authcode == hashB)) }
if((dif < 30) && (dif > -30))
{
var raw = now.ToString() + config.Security_WebUIKey;
string hash = helpers.GetSHA1(raw).Substring(0, 10);
if (hash == authcode)
{ {
accepted = true; string newtoken = tokens.CreateToken(getClientIP());
break; if(newtoken != null) return BasicReply(newtoken);
} }
loop++;
} }
if(accepted == true) return BasicReply("Authcode not accepted");
}
[Route(HttpVerbs.Get, "/friends/{token}")]
public object friends(string token)
{
return BasicReply(bot.getJsonFriendlist());
}
[Route(HttpVerbs.Get, "/nearme/{token}")]
public object nearme(string token)
{
if (bot.GetClient.Network.CurrentSim != null)
{ {
return tokens.CreateToken(HttpContext.Request.RemoteEndPoint.Address); Dictionary<UUID, string> NearMe = new Dictionary<UUID, string>();
Dictionary<uint, Avatar> avcopy = bot.GetClient.Network.CurrentSim.ObjectsAvatars.Copy();
foreach (Avatar av in avcopy.Values)
{
if (av.ID != bot.GetClient.Self.AgentID)
{
NearMe.Add(av.ID, av.Name);
}
}
return BasicReply(JsonConvert.SerializeObject(NearMe));
} }
return "Authcode not accepted"; return BasicReply("Error");
}
[Route(HttpVerbs.Get, "/hello")]
public object Hello()
{
return BasicReply("world");
} }
[Route(HttpVerbs.Get, "/logout/{token}")] [Route(HttpVerbs.Get, "/logout/{token}")]
public string Logout(string token) public object Logout(string token)
{ {
if (tokens.Allow(token, getClientIP()) == true) if (tokens.Allow(token, getClientIP()) == true)
{ {
return tokens.Expire(token); return tokens.Expire(token);
} }
return "Token not accepted"; return BasicReply("Token not accepted");
} }
[Route(HttpVerbs.Get, "/version/{token}")] [Route(HttpVerbs.Get, "/version/{token}")]
public string Version(string token) public object Version(string token)
{ {
if (tokens.Allow(token, getClientIP()) == true) if (tokens.Allow(token, getClientIP()) == true)
{ {
return bot.MyVersion; return BasicReply(bot.MyVersion);
} }
return "Token not accepted"; return BasicReply("Token not accepted");
} }
[Route(HttpVerbs.Get, "/name/{token}")] [Route(HttpVerbs.Get, "/name/{token}")]
public string Name(string token) public object Name(string token)
{ {
if (tokens.Allow(token, getClientIP()) == true) if (tokens.Allow(token, getClientIP()) == true)
{ {
return bot.GetClient.Self.FirstName + " " + bot.GetClient.Self.LastName; return BasicReply(bot.GetClient.Self.FirstName + " " + bot.GetClient.Self.LastName);
} }
return "Token not accepted"; return BasicReply("Token not accepted");
} }
[Route(HttpVerbs.Post, "/command/{token}")] [Route(HttpVerbs.Post, "/command/{token}")]
public async Task<string> command(string token) public async Task<object> command(string token)
{ {
if (tokens.Allow(token, getClientIP()) == true) if (tokens.Allow(token, getClientIP()) == true)
{ {
@ -88,11 +121,11 @@ namespace BetterSecondBot.HttpService
bool status = bot.GetCommandsInterface.Call(data.Command, compressedArgs, UUID.Zero, "~#~"); bool status = bot.GetCommandsInterface.Call(data.Command, compressedArgs, UUID.Zero, "~#~");
if (status == true) if (status == true)
{ {
return "accepted"; return BasicReply("accepted");
} }
} }
} }
return "Token not accepted"; return BasicReply("Token not accepted");
} }
} }

View file

@ -496,12 +496,40 @@ namespace BetterSecondBot.WikiMake
core.callable.Add(new version()); core.callable.Add(new version());
core.callable.Add(new name()); core.callable.Add(new name());
core.callable.Add(new command()); core.callable.Add(new command());
core.callable.Add(new friends());
core.callable.Add(new nearme());
core.callable.Add(new hello());
endpoints.Add(core); endpoints.Add(core);
Endpoint inventory = new Endpoint(); Endpoint inventory = new Endpoint();
inventory.name = "inventory"; inventory.name = "inventory";
inventory.callable.Add(new contents()); inventory.callable.Add(new contents());
inventory.callable.Add(new folders()); inventory.callable.Add(new folders());
inventory.callable.Add(new rename());
inventory.callable.Add(new realuuid());
inventory.callable.Add(new send());
inventory.callable.Add(new delete());
endpoints.Add(inventory); endpoints.Add(inventory);
Endpoint im = new Endpoint();
im.name = "im";
im.callable.Add(new chatwindows());
im.callable.Add(new listwithunread());
im.callable.Add(new haveunreadims());
im.callable.Add(new getimchat());
im.callable.Add(new sendimchat());
endpoints.Add(im);
Endpoint group = new Endpoint();
group.name = "group";
group.callable.Add(new listgroups());
group.callable.Add(new listgroupswithunread());
group.callable.Add(new haveunreadgroupchat());
group.callable.Add(new getgroupchat());
group.callable.Add(new sendgroupchat());
endpoints.Add(group);
Endpoint chat = new Endpoint();
chat.name = "chat";
chat.callable.Add(new localchathistory());
chat.callable.Add(new localchatsay());
endpoints.Add(chat);
} }
public string getCommandMethod(string endpoint, string command) public string getCommandMethod(string endpoint, string command)
@ -726,6 +754,37 @@ namespace BetterSecondBot.WikiMake
} }
} }
public class friends : APIcall
{
public override void Setup()
{
about = "Gets the friendslist <br/>Formated as follows<br/>friendreplyobject<br/><ul><li>name: String</li><li>id: String</li><li>online: bool</li></ul>";
returns.Add("array UUID = friendreplyobject");
base.Setup();
}
}
public class nearme : APIcall
{
public override void Setup()
{
about = "returns a list of all known avatars near (same sim)>";
returns.Add("array UUID = Name");
base.Setup();
}
}
public class hello : APIcall
{
public override void Setup()
{
RequiresToken = false;
about = "used to test you can talk to the api but mostly pointless.";
returns.Add("world");
base.Setup();
}
}
public class name : APIcall public class name : APIcall
{ {
public override void Setup() public override void Setup()
@ -778,4 +837,184 @@ namespace BetterSecondBot.WikiMake
} }
} }
public class rename : postAPIcall
{
public override void Setup()
{
about = "renames a folder or inventory item";
returns.Add("true|false");
values.Add("item", new KeyValuePair<string, string>("URLARG", "UUID of the item/folder we are working on"));
values.Add("newname", new KeyValuePair<string, string>("string", "What we are setting"));
base.Setup();
}
}
public class realuuid : APIcall
{
public override void Setup()
{
about = "converts a inventory uuid to a realworld uuid<br/>Needed for texture preview";
returns.Add("Failed");
returns.Add("UUID");
values.Add("item", new KeyValuePair<string, string>("URLARG", "UUID of the item/folder we are working on"));
base.Setup();
}
}
public class send : APIcall
{
public override void Setup()
{
about = "sends a item to an avatar";
returns.Add("Failed");
returns.Add("UUID");
values.Add("item", new KeyValuePair<string, string>("URLARG", "UUID of the item we are working on"));
values.Add("avatar", new KeyValuePair<string, string>("URLARG", "a UUID or Firstname Lastname"));
base.Setup();
}
}
public class delete : APIcall
{
public override void Setup()
{
about = "Removes a item/folder from inventory (Make sure you set the isfolder flag correctly!)";
returns.Add("Failed");
returns.Add("UUID");
values.Add("item", new KeyValuePair<string, string>("URLARG", "UUID of the item/folder we are working on"));
values.Add("isfolder", new KeyValuePair<string, string>("URLARG", "true or false if this is a folder"));
base.Setup();
}
}
public class chatwindows : APIcall
{
public override void Setup()
{
about = "gets a full list of all chat windows";
returns.Add("array UUID = Name");
base.Setup();
}
}
public class listwithunread : APIcall
{
public override void Setup()
{
about = "gets a list of chat windows with unread messages";
returns.Add("array of UUID");
base.Setup();
}
}
public class haveunreadims : APIcall
{
public override void Setup()
{
about = "gets if there are any unread im messages at all";
returns.Add("true|false");
base.Setup();
}
}
public class getimchat : APIcall
{
public override void Setup()
{
about = "gets the chat from the selected window";
values.Add("window", new KeyValuePair<string, string>("URLARG", "the UUID of the chat window"));
returns.Add("Chat contents");
returns.Add("Window UUID invaild");
base.Setup();
}
}
public class sendimchat : postAPIcall
{
public override void Setup()
{
about = "sends a im to the selected avatar";
values.Add("avatar", new KeyValuePair<string, string>("URLARG", "a UUID or Firstname Lastname"));
values.Add("message", new KeyValuePair<string, string>("string", "the message to send"));
returns.Add("ok");
base.Setup();
}
}
public class listgroups : APIcall
{
public override void Setup()
{
about = "fetchs a list of all groups known to the bot";
returns.Add("array UUID=name");
base.Setup();
}
}
public class listgroupswithunread : APIcall
{
public override void Setup()
{
about = "fetchs a list of all groups with unread messages";
returns.Add("array UUID");
base.Setup();
}
}
public class haveunreadgroupchat : APIcall
{
public override void Setup()
{
about = "checks if there are any groups with unread messages";
returns.Add("true|false");
base.Setup();
}
}
public class getgroupchat : APIcall
{
public override void Setup()
{
about = "fetchs the groupchat history";
values.Add("group ", new KeyValuePair<string, string>("URLARG", "UUID of the group"));
returns.Add("Group UUID invaild");
returns.Add("Group Chat");
base.Setup();
}
}
public class sendgroupchat : postAPIcall
{
public override void Setup()
{
about = "sends a message to the groupchat";
values.Add("group ", new KeyValuePair<string, string>("URLARG", "UUID of the group"));
values.Add("message ", new KeyValuePair<string, string>("string", "the message to send"));
returns.Add("Group UUID invaild");
returns.Add("Processing");
base.Setup();
}
}
public class localchathistory : APIcall
{
public override void Setup()
{
about = "fetchs the last 20 localchat messages";
returns.Add("array string");
base.Setup();
}
}
public class localchatsay : postAPIcall
{
public override void Setup()
{
about = "sends a message to localchat";
values.Add("message ", new KeyValuePair<string, string>("string", "the message to send"));
returns.Add("see->localchathistory");
base.Setup();
}
}
} }

View file

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

View file

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

View file

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

View file

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

View file

@ -23,7 +23,7 @@ namespace BSB.Commands.Inventory
InventoryItem itm = bot.GetClient.Inventory.FetchItem(targetitem, bot.GetClient.Self.AgentID, (search_delay_time * 1000)); InventoryItem itm = bot.GetClient.Inventory.FetchItem(targetitem, bot.GetClient.Self.AgentID, (search_delay_time * 1000));
if (itm != null) if (itm != null)
{ {
bot.GetClient.Inventory.GiveItem(itm.AssetUUID, itm.Name, itm.AssetType, targetavatar, false); bot.GetClient.Inventory.GiveItem(itm.UUID, itm.Name, itm.AssetType, targetavatar, false);
return true; return true;
} }
else else

View file

@ -22,6 +22,19 @@ namespace BSB.Static
public static class HelperInventory public static class HelperInventory
{ {
public static InventoryItem getItemByInventoryUUID(CommandsBot bot, UUID target)
{
return bot.GetClient.Inventory.FetchItem(target, bot.GetClient.Self.AgentID, 3000);
}
public static UUID GetAssetUUID(CommandsBot bot, UUID target)
{
InventoryItem A = getItemByInventoryUUID(bot, target);
if (A != null)
{
return A.AssetUUID;
}
return UUID.Zero;
}
public static InventoryBase FindFolder(CommandsBot bot, InventoryFolder current,UUID target) public static InventoryBase FindFolder(CommandsBot bot, InventoryFolder current,UUID target)
{ {
List<InventoryBase> T = bot.GetClient.Inventory.Store.GetContents(current); List<InventoryBase> T = bot.GetClient.Inventory.Store.GetContents(current);
@ -102,7 +115,14 @@ namespace BSB.Static
public static string MapFolderJson(CommandsBot bot) public static string MapFolderJson(CommandsBot bot)
{ {
return JsonConvert.SerializeObject(DoMapFolderJson(bot, bot.GetClient.Inventory.Store.RootFolder)).Replace("\\\"","\""); if (bot.GetClient.Inventory.Store != null)
{
if (bot.GetClient.Inventory.Store.RootFolder != null)
{
return JsonConvert.SerializeObject(DoMapFolderJson(bot, bot.GetClient.Inventory.Store.RootFolder));
}
}
return null;
} }
public static InventoryMapFolder DoMapFolderJson(CommandsBot bot, InventoryFolder folder) public static InventoryMapFolder DoMapFolderJson(CommandsBot bot, InventoryFolder folder)

View file

@ -25,6 +25,32 @@ namespace BSB.bottypes
protected bool show_av_storage_info_in_status = true; protected bool show_av_storage_info_in_status = true;
protected string AVstorageBot_laststatus = ""; protected string AVstorageBot_laststatus = "";
protected Dictionary<UUID, string> FriendNames = new Dictionary<UUID, string>();
protected override void AvatarFriendNames(object o, FriendNamesEventArgs E)
{
FriendNames = E.Names;
}
public string getJsonFriendlist()
{
Dictionary<UUID, friendreplyobject> Friends = new Dictionary<UUID, friendreplyobject>();
Dictionary<UUID, FriendInfo> friendscopy = GetClient.Friends.FriendList.Copy();
foreach (KeyValuePair<UUID, FriendInfo> av in friendscopy)
{
string name = FindAvatarKey2Name(av.Key);
if (name != "loopup")
{
friendreplyobject entry = new friendreplyobject();
entry.name = name;
entry.id = av.Key.ToString();
entry.online = av.Value.IsOnline;
Friends.Add(av.Key, entry);
}
}
return JsonConvert.SerializeObject(Friends);
}
public override string GetStatus() public override string GetStatus()
{ {
cleanupAvatarStorage(); cleanupAvatarStorage();
@ -46,6 +72,7 @@ namespace BSB.bottypes
} }
reply += AvatarStorageLastUsed.Count.ToString() + " loaded"; reply += AvatarStorageLastUsed.Count.ToString() + " loaded";
} }
reply += " - " + FriendNames.Count() + " Friends";
if (reply != "") if (reply != "")
{ {
reply = " (AVStorage: " + reply + ")"; reply = " (AVStorage: " + reply + ")";
@ -299,6 +326,19 @@ namespace BSB.bottypes
AvatarStorageLastUsed[avatar_name] = helpers.UnixTimeNow(); AvatarStorageLastUsed[avatar_name] = helpers.UnixTimeNow();
return AvatarName2Key[avatar_name].ToString(); return AvatarName2Key[avatar_name].ToString();
} }
else if (FriendNames.ContainsValue(avatar_name) == true)
{
string returnvalue = "";
foreach(UUID entry in FriendNames.Keys)
{
if(FriendNames[entry] == avatar_name)
{
returnvalue = entry.ToString();
break;
}
}
return returnvalue;
}
return ""; return "";
} }
@ -336,6 +376,10 @@ namespace BSB.bottypes
AvatarStorageLastUsed[AvatarKey2Name[avatar_uuid]] = helpers.UnixTimeNow(); AvatarStorageLastUsed[AvatarKey2Name[avatar_uuid]] = helpers.UnixTimeNow();
return AvatarKey2Name[avatar_uuid]; return AvatarKey2Name[avatar_uuid];
} }
else if(FriendNames.ContainsKey(avatar_uuid) == true)
{
return FriendNames[avatar_uuid];
}
return ""; return "";
} }
@ -406,5 +450,12 @@ namespace BSB.bottypes
public bool found { get; set; } public bool found { get; set; }
public bool status { get; set; } public bool status { get; set; }
public string message { get; set; } public string message { get; set; }
}
public class friendreplyobject
{
public string name;
public string id;
public bool online;
} }
} }

View file

@ -354,11 +354,18 @@ namespace BSB.bottypes
Client.Groups.CurrentGroups += GroupsHandler; Client.Groups.CurrentGroups += GroupsHandler;
Client.Self.ScriptQuestion += PermissionsHandler; Client.Self.ScriptQuestion += PermissionsHandler;
Client.Friends.FriendshipResponse += FriendshipResponse; Client.Friends.FriendshipResponse += FriendshipResponse;
Client.Friends.FriendNames += AvatarFriendNames;
delay_group_fetch = helpers.UnixTimeNow() + 10; delay_group_fetch = helpers.UnixTimeNow() + 10;
} }
base.AfterBotLoginHandler(); base.AfterBotLoginHandler();
} }
protected virtual void AvatarFriendNames(object o, FriendNamesEventArgs E)
{
}
protected virtual void FriendshipResponse(object o, FriendshipResponseEventArgs E) protected virtual void FriendshipResponse(object o, FriendshipResponseEventArgs E)
{ {

View file

@ -50,13 +50,22 @@ namespace BSB.bottypes
} }
public override void AddToIMchat(UUID avatar, string name, string message) public override void AddToIMchat(UUID avatar, string name, string message)
{ {
string sendername = name;
if(sendername == GetClient.Self.Name)
{
name = FindAvatarKey2Name(avatar);
}
if (im_chat_history.ContainsKey(avatar) == false) if (im_chat_history.ContainsKey(avatar) == false)
{ {
if(im_chat_history_to_name.ContainsKey(avatar) == false)
{
im_chat_history_to_name.Add(avatar, name);
}
im_chat_history.Add(avatar, new List<string>()); im_chat_history.Add(avatar, new List<string>());
im_chat_unread.Add(avatar, false); im_chat_unread.Add(avatar, false);
} }
var date = DateTime.Now; var date = DateTime.Now;
im_chat_history[avatar].Add("[" + date.Hour.ToString() + ":" + date.Minute.ToString() + "] " + name + ":" + message + ""); im_chat_history[avatar].Add("[" + date.Hour.ToString() + ":" + date.Minute.ToString() + "] " + sendername + ":" + message + "");
if (im_chat_history[avatar].Count > imchatlimit) if (im_chat_history[avatar].Count > imchatlimit)
{ {
im_chat_history[avatar].RemoveAt(0); im_chat_history[avatar].RemoveAt(0);
@ -110,6 +119,11 @@ namespace BSB.bottypes
} }
} }
} }
}
public override bool HasUnreadGroupchats()
{
return group_chat_unread.ContainsValue(true);
} }
public override bool GroupHasUnread(UUID group) public override bool GroupHasUnread(UUID group)

View file

@ -0,0 +1,87 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<ProjectType>Local</ProjectType>
<ProductVersion>14.0.25123</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{89D7A3E5-0000-0000-0000-000000000000}</ProjectGuid>
<Configurations>Debug;Release;DockerBuild</Configurations>
<AssemblyName>LibreMetaverse.StructuredData</AssemblyName>
<DefaultClientScript>JScript</DefaultClientScript>
<DefaultHTMLPageLayout>Grid</DefaultHTMLPageLayout>
<DefaultTargetSchema>IE50</DefaultTargetSchema>
<DelaySign>false</DelaySign>
<TargetFramework>netcoreapp3.1</TargetFramework>
<OutputType>Library</OutputType>
<RootNamespace>LibreMetaverse.StructuredData</RootNamespace>
<GenerateAssemblyInfo>true</GenerateAssemblyInfo>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<AllowUnsafeBlocks>True</AllowUnsafeBlocks>
<BaseAddress>285212672</BaseAddress>
<CheckForOverflowUnderflow>False</CheckForOverflowUnderflow>
<ConfigurationOverrideFile>
</ConfigurationOverrideFile>
<DefineConstants>TRACE;DEBUG</DefineConstants>
<DebugSymbols>True</DebugSymbols>
<FileAlignment>4096</FileAlignment>
<Optimize>False</Optimize>
<OutputPath>..\bin\</OutputPath>
<RegisterForComInterop>False</RegisterForComInterop>
<RemoveIntegerChecks>False</RemoveIntegerChecks>
<TreatWarningsAsErrors>False</TreatWarningsAsErrors>
<WarningLevel>4</WarningLevel>
<NoStdLib>False</NoStdLib>
<NoWarn>1591,1574,0419</NoWarn>
<PlatformTarget>AnyCPU</PlatformTarget>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<AllowUnsafeBlocks>True</AllowUnsafeBlocks>
<BaseAddress>285212672</BaseAddress>
<CheckForOverflowUnderflow>False</CheckForOverflowUnderflow>
<DefineConstants>TRACE</DefineConstants>
<DocumentationFile>LibreMetaverse.StructuredData.XML</DocumentationFile>
<DebugSymbols>False</DebugSymbols>
<FileAlignment>4096</FileAlignment>
<Optimize>True</Optimize>
<OutputPath>..\bin\</OutputPath>
<RegisterForComInterop>False</RegisterForComInterop>
<RemoveIntegerChecks>False</RemoveIntegerChecks>
<TreatWarningsAsErrors>False</TreatWarningsAsErrors>
<WarningLevel>4</WarningLevel>
<NoStdLib>False</NoStdLib>
<NoWarn>1591,1574,0419</NoWarn>
<PlatformTarget>AnyCPU</PlatformTarget>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DockerBuild|x64'">
<ErrorReport>none</ErrorReport>
<DockerDefaultTargetOS>Linux</DockerDefaultTargetOS>
<PublishTrimmed>false</PublishTrimmed>
<PublishSingleFile>false</PublishSingleFile>
<TreatWarningsAsErrors>false</TreatWarningsAsErrors>
<RuntimeIdentifier>linux-x64</RuntimeIdentifier>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\LibreMetaverseTypes\LibreMetaverse.Types.csproj" />
</ItemGroup>
<ItemGroup>
<Folder Include="Properties\" />
</ItemGroup>
<ItemGroup>
<None Include="..\LICENSE.txt">
<Pack>True</Pack>
<PackagePath></PackagePath>
</None>
</ItemGroup>
<PropertyGroup>
<PreBuildEvent>
</PreBuildEvent>
<PostBuildEvent>
</PostBuildEvent>
<Version>1.2.0</Version>
<Authors>Sjofn LLC, OpenMetaverse Developers</Authors>
<Product>LibreMetaverse.StructuredData</Product>
<Copyright>Copyright © OpenMetaverse Developers 2008, 2017. Copyright © Sjofn LLC 2018-2019. All rights reserved.</Copyright>
<PackageLicenseFile>LICENSE.txt</PackageLicenseFile>
<RepositoryUrl>https://github.com/cinderblocks/libremetaverse</RepositoryUrl>
</PropertyGroup>
</Project>

View file

@ -0,0 +1,15 @@
<?xml version="1.0"?>
<package >
<metadata>
<id>LibreMetaverse.StructuredData</id>
<version>$version$</version>
<authors>Cinder Biscuits</authors>
<owners>Cinder Biscuits</owners>
<licenseUrl>https://github.com/cinderblocks/libremetaverse/blob/master/LICENSE.txt</licenseUrl>
<projectUrl>https://github.com/cinderblocks/libremetaverse</projectUrl>
<requireLicenseAcceptance>false</requireLicenseAcceptance>
<description>LibreMetaverse structured data library</description>
<copyright>Copyright 2017</copyright>
<tags>LMV OMV OpenMetaverse OpenSim Halcyon OpenMetaverseFoundation VirtualWorld Radegast SecondLife</tags>
</metadata>
</package>

View file

@ -0,0 +1,95 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<ProjectType>Local</ProjectType>
<ProductVersion>14.0.25123</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{27C70F3A-0000-0000-0000-000000000000}</ProjectGuid>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Configurations>Debug;Release;DockerBuild</Configurations>
<AssemblyName>LibreMetaverse</AssemblyName>
<DefaultClientScript>JScript</DefaultClientScript>
<DefaultHTMLPageLayout>Grid</DefaultHTMLPageLayout>
<DefaultTargetSchema>IE50</DefaultTargetSchema>
<DelaySign>false</DelaySign>
<OutputType>Library</OutputType>
<RootNamespace>LibreMetaverse</RootNamespace>
<GenerateAssemblyInfo>true</GenerateAssemblyInfo>
<TargetFramework>netcoreapp3.1</TargetFramework>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<AllowUnsafeBlocks>True</AllowUnsafeBlocks>
<BaseAddress>285212672</BaseAddress>
<CheckForOverflowUnderflow>False</CheckForOverflowUnderflow>
<DefineConstants>TRACE;DEBUG</DefineConstants>
<DebugSymbols>True</DebugSymbols>
<FileAlignment>4096</FileAlignment>
<Optimize>False</Optimize>
<OutputPath>..\bin\</OutputPath>
<RegisterForComInterop>False</RegisterForComInterop>
<RemoveIntegerChecks>False</RemoveIntegerChecks>
<TreatWarningsAsErrors>False</TreatWarningsAsErrors>
<WarningLevel>4</WarningLevel>
<NoStdLib>False</NoStdLib>
<NoWarn>1591,1574,0419</NoWarn>
<PlatformTarget>AnyCPU</PlatformTarget>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<AllowUnsafeBlocks>True</AllowUnsafeBlocks>
<BaseAddress>285212672</BaseAddress>
<CheckForOverflowUnderflow>False</CheckForOverflowUnderflow>
<DefineConstants>TRACE</DefineConstants>
<DocumentationFile>LibreMetaverse.XML</DocumentationFile>
<DebugSymbols>False</DebugSymbols>
<FileAlignment>4096</FileAlignment>
<Optimize>True</Optimize>
<OutputPath>..\bin\</OutputPath>
<RegisterForComInterop>False</RegisterForComInterop>
<RemoveIntegerChecks>False</RemoveIntegerChecks>
<TreatWarningsAsErrors>False</TreatWarningsAsErrors>
<WarningLevel>4</WarningLevel>
<NoStdLib>False</NoStdLib>
<NoWarn>1591,1574,0419</NoWarn>
<PlatformTarget>AnyCPU</PlatformTarget>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DockerBuild|x64'">
<ErrorReport>none</ErrorReport>
<DockerDefaultTargetOS>Linux</DockerDefaultTargetOS>
<PublishTrimmed>false</PublishTrimmed>
<PublishSingleFile>false</PublishSingleFile>
<TreatWarningsAsErrors>false</TreatWarningsAsErrors>
<RuntimeIdentifier>linux-x64</RuntimeIdentifier>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="log4net" Version="2.0.12" />
<PackageReference Include="Microsoft.Experimental.Collections" Version="1.0.6-e190117-3" />
<PackageReference Include="Microsoft.Extensions.ObjectPool" Version="5.0.2" />
<PackageReference Include="System.Drawing.Common" Version="5.0.0" />
<PackageReference Include="System.Net.Http" Version="4.3.4" />
<PackageReference Include="System.Net.NameResolution" Version="4.3.0" />
<PackageReference Include="System.Threading.Channels" Version="5.0.0" />
<PackageReference Include="XmlRpcCore" Version="3.1.2.77" />
<PackageReference Include="zlib.net-mutliplatform" Version="1.0.4" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\LibreMetaverse.StructuredData\LibreMetaverse.StructuredData.csproj" />
<ProjectReference Include="..\LibreMetaverseTypes\LibreMetaverse.Types.csproj" />
</ItemGroup>
<ItemGroup>
<None Include="..\LICENSE.txt">
<Pack>True</Pack>
<PackagePath></PackagePath>
</None>
</ItemGroup>
<PropertyGroup>
<PreBuildEvent>
</PreBuildEvent>
<PostBuildEvent>
</PostBuildEvent>
<Version>1.2.0</Version>
<Authors>Sjofn LLC, OpenMetaverse Developers</Authors>
<Product>LibreMetaverse</Product>
<Copyright>Copyright © OpenMetaverse Developers 2008, 2017. Copyright © Sjofn LLC 2018-2019. All rights reserved.</Copyright>
<PackageLicenseFile>LICENSE.txt</PackageLicenseFile>
<RepositoryUrl>https://github.com/cinderblocks/libremetaverse</RepositoryUrl>
</PropertyGroup>
</Project>

View file

@ -0,0 +1,15 @@
<?xml version="1.0"?>
<package >
<metadata>
<id>LibreMetaverse</id>
<version>$version$</version>
<authors>Cinder Biscuits</authors>
<owners>Cinder Biscuits</owners>
<licenseUrl>https://github.com/cinderblocks/libremetaverse/blob/master/LICENSE.txt</licenseUrl>
<projectUrl>https://github.com/cinderblocks/libremetaverse</projectUrl>
<requireLicenseAcceptance>false</requireLicenseAcceptance>
<description>LibreMetaverse allows your code to read and work with data send across a SecondLife, Halcyon, OpenSimulator, or related connection.</description>
<copyright>Copyright 2017</copyright>
<tags>LMV OMV OpenMetaverse OpenSim OpenSimulator Halcyon OpenMetaverseFoundation VirtualWorld Radegast SecondLife</tags>
</metadata>
</package>

View file

@ -0,0 +1,81 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<ProjectType>Local</ProjectType>
<ProductVersion>14.0.25123</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{B37B02AD-0000-0000-0000-000000000000}</ProjectGuid>
<Configurations>Debug;Release;DockerBuild</Configurations>
<AssemblyName>LibreMetaverse.Types</AssemblyName>
<DefaultClientScript>JScript</DefaultClientScript>
<DefaultHTMLPageLayout>Grid</DefaultHTMLPageLayout>
<DefaultTargetSchema>IE50</DefaultTargetSchema>
<DelaySign>false</DelaySign>
<TargetFramework>netcoreapp3.1</TargetFramework>
<OutputType>Library</OutputType>
<RootNamespace>LibreMetaverse</RootNamespace>
<GenerateAssemblyInfo>true</GenerateAssemblyInfo>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<AllowUnsafeBlocks>True</AllowUnsafeBlocks>
<BaseAddress>285212672</BaseAddress>
<CheckForOverflowUnderflow>False</CheckForOverflowUnderflow>
<DefineConstants>TRACE;DEBUG</DefineConstants>
<DebugSymbols>True</DebugSymbols>
<FileAlignment>4096</FileAlignment>
<Optimize>False</Optimize>
<OutputPath>..\bin\</OutputPath>
<RegisterForComInterop>False</RegisterForComInterop>
<RemoveIntegerChecks>False</RemoveIntegerChecks>
<TreatWarningsAsErrors>False</TreatWarningsAsErrors>
<WarningLevel>4</WarningLevel>
<NoStdLib>False</NoStdLib>
<NoWarn>1591,1574,0419</NoWarn>
<PlatformTarget>AnyCPU</PlatformTarget>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<AllowUnsafeBlocks>True</AllowUnsafeBlocks>
<BaseAddress>285212672</BaseAddress>
<CheckForOverflowUnderflow>False</CheckForOverflowUnderflow>
<DefineConstants>TRACE</DefineConstants>
<DocumentationFile>LibreMetaverseTypes.XML</DocumentationFile>
<DebugSymbols>False</DebugSymbols>
<FileAlignment>4096</FileAlignment>
<Optimize>True</Optimize>
<OutputPath>..\bin\</OutputPath>
<RegisterForComInterop>False</RegisterForComInterop>
<RemoveIntegerChecks>False</RemoveIntegerChecks>
<TreatWarningsAsErrors>False</TreatWarningsAsErrors>
<WarningLevel>4</WarningLevel>
<NoStdLib>False</NoStdLib>
<NoWarn>1591,1574,0419</NoWarn>
<PlatformTarget>AnyCPU</PlatformTarget>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DockerBuild|x64'">
<ErrorReport>none</ErrorReport>
<DockerDefaultTargetOS>Linux</DockerDefaultTargetOS>
<PublishTrimmed>false</PublishTrimmed>
<PublishSingleFile>false</PublishSingleFile>
<TreatWarningsAsErrors>false</TreatWarningsAsErrors>
<RuntimeIdentifier>linux-x64</RuntimeIdentifier>
</PropertyGroup>
<ItemGroup>
<Folder Include="Properties\" />
</ItemGroup>
<ItemGroup>
<None Include="..\LICENSE.txt">
<Pack>True</Pack>
<PackagePath></PackagePath>
</None>
</ItemGroup>
<PropertyGroup>
<PreBuildEvent>
</PreBuildEvent>
<PostBuildEvent>
</PostBuildEvent>
<Version>1.2.0</Version>
<Authors>Sjofn LLC, Openmetaverse Developers</Authors>
<Copyright>Copyright © OpenMetaverse Developers 2008, 2017. Copyright © Sjofn LLC. All rights reserved.</Copyright>
<PackageLicenseFile>LICENSE.txt</PackageLicenseFile>
<RepositoryUrl>https://github.com/cinderblocks/libremetaverse</RepositoryUrl>
</PropertyGroup>
</Project>

View file

@ -0,0 +1,15 @@
<?xml version="1.0"?>
<package >
<metadata>
<id>LibreMetaverse.Types</id>
<version>$version$</version>
<authors>Cinder Biscuits</authors>
<owners>Cinder Biscuits</owners>
<licenseUrl>https://github.com/cinderblocks/libremetaverse/blob/master/LICENSE.txt</licenseUrl>
<projectUrl>https://github.com/cinderblocks/libremetaverse</projectUrl>
<requireLicenseAcceptance>false</requireLicenseAcceptance>
<description>LibreMetaverse type library</description>
<copyright>Copyright 2017</copyright>
<tags>LMV OMV OpenMetaverse OpenSim Halcyon OpenMetaverseFoundation VirtualWorld Radegast SecondLife</tags>
</metadata>
</package>

View file

@ -1,33 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<AllowUnsafeBlocks>True</AllowUnsafeBlocks>
<TargetFramework>netcoreapp3.1</TargetFramework>
<Configurations>Debug;Release;DockerBuild</Configurations>
<Platforms>x64</Platforms>
<PackageLicenseFile>LICENSE.txt</PackageLicenseFile>
<Description>see LibreMetaverse-core</Description>
<GeneratePackageOnBuild>false</GeneratePackageOnBuild>
<Version>1.0.3</Version>
<PackageProjectUrl>https://github.com/Madpeterz/libremetaverse-core</PackageProjectUrl>
<RepositoryUrl>https://github.com/Madpeterz/libremetaverse-core</RepositoryUrl>
<RepositoryType>git</RepositoryType>
<FileVersion>1.0.3.0</FileVersion>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DockerBuild|x64'">
<ErrorReport>none</ErrorReport>
<DockerDefaultTargetOS>Linux</DockerDefaultTargetOS>
<PublishTrimmed>false</PublishTrimmed>
<PublishSingleFile>false</PublishSingleFile>
<TreatWarningsAsErrors>false</TreatWarningsAsErrors>
<RuntimeIdentifier>linux-x64</RuntimeIdentifier>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\Libremetaverse.types\LibreMetaverse-core.Types.csproj" />
</ItemGroup>
<ItemGroup>
<None Include="..\LICENSE.txt">
<Pack>True</Pack>
<PackagePath></PackagePath>
</None>
</ItemGroup>
</Project>

View file

@ -1,31 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<AllowUnsafeBlocks>True</AllowUnsafeBlocks>
<TargetFramework>netcoreapp3.1</TargetFramework>
<Configurations>Debug;Release;DockerBuild</Configurations>
<Platforms>x64</Platforms>
<GeneratePackageOnBuild>false</GeneratePackageOnBuild>
<Description>see LibreMetaverse-core</Description>
<PackageLicenseFile>LICENSE.txt</PackageLicenseFile>
<PackageProjectUrl>https://github.com/Madpeterz/libremetaverse-core</PackageProjectUrl>
<RepositoryUrl>https://github.com/Madpeterz/libremetaverse-core</RepositoryUrl>
<RepositoryType>git</RepositoryType>
<AssemblyVersion>1.0.3.0</AssemblyVersion>
<FileVersion>1.0.3.0</FileVersion>
<Version>1.0.3</Version>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DockerBuild|x64'">
<ErrorReport>none</ErrorReport>
<DockerDefaultTargetOS>Linux</DockerDefaultTargetOS>
<PublishTrimmed>false</PublishTrimmed>
<PublishSingleFile>false</PublishSingleFile>
<TreatWarningsAsErrors>false</TreatWarningsAsErrors>
<RuntimeIdentifier>linux-x64</RuntimeIdentifier>
</PropertyGroup>
<ItemGroup>
<None Include="..\LICENSE.txt">
<Pack>True</Pack>
<PackagePath></PackagePath>
</None>
</ItemGroup>
</Project>

View file

@ -30,6 +30,7 @@ using System.Collections.Generic;
using System.IO; using System.IO;
using System.Drawing; using System.Drawing;
using OpenMetaverse.Assets; using OpenMetaverse.Assets;
using log4net;
namespace OpenMetaverse.Imaging namespace OpenMetaverse.Imaging
{ {
@ -39,6 +40,7 @@ namespace OpenMetaverse.Imaging
/// </summary> /// </summary>
public class Baker public class Baker
{ {
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
#region Properties #region Properties
/// <summary>Final baked texture</summary> /// <summary>Final baked texture</summary>
public AssetTexture BakedTexture => bakedTexture; public AssetTexture BakedTexture => bakedTexture;
@ -331,6 +333,7 @@ namespace OpenMetaverse.Imaging
} }
// Apply any alpha wearable textures to make parts of the avatar disappear // Apply any alpha wearable textures to make parts of the avatar disappear
m_log.DebugFormat("[XBakes]: Number of alpha wearable textures: {0}", alphaWearableTextures.Count);
foreach (ManagedImage img in alphaWearableTextures) foreach (ManagedImage img in alphaWearableTextures)
AddAlpha(bakedTexture.Image, img); AddAlpha(bakedTexture.Image, img);
@ -349,8 +352,11 @@ namespace OpenMetaverse.Imaging
lock (ResourceSync) lock (ResourceSync)
{ {
using (Stream stream = Helpers.GetResourceStream(fileName, Settings.RESOURCE_DIR)) using (Stream stream = Helpers.GetResourceStream(fileName, Settings.RESOURCE_DIR))
{ {
bitmap = LoadTGAClass.LoadTGA(stream); if (stream != null)
{
bitmap = LoadTGAClass.LoadTGA(stream);
}
} }
} }
if (bitmap == null) if (bitmap == null)

View file

@ -624,8 +624,12 @@ namespace OpenMetaverse.Imaging
{ {
using (System.IO.FileStream f = System.IO.File.OpenRead(filename)) using (System.IO.FileStream f = System.IO.File.OpenRead(filename))
{ {
return LoadTGA(f); if (f != null)
{
return LoadTGA(f);
}
} }
return null; // file stream error
} }
catch (System.IO.DirectoryNotFoundException) catch (System.IO.DirectoryNotFoundException)
{ {

View file

@ -20,11 +20,16 @@ namespace LibreMetaverse
[NonSerialized] [NonSerialized]
private readonly GridClient Client; private readonly GridClient Client;
private static readonly HttpClient httpClient = new HttpClient(); private static HttpClient httpClient;
public InventoryAISClient(GridClient client) public InventoryAISClient(GridClient client)
{ {
Client = client; Client = client;
HttpClientHandler clientHandler = new HttpClientHandler();
clientHandler.ServerCertificateCustomValidationCallback = (sender, cert, chain, sslPolicyErrors) => { return true; };
httpClient = new HttpClient(clientHandler);
httpClient.DefaultRequestHeaders.Accept.Clear(); httpClient.DefaultRequestHeaders.Accept.Clear();
httpClient.DefaultRequestHeaders.Add("User-Agent", "LibreMetaverse AIS Client"); httpClient.DefaultRequestHeaders.Add("User-Agent", "LibreMetaverse AIS Client");
} }

View file

@ -686,27 +686,30 @@ namespace OpenMetaverse
List<UUID> load_items = new List<UUID>(); List<UUID> load_items = new List<UUID>();
List<UUID> owner_ids = new List<UUID>(); List<UUID> owner_ids = new List<UUID>();
foreach (InventoryBase o in objects) if (objects != null)
{ {
if (o.GetType() != typeof(InventoryFolder)) foreach (InventoryBase o in objects)
{ {
InventoryItem ob = (InventoryItem)o; if (o.GetType() != typeof(InventoryFolder))
if ((ob.IsLink() == true) && (fast_loading == false))
{ {
if (Store.Items.ContainsKey(ob.AssetUUID) == false) InventoryItem ob = (InventoryItem)o;
if ((ob.IsLink() == true) && (fast_loading == false))
{ {
load_items.Add(ob.AssetUUID); if (Store.Items.ContainsKey(ob.AssetUUID) == false)
owner_ids.Add(Client.Self.AgentID); {
load_items.Add(ob.AssetUUID);
owner_ids.Add(Client.Self.AgentID);
}
else
{
cleaned_list.Add(Client.Inventory.FetchItem(ob.AssetUUID, Client.Self.AgentID, 1000 * 5));
}
} }
else else
{ {
cleaned_list.Add(Client.Inventory.FetchItem(ob.AssetUUID, Client.Self.AgentID, 1000 * 5)); cleaned_list.Add(ob);
} }
} }
else
{
cleaned_list.Add(ob);
}
} }
} }

View file

@ -1,62 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<AllowUnsafeBlocks>True</AllowUnsafeBlocks>
<TargetFramework>netcoreapp3.1</TargetFramework>
<Configurations>Debug;Release;DockerBuild</Configurations>
<Platforms>x64</Platforms>
<GeneratePackageOnBuild>false</GeneratePackageOnBuild>
<PackageLicenseFile>LICENSE.txt</PackageLicenseFile>
<Description>.net core targeted version of the LibreMetaverse project</Description>
<PackageProjectUrl>https://github.com/Madpeterz/libremetaverse-core</PackageProjectUrl>
<RepositoryUrl>https://github.com/Madpeterz/libremetaverse-core</RepositoryUrl>
<RepositoryType>git</RepositoryType>
<Version>1.0.3</Version>
<FileVersion>1.0.3.0</FileVersion>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DockerBuild|x64'">
<ErrorReport>none</ErrorReport>
<DockerDefaultTargetOS>Linux</DockerDefaultTargetOS>
<PublishTrimmed>false</PublishTrimmed>
<PublishSingleFile>false</PublishSingleFile>
<TreatWarningsAsErrors>false</TreatWarningsAsErrors>
<RuntimeIdentifier>linux-x64</RuntimeIdentifier>
</PropertyGroup>
<ItemGroup>
<None Remove="libopenjpeg-dotnet-2-1.5.0-dotnet-1.dylib" />
</ItemGroup>
<ItemGroup>
<Resource Include="libopenjpeg-dotnet-2-1.5.0-dotnet-1.dylib">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Resource>
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Experimental.Collections" Version="1.0.6-e190117-3" />
<PackageReference Include="Microsoft.Extensions.ObjectPool" Version="3.1.3" />
<PackageReference Include="System.Drawing.Common" Version="4.7.0" />
<PackageReference Include="XmlRpcCore" Version="3.1.2.77" />
<PackageReference Include="zlib.net-mutliplatform" Version="1.0.4" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Libremetaverse.structureddata\LibreMetaverse-core.StructuredData.csproj" />
</ItemGroup>
<ItemGroup>
<None Include="..\LICENSE.txt">
<Pack>True</Pack>
<PackagePath></PackagePath>
</None>
</ItemGroup>
<ItemGroup>
<None Update="libopenjpeg-dotnet-2-1.5.0-dotnet-1-i686.so">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="libopenjpeg-dotnet-2-1.5.0-dotnet-1-x86_64.so">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="openjpeg-dotnet-x86_64.dll">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="openjpeg-dotnet.dll">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
</ItemGroup>
</Project>

View file

@ -1,15 +0,0 @@
<?xml version="1.0"?>
<package >
<metadata>
<id>LibreMetaverse-core</id>
<version>$version$</version>
<authors>Madpeterz</authors>
<owners>Madpeterz</owners>
<licenseUrl>https://github.com/Madpeterz/libremetaverse-core/blob/master/LICENSE.txt</licenseUrl>
<projectUrl>https://github.com/Madpeterz/libremetaverse-core</projectUrl>
<requireLicenseAcceptance>false</requireLicenseAcceptance>
<description>A port of LibreMetaverse to .net core cleaned up</description>
<copyright>Copyright 2020</copyright>
<tags>SecondLife Docker Linux Windows Secondbot CLI</tags>
</metadata>
</package>

View file

@ -1,209 +1,188 @@
/*
* Copyright (c) 2006-2016, openmetaverse.co
* All rights reserved.
*
* - Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* - Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
* - Neither the name of the openmetaverse.co nor the names
* of its contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
using System; using System;
using System.Text; using System.Reflection;
using log4net;
using log4net.Appender;
using log4net.Config;
[assembly: XmlConfigurator(Watch = true)]
namespace OpenMetaverse namespace OpenMetaverse
{ {
public abstract class LogWriter /// <summary>
{ /// Singleton logging class for the entire library
public static void LogMessage(StringBuilder messageBuilder, Helpers.LogLevel Level) /// </summary>
{
var date = DateTime.Now;
string Message = messageBuilder.ToString();
messageBuilder.Clear();
messageBuilder.Append("[");
if (date.Hour < 10) messageBuilder.Append("0");
messageBuilder.Append(date.Hour.ToString());
messageBuilder.Append(":");
if (date.Minute < 10) messageBuilder.Append("0");
messageBuilder.Append(date.Minute.ToString());
messageBuilder.Append("] ");
switch (Level)
{
case Helpers.LogLevel.Debug:
{
messageBuilder.Append("Debug - ");
break;
}
case Helpers.LogLevel.Info:
{
messageBuilder.Append("Status - ");
break;
}
case Helpers.LogLevel.Warning:
{
messageBuilder.Append("Warn - ");
break;
}
case Helpers.LogLevel.Error:
{
messageBuilder.Append("Error - ");
break;
}
default:
break;
}
messageBuilder.Append(Message);
WriteMessage(Message);
}
protected static void WriteMessage(string message)
{
}
}
public class NoLogWriter : LogWriter
{
}
public class ConsoleWriter : LogWriter
{
public new static void WriteMessage(string message)
{
Console.WriteLine(message);
}
}
public static class Logger public static class Logger
{ {
// Warn,Error,Log,Debug functions /// <summary>
#region Message only methods without Levels /// Callback used for client apps to receive log messages from
public static void Warn(string message) /// the library
{ /// </summary>
Log(message, Helpers.LogLevel.Warning); /// <param name="message">Data being logged</param>
} /// <param name="level">The severity of the log entry from <seealso cref="Helpers.LogLevel"/></param>
public static void Error(string message) public delegate void LogCallback(object message, Helpers.LogLevel level);
{
Log(message, Helpers.LogLevel.Error);
}
public static void Info(string message)
{
Log(message, Helpers.LogLevel.Info);
}
public static void DebugLog(string message)
{
Log(message, Helpers.LogLevel.Debug);
}
#endregion
#region Message+Exception without levels
public static void Warn(string message, Exception e)
{
Log(message, Helpers.LogLevel.Warning, null, e);
}
public static void Error(string message, Exception e)
{
Log(message, Helpers.LogLevel.Error, null, e);
}
public static void Info(string message, Exception e)
{
Log(message, Helpers.LogLevel.Info, null, e);
}
public static void DebugLog(string message, Exception e)
{
Log(message, Helpers.LogLevel.Debug, null, e);
}
#endregion
#region Message+Client without levels
public static void Warn(string message, GridClient client)
{
Log(message, Helpers.LogLevel.Warning, client);
}
public static void Error(string message, GridClient client)
{
Log(message, Helpers.LogLevel.Error, client);
}
public static void Info(string message, GridClient client)
{
Log(message, Helpers.LogLevel.Info, client);
}
public static void DebugLog(string message, GridClient client)
{
Log(message, Helpers.LogLevel.Debug, client);
}
#endregion
#region Message+Client+Exeption without levels [Anything else call Log Directly]
public static void Warn(string message, GridClient client, Exception exception)
{
Log(message, Helpers.LogLevel.Warning, client, exception);
}
public static void Error(string message, GridClient client, Exception exception)
{
Log(message, Helpers.LogLevel.Error, client, exception);
}
public static void Info(string message, GridClient client, Exception exception)
{
Log(message, Helpers.LogLevel.Info, client, exception);
}
public static void DebugLog(string message, GridClient client, Exception exception)
{
Log(message, Helpers.LogLevel.Debug, client, exception);
}
#endregion
public static void Log(string message, Helpers.LogLevel Level, GridClient client, Exception exception) /// <summary>Triggered whenever a message is logged. If this is left
/// null, log messages will go to the console</summary>
public static event LogCallback OnLogMessage;
/// <summary>log4net logging engine</summary>
public static ILog LogInstance;
/// <summary>
/// Default constructor
/// </summary>
static Logger()
{ {
Helpers.LogLevel UseLevel = Helpers.LogLevel.Info; LogInstance = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
string useWriter = "Console";
// If error level reporting isn't enabled we assume no logger is configured and initialize a default
if (client != null) // ConsoleAppender
if (!LogInstance.Logger.IsEnabledFor(log4net.Core.Level.Error))
{ {
UseLevel = client.Settings.LOG_LEVEL; IAppender appender = new ConsoleAppender
useWriter = client.Settings.LOG_WRITER;
}
if (UseLevel >= Level)
{
StringBuilder NewMessage = new StringBuilder();
if (client != null)
{ {
if (client.Settings.LOG_NAMES) Layout = new log4net.Layout.PatternLayout("%timestamp [%thread] %-5level - %message%newline")
{ };
NewMessage.Append("{"); BasicConfigurator.Configure(LogManager.GetRepository(Assembly.GetCallingAssembly()), appender);
NewMessage.Append(client.Self.Name);
NewMessage.Append("} "); if(Settings.LOG_LEVEL != Helpers.LogLevel.None)
} LogInstance.Info("No log configuration found, defaulting to console logging");
}
NewMessage.Append(message);
switch (useWriter)
{
case "NoLogWriter":
{
break;
}
default:
{
ConsoleWriter.LogMessage(NewMessage, Level);
break;
}
}
} }
} }
public static void LogFormat(string Message, Helpers.LogLevel Level, int Value)
/// <summary>
/// Send a log message to the logging engine
/// </summary>
/// <param name="message">The log message</param>
/// <param name="level">The severity of the log entry</param>
public static void Log(object message, Helpers.LogLevel level)
{ {
LogFormat(Message, new[] { Value.ToString() }); Log(message, level, null, null);
}
public static void LogFormat(string Message, string[] Values)
{
LogFormat(Message, Helpers.LogLevel.Debug, Values);
}
public static void LogFormat(string Message, Helpers.LogLevel Level, string[] Values)
{
Log(String.Format(Message, Values), Level);
} }
#region Log overloads /// <summary>
public static void Log(string message) /// Send a log message to the logging engine
/// </summary>
/// <param name="message">The log message</param>
/// <param name="level">The severity of the log entry</param>
/// <param name="client">Instance of the client</param>
public static void Log(object message, Helpers.LogLevel level, GridClient client)
{ {
Log(message, Helpers.LogLevel.Debug); Log(message, level, client, null);
} }
public static void Log(string message, Helpers.LogLevel Level)
/// <summary>
/// Send a log message to the logging engine
/// </summary>
/// <param name="message">The log message</param>
/// <param name="level">The severity of the log entry</param>
/// <param name="exception">Exception that was raised</param>
public static void Log(object message, Helpers.LogLevel level, Exception exception)
{ {
Log(message, Level, null, null); Log(message, level, null, exception);
} }
public static void Log(string message, Helpers.LogLevel Level, GridClient client)
/// <summary>
/// Send a log message to the logging engine
/// </summary>
/// <param name="message">The log message</param>
/// <param name="level">The severity of the log entry</param>
/// <param name="client">Instance of the client</param>
/// <param name="exception">Exception that was raised</param>
public static void Log(object message, Helpers.LogLevel level, GridClient client, Exception exception)
{ {
Log(message, Level, null, null); if (client != null && client.Settings.LOG_NAMES)
message = $"<{client.Self.Name}>: {message}";
OnLogMessage?.Invoke(message, level);
switch (level)
{
case Helpers.LogLevel.Debug:
if (Settings.LOG_LEVEL == Helpers.LogLevel.Debug)
LogInstance.Debug(message, exception);
break;
case Helpers.LogLevel.Info:
if (Settings.LOG_LEVEL == Helpers.LogLevel.Debug
|| Settings.LOG_LEVEL == Helpers.LogLevel.Info)
LogInstance.Info(message, exception);
break;
case Helpers.LogLevel.Warning:
if (Settings.LOG_LEVEL == Helpers.LogLevel.Debug
|| Settings.LOG_LEVEL == Helpers.LogLevel.Info
|| Settings.LOG_LEVEL == Helpers.LogLevel.Warning)
LogInstance.Warn(message, exception);
break;
case Helpers.LogLevel.Error:
if (Settings.LOG_LEVEL == Helpers.LogLevel.Debug
|| Settings.LOG_LEVEL == Helpers.LogLevel.Info
|| Settings.LOG_LEVEL == Helpers.LogLevel.Warning
|| Settings.LOG_LEVEL == Helpers.LogLevel.Error)
LogInstance.Error(message, exception);
break;
default:
break;
}
} }
public static void Log(string message, Helpers.LogLevel Level, Exception exception)
/// <summary>
/// If the library is compiled with DEBUG defined, an event will be
/// fired if an <code>OnLogMessage</code> handler is registered and the
/// message will be sent to the logging engine
/// </summary>
/// <param name="message">The message to log at the DEBUG level to the
/// current logging engine</param>
public static void DebugLog(object message)
{ {
Log(message, Level, null, exception); DebugLog(message, null);
}
/// <summary>
/// If the library is compiled with DEBUG defined and
/// <code>GridClient.Settings.DEBUG</code> is true, an event will be
/// fired if an <code>OnLogMessage</code> handler is registered and the
/// message will be sent to the logging engine
/// </summary>
/// <param name="message">The message to log at the DEBUG level to the
/// current logging engine</param>
/// <param name="client">Instance of the client</param>
[System.Diagnostics.Conditional("DEBUG")]
public static void DebugLog(object message, GridClient client)
{
if (Settings.LOG_LEVEL != Helpers.LogLevel.Debug) return;
if (client != null && client.Settings.LOG_NAMES)
message = $"<{client.Self.Name}>: {message}";
OnLogMessage?.Invoke(message, Helpers.LogLevel.Debug);
LogInstance.Debug(message);
} }
#endregion
} }
} }

View file

@ -2624,7 +2624,7 @@ namespace OpenMetaverse
catch (IndexOutOfRangeException ex) catch (IndexOutOfRangeException ex)
{ {
Logger.Log("Error decoding an ObjectUpdateCompressed packet", Helpers.LogLevel.Warning, Client, ex); Logger.Log("Error decoding an ObjectUpdateCompressed packet", Helpers.LogLevel.Warning, Client, ex);
Logger.Log(block.ToString(), Helpers.LogLevel.Warning); Logger.Log(block, Helpers.LogLevel.Warning);
} }
} }
} }

View file

@ -340,15 +340,27 @@ namespace OpenMetaverse
#region Logging Configuration #region Logging Configuration
public string LOG_WRITER = "Console"; /// <summary>
/// Get or set the minimum log level to output to the console by default
///
/// If the library is not compiled with DEBUG defined and this level is set to DEBUG
/// You will get no output on the console. This behavior can be overriden by creating
/// a logger configuration file for log4net
/// </summary>
public static Helpers.LogLevel LOG_LEVEL = Helpers.LogLevel.Debug;
/// <summary>Attach avatar names to log messages</summary>
public bool LOG_NAMES = true; public bool LOG_NAMES = true;
public bool LOG_DISKCACHE = false;
public bool LOG_RESENDS = false; /// <summary>Log packet retransmission info</summary>
public Helpers.LogLevel LOG_LEVEL = Helpers.LogLevel.Info; public bool LOG_RESENDS = true;
/// <summary>Log disk cache misses and other info</summary>
public bool LOG_DISKCACHE = true;
#endregion #endregion
#region Private Fields #region Private Fields
private GridClient Client; private GridClient Client;
private int priceUpload = 0; private int priceUpload = 0;
public static bool SORT_INVENTORY = false; public static bool SORT_INVENTORY = false;
@ -375,6 +387,5 @@ namespace OpenMetaverse
} }
#endregion #endregion
} }
} }