Initial Release of IGNCore version 2.5

This commit is contained in:
2021-08-09 13:18:56 +02:00
commit a83d98c47e
910 changed files with 224171 additions and 0 deletions
@@ -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