Initial Release of IGNCore version 2.5
This commit is contained in:
@@ -0,0 +1,263 @@
|
||||
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}')}]\n"
|
||||
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("All accounts", 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")
|
||||
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):
|
||||
self.account_service.account_enable(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 = {"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)
|
||||
@@ -0,0 +1,82 @@
|
||||
from core import command_request
|
||||
from core.aochat.BaseModule import BaseModule
|
||||
from core.chat_blob import ChatBlob
|
||||
from core.command_param_types import Const, Options, Int, Character, Any
|
||||
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.util import Util
|
||||
from modules.core.accounting.preference_controller import PreferenceController
|
||||
from modules.core.accounting.services.account_service import AccountService
|
||||
|
||||
|
||||
@instance()
|
||||
class AccountLogController(BaseModule):
|
||||
|
||||
# noinspection DuplicatedCode
|
||||
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.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.pork_service: PorkService = registry.get_instance("pork_service")
|
||||
self.text: Text = registry.get_instance("text")
|
||||
self.preferences: PreferenceController = registry.get_instance("preference_controller")
|
||||
|
||||
@command(command="account", params=[Const("log"), Options(["public", "raid", "loot"]),
|
||||
Character("char"), Int("count", is_optional=True)], access_level="member",
|
||||
description="Lookup logentries of a Account",
|
||||
sub_command="public")
|
||||
def account_log_1(self, _, _1, log_type, user, count):
|
||||
main = self.account_service.get_main(user.char_id).char_id
|
||||
entries = self.account_service.get_logs(main, log_type=log_type, limit=count or 25)
|
||||
return ChatBlob(f"Logentries for {user.name} in the category {log_type}", self.display_logs(entries))
|
||||
|
||||
@command(command="account",
|
||||
params=[Const("log"), Options(["admin", "system", "points"]),
|
||||
Character("char"), Int("count", is_optional=True)],
|
||||
access_level="moderator",
|
||||
description="Lookup logentries of a Account",
|
||||
sub_command="moderate")
|
||||
def account_log_2(self, _, _1, log_type, user, count):
|
||||
main = self.account_service.get_main(user.char_id).char_id
|
||||
entries = self.account_service.get_logs(main, log_type=log_type, limit=count or 25)
|
||||
return ChatBlob(f"Logentries for {user.name} in the category {log_type}", self.display_logs(entries))
|
||||
|
||||
@command(command="account", params=[Const("addlog"), Options(["admin", "public"]),
|
||||
Character("char"), Any("text")], access_level="moderator",
|
||||
description="Add a log entry to an Account",
|
||||
sub_command="moderate")
|
||||
def account_add_log(self, request: command_request, _, log_type, user, text):
|
||||
main = self.account_service.get_main(user.char_id).char_id
|
||||
self.account_service.add_log(main, log_type, text, request.sender.char_id)
|
||||
|
||||
# noinspection LongLine
|
||||
@command(command="account", params=[Const("log"), Const("id"), Int("id")], access_level="moderator",
|
||||
description="View a logentry of an user",
|
||||
sub_command="moderate")
|
||||
def account_view_log(self, _, _1, _2, log_id):
|
||||
entry = self.account_service.get_log_by_id(log_id)
|
||||
if entry:
|
||||
return ChatBlob(f"Information about Logentry {log_id}",
|
||||
f"ID: <highlight>{entry.log_id}</highlight>\n"
|
||||
f"Type: <highlight>{entry.type.capitalize()}</highlight>\n"
|
||||
f"Affected Main: <highlight>{self.character_service.resolve_char_to_name(entry.char_id)}</highlight>\n"
|
||||
f"Responsible Leader: <highlight>{self.character_service.resolve_char_to_name(entry.leader_id)}</highlight>\n"
|
||||
f"Points: <highlight>{f'<green>+{entry.delta}</green>' if entry.delta > 0 else f'<red>{entry.delta}</red>'}</highlight>\n"
|
||||
f"Message: <grey>{entry.reason}</grey>\n"
|
||||
f"Logging Time: <highlight>{self.util.format_datetime(entry.created_at)}</highlight>")
|
||||
else:
|
||||
return f"No Logentry with ID {id} found."
|
||||
|
||||
def display_logs(self, entries) -> str:
|
||||
blob = ""
|
||||
for entry in entries:
|
||||
blob += self.account_service.format_entry(entry)
|
||||
return blob
|
||||
@@ -0,0 +1,66 @@
|
||||
{
|
||||
"list": {
|
||||
"en_US": "Alts of {char} ({amount})",
|
||||
"de_DE": "Alts von {char} ({amount})"
|
||||
},
|
||||
"new_main": {
|
||||
"en_US": "<highlight>{char}</highlight> character has been set as your main. Your preferences have been reset.",
|
||||
"de_DE": "Dein neuer Main ist <highlight>{char}</highlight>."
|
||||
},
|
||||
"not_an_alt": {
|
||||
"en_US": "Error! This character cannot be set as your main since you do not have any alts",
|
||||
"de_DE": "Error! Da du keine Alts hast, kannst du auch keinen Main Charakter setzen."
|
||||
},
|
||||
"already_main": {
|
||||
"en_US": "Error! This character is already set as your main.",
|
||||
"de_DE": "Error! Dieser Charakter ist bereits dein Main."
|
||||
},
|
||||
"add_fail_self": {
|
||||
"en_US": "Error! You cannot register yourself as an alt.",
|
||||
"de_DE": "Error! Du kannst dich nicht als dein eigener Alt registrieren."
|
||||
},
|
||||
"add_success_target": {
|
||||
"en_US": "<highlight>{char}</highlight> has added you as an alt.",
|
||||
"de_DE": "<highlight>{char}</highlight> hat dich als seinen Alt hinzugefügt."
|
||||
},
|
||||
"add_success_self": {
|
||||
"en_US": "<highlight>{char}</highlight> has been added as your alt.",
|
||||
"de_DE": "<highlight>{char}</highlight> wurde zu deinen Alts hinzugefügt."
|
||||
},
|
||||
"add_fail_already": {
|
||||
"en_US": "Error! <highlight>{char}</highlight> already has alts.",
|
||||
"de_DE": "Error! <highlight>{char}</highlight> hat bereits alts."
|
||||
},
|
||||
"rem_success": {
|
||||
"en_US": "<highlight>{char}</highlight> has been removed as your alt.",
|
||||
"de_DE": "<highlight>{char}</highlight> wurde von deinen Alts entfernt."
|
||||
},
|
||||
"rem_fail_not": {
|
||||
"en_US": "Error! <highlight>{char}</highlight> is not your alt.",
|
||||
"de_DE": "Error! <highlight>{char}</highlight> ist kein Alt von dir."
|
||||
},
|
||||
"rem_fail_main": {
|
||||
"en_US": "Error! You cannot remove your main.",
|
||||
"de_DE": "Error! Du kannst deinen Main nicht entfernen."
|
||||
},
|
||||
"altadmin_add_same": {
|
||||
"en_US": "Error! alt and main are identical.",
|
||||
"de_DE": "Error! Der Alt und Main Charakter sind identisch."
|
||||
},
|
||||
"altadmin_add_success": {
|
||||
"en_US": "The Toon <highlight>{alt}</highlight> got added as an alt of <highlight>{main}</highlight> successfully.",
|
||||
"de_DE": "Der Charakter <highlight>{alt}</highlight> ist nun ein Alt von <highlight>{main}</highlight>."
|
||||
},
|
||||
"altadmin_rem_success": {
|
||||
"en_US": "<highlight>{alt}</highlight> is nolonger an alt of <highlight>{main}</highlight>.",
|
||||
"de_DE": "<highlight>{alt}</highlight> ist nun kein Alt von <highlight>{main}</highlight> mehr."
|
||||
},
|
||||
"altadmin_rem_fail_not": {
|
||||
"en_US": "Error! <highlight>{alt}</highlight> is not an alt of <highlight>{main}</highlight>.",
|
||||
"de_DE": "Error! <highlight>{alt}</highlight> ist kein Alt von <highlight>{main}</highlight>."
|
||||
},
|
||||
"altadmin_rem_fail_main": {
|
||||
"en_US": "Error! Main Characters may not get removed from their alt list.",
|
||||
"de_DE": "Error! Du kannst keinen Main von seiner Altliste entfernen."
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,188 @@
|
||||
import re
|
||||
|
||||
import hjson
|
||||
|
||||
from core.chat_blob import ChatBlob
|
||||
from core.command_param_types import Const, Options, Character, Multiple, Any
|
||||
from core.decorators import instance, command
|
||||
from core.dict_object import DictObject
|
||||
from core.setting_service import SettingService
|
||||
from core.text import Text
|
||||
from core.translation_service import TranslationService
|
||||
from core.tyrbot import Tyrbot
|
||||
from modules.core.accounting.register_controller import RegisterController
|
||||
from modules.core.accounting.services.account_service import AccountService
|
||||
|
||||
|
||||
@instance()
|
||||
class AltsController:
|
||||
def inject(self, registry):
|
||||
self.bot: Tyrbot = registry.get_instance("bot")
|
||||
self.account_service: AccountService = registry.get_instance("account_service")
|
||||
self.buddy_service = registry.get_instance("buddy_service")
|
||||
self.util = registry.get_instance("util")
|
||||
self.text: Text = registry.get_instance("text")
|
||||
self.ts: TranslationService = registry.get_instance("translation_service")
|
||||
self.character_service = registry.get_instance("character_service")
|
||||
self.getresp = self.ts.get_response
|
||||
self.setting_service: SettingService = registry.get_instance("setting_service")
|
||||
self.register_controller: RegisterController = registry.get_instance("register_controller")
|
||||
|
||||
def start(self):
|
||||
self.ts.register_translation("module/alts", self.load_alts_msg)
|
||||
|
||||
def load_alts_msg(self) -> dict:
|
||||
with open("modules/core/accounting/alts.msg", mode="r", encoding="UTF-8") as f:
|
||||
return hjson.load(f)
|
||||
|
||||
@command(command="alts", params=[], access_level="member",
|
||||
description="Show your alts")
|
||||
def alts_list_cmd(self, request):
|
||||
alts = self.account_service.get_alts(request.sender.char_id)
|
||||
blob = self.format_alt_list(alts)
|
||||
|
||||
return ChatBlob(self.getresp("module/alts", "list", {"char": alts[0].name, "amount": len(alts)}), blob)
|
||||
|
||||
@command(command="alts", params=[Const("setmain")], access_level="member", description="Set a new main",
|
||||
extended_description="You must run this from the character you want to be your new main")
|
||||
def alts_setmain_cmd(self, request, _):
|
||||
msg, result = self.account_service.set_as_main(request.sender.char_id)
|
||||
|
||||
if result:
|
||||
return self.getresp("module/alts", "new_main", {"char": request.sender.name})
|
||||
elif msg == "not_an_alt":
|
||||
return self.getresp("module/alts", "not_an_alt")
|
||||
elif msg == "already_main":
|
||||
return self.getresp("module/alts", "already_main")
|
||||
else:
|
||||
raise Exception("Unknown msg: " + msg)
|
||||
|
||||
@command(command="alts", params=[Const("add"), Multiple(Character("character"))], access_level="member",
|
||||
description="Add an alt")
|
||||
def alts_add_cmd(self, request, _, alt_chars):
|
||||
responses = []
|
||||
for alt_char in alt_chars:
|
||||
if not alt_char.char_id:
|
||||
responses.append(self.getresp("global", "char_not_found", {"char": alt_char.name}))
|
||||
continue
|
||||
elif alt_char.char_id == request.sender.char_id:
|
||||
responses.append(self.getresp("module/alts", "add_fail_self"))
|
||||
continue
|
||||
manual = self.setting_service.get_value("alt_verification") == "1"
|
||||
if manual:
|
||||
responses.append(self.register_controller.register_alt(request, _, alt_char))
|
||||
continue
|
||||
msg, result = self.account_service.add_alt(request.sender.char_id, alt_char.char_id)
|
||||
|
||||
if result:
|
||||
self.bot.send_mass_message(alt_char.char_id, self.getresp("module/alts", "add_success_target",
|
||||
{"char": request.sender.name}))
|
||||
responses.append(self.getresp("module/alts", "add_success_self", {"char": alt_char.name}))
|
||||
elif msg == "another_main":
|
||||
responses.append(self.getresp("module/alts", "add_fail_already", {"char": alt_char.name}))
|
||||
else:
|
||||
raise Exception("Unknown msg: " + msg)
|
||||
|
||||
return "\n".join(responses)
|
||||
|
||||
@command(command="alts", params=[Options(["rem", "remove"]), Character("character")], access_level="member",
|
||||
description="Remove an alt")
|
||||
def alts_remove_cmd(self, request, _, alt_char):
|
||||
manual = self.setting_service.get_value("alt_verification") == "1"
|
||||
if manual:
|
||||
return "This command is disabled, you cannot remove alts."
|
||||
|
||||
if not alt_char.char_id:
|
||||
return self.getresp("global", "char_not_found", {"char": alt_char.name})
|
||||
|
||||
msg, result = self.account_service.remove_alt(request.sender.char_id, alt_char.char_id)
|
||||
if result:
|
||||
return self.getresp("module/alts", "rem_success", {"char": alt_char.name})
|
||||
elif msg == "not_alt":
|
||||
return self.getresp("module/alts", "rem_fail_not", {"char": alt_char.name})
|
||||
elif msg == "remove_main":
|
||||
return self.getresp("module/alts", "rem_fail_main")
|
||||
else:
|
||||
raise Exception("Unknown msg: " + msg)
|
||||
|
||||
@command(command="alts", params=[Character("character")], access_level="member",
|
||||
description="Show alts of another character", sub_command="show")
|
||||
def alts_list_other_cmd(self, _, char):
|
||||
if not char.char_id:
|
||||
return self.getresp("global", "char_not_found", {"char": char.name})
|
||||
|
||||
alts = self.account_service.get_alts(char.char_id)
|
||||
blob = self.format_alt_list(alts)
|
||||
if len(alts) < 1:
|
||||
return "No alts found"
|
||||
return ChatBlob(self.getresp("module/alts", "list", {"char": alts[0].name, "amount": len(alts)}), blob)
|
||||
|
||||
@command(command="altadmin", params=[Const("add"), Character("main"), Any("alts")],
|
||||
access_level="admin", description="Add alts to Main")
|
||||
def altadmin_add_cmd(self, _, _1, main, altlist):
|
||||
alts = re.findall(r"([^ ]+)", altlist)
|
||||
notfound = []
|
||||
done = []
|
||||
failed = []
|
||||
gotalts = []
|
||||
if alts:
|
||||
for alt in alts:
|
||||
char_id = self.character_service.resolve_char_to_id(alt)
|
||||
if not char_id:
|
||||
notfound.append(alt)
|
||||
continue
|
||||
alt = DictObject({"char_id": char_id, "name": alt})
|
||||
if main.char_id == alt.char_id:
|
||||
failed.append(self.getresp("module/alts", "altadmin_add_same"))
|
||||
|
||||
msg, result = self.account_service.add_alt(main.char_id, alt.char_id)
|
||||
if result:
|
||||
done.append(alt.name)
|
||||
elif msg == "another_main":
|
||||
gotalts.append(alt.name)
|
||||
reply = ""
|
||||
if len(done) > 0:
|
||||
reply += self.getresp("module/alts", "altadmin_add_success",
|
||||
{"alt": ", ".join(done),
|
||||
"main": main.name})
|
||||
if len(notfound) > 0:
|
||||
reply += "\n" + self.getresp("global", "char_not_found", {"char": ", ".join(notfound)})
|
||||
if len(gotalts) > 0:
|
||||
reply += "\n" + self.getresp("module/alts", "add_fail_already", {"char": ", ".join(gotalts)})
|
||||
reply += "\n".join(failed)
|
||||
return reply
|
||||
|
||||
@command(command="altadmin", params=[Options(["rem", "remove"]), Character("main"), Character("alt")],
|
||||
access_level="admin",
|
||||
description="Remove alts of main")
|
||||
def altadmin_remove_cmd(self, _, _1, main, alt):
|
||||
if not main.char_id:
|
||||
return self.getresp("global", "char_not_found", {"char": main.name})
|
||||
if not alt.char_id:
|
||||
return self.getresp("global", "char_not_found", {"char": alt.name})
|
||||
|
||||
msg, result = self.account_service.remove_alt(main.char_id, alt.char_id)
|
||||
|
||||
if result:
|
||||
return self.getresp("module/alts", "altadmin_rem_success", {"alt": alt.name, "main": main.name})
|
||||
elif msg == "not_alt":
|
||||
return self.getresp("module/alts", "altadmin_rem_fail_not", {"alt": alt.name, "main": main.name})
|
||||
elif msg == "remove_main":
|
||||
return self.getresp("module/alts", "altadmin_rem_fail_main")
|
||||
else:
|
||||
raise Exception("Unknown msg: " + msg)
|
||||
|
||||
def format_alt_list(self, alts) -> str:
|
||||
blob = ""
|
||||
for alt in alts:
|
||||
name = f"{alt.name}"
|
||||
blob += f"{self.util.get_prof_icon(alt.profession)} " \
|
||||
f"<yellow>{self.text.zfill(alt.level, 220)}</yellow>:" \
|
||||
f"<green>{self.text.zfill(alt.ai_level, 30)}</green> " \
|
||||
f":: <{alt.faction.lower()}>{name}</{alt.faction.lower()}> " \
|
||||
f"[<{alt.faction.lower()}>{alt.org_name}</{alt.faction.lower()}> - " \
|
||||
f"<highlight>{alt.org_rank_id + 1}</highlight>]"
|
||||
if self.buddy_service.is_online(alt.char_id):
|
||||
blob += " [<green>Online</green>]"
|
||||
blob += "\n"
|
||||
return blob
|
||||
@@ -0,0 +1,41 @@
|
||||
from core import command_request
|
||||
from core.command_param_types import Options, Int, Character, Any
|
||||
from core.db import DB
|
||||
from core.decorators import instance, command
|
||||
from core.event_service import EventService
|
||||
from core.lookup.pork_service import PorkService
|
||||
from core.text import Text
|
||||
from core.util import Util
|
||||
from modules.core.accounting.preference_controller import PreferenceController
|
||||
from modules.core.accounting.services.account_service import AccountService
|
||||
|
||||
|
||||
@instance()
|
||||
class PointsController:
|
||||
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.db: DB = registry.get_instance("db")
|
||||
self.character_service = registry.get_instance("character_service")
|
||||
self.account_service: AccountService = registry.get_instance("account_service")
|
||||
self.event_service: EventService = registry.get_instance("event_service")
|
||||
self.pork_service: PorkService = registry.get_instance("pork_service")
|
||||
self.text: Text = registry.get_instance("text")
|
||||
self.preferences: PreferenceController = registry.get_instance("preference_controller")
|
||||
|
||||
@command(command="account",
|
||||
params=[Options(["give", "take"]), Int("points"), Character("char"), Any("reason")],
|
||||
access_level="admin",
|
||||
description="Give or take points from an Account",
|
||||
sub_command="modify")
|
||||
def account_add_mod_pts(self, request: command_request, option, amount, user, reason):
|
||||
if option == "take":
|
||||
amount = -amount
|
||||
self.account_service.add_pts(user.char_id, amount, reason, request.sender.char_id)
|
||||
|
||||
def display_logs(self, entries):
|
||||
blob = ""
|
||||
for entry in entries:
|
||||
blob += self.account_service.format_entry(entry)
|
||||
return blob
|
||||
@@ -0,0 +1,107 @@
|
||||
from core.buddy_service import BuddyService
|
||||
from core.chat_blob import ChatBlob
|
||||
from core.command_alias_service import CommandAliasService
|
||||
from core.command_param_types import Const, Options, Character
|
||||
from core.db import DB
|
||||
from core.decorators import instance, command
|
||||
from core.logger import Logger
|
||||
from core.lookup.pork_service import PorkService
|
||||
from core.setting_service import SettingService
|
||||
from core.text import Text
|
||||
from core.tyrbot import Tyrbot
|
||||
from core.util import Util
|
||||
from modules.core.accounting.services.account_service import AccountService
|
||||
from modules.core.discord.discord_controller import DiscordController
|
||||
|
||||
|
||||
@instance()
|
||||
class PreferenceController:
|
||||
|
||||
def inject(self, registry):
|
||||
self.logger = Logger(__name__)
|
||||
self.bot: Tyrbot = registry.get_instance("bot")
|
||||
self.db: DB = registry.get_instance("db")
|
||||
self.text: Text = registry.get_instance("text")
|
||||
self.util: Util = registry.get_instance("util")
|
||||
self.account_service: AccountService = registry.get_instance("account_service")
|
||||
self.pork: PorkService = registry.get_instance("pork_service")
|
||||
self.org_pork: PorkService = registry.get_instance("org_pork_service")
|
||||
self.command_alias_service: CommandAliasService = registry.get_instance("command_alias_service")
|
||||
self.buddy_service: BuddyService = registry.get_instance("buddy_service")
|
||||
self.setting_service: SettingService = registry.get_instance("setting_service")
|
||||
self.discord: DiscordController = registry.get_instance("discord_controller")
|
||||
self.job_scheduler = registry.get_instance("job_scheduler")
|
||||
|
||||
def start(self):
|
||||
self.command_alias_service.add_alias("prefs", "preferences")
|
||||
self.command_alias_service.add_alias("autoinvite", "preferences set autoinvite")
|
||||
|
||||
@command(command="preferences", params=[], description="View your Preferences", access_level="member")
|
||||
def show_prefs(self, request):
|
||||
account = self.account_service.get_account(request.sender.char_id)
|
||||
if not account:
|
||||
return "You dont have any preferences you could manage...."
|
||||
return ChatBlob("Your Preferences", self.get_pref_view_full(account))
|
||||
|
||||
@command(command="preferences",
|
||||
params=[Const("set"),
|
||||
Options(["news", "raidinvite", "subtilespam", "autoinvite", "raidspam"]),
|
||||
Options(["on", "off", "yes", "no"])],
|
||||
description="Change your Preferences", access_level="member")
|
||||
def set_prefs(self, request, _, pref: str, value):
|
||||
account = self.account_service.get_account(request.sender.char_id)
|
||||
if not account:
|
||||
return "You dont have any preferences you could manage...."
|
||||
self.set_pref(request.sender.char_id, pref, 0 if value in ["off", "no"] else 1)
|
||||
return f"Your <highlight>{pref.capitalize()}</highlight> preference has been set to {value}."
|
||||
|
||||
@command(command="prefadmin",
|
||||
params=[Const("set"),
|
||||
Character("main"),
|
||||
Options(["news", "raidinvite", "subtilespam", "autoinvite", "raidspam"]),
|
||||
Options(["on", "off", "yes", "no"])],
|
||||
description="Change your Preferences",
|
||||
sub_command='mdf',
|
||||
access_level="admin")
|
||||
def set_pref_admin(self, _, _1, main, pref: str, value):
|
||||
self.set_pref(main.char_id, pref, 0 if value in ["off", "no"] else 1)
|
||||
return f"<highlight>{main.name}</highlight>'s <highlight>{pref.capitalize()}</highlight> " \
|
||||
f"preference has been set to {value}."
|
||||
|
||||
def get_prefs(self, char_id):
|
||||
return self.account_service.get_account(char_id)
|
||||
|
||||
def set_pref(self, char_id, pref, value):
|
||||
pref = "subtile_spam" if pref == "subtilespam" \
|
||||
else "raid_invite" if pref == "raidinvite" \
|
||||
else "news_spam" if pref == "news" \
|
||||
else "auto_invite" if pref == "autoinvite" \
|
||||
else 'raid_spam' if pref == "raidspam" \
|
||||
else ""
|
||||
|
||||
self.db.exec(f"UPDATE account set {pref}={value} where char_id=(SELECT main from account where char_id=?)",
|
||||
[char_id])
|
||||
|
||||
def get_pref_view_small(self, prefs):
|
||||
return f"\n" \
|
||||
f" └ [{self._make_cmd('news', prefs.news_spam)}] News - " \
|
||||
f"Autoinvite [{self._make_cmd('autoinvite', prefs.auto_invite)}], \n" \
|
||||
f" └ [{self._make_cmd('raidinvite', prefs.raid_invite)}] Raidinvite - " \
|
||||
f"Massmessage [{self._make_cmd('raidspam', prefs.raid_invite)}], \n" \
|
||||
f" └ [{self._make_cmd('subtilespam', prefs.subtile_spam)}] Subtilespam"
|
||||
|
||||
def get_pref_view_full(self, prefs):
|
||||
return f"\n" \
|
||||
f"<tab>└ [ {self._make_cmd('news', prefs.news_spam)} ] Do you want your News on Logon? \n" \
|
||||
f"<tab>└ [ {self._make_cmd('autoinvite', prefs.auto_invite)} ] Do you want to receive autoinvites? \n" \
|
||||
f"<tab>└ [ {self._make_cmd('raidinvite', prefs.raid_invite)} ] Do you want to receive raidinvites? \n" \
|
||||
f"<tab>└ [ {self._make_cmd('raidspam', prefs.raid_invite)} ] Do you want to receive massmessages? \n" \
|
||||
f"<tab>└ [ {self._make_cmd('subtilespam', prefs.subtile_spam)} ] Do you want a subtile invite spam? \n"
|
||||
|
||||
def _make_cmd(self, pref, value):
|
||||
# ---
|
||||
# [ ON | OFF ]
|
||||
if value == 1:
|
||||
return f"<green>YES</green> | {self.text.make_chatcmd('NO', f'/tell <myname> preferences set {pref} off')}"
|
||||
else:
|
||||
return f"{self.text.make_chatcmd('YES', f'/tell <myname> preferences set {pref} on')} | <red>NO</red>"
|
||||
@@ -0,0 +1,254 @@
|
||||
import time
|
||||
|
||||
from core.chat_blob import ChatBlob
|
||||
from core.command_alias_service import CommandAliasService
|
||||
from core.command_param_types import Const, Character, Any, Int
|
||||
from core.db import DB
|
||||
from core.decorators import instance, command
|
||||
from core.event_service import EventService
|
||||
from core.lookup.character_history_service import CharacterHistoryService
|
||||
from core.lookup.character_service import CharacterService
|
||||
from core.lookup.pork_service import PorkService
|
||||
from core.message_hub_service import MessageHubService
|
||||
from core.setting_service import SettingService
|
||||
from core.text import Text
|
||||
from core.tyrbot import Tyrbot
|
||||
from core.util import Util
|
||||
from modules.core.accounting.services.account_service import AccountService
|
||||
|
||||
|
||||
@instance()
|
||||
class RegisterController:
|
||||
def inject(self, registry):
|
||||
self.bot: Tyrbot = registry.get_instance("bot")
|
||||
self.buddy_service = registry.get_instance("buddy_service")
|
||||
self.util: Util = registry.get_instance("util")
|
||||
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.pork_service: PorkService = registry.get_instance("pork_service")
|
||||
self.text: Text = registry.get_instance("text")
|
||||
self.setting_service: SettingService = registry.get_instance("setting_service")
|
||||
self.character_history_service: CharacterHistoryService = registry.get_instance("character_history_service")
|
||||
self.command_alias_service: CommandAliasService = registry.get_instance("command_alias_service")
|
||||
self.messagehub: MessageHubService = registry.get_instance("message_hub_service")
|
||||
|
||||
def start(self):
|
||||
self.command_alias_service.add_alias("pending", "register pending")
|
||||
self.command_alias_service.add_alias("recommend", "register recommend")
|
||||
self.messagehub.register_message_source("registration")
|
||||
|
||||
@command(command="register", params=[Const("pending"), Int('count', is_optional=True)],
|
||||
description="Show the latest Recommendations", sub_command="mng", access_level="admin")
|
||||
def register_pending(self, _, _1, limit):
|
||||
limit = limit or 25
|
||||
latest = self.db.query("SELECT "
|
||||
"main.char_id as main_id, "
|
||||
"alt.char_id as alt_id, "
|
||||
"recommender.char_id as recommender_id, "
|
||||
|
||||
"main.name as main_name, "
|
||||
"alt.name as alt_name, "
|
||||
"recommender.name as recommender_name, "
|
||||
|
||||
"main.faction as main_faction, "
|
||||
"alt.faction as alt_faction, "
|
||||
"recommender.faction as recommender_faction, "
|
||||
|
||||
"main.level as main_level, "
|
||||
"alt.level as alt_level, "
|
||||
"recommender.level as main_level, "
|
||||
|
||||
"alt.ai_level as alt_ai_level, "
|
||||
"main.ai_level as main_ai_level, "
|
||||
"recommender.ai_level as recommender_ai_level, "
|
||||
|
||||
"reason "
|
||||
"from pending_accounts p "
|
||||
"left join player alt on alt.char_id = p.alt "
|
||||
"left join player main on main.char_id = p.main "
|
||||
"left join player recommender on recommender.char_id = p.recommender where answered=0 "
|
||||
"order by time desc limit ?", [limit])
|
||||
blob = ""
|
||||
for entry in latest:
|
||||
blob += self.format_pending(entry, buttons=True)
|
||||
|
||||
return ChatBlob("Latest recommendations", blob)
|
||||
|
||||
@command(command="register", params=[Const("pending"), Const('latest'), Int('count', is_optional=True)],
|
||||
description="Show the latest Recommendations", sub_command="mng", access_level="admin")
|
||||
def register_pending_latest(self, _, _1, _2, limit):
|
||||
limit = limit or 25
|
||||
latest = self.db.query("SELECT "
|
||||
"main.char_id as main_id, "
|
||||
"alt.char_id as alt_id, "
|
||||
"recommender.char_id as recommender_id, "
|
||||
|
||||
"main.name as main_name, "
|
||||
"alt.name as alt_name, "
|
||||
"recommender.name as recommender_name, "
|
||||
|
||||
"main.faction as main_faction, "
|
||||
"alt.faction as alt_faction, "
|
||||
"recommender.faction as recommender_faction, "
|
||||
|
||||
"main.level as main_level, "
|
||||
"alt.level as alt_level, "
|
||||
"recommender.level as main_level, "
|
||||
|
||||
"alt.ai_level as alt_ai_level, "
|
||||
"main.ai_level as main_ai_level, "
|
||||
"recommender.ai_level as recommender_ai_level, "
|
||||
|
||||
"reason "
|
||||
"from pending_accounts p "
|
||||
"left join player alt on alt.char_id = p.alt "
|
||||
"left join player main on main.char_id = p.main "
|
||||
"left join player recommender on recommender.char_id = p.recommender "
|
||||
"order by time desc limit ?", [limit])
|
||||
blob = ""
|
||||
for entry in latest:
|
||||
blob += self.format_pending(entry)
|
||||
|
||||
return ChatBlob("Latest recommendations", blob)
|
||||
|
||||
# noinspection LongLine
|
||||
def format_pending(self, entry, buttons=False):
|
||||
button = "[<green>" + self.text.make_tellcmd(name="APPROVE", msg=f"pending approve {entry.alt_name}",
|
||||
style="style='text-decoration:none'") + "</green>] - [<red>" + self.text.make_tellcmd(
|
||||
name="DENY", msg=f"pending deny {entry.alt_name}",
|
||||
style="style='text-decoration:none'") + "</red>]" if buttons else ""
|
||||
if entry.main_id == entry.alt_id:
|
||||
text = f"[<notice>ACC</notice>] <{entry.main_faction.lower()}>{entry.main_name}</{entry.main_faction.lower()}> ({entry.main_level}/<green>{entry.main_ai_level}</green>) " \
|
||||
f" [{self.text.make_tellcmd('W', f'whois {entry.main_name}')}] " \
|
||||
f"[{self.text.make_tellcmd('H', f'history {entry.main_name}')}]\n" \
|
||||
f"Recommender: <{entry.recommender_faction.lower()}>{entry.recommender_name}</{entry.recommender_faction.lower()}> Why: <notice>{entry.reason}</notice>\n" \
|
||||
f"{button}"
|
||||
else:
|
||||
account = self.account_service.get_account(entry.main_id)
|
||||
text = f"[<notice>ALT</notice>] <{entry.alt_faction.lower()}>{entry.alt_name}</{entry.alt_faction.lower()}> ({entry.alt_level}/<green>{entry.alt_ai_level}</green>) " \
|
||||
f" [{self.text.make_tellcmd('W', f'whois {entry.alt_name}')}] " \
|
||||
f"[{self.text.make_tellcmd('H', f'history {entry.alt_name}')}]\n" \
|
||||
f"Main: <{entry.main_faction.lower()}>{entry.main_name}</{entry.main_faction.lower()}> ({entry.main_level}/<green>{entry.main_ai_level}</green>) [Join: {self.util.format_datetime(account.created)}]" \
|
||||
f" - [{self.text.make_tellcmd('W', f'whois {entry.main_name}')}] " \
|
||||
f"[{self.text.make_tellcmd('H', f'history {entry.main_name}')}]\n" \
|
||||
f"{button}"
|
||||
|
||||
return text + "\n\n"
|
||||
|
||||
@command(command="register", params=[Const("pending"), Const('deny'), Character('character')],
|
||||
description="Deny (and disable) a pending account", sub_command="mng", access_level="admin")
|
||||
def register_pending_deny(self, request, _1, _2, user):
|
||||
pending = self.account_service.is_pending(user.char_id)
|
||||
if not pending:
|
||||
return f"There's no pending registration for <highlight>{user.name}</highlight>."
|
||||
self.account_service.create_users([(pending.alt, pending.alt, -1, time.time(), time.time())])
|
||||
self.account_service.add_log(request.sender.char_id, "system",
|
||||
f"Created <highlight>{user.name}</highlight>'s account.",
|
||||
request.sender.char_id)
|
||||
self.account_service.add_log(user.char_id, "system",
|
||||
f"Account closed by <highlight>{request.sender.name}</highlight>.",
|
||||
request.sender.char_id)
|
||||
|
||||
self.db.exec("UPDATE pending_accounts set answered = 1 where alt=?", [pending.alt])
|
||||
self.account_service.account_disable(user.char_id)
|
||||
self.send_notify(self.Notify.DENIED, user.name, user.name)
|
||||
|
||||
# noinspection LongLine
|
||||
@command(command="register", params=[Const("pending"), Const('approve'), Character('character')],
|
||||
description="Approve (and activate) a pending account", sub_command="mng", access_level="admin")
|
||||
def register_pending_approve(self, request, _1, _2, user):
|
||||
pending = self.account_service.is_pending(user.char_id)
|
||||
if not pending:
|
||||
return f"There's no pending registration for <highlight>{user.name}</highlight>."
|
||||
self.account_service.create_users([(pending.alt, pending.alt, 0, time.time(), time.time())])
|
||||
if pending.alt == pending.main:
|
||||
self.db.exec("UPDATE pending_accounts set answered = 1 where alt=?", [pending.alt])
|
||||
self.account_service.add_log(request.sender.char_id, "system",
|
||||
f"Opened <highlight>{user.name}</highlight>'s account.",
|
||||
request.sender.char_id)
|
||||
self.account_service.add_log(user.char_id, "system",
|
||||
f"Account opened by <highlight>{request.sender.name}</highlight>.",
|
||||
request.sender.char_id)
|
||||
recommender: str = self.character_service.get_char_name(pending.recommender)
|
||||
self.buddy_service.add_buddy(user.char_id, "member")
|
||||
self.bot.send_mass_message(user.char_id,
|
||||
f"Your Account has been <green>opened</green> by "
|
||||
f"<highlight>{request.sender.name}</highlight>. "
|
||||
f"<highlight>{recommender.capitalize()}</highlight> has recommended you.")
|
||||
self.send_notify(self.Notify.APPROVAL_MAIN, user.name, user.name)
|
||||
else:
|
||||
msg, typ = self.account_service.add_alt(pending.main, pending.alt, approve=True)
|
||||
if msg == "success":
|
||||
self.db.exec("UPDATE pending_accounts set answered = 1 where alt=?", [pending.alt])
|
||||
self.account_service.add_log(request.sender.char_id, "system",
|
||||
f"Added <highlight>{user.name}</highlight> as an alt of <highlight>{self.character_service.resolve_char_to_name(pending.main)}</highlight>.",
|
||||
request.sender.char_id)
|
||||
self.account_service.add_log(user.char_id, "system",
|
||||
f"Request to add <highlight>{user.name}</highlight> as an alt "
|
||||
f"has been approved by <highlight>{request.sender.name}</highlight>.",
|
||||
request.sender.char_id)
|
||||
self.send_notify(self.Notify.APPROVAL_ALT,
|
||||
self.character_service.resolve_char_to_name(pending.main),
|
||||
user.name)
|
||||
else:
|
||||
return "Something went wrong.."
|
||||
|
||||
@command(command="register", params=[Const('alt'), Character('character')],
|
||||
description="Add an alt", access_level="member")
|
||||
def register_alt(self, request, _, alt):
|
||||
manual = self.setting_service.get_value("alt_verification") == "1"
|
||||
if not alt.char_id:
|
||||
return "Character does not exist"
|
||||
if not manual:
|
||||
return "This command is currently disabled, please use <highlight>!alts add</highlight>"
|
||||
msg, _ = self.account_service.add_pending_alt(request.sender.char_id, alt.char_id)
|
||||
if msg in ["another_main", "already_main"]:
|
||||
return f"You cannot add <highlight>{alt.name}</highlight> as an alt, because it already has a main."
|
||||
elif msg == "pending_alt":
|
||||
return f"There's already a pending registration for the alt <highlight>{alt.name}</highlight>, " \
|
||||
f"please wait for an admin to confirm it."
|
||||
elif msg == "success":
|
||||
self.send_notify(self.Notify.REQUEST_ALT, request.sender.name, alt.name)
|
||||
return f"You requested to add <highlight>{alt.name}</highlight> as an alt."
|
||||
|
||||
@command(command="register", params=[Const('recommend'), Character('character'), Any('reason')],
|
||||
description="Recommend someone as a raider", access_level="member")
|
||||
def register_account(self, request, _, user, reason):
|
||||
if not user.char_id:
|
||||
return "Character does not exist"
|
||||
if self.account_service.get_account(user.char_id):
|
||||
return f"There's already an account for <highlight>{user.name}</highlight> registered."
|
||||
msg, _ = self.account_service.add_pending_account(request.sender.char_id, user.char_id, reason)
|
||||
if msg in ["another_main", "already_main"]:
|
||||
return f"You cannot recommend <highlight>{user.name}</highlight>, " \
|
||||
f"because the character is already registered."
|
||||
elif msg == "pending_alt":
|
||||
return f"There's already a pending registration for the character <highlight>{user.name}</highlight>, " \
|
||||
f"please wait for an admin to confirm it."
|
||||
elif msg == "success":
|
||||
self.send_notify(self.Notify.REQUEST_MAIN, user.name, user.name)
|
||||
|
||||
def send_notify(self, notify_type, main, alt):
|
||||
message = "[<cyan>PG</cyan>] "
|
||||
if notify_type == self.Notify.APPROVAL_MAIN:
|
||||
message += f"[<cyan>Main</cyan>] Approved: <highlight>{main}</highlight>'s Account has been opened."
|
||||
elif notify_type == self.Notify.APPROVAL_ALT:
|
||||
message += f"[<cyan>Alt</cyan>] Approved: <highlight>{alt}</highlight> " \
|
||||
f"has been assigned to <highlight>{main}</highlight>."
|
||||
elif notify_type == self.Notify.DENIED:
|
||||
message += f"Denied: <highlight>{main}</highlight>'s Account has been closed."
|
||||
elif notify_type == self.Notify.REQUEST_ALT:
|
||||
message += f"[<cyan>Alt</cyan>] Request: <highlight>{alt}</highlight> => <highlight>{main}</highlight>"
|
||||
elif notify_type == self.Notify.REQUEST_MAIN:
|
||||
message += f"[<cyan>Main</cyan>] Request: <highlight>{main}</highlight> as a new " \
|
||||
f"<highlight>raider</highlight>"
|
||||
self.messagehub.send_message("registration", None, f"{message}", f"{message}")
|
||||
|
||||
class Notify:
|
||||
APPROVAL_MAIN = "approval-main"
|
||||
APPROVAL_ALT = "approval-alt"
|
||||
DENIED = "denied"
|
||||
REQUEST_ALT = "req-alt"
|
||||
REQUEST_MAIN = "req-main"
|
||||
@@ -0,0 +1,137 @@
|
||||
import inspect
|
||||
from typing import List
|
||||
|
||||
from core.decorators import instance
|
||||
from core.logger import Logger
|
||||
|
||||
|
||||
# noinspection PyUnusedLocal
|
||||
@instance()
|
||||
class AccessService:
|
||||
def __init__(self):
|
||||
self.access_levels = [
|
||||
{"label": "none", "level": 0, "handler": self.no_access},
|
||||
{"label": "all", "level": 100, "handler": self.all_access}]
|
||||
self.logger = Logger(__name__)
|
||||
|
||||
def inject(self, registry):
|
||||
self.character_service = registry.get_instance("character_service")
|
||||
self.account_service = registry.get_instance("account_service")
|
||||
|
||||
def register_access_level(self, label, level, handler):
|
||||
"""
|
||||
Call during pre_start
|
||||
|
||||
Args:
|
||||
label: str
|
||||
level: int
|
||||
handler: (char_id: Int) -> bool
|
||||
"""
|
||||
|
||||
if len(inspect.signature(handler).parameters) != 1:
|
||||
raise Exception(
|
||||
"Incorrect number of arguments for handler '%s.%s()'" % (handler.__module__, handler.__name__))
|
||||
|
||||
self.logger.debug("Registering access level %d with label '%s'" % (level, label))
|
||||
self.access_levels.append({"label": label.lower(), "level": level, "handler": handler})
|
||||
self.access_levels = sorted(self.access_levels, key=lambda k: k["level"])
|
||||
|
||||
def get_access_levels(self) -> List[dict]:
|
||||
return self.access_levels
|
||||
|
||||
def get_access_level(self, char_id) -> dict:
|
||||
account = self.account_service.get_main(char_id)
|
||||
if account:
|
||||
al = self.get_single_access_level(account.char_id)
|
||||
if al["label"] == "all":
|
||||
al = self.get_single_access_level(char_id)
|
||||
return al
|
||||
else:
|
||||
return self.get_single_access_level(char_id)
|
||||
# access_level1 = self.get_single_access_level(char_id)
|
||||
#
|
||||
# alts = self.account_service.get_alts(char_id)
|
||||
# if not alts:
|
||||
# return access_level1
|
||||
#
|
||||
# main = alts[0]
|
||||
# if main.char_id == char_id:
|
||||
# return access_level1
|
||||
# else:
|
||||
# access_level2 = self.get_single_access_level(main.char_id)
|
||||
# if access_level1["level"] < access_level2["level"]:
|
||||
# return access_level1
|
||||
# else:
|
||||
# return access_level2
|
||||
|
||||
def compare_access_levels(self, access_level1, access_level2) -> int:
|
||||
"""
|
||||
Returns a positive number if the access_level1 is greater than access_level2,
|
||||
a negative number if access_level1 is less than access_level2,
|
||||
and 0 if the access levels are equal.
|
||||
|
||||
:param access_level1:
|
||||
:param access_level2:
|
||||
:return: int
|
||||
"""
|
||||
a1 = self.get_access_level_by_label(access_level1)
|
||||
a2 = self.get_access_level_by_label(access_level2)
|
||||
|
||||
return a2["level"] - a1["level"]
|
||||
|
||||
def has_sufficient_access_level(self, char_id1, char_id2) -> bool:
|
||||
"""
|
||||
Returns True if char1 has a higher access level than char2
|
||||
or if char1 is a verified alt of char2, and False otherwise.
|
||||
|
||||
:param char_id1:
|
||||
:param char_id2:
|
||||
:return:
|
||||
"""
|
||||
|
||||
# return True if char_ids are the same
|
||||
if char_id1 == char_id2:
|
||||
return True
|
||||
|
||||
# return True if both chars have the same main
|
||||
if self.account_service.get_main(char_id1).char_id == (self.account_service.get_main(char_id2) or {}).get(
|
||||
"char_id", 0):
|
||||
return True
|
||||
|
||||
a1 = self.get_access_level(char_id1)
|
||||
a2 = self.get_access_level(char_id2)
|
||||
|
||||
return a2["level"] - a1["level"] > 0
|
||||
|
||||
def get_single_access_level(self, char) -> dict:
|
||||
char_id = self.character_service.resolve_char_to_id(char)
|
||||
for access_level in self.access_levels:
|
||||
if access_level["handler"](char_id):
|
||||
return access_level
|
||||
|
||||
def get_access_level_by_level(self, level) -> dict or bool:
|
||||
for access_level in self.access_levels:
|
||||
if access_level["level"] == level:
|
||||
return access_level
|
||||
return False
|
||||
|
||||
def get_access_level_by_label(self, label) -> dict or bool:
|
||||
label = label.lower()
|
||||
for access_level in self.access_levels:
|
||||
if access_level["label"] == label:
|
||||
return access_level
|
||||
return False
|
||||
|
||||
def check_access(self, char, access_level_label) -> bool:
|
||||
char_id = self.character_service.resolve_char_to_id(char)
|
||||
if not char_id:
|
||||
return False
|
||||
# noinspection LongLine
|
||||
return (self.get_access_level(char) or {}).get("level", 100) <= \
|
||||
self.get_access_level_by_label(access_level_label)["level"]
|
||||
|
||||
def no_access(self, char_id) -> bool:
|
||||
return False
|
||||
|
||||
def all_access(self, char_id) -> bool:
|
||||
return True
|
||||
@@ -0,0 +1,568 @@
|
||||
import time
|
||||
from typing import List
|
||||
|
||||
from core.buddy_service import BuddyService
|
||||
from core.db import DB, SqlException
|
||||
from core.decorators import instance, timerevent, event
|
||||
from core.dict_object import DictObject
|
||||
from core.logger import Logger
|
||||
from core.lookup.character_service import CharacterService
|
||||
from core.lookup.pork_service import PorkService
|
||||
from core.setting_service import SettingService
|
||||
from core.setting_types import BooleanSettingType
|
||||
from core.text import Text
|
||||
from core.tyrbot import Tyrbot
|
||||
from modules.core.accounting.services.access_service import AccessService
|
||||
|
||||
|
||||
# noinspection SqlCaseVsIf,SqlResolve,PyMethodMayBeStatic
|
||||
@instance()
|
||||
class AccountService:
|
||||
MAIN_CHANGED_EVENT_TYPE = "main_changed"
|
||||
MEMBER_LOGON = "member_logon"
|
||||
MEMBER_LOGOFF = "member_logoff"
|
||||
|
||||
def __init__(self):
|
||||
self.logger = Logger("Accounting")
|
||||
|
||||
# noinspection PyAttributeOutsideInit
|
||||
def inject(self, registry):
|
||||
self.bot: Tyrbot = registry.get_instance("bot")
|
||||
self.buddy_service: BuddyService = registry.get_instance("buddy_service")
|
||||
self.util = registry.get_instance("util")
|
||||
self.character_service: CharacterService = registry.get_instance("character_service")
|
||||
self.access_service: AccessService = registry.get_instance("access_service")
|
||||
self.db: DB = registry.get_instance("db")
|
||||
self.event_service = registry.get_instance("event_service")
|
||||
self.pork: PorkService = registry.get_instance("pork_service")
|
||||
self.setting_service: SettingService = registry.get_instance("setting_service")
|
||||
self.text: Text = registry.get_instance("text")
|
||||
|
||||
def pre_start(self):
|
||||
self.db.exec("CREATE TABLE IF NOT EXISTS account ("
|
||||
"char_id int(11) NOT NULL,"
|
||||
"points int(11) NOT NULL default 0,"
|
||||
"member int(2) NOT NULL DEFAULT 0,"
|
||||
"created int(255) NOT NULL DEFAULT 0,"
|
||||
"disabled int(2) NOT NULL DEFAULT 0,"
|
||||
"main int(11) NOT NULL DEFAULT char_id,"
|
||||
"subtile_spam int(2) NOT NULL DEFAULT 0,"
|
||||
"auto_invite int(2) NOT NULL DEFAULT 0,"
|
||||
"raid_invite int(2) NOT NULL DEFAULT 1,"
|
||||
"raid_spam int(2) NOT NULL DEFAULT 1,"
|
||||
"news_spam int(2) NOT NULL DEFAULT 1,"
|
||||
"discord_id bigint(30) UNSIGNED NULL DEFAULT 0,"
|
||||
"discord_handle varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '',"
|
||||
"discord_invite text CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '',"
|
||||
"discord_joined int(2) NOT NULL DEFAULT 0,"
|
||||
"logon text CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '',"
|
||||
"logoff text CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '',"
|
||||
"last_seen int(11) NOT NULL DEFAULT 0,"
|
||||
"last_updated int(11) NOT NULL DEFAULT 0,"
|
||||
"PRIMARY KEY (char_id) USING BTREE,"
|
||||
"INDEX char_id(char_id) USING BTREE,"
|
||||
"INDEX main(main) USING BTREE,"
|
||||
"INDEX disabled(disabled) USING BTREE,"
|
||||
"INDEX char_id_2(char_id, disabled) USING BTREE,"
|
||||
"INDEX discord_id(discord_id) USING BTREE)")
|
||||
|
||||
self.db.exec(
|
||||
"CREATE TABLE IF NOT EXISTS raid_log ("
|
||||
"raid_id INT PRIMARY KEY AUTO_INCREMENT, "
|
||||
"raid_name VARCHAR(255) NOT NULL, "
|
||||
"started_by BIGINT NOT NULL, "
|
||||
"raid_start INT NOT NULL, "
|
||||
"raid_end INT NOT NULL)")
|
||||
|
||||
self.db.exec(
|
||||
"CREATE TABLE IF NOT EXISTS raid_log_participants ("
|
||||
"raid_id INT NOT NULL, "
|
||||
"raider_id BIGINT NOT NULL, "
|
||||
"accumulated_points INT DEFAULT 0, "
|
||||
"left_raid INT, "
|
||||
"was_kicked INT, "
|
||||
"was_kicked_reason VARCHAR(500))")
|
||||
|
||||
self.db.exec("CREATE TABLE IF NOT EXISTS points_presets ("
|
||||
"preset_id INT PRIMARY KEY AUTO_INCREMENT, "
|
||||
"name VARCHAR(50) NOT NULL, "
|
||||
"points INT DEFAULT 1, "
|
||||
"UNIQUE(name));")
|
||||
self.db.exec("CREATE TABLE IF NOT EXISTS pending_accounts ("
|
||||
"main INT(11) NOT NULL, "
|
||||
"alt INT(11) NOT NULL, "
|
||||
"reason TEXT DEFAULT '', "
|
||||
"recommender INT(11) NOT NULL , "
|
||||
"time int(255) NOT NULL,"
|
||||
"answered int(2) default 0 not null);")
|
||||
|
||||
self.db.exec("CREATE TABLE IF NOT EXISTS account_log ("
|
||||
"log_id INTEGER PRIMARY KEY AUTO_INCREMENT, "
|
||||
"char_id BIGINT NOT NULL, "
|
||||
"type VARCHAR(32), "
|
||||
"delta INT NOT NULL DEFAULT 0, "
|
||||
"leader_id BIGINT NOT NULL, "
|
||||
"reason VARCHAR(255), "
|
||||
"created_at INTEGER NOT NULL, "
|
||||
"INDEX char_id (char_id), "
|
||||
"INDEX leader (leader_id), "
|
||||
"INDEX created(created_at));")
|
||||
|
||||
self.db.exec("CREATE TABLE IF NOT EXISTS ranks ("
|
||||
"main int(11) NOT NULL, "
|
||||
"`rank` varchar(32) not null, "
|
||||
"INDEX main(main, `rank`) USING BTREE)")
|
||||
|
||||
self.db.exec("CREATE TABLE IF NOT EXISTS org_bots(char_id int primary key not null, org_id int not null)")
|
||||
|
||||
self.event_service.register_event_type(self.MAIN_CHANGED_EVENT_TYPE)
|
||||
self.event_service.register_event_type(self.MEMBER_LOGON)
|
||||
self.event_service.register_event_type(self.MEMBER_LOGOFF)
|
||||
self.setting_service.register_new(self.module_name, "is_alliance_bot", False, BooleanSettingType(),
|
||||
"Is this bot used as an alliancebot")
|
||||
self.setting_service.register_new(self.module_name, "alt_verification", False, BooleanSettingType(),
|
||||
"alts require admin verification")
|
||||
|
||||
if self.setting_service.get_value("is_alliance_bot") == "1":
|
||||
self.access_service.register_access_level("officer", 80, self.check_officer)
|
||||
self.access_service.register_access_level("general", 70, self.check_general)
|
||||
self.access_service.register_access_level("president", 60, self.check_president)
|
||||
self.access_service.register_access_level("council", 40, self.check_council)
|
||||
self.access_service.register_access_level("moderator", 30, self.check_moderator)
|
||||
self.access_service.register_access_level("member", 90, self.check_member)
|
||||
self.access_service.register_access_level("admin", 20, self.check_admin)
|
||||
self.access_service.register_access_level("leader", 50, self.check_leader)
|
||||
self.access_service.register_access_level("superadmin", 10, self.check_superadmin)
|
||||
|
||||
def get_main(self, char_id) -> DictObject:
|
||||
alts = self.get_alts(char_id)
|
||||
return alts[0] if alts else self.db.query_single("select * from player where char_id=?", [char_id])
|
||||
|
||||
def get_alts(self, char_id) -> List[DictObject]:
|
||||
return self.db.query(
|
||||
"SELECT p.*, a.* from account a left join player p on a.char_id = p.char_id where "
|
||||
"main=(SELECT main from account where char_id=?) ORDER BY a.main = a.char_id desc, p.level, p.name DESC",
|
||||
[char_id])
|
||||
|
||||
acc_cache = {}
|
||||
|
||||
def get_account(self, char_id) -> DictObject:
|
||||
|
||||
if char_id not in self.acc_cache.keys():
|
||||
out = self.db.query_single(
|
||||
"SELECT a.*, p.* from account a left join player p on a.char_id = p.char_id where "
|
||||
"a.char_id=(SELECT main from account where char_id=?) "
|
||||
"and a.char_id not in (SELECT char_id from org_bots)",
|
||||
[char_id]) or DictObject({})
|
||||
self.acc_cache[char_id] = out
|
||||
self.bot.job_scheduler.delayed_job(lambda x: self.acc_cache.pop(char_id), 5)
|
||||
else:
|
||||
out = self.acc_cache.get(char_id)
|
||||
return out
|
||||
|
||||
def get_entry(self, char_id) -> DictObject:
|
||||
return self.db.query_single("SELECT a.*, p.* from account a left join player p on a.char_id = p.char_id "
|
||||
"where a.char_id=? and a.char_id not in (SELECT char_id from org_bots)",
|
||||
[char_id]) or DictObject({})
|
||||
|
||||
def add_pending_alt(self, main, alt) -> [str, bool]:
|
||||
data = self.check_alt(alt)
|
||||
if data:
|
||||
return data
|
||||
acc = self.get_account(main)
|
||||
if acc:
|
||||
main = acc.main
|
||||
self.pork.load_character_info(alt, skeleton_only=True)
|
||||
self.db.exec("INSERT INTO pending_accounts(main, alt, recommender, time) VALUES(?, ?, ?, ?)",
|
||||
[acc.main, alt, acc.main, time.time()])
|
||||
self.add_log(main, 'system',
|
||||
f'Requested to add <highlight>{self.character_service.resolve_char_to_name(alt)}</highlight>'
|
||||
f' as an alt',
|
||||
acc.main)
|
||||
return ["success", True]
|
||||
|
||||
def add_pending_account(self, main, user, reason) -> [str, bool]:
|
||||
data = self.check_alt(user)
|
||||
if data:
|
||||
return data
|
||||
acc = self.get_account(main)
|
||||
if acc:
|
||||
main = acc.main
|
||||
self.pork.load_character_info(user, skeleton_only=True)
|
||||
self.db.exec("INSERT INTO pending_accounts(main, alt, recommender, reason, time) VALUES(?, ?, ?, ?, ?)",
|
||||
[user, user, acc.main, reason, time.time()])
|
||||
self.add_log(main, 'system',
|
||||
f'Recommended <highlight>{self.character_service.resolve_char_to_name(user)}</highlight>'
|
||||
f' as raider, reason: {reason}',
|
||||
acc.main)
|
||||
return ["success", True]
|
||||
|
||||
def check_alt(self, alt):
|
||||
alt_alts = self.get_alts(alt) or []
|
||||
if len(alt_alts) > 1:
|
||||
for alts in alt_alts:
|
||||
if alts.char_id == alt:
|
||||
if alts.main != alts.char_id:
|
||||
return ["another_main", False]
|
||||
alt_main = self.get_account(alt)
|
||||
if alt_main:
|
||||
if alt_main.main != alt:
|
||||
return ["already_main", False]
|
||||
if self.is_pending(alt):
|
||||
return ['pending_alt', False]
|
||||
|
||||
def is_pending(self, char_id) -> DictObject or bool:
|
||||
return self.db.query_single("SELECT * from pending_accounts where alt=? and answered = 0", [char_id]) or False
|
||||
|
||||
def add_alt(self, sender, alt, approve=False) -> [str, bool]:
|
||||
alt_alts = self.get_alts(alt) or []
|
||||
if alt_alts:
|
||||
if len(alt_alts) > 1:
|
||||
return ["another_main", False]
|
||||
if alt_main := alt_alts[0]:
|
||||
if alt_main.main != alt:
|
||||
return ["already_main", False]
|
||||
acc = self.get_account(sender)
|
||||
if acc:
|
||||
main = acc.main
|
||||
self.pork.load_character_info(alt, skeleton_only=True)
|
||||
member = -1 if acc.disabled == 1 or acc.member == -1 else 0
|
||||
if self.db.exec("INSERT IGNORE INTO account(char_id, main, created, member) VALUES(?, ?, ?, ?)",
|
||||
[alt, main, time.time(), member]) == 0:
|
||||
self.db.exec("UPDATE account set main=?, created=? where char_id=?", [main, time.time(), alt])
|
||||
self.event_service.fire_event(self.MAIN_CHANGED_EVENT_TYPE,
|
||||
DictObject({"old_main_id": alt, "new_main_id": main}))
|
||||
if not approve:
|
||||
self.add_log(sender, 'system',
|
||||
f'Added <highlight>{self.character_service.resolve_char_to_name(alt)}</highlight>'
|
||||
f' as an alt',
|
||||
acc.main)
|
||||
# Only add as member if he's neither banned, nor unregistered
|
||||
if member != -1:
|
||||
self.buddy_service.add_buddy(alt, "member")
|
||||
return ["success", True]
|
||||
self.db.exec("INSERT IGNORE INTO account(char_id, main, created, member) VALUES(?, ?, ?, ?)",
|
||||
[sender, sender, time.time(), -1])
|
||||
self.db.exec("INSERT INTO account(char_id, main, created, member) VALUES(?, ?, ?, ?) ON DUPLICATE KEY UPDATE "
|
||||
"main=VALUE(main), discord_id=0, discord_handle='', discord_invite='', discord_joined=0",
|
||||
[alt, sender, time.time(), -1])
|
||||
if not approve:
|
||||
self.add_log(sender, 'system',
|
||||
f'Added <highlight>{self.character_service.resolve_char_to_name(alt)}</highlight> as an alt',
|
||||
sender)
|
||||
# Main does not exist, do not add as member
|
||||
# self.buddy_service.add_buddy(alt, "member")
|
||||
return ["success", True]
|
||||
|
||||
def remove_alt(self, sender, alt) -> [str, bool]:
|
||||
if not self.db.query(
|
||||
"SELECT * FROM account where char_id=? and main=(SELECT main from account where char_id=?)",
|
||||
[alt, sender]):
|
||||
return ["not_alt", False]
|
||||
alts = self.get_alts(sender)
|
||||
for row in alts:
|
||||
if row.char_id == alt and row.main == alt:
|
||||
return ["remove_main", False]
|
||||
if row.char_id == alt and row.main == alts[0].char_id:
|
||||
self.db.exec("UPDATE account set main=? where char_id=?", [alt, alt])
|
||||
self.add_log(sender, 'system',
|
||||
f'Removed <highlight>{self.character_service.resolve_char_to_name(alt)}</highlight>'
|
||||
f' from his alts.',
|
||||
sender)
|
||||
return ["success", True]
|
||||
else:
|
||||
return [""]
|
||||
|
||||
def set_as_main(self, sender) -> [str, bool]:
|
||||
alts = self.get_alts(sender)
|
||||
|
||||
if len(alts) < 2:
|
||||
return ["not_an_alt", False]
|
||||
elif alts[0].char_id == sender:
|
||||
return ["already_main", False]
|
||||
else:
|
||||
self.db.exec("UPDATE account set main=? where main=(SELECT main from account where char_id=?)",
|
||||
[sender, sender])
|
||||
self.event_service.fire_event(self.MAIN_CHANGED_EVENT_TYPE,
|
||||
DictObject({"old_main_id": alts[0].char_id,
|
||||
"new_main_id": sender}))
|
||||
return ["success", True]
|
||||
|
||||
def get_orgs(self) -> list:
|
||||
try:
|
||||
return [x["org_id"] for x in self.db.query("SELECT * from orgs", [])]
|
||||
except SqlException:
|
||||
return [self.bot.public_channel_service.org_id]
|
||||
|
||||
def create_users(self, users, disable=False) -> int:
|
||||
if type(users) == list and len(users) > 0:
|
||||
with self.db.pool.get_connection() as conn:
|
||||
with conn.cursor() as cur:
|
||||
if disable:
|
||||
cur.executemany(
|
||||
"INSERT IGNORE INTO account(char_id, main, member, disabled, last_updated, created) "
|
||||
"VALUES(?, ?, ?, 1, ?, ?) ON DUPLICATE KEY UPDATE "
|
||||
"member=VALUE(member), last_updated=VALUE(last_updated), disabled=1",
|
||||
users)
|
||||
return cur.rowcount
|
||||
cur.executemany(
|
||||
"INSERT IGNORE INTO account(char_id, main, member, last_updated, created) "
|
||||
"VALUES(?, ?, ?, ?, ?) ON DUPLICATE KEY UPDATE "
|
||||
"member=VALUE(member), last_updated=VALUE(last_updated)",
|
||||
users)
|
||||
return cur.rowcount
|
||||
|
||||
def account_disable(self, char_id) -> bool:
|
||||
return True if self.db.exec(
|
||||
"UPDATE account set disabled=1 where main in (SELECT main from account where char_id=?)",
|
||||
[char_id]) else False
|
||||
|
||||
def account_enable(self, char_id) -> bool:
|
||||
return True if self.db.exec(
|
||||
"UPDATE account set disabled=0 where main in (SELECT main from account where char_id=?)",
|
||||
[char_id]) else False
|
||||
|
||||
def remove_members(self, users) -> None:
|
||||
if type(users) == list and len(users) > 0:
|
||||
with self.db.pool.get_connection() as conn:
|
||||
with conn.cursor() as cur:
|
||||
cur.executemany("UPDATE account set member=-1 where char_id=? and ?", users)
|
||||
|
||||
def check_member(self, char_id) -> bool:
|
||||
account = self.get_account(char_id) or {}
|
||||
if account.get('disabled', 1) == 1:
|
||||
return False
|
||||
if account.get('member', -1) == -1:
|
||||
return False
|
||||
if self.setting_service.get_value("is_alliance_bot") == "0":
|
||||
return True
|
||||
if account.get('org_id', 0) not in self.get_orgs():
|
||||
return False
|
||||
return True
|
||||
|
||||
def check_president(self, char_id) -> bool:
|
||||
if self.setting_service.get_value("is_alliance_bot") == "0":
|
||||
return False
|
||||
account = self.get_account(char_id) or {}
|
||||
if not self.simple_checks(account):
|
||||
return False
|
||||
if account.get('org_rank_id', -1) == 0:
|
||||
return True
|
||||
return False
|
||||
|
||||
def check_general(self, char_id) -> bool:
|
||||
if self.setting_service.get_value("is_alliance_bot") == "0":
|
||||
return False
|
||||
account = self.get_account(char_id) or {}
|
||||
if not self.simple_checks(account):
|
||||
return False
|
||||
if self.get_rank_count(char_id) != 7:
|
||||
return False
|
||||
if account.get('org_rank_id', -1) <= 1:
|
||||
return True
|
||||
return False
|
||||
|
||||
def check_officer(self, char_id) -> bool:
|
||||
if self.setting_service.get_value("is_alliance_bot") == "0":
|
||||
return False
|
||||
account = self.get_account(char_id) or {}
|
||||
if not self.simple_checks(account):
|
||||
return False
|
||||
if self.get_rank_count(char_id) != 7:
|
||||
return False
|
||||
if account.get('org_rank_id', -1) <= 2:
|
||||
return True
|
||||
return False
|
||||
|
||||
def check_council(self, char_id) -> bool:
|
||||
if self.setting_service.get_value("is_alliance_bot") == "0":
|
||||
return False
|
||||
if self.simple_checks(self.get_account(char_id)):
|
||||
return "council" in self.get_ranks(char_id)
|
||||
|
||||
def check_leader(self, char_id) -> bool:
|
||||
if self.simple_checks(self.get_account(char_id)):
|
||||
return "leader" in self.get_ranks(char_id)
|
||||
|
||||
def check_moderator(self, char_id) -> bool:
|
||||
if self.simple_checks(self.get_account(char_id)):
|
||||
return "moderator" in self.get_ranks(char_id)
|
||||
|
||||
def check_admin(self, char_id) -> bool:
|
||||
if self.simple_checks(self.get_account(char_id)):
|
||||
return "admin" in self.get_ranks(char_id)
|
||||
|
||||
def check_superadmin(self, char_id) -> int:
|
||||
return char_id in self.bot.superadmin
|
||||
|
||||
def get_ranks(self, char_id) -> List[DictObject]:
|
||||
return [x["rank"] for x in
|
||||
self.db.query(" SELECT rank FROM ranks where main = (SELECT main from account where char_id=? limit 1)",
|
||||
[char_id])] or []
|
||||
|
||||
def get_all_admins(self) -> List[DictObject]:
|
||||
return self.get_by_group("admin")
|
||||
|
||||
def get_all_moderators(self) -> List[DictObject]:
|
||||
return self.get_by_group("moderator")
|
||||
|
||||
def get_all_councils(self) -> List[DictObject]:
|
||||
return self.get_by_group("council")
|
||||
|
||||
def get_all_leaders(self) -> List[DictObject]:
|
||||
return self.get_by_group("leader")
|
||||
|
||||
def get_all_members(self, online_only=False) -> List[DictObject]:
|
||||
return self.db.query(
|
||||
f"SELECT p.*, a.*, CASE when o.char_id IS NOT NULL then 1 ELSE 0 end as online from account a "
|
||||
f"LEFT JOIN player p ON a.char_id=p.char_id "
|
||||
f"LEFT JOIN (SELECT * FROM online WHERE bot=?) o ON a.char_id=o.char_id "
|
||||
f"WHERE a.char_id NOT IN (SELECT char_id from org_bots) "
|
||||
f"and a.disabled = 0 {'and o.char_id is not null' if online_only else ''} "
|
||||
f"order by a.main, a.main=a.char_id desc, p.level desc, p.ai_level desc",
|
||||
[self.bot.get_char_id()])
|
||||
|
||||
def get_by_group(self, group) -> List[DictObject]:
|
||||
return self.db.query("""SELECT CASE when rank = 'admin' then 0
|
||||
when rank = 'moderator' then 1
|
||||
when rank = 'council' then 2
|
||||
when rank = 'leader' then 3
|
||||
ELSE 99 END AS rank_id,
|
||||
CASE when o.char_id IS NOT NULL
|
||||
then 1
|
||||
ELSE 0 end as online,
|
||||
p.*, a.* FROM ranks r
|
||||
LEFT JOIN account a ON r.main=a.main
|
||||
LEFT JOIN player p ON a.char_id=p.char_id
|
||||
LEFT JOIN online o ON a.char_id=o.char_id
|
||||
WHERE r.rank=?
|
||||
ORDER BY rank_id, a.main desc, a.main=a.char_id DESC, p.name """, [group])
|
||||
|
||||
def get_group_tag(self, string) -> str or bool:
|
||||
string = string.lower()
|
||||
if string in ["adm", "admins", "admin", "administrator", "administrators"]:
|
||||
return "admin"
|
||||
elif string in ["mod", "mods", "moderator", "moderators"]:
|
||||
return "moderator"
|
||||
elif string in ["cnc", "council", "councilors"]:
|
||||
return "council"
|
||||
elif string in ["rl", "leader", "leaders", "raidleader", "raidleaders", "rls"]:
|
||||
return "leader"
|
||||
elif string in ["all", "full", "everyone"]:
|
||||
return "all"
|
||||
else:
|
||||
return False
|
||||
|
||||
def add_log(self, char_id, log_type, message, leader, delta=0) -> None:
|
||||
main = self.get_main(char_id).char_id
|
||||
self.db.exec("INSERT INTO account_log(char_id, type, delta, leader_id, reason, created_at) "
|
||||
"VALUES (?, ?, ?, ?, ?, ?)",
|
||||
[main, log_type, delta, leader, message, time.time()])
|
||||
|
||||
def get_logs(self, user, log_type=None, limit=25) -> List[DictObject]:
|
||||
if not log_type:
|
||||
return self.db.query("SELECT * FROM account_log "
|
||||
"where char_id=? and type != 'admin' order by log_id desc LIMIT ? ", [user, limit])
|
||||
|
||||
else:
|
||||
return self.db.query("SELECT * FROM account_log "
|
||||
"where char_id=? and type=? order by log_id desc LIMIT ?", [user, log_type, limit])
|
||||
|
||||
def get_log_by_id(self, log_id) -> DictObject:
|
||||
return self.db.query_single("SELECT * FROM account_log where log_id=? ", [log_id])
|
||||
|
||||
def format_entry(self, entry) -> str:
|
||||
msg = f"<grey>[{self.util.format_datetime(entry.created_at)}] " \
|
||||
f"[{self.text.make_tellcmd('D', f'account log id {entry.log_id}')}]</grey> "
|
||||
entry.type = entry.type.lower()
|
||||
if entry.type == "points":
|
||||
entry.reason = entry.reason.replace('"', "'")
|
||||
msg += f"<white>{f'<green>+{entry.delta}P</green>' if entry.delta >= 0 else f'<red>{entry.delta}P</red>'}" \
|
||||
f" by <notice>{self.character_service.resolve_char_to_name(entry.leader_id)}</notice>" \
|
||||
f" for <notice>{entry.reason}</notice></white>"
|
||||
elif entry.type == "loot":
|
||||
msg += f"<white>Won Item: {entry.reason}</white>"
|
||||
elif entry.type == "raid":
|
||||
msg += f"<white>{entry.reason}</white>"
|
||||
elif entry.type == "public":
|
||||
msg += f"<white>{entry.reason}</white>"
|
||||
elif entry.type == "admin":
|
||||
msg += f"<white>Notice from " \
|
||||
f"<notice>{self.character_service.resolve_char_to_name(entry.leader_id)}</notice>: " \
|
||||
f"{entry.reason}</white>"
|
||||
elif entry.type == "system":
|
||||
msg += f"<yellow>{entry.reason}</yellow>"
|
||||
|
||||
return msg + "\n"
|
||||
|
||||
def add_pts(self, char_id, points, reason, leader) -> None:
|
||||
self.db.exec("UPDATE account set points = points+? where char_id=(select main from account where char_id=?)",
|
||||
[points, char_id])
|
||||
self.add_log(char_id, 'points', reason, leader, delta=points)
|
||||
|
||||
def rem_pts(self, char_id, points, reason, leader) -> None:
|
||||
if points < 0:
|
||||
points = -points
|
||||
self.db.exec("UPDATE account set points = points-? where char_id=(select main from account where char_id=?)",
|
||||
[points, char_id])
|
||||
self.add_log(char_id, 'points', reason, leader, delta=-points)
|
||||
|
||||
def add_rank(self, char_id, rank) -> int:
|
||||
return self.db.exec("INSERT INTO ranks(main, `rank`) VALUES(?, ?)", [char_id, rank])
|
||||
|
||||
def del_rank(self, char_id, rank) -> int:
|
||||
return self.db.exec("DELETE FROM ranks where main=? and rank =?", [char_id, rank])
|
||||
|
||||
@timerevent(budatime="12h", description="Delete dead ranks")
|
||||
def clear_raid(self, _, _1):
|
||||
count = self.db.exec("DELETE FROM ranks where main not in (SELECT main from account)")
|
||||
if count > 0:
|
||||
self.logger.info(f"Purged {count} dead ranks")
|
||||
count = self.db.exec(
|
||||
"delete from ranks where main in(select r.main from ranks r "
|
||||
"left join account a on r.main=a.char_id "
|
||||
"where a.member=-1)")
|
||||
if count > 0:
|
||||
self.logger.info(f"Purged {count} ranks; caused by: main no longer in the alliance")
|
||||
|
||||
@event(event_type="main_changed", description="Fix ranks")
|
||||
def fix_ranks(self, _, data):
|
||||
self.db.exec("UPDATE ranks set main=? where main=?", [data.new_main_id, data.old_main_id])
|
||||
self.db.exec("UPDATE account_log set char_id=? where char_id=?", [data.new_main_id, data.old_main_id])
|
||||
self.db.exec("UPDATE account_log set leader_id=? where leader_id=?", [data.new_main_id, data.old_main_id])
|
||||
|
||||
@event(event_type="buddy_logon", description="Member logon manager")
|
||||
def member_login(self, _, data):
|
||||
buddy = self.buddy_service.get_buddy(data.char_id)
|
||||
if buddy:
|
||||
if self.bot.is_ready():
|
||||
if "member" in buddy['types'] or "org_member" in buddy['types']:
|
||||
if main := self.get_account(data.char_id):
|
||||
self.event_service.fire_event(self.MEMBER_LOGON, DictObject({'account': main, 'packet': data}))
|
||||
else:
|
||||
if main := self.get_account(data.char_id):
|
||||
self.event_service.fire_event(self.MEMBER_LOGON, DictObject({'account': main, 'packet': data}))
|
||||
|
||||
@event(event_type="buddy_logoff", description="Member logoff manager")
|
||||
def member_logout(self, _, data):
|
||||
if self.bot.is_ready():
|
||||
buddy = self.buddy_service.get_buddy(data.char_id)
|
||||
if buddy:
|
||||
if "member" in buddy['types'] or "org_member" in buddy['types']:
|
||||
if main := self.get_account(data.char_id):
|
||||
self.event_service.fire_event(self.MEMBER_LOGOFF, DictObject({'account': main, 'packet': data}))
|
||||
|
||||
def get_rank_count(self, char_id):
|
||||
return self.db.query_single(
|
||||
"SELECT MAX(org_rank_id)+1 AS count FROM player WHERE org_id=(SELECT org_id FROM player where char_id=?)",
|
||||
[char_id]).count
|
||||
|
||||
def simple_checks(self, account):
|
||||
if account.get('disabled', 1) == 1:
|
||||
return False
|
||||
if account.get('member', -1) == -1:
|
||||
return False
|
||||
if self.setting_service.get_value("is_alliance_bot") == "1":
|
||||
if account.get('org_id', 0) not in self.get_orgs():
|
||||
return False
|
||||
return True
|
||||
Reference in New Issue
Block a user