c04f76c0db
Fixed command & event threading Events are now threaded by event_type (i.e. all buddy_logon events get ran in the same one) Added default preferences Fixed recipe loading for multiple installs (i.e. on different machines)
284 lines
12 KiB
Python
284 lines
12 KiB
Python
from typing import List
|
|
|
|
from core.chat_blob import ChatBlob
|
|
from core.db import DB
|
|
from core.dict_object import DictObject
|
|
from core.text import Text
|
|
from core.util import Util
|
|
|
|
|
|
class OnlineDisplay:
|
|
def __init__(self, text, util, db):
|
|
self.text: Text = text
|
|
self.util: Util = util
|
|
self.db: DB = db
|
|
|
|
def get_online_players(self, order, group="", params=None):
|
|
return self.db.query(f"SELECT r.*, "
|
|
f"CASE WHEN r.rank = 'admin' then 1 "
|
|
f"WHEN r.rank = 'moderator' then 2 "
|
|
f"WHEN r.rank = 'council' then 3 "
|
|
f"WHEN r.rank = 'leader' then 4 "
|
|
f"else 5 END as r_id, "
|
|
f"CASE WHEN o.channel = 'org' then 1 "
|
|
f"WHEN o.channel = ? then 2 "
|
|
f"WHEN o.channel = 'notify' then 3 "
|
|
f"else 4 END as channel_id, o.channel, "
|
|
f"p.*, a.main as main_id, p2.name as main_name, o.bot from online o "
|
|
f"left join player p on o.char_id = p.char_id "
|
|
f"left join account a on o.char_id = a.char_id "
|
|
f"left join player p2 on a.main = p2.char_id "
|
|
f"left join ranks r on a.main = r.main "
|
|
f"{group} HAVING bot=? {order}", params)
|
|
|
|
def format_blob(self, online, title="Online Players"):
|
|
blob, org, priv, notify = online
|
|
postfix = []
|
|
if org > 0:
|
|
postfix.append(f"<notice>Org: {org}</notice>")
|
|
if priv > 0:
|
|
postfix.append(f"<highlight>Priv: {priv}</notice>")
|
|
if notify > 0:
|
|
postfix.append(f"<notice>Buddylist: {notify}</notice>")
|
|
blob = ChatBlob(title, blob, suffix=f" ({f', '.join(postfix)})")
|
|
return blob
|
|
|
|
def format_by_channel_main(self, query, params):
|
|
query += "order by channel_id, main_name, p.name=main_name, p.name, r_id"
|
|
players = self.get_online_players(query, params=params)
|
|
channel_id = 0
|
|
main_id = 0
|
|
blob = ""
|
|
in_org_priv = []
|
|
org, priv, notify = 0, 0, 0
|
|
previous = DictObject({'char_id': 0})
|
|
for player in players:
|
|
rank = ""
|
|
|
|
if 'rank' in player:
|
|
rank = f" [<red>{player.rank[:1].upper()}</red>]" if player.rank else ""
|
|
if previous.char_id == player.char_id:
|
|
continue
|
|
previous = player
|
|
|
|
if player.char_id in in_org_priv:
|
|
continue
|
|
if player.channel_id != channel_id:
|
|
channel_id = player.channel_id
|
|
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)
|
|
|
|
if main_id != player.main_id:
|
|
main_id = player.main_id
|
|
blob += f"\n<highlight>{player.main_name}</highlight>{rank}:\n"
|
|
if channel_id == 1:
|
|
org += 1
|
|
elif channel_id == 2:
|
|
priv += 1
|
|
elif channel_id == 3:
|
|
notify += 1
|
|
if channel_id == 1:
|
|
blob += self.format_org(player)
|
|
elif channel_id == 2:
|
|
blob += self.format_priv(player)
|
|
elif channel_id == 3:
|
|
blob += self.format_notify(player)
|
|
return blob, org, priv, notify
|
|
|
|
def format_by_channel_prof(self, query, params):
|
|
query += "order by channel_id, profession, level desc, r_id"
|
|
players = self.get_online_players(query, params=params)
|
|
channel_id = 0
|
|
profession = 0
|
|
blob = ""
|
|
in_org_priv = []
|
|
org, priv, notify = 0, 0, 0
|
|
previous = DictObject({'char_id': 0})
|
|
for player in players:
|
|
rank = ""
|
|
if player.char_id in in_org_priv:
|
|
continue
|
|
if 'rank' in player:
|
|
rank = f"[<red>{player.rank[:1].upper()}</red>] " if player.rank else ""
|
|
if previous.char_id == player.char_id:
|
|
continue
|
|
previous = player
|
|
if player.channel_id != channel_id:
|
|
channel_id = player.channel_id
|
|
blob += f"\n\n<tab><notice>.:: <header>{self.get_channel_name(channel_id)}</header> ::.</notice>"
|
|
profession = 0
|
|
in_org_priv.append(player.char_id)
|
|
|
|
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)
|
|
org += 1
|
|
elif channel_id == 2:
|
|
blob += self.format_priv(player, rank, main_order=True)
|
|
priv += 1
|
|
elif channel_id == 3:
|
|
blob += self.format_notify(player, rank, main_order=True)
|
|
notify += 1
|
|
return blob, org, priv, notify
|
|
|
|
def format_by_org(self, query, params):
|
|
blob = ""
|
|
query += " and org_id IN (SELECT org_id from orgs) and channel_id = 3 " \
|
|
"ORDER BY p.org_name, p.name, p.org_rank_id"
|
|
query = self.get_online_players(query, params=params)
|
|
org_id = 0
|
|
temp_blob = {
|
|
}
|
|
last = 0
|
|
for user in query:
|
|
if last == user.char_id:
|
|
continue
|
|
last = user.char_id
|
|
if user.org_name not in temp_blob:
|
|
temp_blob[user.org_name] = {"name": user.org_name, "id": user.org_id, "online": []}
|
|
temp_blob[user.org_name]["online"].extend([user])
|
|
|
|
for key in sorted(temp_blob):
|
|
if len(temp_blob[key]['online']) == 0:
|
|
continue
|
|
for user in temp_blob[key]['online']:
|
|
if org_id != temp_blob[key]["id"]:
|
|
org_id = temp_blob[key]["id"]
|
|
blob += f"\n<pagebreak><highlight>{temp_blob[key]['name']}</highlight>" \
|
|
f"<header> ({len(temp_blob[key]['online']): >3} " \
|
|
f"| {len(temp_blob[key]['online']) / len(query) * 100:.2f}%)</header>\n"
|
|
blob += self.format_org(user)
|
|
return blob, 0, 0, len(query)
|
|
|
|
def get_channel_name(self, c_id):
|
|
if c_id == 1:
|
|
return "Org Channel"
|
|
elif c_id == 2:
|
|
return "Private Channel"
|
|
elif c_id == 3:
|
|
return "Buddylist"
|
|
|
|
def format_org(self, player, rank="", 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"
|
|
|
|
def format_priv(self, player, rank="", 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"
|
|
|
|
def format_notify(self, player, rank="", 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"
|
|
|
|
def count_prof(self, query, params, filters):
|
|
if filters:
|
|
filters = self.util.get_profession(filters)
|
|
params.append(filters)
|
|
if not filters:
|
|
return "Unknown profession"
|
|
query += "and profession = ? ORDER BY p.profession "
|
|
previous = []
|
|
data = []
|
|
for x in self.get_online_players(query, params=params):
|
|
if x.char_id in previous:
|
|
continue
|
|
data.append(f"{x.name} [{x.level}/<green>{x.ai_level}</green>]")
|
|
previous.append(x.char_id)
|
|
return f"""<highlight>{filters}'s</highlight>: {", ".join(data)}"""
|
|
else:
|
|
query += "ORDER BY p.profession "
|
|
data = self.get_online_players(query, params=params)
|
|
profs = {}
|
|
previous = []
|
|
for user in data:
|
|
if user.char_id in previous:
|
|
continue
|
|
previous.append(user.char_id)
|
|
if user.profession not in profs:
|
|
profs[user.profession] = 0
|
|
profs[user.profession] += 1
|
|
blob = []
|
|
for key, value in profs.items():
|
|
blob.append(f"[<highlight>{self.util.get_profession(key, long=False)}</highlight>: {value}]")
|
|
return ", ".join(blob)
|
|
|
|
def count_org(self, query, params, search):
|
|
if search:
|
|
filters = self.db.query_single("SELECT * from all_orgs where org_id = ? OR org_name = ?",
|
|
[search, search])
|
|
if not filters:
|
|
return f"Could not find org {search}"
|
|
params.append(filters.org_id)
|
|
query += "and p.org_id=? ORDER BY p.profession, p.name, p.level "
|
|
previous = []
|
|
data = []
|
|
for x in self.get_online_players(query, params=params):
|
|
if x.char_id in previous:
|
|
continue
|
|
data.append(self.format_org(x))
|
|
previous.append(x.char_id)
|
|
return ChatBlob(f"Online Players ({filters.org_name} - {len(data)})", "".join(data))
|
|
else:
|
|
query += "ORDER BY p.org_name "
|
|
data = self.get_online_players(query, params=params)
|
|
orgs = {}
|
|
count = 0
|
|
previous = []
|
|
for user in data:
|
|
if user.char_id in previous:
|
|
continue
|
|
previous.append(user.char_id)
|
|
if user.org_name not in orgs:
|
|
orgs[user.org_name] = 0
|
|
orgs[user.org_name] += 1
|
|
count += 1
|
|
blob = []
|
|
for key, value in orgs.items():
|
|
blob.append(
|
|
f"[<highlight>{key}</highlight>: {value} - {value / count * 100:.2f}%] "
|
|
f"[{self.text.make_tellcmd('Show', f'count org {key}')}]")
|
|
return ChatBlob(f"Online Organisations ({len(blob)})", "\n ".join(blob))
|
|
|
|
def count_tl(self, query, params: List, search):
|
|
if search:
|
|
min_level, max_level = self.util.get_level_range_tl(search)
|
|
if min_level == 0 and max_level == 0:
|
|
return f" Title level out of range: {search}"
|
|
params.extend([min_level, max_level])
|
|
query += "and p.level > ? and p.level < ? ORDER BY p.level desc "
|
|
previous = []
|
|
data = []
|
|
for x in self.get_online_players(query, params=params):
|
|
if x.char_id in previous:
|
|
continue
|
|
data.append(self.format_priv(x))
|
|
previous.append(x.char_id)
|
|
return ChatBlob(f"Online Players TL{search} ({len(data)})", "".join(data))
|
|
else:
|
|
query += "ORDER BY p.level "
|
|
tls = {}
|
|
previous = []
|
|
for user in self.get_online_players(query, params=params):
|
|
if user.char_id in previous:
|
|
continue
|
|
tl = self.util.get_title_level(user.level)
|
|
if tl not in tls:
|
|
tls[tl] = 0
|
|
tls[tl] += 1
|
|
previous.append(user.char_id)
|
|
blob = []
|
|
for key, value in tls.items():
|
|
blob.append(f"[<highlight>TL{key}</highlight>: {value}]")
|
|
return ", ".join(blob)
|