get rid of the MessageDistributor module... & update discord, to work with API v10
Added discord commands (issue: as they're running over the event hub, they're processed on the same track as other events. => activity ingame triggers the next run; otherwise there's some delay for responses) relay is a standard module now.
This commit is contained in:
@@ -13,6 +13,8 @@ from core.logger import Logger
|
|||||||
from core.registry import Registry
|
from core.registry import Registry
|
||||||
from core.upgrade import run_upgrades
|
from core.upgrade import run_upgrades
|
||||||
|
|
||||||
|
import faulthandler
|
||||||
|
faulthandler.enable()
|
||||||
|
|
||||||
def get_config_from_env():
|
def get_config_from_env():
|
||||||
config_obj = DictObject()
|
config_obj = DictObject()
|
||||||
|
|||||||
+2
-1
@@ -1,9 +1,10 @@
|
|||||||
class ChatBlob:
|
class ChatBlob:
|
||||||
def __init__(self, title, msg, prefix="", suffix=""):
|
def __init__(self, title, msg, prefix="", suffix="", embed=True):
|
||||||
self.title = title
|
self.title = title
|
||||||
self.msg = msg.strip("\n")
|
self.msg = msg.strip("\n")
|
||||||
self.page_prefix = prefix
|
self.page_prefix = prefix
|
||||||
self.page_postfix = suffix
|
self.page_postfix = suffix
|
||||||
|
self.embed = embed
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return f"ChatBlob('{self.title}', '{self.msg}')"
|
return f"ChatBlob('{self.title}', '{self.msg}')"
|
||||||
|
|||||||
+26
-16
@@ -66,6 +66,10 @@ class CommandService:
|
|||||||
self.register_command_channel("Private Message", self.PRIVATE_MESSAGE_CHANNEL)
|
self.register_command_channel("Private Message", self.PRIVATE_MESSAGE_CHANNEL)
|
||||||
self.register_command_channel("Org Channel", self.ORG_CHANNEL)
|
self.register_command_channel("Org Channel", self.ORG_CHANNEL)
|
||||||
self.register_command_channel("Private Channel", self.PRIVATE_CHANNEL)
|
self.register_command_channel("Private Channel", self.PRIVATE_CHANNEL)
|
||||||
|
self.relay_hub_service.register_message_source("tell_logger")
|
||||||
|
self.relay_hub_service.register_message_source("system_logger")
|
||||||
|
self.relay_hub_service.register_message_source("access_denied_logger")
|
||||||
|
self.relay_hub_service.register_message_source("member_logger")
|
||||||
|
|
||||||
def start(self):
|
def start(self):
|
||||||
access_levels = {}
|
access_levels = {}
|
||||||
@@ -205,16 +209,10 @@ class CommandService:
|
|||||||
if not followup:
|
if not followup:
|
||||||
if channel == "msg":
|
if channel == "msg":
|
||||||
if message.lower().startswith("mail"):
|
if message.lower().startswith("mail"):
|
||||||
self.relay_hub_service.send_message("tell_logger", char_id, "mail |usage hidden|",
|
self.relay_hub_service.send_message("tell_logger", DictObject({'char_id': char_id, 'name': self.character_service.resolve_char_to_name(char_id)}), f"[FROM] {self.character_service.resolve_char_to_name(char_id)}: mail |usage hidden|",
|
||||||
"mail |usage hidden|")
|
f"[FROM] {self.character_service.resolve_char_to_name(char_id)}: mail |usage hidden|")
|
||||||
else:
|
else:
|
||||||
self.relay_hub_service.send_message("tell_logger", char_id, message, message)
|
self.relay_hub_service.send_message("tell_logger", DictObject({'char_id': char_id, 'name': self.character_service.resolve_char_to_name(char_id)}), f"[FROM] {self.character_service.resolve_char_to_name(char_id)}: {message}", f"[FROM] {self.character_service.resolve_char_to_name(char_id)}: {message}")
|
||||||
else:
|
|
||||||
if message.lower().startswith("mail"):
|
|
||||||
self.relay_hub_service.send_message("dc_relay_log", char_id, "mail |usage hidden|",
|
|
||||||
"mail |usage hidden|")
|
|
||||||
else:
|
|
||||||
self.relay_hub_service.send_message("dc_relay_log", char_id, message, message)
|
|
||||||
# message = html.unescape(message)
|
# message = html.unescape(message)
|
||||||
command_str, command_args = self.get_command_parts(message)
|
command_str, command_args = self.get_command_parts(message)
|
||||||
|
|
||||||
@@ -253,12 +251,15 @@ class CommandService:
|
|||||||
self.relay_hub_service.send_message("access_denied_logger", sender,
|
self.relay_hub_service.send_message("access_denied_logger", sender,
|
||||||
f"[ERROR] {sender.name}: {message}",
|
f"[ERROR] {sender.name}: {message}",
|
||||||
f"[ERROR] {sender.name}: {message}")
|
f"[ERROR] {sender.name}: {message}")
|
||||||
self.bot.send_mass_message(char_id, self.getresp("global", "error_processing"))
|
if channel == "discord":
|
||||||
|
reply(self.getresp("global", "error_processing"))
|
||||||
|
else:
|
||||||
|
self.bot.send_mass_message(char_id, self.getresp("global", "error_processing"))
|
||||||
|
|
||||||
# record command usage
|
# record command usage
|
||||||
self.usage_service.add_usage(command_str, handler["callback"].__qualname__, char_id, channel)
|
self.usage_service.add_usage(command_str, handler["callback"].__qualname__, char_id, channel)
|
||||||
else:
|
else:
|
||||||
self.access_denied_response(message, sender, cmd_config, reply)
|
self.access_denied_response(message, sender, cmd_config, reply, channel)
|
||||||
else:
|
else:
|
||||||
# handlers were found, but no handler regex matched
|
# handlers were found, but no handler regex matched
|
||||||
help_text = self.get_help_text(char_id, command_str, channel)
|
help_text = self.get_help_text(char_id, command_str, channel)
|
||||||
@@ -266,7 +267,7 @@ class CommandService:
|
|||||||
reply(self.format_help_text(command_str, help_text))
|
reply(self.format_help_text(command_str, help_text))
|
||||||
else:
|
else:
|
||||||
# the command is known, but no help is returned, therefore user does not have access to command
|
# the command is known, but no help is returned, therefore user does not have access to command
|
||||||
self.access_denied_response(message, sender, cmd_config, reply)
|
self.access_denied_response(message, sender, cmd_config, reply, channel)
|
||||||
# if access_level['label'] != "all":
|
# if access_level['label'] != "all":
|
||||||
# self.relay_hub_service.send_message("access_denied_logger", sender,
|
# self.relay_hub_service.send_message("access_denied_logger", sender,
|
||||||
# f"[DENIED] {sender.name}: {message}",
|
# f"[DENIED] {sender.name}: {message}",
|
||||||
@@ -280,20 +281,29 @@ class CommandService:
|
|||||||
0)
|
0)
|
||||||
self.relay_hub_service.send_message("access_denied_logger", sender, f"[ERROR] {sender.name}: {message}",
|
self.relay_hub_service.send_message("access_denied_logger", sender, f"[ERROR] {sender.name}: {message}",
|
||||||
f"[ERROR] {sender.name}: {message}")
|
f"[ERROR] {sender.name}: {message}")
|
||||||
self.bot.send_mass_message(char_id, self.getresp("global", "error_processing"))
|
if channel == "discord":
|
||||||
|
reply(self.getresp("global", "error_processing"))
|
||||||
|
else:
|
||||||
|
self.bot.send_mass_message(char_id, self.getresp("global", "error_processing"))
|
||||||
|
|
||||||
def handle_unknown_command(self, command_str, command_args, channel, sender, reply):
|
def handle_unknown_command(self, command_str, command_args, channel, sender, reply):
|
||||||
self.relay_hub_service.send_message("access_denied_logger", sender,
|
self.relay_hub_service.send_message("access_denied_logger", sender,
|
||||||
f"[UNKNOWN] {sender.name}: {command_str} {command_args}",
|
f"[UNKNOWN] {sender.name}: {command_str} {command_args}",
|
||||||
f"[UNKNOWN] {sender.name}: {command_str} {command_args}")
|
f"[UNKNOWN] {sender.name}: {command_str} {command_args}")
|
||||||
if sender.access_level["label"] != "all":
|
if sender.access_level["label"] != "all":
|
||||||
self.bot.send_mass_message(sender.char_id, self.getresp("global", "unknown_command", {"cmd": command_str}))
|
if channel == "discord":
|
||||||
|
self.getresp("global", "unknown_command", {"cmd": command_str})
|
||||||
|
else:
|
||||||
|
self.bot.send_mass_message(sender.char_id, self.getresp("global", "unknown_command", {"cmd": command_str}))
|
||||||
|
|
||||||
def access_denied_response(self, message, sender, cmd_config, reply):
|
def access_denied_response(self, message, sender, cmd_config, reply, channel):
|
||||||
self.relay_hub_service.send_message("access_denied_logger", sender, f"[DENIED] {sender.name}: {message}",
|
self.relay_hub_service.send_message("access_denied_logger", sender, f"[DENIED] {sender.name}: {message}",
|
||||||
f"[DENIED] {sender.name}: {message}")
|
f"[DENIED] {sender.name}: {message}")
|
||||||
if sender.access_level["label"] != "all":
|
if sender.access_level["label"] != "all":
|
||||||
self.bot.send_mass_message(sender.char_id, self.getresp("global", "access_denied"))
|
if channel == "discord":
|
||||||
|
reply(self.getresp("global", "access_denied"))
|
||||||
|
else:
|
||||||
|
self.bot.send_mass_message(sender.char_id, self.getresp("global", "access_denied"))
|
||||||
|
|
||||||
def get_command_parts(self, message):
|
def get_command_parts(self, message):
|
||||||
parts = message.split(" ", 1)
|
parts = message.split(" ", 1)
|
||||||
|
|||||||
+2
-2
@@ -53,8 +53,8 @@ class Conn(Bot):
|
|||||||
if num_messages > 30:
|
if num_messages > 30:
|
||||||
self.logger.warning("automatically clearing outgoing message queue (%d messages)" % num_messages)
|
self.logger.warning("automatically clearing outgoing message queue (%d messages)" % num_messages)
|
||||||
self.packet_queue.clear()
|
self.packet_queue.clear()
|
||||||
elif num_messages > 10:
|
# elif num_messages > 10:
|
||||||
self.logger.warning("%d messages in outgoing message queue" % num_messages)
|
# self.logger.warning("%d messages in outgoing message queue" % num_messages)
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return self.id
|
return self.id
|
||||||
|
|||||||
+17
-9
@@ -1,6 +1,7 @@
|
|||||||
import inspect
|
import inspect
|
||||||
import threading
|
import threading
|
||||||
import time
|
import time
|
||||||
|
import typing
|
||||||
|
|
||||||
from conf.config import BotConfig
|
from conf.config import BotConfig
|
||||||
from core.aochat import server_packets, client_packets
|
from core.aochat import server_packets, client_packets
|
||||||
@@ -11,15 +12,19 @@ from core.conn import Conn
|
|||||||
from core.db import DB
|
from core.db import DB
|
||||||
from core.decorators import instance
|
from core.decorators import instance
|
||||||
from core.dict_object import DictObject
|
from core.dict_object import DictObject
|
||||||
|
|
||||||
from core.fifo_queue import FifoQueue
|
from core.fifo_queue import FifoQueue
|
||||||
from core.job_scheduler import JobScheduler
|
from core.job_scheduler import JobScheduler
|
||||||
from core.logger import Logger
|
from core.logger import Logger
|
||||||
from core.lookup.character_service import CharacterService
|
|
||||||
from core.public_channel_service import PublicChannelService
|
|
||||||
from core.setting_service import SettingService
|
|
||||||
from core.setting_types import BooleanSettingType
|
|
||||||
from core.text import Text
|
from core.text import Text
|
||||||
from modules.core.accounting.services.access_service import AccessService
|
from core.setting_types import BooleanSettingType
|
||||||
|
|
||||||
|
if typing.TYPE_CHECKING:
|
||||||
|
from core.lookup.character_service import CharacterService
|
||||||
|
from core.public_channel_service import PublicChannelService
|
||||||
|
from core.setting_service import SettingService
|
||||||
|
from modules.core.accounting.services.access_service import AccessService
|
||||||
|
from core.event_service import EventService
|
||||||
|
|
||||||
|
|
||||||
@instance("bot")
|
@instance("bot")
|
||||||
@@ -42,8 +47,8 @@ class IgnCore:
|
|||||||
self.dimension = None
|
self.dimension = None
|
||||||
self.last_timer_event = 0
|
self.last_timer_event = 0
|
||||||
self.start_time = int(time.time())
|
self.start_time = int(time.time())
|
||||||
self.major_version = "IGNCore v2.8"
|
self.major_version = "IGNCore v2.9"
|
||||||
self.minor_version = "4"
|
self.minor_version = "0"
|
||||||
self.incoming_queue = FifoQueue()
|
self.incoming_queue = FifoQueue()
|
||||||
self.mass_message_queue = None
|
self.mass_message_queue = None
|
||||||
self.conns = DictObject()
|
self.conns = DictObject()
|
||||||
@@ -55,7 +60,7 @@ class IgnCore:
|
|||||||
self.text: Text = registry.get_instance("text")
|
self.text: Text = registry.get_instance("text")
|
||||||
self.setting_service: SettingService = registry.get_instance("setting_service")
|
self.setting_service: SettingService = registry.get_instance("setting_service")
|
||||||
self.access_service: AccessService = registry.get_instance("access_service")
|
self.access_service: AccessService = registry.get_instance("access_service")
|
||||||
self.event_service = registry.get_instance("event_service")
|
self.event_service: EventService = registry.get_instance("event_service")
|
||||||
self.job_scheduler: JobScheduler = registry.get_instance("job_scheduler")
|
self.job_scheduler: JobScheduler = registry.get_instance("job_scheduler")
|
||||||
self.command_service = registry.get_instance("command_service")
|
self.command_service = registry.get_instance("command_service")
|
||||||
|
|
||||||
@@ -113,7 +118,7 @@ class IgnCore:
|
|||||||
"created_at INT NOT NULL, "
|
"created_at INT NOT NULL, "
|
||||||
"INDEX `command` (`command`) USING BTREE, "
|
"INDEX `command` (`command`) USING BTREE, "
|
||||||
"INDEX `char_id` (`char_id`) USING BTREE, "
|
"INDEX `char_id` (`char_id`) USING BTREE, "
|
||||||
"INDEX `channel` (`channel`) USING BTREE) ENGINE MEMORY")
|
"INDEX `channel` (`channel`) USING BTREE)")
|
||||||
|
|
||||||
# self.db.exec("UPDATE db_version SET verified = 0")
|
# self.db.exec("UPDATE db_version SET verified = 0")
|
||||||
self.db.exec("UPDATE db_version SET verified = 1 WHERE file = 'db_version'")
|
self.db.exec("UPDATE db_version SET verified = 1 WHERE file = 'db_version'")
|
||||||
@@ -440,5 +445,8 @@ class IgnCore:
|
|||||||
def get_char_name(self):
|
def get_char_name(self):
|
||||||
return self.conns["main"].char_name
|
return self.conns["main"].char_name
|
||||||
|
|
||||||
|
def get_conn(self):
|
||||||
|
return self.conns["main"]
|
||||||
|
|
||||||
def get_char_id(self):
|
def get_char_id(self):
|
||||||
return self.conns["main"].char_id
|
return self.conns["main"].char_id
|
||||||
|
|||||||
@@ -32,6 +32,8 @@ class Logger:
|
|||||||
def format_chat_message(self, msg):
|
def format_chat_message(self, msg):
|
||||||
msg = re.sub(r"<a\s+href=\".+?[^\\]\">", "[link]", msg, flags=re.UNICODE | re.DOTALL)
|
msg = re.sub(r"<a\s+href=\".+?[^\\]\">", "[link]", msg, flags=re.UNICODE | re.DOTALL)
|
||||||
msg = re.sub(r"<a\s+href='.+?'>", "[link]", msg, flags=re.UNICODE | re.DOTALL)
|
msg = re.sub(r"<a\s+href='.+?'>", "[link]", msg, flags=re.UNICODE | re.DOTALL)
|
||||||
|
msg = re.sub(r"<a\s+href=user://\w+?>(\w+?)</a>", "\1", msg, flags=re.UNICODE | re.DOTALL)
|
||||||
|
|
||||||
msg = re.sub(r"<font\s+.+?>", "", msg, flags=re.UNICODE)
|
msg = re.sub(r"<font\s+.+?>", "", msg, flags=re.UNICODE)
|
||||||
msg = re.sub("</font>", "", msg, flags=re.UNICODE)
|
msg = re.sub("</font>", "", msg, flags=re.UNICODE)
|
||||||
msg = re.sub("</a>", "[/link]", msg, flags=re.UNICODE)
|
msg = re.sub("</a>", "[/link]", msg, flags=re.UNICODE)
|
||||||
|
|||||||
@@ -50,7 +50,9 @@ class MessageHubService:
|
|||||||
f"Incorrect number of arguments for handler '{callback.__module__}.{callback.__name__}()'")
|
f"Incorrect number of arguments for handler '{callback.__module__}.{callback.__name__}()'")
|
||||||
|
|
||||||
if destination in self.hub:
|
if destination in self.hub:
|
||||||
raise Exception(f"Message hub destination '{destination}' already subscribed")
|
self.logger.error(f"Message hub destination '{destination}' already subscribed")
|
||||||
|
return
|
||||||
|
# raise Exception(f"Message hub destination '{destination}' already subscribed")
|
||||||
|
|
||||||
for source in default_sources:
|
for source in default_sources:
|
||||||
if source not in self.sources:
|
if source not in self.sources:
|
||||||
|
|||||||
@@ -39,6 +39,7 @@ class SettingService:
|
|||||||
if module.split(".")[0] not in self.bot.modules:
|
if module.split(".")[0] not in self.bot.modules:
|
||||||
return
|
return
|
||||||
setting.set_name(name)
|
setting.set_name(name)
|
||||||
|
setting.module = module
|
||||||
setting.set_description(description)
|
setting.set_description(description)
|
||||||
setting.set_extended_description(extended_description)
|
setting.set_extended_description(extended_description)
|
||||||
|
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ class SettingType:
|
|||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.setting_service = Registry.get_instance("setting_service")
|
self.setting_service = Registry.get_instance("setting_service")
|
||||||
self.name = None
|
self.name = None
|
||||||
|
self.module = ""
|
||||||
|
|
||||||
def set_name(self, name):
|
def set_name(self, name):
|
||||||
self.name = name
|
self.name = name
|
||||||
|
|||||||
@@ -274,4 +274,4 @@ class AccountController:
|
|||||||
rows = self.account_service.get_logs(alts[0].char_id, limit=20)
|
rows = self.account_service.get_logs(alts[0].char_id, limit=20)
|
||||||
for i in rows:
|
for i in rows:
|
||||||
response += self.account_service.format_entry(i)
|
response += self.account_service.format_entry(i)
|
||||||
return self.text.format_page(f"{alts[0].name}'s Account", response)
|
return ChatBlob(f"{alts[0].name}'s Account", response)
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
import typing
|
||||||
|
|
||||||
from core.buddy_service import BuddyService
|
from core.buddy_service import BuddyService
|
||||||
from core.chat_blob import ChatBlob
|
from core.chat_blob import ChatBlob
|
||||||
from core.command_alias_service import CommandAliasService
|
from core.command_alias_service import CommandAliasService
|
||||||
@@ -11,8 +13,9 @@ from core.text import Text
|
|||||||
from core.translation_service import TranslationService
|
from core.translation_service import TranslationService
|
||||||
from core.igncore import IgnCore
|
from core.igncore import IgnCore
|
||||||
from core.util import Util
|
from core.util import Util
|
||||||
from modules.core.accounting.services.account_service import AccountService
|
if typing.TYPE_CHECKING:
|
||||||
from modules.core.discord.discord_controller import DiscordController
|
from modules.core.accounting.services.account_service import AccountService
|
||||||
|
from modules.core.discord.discord_controller import DiscordController
|
||||||
|
|
||||||
|
|
||||||
@instance()
|
@instance()
|
||||||
|
|||||||
@@ -135,6 +135,12 @@
|
|||||||
"en_US": "Could not find setting <highlight>{setting}</highlight>.",
|
"en_US": "Could not find setting <highlight>{setting}</highlight>.",
|
||||||
"de_DE": "Die Einstellung <highlight>{setting}</highlight> wurde nicht gefunden."
|
"de_DE": "Die Einstellung <highlight>{setting}</highlight> wurde nicht gefunden."
|
||||||
},
|
},
|
||||||
|
|
||||||
|
"setting_owner": {
|
||||||
|
"en_US": "Setting owned by module: <highlight>{value}</highlight>\n",
|
||||||
|
"de_DE": "Diese Einstellung gehört zu dem Modul: <highlight>{value}</highlight>\n"
|
||||||
|
|
||||||
|
},
|
||||||
"current_value": {
|
"current_value": {
|
||||||
"en_US": "Current Value: <highlight>{value}</highlight>\n",
|
"en_US": "Current Value: <highlight>{value}</highlight>\n",
|
||||||
"de_DE": "Aktueller Wert: <highlight>{value}</highlight>\n"
|
"de_DE": "Aktueller Wert: <highlight>{value}</highlight>\n"
|
||||||
|
|||||||
@@ -160,6 +160,7 @@ class ConfigController:
|
|||||||
setting = self.setting_service.get(setting_name)
|
setting = self.setting_service.get(setting_name)
|
||||||
|
|
||||||
if setting:
|
if setting:
|
||||||
|
blob += self.getresp("module/config", "setting_owner", {"value": str(setting.module)})
|
||||||
blob += self.getresp("module/config", "current_value", {"value": str(setting.get_display_value())})
|
blob += self.getresp("module/config", "current_value", {"value": str(setting.get_display_value())})
|
||||||
blob += self.getresp("module/config", "description", {"desc": setting.get_description()})
|
blob += self.getresp("module/config", "description", {"desc": setting.get_description()})
|
||||||
if setting.get_extended_description():
|
if setting.get_extended_description():
|
||||||
|
|||||||
@@ -0,0 +1,382 @@
|
|||||||
|
import asyncio
|
||||||
|
import threading
|
||||||
|
import time
|
||||||
|
|
||||||
|
import re
|
||||||
|
from mailbox import Message
|
||||||
|
from typing import TYPE_CHECKING
|
||||||
|
|
||||||
|
from discord import Activity, ActivityType, Message, Embed
|
||||||
|
|
||||||
|
from core.aochat.BaseModule import BaseModule
|
||||||
|
from core.chat_blob import ChatBlob
|
||||||
|
from core.command_param_types import Const
|
||||||
|
|
||||||
|
from core.db import DB
|
||||||
|
from core.decorators import instance, command, event, timerevent
|
||||||
|
from core.dict_object import DictObject
|
||||||
|
from core.logger import Logger
|
||||||
|
from modules.core.ban.ban_service import BanService
|
||||||
|
|
||||||
|
if TYPE_CHECKING:
|
||||||
|
from modules.core.discord.discord_controller import DiscordController
|
||||||
|
from core.message_hub_service import MessageHubService
|
||||||
|
from core.command_service import CommandService
|
||||||
|
|
||||||
|
|
||||||
|
@instance()
|
||||||
|
class DiscordCommandHandler(BaseModule):
|
||||||
|
DISCORD_CHANNEL = "discord"
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
self.logger = Logger(__name__)
|
||||||
|
|
||||||
|
def inject(self, registry):
|
||||||
|
self.bot = registry.get_instance("bot")
|
||||||
|
self.discord: DiscordController = registry.get_instance("discord_controller")
|
||||||
|
self.db: DB = registry.get_instance("db")
|
||||||
|
self.relay_hub_service: MessageHubService = registry.get_instance("message_hub_service")
|
||||||
|
self.command_service: CommandService = registry.get_instance("command_service")
|
||||||
|
|
||||||
|
def pre_start(self):
|
||||||
|
self.command_service.register_command_channel("Discord", self.DISCORD_CHANNEL)
|
||||||
|
|
||||||
|
@event("discord_command", "should the bot take care of discord commands", False)
|
||||||
|
def discord_command_handler(self, _, event_data):
|
||||||
|
acc = event_data.account
|
||||||
|
ctx: Message = event_data.message
|
||||||
|
message = ctx.clean_content
|
||||||
|
if message.startswith(self.discord.setting_service.get("symbol").get_value()):
|
||||||
|
threading.Thread(target=self.command_service.process_command(
|
||||||
|
self.command_service.trim_command_symbol(message),
|
||||||
|
self.DISCORD_CHANNEL,
|
||||||
|
acc.main,
|
||||||
|
lambda msg: self.send_response(ctx, msg),
|
||||||
|
self.discord.bot.get_conn(),
|
||||||
|
False), daemon=True).start()
|
||||||
|
|
||||||
|
def send_response(self, ctx: Message, reply):
|
||||||
|
rsp = ""
|
||||||
|
embeds = []
|
||||||
|
if type(reply) == str:
|
||||||
|
reply = self.discord.text.format_message(reply)
|
||||||
|
rsp = f"> {self.parseDiscord(reply)}"
|
||||||
|
self.discord.relay_hub_service.send_message(f"Discord_({ctx.channel.name})",
|
||||||
|
DictObject({'char_id': 0, 'name': ctx.author.name,
|
||||||
|
'discord_handle':
|
||||||
|
f'{ctx.author.name}#{ctx.author.discriminator}'}),
|
||||||
|
reply, reply)
|
||||||
|
if type(reply) == ChatBlob:
|
||||||
|
if reply.embed:
|
||||||
|
embeds.append(Embed(title=self.parseDiscord(f"{reply.page_prefix} {reply.title} {reply.page_postfix}"),
|
||||||
|
color=0x00FF00,
|
||||||
|
description=self.parseDiscord(reply.msg).replace("\n> ", '\n')))
|
||||||
|
|
||||||
|
else:
|
||||||
|
reply: ChatBlob
|
||||||
|
rsp = self.parseDiscord(reply.page_prefix) + "\n"
|
||||||
|
if not (self.discord.text.strip_html_tags(reply.msg) or reply.msg).startswith(reply.title):
|
||||||
|
rsp += f"**__{reply.title}__**\n"
|
||||||
|
rsp += "> " + self.parseDiscord(reply.msg)
|
||||||
|
rsp += f"\n {self.parseDiscord(reply.page_postfix)}"
|
||||||
|
self.discord.relay_hub_service.send_message(f"Discord_({ctx.channel.name})",
|
||||||
|
DictObject({'char_id': 0, 'name': ctx.author.name,
|
||||||
|
'discord_handle':
|
||||||
|
f'{ctx.author.name}#{ctx.author.discriminator}'}),
|
||||||
|
reply, reply)
|
||||||
|
if len(rsp) > 2000:
|
||||||
|
rsp = self.discord.text.split_by_separators(rsp, 2000)
|
||||||
|
for page in rsp:
|
||||||
|
self.discord.client.loop.create_task(ctx.reply(page))
|
||||||
|
else:
|
||||||
|
self.discord.client.loop.create_task(ctx.reply(rsp, embeds=embeds))
|
||||||
|
|
||||||
|
def parseDiscord(self, ctx: str):
|
||||||
|
proficon = {1: "sold", 2: "ma", 3: "eng", 4: "fixer", 5: "agent", 6: "adv", 7: "trad", 8: "crat", 9: "enf",
|
||||||
|
10: "doc", 11: "nt", 12: "mp", 14: "keep", 15: "shade"}
|
||||||
|
m = re.findall(r"<img src='tdb://id:GFX_GUI_ICON_PROFESSION_(\d+)'>", ctx)
|
||||||
|
for match in m:
|
||||||
|
ctx = ctx.replace(f"<img src='tdb://id:GFX_GUI_ICON_PROFESSION_{match}'>",
|
||||||
|
f"#_{self.discord.util.get_profession(proficon.get(int(match)))}#_")
|
||||||
|
|
||||||
|
for x in ["`", ' *', ' _', ' |']:
|
||||||
|
ctx = ctx.replace(x, f' \\{x.strip()}')
|
||||||
|
for pattern, sub in [(r"(<br>|\n|</br>)", r"\n> "),
|
||||||
|
(r"<highlight>(.*?)</highlight>", r"**\1**"),
|
||||||
|
(r"<title>(.*?)</title>", r"**__\1__**"),
|
||||||
|
(r"<header>(.*?)</header>", r"**__\1__**"),
|
||||||
|
(r"<header2>(.*?)</header2>", r"__\1__"),
|
||||||
|
(r"<notice>(.*?)</notice>", r"*\1*"),
|
||||||
|
(r"<font color=('*?).+?\1>(.*?)</font>", r'\2'),
|
||||||
|
(r"<myname>", self.bot.get_char_name()),
|
||||||
|
(r"<symbol>", self.discord.setting_service.get_value("symbol")),
|
||||||
|
(r"<a href=(.*?)itemref://\d+/\d+/\d+\1>(.+?)<\/a>", r"`\2`"),
|
||||||
|
(r"<(.+?)>\s*?<\1>", ''),
|
||||||
|
(r"<pagebreak>", ''),
|
||||||
|
(r"<a.+?href=\'.*?\'>(.*?)</a>", r'`\1`'),
|
||||||
|
(r"<clan>(.*?)</clan>", r":yellow_circle: \1"),
|
||||||
|
(r"<omni>(.*?)</omni>", r":blue_circle: \1"),
|
||||||
|
(r"<neutral>(.*?)</neutral>", r":white_circle: \1"),
|
||||||
|
(r"<tab>", "\t"),
|
||||||
|
(r"<img src=(.?)rdb://\d+\1>", ''),
|
||||||
|
('#', ''),
|
||||||
|
('<', '<'),
|
||||||
|
('>', '>')]:
|
||||||
|
ctx = re.sub(pattern, sub, ctx)
|
||||||
|
|
||||||
|
cnt = 1
|
||||||
|
while cnt > 0:
|
||||||
|
ctx, cnt = re.subn(r"<(black|white|yellow|blue|green|red|orange|grey|cyan|violet)>(.*?|\d+?)</\1>", r"\2",
|
||||||
|
ctx)
|
||||||
|
|
||||||
|
ctx.rstrip()
|
||||||
|
ctx.rstrip(">")
|
||||||
|
return ctx
|
||||||
|
|
||||||
|
@command(command="discord", params=[Const("invite")], access_level="member",
|
||||||
|
description="Get a personal Discord invite", sub_command="invite")
|
||||||
|
def discord_invite_cmd(self, request, _):
|
||||||
|
if not self.discord.client:
|
||||||
|
return "Discord module has not been initiated yet. Please try again later."
|
||||||
|
account = self.discord.account_service.get_account(request.sender.char_id)
|
||||||
|
if account is None:
|
||||||
|
return "You do not have an account"
|
||||||
|
if account.disabled == 1:
|
||||||
|
return "Your account is disabled"
|
||||||
|
if account.discord_joined == 1:
|
||||||
|
return "You have already joined the Discord server"
|
||||||
|
if account.discord_invite != "":
|
||||||
|
for ginvite in self.discord.invites:
|
||||||
|
if ginvite.code == account.discord_invite:
|
||||||
|
asyncio.run_coroutine_threadsafe(self.discord.discord_delete_invite(ginvite), self.discord.loop)
|
||||||
|
invite = asyncio.run_coroutine_threadsafe(self.discord.discord_create_invite(account.name), self.discord.loop)
|
||||||
|
invite = invite.result()
|
||||||
|
self.discord.data.set_discord_invite(account.char_id, invite.code)
|
||||||
|
self.bot.send_mass_message(request.sender.char_id,
|
||||||
|
f"Your personal Discord invite is: {invite} \n"
|
||||||
|
f"This invite is only valid for 5 minutes.")
|
||||||
|
|
||||||
|
@command(command="discord", params=[Const("update")], access_level="member",
|
||||||
|
description="Update your discord information", sub_command="update")
|
||||||
|
def discord_update_cmd(self, request, _):
|
||||||
|
if not self.discord.client:
|
||||||
|
return "Discord module has not been initiated yet. Please try again later."
|
||||||
|
return self.discord.discord_update_account(request.sender.char_id)
|
||||||
|
|
||||||
|
@command(command="discord", params=[Const("disconnect")], access_level="admin",
|
||||||
|
description="Disconnect from Discord", sub_command="admin")
|
||||||
|
def discord_disconnect_cmd(self, _, _1):
|
||||||
|
if not self.discord.client:
|
||||||
|
return "Discord module has not been initiated yet. Please try again later."
|
||||||
|
if self.discord.client.is_closed():
|
||||||
|
return "Discord is already disconnected"
|
||||||
|
else:
|
||||||
|
asyncio.run_coroutine_threadsafe(self.discord.discord_disconnect(), self.discord.loop)
|
||||||
|
return "Disconnecting Discord"
|
||||||
|
|
||||||
|
@command(command="discord",
|
||||||
|
params=[Const("members")],
|
||||||
|
access_level="admin",
|
||||||
|
description="Get all discord members",
|
||||||
|
sub_command="members")
|
||||||
|
def discord_members_cmd(self, _, _1):
|
||||||
|
if not self.discord.client:
|
||||||
|
return "Discord module has not been initiated yet. Please try again later."
|
||||||
|
blob = ""
|
||||||
|
for member in self.discord.guild.members:
|
||||||
|
member_roles = []
|
||||||
|
for role in member.roles:
|
||||||
|
if role.name == "@everyone": # Skip @everyone as everyone has it.
|
||||||
|
continue
|
||||||
|
member_roles.append(f"{role.name}")
|
||||||
|
member_roles.sort(key=str.lower)
|
||||||
|
blob += f"{member.name + '#' + member.discriminator} ({', '.join(member_roles)})\n"
|
||||||
|
return ChatBlob(f"Discord Members ({len(self.discord.guild.members):d})", blob)
|
||||||
|
|
||||||
|
@event(event_type="connect", description="Connects the Discord client automatically on startup, if a token exists")
|
||||||
|
def handle_connect_event(self, _, _1):
|
||||||
|
token = self.discord.setting_discord_token().get_value()
|
||||||
|
if token.lower() in ["none", "", "null"]:
|
||||||
|
return
|
||||||
|
|
||||||
|
# noinspection PyTypeChecker
|
||||||
|
self.discord.loop = asyncio.get_event_loop()
|
||||||
|
self.discord.loop.create_task(self.discord.discord_connect(token))
|
||||||
|
self.discord.thread = threading.Thread(target=self.discord.run_it_forever, daemon=True)
|
||||||
|
self.discord.thread.start()
|
||||||
|
|
||||||
|
@event(event_type=BanService.BAN_ADDED_EVENT, description="Ban user from Discord")
|
||||||
|
def ban_added_event(self, _, event_data):
|
||||||
|
token = self.discord.setting_discord_token().get_value()
|
||||||
|
if token.lower() in ["none", "", "null"]:
|
||||||
|
return
|
||||||
|
account = self.discord.account_service.get_account(event_data.char_id)
|
||||||
|
if account.discord_joined == 1 and account.discord_id != "":
|
||||||
|
member = self.discord.guild.get_member(int(account.discord_id))
|
||||||
|
if member is not None:
|
||||||
|
ban = asyncio.run_coroutine_threadsafe(self.discord.discord_ban_user(member, event_data.reason),
|
||||||
|
self.discord.client.loop)
|
||||||
|
|
||||||
|
@event(event_type=BanService.BAN_REMOVED_EVENT, description="Remove Discord ban")
|
||||||
|
def ban_removed_event(self, _, event_data):
|
||||||
|
token = self.discord.setting_discord_token().get_value()
|
||||||
|
if token.lower() in ["none", "", "null"]:
|
||||||
|
return
|
||||||
|
account = self.discord.account_service.get_account(event_data.char_id)
|
||||||
|
if account.discord_id != "":
|
||||||
|
banlist = asyncio.run_coroutine_threadsafe(self.discord.discord_banlist(), self.discord.client.loop)
|
||||||
|
banlist = banlist.result()
|
||||||
|
for ban in banlist:
|
||||||
|
if ban.user.id == int(account.discord_id):
|
||||||
|
unban = asyncio.run_coroutine_threadsafe(self.discord.discord_unban_user(ban.user),
|
||||||
|
self.discord.client.loop)
|
||||||
|
|
||||||
|
@timerevent(budatime="1s", description="Handle Discord queue")
|
||||||
|
def timer_check_discord_queue(self, _, _1):
|
||||||
|
while self.discord.discord_queue:
|
||||||
|
t = int(time.time())
|
||||||
|
obj = self.discord.discord_queue.pop(0)
|
||||||
|
if obj.type == "on_member_remove":
|
||||||
|
member = obj.member
|
||||||
|
handle = member.name + "#" + member.discriminator
|
||||||
|
|
||||||
|
account = self.discord.data.get_account_discord_id(member.id)
|
||||||
|
if not account:
|
||||||
|
log = '**%s** has left discord (**%s**)' % (member.nick or member.name, handle)
|
||||||
|
self.relay_hub_service.send_message("system_logger", 0, log, log)
|
||||||
|
self.logger.info(log)
|
||||||
|
continue
|
||||||
|
main = self.discord.account_service.get_main(account.char_id)
|
||||||
|
if account is None:
|
||||||
|
continue
|
||||||
|
log = '**%s** has left discord (**%s**)' % (main.name, handle)
|
||||||
|
self.relay_hub_service.send_message("system_logger", 0, log, log)
|
||||||
|
self.logger.info(log)
|
||||||
|
# self.bot.send_private_channel_message("%s has left Discord (%s)" % (main.name, handle))
|
||||||
|
self.discord.data.set_discord_left(account.main)
|
||||||
|
if account.discord_handle != handle:
|
||||||
|
self.discord.data.set_discord_handle(member.id, handle)
|
||||||
|
if obj.type == "on_member_join":
|
||||||
|
member = obj.member
|
||||||
|
invite_used = obj.invite
|
||||||
|
handle = member.name + "#" + member.discriminator
|
||||||
|
if invite_used is None:
|
||||||
|
log = '**%s** joined discord with unknown invite' % handle
|
||||||
|
self.relay_hub_service. \
|
||||||
|
send_message("system_logger", 0,
|
||||||
|
log + f" {self.get_role('Administrator', self.guild.roles).mention}'s, "
|
||||||
|
f"check that!",
|
||||||
|
log + f" {self.get_role('Administrator', self.guild.roles).mention}'s, "
|
||||||
|
f"check that!")
|
||||||
|
self.logger.info(log)
|
||||||
|
continue
|
||||||
|
self.discord.guild = self.discord.client.get_guild(self.discord.client.guilds[0].id)
|
||||||
|
account = self.discord.data.get_discord_invite(invite_used.code)
|
||||||
|
if account is None:
|
||||||
|
log = '**%s** joined discord with invite **%s** but couldnt find account!' % (
|
||||||
|
handle, invite_used.code)
|
||||||
|
self.relay_hub_service. \
|
||||||
|
send_message("system_logger", 0,
|
||||||
|
log + f" {self.get_role('Administrator', self.guild.roles).mention}'s, "
|
||||||
|
f"check that!",
|
||||||
|
log + f" {self.get_role('Administrator', self.guild.roles).mention}'s, "
|
||||||
|
f"check that!")
|
||||||
|
self.logger.info(log)
|
||||||
|
asyncio.run_coroutine_threadsafe(self.discord.discord_member_roles(member, None, None),
|
||||||
|
self.discord.loop)
|
||||||
|
continue
|
||||||
|
|
||||||
|
main = self.discord.account_service.get_main(account.main)
|
||||||
|
self.discord.data.set_discord_joined(account.main, handle, member.id)
|
||||||
|
if self.discord.setting_service.get_value('is_alliance_bot') == '1':
|
||||||
|
nick = f"{f'[{self.discord.alias_controller.get_alias(main.org_id)}] '}{main.name}"
|
||||||
|
else:
|
||||||
|
nick = f"{main.name}"
|
||||||
|
nick = asyncio.run_coroutine_threadsafe(self.discord.discord_member_nick(member, nick),
|
||||||
|
self.discord.loop)
|
||||||
|
access_level = access_level = self.discord.access_service.get_access_level(account.main)
|
||||||
|
roles = asyncio.run_coroutine_threadsafe(
|
||||||
|
self.discord.discord_member_roles(member, account, access_level),
|
||||||
|
self.discord.loop)
|
||||||
|
# noinspection LongLine
|
||||||
|
log = '**%s** joined discord with invite **%s** and matches account **%s**' \
|
||||||
|
% (handle, invite_used.code,
|
||||||
|
f"{f'[{self.discord.alias_controller.get_alias(main.org_id)}] ' if self.discord.setting_service.get_value('is_alliance_bot') == '1' else ''}{main.name}")
|
||||||
|
self.relay_hub_service.send_message("system_logger", account.main, log, log)
|
||||||
|
self.logger.info(log)
|
||||||
|
|
||||||
|
@timerevent(budatime="1h", description="Verify Discord members", run_at_startup=True)
|
||||||
|
def timer_check_discord_members(self, event_type, event_data):
|
||||||
|
token = self.discord.setting_discord_token().get_value()
|
||||||
|
if token.lower() in ["none", "", "null"]:
|
||||||
|
return
|
||||||
|
if not self.bot.is_ready():
|
||||||
|
return
|
||||||
|
update = asyncio.run_coroutine_threadsafe(self.discord.discord_update_bot_basic(), self.discord.loop)
|
||||||
|
# Update accounts that have left/joined discord without the bot being online
|
||||||
|
accounts = self.db.query("SELECT * FROM account WHERE discord_id !=''")
|
||||||
|
for account in accounts:
|
||||||
|
match = False
|
||||||
|
for member in self.discord.guild.members:
|
||||||
|
handle = member.name + "#" + member.discriminator
|
||||||
|
if member.id == int(account.discord_id):
|
||||||
|
match = True
|
||||||
|
if account.discord_joined == 0:
|
||||||
|
self.discord.data.set_discord_joined(account.main, handle, member.id)
|
||||||
|
break
|
||||||
|
if match is False:
|
||||||
|
if account.discord_joined == 1:
|
||||||
|
self.discord.data.set_discord_left(account.main)
|
||||||
|
# Update current discord Members
|
||||||
|
accounts = self.discord.db.query("SELECT * FROM account WHERE discord_joined = 1 and char_id = main")
|
||||||
|
for member in self.discord.guild.members:
|
||||||
|
if member.id == self.discord.client.user.id:
|
||||||
|
continue
|
||||||
|
member_account = None
|
||||||
|
|
||||||
|
for account in list(accounts):
|
||||||
|
if int(account.discord_id) == member.id:
|
||||||
|
member_account = account
|
||||||
|
accounts.remove(account)
|
||||||
|
break
|
||||||
|
access_level = 0
|
||||||
|
if member_account is not None:
|
||||||
|
access_level = self.discord.access_service.get_access_level(member_account.main)
|
||||||
|
roles = asyncio.run_coroutine_threadsafe(
|
||||||
|
self.discord.discord_member_roles(member, member_account, access_level),
|
||||||
|
self.discord.loop)
|
||||||
|
if member_account is not None:
|
||||||
|
main = self.discord.pork.get_character_info(member_account.main)
|
||||||
|
# noinspection LongLine
|
||||||
|
nick = f"{f'[{self.discord.alias_controller.get_alias(main.org_id)}] ' if self.discord.setting_service.get_value('is_alliance_bot') == '1' else ''}{main.name}"
|
||||||
|
|
||||||
|
nick = asyncio.run_coroutine_threadsafe(self.discord.discord_member_nick(member, nick),
|
||||||
|
self.discord.loop)
|
||||||
|
|
||||||
|
@event(event_type="main_changed", description="Fix discord names & ranks")
|
||||||
|
def fix_ranks(self, _, data):
|
||||||
|
row = self.db.query_single("SELECT * from account where char_id=?", [data.old_main_id])
|
||||||
|
if row.discord_joined == 0:
|
||||||
|
self.logger.debug(f"{data.old_main_id} was not in discord, ignoring main fixing")
|
||||||
|
return
|
||||||
|
elif row.discord_joined == 1:
|
||||||
|
self.db.exec(
|
||||||
|
"UPDATE account set discord_handle=?, discord_id=?, discord_invite=?, discord_joined=? where char_id=?",
|
||||||
|
[row.discord_handle, row.discord_id, row.discord_invite, row.discord_joined, data.new_main_id])
|
||||||
|
self.db.exec(
|
||||||
|
"UPDATE account set discord_handle='', discord_id=0, discord_invite='', discord_joined=0 "
|
||||||
|
"where char_id=?",
|
||||||
|
[data.old_main_id])
|
||||||
|
self.logger.info(f"{data.old_main_id} was in discord, overwriting {data.new_main_id} with {data}")
|
||||||
|
|
||||||
|
self.discord.discord_update_account(data.new_main_id)
|
||||||
|
|
||||||
|
@timerevent(budatime="5m", description="update activity")
|
||||||
|
def change_count(self, _, _1):
|
||||||
|
if hasattr(self, "loop"):
|
||||||
|
count = self.db.query_single('SELECT count(*) as count from online '
|
||||||
|
'where char_id NOT IN (select char_id from org_bots) and bot=?',
|
||||||
|
[self.bot.get_char_id()]).count
|
||||||
|
act = Activity(type=ActivityType.listening,
|
||||||
|
name=f"{count} Players")
|
||||||
|
asyncio.run_coroutine_threadsafe(self.discord.client.change_presence(activity=act), self.discord.loop)
|
||||||
@@ -1,36 +1,38 @@
|
|||||||
import asyncio
|
import asyncio
|
||||||
import html
|
|
||||||
import logging
|
import logging
|
||||||
import re
|
import re
|
||||||
import threading
|
|
||||||
import time
|
import time
|
||||||
from asyncio import BaseEventLoop
|
from datetime import datetime, timedelta
|
||||||
|
from functools import partial
|
||||||
from html.parser import HTMLParser
|
from html.parser import HTMLParser
|
||||||
|
|
||||||
# noinspection PyPackageRequirements
|
# noinspection PyPackageRequirements
|
||||||
import discord
|
from typing import TYPE_CHECKING
|
||||||
import emojis as emojis
|
|
||||||
# noinspection PyPackageRequirements
|
|
||||||
from discord import Message, TextChannel, Guild, Embed, Role
|
|
||||||
|
|
||||||
|
# noinspection PyPackageRequirements
|
||||||
|
import discord
|
||||||
|
from discord import Message, TextChannel, Embed, Role, Guild
|
||||||
from core.chat_blob import ChatBlob
|
from core.chat_blob import ChatBlob
|
||||||
from core.command_param_types import Const
|
|
||||||
from core.db import DB
|
from core.db import DB
|
||||||
from core.decorators import instance, command, event, timerevent
|
from core.decorators import instance, event, timerevent
|
||||||
from core.dict_object import DictObject
|
from core.dict_object import DictObject
|
||||||
from core.logger import Logger
|
from core.logger import Logger
|
||||||
from core.lookup.character_service import CharacterService
|
from core.setting_types import HiddenSettingType, NumberSettingType, TextSettingType, BooleanSettingType
|
||||||
from core.lookup.pork_service import PorkService
|
|
||||||
from core.message_hub_service import MessageHubService
|
|
||||||
from core.setting_service import SettingService
|
|
||||||
from core.setting_types import HiddenSettingType
|
|
||||||
from core.text import Text
|
from core.text import Text
|
||||||
from core.igncore import IgnCore
|
from core.igncore import IgnCore
|
||||||
from core.util import Util
|
from core.util import Util
|
||||||
from modules.core.accounting.services.access_service import AccessService
|
from modules.core.discord.discord_data import DiscordData
|
||||||
from modules.core.accounting.services.account_service import AccountService
|
from modules.core.discord.discord_management import DiscordManager
|
||||||
from modules.core.ban.ban_service import BanService
|
|
||||||
from modules.onlinebot.online.org_alias_controller import OrgAliasController
|
if TYPE_CHECKING:
|
||||||
|
from modules.core.accounting.services.access_service import AccessService
|
||||||
|
from modules.core.accounting.services.account_service import AccountService
|
||||||
|
from modules.onlinebot.online.org_alias_controller import OrgAliasController
|
||||||
|
from modules.core.discord.discord_command_handler import DiscordCommandHandler
|
||||||
|
from core.lookup.character_service import CharacterService
|
||||||
|
from core.lookup.pork_service import PorkService
|
||||||
|
from core.message_hub_service import MessageHubService
|
||||||
|
from core.setting_service import SettingService
|
||||||
|
|
||||||
|
|
||||||
class MLStripper(HTMLParser):
|
class MLStripper(HTMLParser):
|
||||||
@@ -61,18 +63,11 @@ class DiscordController:
|
|||||||
logging.getLogger("discord.gateway").setLevel(logging.WARN)
|
logging.getLogger("discord.gateway").setLevel(logging.WARN)
|
||||||
logging.getLogger("discord.client").setLevel(logging.WARN)
|
logging.getLogger("discord.client").setLevel(logging.WARN)
|
||||||
intents = discord.Intents.all()
|
intents = discord.Intents.all()
|
||||||
|
intents.message_content = True
|
||||||
self.client = discord.Client(intents=intents, chunk_guilds_at_startup=True)
|
self.client = discord.Client(intents=intents, chunk_guilds_at_startup=True)
|
||||||
self.client.event(self.on_ready)
|
self.manager: DiscordManager = DiscordManager(self)
|
||||||
self.client.event(self.on_member_join)
|
|
||||||
self.client.event(self.on_member_remove)
|
|
||||||
self.client.event(self.on_member_update)
|
|
||||||
self.client.event(self.on_guild_role_delete)
|
|
||||||
self.client.event(self.on_guild_role_create)
|
|
||||||
self.client.event(self.on_guild_role_update)
|
|
||||||
self.client.event(self.on_invite_create)
|
|
||||||
self.client.event(self.on_invite_delete)
|
|
||||||
self.client.event(self.on_message)
|
self.client.event(self.on_message)
|
||||||
self.guild = None
|
self.guild: Guild = None
|
||||||
self.channel = None
|
self.channel = None
|
||||||
self.thread = None
|
self.thread = None
|
||||||
self.invites = None
|
self.invites = None
|
||||||
@@ -106,9 +101,17 @@ class DiscordController:
|
|||||||
self.account_service: AccountService = registry.get_instance("account_service")
|
self.account_service: AccountService = registry.get_instance("account_service")
|
||||||
self.setting_service: SettingService = registry.get_instance("setting_service")
|
self.setting_service: SettingService = registry.get_instance("setting_service")
|
||||||
|
|
||||||
|
self.data: DiscordData = DiscordData(self.db, self.client)
|
||||||
|
self.cmd: DiscordCommandHandler = registry.get_instance("discord_command_handler")
|
||||||
|
|
||||||
def pre_start(self):
|
def pre_start(self):
|
||||||
self.setting_service.register(self.module_name, "discord_token", "", HiddenSettingType(allow_empty=True),
|
self.setting_service.register(self.module_name, "discord_token", "", HiddenSettingType(allow_empty=True),
|
||||||
"Enter your Discord token here")
|
"Enter your Discord token here")
|
||||||
|
self.setting_service.register(self.module_name, "public_relay", "[0]", TextSettingType(),
|
||||||
|
"Public discord relay (purpose: autodelete messages after 1h)")
|
||||||
|
self.setting_service.register(self.module_name, "channel_blacklist", "[0]", TextSettingType(),
|
||||||
|
"Channels which should not trigger the command handler")
|
||||||
|
self.bot.event_service.register_event_type("discord_command")
|
||||||
|
|
||||||
def get_name(self, discord_id):
|
def get_name(self, discord_id):
|
||||||
data = self.db.query_single(
|
data = self.db.query_single(
|
||||||
@@ -118,242 +121,9 @@ class DiscordController:
|
|||||||
def setting_discord_token(self):
|
def setting_discord_token(self):
|
||||||
return self.setting_service.get("discord_token")
|
return self.setting_service.get("discord_token")
|
||||||
|
|
||||||
@command(command="discord", params=[Const("invite")], access_level="member",
|
|
||||||
description="Get a personal Discord invite", sub_command="invite")
|
|
||||||
def discord_invite_cmd(self, request, _):
|
|
||||||
if not self.client:
|
|
||||||
return "Discord module has not been initiated yet. Please try again later."
|
|
||||||
account = self.account_service.get_account(request.sender.char_id)
|
|
||||||
if account is None:
|
|
||||||
return "You do not have an account"
|
|
||||||
if account.disabled == 1:
|
|
||||||
return "Your account is disabled"
|
|
||||||
if account.discord_joined == 1:
|
|
||||||
return "You have already joined the Discord server"
|
|
||||||
if account.discord_invite != "":
|
|
||||||
for ginvite in self.invites:
|
|
||||||
if ginvite.code == account.discord_invite:
|
|
||||||
asyncio.run_coroutine_threadsafe(self.discord_delete_invite(ginvite), self.loop)
|
|
||||||
invite = asyncio.run_coroutine_threadsafe(self.discord_create_invite(account.name), self.loop)
|
|
||||||
invite = invite.result()
|
|
||||||
self.set_discord_invite(account.char_id, invite.code)
|
|
||||||
self.bot.send_mass_message(request.sender.char_id,
|
|
||||||
f"Your personal Discord invite is: {invite} \n"
|
|
||||||
f"This invite is only valid for 5 minutes.")
|
|
||||||
|
|
||||||
@command(command="discord", params=[Const("update")], access_level="member",
|
|
||||||
description="Update your discord information", sub_command="update")
|
|
||||||
def discord_update_cmd(self, request, _):
|
|
||||||
if not self.client:
|
|
||||||
return "Discord module has not been initiated yet. Please try again later."
|
|
||||||
return self.discord_update_account(request.sender.char_id)
|
|
||||||
|
|
||||||
@command(command="discord", params=[Const("disconnect")], access_level="admin",
|
|
||||||
description="Disconnect from Discord", sub_command="admin")
|
|
||||||
def discord_disconnect_cmd(self, _, _1):
|
|
||||||
if not self.client:
|
|
||||||
return "Discord module has not been initiated yet. Please try again later."
|
|
||||||
if self.client.is_closed():
|
|
||||||
return "Discord is already disconnected"
|
|
||||||
else:
|
|
||||||
asyncio.run_coroutine_threadsafe(self.discord_disconnect(), self.loop)
|
|
||||||
return "Disconnecting Discord"
|
|
||||||
|
|
||||||
@command(command="discord",
|
|
||||||
params=[Const("members")],
|
|
||||||
access_level="admin",
|
|
||||||
description="Get all discord members",
|
|
||||||
sub_command="members")
|
|
||||||
def discord_members_cmd(self, _, _1):
|
|
||||||
if not self.client:
|
|
||||||
return "Discord module has not been initiated yet. Please try again later."
|
|
||||||
blob = ""
|
|
||||||
for member in self.guild.members:
|
|
||||||
member_roles = []
|
|
||||||
for role in member.roles:
|
|
||||||
if role.name == "@everyone": # Skip @everyone as everyone has it.
|
|
||||||
continue
|
|
||||||
member_roles.append("%s" % role.name)
|
|
||||||
member_roles.sort(key=str.lower)
|
|
||||||
blob += "%s (%s)\n" % (member.name + "#" + member.discriminator, ", ".join(member_roles))
|
|
||||||
return ChatBlob("Discord Members (%d)" % (len(self.guild.members)), blob)
|
|
||||||
|
|
||||||
@event(event_type="connect", description="Connects the Discord client automatically on startup, if a token exists")
|
|
||||||
def handle_connect_event(self, _, _1):
|
|
||||||
token = self.setting_discord_token().get_value()
|
|
||||||
if token.lower() in ["none", "", "null"]:
|
|
||||||
return
|
|
||||||
|
|
||||||
# noinspection PyTypeChecker
|
|
||||||
self.loop: BaseEventLoop = asyncio.get_event_loop()
|
|
||||||
self.loop.create_task(self.discord_connect(token))
|
|
||||||
self.thread = threading.Thread(target=self.run_it_forever, daemon=True)
|
|
||||||
self.thread.start()
|
|
||||||
|
|
||||||
@event(event_type=BanService.BAN_ADDED_EVENT, description="Ban user from Discord")
|
|
||||||
def ban_added_event(self, _, event_data):
|
|
||||||
token = self.setting_discord_token().get_value()
|
|
||||||
if token.lower() in ["none", "", "null"]:
|
|
||||||
return
|
|
||||||
account = self.account_service.get_account(event_data.char_id)
|
|
||||||
if account.discord_joined == 1 and account.discord_id != "":
|
|
||||||
member = self.guild.get_member(int(account.discord_id))
|
|
||||||
if member is not None:
|
|
||||||
ban = asyncio.run_coroutine_threadsafe(self.discord_ban_user(member, event_data.reason), self.loop)
|
|
||||||
|
|
||||||
@event(event_type=BanService.BAN_REMOVED_EVENT, description="Remove Discord ban")
|
|
||||||
def ban_removed_event(self, _, event_data):
|
|
||||||
token = self.setting_discord_token().get_value()
|
|
||||||
if token.lower() in ["none", "", "null"]:
|
|
||||||
return
|
|
||||||
account = self.account_service.get_account(event_data.char_id)
|
|
||||||
if account.discord_id != "":
|
|
||||||
banlist = asyncio.run_coroutine_threadsafe(self.discord_banlist(), self.loop)
|
|
||||||
banlist = banlist.result()
|
|
||||||
for ban in banlist:
|
|
||||||
if ban.user.id == int(account.discord_id):
|
|
||||||
unban = asyncio.run_coroutine_threadsafe(self.discord_unban_user(ban.user), self.loop)
|
|
||||||
|
|
||||||
@timerevent(budatime="1s", description="Handle Discord queue")
|
|
||||||
def timer_check_discord_queue(self, _, _1):
|
|
||||||
while self.discord_queue:
|
|
||||||
t = int(time.time())
|
|
||||||
obj = self.discord_queue.pop(0)
|
|
||||||
if obj.type == "on_member_remove":
|
|
||||||
member = obj.member
|
|
||||||
handle = member.name + "#" + member.discriminator
|
|
||||||
|
|
||||||
account = self.get_account_discord_id(member.id)
|
|
||||||
if not account:
|
|
||||||
log = '**%s** has left discord (**%s**)' % (member.nick or member.name, handle)
|
|
||||||
self.relay_hub_service.send_message("system_logger", 0, log, log)
|
|
||||||
self.logger.info(log)
|
|
||||||
continue
|
|
||||||
main = self.account_service.get_main(account.char_id)
|
|
||||||
if account is None:
|
|
||||||
continue
|
|
||||||
log = '**%s** has left discord (**%s**)' % (main.name, handle)
|
|
||||||
self.relay_hub_service.send_message("system_logger", 0, log, log)
|
|
||||||
self.logger.info(log)
|
|
||||||
# self.bot.send_private_channel_message("%s has left Discord (%s)" % (main.name, handle))
|
|
||||||
self.set_discord_left(account.main)
|
|
||||||
if account.discord_handle != handle:
|
|
||||||
self.set_discord_handle(member.id, handle)
|
|
||||||
if obj.type == "on_member_join":
|
|
||||||
member = obj.member
|
|
||||||
invite_used = obj.invite
|
|
||||||
handle = member.name + "#" + member.discriminator
|
|
||||||
if invite_used is None:
|
|
||||||
log = '**%s** joined discord with unknown invite' % handle
|
|
||||||
self.relay_hub_service. \
|
|
||||||
send_message("system_logger", 0,
|
|
||||||
log + f" {self.get_role('Administrator', self.guild.roles).mention}'s, "
|
|
||||||
f"check that!",
|
|
||||||
log + f" {self.get_role('Administrator', self.guild.roles).mention}'s, "
|
|
||||||
f"check that!")
|
|
||||||
self.logger.info(log)
|
|
||||||
continue
|
|
||||||
self.guild: Guild = self.client.get_guild(self.client.guilds[0].id)
|
|
||||||
account = self.get_discord_invite(invite_used.code)
|
|
||||||
if account is None:
|
|
||||||
log = '**%s** joined discord with invite **%s** but couldnt find account!' % (
|
|
||||||
handle, invite_used.code)
|
|
||||||
self.relay_hub_service. \
|
|
||||||
send_message("system_logger", 0,
|
|
||||||
log + f" {self.get_role('Administrator', self.guild.roles).mention}'s, "
|
|
||||||
f"check that!",
|
|
||||||
log + f" {self.get_role('Administrator', self.guild.roles).mention}'s, "
|
|
||||||
f"check that!")
|
|
||||||
self.logger.info(log)
|
|
||||||
asyncio.run_coroutine_threadsafe(self.discord_member_roles(member, None, None), self.loop)
|
|
||||||
continue
|
|
||||||
|
|
||||||
main = self.account_service.get_main(account.main)
|
|
||||||
self.set_discord_joined(account.main, handle, member.id)
|
|
||||||
if self.setting_service.get_value('is_alliance_bot') == '1':
|
|
||||||
nick = f"{f'[{self.alias_controller.get_alias(main.org_id)}] '}{main.name}"
|
|
||||||
else:
|
|
||||||
nick = f"{main.name}"
|
|
||||||
nick = asyncio.run_coroutine_threadsafe(self.discord_member_nick(member, nick), self.loop)
|
|
||||||
access_level = access_level = self.access_service.get_access_level(account.main)
|
|
||||||
roles = asyncio.run_coroutine_threadsafe(self.discord_member_roles(member, account, access_level),
|
|
||||||
self.loop)
|
|
||||||
# noinspection LongLine
|
|
||||||
log = '**%s** joined discord with invite **%s** and matches account **%s**' \
|
|
||||||
% (handle, invite_used.code,
|
|
||||||
f"{f'[{self.alias_controller.get_alias(main.org_id)}] ' if self.setting_service.get_value('is_alliance_bot') == '1' else ''}{main.name}")
|
|
||||||
self.relay_hub_service.send_message("system_logger", account.main, log, log)
|
|
||||||
self.logger.info(log)
|
|
||||||
|
|
||||||
@timerevent(budatime="1h", description="Verify Discord members", run_at_startup=True)
|
|
||||||
def timer_check_discord_members(self, event_type, event_data):
|
|
||||||
token = self.setting_discord_token().get_value()
|
|
||||||
if token.lower() in ["none", "", "null"]:
|
|
||||||
return
|
|
||||||
if not self.bot.is_ready():
|
|
||||||
return
|
|
||||||
update = asyncio.run_coroutine_threadsafe(self.discord_update_bot_basic(), self.loop)
|
|
||||||
# Update accounts that have left/joined discord without the bot being online
|
|
||||||
accounts = self.db.query("SELECT * FROM account WHERE discord_id !=''")
|
|
||||||
for account in accounts:
|
|
||||||
match = False
|
|
||||||
for member in self.guild.members:
|
|
||||||
handle = member.name + "#" + member.discriminator
|
|
||||||
if member.id == int(account.discord_id):
|
|
||||||
match = True
|
|
||||||
if account.discord_joined == 0:
|
|
||||||
self.set_discord_joined(account.main, handle, member.id)
|
|
||||||
break
|
|
||||||
if match is False:
|
|
||||||
if account.discord_joined == 1:
|
|
||||||
self.set_discord_left(account.main)
|
|
||||||
# Update current discord Members
|
|
||||||
accounts = self.db.query("SELECT * FROM account WHERE discord_joined = 1 and char_id = main")
|
|
||||||
for member in self.guild.members:
|
|
||||||
if member.id == self.client.user.id:
|
|
||||||
continue
|
|
||||||
member_account = None
|
|
||||||
|
|
||||||
for account in list(accounts):
|
|
||||||
if int(account.discord_id) == member.id:
|
|
||||||
member_account = account
|
|
||||||
accounts.remove(account)
|
|
||||||
break
|
|
||||||
access_level = 0
|
|
||||||
if member_account is not None:
|
|
||||||
access_level = self.access_service.get_access_level(member_account.main)
|
|
||||||
roles = asyncio.run_coroutine_threadsafe(self.discord_member_roles(member, member_account, access_level),
|
|
||||||
self.loop)
|
|
||||||
if member_account is not None:
|
|
||||||
main = self.pork.get_character_info(member_account.main)
|
|
||||||
# noinspection LongLine
|
|
||||||
nick = f"{f'[{self.alias_controller.get_alias(main.org_id)}] ' if self.setting_service.get_value('is_alliance_bot') == '1' else ''}{main.name}"
|
|
||||||
|
|
||||||
nick = asyncio.run_coroutine_threadsafe(self.discord_member_nick(member, nick), self.loop)
|
|
||||||
|
|
||||||
def run_it_forever(self):
|
def run_it_forever(self):
|
||||||
self.loop.run_forever()
|
self.loop.run_forever()
|
||||||
|
|
||||||
def set_discord_invite(self, char_id, invite):
|
|
||||||
return self.db.exec("UPDATE account SET discord_invite = ? WHERE main = ?", [invite, char_id])
|
|
||||||
|
|
||||||
def set_discord_joined(self, char_id, handle, discord_id):
|
|
||||||
return self.db.exec("UPDATE account SET discord_joined = 1, discord_handle = ?, discord_id = ? WHERE main = ?",
|
|
||||||
[handle, discord_id, char_id])
|
|
||||||
|
|
||||||
def set_discord_left(self, char_id):
|
|
||||||
return self.db.exec("UPDATE account SET discord_joined = 0 WHERE main = ?", [char_id])
|
|
||||||
|
|
||||||
def set_discord_handle(self, discord_id, handle):
|
|
||||||
return self.db.exec("UPDATE account SET discord_handle = ? WHERE discord_id = ?", [handle, discord_id])
|
|
||||||
|
|
||||||
def get_discord_invite(self, invite):
|
|
||||||
return self.db.query_single("SELECT * FROM account WHERE discord_invite = ?", [invite])
|
|
||||||
|
|
||||||
def get_account_discord_id(self, discord_id):
|
|
||||||
return self.db.query_single(
|
|
||||||
"SELECT * FROM account a left join player p on a.char_id=p.char_id WHERE discord_id = ?", [discord_id])
|
|
||||||
|
|
||||||
def discord_update_account(self, char_id):
|
def discord_update_account(self, char_id):
|
||||||
account = self.account_service.get_account(char_id)
|
account = self.account_service.get_account(char_id)
|
||||||
if account is None:
|
if account is None:
|
||||||
@@ -371,65 +141,12 @@ class DiscordController:
|
|||||||
return "Processing..."
|
return "Processing..."
|
||||||
return "No Discord account found"
|
return "No Discord account found"
|
||||||
|
|
||||||
def discord_invite_used(self, temp_invites):
|
|
||||||
for temp_invite in temp_invites:
|
|
||||||
# if temp_invite.inviter.id == self.client.user.id:
|
|
||||||
# ## Using this line limits it to invite created by the account the Discord bot runs as..
|
|
||||||
for invite in self.invites:
|
|
||||||
if int(temp_invite.uses) > int(invite.uses) and temp_invite.code == invite.code:
|
|
||||||
return temp_invite
|
|
||||||
return None
|
|
||||||
|
|
||||||
def get_role(self, name, roles) -> Role or None:
|
def get_role(self, name, roles) -> Role or None:
|
||||||
for role in roles:
|
for role in roles:
|
||||||
if role.name == name:
|
if role.name == name:
|
||||||
return role
|
return role
|
||||||
return None
|
return None
|
||||||
|
|
||||||
async def on_member_join(self, member):
|
|
||||||
temp_invites = await self.guild.invites()
|
|
||||||
invite_used = self.discord_invite_used(temp_invites)
|
|
||||||
self.discord_queue.append(DictObject({"type": "on_member_join", "member": member, "invite": invite_used}))
|
|
||||||
await invite_used.delete()
|
|
||||||
|
|
||||||
async def on_member_remove(self, member):
|
|
||||||
self.discord_queue.append(DictObject({"type": "on_member_remove", "member": member}))
|
|
||||||
await self.discord_update_bot_full()
|
|
||||||
|
|
||||||
async def on_ready(self):
|
|
||||||
await self.discord_update_bot_full()
|
|
||||||
count = self.db.query_single('SELECT count(*) as count from online '
|
|
||||||
'where char_id NOT IN (select char_id from org_bots) and bot=?',
|
|
||||||
[self.bot.get_char_id()]).count
|
|
||||||
|
|
||||||
act = discord.Activity(type=discord.ActivityType.listening,
|
|
||||||
name=f"{count} Players")
|
|
||||||
asyncio.run_coroutine_threadsafe(self.client.change_presence(activity=act), self.loop)
|
|
||||||
await self.clean_channel()
|
|
||||||
|
|
||||||
if self.guild.large:
|
|
||||||
self.logger.error(
|
|
||||||
f"Guild {self.guild.name} is classified as large, "
|
|
||||||
f"you need to request offline members to manage roles properly, this is not yet implemented")
|
|
||||||
|
|
||||||
async def on_member_update(self, member_before, member_after):
|
|
||||||
await self.discord_update_bot_basic()
|
|
||||||
|
|
||||||
async def on_guild_role_create(self, role):
|
|
||||||
await self.discord_update_bot_full()
|
|
||||||
|
|
||||||
async def on_guild_role_delete(self, role):
|
|
||||||
await self.discord_update_bot_full()
|
|
||||||
|
|
||||||
async def on_guild_role_update(self, role_before, role_after):
|
|
||||||
await self.discord_update_bot_full()
|
|
||||||
|
|
||||||
async def on_invite_create(self, invite):
|
|
||||||
await self.discord_update_bot_full()
|
|
||||||
|
|
||||||
async def on_invite_delete(self, invite):
|
|
||||||
await self.discord_update_bot_full()
|
|
||||||
|
|
||||||
async def discord_update_bot_basic(self):
|
async def discord_update_bot_basic(self):
|
||||||
self.guild = self.client.get_guild(self.client.guilds[0].id)
|
self.guild = self.client.get_guild(self.client.guilds[0].id)
|
||||||
self.channel = self.client.get_channel(self.guild.text_channels[0].id)
|
self.channel = self.client.get_channel(self.guild.text_channels[0].id)
|
||||||
@@ -448,7 +165,37 @@ class DiscordController:
|
|||||||
await self.client.start(token)
|
await self.client.start(token)
|
||||||
|
|
||||||
except discord.ClientException as exc:
|
except discord.ClientException as exc:
|
||||||
self.logger.error("Something broke, I'm out!: %s" % str(exc))
|
self.logger.error(f"Something broke, I'm out!: {str(exc)}")
|
||||||
|
|
||||||
|
async def setup_relayhub(self):
|
||||||
|
for channel in self.guild.channels:
|
||||||
|
if type(channel) == TextChannel:
|
||||||
|
channel: TextChannel
|
||||||
|
self.relay_hub_service.register_message_source(f"Discord_({channel.name.replace(' ', '_')})")
|
||||||
|
self.relay_hub_service.register_message_destination(f"Discord_({channel.name.replace(' ', '_')})",
|
||||||
|
partial(self.relay, channel.id), [], [f"Discord_({channel.name.replace(' ', '_')})"])
|
||||||
|
|
||||||
|
def relay(self, channel, ctx):
|
||||||
|
ch: TextChannel = self.guild.get_channel(channel)
|
||||||
|
msg = ctx.formatted_message
|
||||||
|
del_after = 3600 if f"{ch.id}" in self.setting_service.get_value("public_relay").lstrip("[").rstrip("]").split(',') else None
|
||||||
|
if ctx.source == "alliance":
|
||||||
|
msg = self.cmd.parseDiscord(ctx.message)
|
||||||
|
elif type(msg) == ChatBlob:
|
||||||
|
if msg.embed:
|
||||||
|
msg: ChatBlob
|
||||||
|
blob = Embed(title=msg.title, color=0x00FF00, description=self.cmd.parseDiscord(msg.msg).replace("\n> ", '\n'))
|
||||||
|
asyncio.run_coroutine_threadsafe(ch.send("", delete_after=del_after, embed=blob), self.loop)
|
||||||
|
return
|
||||||
|
rsp = self.cmd.parseDiscord(ctx.formatted_message.page_prefix) + "\n"
|
||||||
|
if not self.text.strip_html_tags(ctx.formatted_message.msg).startswith(ctx.formatted_message.title):
|
||||||
|
rsp += f"**__{ctx.formatted_message.title}__**\n"
|
||||||
|
rsp += "> " + self.cmd.parseDiscord(ctx.formatted_message.msg)
|
||||||
|
rsp += f"\n {self.cmd.parseDiscord(ctx.formatted_message.page_postfix)}"
|
||||||
|
msg = rsp
|
||||||
|
else:
|
||||||
|
msg = self.cmd.parseDiscord(ctx.formatted_message)
|
||||||
|
msg: Message = asyncio.run_coroutine_threadsafe(ch.send(msg, delete_after=del_after), self.loop)
|
||||||
|
|
||||||
async def discord_create_invite(self, reason=""):
|
async def discord_create_invite(self, reason=""):
|
||||||
created_invite = await self.channel.create_invite(max_age=300, max_uses=2, reason=reason)
|
created_invite = await self.channel.create_invite(max_age=300, max_uses=2, reason=reason)
|
||||||
@@ -578,28 +325,29 @@ class DiscordController:
|
|||||||
await discord_user.remove_roles(role)
|
await discord_user.remove_roles(role)
|
||||||
|
|
||||||
async def on_message(self, msg: Message):
|
async def on_message(self, msg: Message):
|
||||||
|
if f"{msg.channel.id}" in self.setting_service.get_value("public_relay").lstrip("[").rstrip("]").split(','):
|
||||||
|
await msg.delete(delay=3600)
|
||||||
if msg.author.id == self.client.user.id:
|
if msg.author.id == self.client.user.id:
|
||||||
return
|
return
|
||||||
if not self.setting_service.get_value("dc_relay_public"):
|
|
||||||
return
|
|
||||||
channel: TextChannel = msg.channel
|
channel: TextChannel = msg.channel
|
||||||
if channel.id == int(self.setting_service.get_value("dc_relay_public")):
|
acc = self.data.get_account_discord_id(msg.author.id)
|
||||||
|
if acc:
|
||||||
if self.setting_service.get_value('is_alliance_bot') == "0":
|
acc.discord_nick = msg.author.nick or msg.author.name+'#'+msg.author.discriminator
|
||||||
response = f"[<notice>{html.escape(msg.author.nick if msg.author.nick else msg.author.name, False)}" \
|
prefix = f"[{self.alias_controller.get_alias(acc.member)}] {acc.name}: " if self.alias_usage().get_value() else f"[DC] {acc.name}: "
|
||||||
f"</notice>]: " \
|
self.relay_hub_service.send_message("Discord_(" + channel.name+")",
|
||||||
f"{html.escape(emojis.decode(msg.clean_content), False)}"
|
DictObject(acc), msg.content,
|
||||||
else:
|
prefix + msg.content)
|
||||||
response = f"{html.escape(msg.author.nick if msg.author.nick else msg.author.name, False)}: " \
|
else:
|
||||||
f"{html.escape(emojis.decode(msg.clean_content), False)}"
|
prefix = f"[-UNK-] {msg.author.username}: " if self.alias_usage().get_value() else f"[DC] {msg.author.username}: "
|
||||||
await msg.delete(delay=3600)
|
self.relay_hub_service.send_message("Discord_(" + channel.name+")",
|
||||||
sender = self.db.query_single("SELECT * from account a left join player p on a.main = p.char_id where a.discord_id = ?", [msg.author.id])
|
DictObject({'char_id': 0, 'name': msg.author.username, 'discord_handle': f'{msg.author.name}#{msg.author.discriminator}'}), msg.content,
|
||||||
self.relay_hub_service.send_message("public_relay", sender, html.escape(emojis.decode(msg.clean_content), False), response)
|
prefix + msg.content)
|
||||||
|
if str(channel.id) not in self.channel_blacklist().get_value().lstrip("[").rstrip("]").split(','):
|
||||||
|
self.bot.event_service.fire_event("discord_command", DictObject({'account': acc, 'message': msg}))
|
||||||
|
|
||||||
if self.is_command(msg.content):
|
if self.is_command(msg.content):
|
||||||
admin = self.get_role("Administrator", self.guild.roles)
|
admin = self.get_role("Administrator", self.guild.roles)
|
||||||
council = self.get_role("Council", self.guild.roles)
|
council = self.get_role("Council", self.guild.roles)
|
||||||
|
|
||||||
if msg.content[:4] == "!pin":
|
if msg.content[:4] == "!pin":
|
||||||
if admin in msg.author.roles:
|
if admin in msg.author.roles:
|
||||||
matches = re.findall(pattern="<head>(.+?)<\/head>(.+)", string=msg.content[4:].strip(),
|
matches = re.findall(pattern="<head>(.+?)<\/head>(.+)", string=msg.content[4:].strip(),
|
||||||
@@ -611,7 +359,7 @@ class DiscordController:
|
|||||||
mess = await channel.send(embed=Embed(color=3066993, description=msg.content[4:]))
|
mess = await channel.send(embed=Embed(color=3066993, description=msg.content[4:]))
|
||||||
await mess.pin()
|
await mess.pin()
|
||||||
|
|
||||||
if msg.content[:5] == "!note":
|
if msg.content[:6] == "!note ":
|
||||||
if admin in msg.author.roles:
|
if admin in msg.author.roles:
|
||||||
matches = re.findall(pattern="<head>(.+?)<\/head>(.+)", string=msg.content[5:].strip(),
|
matches = re.findall(pattern="<head>(.+?)<\/head>(.+)", string=msg.content[5:].strip(),
|
||||||
flags=re.DOTALL)
|
flags=re.DOTALL)
|
||||||
@@ -636,73 +384,23 @@ class DiscordController:
|
|||||||
else:
|
else:
|
||||||
await msg.channel.purge(check=self.check, limit=count)
|
await msg.channel.purge(check=self.check, limit=count)
|
||||||
await msg.delete(delay=0)
|
await msg.delete(delay=0)
|
||||||
if msg.content[:10] == "!subscribe":
|
|
||||||
if admin in msg.author.roles:
|
|
||||||
out = msg.content[10:].strip()
|
|
||||||
if self.setting_service.get(out) is None:
|
|
||||||
await msg.reply(f"The Channel {out} does not exist.")
|
|
||||||
else:
|
|
||||||
self.setting_service.set_value(out, msg.channel.id)
|
|
||||||
self.send_message(msg.channel.id, Embed(color=3066993, title="Channel Guard",
|
|
||||||
description=f"This channel has been "
|
|
||||||
f"subscribed to the source {out}."))
|
|
||||||
|
|
||||||
def send_message(self, channel: int, message, delete=0):
|
|
||||||
if self.client.is_ready():
|
|
||||||
channel: TextChannel = self.client.get_channel(int(channel)) if type(channel) in [int, str] else channel
|
|
||||||
if type(message) == Embed:
|
|
||||||
if delete != 0:
|
|
||||||
asyncio.run_coroutine_threadsafe(channel.send(embed=message, delete_after=delete), self.loop)
|
|
||||||
else:
|
|
||||||
asyncio.run_coroutine_threadsafe(channel.send(embed=message), self.loop)
|
|
||||||
|
|
||||||
else:
|
|
||||||
if delete != 0:
|
|
||||||
asyncio.run_coroutine_threadsafe(channel.send(message, delete_after=delete), self.loop)
|
|
||||||
else:
|
|
||||||
asyncio.run_coroutine_threadsafe(channel.send(message), self.loop)
|
|
||||||
|
|
||||||
def is_command(self, message: str):
|
def is_command(self, message: str):
|
||||||
for x in ["subscribe", "pin", "purge", "note"]:
|
for x in ["subscribe", "pin", "purge", "note"]:
|
||||||
if message.startswith("!" + x):
|
if message.startswith("!" + x):
|
||||||
return True
|
return True
|
||||||
|
|
||||||
async def clean_channel(self):
|
|
||||||
if self.setting_service.get_value("dc_relay_public") not in ["0", None]:
|
|
||||||
channel: TextChannel = self.client.get_channel(int(self.setting_service.get_value("dc_relay_public")))
|
|
||||||
for i in range(5):
|
|
||||||
await channel.purge(check=self.check)
|
|
||||||
|
|
||||||
def check(self, msg: Message):
|
def check(self, msg: Message):
|
||||||
if msg.pinned or len(msg.embeds) > 0:
|
if msg.pinned or (len(msg.embeds) > 0 and (msg.created_at.utcnow() < datetime.utcnow()-timedelta(hours=12))):
|
||||||
return False
|
return False
|
||||||
else:
|
else:
|
||||||
return True
|
return True
|
||||||
|
|
||||||
@event(event_type="main_changed", description="Fix discord names & ranks")
|
def alias_usage(self) -> BooleanSettingType:
|
||||||
def fix_ranks(self, _, data):
|
return self.setting_service.get("is_alliance_bot")
|
||||||
row = self.db.query_single("SELECT * from account where char_id=?", [data.old_main_id])
|
|
||||||
if row.discord_joined == 0:
|
|
||||||
self.logger.debug(f"{data.old_main_id} was not in discord, ignoring main fixing")
|
|
||||||
return
|
|
||||||
elif row.discord_joined == 1:
|
|
||||||
self.db.exec(
|
|
||||||
"UPDATE account set discord_handle=?, discord_id=?, discord_invite=?, discord_joined=? where char_id=?",
|
|
||||||
[row.discord_handle, row.discord_id, row.discord_invite, row.discord_joined, data.new_main_id])
|
|
||||||
self.db.exec(
|
|
||||||
"UPDATE account set discord_handle='', discord_id=0, discord_invite='', discord_joined=0 "
|
|
||||||
"where char_id=?",
|
|
||||||
[data.old_main_id])
|
|
||||||
self.logger.info(f"{data.old_main_id} was in discord, overwriting {data.new_main_id} with {data}")
|
|
||||||
|
|
||||||
self.discord_update_account(data.new_main_id)
|
def channel_blacklist(self) -> TextSettingType:
|
||||||
|
return self.setting_service.get("channel_blacklist")
|
||||||
|
|
||||||
@timerevent(budatime="5m", description="update activity")
|
def public_relay(self) -> TextSettingType:
|
||||||
def change_count(self, _, _1):
|
return self.setting_service.get("public_relay")
|
||||||
if hasattr(self, "loop"):
|
|
||||||
count = self.db.query_single('SELECT count(*) as count from online '
|
|
||||||
'where char_id NOT IN (select char_id from org_bots) and bot=?',
|
|
||||||
[self.bot.get_char_id()]).count
|
|
||||||
act = discord.Activity(type=discord.ActivityType.listening,
|
|
||||||
name=f"{count} Players")
|
|
||||||
asyncio.run_coroutine_threadsafe(self.client.change_presence(activity=act), self.loop)
|
|
||||||
|
|||||||
@@ -0,0 +1,25 @@
|
|||||||
|
|
||||||
|
class DiscordData:
|
||||||
|
def __init__(self, db, client):
|
||||||
|
self.db = db
|
||||||
|
self.client = client
|
||||||
|
|
||||||
|
def set_discord_invite(self, char_id, invite):
|
||||||
|
return self.db.exec("UPDATE account SET discord_invite = ? WHERE main = ?", [invite, char_id])
|
||||||
|
|
||||||
|
def set_discord_joined(self, char_id, handle, discord_id):
|
||||||
|
return self.db.exec("UPDATE account SET discord_joined = 1, discord_handle = ?, discord_id = ? WHERE main = ?",
|
||||||
|
[handle, discord_id, char_id])
|
||||||
|
|
||||||
|
def set_discord_left(self, char_id):
|
||||||
|
return self.db.exec("UPDATE account SET discord_joined = 0 WHERE main = ?", [char_id])
|
||||||
|
|
||||||
|
def set_discord_handle(self, discord_id, handle):
|
||||||
|
return self.db.exec("UPDATE account SET discord_handle = ? WHERE discord_id = ?", [handle, discord_id])
|
||||||
|
|
||||||
|
def get_discord_invite(self, invite):
|
||||||
|
return self.db.query_single("SELECT * FROM account WHERE discord_invite = ?", [invite])
|
||||||
|
|
||||||
|
def get_account_discord_id(self, discord_id):
|
||||||
|
return self.db.query_single(
|
||||||
|
"SELECT * FROM account a left join player p on a.char_id=p.char_id WHERE discord_id = ?", [discord_id])
|
||||||
@@ -0,0 +1,82 @@
|
|||||||
|
import asyncio
|
||||||
|
|
||||||
|
from discord import Activity, ActivityType, TextChannel
|
||||||
|
|
||||||
|
from core.dict_object import DictObject
|
||||||
|
|
||||||
|
|
||||||
|
class DiscordManager:
|
||||||
|
def __init__(self, client):
|
||||||
|
self.client = client
|
||||||
|
client = client.client
|
||||||
|
client.event(self.on_ready)
|
||||||
|
client.event(self.on_member_join)
|
||||||
|
client.event(self.on_member_remove)
|
||||||
|
client.event(self.on_member_update)
|
||||||
|
client.event(self.on_guild_role_delete)
|
||||||
|
client.event(self.on_guild_role_create)
|
||||||
|
client.event(self.on_guild_role_update)
|
||||||
|
client.event(self.on_invite_create)
|
||||||
|
client.event(self.on_invite_delete)
|
||||||
|
|
||||||
|
async def on_member_update(self, member_before, member_after):
|
||||||
|
await self.client.discord_update_bot_basic()
|
||||||
|
|
||||||
|
async def on_guild_role_create(self, role):
|
||||||
|
await self.client.discord_update_bot_full()
|
||||||
|
|
||||||
|
async def on_guild_role_delete(self, role):
|
||||||
|
await self.client.discord_update_bot_full()
|
||||||
|
|
||||||
|
async def on_guild_role_update(self, role_before, role_after):
|
||||||
|
await self.client.discord_update_bot_full()
|
||||||
|
|
||||||
|
async def on_invite_create(self, invite):
|
||||||
|
await self.client.discord_update_bot_full()
|
||||||
|
|
||||||
|
async def on_invite_delete(self, invite):
|
||||||
|
await self.client.discord_update_bot_full()
|
||||||
|
|
||||||
|
async def on_member_join(self, member):
|
||||||
|
temp_invites = await self.client.guild.invites()
|
||||||
|
invite_used = self.discord_invite_used(temp_invites)
|
||||||
|
self.client.discord_queue.append(
|
||||||
|
DictObject({"type": "on_member_join", "member": member, "invite": invite_used}))
|
||||||
|
await invite_used.delete()
|
||||||
|
|
||||||
|
def discord_invite_used(self, temp_invites):
|
||||||
|
for temp_invite in temp_invites:
|
||||||
|
# if temp_invite.inviter.id == self.client.user.id:
|
||||||
|
# ## Using this line limits it to invite created by the account the Discord bot runs as..
|
||||||
|
for invite in self.client.invites:
|
||||||
|
if int(temp_invite.uses) > int(invite.uses) and temp_invite.code == invite.code:
|
||||||
|
return temp_invite
|
||||||
|
return None
|
||||||
|
|
||||||
|
async def on_member_remove(self, member):
|
||||||
|
self.client.discord_queue.append(DictObject({"type": "on_member_remove", "member": member}))
|
||||||
|
await self.client.discord_update_bot_full()
|
||||||
|
|
||||||
|
async def on_ready(self):
|
||||||
|
await self.client.discord_update_bot_full()
|
||||||
|
count = self.client.db.query_single('SELECT count(*) as count from online '
|
||||||
|
'where char_id NOT IN (select char_id from org_bots) and bot=?',
|
||||||
|
[self.client.bot.get_char_id()]).count
|
||||||
|
|
||||||
|
act = Activity(type=ActivityType.listening,
|
||||||
|
name=f"{count} Players")
|
||||||
|
asyncio.run_coroutine_threadsafe(self.client.client.change_presence(activity=act), self.client.loop)
|
||||||
|
asyncio.run_coroutine_threadsafe(self.client.setup_relayhub(), self.client.loop)
|
||||||
|
await self.clean_channel()
|
||||||
|
|
||||||
|
if self.client.guild.large:
|
||||||
|
self.client.logger.error(
|
||||||
|
f"Guild {self.client.guild.name} is classified as large, "
|
||||||
|
f"you need to request offline members to manage roles properly, this is not yet implemented")
|
||||||
|
|
||||||
|
async def clean_channel(self):
|
||||||
|
for channel in self.client.setting_service.get_value("public_relay").lstrip("[").rstrip("]").split(','):
|
||||||
|
if ch := self.client.client.get_channel(int(channel)):
|
||||||
|
for i in range(5):
|
||||||
|
await ch.purge(check=self.client.check)
|
||||||
|
|
||||||
@@ -235,22 +235,25 @@ class PrivateChannelController:
|
|||||||
@event(event_type=IgnCore.OUTGOING_PRIVATE_CHANNEL_MESSAGE_EVENT,
|
@event(event_type=IgnCore.OUTGOING_PRIVATE_CHANNEL_MESSAGE_EVENT,
|
||||||
description="Relay commands from the private channel to the relay hub", is_hidden=True)
|
description="Relay commands from the private channel to the relay hub", is_hidden=True)
|
||||||
def outgoing_private_channel_message_event(self, _, event_data):
|
def outgoing_private_channel_message_event(self, _, event_data):
|
||||||
|
|
||||||
if isinstance(event_data.message, ChatBlob):
|
if isinstance(event_data.message, ChatBlob):
|
||||||
pages = self.text.paginate(event_data.message,
|
pages = self.text.paginate(event_data.message,
|
||||||
self.setting_service.get("org_channel_max_page_length").get_value())
|
self.setting_service.get("org_channel_max_page_length").get_value())
|
||||||
if len(pages) < 4:
|
if len(pages) < 4:
|
||||||
for page in pages:
|
for page in pages:
|
||||||
message = "{priv}{message}".format(priv=self.PRIVATE_CHANNEL_PREFIX, message=page)
|
# message = "{org} {message}".format(org=self.ORG_CHANNEL_PREFIX, message=page)
|
||||||
|
event_data.message.page_prefix = self.PRIVATE_CHANNEL_PREFIX
|
||||||
self.message_hub_service.send_message(self.MESSAGE_SOURCE,
|
self.message_hub_service.send_message(self.MESSAGE_SOURCE,
|
||||||
None,
|
None,
|
||||||
page,
|
page,
|
||||||
message)
|
event_data.message)
|
||||||
else:
|
else:
|
||||||
message = "{priv}{message}".format(priv=self.PRIVATE_CHANNEL_PREFIX, message=event_data.message.title)
|
# message = "{org} {message}".format(org=self.ORG_CHANNEL_PREFIX, message=event_data.message.title)
|
||||||
|
event_data.message.page_prefix = self.PRIVATE_CHANNEL_PREFIX
|
||||||
self.message_hub_service.send_message(self.MESSAGE_SOURCE,
|
self.message_hub_service.send_message(self.MESSAGE_SOURCE,
|
||||||
None,
|
None,
|
||||||
event_data.message.title,
|
event_data.message.title,
|
||||||
message)
|
event_data.message)
|
||||||
else:
|
else:
|
||||||
message = "{priv}{message}".format(priv=self.PRIVATE_CHANNEL_PREFIX, message=event_data.message)
|
message = "{priv}{message}".format(priv=self.PRIVATE_CHANNEL_PREFIX, message=event_data.message)
|
||||||
self.message_hub_service.send_message(self.MESSAGE_SOURCE,
|
self.message_hub_service.send_message(self.MESSAGE_SOURCE,
|
||||||
|
|||||||
@@ -1,20 +1,26 @@
|
|||||||
import json
|
import json
|
||||||
import math
|
import math
|
||||||
|
import typing
|
||||||
|
|
||||||
from core.buddy_service import BuddyService
|
from core.buddy_service import BuddyService
|
||||||
from core.chat_blob import ChatBlob
|
from core.chat_blob import ChatBlob
|
||||||
from core.command_param_types import Const, Character, Any, NamedParameters
|
from core.command_param_types import Const, Character, Any, NamedParameters
|
||||||
from core.decorators import instance, command, event
|
from core.decorators import instance, command, event
|
||||||
from core.dict_object import DictObject
|
from core.dict_object import DictObject
|
||||||
|
|
||||||
from core.logger import Logger
|
from core.logger import Logger
|
||||||
from core.lookup.character_service import CharacterService
|
|
||||||
from core.lookup.pork_service import PorkService
|
|
||||||
from core.private_channel_service import PrivateChannelService
|
|
||||||
from core.setting_service import SettingService
|
from core.setting_service import SettingService
|
||||||
from core.setting_types import TextSettingType
|
from core.setting_types import TextSettingType
|
||||||
from core.text import Text
|
from core.text import Text
|
||||||
from core.translation_service import TranslationService
|
from core.translation_service import TranslationService
|
||||||
from core.igncore import IgnCore
|
from core.igncore import IgnCore
|
||||||
|
from core.private_channel_service import PrivateChannelService
|
||||||
|
|
||||||
|
if typing.TYPE_CHECKING:
|
||||||
|
from core.lookup.character_service import CharacterService
|
||||||
|
from core.lookup.pork_service import PorkService
|
||||||
|
from core.event_service import EventService
|
||||||
|
|
||||||
|
|
||||||
# noinspection SqlCaseVsIf,SqlCaseVsCoalesce
|
# noinspection SqlCaseVsIf,SqlCaseVsCoalesce
|
||||||
@@ -38,6 +44,7 @@ class RIAdminController:
|
|||||||
self.getresp = self.ts.get_response
|
self.getresp = self.ts.get_response
|
||||||
self.buddy_service: BuddyService = registry.get_instance("buddy_service")
|
self.buddy_service: BuddyService = registry.get_instance("buddy_service")
|
||||||
self.pork: PorkService = registry.get_instance("pork_service")
|
self.pork: PorkService = registry.get_instance("pork_service")
|
||||||
|
self.event_service: EventService = registry.get_instance("event_service")
|
||||||
|
|
||||||
def start(self):
|
def start(self):
|
||||||
self.db.exec(
|
self.db.exec(
|
||||||
@@ -54,6 +61,8 @@ class RIAdminController:
|
|||||||
TextSettingType(), "Allowed bots (charID's)",
|
TextSettingType(), "Allowed bots (charID's)",
|
||||||
extended_description="This setting is *NOT* synchronized across the network;"
|
extended_description="This setting is *NOT* synchronized across the network;"
|
||||||
" this needs to be done manually!")
|
" this needs to be done manually!")
|
||||||
|
def pre_start(self):
|
||||||
|
self.event_service.register_event_type("RAID_END")
|
||||||
|
|
||||||
@event(event_type="buddy_logoff", description="Track raiders")
|
@event(event_type="buddy_logoff", description="Track raiders")
|
||||||
def raider_logoff(self, _, event_data):
|
def raider_logoff(self, _, event_data):
|
||||||
|
|||||||
@@ -1,112 +1,112 @@
|
|||||||
from core.aochat import server_packets, client_packets
|
# from core.aochat import server_packets, client_packets
|
||||||
from core.conn import Conn
|
# from core.conn import Conn
|
||||||
from core.decorators import instance
|
# from core.decorators import instance
|
||||||
from core.igncore import IgnCore
|
# from core.igncore import IgnCore
|
||||||
from core.logger import Logger
|
# from core.logger import Logger
|
||||||
from core.lookup.character_service import CharacterService
|
# from core.lookup.character_service import CharacterService
|
||||||
from core.setting_service import SettingService
|
# from core.setting_service import SettingService
|
||||||
from core.setting_types import TextSettingType, BooleanSettingType, ColorSettingType
|
# from core.setting_types import TextSettingType, BooleanSettingType, ColorSettingType
|
||||||
from core.text import Text
|
# from core.text import Text
|
||||||
from modules.onlinebot.online.org_alias_controller import OrgAliasController
|
# from modules.onlinebot.online.org_alias_controller import OrgAliasController
|
||||||
|
#
|
||||||
|
#
|
||||||
@instance("AllianceRelayController")
|
# @instance("AllianceRelayController")
|
||||||
class AllianceRelayController:
|
# class AllianceRelayController:
|
||||||
relay_channel_id = None
|
# relay_channel_id = None
|
||||||
MESSAGE_SOURCE = "alliance"
|
# MESSAGE_SOURCE = "alliance"
|
||||||
|
#
|
||||||
def __init__(self):
|
# def __init__(self):
|
||||||
self.logger = Logger(__name__)
|
# self.logger = Logger(__name__)
|
||||||
|
#
|
||||||
# noinspection DuplicatedCode
|
# # noinspection DuplicatedCode
|
||||||
def inject(self, registry):
|
# def inject(self, registry):
|
||||||
self.bot: IgnCore = registry.get_instance("bot")
|
# self.bot: IgnCore = registry.get_instance("bot")
|
||||||
self.setting_service: SettingService = registry.get_instance("setting_service")
|
# self.setting_service: SettingService = registry.get_instance("setting_service")
|
||||||
self.character_service: CharacterService = registry.get_instance("character_service")
|
# self.character_service: CharacterService = registry.get_instance("character_service")
|
||||||
self.message_hub_service = registry.get_instance("message_hub_service")
|
# self.message_hub_service = registry.get_instance("message_hub_service")
|
||||||
self.public_channel_service = registry.get_instance("public_channel_service")
|
# self.public_channel_service = registry.get_instance("public_channel_service")
|
||||||
self.text: Text = registry.get_instance("text")
|
# self.text: Text = registry.get_instance("text")
|
||||||
self.alias_controller: OrgAliasController = registry.get_instance("org_alias_controller")
|
# self.alias_controller: OrgAliasController = registry.get_instance("org_alias_controller")
|
||||||
|
#
|
||||||
def pre_start(self):
|
# def pre_start(self):
|
||||||
self.message_hub_service.register_message_source(self.MESSAGE_SOURCE)
|
# self.message_hub_service.register_message_source(self.MESSAGE_SOURCE)
|
||||||
|
#
|
||||||
def start(self):
|
# def start(self):
|
||||||
self.setting_service.register(self.module_name, "arelaybot", "",
|
# self.setting_service.register(self.module_name, "arelaybot", "",
|
||||||
TextSettingType(allow_empty=True), "Bot for alliance relay")
|
# TextSettingType(allow_empty=True), "Bot for alliance relay")
|
||||||
|
#
|
||||||
self.setting_service.register(self.module_name, "arelay_enabled", False,
|
# self.setting_service.register(self.module_name, "arelay_enabled", False,
|
||||||
BooleanSettingType(), "Enable the alliance relay")
|
# BooleanSettingType(), "Enable the alliance relay")
|
||||||
|
#
|
||||||
self.setting_service.register(self.module_name, "arelay_color", "#C3C3C3",
|
# self.setting_service.register(self.module_name, "arelay_color", "#C3C3C3",
|
||||||
ColorSettingType(),
|
# ColorSettingType(),
|
||||||
"Color of messages from relay")
|
# "Color of messages from relay")
|
||||||
|
#
|
||||||
self.message_hub_service.register_message_destination(self.MESSAGE_SOURCE, self.handle_relay_hub_message, [],
|
# # self.message_hub_service.register_message_destination(self.MESSAGE_SOURCE, self.handle_relay_hub_message, [],
|
||||||
[self.MESSAGE_SOURCE])
|
# # [self.MESSAGE_SOURCE])
|
||||||
|
#
|
||||||
self.bot.register_packet_handler(server_packets.PrivateChannelInvited.id, self.handle_private_channel_invite,
|
# self.bot.register_packet_handler(server_packets.PrivateChannelInvited.id, self.handle_private_channel_invite,
|
||||||
100)
|
# 100)
|
||||||
self.bot.register_packet_handler(server_packets.PrivateChannelMessage.id, self.handle_private_channel_message)
|
# self.bot.register_packet_handler(server_packets.PrivateChannelMessage.id, self.handle_private_channel_message)
|
||||||
|
#
|
||||||
# noinspection DuplicatedCode
|
# # noinspection DuplicatedCode
|
||||||
def handle_private_channel_invite(self, conn: Conn, packet: server_packets.PrivateChannelInvited):
|
# def handle_private_channel_invite(self, conn: Conn, packet: server_packets.PrivateChannelInvited):
|
||||||
if conn.id != "main":
|
# if conn.id != "main":
|
||||||
return
|
# return
|
||||||
|
#
|
||||||
if not self.setting_service.get("arelay_enabled").get_value():
|
# if not self.setting_service.get("arelay_enabled").get_value():
|
||||||
return
|
# return
|
||||||
|
#
|
||||||
channel_name = self.character_service.get_char_name(packet.private_channel_id)
|
# channel_name = self.character_service.get_char_name(packet.private_channel_id)
|
||||||
if self.setting_service.get_value("arelaybot").lower() == channel_name.lower():
|
# if self.setting_service.get_value("arelaybot").lower() == channel_name.lower():
|
||||||
self.bot.send_packet(client_packets.PrivateChannelJoin(packet.private_channel_id))
|
# self.bot.send_packet(client_packets.PrivateChannelJoin(packet.private_channel_id))
|
||||||
self.logger.info("Joined private channel {channel}".format(channel=channel_name))
|
# self.logger.info("Joined private channel {channel}".format(channel=channel_name))
|
||||||
self.relay_channel_id = packet.private_channel_id
|
# self.relay_channel_id = packet.private_channel_id
|
||||||
|
#
|
||||||
# noinspection DuplicatedCode
|
# # noinspection DuplicatedCode
|
||||||
def handle_private_channel_message(self, conn: Conn, packet: server_packets.PrivateChannelMessage):
|
# def handle_private_channel_message(self, conn: Conn, packet: server_packets.PrivateChannelMessage):
|
||||||
if conn.id != "main":
|
# if conn.id != "main":
|
||||||
return
|
# return
|
||||||
|
#
|
||||||
if not self.setting_service.get("arelay_enabled").get_value():
|
# if not self.setting_service.get("arelay_enabled").get_value():
|
||||||
return
|
# return
|
||||||
|
#
|
||||||
# ignore packets from the bot's own private channel and from the bot itself
|
# # ignore packets from the bot's own private channel and from the bot itself
|
||||||
if packet.private_channel_id == self.bot.get_char_id() or packet.char_id == self.bot.get_char_id():
|
# if packet.private_channel_id == self.bot.get_char_id() or packet.char_id == self.bot.get_char_id():
|
||||||
return
|
# return
|
||||||
|
#
|
||||||
message = packet.message.lstrip()
|
# message = packet.message.lstrip()
|
||||||
if message[:6] != "!agcr ":
|
# if message[:6] != "!agcr ":
|
||||||
return
|
# return
|
||||||
|
#
|
||||||
message = message[6:]
|
# message = message[6:]
|
||||||
formatted_message = self.setting_service.get("arelay_color").format_text(message)
|
# formatted_message = self.setting_service.get("arelay_color").format_text(message)
|
||||||
|
#
|
||||||
sender = None
|
# sender = None
|
||||||
self.message_hub_service.send_message(self.MESSAGE_SOURCE, sender, message, formatted_message)
|
# self.message_hub_service.send_message(self.MESSAGE_SOURCE, sender, message, formatted_message)
|
||||||
|
#
|
||||||
def handle_relay_hub_message(self, ctx):
|
# def handle_relay_hub_message(self, ctx):
|
||||||
if not self.setting_service.get("arelay_enabled").get_value():
|
# if not self.setting_service.get("arelay_enabled").get_value():
|
||||||
return
|
# return
|
||||||
|
#
|
||||||
plain_msg = ctx.message or ctx.formatted_message
|
# plain_msg = ctx.message or ctx.formatted_message
|
||||||
invite = self.text.make_chatcmd("click here", "/tell <myname> discord invite",
|
# invite = self.text.make_chatcmd("click here", "/tell <myname> discord invite",
|
||||||
style="style='text-decoration:none'")
|
# style="style='text-decoration:none'")
|
||||||
name = f"[{self.alias_controller.get_alias(ctx.sender.org_id)}] {ctx.sender.name}"
|
# name = f"[{self.alias_controller.get_alias(ctx.sender.org_id)}] {ctx.sender.name}"
|
||||||
blob = self.text.format_page('Info',
|
# blob = self.text.format_page('Info',
|
||||||
f"<header>::: Information :::</header><br><br>"
|
# f"<header>::: Information :::</header><br><br>"
|
||||||
f"This message has been sent to you by:<br><br>"
|
# f"This message has been sent to you by:<br><br>"
|
||||||
f"<header2>Igncom</header2><br>"
|
# f"<header2>Igncom</header2><br>"
|
||||||
f"<notice>{ctx.sender.discord_handle}</notice><br>"
|
# f"<notice>{ctx.sender.discord_handle}</notice><br>"
|
||||||
f"<highlight>{name}</highlight> on Alliance Discord.<br><br>"
|
# f"<highlight>{name}</highlight> on Alliance Discord.<br><br>"
|
||||||
f"To reply, either respond in the relay or "
|
# f"To reply, either respond in the relay or "
|
||||||
f"contact them directly at the provided handles.<br><br>"
|
# f"contact them directly at the provided handles.<br><br>"
|
||||||
f"<header2>Have you joined The Alliance Discord yet? "
|
# f"<header2>Have you joined The Alliance Discord yet? "
|
||||||
f"If not <highlight>{invite}</highlight> to receive an invite.</header2>")
|
# f"If not <highlight>{invite}</highlight> to receive an invite.</header2>")
|
||||||
self.send_message_to_alliance(f"{name}: {plain_msg}" + f" <yellow>[{blob}]</yellow>")
|
# self.send_message_to_alliance(f"{name}: {plain_msg}" + f" <yellow>[{blob}]</yellow>")
|
||||||
|
#
|
||||||
def send_message_to_alliance(self, msg):
|
# def send_message_to_alliance(self, msg):
|
||||||
if self.relay_channel_id:
|
# if self.relay_channel_id:
|
||||||
packet = client_packets.PrivateChannelMessage(self.relay_channel_id,
|
# packet = client_packets.PrivateChannelMessage(self.relay_channel_id,
|
||||||
"!agcr " + self.text.format_message(msg, False), "\0")
|
# "!agcr " + self.text.format_message(msg, False), "\0")
|
||||||
self.bot.conns["main"].send_packet(packet)
|
# self.bot.conns["main"].send_packet(packet)
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ import re
|
|||||||
import time
|
import time
|
||||||
from threading import Thread
|
from threading import Thread
|
||||||
|
|
||||||
|
import datetime
|
||||||
import requests
|
import requests
|
||||||
|
|
||||||
from core.buddy_service import BuddyService
|
from core.buddy_service import BuddyService
|
||||||
@@ -359,4 +360,8 @@ class OrgController:
|
|||||||
if len(current) > 10:
|
if len(current) > 10:
|
||||||
out.append(current)
|
out.append(current)
|
||||||
if len(out) > 0:
|
if len(out) > 0:
|
||||||
self.relay_hub_service.send_message("member_logger", None, out, out)
|
y = 0
|
||||||
|
for x in out:
|
||||||
|
y += 1
|
||||||
|
blob = ChatBlob(f"Recent changes - {datetime.date.today()} - ({y}/{len(out)})", x, embed=True)
|
||||||
|
self.relay_hub_service.send_message("member_logger", None, blob, blob)
|
||||||
|
|||||||
@@ -120,17 +120,19 @@ class OrgChannelController:
|
|||||||
self.setting_service.get("org_channel_max_page_length").get_value())
|
self.setting_service.get("org_channel_max_page_length").get_value())
|
||||||
if len(pages) < 4:
|
if len(pages) < 4:
|
||||||
for page in pages:
|
for page in pages:
|
||||||
message = "{org} {message}".format(org=self.ORG_CHANNEL_PREFIX, message=page)
|
# message = "{org} {message}".format(org=self.ORG_CHANNEL_PREFIX, message=page)
|
||||||
|
event_data.message.page_prefix = self.ORG_CHANNEL_PREFIX
|
||||||
self.message_hub_service.send_message(self.MESSAGE_SOURCE,
|
self.message_hub_service.send_message(self.MESSAGE_SOURCE,
|
||||||
None,
|
None,
|
||||||
page,
|
page,
|
||||||
message)
|
event_data.message)
|
||||||
else:
|
else:
|
||||||
message = "{org} {message}".format(org=self.ORG_CHANNEL_PREFIX, message=event_data.message.title)
|
# message = "{org} {message}".format(org=self.ORG_CHANNEL_PREFIX, message=event_data.message.title)
|
||||||
|
event_data.message.page_prefix = self.ORG_CHANNEL_PREFIX
|
||||||
self.message_hub_service.send_message(self.MESSAGE_SOURCE,
|
self.message_hub_service.send_message(self.MESSAGE_SOURCE,
|
||||||
None,
|
None,
|
||||||
event_data.message.title,
|
event_data.message.title,
|
||||||
message)
|
event_data.message)
|
||||||
else:
|
else:
|
||||||
message = "{org} {message}".format(org=self.ORG_CHANNEL_PREFIX, message=event_data.message)
|
message = "{org} {message}".format(org=self.ORG_CHANNEL_PREFIX, message=event_data.message)
|
||||||
self.message_hub_service.send_message(self.MESSAGE_SOURCE,
|
self.message_hub_service.send_message(self.MESSAGE_SOURCE,
|
||||||
|
|||||||
@@ -76,9 +76,6 @@ class RaidbotController(BaseModule):
|
|||||||
self.account_service: AccountService = registry.get_instance("account_service")
|
self.account_service: AccountService = registry.get_instance("account_service")
|
||||||
self.buddy_service: BuddyService = registry.get_instance("buddy_service")
|
self.buddy_service: BuddyService = registry.get_instance("buddy_service")
|
||||||
|
|
||||||
def pre_start(self):
|
|
||||||
self.event_service.register_event_type("RAID_END")
|
|
||||||
|
|
||||||
@event("connect", "Adds all raiders to buddylist")
|
@event("connect", "Adds all raiders to buddylist")
|
||||||
def connect(self, _, _1):
|
def connect(self, _, _1):
|
||||||
query = self.db.query("SELECT char_id, member from account where member != -1 and disabled = 0")
|
query = self.db.query("SELECT char_id, member from account where member != -1 and disabled = 0")
|
||||||
|
|||||||
@@ -1,137 +1,137 @@
|
|||||||
import asyncio
|
# import asyncio
|
||||||
import datetime
|
# import datetime
|
||||||
import html
|
# import html
|
||||||
|
#
|
||||||
# noinspection PyPackageRequirements
|
# # noinspection PyPackageRequirements
|
||||||
from discord import Embed
|
# from discord import Embed
|
||||||
|
#
|
||||||
from core.command_service import CommandService
|
# from core.command_service import CommandService
|
||||||
from core.db import DB
|
# from core.db import DB
|
||||||
from core.decorators import instance
|
# from core.decorators import instance
|
||||||
from core.logger import Logger
|
# from core.logger import Logger
|
||||||
from core.lookup.character_service import CharacterService
|
# from core.lookup.character_service import CharacterService
|
||||||
from core.lookup.pork_service import PorkService
|
# from core.lookup.pork_service import PorkService
|
||||||
from core.message_hub_service import MessageHubService
|
# from core.message_hub_service import MessageHubService
|
||||||
from core.registry import Registry
|
# from core.registry import Registry
|
||||||
from core.setting_service import SettingService
|
# from core.setting_service import SettingService
|
||||||
from core.setting_types import NumberSettingType
|
# from core.setting_types import NumberSettingType
|
||||||
from core.text import Text
|
# from core.text import Text
|
||||||
from core.igncore import IgnCore
|
# from core.igncore import IgnCore
|
||||||
from modules.core.accounting.services.access_service import AccessService
|
# from modules.core.accounting.services.access_service import AccessService
|
||||||
from modules.core.discord.discord_controller import DiscordController
|
# from modules.core.discord.discord_controller import DiscordController
|
||||||
|
#
|
||||||
|
#
|
||||||
# noinspection DuplicatedCode,PyAttributeOutsideInit
|
# # noinspection DuplicatedCode,PyAttributeOutsideInit
|
||||||
@instance()
|
# @instance()
|
||||||
class MessageDistributor:
|
# class MessageDistributor:
|
||||||
MESSAGE_SOURCE = "discord"
|
# MESSAGE_SOURCE = "discord"
|
||||||
|
#
|
||||||
def __init__(self):
|
# def __init__(self):
|
||||||
self.logger = Logger(__name__)
|
# self.logger = Logger(__name__)
|
||||||
|
#
|
||||||
def inject(self, registry):
|
# def inject(self, registry):
|
||||||
self.bot: IgnCore = registry.get_instance("bot")
|
# self.bot: IgnCore = registry.get_instance("bot")
|
||||||
self.db: DB = registry.get_instance("db")
|
# self.db: DB = registry.get_instance("db")
|
||||||
self.character_service: CharacterService = registry.get_instance("character_service")
|
# self.character_service: CharacterService = registry.get_instance("character_service")
|
||||||
self.access_service: AccessService = registry.get_instance("access_service")
|
# self.access_service: AccessService = registry.get_instance("access_service")
|
||||||
self.pork: PorkService = registry.get_instance("pork_service")
|
# self.pork: PorkService = registry.get_instance("pork_service")
|
||||||
self.relay_hub_service: MessageHubService = registry.get_instance("message_hub_service")
|
# self.relay_hub_service: MessageHubService = registry.get_instance("message_hub_service")
|
||||||
self.discord: DiscordController = registry.get_instance("discord_controller")
|
# self.discord: DiscordController = registry.get_instance("discord_controller")
|
||||||
self.cmd_service: CommandService = registry.get_instance("command_service")
|
# self.cmd_service: CommandService = registry.get_instance("command_service")
|
||||||
self.setting_service: SettingService = registry.get_instance("setting_service")
|
# self.setting_service: SettingService = registry.get_instance("setting_service")
|
||||||
self.text: Text = registry.get_instance("text")
|
# self.text: Text = registry.get_instance("text")
|
||||||
|
#
|
||||||
def pre_start(self):
|
# def pre_start(self):
|
||||||
self.relay_hub_service.register_message_source("public_relay")
|
# self.relay_hub_service.register_message_source("public_relay")
|
||||||
self.relay_hub_service.register_message_source("tell_logger")
|
# self.relay_hub_service.register_message_source("tell_logger")
|
||||||
self.relay_hub_service.register_message_source("system_logger")
|
# self.relay_hub_service.register_message_source("system_logger")
|
||||||
self.relay_hub_service.register_message_source("access_denied_logger")
|
# self.relay_hub_service.register_message_source("access_denied_logger")
|
||||||
self.relay_hub_service.register_message_source("member_logger")
|
# self.relay_hub_service.register_message_source("member_logger")
|
||||||
|
#
|
||||||
def start(self):
|
# def start(self):
|
||||||
self.relay_hub_service.register_message_destination("tell_log", self.handle_logging_tell, ["tell_logger"],
|
# self.relay_hub_service.register_message_destination("tell_log", self.handle_logging_tell, ["tell_logger"],
|
||||||
["tell_log"])
|
# ["tell_log"])
|
||||||
self.setting_service.register(self.module_name, "dc_tell_log", 0, NumberSettingType(allow_empty=True),
|
# self.setting_service.register(self.module_name, "dc_tell_log", 0, NumberSettingType(allow_empty=True),
|
||||||
"ChannelID for the Tell Log")
|
# "ChannelID for the Tell Log")
|
||||||
|
#
|
||||||
self.relay_hub_service.register_message_destination("access_denied_log", self.handle_logging_denied,
|
# self.relay_hub_service.register_message_destination("access_denied_log", self.handle_logging_denied,
|
||||||
["access_denied_logger"], ["access_denied_log"])
|
# ["access_denied_logger"], ["access_denied_log"])
|
||||||
self.setting_service.register(self.module_name, "dc_denied_log", 0, NumberSettingType(allow_empty=True),
|
# self.setting_service.register(self.module_name, "dc_denied_log", 0, NumberSettingType(allow_empty=True),
|
||||||
"ChannelID for the Access Denied Log")
|
# "ChannelID for the Access Denied Log")
|
||||||
|
#
|
||||||
self.relay_hub_service.register_message_destination("relay_log", self.handle_logging_relay,
|
# self.relay_hub_service.register_message_destination("relay_log", self.handle_logging_relay,
|
||||||
["alliance", "public_relay"], ["relay_log"])
|
# ["alliance", "public_relay"], ["relay_log"])
|
||||||
self.setting_service.register(self.module_name, "dc_relay_log", 0, NumberSettingType(allow_empty=True),
|
# self.setting_service.register(self.module_name, "dc_relay_log", 0, NumberSettingType(allow_empty=True),
|
||||||
"ChannelID for the Relay Log")
|
# "ChannelID for the Relay Log")
|
||||||
|
#
|
||||||
self.relay_hub_service.register_message_destination("public_relay", self.handle_public_relay, ["alliance"],
|
# self.relay_hub_service.register_message_destination("public_relay", self.handle_public_relay, ["alliance"],
|
||||||
["public_relay"])
|
# ["public_relay"])
|
||||||
self.setting_service.register(self.module_name, "dc_relay_public", 0, NumberSettingType(allow_empty=True),
|
# self.setting_service.register(self.module_name, "dc_relay_public", 0, NumberSettingType(allow_empty=True),
|
||||||
"ChannelID for the Public Relay Channel")
|
# "ChannelID for the Public Relay Channel")
|
||||||
|
#
|
||||||
self.relay_hub_service.register_message_destination("system", self.handle_logging_system, ["system_logger"],
|
# self.relay_hub_service.register_message_destination("system", self.handle_logging_system, ["system_logger"],
|
||||||
["system"])
|
# ["system"])
|
||||||
self.setting_service.register(self.module_name, "dc_system_log", 0, NumberSettingType(allow_empty=True),
|
# self.setting_service.register(self.module_name, "dc_system_log", 0, NumberSettingType(allow_empty=True),
|
||||||
"ChannelID for the System Channel")
|
# "ChannelID for the System Channel")
|
||||||
|
#
|
||||||
self.relay_hub_service.register_message_destination("dc_member_log", self.handle_logging_members,
|
# self.relay_hub_service.register_message_destination("dc_member_log", self.handle_logging_members,
|
||||||
["member_logger"], ["dc_member_log"])
|
# ["member_logger"], ["dc_member_log"])
|
||||||
self.setting_service.register(self.module_name, "dc_member_log", 0, NumberSettingType(allow_empty=True),
|
# self.setting_service.register(self.module_name, "dc_member_log", 0, NumberSettingType(allow_empty=True),
|
||||||
"ChannelID for the Member Log")
|
# "ChannelID for the Member Log")
|
||||||
|
#
|
||||||
if Registry.get_instance("darknet", is_optional=True):
|
# if Registry.get_instance("darknet", is_optional=True):
|
||||||
self.relay_hub_service.register_message_destination("dc_darknet_log", self.handle_darknet_log, ["darknet"],
|
# self.relay_hub_service.register_message_destination("dc_darknet_log", self.handle_darknet_log, ["darknet"],
|
||||||
[""])
|
# [""])
|
||||||
self.setting_service.register(self.module_name, "dc_darknet_log", 0, NumberSettingType(allow_empty=True),
|
# self.setting_service.register(self.module_name, "dc_darknet_log", 0, NumberSettingType(allow_empty=True),
|
||||||
"ChannelID for the Darknet Log")
|
# "ChannelID for the Darknet Log")
|
||||||
|
#
|
||||||
def handle_public_relay(self, ctx):
|
# def handle_public_relay(self, ctx):
|
||||||
if self.setting_service.get_value("dc_relay_public") != "0":
|
# if self.setting_service.get_value("dc_relay_public") != "0":
|
||||||
message = self.format(ctx.formatted_message)
|
# message = self.format(ctx.formatted_message)
|
||||||
self.discord.send_message(self.setting_service.get_value("dc_relay_public"), html.unescape(message),
|
# self.discord.send_message(self.setting_service.get_value("dc_relay_public"), html.unescape(message),
|
||||||
delete=3600) # delete after 1h
|
# delete=3600) # delete after 1h
|
||||||
|
#
|
||||||
def handle_logging_tell(self, ctx):
|
# def handle_logging_tell(self, ctx):
|
||||||
if self.setting_service.get_value("dc_tell_log") != "0":
|
# if self.setting_service.get_value("dc_tell_log") != "0":
|
||||||
message = self.format(ctx.message)
|
# message = self.format(ctx.message)
|
||||||
self.discord.send_message(self.setting_service.get_value("dc_tell_log"),
|
# self.discord.send_message(self.setting_service.get_value("dc_tell_log"),
|
||||||
f"[FROM] {self.character_service.get_char_name(ctx.sender)}: {message}")
|
# f"[FROM] {self.character_service.get_char_name(ctx.sender)}: {message}")
|
||||||
|
#
|
||||||
def handle_logging_denied(self, ctx):
|
# def handle_logging_denied(self, ctx):
|
||||||
if self.setting_service.get_value("dc_denied_log") != "0":
|
# if self.setting_service.get_value("dc_denied_log") != "0":
|
||||||
message = self.format(ctx.message)
|
# message = self.format(ctx.message)
|
||||||
self.discord.send_message(self.setting_service.get_value("dc_denied_log"), message)
|
# self.discord.send_message(self.setting_service.get_value("dc_denied_log"), message)
|
||||||
|
#
|
||||||
def handle_darknet_log(self, ctx):
|
# def handle_darknet_log(self, ctx):
|
||||||
if self.setting_service.get_value("dc_darknet_log") != "0":
|
# if self.setting_service.get_value("dc_darknet_log") != "0":
|
||||||
message = self.format(ctx.message)
|
# message = self.format(ctx.message)
|
||||||
self.discord.send_message(self.setting_service.get_value("dc_darknet_log"), message)
|
# self.discord.send_message(self.setting_service.get_value("dc_darknet_log"), message)
|
||||||
|
#
|
||||||
def handle_logging_relay(self, ctx):
|
# def handle_logging_relay(self, ctx):
|
||||||
if self.setting_service.get_value("dc_relay_log") != "0":
|
# if self.setting_service.get_value("dc_relay_log") != "0":
|
||||||
message = self.format(ctx.formatted_message)
|
# message = self.format(ctx.formatted_message)
|
||||||
self.discord.send_message(self.setting_service.get_value("dc_relay_log"), f"{html.unescape(message)}")
|
# self.discord.send_message(self.setting_service.get_value("dc_relay_log"), f"{html.unescape(message)}")
|
||||||
|
#
|
||||||
def handle_logging_system(self, ctx):
|
# def handle_logging_system(self, ctx):
|
||||||
if self.setting_service.get_value("dc_system_log") != "0":
|
# if self.setting_service.get_value("dc_system_log") != "0":
|
||||||
message = self.format(ctx.message)
|
# message = self.format(ctx.message)
|
||||||
self.discord.send_message(self.setting_service.get_value("dc_system_log"), f"{html.unescape(message)}")
|
# self.discord.send_message(self.setting_service.get_value("dc_system_log"), f"{html.unescape(message)}")
|
||||||
|
#
|
||||||
def handle_logging_members(self, ctx):
|
# def handle_logging_members(self, ctx):
|
||||||
if self.setting_service.get_value("dc_member_log") != "0":
|
# if self.setting_service.get_value("dc_member_log") != "0":
|
||||||
channel = self.discord.client.get_channel(int(self.setting_service.get_value("dc_member_log")))
|
# channel = self.discord.client.get_channel(int(self.setting_service.get_value("dc_member_log")))
|
||||||
spam = []
|
# spam = []
|
||||||
current = 0
|
# current = 0
|
||||||
for message in ctx.message:
|
# for message in ctx.message:
|
||||||
current += 1
|
# current += 1
|
||||||
spam.append(Embed(title=f"Recent changes - {datetime.date.today()} - ({current}/{len(ctx.message)})",
|
# spam.append(Embed(title=f"Recent changes - {datetime.date.today()} - ({current}/{len(ctx.message)})",
|
||||||
description=message, color=3066993))
|
# description=message, color=3066993))
|
||||||
asyncio.run_coroutine_threadsafe(self.send_spam(channel, spam), self.discord.loop)
|
# asyncio.run_coroutine_threadsafe(self.send_spam(channel, spam), self.discord.loop)
|
||||||
|
#
|
||||||
async def send_spam(self, channel, message):
|
# async def send_spam(self, channel, message):
|
||||||
if self.discord.client.is_ready():
|
# if self.discord.client.is_ready():
|
||||||
for i in message:
|
# for i in message:
|
||||||
await channel.send(embed=i)
|
# await channel.send(embed=i)
|
||||||
|
#
|
||||||
def format(self, message):
|
# def format(self, message):
|
||||||
return self.text.strip_html_tags(message)
|
# return self.text.strip_html_tags(message)
|
||||||
|
|||||||
+77
-21
@@ -1,4 +1,5 @@
|
|||||||
import re
|
import re
|
||||||
|
import typing
|
||||||
|
|
||||||
from core.aochat import server_packets, client_packets
|
from core.aochat import server_packets, client_packets
|
||||||
from core.aochat.client_packets import PrivateChannelLeave
|
from core.aochat.client_packets import PrivateChannelLeave
|
||||||
@@ -16,6 +17,10 @@ from core.igncore import IgnCore
|
|||||||
|
|
||||||
|
|
||||||
# noinspection DuplicatedCode
|
# noinspection DuplicatedCode
|
||||||
|
if typing.TYPE_CHECKING:
|
||||||
|
from modules.core.discord.discord_controller import DiscordController
|
||||||
|
|
||||||
|
|
||||||
@instance()
|
@instance()
|
||||||
class AllianceRelay:
|
class AllianceRelay:
|
||||||
MESSAGE_SOURCE = "alliance"
|
MESSAGE_SOURCE = "alliance"
|
||||||
@@ -30,6 +35,7 @@ class AllianceRelay:
|
|||||||
self.character_service: CharacterService = registry.get_instance("character_service")
|
self.character_service: CharacterService = registry.get_instance("character_service")
|
||||||
self.message_hub_service = registry.get_instance("message_hub_service")
|
self.message_hub_service = registry.get_instance("message_hub_service")
|
||||||
self.public_channel_service = registry.get_instance("public_channel_service")
|
self.public_channel_service = registry.get_instance("public_channel_service")
|
||||||
|
self.discord: DiscordController = registry.get_instance("discord_controller")
|
||||||
self.text: Text = registry.get_instance("text")
|
self.text: Text = registry.get_instance("text")
|
||||||
|
|
||||||
def pre_start(self):
|
def pre_start(self):
|
||||||
@@ -54,17 +60,24 @@ class AllianceRelay:
|
|||||||
if color:
|
if color:
|
||||||
return f"<font color={color}>{msg}</font>"
|
return f"<font color={color}>{msg}</font>"
|
||||||
return "UNSET"
|
return "UNSET"
|
||||||
|
|
||||||
blob = ""
|
blob = ""
|
||||||
for bot in self.relay_bots().get_value().keys():
|
for bot in self.relay_bots().get_value().keys():
|
||||||
enabled = self.relay_enabled().get_value().get(bot, self.relay_enabled().get_value().get('default', 'UNSET'))
|
enabled = self.relay_enabled().get_value().get(bot,
|
||||||
|
self.relay_enabled().get_value().get('default', 'UNSET'))
|
||||||
prefix = self.relay_symbols().get_value().get(bot, self.relay_symbols().get_value().get('default'))
|
prefix = self.relay_symbols().get_value().get(bot, self.relay_symbols().get_value().get('default'))
|
||||||
relay_cmd = self.relay_command().get_value().get(bot, self.relay_command().get_value().get('default'))
|
relay_cmd = self.relay_command().get_value().get(bot, self.relay_command().get_value().get('default'))
|
||||||
base = self.relay_color_base().get_value().get(bot, self.relay_color_base().get_value().get('default', None))
|
base = self.relay_color_base().get_value().get(bot,
|
||||||
sender = self.relay_color_sender().get_value().get(bot, self.relay_color_sender().get_value().get('default', None))
|
self.relay_color_base().get_value().get('default', None))
|
||||||
|
sender = self.relay_color_sender().get_value().get(bot, self.relay_color_sender().get_value().get('default',
|
||||||
|
None))
|
||||||
abbrv = self.relay_color_org().get_value().get(bot, self.relay_color_org().get_value().get('default', None))
|
abbrv = self.relay_color_org().get_value().get(bot, self.relay_color_org().get_value().get('default', None))
|
||||||
msg = self.relay_color_msg().get_value().get(bot, self.relay_color_msg().get_value().get('default', None))
|
msg = self.relay_color_msg().get_value().get(bot, self.relay_color_msg().get_value().get('default', None))
|
||||||
our_abbrv = self.relay_guild_abbreviations().get_value().get(bot, self.relay_guild_abbreviations().get_value().get('default', 'UNSET'))
|
our_abbrv = self.relay_guild_abbreviations().get_value().get(bot,
|
||||||
example = display_color(base, f'[{display_color(abbrv, our_abbrv)}] {display_color(sender, request.sender.name)}: {display_color(msg, "And I sent you a message")}')
|
self.relay_guild_abbreviations().get_value().get(
|
||||||
|
'default', 'UNSET'))
|
||||||
|
example = display_color(base,
|
||||||
|
f'[{display_color(abbrv, our_abbrv)}] {display_color(sender, request.sender.name)}: {display_color(msg, "And I sent you a message")}')
|
||||||
blob += f"Relay <highlight>{self.character_service.get_char_name(int(bot))}</highlight>:\n"
|
blob += f"Relay <highlight>{self.character_service.get_char_name(int(bot))}</highlight>:\n"
|
||||||
blob += f" Enabled: {enabled} [{self.text.make_tellcmd('Toggle', f'mrelay status {bot} {not enabled}')}]\n"
|
blob += f" Enabled: {enabled} [{self.text.make_tellcmd('Toggle', f'mrelay status {bot} {not enabled}')}]\n"
|
||||||
blob += f" Prefix: {prefix} [{self.text.make_tellcmd('Edit', f'mrelay prefix {bot}')}]\n"
|
blob += f" Prefix: {prefix} [{self.text.make_tellcmd('Edit', f'mrelay prefix {bot}')}]\n"
|
||||||
@@ -148,7 +161,8 @@ class AllianceRelay:
|
|||||||
return f"Successfully deleted relay <highlight>{bot.name}</highlight>"
|
return f"Successfully deleted relay <highlight>{bot.name}</highlight>"
|
||||||
|
|
||||||
@command(command="mrelay",
|
@command(command="mrelay",
|
||||||
params=[Const("rcmd"), Character("relaybot_name"), Any("relay_command", is_optional=True)], access_level="admin",
|
params=[Const("rcmd"), Character("relaybot_name"), Any("relay_command", is_optional=True)],
|
||||||
|
access_level="admin",
|
||||||
description="Change the relay command used in a relay")
|
description="Change the relay command used in a relay")
|
||||||
def mrelay_rcmd(self, request, _, bot, relay_command):
|
def mrelay_rcmd(self, request, _, bot, relay_command):
|
||||||
bots: dict = self.relay_bots().get_value()
|
bots: dict = self.relay_bots().get_value()
|
||||||
@@ -173,7 +187,8 @@ class AllianceRelay:
|
|||||||
f"<highlight>{self.character_service.get_char_name(int(bot))}</highlight>: <highlight>{relay_command}</highlight>"
|
f"<highlight>{self.character_service.get_char_name(int(bot))}</highlight>: <highlight>{relay_command}</highlight>"
|
||||||
|
|
||||||
@command(command="mrelay",
|
@command(command="mrelay",
|
||||||
params=[Const("prefix"), Character("relaybot_name"), Any("prefix", is_optional=True)], access_level="admin",
|
params=[Const("prefix"), Character("relaybot_name"), Any("prefix", is_optional=True)],
|
||||||
|
access_level="admin",
|
||||||
description="Change the prefix setting of the relays")
|
description="Change the prefix setting of the relays")
|
||||||
def mrelay_prefix(self, request, _, bot, prefix):
|
def mrelay_prefix(self, request, _, bot, prefix):
|
||||||
bots: dict = self.relay_bots().get_value()
|
bots: dict = self.relay_bots().get_value()
|
||||||
@@ -234,7 +249,9 @@ class AllianceRelay:
|
|||||||
return f"Successfully changed the status of the relay " \
|
return f"Successfully changed the status of the relay " \
|
||||||
f"<highlight>{self.character_service.get_char_name(int(bot))}</highlight> to: <highlight>{option}</highlight>"
|
f"<highlight>{self.character_service.get_char_name(int(bot))}</highlight> to: <highlight>{option}</highlight>"
|
||||||
|
|
||||||
@command(command="mrelay", params=[Const("color"), Character("relaybot_name"), Options(["base", "sender", "org", "msg"]), Any("color_code", is_optional=True)], access_level="admin",
|
@command(command="mrelay",
|
||||||
|
params=[Const("color"), Character("relaybot_name"), Options(["base", "sender", "org", "msg"]),
|
||||||
|
Any("color_code", is_optional=True)], access_level="admin",
|
||||||
description="Change the color settings of the relays")
|
description="Change the color settings of the relays")
|
||||||
def mrelay_color(self, request, _, bot, option, color):
|
def mrelay_color(self, request, _, bot, option, color):
|
||||||
bots: dict = self.relay_bots().get_value()
|
bots: dict = self.relay_bots().get_value()
|
||||||
@@ -312,7 +329,8 @@ class AllianceRelay:
|
|||||||
return
|
return
|
||||||
if str(packet.private_channel_id) not in self.relay_bots().get_value().keys():
|
if str(packet.private_channel_id) not in self.relay_bots().get_value().keys():
|
||||||
return
|
return
|
||||||
if not self.relay_enabled().get_value().get(str(packet.private_channel_id), self.relay_enabled().get_value().get('default', False)):
|
if not self.relay_enabled().get_value().get(str(packet.private_channel_id),
|
||||||
|
self.relay_enabled().get_value().get('default', False)):
|
||||||
return
|
return
|
||||||
self.bot.send_packet(client_packets.PrivateChannelJoin(packet.private_channel_id))
|
self.bot.send_packet(client_packets.PrivateChannelJoin(packet.private_channel_id))
|
||||||
self.logger.info(f"Joined private channel {self.character_service.get_char_name(packet.private_channel_id)}")
|
self.logger.info(f"Joined private channel {self.character_service.get_char_name(packet.private_channel_id)}")
|
||||||
@@ -344,38 +362,72 @@ class AllianceRelay:
|
|||||||
text = text.strip()
|
text = text.strip()
|
||||||
|
|
||||||
plain = f"[{org}] {name}: {text}"
|
plain = f"[{org}] {name}: {text}"
|
||||||
org = self.format_text(self.relay_color_org().get_value().get(priv, self.relay_color_org().get_value().get("default")), org)
|
org = self.format_text(
|
||||||
name = self.format_text(self.relay_color_sender().get_value().get(priv, self.relay_color_sender().get_value().get("default")), name)
|
self.relay_color_org().get_value().get(priv, self.relay_color_org().get_value().get("default")), org)
|
||||||
text = self.format_text(self.relay_color_msg().get_value().get(priv, self.relay_color_msg().get_value().get("default")), text)
|
name = self.format_text(
|
||||||
formatted = self.format_text(self.relay_color_base().get_value().get(priv, self.relay_color_base().get_value().get("default")), f"[{org}] {name}: {text}")
|
self.relay_color_sender().get_value().get(priv, self.relay_color_sender().get_value().get("default")), name)
|
||||||
|
text = self.format_text(
|
||||||
|
self.relay_color_msg().get_value().get(priv, self.relay_color_msg().get_value().get("default")), text)
|
||||||
|
formatted = self.format_text(
|
||||||
|
self.relay_color_base().get_value().get(priv, self.relay_color_base().get_value().get("default")),
|
||||||
|
f"[{org}] {name}: {text}")
|
||||||
sender = DictObject({"char_id": packet.char_id, "name": self.character_service.get_char_name(packet.char_id)})
|
sender = DictObject({"char_id": packet.char_id, "name": self.character_service.get_char_name(packet.char_id)})
|
||||||
self.message_hub_service.send_message(self.MESSAGE_SOURCE, sender, plain, formatted)
|
self.message_hub_service.send_message(self.MESSAGE_SOURCE, sender, self.text.strip_html_tags(plain), formatted)
|
||||||
|
|
||||||
def handle_relay_hub_message(self, ctx):
|
def handle_relay_hub_message(self, ctx):
|
||||||
enabled = lambda x: self.relay_enabled().get_value().get(x, self.relay_enabled().get_value().get('default', False))
|
enabled = lambda x: self.relay_enabled().get_value().get(x,
|
||||||
|
self.relay_enabled().get_value().get('default', False))
|
||||||
if not ctx.message:
|
if not ctx.message:
|
||||||
return
|
return
|
||||||
|
if not ctx.sender:
|
||||||
|
return
|
||||||
|
if type(ctx.message) == ChatBlob:
|
||||||
|
return
|
||||||
for key in self.relay_bots().get_value().keys():
|
for key in self.relay_bots().get_value().keys():
|
||||||
if key not in self.relay_channel:
|
if key not in self.relay_channel:
|
||||||
continue
|
continue
|
||||||
if not enabled(key):
|
if not enabled(key):
|
||||||
continue
|
continue
|
||||||
prefix = self.relay_symbols().get_value().get(key, self.relay_symbols().get_value().get('default', False))
|
prefix = self.relay_symbols().get_value().get(key, self.relay_symbols().get_value().get('default', False))
|
||||||
if not ctx.message.startswith(prefix):
|
if not(ctx.message.startswith(prefix)):
|
||||||
continue
|
continue
|
||||||
|
sender = ctx.sender.name
|
||||||
message = ctx.message[len(prefix):].strip()
|
message = ctx.message[len(prefix):].strip()
|
||||||
if len(message) < 1:
|
if len(message) < 1:
|
||||||
continue
|
continue
|
||||||
sender = ctx.sender.name
|
|
||||||
|
|
||||||
abbrv = self.relay_guild_abbreviations().get_value().get(key, self.setting_service.get_value("org_name"))
|
abbrv = self.relay_guild_abbreviations().get_value().get(key, self.setting_service.get_value("org_name"))
|
||||||
if ctx.source == "private_channel":
|
if ctx.source == "private_channel":
|
||||||
abbrv += " - Guest"
|
abbrv += " - Guest"
|
||||||
elif ctx.source == "public_relay":
|
elif ctx.source.startswith("Discord_("):
|
||||||
abbrv += " - DC"
|
abbrv += " - DC"
|
||||||
|
|
||||||
cmd = self.relay_command().get_value().get(key, self.relay_command().get_value().get("default"))
|
cmd = self.relay_command().get_value().get(key, self.relay_command().get_value().get("default"))
|
||||||
msg = f"{cmd} [{abbrv}] {sender}: {message}"
|
# msg = f"{cmd} [{abbrv}] {sender}: {message}"
|
||||||
|
blob = ""
|
||||||
|
if ctx.source.startswith("Discord_("):
|
||||||
|
if self.discord.alias_usage().get_value():
|
||||||
|
abbrv = self.discord.alias_controller.get_alias(ctx.sender.org_id)
|
||||||
|
invite = self.text.make_chatcmd("click here", "/tell <myname> discord invite",
|
||||||
|
style="style='text-decoration:none'")
|
||||||
|
# name = "<header2><myname></header2>"
|
||||||
|
if self.discord.guild and self.discord.bot:
|
||||||
|
name = f"<header2>DC Server: <highlight>{self.discord.guild.name}</highlight> - " \
|
||||||
|
f"Bot: <highlight><myname></highlight></header2>"
|
||||||
|
blob = self.text.format_page('Info',
|
||||||
|
f"<header>::: Information :::</header><br><br>"
|
||||||
|
f"This message has been sent to you by:<br><br>"
|
||||||
|
f"{name}<br>"
|
||||||
|
f"<tab>Sender: <notice>{ctx.sender.name}</notice><br>"
|
||||||
|
f"<tab>Tag: <highlight>{ctx.sender.discord_nick}</highlight><br><br>"
|
||||||
|
f"To reply, either respond in the relay or "
|
||||||
|
f"contact them directly at the provided handles.<br><br>"
|
||||||
|
f"<header2>Have you joined our Discord Server yet? "
|
||||||
|
f"If not <highlight>{invite}</highlight> to receive an invite.</header2>")
|
||||||
|
blob = f"<yellow>[{blob}]</yellow>"
|
||||||
|
# msg = f"{cmd} [{self.discord.alias_controller.get_alias(ctx.sender.org_id)}] {ctx.message} <yellow>[{blob}]</yellow>"
|
||||||
|
msg = f"{cmd} [{abbrv}] {sender}: {message} {blob}"
|
||||||
|
|
||||||
self.send_message_to_alliance(key, msg)
|
self.send_message_to_alliance(key, msg)
|
||||||
|
|
||||||
def send_message_to_alliance(self, alliance, msg):
|
def send_message_to_alliance(self, alliance, msg):
|
||||||
@@ -398,7 +450,8 @@ class AllianceRelay:
|
|||||||
def relay_enabled(self) -> DictionarySettingType:
|
def relay_enabled(self) -> DictionarySettingType:
|
||||||
return DictionarySettingType()
|
return DictionarySettingType()
|
||||||
|
|
||||||
@setting(name="relay_guild_abbreviations", value={"default": "UNSET"}, description="Abbreviations used for the relays")
|
@setting(name="relay_guild_abbreviations", value={"default": "UNSET"},
|
||||||
|
description="Abbreviations used for the relays")
|
||||||
def relay_guild_abbreviations(self) -> DictionarySettingType:
|
def relay_guild_abbreviations(self) -> DictionarySettingType:
|
||||||
return DictionarySettingType()
|
return DictionarySettingType()
|
||||||
|
|
||||||
@@ -431,3 +484,6 @@ class AllianceRelay:
|
|||||||
|
|
||||||
def format_text(self, color, message):
|
def format_text(self, color, message):
|
||||||
return f"<font color={color}>{message}</font>"
|
return f"<font color={color}>{message}</font>"
|
||||||
|
|
||||||
|
# def alias_usage(self):
|
||||||
|
# return self.setting_service.get("use_prefix")
|
||||||
@@ -47,7 +47,7 @@ class TimeController:
|
|||||||
day += "rd"
|
day += "rd"
|
||||||
else:
|
else:
|
||||||
day += "th"
|
day += "th"
|
||||||
return f"Currently its {now.hour}:{now.minute}:{now.second} " \
|
return f"Currently its {now.hour:02}:{now.minute:02}:{now.second:02} " \
|
||||||
f"{calendar.month_name[now.month]} {day}, {now.year + 27474} Rubi-Ka Universal Time."
|
f"{calendar.month_name[now.month]} {day}, {now.year + 27474} Rubi-Ka Universal Time."
|
||||||
|
|
||||||
@command(command="time", params=[Any("timezone")], access_level="member",
|
@command(command="time", params=[Any("timezone")], access_level="member",
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import time
|
import time
|
||||||
|
import typing
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
|
||||||
from core.buddy_service import BuddyService
|
from core.buddy_service import BuddyService
|
||||||
@@ -8,16 +9,17 @@ from core.db import DB
|
|||||||
from core.decorators import instance, command
|
from core.decorators import instance, command
|
||||||
from core.job_scheduler import JobScheduler
|
from core.job_scheduler import JobScheduler
|
||||||
from core.logger import Logger
|
from core.logger import Logger
|
||||||
from core.lookup.pork_service import PorkService
|
|
||||||
from core.setting_service import SettingService
|
|
||||||
from core.text import Text
|
from core.text import Text
|
||||||
from core.igncore import IgnCore
|
from core.igncore import IgnCore
|
||||||
from core.util import Util
|
from core.util import Util
|
||||||
from modules.core.accounting.preference_controller import PreferenceController
|
if typing.TYPE_CHECKING:
|
||||||
from modules.core.accounting.services.account_service import AccountService
|
from core.lookup.pork_service import PorkService
|
||||||
from modules.core.ban.ban_service import BanService
|
from core.setting_service import SettingService
|
||||||
from modules.core.discord.discord_controller import DiscordController
|
from modules.core.accounting.preference_controller import PreferenceController
|
||||||
from modules.onlinebot.online.org_alias_controller import OrgAliasController
|
from modules.core.accounting.services.account_service import AccountService
|
||||||
|
from modules.core.ban.ban_service import BanService
|
||||||
|
from modules.core.discord.discord_controller import DiscordController
|
||||||
|
from modules.onlinebot.online.org_alias_controller import OrgAliasController
|
||||||
|
|
||||||
|
|
||||||
@instance()
|
@instance()
|
||||||
|
|||||||
@@ -3,13 +3,14 @@ import time
|
|||||||
from core.chat_blob import ChatBlob
|
from core.chat_blob import ChatBlob
|
||||||
from core.command_alias_service import CommandAliasService
|
from core.command_alias_service import CommandAliasService
|
||||||
from core.command_param_types import Any
|
from core.command_param_types import Any
|
||||||
from core.decorators import instance, command, event
|
from core.decorators import instance, command, event, setting
|
||||||
from core.dict_object import DictObject
|
from core.dict_object import DictObject
|
||||||
from core.igncore import IgnCore
|
from core.igncore import IgnCore
|
||||||
from core.job_scheduler import JobScheduler
|
from core.job_scheduler import JobScheduler
|
||||||
from core.logger import Logger
|
from core.logger import Logger
|
||||||
|
from core.message_hub_service import MessageHubService
|
||||||
from core.setting_service import SettingService
|
from core.setting_service import SettingService
|
||||||
from core.setting_types import BooleanSettingType
|
from core.setting_types import BooleanSettingType, TextSettingType
|
||||||
from core.text import Text
|
from core.text import Text
|
||||||
from core.util import Util
|
from core.util import Util
|
||||||
from modules.standard.datanet.ws_controller import WebsocketRelayController
|
from modules.standard.datanet.ws_controller import WebsocketRelayController
|
||||||
@@ -35,8 +36,11 @@ class WorldBossController:
|
|||||||
self.command_alias_service: CommandAliasService = registry.get_instance("command_alias_service")
|
self.command_alias_service: CommandAliasService = registry.get_instance("command_alias_service")
|
||||||
self.job_scheduler: JobScheduler = registry.get_instance("job_scheduler")
|
self.job_scheduler: JobScheduler = registry.get_instance("job_scheduler")
|
||||||
self.setting_service: SettingService = registry.get_instance("setting_service")
|
self.setting_service: SettingService = registry.get_instance("setting_service")
|
||||||
|
self.relay_hub: MessageHubService = registry.get_instance("message_hub_service")
|
||||||
|
|
||||||
def pre_start(self):
|
def pre_start(self):
|
||||||
|
self.relay_hub.register_message_source("timers")
|
||||||
|
|
||||||
self.setting_service.register(self.module_name, 'timer_spam', False, BooleanSettingType(),
|
self.setting_service.register(self.module_name, 'timer_spam', False, BooleanSettingType(),
|
||||||
"should timers be spammed")
|
"should timers be spammed")
|
||||||
self.command_alias_service.add_alias("tara", "wb tara")
|
self.command_alias_service.add_alias("tara", "wb tara")
|
||||||
@@ -120,7 +124,7 @@ class WorldBossController:
|
|||||||
return DictObject({'spawn': last - immortal, 'mortal': last})
|
return DictObject({'spawn': last - immortal, 'mortal': last})
|
||||||
|
|
||||||
def send_warn(self, msg):
|
def send_warn(self, msg):
|
||||||
self.bot.send_private_channel_message(f"[<red>WB</red>] {msg}")
|
self.relay_hub.send_message("timers", None, f"[<red>WB</red>] {msg}", f"[<red>WB</red>] {msg}")
|
||||||
|
|
||||||
def get_next_alert(self, duration):
|
def get_next_alert(self, duration):
|
||||||
for alert in self.alerts:
|
for alert in self.alerts:
|
||||||
@@ -190,3 +194,8 @@ class WorldBossController:
|
|||||||
job['id'] = job_id
|
job['id'] = job_id
|
||||||
return
|
return
|
||||||
self.jobs.append({'name': timer.name, 'id': job_id})
|
self.jobs.append({'name': timer.name, 'id': job_id})
|
||||||
|
|
||||||
|
# @setting('alert_times', '[480 * 60, 360 * 60, 240 * 60, 120 * 60, 60 * 60, 60 * 15, 60 * 5, 60 * 3, 60 * 2, 60, 30, 15, 5, 0]', 'Worldboss timer spam messages (ETA and actual)')
|
||||||
|
# def alert_times(self):
|
||||||
|
# return TextSettingType(['[480 * 60, 360 * 60, 240 * 60, 120 * 60, 60 * 60, 60 * 15, 60 * 5, 60 * 3, 60 * 2, 60, 30, 15, 5, 0]'])
|
||||||
|
|
||||||
|
|||||||
@@ -39,11 +39,11 @@ class OnlineDisplay:
|
|||||||
if org > 0:
|
if org > 0:
|
||||||
postfix.append(f"<notice>Org: {org}</notice>")
|
postfix.append(f"<notice>Org: {org}</notice>")
|
||||||
if priv > 0:
|
if priv > 0:
|
||||||
postfix.append(f"<highlight>Priv: {priv}</notice>")
|
postfix.append(f"<notice>Priv: {priv}</notice>")
|
||||||
if notify > 0:
|
if notify > 0:
|
||||||
postfix.append(f"<notice>Buddylist: {notify}</notice>")
|
postfix.append(f"<notice>Buddylist: {notify}</notice>")
|
||||||
blob = ChatBlob(title, blob, suffix=f" ({f', '.join(postfix)})")
|
blob = ChatBlob(title, blob, suffix=f" ({f', '.join(postfix)})")
|
||||||
return blob
|
return blob if (org+priv+notify) != 0 else "There's nobody online."
|
||||||
|
|
||||||
def format_by_channel_main(self, query, params):
|
def format_by_channel_main(self, query, params):
|
||||||
query += "order by channel_id, main_name, p.name=main_name, p.name, r_id"
|
query += "order by channel_id, main_name, p.name=main_name, p.name, r_id"
|
||||||
@@ -161,7 +161,7 @@ class OnlineDisplay:
|
|||||||
if org_id != temp_blob[key]["id"]:
|
if org_id != temp_blob[key]["id"]:
|
||||||
org_id = temp_blob[key]["id"]
|
org_id = temp_blob[key]["id"]
|
||||||
blob += f"\n<pagebreak><highlight>{temp_blob[key]['name']}</highlight>" \
|
blob += f"\n<pagebreak><highlight>{temp_blob[key]['name']}</highlight>" \
|
||||||
f"<header> ({len(temp_blob[key]['online']): >3} " \
|
f" <header>({len(temp_blob[key]['online']): >3} " \
|
||||||
f"| {len(temp_blob[key]['online']) / len(query) * 100:.2f}%)</header>\n"
|
f"| {len(temp_blob[key]['online']) / len(query) * 100:.2f}%)</header>\n"
|
||||||
blob += self.format_org(user)
|
blob += self.format_org(user)
|
||||||
return blob, 0, 0, len(query)
|
return blob, 0, 0, len(query)
|
||||||
|
|||||||
@@ -214,18 +214,18 @@ class SpecialsController:
|
|||||||
|
|
||||||
blob += "<header2>Martial Artist</header2>\n"
|
blob += "<header2>Martial Artist</header2>\n"
|
||||||
blob += f"Speed: <highlight>{ma_info.ma_speed:.2f} / {ma_info.ma_speed:.2f} secs</highlight>\n"
|
blob += f"Speed: <highlight>{ma_info.ma_speed:.2f} / {ma_info.ma_speed:.2f} secs</highlight>\n"
|
||||||
blob += f"Damage: <highlight>{ma_info.ma_min_dmg:d} - {ma_info.ma_max_dmg:d} " \
|
blob += f"Damage: <highlight>{ma_info.ma_min_dmg:.2f} - {ma_info.ma_max_dmg:.2f} " \
|
||||||
f"({ma_info.ma_crit_dmg:d})</highlight>\n\n"
|
f"({ma_info.ma_crit_dmg:.2f})</highlight>\n\n"
|
||||||
|
|
||||||
blob += "<header2>Shade</header2>\n"
|
blob += "<header2>Shade</header2>\n"
|
||||||
blob += f"Speed: <highlight>{ma_info.shade_speed:.2f} / {ma_info.shade_speed:.2f} secs</highlight>\n"
|
blob += f"Speed: <highlight>{ma_info.shade_speed:.2f} / {ma_info.shade_speed:.2f} secs</highlight>\n"
|
||||||
blob += f"Damage: <highlight>{ma_info.shade_min_dmg:d} - {ma_info.shade_max_dmg:d} " \
|
blob += f"Damage: <highlight>{ma_info.shade_min_dmg:.2f} - {ma_info.shade_max_dmg:.2f} " \
|
||||||
f"({ma_info.shade_crit_dmg:d})</highlight>\n\n"
|
f"({ma_info.shade_crit_dmg:.2f})</highlight>\n\n"
|
||||||
|
|
||||||
blob += "<header2>All other professions</header2>\n"
|
blob += "<header2>All other professions</header2>\n"
|
||||||
blob += f"Speed: <highlight>{ma_info.gen_speed:.2f} / {ma_info.gen_speed:.2f} secs</highlight>\n"
|
blob += f"Speed: <highlight>{ma_info.gen_speed:.2f} / {ma_info.gen_speed:.2f} secs</highlight>\n"
|
||||||
blob += f"Damage: <highlight>{ma_info.gen_min_dmg:d} - {ma_info.gen_max_dmg:d} " \
|
blob += f"Damage: <highlight>{ma_info.gen_min_dmg:.2f} - {ma_info.gen_max_dmg:.2f} " \
|
||||||
f"({ma_info.gen_crit_dmg:d})</highlight>\n\n"
|
f"({ma_info.gen_crit_dmg:.2f})</highlight>\n\n"
|
||||||
|
|
||||||
return ChatBlob("Martial Arts Results", blob)
|
return ChatBlob("Martial Arts Results", blob)
|
||||||
|
|
||||||
|
|||||||
@@ -108,12 +108,12 @@ class CharacterInfoController:
|
|||||||
blob += self.alts_controller.format_alt_list(alts)
|
blob += self.alts_controller.format_alt_list(alts)
|
||||||
|
|
||||||
more_info = self.text.paginate_single(ChatBlob("More Info", blob))
|
more_info = self.text.paginate_single(ChatBlob("More Info", blob))
|
||||||
|
msg = ChatBlob("More Info", blob, self.text.format_char_info(char_info, online_status, True)+" ")
|
||||||
msg = self.text.format_char_info(char_info, online_status, True) + " " + more_info
|
# msg = self.text.format_char_info(char_info, online_status, True) + " " + more_info
|
||||||
elif char.char_id:
|
elif char.char_id:
|
||||||
blob = "<notice>Note: Could not retrieve detailed info for character.</notice>\n\n"
|
blob = "<notice>Note: Could not retrieve detailed info for character.</notice>\n\n"
|
||||||
blob += f"Name: <highlight>{char.name}</highlight>\n"
|
blob += f"Name: <highlight>{char.name}</highlight>\n"
|
||||||
blob += f"Character ID: <highlight>{char.char_id:d}</highlight>\n"
|
blob += f"Character ID: <highlight>{char.char_id}</highlight>\n"
|
||||||
if online_status is not None:
|
if online_status is not None:
|
||||||
blob += f"Online status: {'<green>Online</green>' if online_status else '<red>Offline</red>'}\n"
|
blob += f"Online status: {'<green>Online</green>' if online_status else '<red>Offline</red>'}\n"
|
||||||
blob += self.get_name_history(char.char_id)
|
blob += self.get_name_history(char.char_id)
|
||||||
|
|||||||
+1
-1
@@ -1,7 +1,7 @@
|
|||||||
bbcode==1.1.0
|
bbcode==1.1.0
|
||||||
beautifulsoup4==4.10.0
|
beautifulsoup4==4.10.0
|
||||||
cryptography==3.3.2
|
cryptography==3.3.2
|
||||||
discord.py @ git+https://github.com/Rapptz/discord.py@45d498c1b76deaf3b394d17ccf56112fa691d160
|
discord.py @ git+https://github.com/Rapptz/discord.py@1bfe6b2bb160ce802a1f08afed73941a19a0a651
|
||||||
emojis==0.6.0
|
emojis==0.6.0
|
||||||
hjson==3.0.2
|
hjson==3.0.2
|
||||||
mariadb==1.0.7
|
mariadb==1.0.7
|
||||||
|
|||||||
Reference in New Issue
Block a user