Files
igncore/modules/core/accounting/account_controller.py
T
Minidodo 17c776faec Fixed:
-> !wants
-> !orgs info
-> special cmd's
-> !assist
-> "afk" for players without active account
-> !loot add <item_ref> <count> => nolonger breaks !account
Changes:
-> grouped !tara, !gaunt, .. into !wb
-> Display the most recent news entry on logon (default: enabled)
-> improved grouping of !items
-> Added the option to authentificate WS connections (Datanet module). This is used in special cases, where the Websocket Server requires the clien tto authentificate itself. (Server sends "#auth", client responds with the auth string)
-> Add main name to relaying (priv <-> org) [default: disabled]
-> Added logon/logoff messages back
-> restricted default access to "dangerous" commands to moderator
-> Added optional logging (Private Channel, Org Channel, Tells, ... disabled by default)

Rewrite of the Tower Module.
-> More verbosity, if enabled in config. by default, GAS and Hot timer only.
-> !hot displays currently hot (and in penalty) sites, and these which go hot in < 60 minutes
-> !attacks filterable by PF and Site
-> display current contract QL's grouped by org: !contracts (requires managed cache)
2021-11-25 14:09:43 +01:00

278 lines
16 KiB
Python

import time
from core import command_request
from core.chat_blob import ChatBlob
from core.command_param_types import Const, Character, Options
from core.db import DB
from core.decorators import instance, command
from core.event_service import EventService
from core.lookup.character_service import CharacterService
from core.lookup.pork_service import PorkService
from core.text import Text
from core.translation_service import TranslationService
from core.util import Util
from modules.core.accounting.preference_controller import PreferenceController
from modules.core.accounting.services.access_service import AccessService
from modules.core.accounting.services.account_service import AccountService
@instance()
class AccountController:
def inject(self, registry):
self.bot = registry.get_instance("bot")
self.buddy_service = registry.get_instance("buddy_service")
self.util: Util = registry.get_instance("util")
self.ts: TranslationService = registry.get_instance("translation_service")
self.db: DB = registry.get_instance("db")
self.character_service: CharacterService = registry.get_instance("character_service")
self.account_service: AccountService = registry.get_instance("account_service")
self.event_service: EventService = registry.get_instance("event_service")
self.getresp = self.ts.get_response
self.pork_service: PorkService = registry.get_instance("pork_service")
self.text: Text = registry.get_instance("text")
self.preferences: PreferenceController = registry.get_instance("preference_controller")
self.access_service: AccessService = registry.get_instance("access_service")
@command(command="account", params=[], access_level="member",
description="View your account")
def account(self, request: command_request):
return self.show_account(request.sender.char_id)
@command(command="accounts", params=[Const('online', is_optional=True)], access_level="moderator",
description="View all accounts")
def accounts(self, request: command_request, online):
accs = self.account_service.get_all_members(True if online else False)
main = 0
main_name = ""
entries = []
for entry in accs:
out = ""
if main != entry.main:
main = entry.main
out += f"\n<{entry.faction.lower()}>{entry.name}</{entry.faction.lower()}>: " \
f"[{self.text.make_tellcmd('D', f'account {entry.name}')}]"
main_name = entry.name
# n = f"<red>N</red>" if entry.last_seen == 0 else ""
# out += f"<tab> {self.util.get_prof_icon(entry.profession)}" \
# f" {self.text.zfill(entry.level, 220)}/<green>{self.text.zfill(entry.ai_level, 30)}</green> " \
# f"<{entry.faction.lower()}>{entry.name}</{entry.faction.lower()}> {n}\n"
entries.append([main_name, out])
out = ""
msg = sorted(entries, key=lambda k: k[0])
for _, mess in msg:
out += mess
self.bot.send_mass_message(request.sender.char_id, ChatBlob(f"All accounts ({len(entries)})", out))
@command(command="points", params=[], access_level="member",
description="View your points")
def points(self, request: command_request):
alts = self.account_service.get_account(request.sender.char_id)
self.bot.send_mass_message(request.sender.char_id,
f"So far, you've piled <notice>{alts.points}</notice> points up.")
@command(command="account", params=[Character("user")],
access_level="moderator",
sub_command="moderate", description="Lookup account of another char")
def display_account(self, _, user):
if not user.char_id:
return f"Character <highlight>{user.name}</highlight> not found."
return self.show_account(user.char_id, True)
@command(command="account", params=[Const("add"), Character("char")],
access_level="moderator",
sub_command="moderate", description="Create a new account for given character",
extended_description="Potentially breaks in bots using a database generated by an onlinebot. "
"Use with extreme caution.")
def add_account(self, request: command_request, _, user):
if not user.char_id:
return f"Character <highlight>{user.name}</highlight> not found."
if self.account_service.get_account(user.char_id):
# Unban the account, if banned
self.account_service.account_enable(user.char_id)
# set the memberstatus to 0
# (-1 is no member,
# 0 is member,
# any number above 0 indicates that its an org_member of the same ID)
self.account_service.account_add_member(user.char_id)
for char in self.account_service.get_alts(user.char_id):
self.buddy_service.add_buddy(char.char_id, "member")
self.account_service.add_log(request.sender.char_id, "system",
f"Opened Account for <highlight>{user.name}</highlight>.",
request.sender.char_id)
self.account_service.add_log(user.char_id, "system",
f"Account has been reopened by <highlight>{request.sender.name}</highlight>.",
request.sender.char_id)
return f"There's already an account for character <highlight>{user.name}</highlight>; It has been enabled."
count = self.account_service.create_users([(user.char_id, user.char_id, 0, time.time(), time.time())])
if count > 0:
self.buddy_service.add_buddy(user.char_id, "member")
self.account_service.add_log(request.sender.char_id, "system",
f"Created Account for <highlight>{user.name}</highlight>.",
request.sender.char_id)
self.account_service.add_log(user.char_id, "system",
f"Account has been created by <highlight>{request.sender.name}</highlight>.",
request.sender.char_id)
self.bot.send_mass_message(user.char_id,
f"Your Account has been <green>opened</green> by "
f"<highlight>{request.sender.name}</highlight>.")
return f"Character <highlight>{user.name}'s</highlight> Account has been created!"
else:
return f"There's already an account for character <highlight>{user.name}</highlight>."
@command(command="account", params=[Const("rem"), Character("char")],
access_level="moderator",
sub_command="moderate", description="Disable a new account for given character")
def rem_account(self, request: command_request, _, user):
if not user.char_id:
return f"Character <highlight>{user.name}</highlight> not found."
if not self.access_service.has_sufficient_access_level(request.sender.char_id, user.char_id):
return f"The user <highlight>{user.name}</highlight> has a higher rank then you, you cant do that."
disabled = self.account_service.account_disable(user.char_id)
if disabled:
self.buddy_service.remove_buddy(user.char_id, "member")
self.account_service.add_log(request.sender.char_id, "system",
f"Disabled Account of <highlight>{user.name}</highlight>.",
request.sender.char_id)
self.account_service.add_log(user.char_id, "system",
f"Account disabled by <highlight>{request.sender.name}</highlight>.",
request.sender.char_id)
return f"Character <highlight>{user.name}'s</highlight> Account has been disabled!"
else:
return f"There's no active account for character <highlight>{user.name}</highlight>."
@command(command="account", params=[Const("purge"), Character("char")],
access_level="admin",
sub_command="modify", description="Purge a user from the database")
def purge_account(self, request: command_request, _, user):
if not user.char_id:
return f"Character <highlight>{user.name}</highlight> not found."
if not self.access_service.has_sufficient_access_level(request.sender.char_id, user.char_id):
return f"The user <highlight>{user.name}</highlight> has a higher rank then you, you cant do that."
account = self.account_service.get_alts(user.char_id)
if account:
for alt in account:
self.buddy_service.remove_buddy(alt.char_id, "member")
self.db.exec("DELETE FROM notes where char_id=?", [alt.char_id])
self.db.exec("DELETE FROM account where main=?", [account[0].main])
self.db.exec("DELETE FROM account_log where char_id=?", [account[0].main])
self.db.exec("DELETE FROM command_usage where char_id=?", [account[0].main])
self.db.exec("DELETE FROM pending_accounts where main=? or alt=?", [account[0].main, account[0].main])
self.db.exec("DELETE FROM mail where recipient=? or sender=?", [account[0].main, account[0].main])
self.account_service.add_log(request.sender.char_id, "system",
f"Disabled Account of <highlight>{user.name}</highlight>.",
request.sender.char_id)
return f"Character <highlight>{user.name}'s</highlight> Account has been purged!"
else:
return f"There's no active account for character <highlight>{user.name}</highlight>."
@command(command="account",
params=[Const("rank"), Options(["admin", "moderator", "council", "leader"]), Character("user")],
access_level="admin", sub_command="modify", description="Add a rank to an Account")
def set_rank(self, request: command_request, _, rank: str, user):
if not user.char_id:
return f"Character <highlight>{user.name}</highlight> not found."
user = self.account_service.get_main(user.char_id)
if not user:
return f"No account for <highlight>{user.name}</highlight> found."
# is Superadmin
if rank == "admin" and \
self.account_service.check_superadmin(self.account_service.get_main(request.sender.char_id).char_id):
if "admin" in self.account_service.get_ranks(user.char_id):
return f"<highlight>{user.name}</highlight> already has the rank " \
f"<highlight>{rank.capitalize()}</highlight>."
else:
self.account_service.add_rank(user.char_id, "admin")
return f"<highlight>{user.name}</highlight> got promoted to the rank " \
f"<highlight>{rank.capitalize()}</highlight>."
# is Admin
if self.account_service.check_admin(self.account_service.get_main(request.sender.char_id).char_id) \
or self.account_service.check_superadmin(self.account_service.get_main(request.sender.char_id).char_id):
if rank.lower() in self.account_service.get_ranks(user.char_id):
return f"<highlight>{user.name}</highlight> already has the rank " \
f"<highlight>{rank.capitalize()}</highlight>."
else:
self.account_service.add_rank(user.char_id, rank.lower())
return f"<highlight>{user.name}</highlight> got promoted to the rank " \
f"<highlight>{rank.capitalize()}</highlight>."
return "You can't do that."
@command(command="account",
params=[Options(["delrank", "remrank"]), Options(["admin", "moderator", "council", "leader"]),
Character("user")],
access_level="admin", sub_command="modify", description="Remove a rank from an Account")
def rem_rank(self, request: command_request, _, rank: str, user):
if not user.char_id:
return f"Character <highlight>{user.name}</highlight> not found."
user = self.account_service.get_main(user.char_id)
# is Superadmin
if rank == "admin" and self.account_service.check_superadmin(
self.account_service.get_main(request.sender.char_id).char_id):
if "admin" not in self.account_service.get_ranks(user.char_id):
return f"<highlight>{user.name}</highlight> is not in the " \
f"<highlight>{rank.capitalize()}</highlight> group."
else:
self.account_service.del_rank(user.char_id, "admin")
return f"<highlight>{user.name}</highlight> is nolonger in the " \
f"<highlight>{rank.capitalize()}</highlight> group."
# is Admin
elif self.account_service.check_admin(self.account_service.get_main(request.sender.char_id).char_id):
if rank.lower() not in self.account_service.get_ranks(user.char_id):
return f"<highlight>{user.name}</highlight> is not in the " \
f"<highlight>{rank.capitalize()}</highlight> group."
else:
self.account_service.del_rank(user.char_id, rank.lower())
return f"<highlight>{user.name}</highlight> is nolonger in the " \
f"<highlight>{rank.capitalize()}</highlight> group."
def show_account(self, char_id, mod=False) -> str:
alts = self.account_service.get_alts(char_id)
if len(alts) < 1:
return "No Account registered for this user."
prefs = self.preferences.get_pref_view_small(alts[0])
response = f"<header>{alts[0].name}'s Account</header>\n\n" \
f" Owner: <notice>{alts[0].name}</notice> ({alts[0].char_id}) " \
f"[{self.text.make_tellcmd('W', f'whois {alts[0].name}')}] " \
f"[{self.text.make_tellcmd('Alts', f'alts {alts[0].name}')}] " \
f"({len(alts)})\n"
if not mod:
response += f" Options: {prefs}\n"
response += f" Points: <notice>{alts[0].points}</notice>\n"
last_seen = {}
for x in alts:
if x.last_seen > last_seen.get("last_seen", 0):
last_seen = x
access_levels = {f"Member ({alts[0].member})": self.account_service.check_member(alts[0].char_id),
"Officer": self.account_service.check_officer(alts[0].char_id),
"General": self.account_service.check_general(alts[0].char_id),
"President": self.account_service.check_president(alts[0].char_id),
"Leader": self.account_service.check_leader(alts[0].char_id),
"Council": self.account_service.check_council(alts[0].char_id),
"Moderator": self.account_service.check_moderator(alts[0].char_id),
"Admin": self.account_service.check_admin(alts[0].char_id)}
perms = []
for key, value in access_levels.items():
if value:
perms.append(key)
response += f" Status: {'<green>Open</green>' if alts[0].disabled == 0 else '<red>Closed</red>'}\n"
response += f" Created at: <notice>{self.util.format_datetime(alts[0].created)}</notice>\n"
if last_seen:
response += f" Last seen on <notice>{last_seen.name}</notice> <highlight>{self.util.time_to_readable(time.time() - last_seen.last_seen)}</highlight> ago\n"
response += f" Permissions: <notice>{', '.join(perms)}</notice>\n"
if alts[0].discord_joined == 1:
joined = ' (Joined server)'
else:
joined = ' (Left server)' if alts[0].discord_invite != '' else 'Never joined'
response += f" Discord: <notice>{alts[0].discord_handle}</notice>{joined}\n\n"
log_types = ['Points', 'Loot', 'Raid', 'Public', 'Admin', 'System']
response += " Logs: ["
for i in log_types:
response += f" {self.text.make_tellcmd(i, f'account log {i.lower()} {alts[0].name} 100')}"
response += " ]\n\n"
response += "<header>Last 20 Logs</header>\n"
rows = self.account_service.get_logs(alts[0].char_id, limit=20)
for i in rows:
response += self.account_service.format_entry(i)
return self.text.format_page(f"{alts[0].name}'s Account", response)