Added afk/brb

Timer messages ("Timer XX has yyy left") now get resumed after a bot restart
Alliance relay is discord compatible now. [Orgbot]
This commit is contained in:
2021-10-26 22:35:31 +02:00
parent bd8055dac7
commit 2d7ecf4883
14 changed files with 119 additions and 48 deletions
+1 -1
View File
@@ -50,7 +50,7 @@ try:
mod = __import__(f'conf.{bot}', fromlist=['BotConfig']) mod = __import__(f'conf.{bot}', fromlist=['BotConfig'])
config: BotConfig = getattr(mod, 'BotConfig') config: BotConfig = getattr(mod, 'BotConfig')
if sys.version_info < (3, 9): if sys.version_info < (3, 9):
logger.warning("Versions lower then Python3.10 are not supported.") logger.warning("Versions lower then Python3.9 are not supported.")
exit(-1) exit(-1)
# load config values from env vars # load config values from env vars
+3 -5
View File
@@ -25,6 +25,7 @@ class BotConfig:
"username": "", "username": "",
"password": "", "password": "",
"host": "", "host": "",
"port": 3306,
"name": ""}) "name": ""})
# IGNCore supports splitting of the DB; If you're hosting multiple bots, its generally a good idea to fill # IGNCore supports splitting of the DB; If you're hosting multiple bots, its generally a good idea to fill
@@ -39,14 +40,11 @@ class BotConfig:
"username": "", "username": "",
"password": "", "password": "",
"host": "", "host": "",
"port": 3306,
"name": "" "name": ""
}) })
# END # # END #
# If you have got access to any sort of tower API (there are multiple)
# you can enter the URI for accessing it here.
tower_url = ""
# In this section you can add some slaves to the bot. # In this section you can add some slaves to the bot.
# They serve as a buddylist expander, and tells may get sent through them. (Tells which are known to be spammy) # They serve as a buddylist expander, and tells may get sent through them. (Tells which are known to be spammy)
slaves = [ slaves = [
@@ -75,4 +73,4 @@ class BotConfig:
] ]
# DO NOT TOUCH THIS LINE # DO NOT TOUCH THIS LINE
slaves = [DictObject(x) for x in slaves if password != ""] slaves = [DictObject(x) for x in slaves]
+4 -2
View File
@@ -12,6 +12,7 @@ class BotConfig:
"username": "", "username": "",
"password": "", "password": "",
"host": "", "host": "",
"port": 3306,
"name": ""}) "name": ""})
shared_db = DictObject({ shared_db = DictObject({
@@ -19,9 +20,9 @@ class BotConfig:
"username": "", "username": "",
"password": "", "password": "",
"host": "", "host": "",
"port": 3306,
"name": "" "name": ""
}) })
tower_url = ""
slaves = [ slaves = [
# {"username": "account_name", "password": "password", "character": "character_name"}, # {"username": "account_name", "password": "password", "character": "character_name"},
@@ -39,4 +40,5 @@ class BotConfig:
"modules/raidbot" "modules/raidbot"
] ]
slaves = [DictObject(x) for x in slaves if password != ""] # DO NOT TOUCH THIS LINE
slaves = [DictObject(x) for x in slaves]
+1 -1
View File
@@ -42,7 +42,7 @@ class IgnCore:
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.7" self.major_version = "IGNCore v2.7"
self.minor_version = "1" self.minor_version = "2"
self.incoming_queue = FifoQueue() self.incoming_queue = FifoQueue()
self.mass_message_queue = None self.mass_message_queue = None
self.conns = DictObject() self.conns = DictObject()
+5 -5
View File
@@ -1,12 +1,12 @@
#!/usr/bin/env bash #!/usr/bin/env bash
PYTHON_BINARY=python3 #PYTHON_BINARY=python3
if ! [ -x "$(command -v $PYTHON_BINARY)" ]; then #if ! [ -x "$(command -v $PYTHON_BINARY)" ]; then
PYTHON_BINARY=python # PYTHON_BINARY=python
fi #fi
$PYTHON_BINARY --version
source venv/bin/activate source venv/bin/activate
python --version
set -o pipefail -o errexit set -o pipefail -o errexit
# The bot uses non-zero exit codes to signal state. # The bot uses non-zero exit codes to signal state.
@@ -122,18 +122,18 @@ class AccountService:
self.event_service.register_event_type(self.MEMBER_LOGON) self.event_service.register_event_type(self.MEMBER_LOGON)
self.event_service.register_event_type(self.MEMBER_LOGOFF) self.event_service.register_event_type(self.MEMBER_LOGOFF)
self.setting_service.register(self.module_name, "is_alliance_bot", False, BooleanSettingType(), self.setting_service.register(self.module_name, "is_alliance_bot", False, BooleanSettingType(),
"Is this bot used as an alliancebot") "Is this bot used as an alliancebot")
self.setting_service.register(self.module_name, "alt_verification", False, BooleanSettingType(), self.setting_service.register(self.module_name, "alt_verification", False, BooleanSettingType(),
"alts require admin verification") "alts require admin verification")
# Default preferences # Default preferences
self.setting_service.register(self.module_name, "pref_autoinvite", False, BooleanSettingType(), self.setting_service.register(self.module_name, "pref_autoinvite", False, BooleanSettingType(),
"Default Value for the auto invite preference") "Default Value for the auto invite preference")
self.setting_service.register(self.module_name, "pref_raidinvite", True, BooleanSettingType(), self.setting_service.register(self.module_name, "pref_raidinvite", True, BooleanSettingType(),
"Default Value for the raid invite (Massinvite) preference") "Default Value for the raid invite (Massinvite) preference")
self.setting_service.register(self.module_name, "pref_raidspam", True, BooleanSettingType(), self.setting_service.register(self.module_name, "pref_raidspam", True, BooleanSettingType(),
"Default Value for the raid spam (Mass Message) preference") "Default Value for the raid spam (Mass Message) preference")
self.setting_service.register(self.module_name, "pref_newsspam", True, BooleanSettingType(), self.setting_service.register(self.module_name, "pref_newsspam", True, BooleanSettingType(),
"Default Value for the news spam (News on logon) preference") "Default Value for the news spam (News on logon) preference")
v = self.setting_service.get_value("pref_raidspam") v = self.setting_service.get_value("pref_raidspam")
# Ranks # Ranks
@@ -316,6 +316,7 @@ class AccountService:
try: try:
def del_orgs(_): def del_orgs(_):
del self.orgs del self.orgs
self.orgs = [x["org_id"] for x in self.db.query("SELECT * from orgs", [])] self.orgs = [x["org_id"] for x in self.db.query("SELECT * from orgs", [])]
self.bot.job_scheduler.delayed_job(del_orgs, 60) self.bot.job_scheduler.delayed_job(del_orgs, 60)
return self.orgs return self.orgs
@@ -331,6 +332,7 @@ class AccountService:
try: try:
def del_orgs(_): def del_orgs(_):
del self.org_names del self.org_names
self.orgs = [x["org_name"] for x in self.db.query("SELECT * from orgs o " self.orgs = [x["org_name"] for x in self.db.query("SELECT * from orgs o "
"LEFT JOIN all_orgs a on o.org_id = ao.org_id", [])] "LEFT JOIN all_orgs a on o.org_id = ao.org_id", [])]
self.bot.job_scheduler.delayed_job(del_orgs, 60) self.bot.job_scheduler.delayed_job(del_orgs, 60)
+4 -2
View File
@@ -108,7 +108,7 @@ class DiscordController:
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")
def get_name(self, discord_id): def get_name(self, discord_id):
data = self.db.query_single( data = self.db.query_single(
@@ -584,6 +584,7 @@ class DiscordController:
return return
channel: TextChannel = msg.channel channel: TextChannel = msg.channel
if channel.id == int(self.setting_service.get_value("dc_relay_public")): if channel.id == int(self.setting_service.get_value("dc_relay_public")):
if self.setting_service.get_value('is_alliance_bot') == "0": if self.setting_service.get_value('is_alliance_bot') == "0":
response = f"[<notice>{html.escape(msg.author.nick if msg.author.nick else msg.author.name, False)}" \ response = f"[<notice>{html.escape(msg.author.nick if msg.author.nick else msg.author.name, False)}" \
f"</notice>]: " \ f"</notice>]: " \
@@ -592,7 +593,8 @@ class DiscordController:
response = f"{html.escape(msg.author.nick if msg.author.nick else msg.author.name, False)}: " \ response = f"{html.escape(msg.author.nick if msg.author.nick else msg.author.name, False)}: " \
f"{html.escape(emojis.decode(msg.clean_content), False)}" f"{html.escape(emojis.decode(msg.clean_content), False)}"
await msg.delete(delay=3600) await msg.delete(delay=3600)
self.relay_hub_service.send_message("public_relay", [msg.author.nick, msg.author], response, response) 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])
self.relay_hub_service.send_message("public_relay", sender, html.escape(emojis.decode(msg.clean_content), False), response)
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)
@@ -42,6 +42,7 @@ class PrivateChannelController:
self.account_service: AccountService = registry.get_instance("account_service") self.account_service: AccountService = registry.get_instance("account_service")
self.db: DB = registry.get_instance("db") self.db: DB = registry.get_instance("db")
self.priv: PrivateChannelService = registry.get_instance("private_channel_service") self.priv: PrivateChannelService = registry.get_instance("private_channel_service")
self.online_controller = registry.get_instance("online_controller", is_optional=True)
def pre_start(self): def pre_start(self):
self.db.create_view("online") self.db.create_view("online")
@@ -205,6 +206,10 @@ class PrivateChannelController:
msg = f"{self.text.format_char_info(self.pork.get_character_info(event_data.char_id))} joined us {info}" msg = f"{self.text.format_char_info(self.pork.get_character_info(event_data.char_id))} joined us {info}"
self.bot.send_private_channel_message(msg, fire_outgoing_event=False) self.bot.send_private_channel_message(msg, fire_outgoing_event=False)
self.message_hub_service.send_message(self.MESSAGE_SOURCE, None, msg, self.PRIVATE_CHANNEL_PREFIX + msg) self.message_hub_service.send_message(self.MESSAGE_SOURCE, None, msg, self.PRIVATE_CHANNEL_PREFIX + msg)
afk_list = {}
if self.online_controller:
afk_list = self.online_controller.afk_list
od = OnlineDisplay(self.text, self.util, self.db, afk_list)
od = OnlineDisplay(self.text, self.util, self.db) od = OnlineDisplay(self.text, self.util, self.db)
params = [self.bot.name, self.bot.get_char_id()] params = [self.bot.name, self.bot.get_char_id()]
self.bot.send_mass_message(event_data.char_id, self.bot.send_mass_message(event_data.char_id,
@@ -4,7 +4,6 @@ import time
from threading import Thread from threading import Thread
import requests import requests
from mysql.connector.cursor import CursorBase
from core.buddy_service import BuddyService from core.buddy_service import BuddyService
from core.cache_service import CacheService from core.cache_service import CacheService
@@ -173,7 +172,6 @@ class OrgController:
with self.db.pool.get_connection() as conn: with self.db.pool.get_connection() as conn:
with conn.cursor() as cur: with conn.cursor() as cur:
cur: CursorBase
cur.executemany( cur.executemany(
"INSERT INTO all_orgs(org_id, org_name, member_count, faction, last_seen) " "INSERT INTO all_orgs(org_id, org_name, member_count, faction, last_seen) "
"VALUES(?, ?, ?, ?, ?) " "VALUES(?, ?, ?, ?, ?) "
@@ -235,7 +233,6 @@ class OrgController:
with self.db.lock: with self.db.lock:
with self.db.pool.get_connection() as conn: with self.db.pool.get_connection() as conn:
with conn.cursor() as cur: with conn.cursor() as cur:
cur: CursorBase
cur.executemany("INSERT INTO player(char_id, name, first_name, last_name, " cur.executemany("INSERT INTO player(char_id, name, first_name, last_name, "
"level, breed, gender, faction, profession, profession_title, " "level, breed, gender, faction, profession, profession_title, "
"ai_rank, ai_level, org_id, org_name, org_rank_name, " "ai_rank, ai_level, org_id, org_name, org_rank_name, "
+11 -4
View File
@@ -6,6 +6,7 @@ from core.chat_blob import ChatBlob
from core.command_param_types import Const, Character, Options, Any from core.command_param_types import Const, Character, Options, Any
from core.conn import Conn from core.conn import Conn
from core.decorators import instance, command, setting from core.decorators import instance, command, setting
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.character_service import CharacterService
from core.setting_service import SettingService from core.setting_service import SettingService
@@ -44,8 +45,8 @@ class AllianceRelay:
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)
@command(command="mrelay", params=[], access_level="admin", @command(command="mrelay", params=[], access_level="member",
description="View the relay settings") description="View the relay settings", sub_command="info")
def mrelay(self, request): def mrelay(self, request):
def display_color(color, msg=None): def display_color(color, msg=None):
if not msg: if not msg:
@@ -347,7 +348,8 @@ class AllianceRelay:
name = self.format_text(self.relay_color_sender().get_value().get(priv, self.relay_color_sender().get_value().get("default")), name) name = self.format_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) 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}") 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.message_hub_service.send_message(self.MESSAGE_SOURCE, None, plain, formatted) 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)
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))
@@ -366,7 +368,12 @@ class AllianceRelay:
if len(message) < 1: if len(message) < 1:
continue continue
sender = ctx.sender.name sender = ctx.sender.name
abbrv = self.relay_guild_abbreviations().get_value().get(key, self.relay_guild_abbreviations().get_value().get("default"))
abbrv = self.relay_guild_abbreviations().get_value().get(key, self.setting_service.get_value("org_name"))
if ctx.source == "private_channel":
abbrv += " - Guest"
elif ctx.source == "public_relay":
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}"
self.send_message_to_alliance(key, msg) self.send_message_to_alliance(key, msg)
+4 -1
View File
@@ -88,7 +88,10 @@ class OrgChannelController:
self.bot.send_org_message(msg, fire_outgoing_event=False) self.bot.send_org_message(msg, fire_outgoing_event=False)
self.message_hub_service.send_message(self.MESSAGE_SOURCE, None, None, "[<cyan>Org</cyan>] " + msg) self.message_hub_service.send_message(self.MESSAGE_SOURCE, None, None, "[<cyan>Org</cyan>] " + msg)
od = OnlineDisplay(self.text, self.util, self.db) afk_list = []
if self.online_controller:
afk_list = self.online_controller.afk_list
od = OnlineDisplay(self.text, self.util, self.db, afk_list)
params = [self.bot.name, self.bot.get_char_id()] params = [self.bot.name, self.bot.get_char_id()]
self.bot.send_mass_message(event_data.packet.char_id, self.bot.send_mass_message(event_data.packet.char_id,
od.format_blob(od.format_by_channel_main("and channel_id IN (1, 2) ", params))) od.format_blob(od.format_by_channel_main("and channel_id IN (1, 2) ", params)))
+45 -2
View File
@@ -1,3 +1,4 @@
import re
import time import time
from threading import Thread from threading import Thread
@@ -7,13 +8,17 @@ from core.command_alias_service import CommandAliasService
from core.command_param_types import Int, Any, Const, Options from core.command_param_types import Int, Any, Const, Options
from core.db import DB from core.db import DB
from core.decorators import instance, event, command from core.decorators import instance, event, command
from core.dict_object import DictObject
from core.fifo_queue import FifoQueue from core.fifo_queue import FifoQueue
from core.logger import Logger from core.logger import Logger
from core.lookup.character_service import CharacterService
from core.private_channel_service import PrivateChannelService from core.private_channel_service import PrivateChannelService
from core.public_channel_service import PublicChannelService
from core.setting_service import SettingService 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.services.account_service import AccountService
from modules.standard.online.online_display import OnlineDisplay from modules.standard.online.online_display import OnlineDisplay
@@ -26,7 +31,8 @@ class User:
@instance() @instance()
class OnlineController: class OnlineController:
def __init__(self): def __init__(self):
self.assist = [] self.afk_list = {}
self.afk_regex = re.compile("^(afk|brb) ?(.*)$", re.IGNORECASE)
self.awaiting_data = FifoQueue() self.awaiting_data = FifoQueue()
def inject(self, registry): def inject(self, registry):
@@ -39,7 +45,9 @@ class OnlineController:
self.buddy_service: BuddyService = registry.get_instance("buddy_service") self.buddy_service: BuddyService = registry.get_instance("buddy_service")
self.setting_service: SettingService = registry.get_instance("setting_service") self.setting_service: SettingService = registry.get_instance("setting_service")
self.priv: PrivateChannelService = registry.get_instance("private_channel_service") self.priv: PrivateChannelService = registry.get_instance("private_channel_service")
self.online_display: OnlineDisplay = OnlineDisplay(self.text, self.util, self.db) self.online_display: OnlineDisplay = OnlineDisplay(self.text, self.util, self.db, self.afk_list)
self.account_service: AccountService = registry.get_instance("account_service")
self.character_service: CharacterService = registry.get_instance("character_service")
def pre_start(self): def pre_start(self):
self.db.exec("DROP TABLE IF EXISTS online") self.db.exec("DROP TABLE IF EXISTS online")
@@ -67,6 +75,8 @@ class OnlineController:
def priv_leave(self, _, event_data): def priv_leave(self, _, event_data):
self.db.exec("delete from online where char_id = ? and bot = ? and channel=?", self.db.exec("delete from online where char_id = ? and bot = ? and channel=?",
[event_data.char_id, self.bot.get_char_id(), self.bot.name]) [event_data.char_id, self.bot.get_char_id(), self.bot.name])
for alt in self.account_service.get_alts(event_data.char_id):
self.afk_list.pop(alt.char_id, None)
@event(event_type="member_logon", description="declare players as online") @event(event_type="member_logon", description="declare players as online")
def logon(self, _, event_data): def logon(self, _, event_data):
@@ -90,6 +100,8 @@ class OnlineController:
self.db.exec("DELETE FROM online where char_id=? and bot=?", self.db.exec("DELETE FROM online where char_id=? and bot=?",
[data.packet.char_id, self.bot.get_char_id()]) [data.packet.char_id, self.bot.get_char_id()])
self.db.exec("UPDATE account set last_seen=? where char_id=?", [time.time(), data.packet.char_id]) self.db.exec("UPDATE account set last_seen=? where char_id=?", [time.time(), data.packet.char_id])
for alt in self.account_service.get_alts(data.packet.char_id):
self.afk_list.pop(alt.char_id, None)
@command(command="online", params=[Const('all', is_optional=True), @command(command="online", params=[Const('all', is_optional=True),
Int("min_level", is_optional=True), Int("min_level", is_optional=True),
@@ -134,3 +146,34 @@ class OnlineController:
return f"Invalid Title level: {filters}" return f"Invalid Title level: {filters}"
output = self.online_display.count_tl(query, params, filters) output = self.online_display.count_tl(query, params, filters)
return output if output != "" else "Nobody is in my private channel, sorry..." return output if output != "" else "Nobody is in my private channel, sorry..."
@event(PrivateChannelService.PRIVATE_CHANNEL_MESSAGE_EVENT, "Check for afk messages in private channel")
def afk_check_private_channel_event(self, event_type, event_data):
self.afk_check(event_data.char_id, event_data.message, lambda msg: self.bot.send_private_channel_message(msg))
@event(PublicChannelService.ORG_CHANNEL_MESSAGE_EVENT, "Check for afk messages in org channel")
def afk_check_org_channel_event(self, event_type, event_data):
self.afk_check(event_data.char_id, event_data.message, lambda msg: self.bot.send_org_message(msg))
def afk_check(self, char_id, message, channel_reply):
matches = self.afk_regex.search(message)
if matches:
char_name = self.character_service.resolve_char_to_name(char_id)
channel_reply(f"<highlight>{char_name}</highlight> is now afk.")
alts = self.account_service.get_alts(char_id)
for alt in alts:
self.afk_list[alt.char_id] = DictObject({"message": message, "time": time.time()})
elif char_id in self.afk_list.keys():
# TODO handle multiple rows
alts = self.account_service.get_alts(char_id)
data = None
for alt in alts:
out = self.afk_list.pop(alt.char_id)
if data:
continue
data = out
char_name = self.character_service.resolve_char_to_name(char_id)
time_string = self.util.time_to_readable(int(time.time()) - data.time)
channel_reply(f"<highlight>{char_name}</highlight> is back after {time_string}.")
+17 -12
View File
@@ -1,3 +1,4 @@
import time
from typing import List from typing import List
from core.chat_blob import ChatBlob from core.chat_blob import ChatBlob
@@ -8,10 +9,11 @@ from core.util import Util
class OnlineDisplay: class OnlineDisplay:
def __init__(self, text, util, db): def __init__(self, text, util, db, afk_list={}):
self.text: Text = text self.text: Text = text
self.util: Util = util self.util: Util = util
self.db: DB = db self.db: DB = db
self.afk_list = afk_list
def get_online_players(self, order, group="", params=None): def get_online_players(self, order, group="", params=None):
return self.db.query(f"SELECT r.*, " return self.db.query(f"SELECT r.*, "
@@ -68,10 +70,11 @@ class OnlineDisplay:
blob += f"\n\n<tab><notice>.:: <header>{self.get_channel_name(channel_id)}</header> ::.</notice>" blob += f"\n\n<tab><notice>.:: <header>{self.get_channel_name(channel_id)}</header> ::.</notice>"
main_id = 0 main_id = 0
in_org_priv.append(player.char_id) in_org_priv.append(player.char_id)
afk = self.afk_list.get(player.char_id, None)
if main_id != player.main_id: if main_id != player.main_id:
main_id = player.main_id main_id = player.main_id
blob += f"\n<highlight>{player.main_name}</highlight>{rank}:\n" afk = "" if not afk else f" [<notice>{afk.message} - since {self.util.time_to_readable(int(time.time() - afk.time))}</notice>]"
blob += f"\n<highlight>{player.main_name}</highlight>{rank}:{afk}\n"
if channel_id == 1: if channel_id == 1:
org += 1 org += 1
elif channel_id == 2: elif channel_id == 2:
@@ -109,18 +112,20 @@ class OnlineDisplay:
blob += f"\n\n<tab><notice>.:: <header>{self.get_channel_name(channel_id)}</header> ::.</notice>" blob += f"\n\n<tab><notice>.:: <header>{self.get_channel_name(channel_id)}</header> ::.</notice>"
profession = 0 profession = 0
in_org_priv.append(player.char_id) in_org_priv.append(player.char_id)
afk = self.afk_list.get(player.char_id, None)
afk = "" if not afk else f" [<notice>{afk.message} - since {self.util.time_to_readable(int(time.time() - afk.time))}</notice>]"
if profession != player.profession: if profession != player.profession:
profession = player.profession profession = player.profession
blob += f"\n<highlight>{player.profession}</highlight>:\n" blob += f"\n<highlight>{player.profession}</highlight>:\n"
if channel_id == 1: if channel_id == 1:
blob += self.format_org(player, rank, main_order=True) blob += self.format_org(player, rank, afk, main_order=True)
org += 1 org += 1
elif channel_id == 2: elif channel_id == 2:
blob += self.format_priv(player, rank, main_order=True) blob += self.format_priv(player, rank, afk, main_order=True)
priv += 1 priv += 1
elif channel_id == 3: elif channel_id == 3:
blob += self.format_notify(player, rank, main_order=True) blob += self.format_notify(player, rank, afk, main_order=True)
notify += 1 notify += 1
return blob, org, priv, notify return blob, org, priv, notify
@@ -161,25 +166,25 @@ class OnlineDisplay:
elif c_id == 3: elif c_id == 3:
return "Buddylist" return "Buddylist"
def format_org(self, player, rank="", main_order=False): def format_org(self, player, rank="", afk="", main_order=False):
main = f"[{self.text.make_tellcmd(player.main_name, f'alts {player.main_name}')}]" if main_order else "" main = f"[{self.text.make_tellcmd(player.main_name, f'alts {player.main_name}')}]" if main_order else ""
return f" {self.util.get_prof_icon(player.profession)} {rank}" \ return f" {self.util.get_prof_icon(player.profession)} {rank}" \
f"{self.text.zfill(player.level, 220)}/<green>{self.text.zfill(player.ai_level, 30)}</green> " \ f"{self.text.zfill(player.level, 220)}/<green>{self.text.zfill(player.ai_level, 30)}</green> " \
f"<{player.faction.lower()}>{player.name}</{player.faction.lower()}> ({player.org_rank_name}) {main}\n" f"<{player.faction.lower()}>{player.name}</{player.faction.lower()}> ({player.org_rank_name}){afk} {main}\n"
def format_priv(self, player, rank="", main_order=False): def format_priv(self, player, rank="", afk="", main_order=False):
main = f"[{self.text.make_tellcmd(player.main_name, f'alts {player.main_name}')}]" if main_order else "" main = f"[{self.text.make_tellcmd(player.main_name, f'alts {player.main_name}')}]" if main_order else ""
return f" {self.util.get_prof_icon(player.profession)} {rank}" \ return f" {self.util.get_prof_icon(player.profession)} {rank}" \
f"{self.text.zfill(player.level, 220)}/<green>{self.text.zfill(player.ai_level, 30)}</green> " \ f"{self.text.zfill(player.level, 220)}/<green>{self.text.zfill(player.ai_level, 30)}</green> " \
f"<{player.faction.lower()}>{player.name}</{player.faction.lower()}> " \ f"<{player.faction.lower()}>{player.name}</{player.faction.lower()}> " \
f"({player.org_name}|{player.org_rank_name}) {main}\n" f"({player.org_name}|{player.org_rank_name}){afk} {main}\n"
def format_notify(self, player, rank="", main_order=False): def format_notify(self, player, rank="", afk="", main_order=False):
main = f"[{self.text.make_tellcmd(player.main_name, f'alts {player.main_name}')}]" if main_order else "" main = f"[{self.text.make_tellcmd(player.main_name, f'alts {player.main_name}')}]" if main_order else ""
return f" {self.util.get_prof_icon(player.profession)} {rank}" \ return f" {self.util.get_prof_icon(player.profession)} {rank}" \
f"{self.text.zfill(player.level, 220)}/<green>{self.text.zfill(player.ai_level, 30)}</green> " \ f"{self.text.zfill(player.level, 220)}/<green>{self.text.zfill(player.ai_level, 30)}</green> " \
f"<{player.faction.lower()}>{player.name}</{player.faction.lower()}> " \ f"<{player.faction.lower()}>{player.name}</{player.faction.lower()}> " \
f"({player.org_name}|{player.org_rank_name}) {main}\n" f"({player.org_name}|{player.org_rank_name}){afk} {main}\n"
def count_prof(self, query, params, filters): def count_prof(self, query, params, filters):
if filters: if filters:
+11 -4
View File
@@ -2,7 +2,8 @@ import time
from core.chat_blob import ChatBlob from core.chat_blob import ChatBlob
from core.command_param_types import Any, Const, Time, Options from core.command_param_types import Any, Const, Time, Options
from core.decorators import instance, command from core.decorators import instance, command, event
from core.igncore import IgnCore
from core.registry import Registry from core.registry import Registry
from modules.standard.news.worldboss_controller import WorldBossController from modules.standard.news.worldboss_controller import WorldBossController
@@ -35,7 +36,7 @@ class TimerController:
self.alerts = [60 * 60, 60 * 15, 60 * 1] self.alerts = [60 * 60, 60 * 15, 60 * 1]
def inject(self, registry): def inject(self, registry):
self.bot = registry.get_instance("bot") self.bot: IgnCore = registry.get_instance("bot")
self.db = registry.get_instance("db") self.db = registry.get_instance("db")
self.util = registry.get_instance("util") self.util = registry.get_instance("util")
self.job_scheduler = registry.get_instance("job_scheduler") self.job_scheduler = registry.get_instance("job_scheduler")
@@ -129,6 +130,12 @@ class TimerController:
else: else:
return f"Error! Insufficient access level to remove timer <highlight>{timer.name}</highlight>." return f"Error! Insufficient access level to remove timer <highlight>{timer.name}</highlight>."
@event("connect", description="reload timers on restart")
def reload_timers(self, _, _1):
timers = self.db.query("SELECT * from timer")
for timer in timers:
self.timer_alert(time.time(), timer.name)
@command(command="rtimer", @command(command="rtimer",
params=[Const("add", is_optional=True), params=[Const("add", is_optional=True),
TimerTime("start_time"), TimerTime("start_time"),
@@ -195,7 +202,6 @@ class TimerController:
if timer.finished_at > t: if timer.finished_at > t:
msg = f"Timer <highlight>{timer.name}</highlight> has " \ msg = f"Timer <highlight>{timer.name}</highlight> has " \
f"<highlight>{self.util.time_to_readable(timer.finished_at - t)}</highlight> left." f"<highlight>{self.util.time_to_readable(timer.finished_at - t)}</highlight> left."
alert_duration = self.get_next_alert(timer.finished_at - t) alert_duration = self.get_next_alert(timer.finished_at - t)
job_id = self.job_scheduler.scheduled_job(self.timer_alert, t + alert_duration, timer.name) job_id = self.job_scheduler.scheduled_job(self.timer_alert, t + alert_duration, timer.name)
@@ -213,7 +219,8 @@ class TimerController:
new_t += timer.repeating_every new_t += timer.repeating_every
self.add_timer(timer.name, timer.char_id, timer.channel, new_t, timer.repeating_every, self.add_timer(timer.name, timer.char_id, timer.channel, new_t, timer.repeating_every,
timer.repeating_every) timer.repeating_every)
if not self.bot.is_ready():
return
if timer.channel == "org": if timer.channel == "org":
self.bot.send_org_message(msg) self.bot.send_org_message(msg)
elif timer.channel == "priv": elif timer.channel == "priv":