2d7ecf4883
Timer messages ("Timer XX has yyy left") now get resumed after a bot restart
Alliance relay is discord compatible now. [Orgbot]
289 lines
13 KiB
Python
289 lines
13 KiB
Python
import time
|
|
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, 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.*, "
|
|
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)
|
|
afk = self.afk_list.get(player.char_id, None)
|
|
if main_id != player.main_id:
|
|
main_id = player.main_id
|
|
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:
|
|
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)
|
|
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, afk, main_order=True)
|
|
org += 1
|
|
elif channel_id == 2:
|
|
blob += self.format_priv(player, rank, afk, main_order=True)
|
|
priv += 1
|
|
elif channel_id == 3:
|
|
blob += self.format_notify(player, rank, afk, 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="", 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}){afk} {main}\n"
|
|
|
|
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}){afk} {main}\n"
|
|
|
|
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}){afk} {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)
|