Files
igncore/modules/standard/online/online_display.py
T

285 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"Org: {org}")
if priv > 0:
postfix.append(f"Priv: {priv}")
if notify > 0:
postfix.append(f"Buddylist: {notify}")
blob = ChatBlob(title, blob)
blob.page_postfix = 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)