diff --git a/BSBshared/BotTypes/BasicBot.cs b/BSBshared/BotTypes/BasicBot.cs index 2580a80..e9b08ba 100644 --- a/BSBshared/BotTypes/BasicBot.cs +++ b/BSBshared/BotTypes/BasicBot.cs @@ -32,6 +32,7 @@ namespace BetterSecondBotShared.bottypes } protected Dictionary custom_commands = new Dictionary(); + public Dictionary getCustomCommands { get { return custom_commands; } } protected bool loaded_custom_commands = false; protected void LoadCustomCommands() { diff --git a/CLI/CliDocker.cs b/CLI/CliDocker.cs index bede28e..a455c7e 100644 --- a/CLI/CliDocker.cs +++ b/CLI/CliDocker.cs @@ -1,4 +1,5 @@ -using BetterSecondBotShared.IO; +using BetterSecondBot.DiscordSupervisor; +using BetterSecondBotShared.IO; using BetterSecondBotShared.Json; using BetterSecondBotShared.logs; using BetterSecondBotShared.Static; @@ -17,7 +18,7 @@ namespace BetterSecondBot LogFormater.Status("-> Getting config from Docker"); JsonConfig Config = MakeJsonConfig.FromENV(); Config = MakeJsonConfig.Http_config_check(Config); - new CliExitOnLogout(Config,true); + new DiscordTTS(Config,true); } } } diff --git a/CLI/CliExitOnLogout.cs b/CLI/CliExitOnLogout.cs index 2aa54ee..40fdc58 100644 --- a/CLI/CliExitOnLogout.cs +++ b/CLI/CliExitOnLogout.cs @@ -14,12 +14,35 @@ namespace BetterSecondBot { public class CliExitOnLogout { - public CliExitOnLogout(JsonConfig Config, bool as_docker) + public bool Exited { get { return exitBot; } } + protected bool exitBot = false; + public SecondBot Bot; + + protected void keep_alive() + { + while (Bot.KillMe == false) + { + string NewStatusMessage = Bot.GetStatus(); + if (NewStatusMessage != Bot.LastStatusMessage) + { + NewStatusMessage = NewStatusMessage.Trim(); + if (NewStatusMessage.Replace(" ", "") != "") + { + Bot.LastStatusMessage = NewStatusMessage; + Bot.Log2File(LogFormater.Status(Bot.LastStatusMessage, false), ConsoleLogLogLevel.Status); + } + } + Thread.Sleep(1000); + } + Bot.GetClient.Network.Logout(); + } + public CliExitOnLogout(JsonConfig Config, bool as_docker, bool use_self_keep_alive) { + exitBot = false; LogFormater.Status("Mode: Cli [Basic]"); if (helpers.botRequired(Config) == true) { - SecondBot Bot = new SecondBot(); + Bot = new SecondBot(); Bot.Setup(Config, AssemblyInfo.GetGitHash()); if(as_docker == true) { @@ -31,25 +54,18 @@ namespace BetterSecondBot SecondBotHttpServer my_http_server = new SecondBotHttpServer(); my_http_server.StartHttpServer(Bot, Config); } - while (Bot.KillMe == false) - { - string NewStatusMessage = Bot.GetStatus(); - if (NewStatusMessage != Bot.LastStatusMessage) - { - NewStatusMessage = NewStatusMessage.Trim(); - if (NewStatusMessage.Replace(" ", "") != "") - { - Bot.LastStatusMessage = NewStatusMessage; - Bot.Log2File(LogFormater.Status(Bot.LastStatusMessage, false), ConsoleLogLogLevel.Status); - } - } - Thread.Sleep(1000); + if(use_self_keep_alive == true) + { + keep_alive(); } - Bot.GetClient.Network.Logout(); } else { LogFormater.Warn("Required settings missing"); + } + if (use_self_keep_alive == true) + { + exitBot = true; } } } diff --git a/CLI/CliHardware.cs b/CLI/CliHardware.cs index 0f88b6f..6b9574f 100644 --- a/CLI/CliHardware.cs +++ b/CLI/CliHardware.cs @@ -5,6 +5,8 @@ using Newtonsoft.Json; using System; using static BetterSecondBot.Program; using BetterSecondBotShared.logs; +using BetterSecondBot.DiscordSupervisor; + namespace BetterSecondBot { public class CliHardware @@ -77,7 +79,7 @@ namespace BetterSecondBot if(ok_to_try_start == true) { Config = MakeJsonConfig.Http_config_check(Config); - new CliExitOnLogout(Config,false); + new DiscordTTS(Config, false); } } } diff --git a/Core/bottypes/Discord/ChannelControl.cs b/CLI/DiscordSupervisor/ChannelControl.cs similarity index 89% rename from Core/bottypes/Discord/ChannelControl.cs rename to CLI/DiscordSupervisor/ChannelControl.cs index c14fe68..28f06f8 100644 --- a/Core/bottypes/Discord/ChannelControl.cs +++ b/CLI/DiscordSupervisor/ChannelControl.cs @@ -5,12 +5,12 @@ using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; -namespace BSB.bottypes +namespace BetterSecondBot.DiscordSupervisor { - public abstract class DiscordBotChannelControl : DiscordBotFunctions + public abstract class DiscordChannelControl : DiscordFunctions { - protected async Task SendMessageToChannelAsync(string channelname, string message, string catmapid, UUID sender_id, string TopicType) + protected async Task SendMessageToChannelAsync(string channelname, string message, string catmapid, UUID sender_id, string TopicType) { if (AllowNewOutbound() == true) { @@ -20,9 +20,10 @@ namespace BSB.bottypes ITextChannel Channel = await FindTextChannel(channelname, catmap[catmapid], sender_id, TopicType).ConfigureAwait(false); if (Channel != null) { - await Channel.SendMessageAsync(message); + return await Channel.SendMessageAsync(message); } - } + } + return null; } protected async Task FindTextChannel(string channelname, ICategoryChannel cat, UUID sender, string TopicType) @@ -169,7 +170,10 @@ namespace BSB.bottypes } else if (sender_id == UUID.Zero.ToString()) { - display_topic = "" + myconfig.Basic_BotUserName + " #" + MyVersion + ""; + if (controler.Bot != null) + { + display_topic = "" + myconfig.Basic_BotUserName + " #" + controler.Bot.MyVersion + ""; + } } else if (channeltopictype == "Group") { @@ -242,13 +246,17 @@ namespace BSB.bottypes { _ = await FindTextChannel(A, catmap["bot"], UUID.Zero, "bot").ConfigureAwait(false); } - foreach (Group G in mygroups.Values) - { - string groupname = G.Name.ToLowerInvariant(); - groupname = String.Concat(groupname.Where(char.IsLetterOrDigit)); - if (GroupChannels.Contains(groupname) == false) - { - _ = await FindTextChannel(groupname, catmap["group"], G.ID, "Group").ConfigureAwait(false); + + if (HasBot() == true) + { + foreach (Group G in controler.Bot.MyGroups.Values) + { + string groupname = G.Name.ToLowerInvariant(); + groupname = String.Concat(groupname.Where(char.IsLetterOrDigit)); + if (GroupChannels.Contains(groupname) == false) + { + _ = await FindTextChannel(groupname, catmap["group"], G.ID, "Group").ConfigureAwait(false); + } } } } diff --git a/CLI/DiscordSupervisor/Discord-super.cs b/CLI/DiscordSupervisor/Discord-super.cs new file mode 100644 index 0000000..60adcd5 --- /dev/null +++ b/CLI/DiscordSupervisor/Discord-super.cs @@ -0,0 +1,72 @@ +using BetterSecondBotShared.Json; +using BetterSecondBotShared.logs; +using System; +using System.Collections.Generic; +using System.Text; +using System.Threading; + +namespace BetterSecondBot.DiscordSupervisor +{ + public class Discord_super : DiscordEvents + { + protected int warmup = 0; + protected override void keep_alive() + { + while (exit_super == false) + { + string NewStatusMessage = GetStatus(); + if (NewStatusMessage != LastStatusMessage) + { + NewStatusMessage = NewStatusMessage.Trim(); + if (DiscordClientConnected == true) + { + DiscordStatusUpdate(); + } + if (NewStatusMessage.Replace(" ", "") != "") + { + if (LastStatusMessage != NewStatusMessage) + { + LastStatusMessage = NewStatusMessage; + if (HasBasicBot() == true) + { + controler.Bot.Log2File(LogFormater.Status(LastStatusMessage, false), ConsoleLogLogLevel.Status); + } + else + { + Console.WriteLine(LastStatusMessage); + } + } + } + } + Thread.Sleep(1000); + } + } + public Discord_super(JsonConfig configfile, bool as_docker) + { + myconfig = configfile; + running_as_docker = as_docker; + startService(); + } + + protected void startService() + { + if (myconfig.DiscordFull_Enable == true) + { + _ = StartDiscordClientService(); + login_bot(false); + keep_alive(); + } + else + { + login_bot(true); + } + } + + protected override void login_bot(bool self_keep_alive) + { + controler = new CliExitOnLogout(myconfig, running_as_docker, self_keep_alive); + attach_events(); + } + + } +} diff --git a/CLI/DiscordSupervisor/DiscordBot.cs b/CLI/DiscordSupervisor/DiscordBot.cs new file mode 100644 index 0000000..c531f68 --- /dev/null +++ b/CLI/DiscordSupervisor/DiscordBot.cs @@ -0,0 +1,41 @@ +using System; +using System.Collections.Generic; +using OpenMetaverse; +using Discord; +using BetterSecondBotShared.Static; +using Discord.WebSocket; +using System.Threading.Tasks; +using System.Linq; + +namespace BetterSecondBot.DiscordSupervisor +{ + public abstract class DiscordBot : DiscordInbound + { + protected virtual async Task StartDiscordClientService() + { + DiscordClient = new DiscordSocketClient(); + DiscordClient.Ready += DiscordClientReady; + DiscordClient.LoggedOut += DiscordClientLoggedOut; + DiscordClient.MessageReceived += DiscordClientMessageReceived; + await DiscordClient.LoginAsync(TokenType.Bot, myconfig.DiscordFull_Token); + _ = DiscordClient.StartAsync(); + } + + protected virtual async Task DiscordClientReady() + { + DiscordServer = DiscordClient.GetGuild(myconfig.DiscordFull_ServerID); + if (DiscordServer != null) + { + DiscordUnixTimeOnine = helpers.UnixTimeNow(); + DiscordClientConnected = true; + await DiscordRebuildChannels(); + } + else + { + DiscordClientConnected = false; + } + return Task.CompletedTask; + } + + } +} diff --git a/CLI/DiscordSupervisor/DiscordEvents.cs b/CLI/DiscordSupervisor/DiscordEvents.cs new file mode 100644 index 0000000..c6751b4 --- /dev/null +++ b/CLI/DiscordSupervisor/DiscordEvents.cs @@ -0,0 +1,20 @@ +using BSB.bottypes; +using System; +using System.Collections.Generic; +using System.Text; + +namespace BetterSecondBot.DiscordSupervisor +{ + public class DiscordEvents : DiscordBot + { + protected void attach_events() + { + controler.Bot.MessageEvent += BotChatControlerHandler; + } + + protected void BotChatControlerHandler(object sender, MessageEventArgs e) + { + BotChatControler(e.message, e.sender_name, e.sender_uuid, e.avatar, e.group, e.group_uuid, e.localchat, e.fromme); + } + } +} diff --git a/Core/bottypes/DiscordTTS/DiscordTTS.cs b/CLI/DiscordSupervisor/DiscordTTS/DiscordTTS.cs similarity index 66% rename from Core/bottypes/DiscordTTS/DiscordTTS.cs rename to CLI/DiscordSupervisor/DiscordTTS/DiscordTTS.cs index 5d450bd..ff6e79e 100644 --- a/Core/bottypes/DiscordTTS/DiscordTTS.cs +++ b/CLI/DiscordSupervisor/DiscordTTS/DiscordTTS.cs @@ -6,24 +6,33 @@ using BetterSecondBotShared.Static; using Discord.WebSocket; using System.Threading.Tasks; using System.Linq; - -namespace BSB.bottypes +using BetterSecondBotShared.Json; + +namespace BetterSecondBot.DiscordSupervisor { - public abstract class DiscordBotTTS : DiscordBot + public class DiscordTTS : Discord_super { + public DiscordTTS(JsonConfig configfile, bool as_docker) : base(configfile, as_docker) + { + + } protected ITextChannel TTSchannel; protected IGuild TTSDiscordServer; protected override async Task DiscordClientReady() { - await base.DiscordClientReady(); - TTSDiscordServer = DiscordClient.GetGuild(myconfig.DiscordTTS_server_id); - if (TTSDiscordServer != null) - { - IGuildUser user = await TTSDiscordServer.GetCurrentUserAsync(); - await user.ModifyAsync(x => { - x.Nickname = myconfig.DiscordTTS_Nickname; - }); - FindTTsChannel(); + await base.DiscordClientReady(); + if (myconfig.DiscordTTS_Enable == true) + { + TTSDiscordServer = DiscordClient.GetGuild(myconfig.DiscordTTS_server_id); + if (TTSDiscordServer != null) + { + IGuildUser user = await TTSDiscordServer.GetCurrentUserAsync(); + await user.ModifyAsync(x => + { + x.Nickname = myconfig.DiscordTTS_Nickname; + }); + FindTTsChannel(); + } } return Task.CompletedTask; } @@ -38,7 +47,6 @@ namespace BSB.bottypes protected override async Task DiscordIMMessage(UUID sender_uuid, string sender_name, string message) { - await base.DiscordIMMessage(sender_uuid, sender_name, message); if (myconfig.DiscordTTS_Enable == true) { if ((helpers.notempty(sender_name) == true) && (helpers.notempty(message) == true)) diff --git a/Core/bottypes/Discord/Functions.cs b/CLI/DiscordSupervisor/Functions.cs similarity index 76% rename from Core/bottypes/Discord/Functions.cs rename to CLI/DiscordSupervisor/Functions.cs index 7d565b2..8ff9689 100644 --- a/Core/bottypes/Discord/Functions.cs +++ b/CLI/DiscordSupervisor/Functions.cs @@ -2,9 +2,9 @@ using System.Threading; using System.Threading.Tasks; -namespace BSB.bottypes +namespace BetterSecondBot.DiscordSupervisor { - public abstract class DiscordBotFunctions : Values + public abstract class DiscordFunctions : DiscordValues { protected Task WaitForUnlock() { @@ -38,14 +38,5 @@ namespace BSB.bottypes await DiscordClient.LogoutAsync(); } - public override void KillMePlease() - { - base.KillMePlease(); - if (DiscordClient != null) - { - _ = DiscordKillMePlease(); - } - } - } } diff --git a/CLI/DiscordSupervisor/Inbound.cs b/CLI/DiscordSupervisor/Inbound.cs new file mode 100644 index 0000000..0a50453 --- /dev/null +++ b/CLI/DiscordSupervisor/Inbound.cs @@ -0,0 +1,325 @@ +using Discord; +using Discord.WebSocket; +using OpenMetaverse; +using System; +using System.Text; +using System.Threading.Tasks; +using System.Linq; +using System.Threading; + +namespace BetterSecondBot.DiscordSupervisor +{ + public abstract class DiscordInbound : DiscordRelay + { + protected async Task InboundLocalchatMessage(IUserMessage message) + { + if (HasBot() == true) + { + IGuildUser user = (IGuildUser)message.Author; + controler.Bot.GetClient.Self.Chat(message.Content, 0, ChatType.Normal); + return await MarkMessage(message, "✅"); + } + return await MarkMessage(message, "❌"); + } + protected async Task InboundInterfaceMessage(IUserMessage message) + { + if (message.Content == "login") + { + if (HasBot() == true) + { + return await MarkMessage(message, "❌"); + } + login_bot(false); + return await MarkMessage(message, "✅").ConfigureAwait(false); + } + else if (message.Content == "logout") + { + if(HasBot() == false) + { + return await MarkMessage(message, "❌"); + } + controler.Bot.KillMePlease(); + return await MarkMessage(message, "✅").ConfigureAwait(false); + } + else if(message.Content == "exit") + { + if (HasBot() == true) + { + controler.Bot.KillMePlease(); + controler.Bot.GetClient.Network.Logout(); + } + exit_super = true; + return await MarkMessage(message, "✅").ConfigureAwait(false); + } + else + { + if (HasBot() == true) + { + StringBuilder output = new StringBuilder(); + if (message.Content.StartsWith("!")) + { + if (message.Content == "!commands") + { + int counter = 0; + string addon = ""; + foreach (string a in controler.Bot.GetCommandsInterface.GetCommandsList()) + { + output.Append(addon); + addon = " , "; + output.Append(a); + counter++; + if (counter == 5) + { + output.Append("\n"); + addon = ""; + counter = 0; + } + } + await SendMessageToChannelAsync("interface", output.ToString(), "bot", UUID.Zero, "bot"); + } + else if (message.Content.StartsWith("!help") == true) + { + string[] bits = message.Content.Split(' '); + if (bits.Length == 2) + { + string command = bits[1].ToLowerInvariant(); + + if (controler.Bot.GetCommandsInterface.GetCommandsList().Contains(command) == true) + { + output.Append("\n=========================\nCommand:"); + output.Append(command); + output.Append("\n"); + output.Append("Workspace: "); + output.Append(controler.Bot.GetCommandsInterface.GetCommandWorkspace(command)); + output.Append("\n"); + output.Append("Min args: "); + output.Append(controler.Bot.GetCommandsInterface.GetCommandArgs(command).ToString()); + output.Append("\n"); + output.Append("Arg types: "); + output.Append(String.Join(",", controler.Bot.GetCommandsInterface.GetCommandArgTypes(command))); + output.Append("\n"); + output.Append("\n"); + output.Append("About: "); + output.Append(controler.Bot.GetCommandsInterface.GetCommandHelp(command)); + await SendMessageToChannelAsync("interface", output.ToString(), "bot", UUID.Zero, "bot"); + } + else + { + output.Append("Unable to find command: "); + output.Append(command); + output.Append(" please use !commands for a full list"); + await SendMessageToChannelAsync("interface", output.ToString(), "bot", UUID.Zero, "bot"); + } + } + else + { + await SendMessageToChannelAsync("interface", "Please format help request as follows: !help commandname", "bot", UUID.Zero, "bot"); + } + } + else + { + output.Append("Unknown request: "); + output.Append(message.Content); + await SendMessageToChannelAsync("interface", output.ToString(), "bot", UUID.Zero, "bot"); + } + } + else + { + string[] bits = message.Content.Split("|||"); + string command = bits[0].ToLowerInvariant(); + bool known_command = controler.Bot.GetCommandsInterface.GetCommandsList().Contains(command); + if (known_command == false) + { + known_command = controler.Bot.getCustomCommands.ContainsKey(command); + } + if (known_command == true) + { + bool process_status = false; + if (bits.Length == 1) + { + bits = new string[] { bits[0], "" }; + } + if (controler.Bot.getCustomCommands.ContainsKey(command) == false) + { + process_status = controler.Bot.GetCommandsInterface.Call(command, bits[1], UUID.Zero); + } + else + { + process_status = true; + Thread t = new Thread(() => controler.Bot.custom_commands_loop(command, bits[1], UUID.Zero)); + t.Start(); + } + if (process_status == true) + { + await MarkMessage(message, "✅").ConfigureAwait(false); + } + else + { + await MarkMessage(message, "❌").ConfigureAwait(false); + } + } + else + { + output.Append("Unable to find command: "); + output.Append(command); + output.Append(" please use !commands for a full list"); + await SendMessageToChannelAsync("interface", output.ToString(), "bot", UUID.Zero, "bot"); + } + } + } + } + return Task.CompletedTask; + } + protected virtual async Task InboundImMessage(ITextChannel Chan, IUserMessage message) + { + if (HasBot() == true) + { + if (message.Content.StartsWith("!close")) + { + await Chan.DeleteAsync(); + } + else if (message.Content.StartsWith("!clear")) + { + await CleanDiscordChannel(Chan, 0, true); + } + else + { + string[] bits = Chan.Topic.Split(':'); + if (bits.Length >= 2) + { + if (bits[0] == "IM") + { + if (UUID.TryParse(bits[1], out UUID avatar) == true) + { + IGuildUser user = (IGuildUser)message.Author; + controler.Bot.GetClient.Self.InstantMessage(avatar, message.Content); + await MarkMessage(message, "✅"); + } + } + } + } + } + return Task.CompletedTask; + } + + protected async Task InboundGroupImMessage(ITextChannel Chan, IUserMessage message) + { + if (HasBot() == true) + { + string[] bits = Chan.Topic.Split(':'); + if (bits.Length >= 2) + { + if (bits[0] == "Group") + { + if (UUID.TryParse(bits[1], out UUID group) == true) + { + if (controler.Bot.MyGroups.ContainsKey(group) == true) + { + if (message.Content == "!clear") + { + await CleanDiscordChannel(Chan, 0, true).ConfigureAwait(false); + } + else if (message.Content.StartsWith("!notice") == true) + { + string Noticetitle = "Notice"; + string Noticemessage; + bits = message.Content.Split("|||", StringSplitOptions.None); + if (bits.Length == 2) + { + Noticetitle = bits[0]; + Noticemessage = bits[1]; + } + else + { + Noticemessage = bits[0]; + } + Noticetitle = Noticetitle.Replace("!notice ", ""); + Noticetitle = Noticetitle.Trim(); + controler.Bot.GetCommandsInterface.Call("GroupNotice", "" + group.ToString() + "~#~" + Noticetitle + "~#~" + Noticemessage, UUID.Zero); + await MarkMessage(message, "✅"); + } + else + { + IGuildUser user = (IGuildUser)message.Author; + controler.Bot.GetCommandsInterface.Call("Groupchat", "" + group.ToString() + "~#~" + message.Content, UUID.Zero); + await MarkMessage(message, "✅"); + } + } + } + } + } + } + else + { + await MarkMessage(message, "❌").ConfigureAwait(false); + } + return Task.CompletedTask; + } + + protected async Task MarkMessage(IUserMessage message,string emote) + { + var Tickmark = new Emoji(emote); + await message.AddReactionAsync(Tickmark, RequestOptions.Default); + return Task.CompletedTask; + } + + + + protected async Task DiscordClientMessageReceived(SocketMessage message) + { + if (AllowNewOutbound() == true) + { + if (message.Author.IsBot == false) + { + ITextChannel Chan = (ITextChannel)message.Channel; + if (message.Content.StartsWith("!clear") == true) + { + await CleanDiscordChannel(Chan, 0, true).ConfigureAwait(false); + } + else if (Chan.CategoryId == catmap["bot"].Id) + { + if (Chan.Name == "interface") + { + await InboundInterfaceMessage((IUserMessage)message).ConfigureAwait(false); + } + else if (Chan.Name == "localchat") + { + await InboundLocalchatMessage((IUserMessage)message).ConfigureAwait(false); + } + else if(Chan.Name == "status") + { + IUserMessage Message = await SendMessageToChannelAsync("interface", message.Content, "bot", UUID.Zero, "bot").ConfigureAwait(true); + if (Message == null) + { + await MarkMessage((IUserMessage)message, "❌").ConfigureAwait(false); + } + else + { + ITextChannel channel = await FindTextChannel(DiscordServer, "interface"); + if (channel != null) + { + await message.DeleteAsync().ConfigureAwait(false); + await InboundInterfaceMessage(Message).ConfigureAwait(false); + } + else + { + await MarkMessage((IUserMessage)message, "❌").ConfigureAwait(false); + } + } + + } + } + else if (Chan.CategoryId == catmap["im"].Id) + { + await InboundImMessage(Chan, (IUserMessage)message).ConfigureAwait(false); + } + else if (Chan.CategoryId == catmap["group"].Id) + { + await InboundGroupImMessage(Chan, (IUserMessage)message).ConfigureAwait(false); + } + } + } + return Task.CompletedTask; + } + } +} diff --git a/CLI/DiscordSupervisor/Status.cs b/CLI/DiscordSupervisor/Status.cs new file mode 100644 index 0000000..be0652c --- /dev/null +++ b/CLI/DiscordSupervisor/Status.cs @@ -0,0 +1,72 @@ +using OpenMetaverse; + +namespace BetterSecondBot.DiscordSupervisor +{ + public abstract class DiscordStatus : DiscordChannelControl + { + protected void DiscordStatusUpdate() + { + if (AllowNewOutbound() == true) + { + if (LastSendDiscordStatus != LastStatusMessage) + { + LastSendDiscordStatus = LastStatusMessage; + _ = SendMessageToChannelAsync("status", LastSendDiscordStatus, "bot", UUID.Zero, "bot"); + } + } + } + string DiscordBotStatus_laststatus = ""; + public string GetStatus() + { + string reply = ""; + if (myconfig.DiscordFull_Enable == true) + { + if (DiscordClientConnected == true) + { + reply = "[Discord-V: connected]"; + } + else + { + reply = "[Discord-V: Disconnected]"; + } + } + if (HasBasicBot() == false) + { + reply = reply + " (Not logged in)"; + } + if (reply != "") + { + reply = " " + reply; + } + if(reply == DiscordBotStatus_laststatus) + { + reply = ""; + } + else + { + DiscordBotStatus_laststatus = reply; + } + if(HasBasicBot() == true) + { + controler.Bot.LastStatusMessage = controler.Bot.GetStatus(); + reply = controler.Bot.LastStatusMessage + reply; + if (controler.Bot.KillMe == true) + { + controler.Bot.GetClient.Network.Logout(); + controler = null; + if (DiscordClientConnected == true) + { + reply = "[Discord-V: connected] (Logging out)"; + } + else + { + reply = "[Discord-V: Disconnected] (Logging out)"; + } + } + + } + return reply; + } + + } +} diff --git a/CLI/DiscordSupervisor/Values.cs b/CLI/DiscordSupervisor/Values.cs new file mode 100644 index 0000000..ce98fba --- /dev/null +++ b/CLI/DiscordSupervisor/Values.cs @@ -0,0 +1,57 @@ +using BetterSecondBotShared.Json; +using Discord; +using Discord.WebSocket; +using System.Collections.Generic; + +namespace BetterSecondBot.DiscordSupervisor +{ + public abstract class DiscordValues + { + protected JsonConfig myconfig; + protected bool exit_super = false; + protected CliExitOnLogout controler; + protected bool running_as_docker = false; + + protected bool discord_group_relay; + protected DiscordSocketClient DiscordClient; + protected bool DiscordClientConnected; + protected IGuild DiscordServer; + protected string LastSendDiscordStatus = ""; + protected long DiscordUnixTimeOnine; + protected bool DiscordLock; + protected string LastStatusMessage = ""; + + protected Dictionary catmap = new Dictionary(); + + protected virtual void login_bot(bool self_keepalive) + { + + } + + protected virtual void keep_alive() + { + + } + + protected bool HasBot() + { + if (HasBasicBot() == true) + { + return controler.Bot.GetClient.Network.Connected; + } + return false; + } + + protected bool HasBasicBot() + { + if (controler != null) + { + if (controler.Bot != null) + { + return true; + } + } + return false; + } + } +} diff --git a/CLI/DiscordSupervisor/relay.cs b/CLI/DiscordSupervisor/relay.cs new file mode 100644 index 0000000..3ef95cc --- /dev/null +++ b/CLI/DiscordSupervisor/relay.cs @@ -0,0 +1,129 @@ +using BetterSecondBotShared.Static; +using Discord.Webhook; +using OpenMetaverse; +using System.Threading.Tasks; + +namespace BetterSecondBot.DiscordSupervisor +{ + public abstract class DiscordRelay : DiscordStatus + { + public void SendIM(UUID avatar, string message) + { + if (HasBot() == true) + { + controler.Bot.SendIM(avatar, message); + if (controler.Bot.AvatarKey2Name.ContainsKey(avatar) == true) + { + if (DiscordClientConnected == true) + { + _ = SendMessageToChannelAsync(controler.Bot.AvatarKey2Name[avatar], "Bot/Script: " + message + "", "im", avatar, "IM").ConfigureAwait(false); + } + } + } + } + protected async Task DiscordGroupMessage(UUID group_uuid, string sender_name, string message) + { + if (HasBot() == true) + { + if ((helpers.notempty(sender_name) == true) && (helpers.notempty(message) == true)) + { + if (controler.Bot.MyGroups.ContainsKey(group_uuid) == true) + { + await SendMessageToChannelAsync(controler.Bot.MyGroups[group_uuid].Name, "" + sender_name + ": " + message + "", "group", group_uuid, "Group").ConfigureAwait(false); + } + } + } + } + protected virtual async Task DiscordIMMessage(UUID sender_uuid, string sender_name, string message) + { + if ((helpers.notempty(sender_name) == true) && (helpers.notempty(message) == true)) + { + await SendMessageToChannelAsync(sender_name, "" + sender_name + ": " + message + "", "im", sender_uuid, "IM").ConfigureAwait(false); + } + } + + protected async void BotChatControler(string message, string sender_name, UUID sender_uuid, bool avatar, bool group, UUID group_uuid, bool localchat, bool fromme) + { + await DiscordBotChatControler(message, sender_name, sender_uuid, avatar, group, group_uuid, localchat, fromme).ConfigureAwait(false); + } + + public string CommandHistoryAdd(string command, string arg, bool status, string WhyFailed) + { + if (HasBot() == true) + { + string output = controler.Bot.CommandHistoryAdd(command, arg, status, WhyFailed); + if (output != "") + { + _ = SendMessageToChannelAsync("interface", output, "bot", UUID.Zero, "bot"); + } + return output; + } + return ""; + } + + protected async Task DiscordBotChatControler(string message, string sender_name, UUID sender_uuid, bool avatar, bool group, UUID group_uuid, bool localchat, bool fromme) + { + if (HasBot() == true) + { + if (fromme == false) + { + if (discord_group_relay == true) + { + // GroupChat Relay only + if (group == true) + { + if (myconfig.DiscordRelay_URL != "") + { + if ((myconfig.DiscordRelay_GroupUUID == group_uuid.ToString()) || (myconfig.DiscordRelay_GroupUUID == "*") || (myconfig.DiscordRelay_GroupUUID == "all")) + { + Group Gr = controler.Bot.MyGroups[group_uuid]; + try + { + using var DWHclient = new DiscordWebhookClient(myconfig.DiscordRelay_URL); + string SendMessage = "(" + Gr.Name + ") @" + sender_name + ":" + message + ""; + await DWHclient.SendMessageAsync(text: SendMessage).ConfigureAwait(false); + DWHclient.Dispose(); + } + catch + { + controler.Bot.Info("Discord web hook has failed - marking as disabled untill next restart!"); + myconfig.DiscordRelay_URL = ""; + } + } + } + } + } + if (DiscordClientConnected == true) + { + if (avatar == true) + { + if (localchat == false) + { + if (group == true) + { + controler.Bot.Debug("DiscordBotChatControler - GroupChat:(" + group_uuid.ToString() + " -> " + sender_name + ":" + message); + await DiscordGroupMessage(group_uuid, sender_name, message).ConfigureAwait(false); + } + else + { + controler.Bot.Debug("DiscordBotChatControler - IM:" + sender_name + ":" + message); + await DiscordIMMessage(sender_uuid, sender_name, message).ConfigureAwait(false); + } + } + else + { + controler.Bot.Debug("DiscordBotChatControler - Localchat:" + sender_name + ":" + message); + await SendMessageToChannelAsync("localchat", "" + sender_name + ":" + message, "bot", UUID.Zero, "bot").ConfigureAwait(false); + } + } + else + { + controler.Bot.Debug("DiscordBotChatControler - Not from an avatar"); + } + } + } + } + return Task.CompletedTask; + } + } +} diff --git a/Core/bottypes/AVstorageBot.cs b/Core/bottypes/AVstorageBot.cs index 086f534..ea985be 100644 --- a/Core/bottypes/AVstorageBot.cs +++ b/Core/bottypes/AVstorageBot.cs @@ -15,8 +15,8 @@ namespace BSB.bottypes public UUID getMaster_uuid { get { return master_uuid; } } protected Dictionary AvatarStorageLastUsed = new Dictionary(); - protected Dictionary AvatarName2Key = new Dictionary(); - protected Dictionary AvatarKey2Name = new Dictionary(); + public Dictionary AvatarName2Key = new Dictionary(); + public Dictionary AvatarKey2Name = new Dictionary(); protected Dictionary> PendingAvatarFinds_vianame = new Dictionary>(); protected Dictionary> PendingAvatarFinds_viauuid = new Dictionary>(); diff --git a/Core/bottypes/CommandsBot.cs b/Core/bottypes/CommandsBot.cs index 31d3f28..b4a34aa 100644 --- a/Core/bottypes/CommandsBot.cs +++ b/Core/bottypes/CommandsBot.cs @@ -144,7 +144,7 @@ namespace BSB.bottypes } } - protected void custom_commands_loop(string command,string arg,UUID caller) + public void custom_commands_loop(string command,string arg,UUID caller) { List customargs = arg.Split(new[] { "~#~" }, StringSplitOptions.RemoveEmptyEntries).ToList(); while(customargs.Count < 5) diff --git a/Core/bottypes/DialogsBot.cs b/Core/bottypes/DialogsBot.cs index 0dd1999..d2f02c4 100644 --- a/Core/bottypes/DialogsBot.cs +++ b/Core/bottypes/DialogsBot.cs @@ -12,7 +12,7 @@ using System.Threading; namespace BSB.bottypes { - public abstract class DialogsBot : DiscordBotTTS + public abstract class DialogsBot : ChatRelay { protected bool TrackDialogs; protected int RelayDialogsToChannel; diff --git a/Core/bottypes/Discord/DiscordBot.cs b/Core/bottypes/Discord/DiscordBot.cs deleted file mode 100644 index b3d2aa4..0000000 --- a/Core/bottypes/Discord/DiscordBot.cs +++ /dev/null @@ -1,76 +0,0 @@ -using System; -using System.Collections.Generic; -using OpenMetaverse; -using Discord; -using BetterSecondBotShared.Static; -using Discord.WebSocket; -using System.Threading.Tasks; -using System.Linq; - -namespace BSB.bottypes -{ - public abstract class DiscordBot : DiscordBotInbound - { - protected override void AfterBotLoginHandler() - { - _ = DiscordBotAfterLogin(); - base.AfterBotLoginHandler(); - } - protected virtual async Task DiscordBotAfterLogin() - { - if (reconnect == false) - { - if (helpers.notempty(myconfig.DiscordFull_Token) == false) - { - myconfig.DiscordFull_Enable = false; - } - else if (myconfig.DiscordFull_ServerID <= 0) - { - myconfig.DiscordFull_Enable = false; - } - if (myconfig.DiscordFull_Enable == false) - { - if (helpers.notempty(myconfig.DiscordRelay_URL) == true) - { - if (helpers.notempty(myconfig.DiscordRelay_GroupUUID) == true) - { - if (UUID.TryParse(myconfig.DiscordRelay_GroupUUID, out UUID targetgroup) == true) - { - if (targetgroup != UUID.Zero) - { - discord_group_relay = true; - } - } - } - } - } - else - { - DiscordClient = new DiscordSocketClient(); - DiscordClient.Ready += DiscordClientReady; - DiscordClient.LoggedOut += DiscordClientLoggedOut; - DiscordClient.MessageReceived += DiscordClientMessageReceived; - await DiscordClient.LoginAsync(TokenType.Bot, myconfig.DiscordFull_Token); - _ = DiscordClient.StartAsync(); - } - } - } - - protected virtual async Task DiscordClientReady() - { - DiscordServer = DiscordClient.GetGuild(myconfig.DiscordFull_ServerID); - if (DiscordServer != null) - { - DiscordUnixTimeOnine = helpers.UnixTimeNow(); - DiscordClientConnected = true; - await DiscordRebuildChannels(); - } - else - { - DiscordClientConnected = false; - } - return Task.CompletedTask; - } - - } -} diff --git a/Core/bottypes/Discord/Inbound.cs b/Core/bottypes/Discord/Inbound.cs deleted file mode 100644 index 87b1765..0000000 --- a/Core/bottypes/Discord/Inbound.cs +++ /dev/null @@ -1,260 +0,0 @@ -using Discord; -using Discord.WebSocket; -using OpenMetaverse; -using System; -using System.Text; -using System.Threading.Tasks; -using System.Linq; -using System.Threading; - -namespace BSB.bottypes -{ - public abstract class DiscordBotInbound : DiscordBotRelay - { - protected async Task InboundLocalchatMessage(SocketMessage message) - { - IGuildUser user = (IGuildUser)message.Author; - Client.Self.Chat(message.Content, 0, ChatType.Normal); - return await MarkMessage(message, "✅"); - } - protected async Task InboundInterfaceMessage(SocketMessage message) - { - StringBuilder output = new StringBuilder(); - if (message.Content.StartsWith("!")) - { - if (message.Content == "!commands") - { - int counter = 0; - string addon = ""; - foreach (string a in CommandsInterface.GetCommandsList()) - { - output.Append(addon); - addon = " , "; - output.Append(a); - counter++; - if (counter == 5) - { - output.Append("\n"); - addon = ""; - counter = 0; - } - } - await SendMessageToChannelAsync("interface", output.ToString(), "bot", UUID.Zero, "bot"); - } - else if (message.Content.StartsWith("!help") == true) - { - string[] bits = message.Content.Split(' '); - if (bits.Length == 2) - { - string command = bits[1].ToLowerInvariant(); - - if (CommandsInterface.GetCommandsList().Contains(command) == true) - { - output.Append("\n=========================\nCommand:"); - output.Append(command); - output.Append("\n"); - output.Append("Workspace: "); - output.Append(CommandsInterface.GetCommandWorkspace(command)); - output.Append("\n"); - output.Append("Min args: "); - output.Append(CommandsInterface.GetCommandArgs(command).ToString()); - output.Append("\n"); - output.Append("Arg types: "); - output.Append(String.Join(",", CommandsInterface.GetCommandArgTypes(command))); - output.Append("\n"); - output.Append("\n"); - output.Append("About: "); - output.Append(CommandsInterface.GetCommandHelp(command)); - await SendMessageToChannelAsync("interface", output.ToString(), "bot", UUID.Zero, "bot"); - } - else - { - output.Append("Unable to find command: "); - output.Append(command); - output.Append(" please use !commands for a full list"); - await SendMessageToChannelAsync("interface", output.ToString(), "bot", UUID.Zero, "bot"); - } - } - else - { - await SendMessageToChannelAsync("interface", "Please format help request as follows: !help commandname", "bot", UUID.Zero, "bot"); - } - } - else - { - output.Append("Unknown request: "); - output.Append(message.Content); - await SendMessageToChannelAsync("interface", output.ToString(), "bot", UUID.Zero, "bot"); - } - } - else - { - string[] bits = message.Content.Split("|||"); - string command = bits[0].ToLowerInvariant(); - bool known_command = CommandsInterface.GetCommandsList().Contains(command); - if(known_command == false) - { - known_command = custom_commands.ContainsKey(command); - } - if (known_command == true) - { - bool process_status = false; - if(bits.Length == 1) - { - bits = new string[] { bits[0], "" }; - } - if (custom_commands.ContainsKey(command) == false) - { - process_status = CommandsInterface.Call(command, bits[1], UUID.Zero); - } - else - { - process_status = true; - Thread t = new Thread(() => custom_commands_loop(command, bits[1], UUID.Zero)); - t.Start(); - } - if (process_status == true) - { - await MarkMessage(message, "✅").ConfigureAwait(false); - } - else - { - await MarkMessage(message, "❌").ConfigureAwait(false); - } - } - else - { - output.Append("Unable to find command: "); - output.Append(command); - output.Append(" please use !commands for a full list"); - await SendMessageToChannelAsync("interface", output.ToString(), "bot", UUID.Zero, "bot"); - } - } - return Task.CompletedTask; - } - protected virtual async Task InboundImMessage(ITextChannel Chan, SocketMessage message) - { - if (message.Content.StartsWith("!close")) - { - await Chan.DeleteAsync(); - } - else if (message.Content.StartsWith("!clear")) - { - await CleanDiscordChannel(Chan, 0, true); - } - else - { - string[] bits = Chan.Topic.Split(':'); - if (bits.Length >= 2) - { - if (bits[0] == "IM") - { - if (UUID.TryParse(bits[1], out UUID avatar) == true) - { - IGuildUser user = (IGuildUser)message.Author; - Client.Self.InstantMessage(avatar, message.Content); - await MarkMessage(message, "✅"); - } - } - } - } - return Task.CompletedTask; - } - - protected async Task InboundGroupImMessage(ITextChannel Chan, SocketMessage message) - { - string[] bits = Chan.Topic.Split(':'); - if (bits.Length >= 2) - { - if (bits[0] == "Group") - { - if (UUID.TryParse(bits[1], out UUID group) == true) - { - if (mygroups.ContainsKey(group) == true) - { - if (message.Content == "!clear") - { - await CleanDiscordChannel(Chan, 0, true).ConfigureAwait(false); - } - else if (message.Content.StartsWith("!notice") == true) - { - string Noticetitle = "Notice"; - string Noticemessage; - bits = message.Content.Split("|||", StringSplitOptions.None); - if (bits.Length == 2) - { - Noticetitle = bits[0]; - Noticemessage = bits[1]; - } - else - { - Noticemessage = bits[0]; - } - Noticetitle = Noticetitle.Replace("!notice ", ""); - Noticetitle = Noticetitle.Trim(); - CommandsInterface.Call("GroupNotice", "" + group.ToString() + "~#~" + Noticetitle + "~#~" + Noticemessage, UUID.Zero); - await MarkMessage(message, "✅"); - } - else - { - IGuildUser user = (IGuildUser)message.Author; - CommandsInterface.Call("Groupchat", "" + group.ToString() + "~#~" + message.Content, UUID.Zero); - await MarkMessage(message, "✅"); - } - } - } - } - } - return Task.CompletedTask; - } - - protected async Task MarkMessage(SocketMessage message,string emote) - { - var Tickmark = new Emoji(emote); - await message.AddReactionAsync(Tickmark, RequestOptions.Default); - return Task.CompletedTask; - } - - protected async Task DiscordClientMessageReceived(SocketMessage message) - { - if (AllowNewOutbound() == true) - { - if (message.Author.IsBot == false) - { - if (Client.Network.Connected == false) - { - await message.DeleteAsync().ConfigureAwait(false); - } - else - { - ITextChannel Chan = (ITextChannel)message.Channel; - if (message.Content.StartsWith("!clear") == true) - { - await CleanDiscordChannel(Chan, 0, true).ConfigureAwait(false); - } - else if (Chan.CategoryId == catmap["bot"].Id) - { - if (Chan.Name == "interface") - { - await InboundInterfaceMessage(message).ConfigureAwait(false); - } - else if(Chan.Name == "localchat") - { - await InboundLocalchatMessage(message).ConfigureAwait(false); - } - } - else if (Chan.CategoryId == catmap["im"].Id) - { - await InboundImMessage(Chan, message).ConfigureAwait(false); - } - else if (Chan.CategoryId == catmap["group"].Id) - { - await InboundGroupImMessage(Chan, message).ConfigureAwait(false); - } - } - } - } - return Task.CompletedTask; - } - } -} diff --git a/Core/bottypes/Discord/Status.cs b/Core/bottypes/Discord/Status.cs deleted file mode 100644 index cdff0dd..0000000 --- a/Core/bottypes/Discord/Status.cs +++ /dev/null @@ -1,51 +0,0 @@ -using OpenMetaverse; - -namespace BSB.bottypes -{ - public abstract class DiscordBotStatus : DiscordBotChannelControl - { - protected void DiscordStatusUpdate() - { - if (AllowNewOutbound() == true) - { - if (LastSendDiscordStatus != LastStatusMessage) - { - LastSendDiscordStatus = LastStatusMessage; - _ = SendMessageToChannelAsync("status", LastSendDiscordStatus, "bot", UUID.Zero, "bot"); - } - } - } - string DiscordBotStatus_laststatus = ""; - public override string GetStatus() - { - string reply = ""; - if (myconfig.DiscordFull_Enable == true) - { - if (DiscordClientConnected == true) - { - reply = "[Discord: connected]"; - DiscordStatusUpdate(); - } - else - { - reply = "[Discord: Disconnected]"; - } - } - else if (discord_group_relay == true) - { - reply = " [Discord: Group Relay]"; - } - if (reply != "") - { - reply = " " + reply; - } - if (reply != DiscordBotStatus_laststatus) - { - DiscordBotStatus_laststatus = reply; - return base.GetStatus() + reply; - } - return base.GetStatus(); - } - - } -} diff --git a/Core/bottypes/Discord/Values.cs b/Core/bottypes/Discord/Values.cs deleted file mode 100644 index e0c85dc..0000000 --- a/Core/bottypes/Discord/Values.cs +++ /dev/null @@ -1,19 +0,0 @@ -using Discord; -using Discord.WebSocket; -using System.Collections.Generic; - -namespace BSB.bottypes -{ - public abstract class Values : ChatRelay - { - protected bool discord_group_relay; - protected DiscordSocketClient DiscordClient; - protected bool DiscordClientConnected; - protected IGuild DiscordServer; - protected string LastSendDiscordStatus = ""; - protected long DiscordUnixTimeOnine; - protected bool DiscordLock; - - protected Dictionary catmap = new Dictionary(); - } -} diff --git a/Core/bottypes/Discord/relay.cs b/Core/bottypes/Discord/relay.cs deleted file mode 100644 index 99aae4c..0000000 --- a/Core/bottypes/Discord/relay.cs +++ /dev/null @@ -1,114 +0,0 @@ -using BetterSecondBotShared.Static; -using Discord.Webhook; -using OpenMetaverse; -using System.Threading.Tasks; - -namespace BSB.bottypes -{ - public abstract class DiscordBotRelay : DiscordBotStatus - { - public override void SendIM(UUID avatar, string message) - { - base.SendIM(avatar, message); - if (AvatarKey2Name.ContainsKey(avatar) == true) - { - if (DiscordClientConnected == true) - { - _ = SendMessageToChannelAsync(AvatarKey2Name[avatar], "Bot/Script: " + message + "", "im", avatar, "IM").ConfigureAwait(false); - } - } - } - protected async Task DiscordGroupMessage(UUID group_uuid, string sender_name, string message) - { - if ((helpers.notempty(sender_name) == true) && (helpers.notempty(message) == true)) - { - if (mygroups.ContainsKey(group_uuid) == true) - { - await SendMessageToChannelAsync(mygroups[group_uuid].Name, "" + sender_name + ": " + message + "", "group", group_uuid, "Group").ConfigureAwait(false); - } - } - } - protected virtual async Task DiscordIMMessage(UUID sender_uuid, string sender_name, string message) - { - if ((helpers.notempty(sender_name) == true) && (helpers.notempty(message) == true)) - { - await SendMessageToChannelAsync(sender_name, "" + sender_name + ": " + message + "", "im", sender_uuid, "IM").ConfigureAwait(false); - } - } - protected async override void BotChatControler(string message, string sender_name, UUID sender_uuid, bool avatar, bool group, UUID group_uuid, bool localchat, bool fromme) - { - base.BotChatControler(message, sender_name, sender_uuid, avatar, group, group_uuid, localchat, fromme); - await DiscordBotChatControler(message, sender_name, sender_uuid, avatar, group, group_uuid, localchat, fromme).ConfigureAwait(false); - } - - public override string CommandHistoryAdd(string command, string arg, bool status, string WhyFailed) - { - string output = base.CommandHistoryAdd(command, arg, status, WhyFailed); - if (output != "") - { - _ = SendMessageToChannelAsync("interface", output, "bot", UUID.Zero, "bot"); - } - return output; - } - protected async Task DiscordBotChatControler(string message, string sender_name, UUID sender_uuid, bool avatar, bool group, UUID group_uuid, bool localchat, bool fromme) - { - if (fromme == false) - { - if (discord_group_relay == true) - { - // GroupChat Relay only - if (group == true) - { - if (myconfig.DiscordRelay_URL != "") - { - if ((myconfig.DiscordRelay_GroupUUID == group_uuid.ToString()) || (myconfig.DiscordRelay_GroupUUID == "*") || (myconfig.DiscordRelay_GroupUUID == "all")) - { - Group Gr = mygroups[group_uuid]; - try - { - using var DWHclient = new DiscordWebhookClient(myconfig.DiscordRelay_URL); - string SendMessage = "(" + Gr.Name + ") @" + sender_name + ":" + message + ""; - await DWHclient.SendMessageAsync(text: SendMessage).ConfigureAwait(false); - DWHclient.Dispose(); - } - catch { - Info("Discord web hook has failed - marking as disabled untill next restart!"); - myconfig.DiscordRelay_URL = ""; - } - } - } - } - } - if (DiscordClientConnected == true) - { - if (avatar == true) - { - if (localchat == false) - { - if (group == true) - { - Debug("DiscordBotChatControler - GroupChat:("+ group_uuid.ToString()+" -> " + sender_name + ":" + message); - await DiscordGroupMessage(group_uuid, sender_name, message).ConfigureAwait(false); - } - else - { - Debug("DiscordBotChatControler - IM:" + sender_name + ":" + message); - await DiscordIMMessage(sender_uuid, sender_name, message).ConfigureAwait(false); - } - } - else - { - Debug("DiscordBotChatControler - Localchat:" + sender_name + ":" + message); - await SendMessageToChannelAsync("localchat", "" + sender_name + ":" + message, "bot", UUID.Zero, "bot").ConfigureAwait(false); - } - } - else - { - Debug("DiscordBotChatControler - Not from an avatar"); - } - } - } - return Task.CompletedTask; - } - } -} diff --git a/Core/bottypes/EventsBot.cs b/Core/bottypes/EventsBot.cs index 14bc7fa..1b98023 100644 --- a/Core/bottypes/EventsBot.cs +++ b/Core/bottypes/EventsBot.cs @@ -59,14 +59,65 @@ namespace BSB.bottypes } + } + + public class MessageEventArgs : EventArgs + { + public string message { get; } + public string sender_name { get; } + public UUID sender_uuid { get; } + public bool avatar { get; } + public bool group { get; } + public UUID group_uuid { get; } + public bool localchat { get; } + public bool fromme { get; } + + public MessageEventArgs(string message, string sender_name, UUID sender_uuid, bool avatar, bool group, UUID group_uuid, bool localchat, bool fromme) + { + this.message = message; + this.sender_name = sender_name; + this.sender_uuid = sender_uuid; + this.avatar = avatar; + this.group = group; + this.group_uuid = group_uuid; + this.localchat = localchat; + this.fromme = fromme; + } } + public class EventsBot : VoidEventBot - { + { + private EventHandler _MessageEvent; + + private readonly object _MessageEventLock = new object(); + + /// Raised when a request we sent to friend another agent is accepted or declined + public event EventHandler MessageEvent + { + add { lock (_MessageEventLock) { _MessageEvent += value; } } + remove { lock (_MessageEventLock) { _MessageEvent -= value; } } + } + + protected void On_MessageEvent(MessageEventArgs e) + { + EventHandler handler = _MessageEvent; + handler?.Invoke(this, e); + } + + protected virtual void BotChatControler(string message, string sender_name, UUID sender_uuid, bool avatar, bool group, UUID group_uuid, bool localchat, bool fromme) + { + if (_MessageEvent != null) + { + On_MessageEvent(new MessageEventArgs(message, sender_name, sender_uuid, avatar, group, group_uuid, localchat, fromme)); + } + } + protected bool login_auto_logout; protected long delay_group_fetch; protected Dictionary>> group_members_storage = new Dictionary>>(); protected virtual void GroupMembersReplyHandler(object sender, GroupMembersReplyEventArgs e) { + } public bool FastCheckInGroup(UUID group,UUID avatar) diff --git a/Core/bottypes/MessageSwitcherBot.cs b/Core/bottypes/MessageSwitcherBot.cs index cfcf58f..d31b0a5 100644 --- a/Core/bottypes/MessageSwitcherBot.cs +++ b/Core/bottypes/MessageSwitcherBot.cs @@ -52,8 +52,9 @@ namespace BSB.bottypes { BotChatControler(message, sender_name, sender_uuid, avatar, group, group_uuid, localchat, false); } - protected virtual void BotChatControler(string message, string sender_name, UUID sender_uuid, bool avatar,bool group, UUID group_uuid, bool localchat,bool fromme) + protected override void BotChatControler(string message, string sender_name, UUID sender_uuid, bool avatar,bool group, UUID group_uuid, bool localchat,bool fromme) { + base.BotChatControler(message, sender_name, sender_uuid, avatar, group, group_uuid, localchat, fromme); if (fromme == false) { if (localchat == false) diff --git a/Core/bottypes/loadorder.txt b/Core/bottypes/loadorder.txt index 427812d..a456f07 100644 --- a/Core/bottypes/loadorder.txt +++ b/Core/bottypes/loadorder.txt @@ -1,6 +1,4 @@ -SecondBot -> DialogsBot -> DiscordBotTTS -> DiscordBot -> DiscordBotInbound -> -DiscordBotRelay -> DiscordBotStatus -> DiscordBotChannelControl -> -DiscordBotFunctions -> Values -> ChatRelay -> RLVbot -> RLVbotHelper -> -AwaitReplyEventBot -> CommandsBot -> AVstorageBot -> AtHome -> -MessageSwitcherBot -> EventsBot -> VoidEventBot -> AnimationsBot -> +SecondBot -> DialogsBot -> ChatRelay -> RLVbot -> RLVbotHelper -> +AwaitReplyEventBot -> CommandsBot -> AVstorageBot -> AtHome -> +MessageSwitcherBot -> EventsBot -> VoidEventBot -> AnimationsBot -> VirtualsBot -> Log2FileBot -> ActionsAutoAcceptBot -> BasicBot \ No newline at end of file diff --git a/libremetaverse-core/Libremetaverse/LibreMetaverse-core.csproj b/libremetaverse-core/Libremetaverse/LibreMetaverse-core.csproj index ca35b1f..0603d15 100644 --- a/libremetaverse-core/Libremetaverse/LibreMetaverse-core.csproj +++ b/libremetaverse-core/Libremetaverse/LibreMetaverse-core.csproj @@ -21,6 +21,14 @@ false linux-x64 + + + + + + Always + + @@ -41,6 +49,12 @@ Always + + Always + + + Always + Always diff --git a/libremetaverse-core/Libremetaverse/libopenjpeg-dotnet-2-1.5.0-dotnet-1-i686.so b/libremetaverse-core/Libremetaverse/libopenjpeg-dotnet-2-1.5.0-dotnet-1-i686.so new file mode 100644 index 0000000..193eca4 Binary files /dev/null and b/libremetaverse-core/Libremetaverse/libopenjpeg-dotnet-2-1.5.0-dotnet-1-i686.so differ diff --git a/libremetaverse-core/Libremetaverse/libopenjpeg-dotnet-2-1.5.0-dotnet-1-x86_64.so b/libremetaverse-core/Libremetaverse/libopenjpeg-dotnet-2-1.5.0-dotnet-1-x86_64.so new file mode 100644 index 0000000..7a9bdfc Binary files /dev/null and b/libremetaverse-core/Libremetaverse/libopenjpeg-dotnet-2-1.5.0-dotnet-1-x86_64.so differ diff --git a/libremetaverse-core/Libremetaverse/libopenjpeg-dotnet-2-1.5.0-dotnet-1.dylib b/libremetaverse-core/Libremetaverse/libopenjpeg-dotnet-2-1.5.0-dotnet-1.dylib new file mode 100644 index 0000000..91f7264 Binary files /dev/null and b/libremetaverse-core/Libremetaverse/libopenjpeg-dotnet-2-1.5.0-dotnet-1.dylib differ diff --git a/libremetaverse-core/Libremetaverse/openjpeg-dotnet-x86_64.dll b/libremetaverse-core/Libremetaverse/openjpeg-dotnet-x86_64.dll new file mode 100644 index 0000000..9e8cd21 Binary files /dev/null and b/libremetaverse-core/Libremetaverse/openjpeg-dotnet-x86_64.dll differ diff --git a/libremetaverse-core/Libremetaverse/openjpeg-dotnet.dll b/libremetaverse-core/Libremetaverse/openjpeg-dotnet.dll new file mode 100644 index 0000000..6377b8d Binary files /dev/null and b/libremetaverse-core/Libremetaverse/openjpeg-dotnet.dll differ diff --git a/libremetaverse-core/libopenjpeg-dotnet-2-1.5.0-dotnet-1-i686.so b/libremetaverse-core/libopenjpeg-dotnet-2-1.5.0-dotnet-1-i686.so new file mode 100644 index 0000000..193eca4 Binary files /dev/null and b/libremetaverse-core/libopenjpeg-dotnet-2-1.5.0-dotnet-1-i686.so differ diff --git a/libremetaverse-core/libopenjpeg-dotnet-2-1.5.0-dotnet-1-x86_64.so b/libremetaverse-core/libopenjpeg-dotnet-2-1.5.0-dotnet-1-x86_64.so new file mode 100644 index 0000000..7a9bdfc Binary files /dev/null and b/libremetaverse-core/libopenjpeg-dotnet-2-1.5.0-dotnet-1-x86_64.so differ diff --git a/libremetaverse-core/libopenjpeg-dotnet-2-1.5.0-dotnet-1.dylib b/libremetaverse-core/libopenjpeg-dotnet-2-1.5.0-dotnet-1.dylib new file mode 100644 index 0000000..91f7264 Binary files /dev/null and b/libremetaverse-core/libopenjpeg-dotnet-2-1.5.0-dotnet-1.dylib differ diff --git a/libremetaverse-core/openjpeg-dotnet-x86_64.dll b/libremetaverse-core/openjpeg-dotnet-x86_64.dll new file mode 100644 index 0000000..9e8cd21 Binary files /dev/null and b/libremetaverse-core/openjpeg-dotnet-x86_64.dll differ diff --git a/libremetaverse-core/openjpeg-dotnet.dll b/libremetaverse-core/openjpeg-dotnet.dll new file mode 100644 index 0000000..6377b8d Binary files /dev/null and b/libremetaverse-core/openjpeg-dotnet.dll differ