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"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}{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 {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"\n\n" \
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 += "\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)