d0c8c1744c
Added default alias !list for !loot (bebot like) Changed the layout of !notes, its more compact now. fixed !count in the rare case of an empty private channel
137 lines
6.1 KiB
Python
137 lines
6.1 KiB
Python
import time
|
|
from threading import Thread
|
|
|
|
from core.bot_status import BotStatus
|
|
from core.buddy_service import BuddyService
|
|
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.fifo_queue import FifoQueue
|
|
from core.logger import Logger
|
|
from core.private_channel_service import PrivateChannelService
|
|
from core.setting_service import SettingService
|
|
from core.text import Text
|
|
from core.tyrbot import Tyrbot
|
|
from core.util import Util
|
|
from modules.standard.online.online_display import OnlineDisplay
|
|
|
|
|
|
class User:
|
|
def __init__(self, char_id, loggedin=True):
|
|
self.char_id = char_id
|
|
self.logged = loggedin
|
|
|
|
|
|
@instance()
|
|
class OnlineController:
|
|
def __init__(self):
|
|
self.assist = []
|
|
self.awaiting_data = FifoQueue()
|
|
|
|
def inject(self, registry):
|
|
self.logger = Logger(__name__)
|
|
self.bot: Tyrbot = registry.get_instance("bot")
|
|
self.db: DB = registry.get_instance("db")
|
|
self.text: Text = registry.get_instance("text")
|
|
self.util: Util = registry.get_instance("util")
|
|
self.command_alias_service: CommandAliasService = registry.get_instance("command_alias_service")
|
|
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)
|
|
|
|
def pre_start(self):
|
|
self.db.exec("DROP TABLE IF EXISTS online")
|
|
self.db.shared.exec(
|
|
"CREATE TABLE IF NOT EXISTS online (char_id BIGINT NOT NULL primary key, "
|
|
"channel varchar(32) not null default 'notify', "
|
|
"bot BIGINT not null, "
|
|
"index bot(bot)) ENGINE MEMORY")
|
|
self.db.create_view("online")
|
|
self.command_alias_service.add_alias("o", "online")
|
|
|
|
@event(event_type="connect", description="Start online watcher")
|
|
def startup(self, _, _1):
|
|
self.db.exec("DELETE from online where bot=?", [self.bot.get_char_id()])
|
|
|
|
self.watchdog = Thread(name="watchdog", target=self.buddy_handler, daemon=True)
|
|
self.watchdog.start()
|
|
|
|
@event(event_type="private_channel_joined", description="Change online channel", is_hidden=True)
|
|
def priv_join(self, _, event_data):
|
|
self.db.exec("insert ignore into online(channel, char_id, bot) VALUES (?, ?, ?)",
|
|
[self.bot.name, event_data.char_id, self.bot.get_char_id()])
|
|
|
|
@event(event_type="private_channel_left", description="Change online channel", is_hidden=True)
|
|
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])
|
|
|
|
@event(event_type="member_logon", description="declare players as online")
|
|
def logon(self, _, event_data):
|
|
self.awaiting_data.put([event_data, 'notify', True])
|
|
|
|
@event(event_type="member_logoff", description="declare players as offline")
|
|
def logoff(self, _, event_data):
|
|
if self.bot.is_ready():
|
|
self.awaiting_data.put([event_data, 'notify', False])
|
|
|
|
def buddy_handler(self):
|
|
while self.bot.status != BotStatus.SHUTDOWN:
|
|
data, channel, logged = self.awaiting_data.get()
|
|
buddy = (self.buddy_service.get_buddy(data.packet.char_id) or {}).get("types", [])
|
|
if ("org_member" in buddy) or ("member" in buddy):
|
|
if logged:
|
|
self.db.exec("INSERT IGNORE INTO online VALUES(?, ?, ?)",
|
|
[data.packet.char_id, channel, self.bot.get_char_id()])
|
|
self.db.exec("UPDATE account set last_seen=? where char_id=?", [time.time(), data.packet.char_id])
|
|
else:
|
|
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])
|
|
|
|
@command(command="online", params=[Const('all', is_optional=True),
|
|
Int("min_level", is_optional=True),
|
|
Any("profession", is_optional=True)],
|
|
description="shows online players",
|
|
access_level="member")
|
|
def online_all_cmd(self, _, const_all, min_level, profession):
|
|
query = ""
|
|
params = [self.bot.name, self.bot.get_char_id()]
|
|
if const_all:
|
|
query += "and channel_id IN (1, 2, 3) "
|
|
else:
|
|
query += "and channel_id IN (1, 2) "
|
|
if min_level:
|
|
query += "and p.level >= ? "
|
|
params.append(min_level)
|
|
if profession:
|
|
query += "and p.profession = ? "
|
|
params.append(self.util.get_profession(profession))
|
|
blob = self.online_display.format_by_channel_main(query, params)
|
|
_.reply(self.online_display.format_blob(blob))
|
|
|
|
@command(command="count",
|
|
params=[Options(["org", "prof", "tl"], is_optional=True), Any("filter", is_optional=True)],
|
|
description="Counts online players",
|
|
access_level="member")
|
|
def count(self, _, option, filters):
|
|
query = "and channel_id IN (1, 2) "
|
|
params = [self.bot.name, self.bot.get_char_id()]
|
|
if not option:
|
|
option = "prof"
|
|
output = ""
|
|
if option == "prof":
|
|
output = self.online_display.count_prof(query, params, filters)
|
|
elif option == "org":
|
|
output = self.online_display.count_org(query, params, filters)
|
|
elif option == "tl":
|
|
if filters:
|
|
try:
|
|
filters = int(filters)
|
|
except ValueError:
|
|
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..."
|