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}: " \ f"[{self.text.make_tellcmd('D', f'account {entry.name}')}]" main_name = entry.name # n = f"N" if entry.last_seen == 0 else "" # out += f" {self.util.get_prof_icon(entry.profession)}" \ # f" {self.text.zfill(entry.level, 220)}/{self.text.zfill(entry.ai_level, 30)} " \ # f"<{entry.faction.lower()}>{entry.name} {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 {alts.points} 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 {user.name} 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 {user.name} 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 {user.name}.", request.sender.char_id) self.account_service.add_log(user.char_id, "system", f"Account has been reopened by {request.sender.name}.", request.sender.char_id) return f"There's already an account for character {user.name}; 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 {user.name}.", request.sender.char_id) self.account_service.add_log(user.char_id, "system", f"Account has been created by {request.sender.name}.", request.sender.char_id) self.bot.send_mass_message(user.char_id, f"Your Account has been opened by " f"{request.sender.name}.") return f"Character {user.name}'s Account has been created!" else: return f"There's already an account for character {user.name}." @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 {user.name} not found." if not self.access_service.has_sufficient_access_level(request.sender.char_id, user.char_id): return f"The user {user.name} 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 {user.name}.", request.sender.char_id) self.account_service.add_log(user.char_id, "system", f"Account disabled by {request.sender.name}.", request.sender.char_id) return f"Character {user.name}'s Account has been disabled!" else: return f"There's no active account for character {user.name}." @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 {user.name} not found." if not self.access_service.has_sufficient_access_level(request.sender.char_id, user.char_id): return f"The user {user.name} 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"Purged the account of {user.name}.", request.sender.char_id) return f"Character {user.name}'s Account has been purged!" else: return f"There's no active account for character {user.name}." @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 {user.name} not found." user = self.account_service.get_main(user.char_id) if not user: return f"No account for {user.name} 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"{user.name} already has the rank " \ f"{rank.capitalize()}." else: self.account_service.add_rank(user.char_id, "admin") return f"{user.name} got promoted to the rank " \ f"{rank.capitalize()}." # 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"{user.name} already has the rank " \ f"{rank.capitalize()}." else: self.account_service.add_rank(user.char_id, rank.lower()) return f"{user.name} got promoted to the rank " \ f"{rank.capitalize()}." 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 {user.name} 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"{user.name} is not in the " \ f"{rank.capitalize()} group." else: self.account_service.del_rank(user.char_id, "admin") return f"{user.name} is nolonger in the " \ f"{rank.capitalize()} 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"{user.name} is not in the " \ f"{rank.capitalize()} group." else: self.account_service.del_rank(user.char_id, rank.lower()) return f"{user.name} is nolonger in the " \ f"{rank.capitalize()} 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"" \ f" Owner: {alts[0].name} ({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: {alts[0].points}\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: {'Open' if alts[0].disabled == 0 else 'Closed'}\n" response += f" Created at: {self.util.format_datetime(alts[0].created)}\n" if last_seen: response += f" Last seen on {last_seen.name} {self.util.time_to_readable(time.time() - last_seen.last_seen)} ago\n" response += f" Permissions: {', '.join(perms)}\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: {alts[0].discord_handle}{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 += "
Last 20 Logs
\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 ChatBlob(f"{alts[0].name}'s Account", response)