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:
@@ -1,3 +1,4 @@
|
||||
import re
|
||||
import time
|
||||
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.db import DB
|
||||
from core.decorators import instance, event, command
|
||||
from core.dict_object import DictObject
|
||||
from core.fifo_queue import FifoQueue
|
||||
from core.logger import Logger
|
||||
from core.lookup.character_service import CharacterService
|
||||
from core.private_channel_service import PrivateChannelService
|
||||
from core.public_channel_service import PublicChannelService
|
||||
from core.setting_service import SettingService
|
||||
from core.text import Text
|
||||
from core.igncore import IgnCore
|
||||
from core.util import Util
|
||||
from modules.core.accounting.services.account_service import AccountService
|
||||
from modules.standard.online.online_display import OnlineDisplay
|
||||
|
||||
|
||||
@@ -26,7 +31,8 @@ class User:
|
||||
@instance()
|
||||
class OnlineController:
|
||||
def __init__(self):
|
||||
self.assist = []
|
||||
self.afk_list = {}
|
||||
self.afk_regex = re.compile("^(afk|brb) ?(.*)$", re.IGNORECASE)
|
||||
self.awaiting_data = FifoQueue()
|
||||
|
||||
def inject(self, registry):
|
||||
@@ -39,7 +45,9 @@ class OnlineController:
|
||||
self.buddy_service: BuddyService = registry.get_instance("buddy_service")
|
||||
self.setting_service: SettingService = registry.get_instance("setting_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):
|
||||
self.db.exec("DROP TABLE IF EXISTS online")
|
||||
@@ -67,6 +75,8 @@ class OnlineController:
|
||||
def priv_leave(self, _, event_data):
|
||||
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])
|
||||
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")
|
||||
def logon(self, _, event_data):
|
||||
@@ -90,6 +100,8 @@ class OnlineController:
|
||||
self.db.exec("DELETE FROM online where char_id=? and bot=?",
|
||||
[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])
|
||||
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),
|
||||
Int("min_level", is_optional=True),
|
||||
@@ -134,3 +146,34 @@ class OnlineController:
|
||||
return f"Invalid Title level: {filters}"
|
||||
output = self.online_display.count_tl(query, params, filters)
|
||||
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}.")
|
||||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import time
|
||||
from typing import List
|
||||
|
||||
from core.chat_blob import ChatBlob
|
||||
@@ -8,10 +9,11 @@ from core.util import Util
|
||||
|
||||
|
||||
class OnlineDisplay:
|
||||
def __init__(self, text, util, db):
|
||||
def __init__(self, text, util, db, afk_list={}):
|
||||
self.text: Text = text
|
||||
self.util: Util = util
|
||||
self.db: DB = db
|
||||
self.afk_list = afk_list
|
||||
|
||||
def get_online_players(self, order, group="", params=None):
|
||||
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>"
|
||||
main_id = 0
|
||||
in_org_priv.append(player.char_id)
|
||||
|
||||
afk = self.afk_list.get(player.char_id, None)
|
||||
if 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:
|
||||
org += 1
|
||||
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>"
|
||||
profession = 0
|
||||
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:
|
||||
profession = player.profession
|
||||
blob += f"\n<highlight>{player.profession}</highlight>:\n"
|
||||
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
|
||||
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
|
||||
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
|
||||
return blob, org, priv, notify
|
||||
|
||||
@@ -161,25 +166,25 @@ class OnlineDisplay:
|
||||
elif c_id == 3:
|
||||
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 ""
|
||||
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"<{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 ""
|
||||
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"<{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 ""
|
||||
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"<{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):
|
||||
if filters:
|
||||
|
||||
@@ -2,7 +2,8 @@ import time
|
||||
|
||||
from core.chat_blob import ChatBlob
|
||||
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 modules.standard.news.worldboss_controller import WorldBossController
|
||||
|
||||
@@ -35,7 +36,7 @@ class TimerController:
|
||||
self.alerts = [60 * 60, 60 * 15, 60 * 1]
|
||||
|
||||
def inject(self, registry):
|
||||
self.bot = registry.get_instance("bot")
|
||||
self.bot: IgnCore = registry.get_instance("bot")
|
||||
self.db = registry.get_instance("db")
|
||||
self.util = registry.get_instance("util")
|
||||
self.job_scheduler = registry.get_instance("job_scheduler")
|
||||
@@ -129,6 +130,12 @@ class TimerController:
|
||||
else:
|
||||
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",
|
||||
params=[Const("add", is_optional=True),
|
||||
TimerTime("start_time"),
|
||||
@@ -195,7 +202,6 @@ class TimerController:
|
||||
if timer.finished_at > t:
|
||||
msg = f"Timer <highlight>{timer.name}</highlight> has " \
|
||||
f"<highlight>{self.util.time_to_readable(timer.finished_at - t)}</highlight> left."
|
||||
|
||||
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)
|
||||
|
||||
@@ -213,7 +219,8 @@ class TimerController:
|
||||
new_t += timer.repeating_every
|
||||
self.add_timer(timer.name, timer.char_id, timer.channel, new_t, timer.repeating_every,
|
||||
timer.repeating_every)
|
||||
|
||||
if not self.bot.is_ready():
|
||||
return
|
||||
if timer.channel == "org":
|
||||
self.bot.send_org_message(msg)
|
||||
elif timer.channel == "priv":
|
||||
|
||||
Reference in New Issue
Block a user