Files
igncore/modules/core/accounting/account_controller.py
T
Minidodo 810c2c8c4d Fix for mrelay - some bots are sending malformed messages, caused by wrong usage of their modules.
Accessing an external service through the bot for gathering tower data is nolonger supported; and should be done via external scripts.
Fix for callers, and missing alias'es for loot tables.
!accounts will only show mains now.
the character order of all alt lists has been reversed: [main] high => low instead of [main] low => high
!account add <name> also marks accounts as type 0, if an account gets re-enabled. might cause strange behaviour with member-logs, if used in onlinebots.
Member type is being displayed in !account now. [Member (X)]
2021-09-19 14:09:44 +02:00

272 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):
out = self.show_account(request.sender.char_id)
self.bot.send_mass_message(request.sender.char_id, out)
@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)
self.buddy_service.add_buddy(user.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"
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"
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)