84a5933490
generified the Worldboss module; removed the spammy-section as of currently, will be readded at a later stage.
643 lines
34 KiB
Python
643 lines
34 KiB
Python
import time
|
|
from collections import OrderedDict
|
|
from typing import Union
|
|
|
|
from core.aochat import server_packets
|
|
from core.aochat.BaseModule import BaseModule
|
|
from core.buddy_service import BuddyService
|
|
from core.chat_blob import ChatBlob
|
|
from core.command_param_types import Const, Int, Any, Options, Character
|
|
from core.command_request import CommandRequest
|
|
from core.db import DB
|
|
from core.decorators import instance, command, timerevent, event
|
|
from core.dict_object import DictObject
|
|
from core.event_service import EventService
|
|
from core.lookup.character_service import CharacterService
|
|
from core.lookup.pork_service import PorkService
|
|
from core.private_channel_service import PrivateChannelService
|
|
from core.sender_obj import SenderObj
|
|
from core.setting_service import SettingService
|
|
from core.text import Text
|
|
from core.igncore import IgnCore
|
|
from core.util import Util
|
|
from modules.core.accounting.services.account_service import AccountService
|
|
from modules.raidbot.raid.preset_controller import PresetController
|
|
from modules.standard.online.online_controller import OnlineController
|
|
from modules.standard.raid.leader_controller import LeaderController
|
|
|
|
|
|
class Raider:
|
|
def __init__(self, alts, active):
|
|
self.main_id = alts[0].char_id
|
|
self.alts = alts
|
|
self.active_id = active
|
|
self.accumulated_points = 0
|
|
self.is_active = True
|
|
self.left_raid = None
|
|
self.was_kicked = None
|
|
self.was_kicked_reason = None
|
|
|
|
def get_active_char(self):
|
|
for alt in self.alts:
|
|
if self.active_id == alt.char_id:
|
|
return alt
|
|
return None
|
|
|
|
|
|
class Raid:
|
|
def __init__(self, raid_name, started_by, raiders=None):
|
|
self.raid_name = raid_name
|
|
self.desc = raid_name
|
|
self.started_at = int(time.time())
|
|
self.started_by = started_by
|
|
self.raiders = raiders or []
|
|
self.is_open = True
|
|
self.raid_orders = None
|
|
self.level = 180
|
|
|
|
|
|
@instance()
|
|
class RaidbotController(BaseModule):
|
|
NO_RAID_RUNNING_RESPONSE = "No raid is running."
|
|
|
|
def __init__(self):
|
|
self.raid = None
|
|
|
|
def inject(self, registry):
|
|
self.bot: IgnCore = registry.get_instance("bot")
|
|
self.db: DB = registry.get_instance("db")
|
|
self.text: Text = registry.get_instance("text")
|
|
self.setting_service: SettingService = registry.get_instance("setting_service")
|
|
self.character_service: CharacterService = registry.get_instance("character_service")
|
|
self.preset_controller: PresetController = registry.get_instance("preset_controller")
|
|
self.util: Util = registry.get_instance("util")
|
|
self.event_service: EventService = registry.get_instance("event_service")
|
|
self.leader: LeaderController = registry.get_instance("leader_controller")
|
|
self.getresp = registry.get_instance("translation_service").get_response
|
|
self.pork: PorkService = registry.get_instance("pork_service")
|
|
self.private_channel_service: PrivateChannelService = registry.get_instance("private_channel_service")
|
|
self.account_service: AccountService = registry.get_instance("account_service")
|
|
self.buddy_service: BuddyService = registry.get_instance("buddy_service")
|
|
self.online: OnlineController = registry.get_instance("online_controller")
|
|
|
|
@event("connect", "Adds all raiders to buddylist")
|
|
def connect(self, _, _1):
|
|
query = self.db.query("SELECT char_id, member from account where member != -1 and disabled = 0")
|
|
if query:
|
|
for player in query:
|
|
self.buddy_service.add_buddy(player.char_id, "member")
|
|
|
|
@command(command="raid", params=[], access_level="member",
|
|
description="Show the current raid status")
|
|
def raid_cmd(self, _):
|
|
if not self.raid:
|
|
return self.NO_RAID_RUNNING_RESPONSE
|
|
|
|
t = int(time.time())
|
|
|
|
blob = ""
|
|
blob += f"Name: <highlight>{self.raid.desc}</highlight>\n"
|
|
blob += f"Minimum Level: <highlight>{self.raid.level}</highlight>\n"
|
|
blob += f"Started By: <highlight>{self.raid.started_by.name}</highlight>\n"
|
|
blob += f"Raidleader: " \
|
|
f"<highlight>" \
|
|
f"{self.leader.leader.name if self.leader.leader else '<red>not set - use !leader set</red>'}" \
|
|
f"</highlight>\n"
|
|
blob += f"Started At: <highlight>{self.util.format_datetime(self.raid.started_at)}</highlight> " \
|
|
f"({self.util.time_to_readable(t - self.raid.started_at)} ago)\n"
|
|
if self.raid.is_open:
|
|
blob += f"Status: <green>Open</green> [{self.text.make_chatcmd('Join', '/tell <myname> raid join')}] " \
|
|
f"<red>[{self.text.make_chatcmd('Lock', '/tell <myname> raid lock')}]</red>"
|
|
else:
|
|
blob += f"Status: <red>Closed</red> " \
|
|
f"<green>[{self.text.make_chatcmd('Unlock', '/tell <myname> raid open')}]</green>"
|
|
blob += "\n\n"
|
|
|
|
if self.raid.raid_orders:
|
|
blob += "<header2>Orders</header2>\n"
|
|
blob += self.raid.raid_orders + "\n\n"
|
|
blob += "<header2>Raiders</header2>\n"
|
|
for raider in self.raid.raiders:
|
|
if raider.is_active:
|
|
blob += self.format_row(raider.get_active_char())
|
|
return ChatBlob("Raid Status", blob)
|
|
|
|
def format_row(self, user):
|
|
return f" {self.util.get_prof_icon(user.profession)} " \
|
|
f"<{user.faction.lower()}>{user.name}</{user.faction.lower()}>" \
|
|
f" ({user.level}/<green>{user.ai_level}</green>) " \
|
|
f"[<{user.faction.lower()}>{user.org_name}</{user.faction.lower()}>|<cyan>{user.org_rank_name}</cyan>]\n"
|
|
|
|
@event(event_type="private_channel_left", description="Autokick inactive characters")
|
|
def left_channel(self, _1, event_data: server_packets.PrivateChannelClientLeft):
|
|
self.raid_kick_cmd(None, None, self.pork.get_character_info(event_data.char_id), "Left private channel")
|
|
|
|
@command(command="raid", params=[Const("start"), Any("raid_name")],
|
|
description="Start new raid", access_level="leader", sub_command="manage")
|
|
def raid_start_cmd(self, request: CommandRequest, _, raid_name: str):
|
|
if self.raid:
|
|
return "The <highlight>%s</highlight> raid is already running." % self.raid.raid_name
|
|
|
|
self.raid = Raid(raid_name, request.sender)
|
|
|
|
leader_alts = self.account_service.get_alts(request.sender.char_id)
|
|
self.raid.raiders.append(Raider(leader_alts, request.sender.char_id))
|
|
join_link = self.get_raid_join_blob("Click here")
|
|
|
|
msg = "\n" \
|
|
f"<highlight>────────[ Raid starting ]────────</highlight>\n" \
|
|
f"Initiator: <highlight>{request.sender.name}</highlight>\n" \
|
|
f"Raid Name: <highlight>{raid_name}</highlight>\n" \
|
|
f"{join_link} to join\n" \
|
|
f"<highlight>────────[ Raid starting ]────────</highlight>"
|
|
self.leader.leader = None
|
|
self.leader.set_raid_leader(request.sender, request.sender)
|
|
# self.bot.send_org_message(msg)
|
|
self.bot.send_private_channel_message(msg)
|
|
self.account_service.add_log(leader_alts[0].char_id, "raid",
|
|
f"[<notice>STARTED</notice>] Raid with desc: <highlight>{raid_name}</highlight>",
|
|
request.sender.char_id)
|
|
if request.channel == "msg":
|
|
return "You have been set as the <notice>active</notice> Raidleader. " \
|
|
"Set another Raidleader by using <notice>!leader set <name></notice>"
|
|
else:
|
|
return f"{request.sender.name} has been set as the <notice>active</notice> Raidleader automatically."
|
|
|
|
@command(command="raid",
|
|
params=[Const("desc"), Any("description")],
|
|
description="Change the raid description",
|
|
access_level="leader", sub_command="manage")
|
|
def raid_desc_cmd(self, _1, _2, desc):
|
|
if not self.raid:
|
|
return self.NO_RAID_RUNNING_RESPONSE
|
|
else:
|
|
self.raid.desc = desc
|
|
return f"Changed raid description to <highlight>{desc}</highlight> successfully."
|
|
|
|
@command(command="raid",
|
|
params=[Const("level"), Int("level")],
|
|
description="Change the minimum raider level",
|
|
access_level="leader",
|
|
sub_command="manage")
|
|
def raid_level_cmd(self, _1, _2, level):
|
|
if not self.raid:
|
|
return self.NO_RAID_RUNNING_RESPONSE
|
|
else:
|
|
self.raid.level = level
|
|
return f"Changed minimum raider level to <highlight>{level}</highlight> successfully."
|
|
|
|
@command(command="raid",
|
|
params=[Const("add"), Character("character_name")],
|
|
description="add an player to the raid",
|
|
access_level="leader", sub_command="manage")
|
|
def raid_add_cmd(self, request, _, char: SenderObj):
|
|
if not self.raid:
|
|
return self.NO_RAID_RUNNING_RESPONSE
|
|
if not char.char_id:
|
|
return self.getresp("global", "char_not_found", {"char": char.name})
|
|
if not self.private_channel_service.in_private_channel(char.char_id):
|
|
return f"The player <highlight>{char.name}</highlight> is not in my private channel. You cannot add him/her to the raid."
|
|
main_id = self.account_service.get_main(char.char_id).char_id
|
|
in_raid = self.is_in_raid(main_id)
|
|
if in_raid is not None:
|
|
if in_raid.active_id == char.char_id:
|
|
if in_raid.is_active:
|
|
return f"The Character <highlight>{char.name}</highlight> is already participating in the Raid."
|
|
else:
|
|
in_raid.is_active = True
|
|
in_raid.was_kicked = None
|
|
in_raid.was_kicked_reason = None
|
|
in_raid.left_raid = None
|
|
self.account_service.add_log(main_id, "raid",
|
|
f"[<notice>ADD</notice>] Added to the raid by "
|
|
f"<highlight>{request.sender.name}</highlight>",
|
|
request.sender.char_id)
|
|
self.send_raid_msg("<green>READD</green>",
|
|
f"<highlight>{char.name}</highlight> by "
|
|
f"<highlight>{request.sender.name}</highlight>")
|
|
elif in_raid.is_active:
|
|
former_active_name = self.character_service.resolve_char_to_name(in_raid.active_id)
|
|
return f"<highlight>{char.name}</highlight> is already participating in the raid with the char " \
|
|
f"<highlight>{former_active_name}</highlight>"
|
|
else:
|
|
alts = self.account_service.get_alts(char.char_id)
|
|
self.raid.raiders.append(Raider(alts, char.char_id))
|
|
self.account_service.add_log(main_id, "raid", f"[<notice>ADD</notice>] Added to the raid by "
|
|
f"<highlight>{request.sender.name}</highlight>",
|
|
request.sender.char_id)
|
|
self.send_raid_msg("<green>ADD</green>", f"<highlight>{char.name}</highlight> by "
|
|
f"<highlight>{request.sender.name}</highlight>")
|
|
|
|
@command(command="raid", params=[Const("join")], description="Join the ongoing raid", access_level="member")
|
|
def raid_join_cmd(self, request, _):
|
|
if not self.raid:
|
|
return self.NO_RAID_RUNNING_RESPONSE
|
|
if not self.private_channel_service.in_private_channel(request.sender.char_id):
|
|
return "You are not in my private channel. you cant join the raid."
|
|
main_id = self.account_service.get_main(request.sender.char_id).char_id
|
|
in_raid = self.is_in_raid(main_id)
|
|
user = self.pork.get_character_info(request.sender.char_id)
|
|
if user.level < self.raid.level:
|
|
return f"You need to be at least level <highlight>{self.raid.level}</highlight> " \
|
|
f"to participate in this raid."
|
|
if in_raid is not None:
|
|
if in_raid.active_id == request.sender.char_id:
|
|
if in_raid.is_active:
|
|
return "You are already participating in the raid."
|
|
else:
|
|
if not self.raid.is_open:
|
|
return "Raid is closed."
|
|
in_raid.is_active = True
|
|
in_raid.was_kicked = None
|
|
in_raid.was_kicked_reason = None
|
|
in_raid.left_raid = None
|
|
self.account_service.add_log(main_id, "raid", f"[<notice>JOIN</notice>] Raid: "
|
|
f"<highlight>{self.raid.raid_name}</highlight>",
|
|
request.sender.char_id)
|
|
self.send_raid_msg("<green>REJOIN</green>", f"<green>{request.sender.name}</green>")
|
|
|
|
elif in_raid.is_active:
|
|
former_active_name = self.character_service.resolve_char_to_name(in_raid.active_id)
|
|
in_raid.active_id = request.sender.char_id
|
|
self.account_service.add_log(main_id, "raid", f"[<notice>JOIN</notice>] Raid: "
|
|
f"<highlight>{self.raid.raid_name}</highlight>",
|
|
request.sender.char_id)
|
|
self.send_raid_msg("<green>ALT</green>", f"<highlight>{request.sender.name}</highlight> "
|
|
f"[before: <highlight>{former_active_name}</highlight>]")
|
|
|
|
elif not in_raid.is_active:
|
|
if not self.raid.is_open:
|
|
return "Raid is closed."
|
|
former_active_name = self.character_service.resolve_char_to_name(in_raid.active_id)
|
|
in_raid.active_id = request.sender.char_id
|
|
in_raid.was_kicked = None
|
|
in_raid.was_kicked_reason = None
|
|
in_raid.left_raid = None
|
|
self.account_service.add_log(main_id, "raid",
|
|
f"[<notice>JOIN</notice>] Raid: "
|
|
f"<highlight>{self.raid.raid_name}</highlight>",
|
|
request.sender.char_id)
|
|
self.send_raid_msg("<green>ALT</green>", f"<highlight>{request.sender.name}</highlight> "
|
|
f"[before: <highlight>{former_active_name}</highlight>]")
|
|
|
|
elif self.raid.is_open:
|
|
alts = self.account_service.get_alts(request.sender.char_id)
|
|
self.raid.raiders.append(Raider(alts, request.sender.char_id))
|
|
self.account_service.add_log(main_id, "raid",
|
|
f"[<notice>JOIN</notice>] Raid: <highlight>{self.raid.raid_name}</highlight>",
|
|
request.sender.char_id)
|
|
self.send_raid_msg("<green>JOIN</green>", f"<green>{request.sender.name}</green>")
|
|
|
|
# self.bot.send_private_channel_message("<highlight>%s</highlight> joined the raid." % request.sender.name)
|
|
else:
|
|
return "Raid is closed."
|
|
|
|
@command(command="raid", params=[Const("leave")], description="Leave the ongoing raid", access_level="member")
|
|
def raid_leave_cmd(self, request, _):
|
|
main = self.account_service.get_main(request.sender.char_id).char_id
|
|
in_raid = self.is_in_raid(main)
|
|
if in_raid:
|
|
if not in_raid.is_active:
|
|
return "You are not active in the raid."
|
|
|
|
in_raid.is_active = False
|
|
in_raid.left_raid = int(time.time())
|
|
self.account_service.add_log(main, "raid",
|
|
f"[<notice>LEAVE</notice>] Raid: <highlight>{self.raid.raid_name}</highlight>",
|
|
request.sender.char_id)
|
|
self.send_raid_msg("<red>LEAVE</red>", f"<red>{request.sender.name}</red>")
|
|
# self.bot.send_private_channel_message("<highlight>%s</highlight> left the raid." % request.sender.name)
|
|
else:
|
|
return "You are not in the raid."
|
|
|
|
@command(command="raid",
|
|
params=[Const("addpts")],
|
|
description="Show Presets for adding points",
|
|
access_level="leader",
|
|
sub_command="manage")
|
|
def points_presets_cmd(self, request, _):
|
|
return ChatBlob("PTS Presets", self.preset_controller.build_preset_list)
|
|
|
|
@command(command="raid",
|
|
params=[Const("addpts"), Any("name")],
|
|
description="Add points to all active participants",
|
|
access_level="leader",
|
|
sub_command="manage")
|
|
def points_add_cmd(self, request, _, name: str):
|
|
if not self.raid:
|
|
return self.NO_RAID_RUNNING_RESPONSE
|
|
|
|
preset = self.db.query_single("SELECT * FROM points_presets WHERE name = ?", [name])
|
|
if not preset:
|
|
return ChatBlob("No such preset - see list of presets", self.preset_controller.build_preset_list)
|
|
count = 0
|
|
|
|
for raider in self.raid.raiders:
|
|
current_points = self.account_service.get_account(raider.main_id)
|
|
if raider.is_active:
|
|
if current_points and current_points.disabled == 0:
|
|
self.account_service.add_pts(raider.main_id,
|
|
preset.points,
|
|
f"{preset.name}",
|
|
request.sender.char_id)
|
|
raider.accumulated_points += preset.points
|
|
count += 1
|
|
self.bot.send_private_channel_message(f"<highlight>{preset.points}</highlight> points added "
|
|
f"to all active raiders (<highlight>{count}</highlight>).")
|
|
|
|
@command(command="raid", params=[Const("check")], description="Get a list of raiders to do active check",
|
|
access_level="leader", sub_command="manage")
|
|
def raid_active_cmd(self, _1, _):
|
|
if not self.raid:
|
|
return self.NO_RAID_RUNNING_RESPONSE
|
|
|
|
blob = ""
|
|
raider_names = []
|
|
for raider in self.raid.raiders:
|
|
if not raider.is_active:
|
|
continue
|
|
raider_name = self.character_service.resolve_char_to_name(raider.active_id)
|
|
akick_link = self.text.make_chatcmd("Active kick", f"/tell <myname> raid kick {raider.main_id} inactive")
|
|
warn_link = self.text.make_chatcmd("Warn",
|
|
f"/tell <myname> cmd {raider_name} missed active check, "
|
|
f"please give notice.")
|
|
blob += f"<highlight>{raider_name}</highlight> [{akick_link}] [{warn_link}]\n"
|
|
raider_names.append(raider_name)
|
|
active_check_names = "/assist "
|
|
active_check_names += "\\n /assist ".join(raider_names)
|
|
blob += "[<a href='chatcmd://%s'>Active check</a>]\n\n" % active_check_names
|
|
raider_names.clear()
|
|
return ChatBlob("Active check", blob)
|
|
|
|
@command(command="raid", params=[Const("list")], description="Get a list if (in)active raiders.",
|
|
access_level="leader", sub_command="manage")
|
|
def raid_check_cmd(self, _1, _):
|
|
if not self.raid:
|
|
return self.NO_RAID_RUNNING_RESPONSE
|
|
|
|
raiders = {}
|
|
o = self.online.online_display.get_online_players("ORDER BY p.profession, p.name", "", [self.bot.get_char_name(), self.bot.get_char_id()])
|
|
users = []
|
|
for x in self.raid.raiders:
|
|
if x.is_active:
|
|
users.append(self.character_service.resolve_char_to_name(x.active_id))
|
|
|
|
for x in o:
|
|
if x.channel_id not in [1, 2, 4] and x.name not in users:
|
|
continue
|
|
if x.name in raiders.keys():
|
|
if raiders[x.name].channel_id < x.channel_id:
|
|
continue
|
|
raiders[x.name] = x
|
|
if x.name in users:
|
|
raiders[x.name].update({'in_raid': True})
|
|
else:
|
|
raiders[x.name].update({'in_raid': False})
|
|
|
|
raiders = DictObject(raiders)
|
|
blob = ""
|
|
for name, raider in raiders.items():
|
|
if not raider.in_raid and raider.channel_id > 2:
|
|
continue
|
|
entry = f"{self.util.get_prof_icon(raider.profession)} " \
|
|
f"{self.text.zfill(raider.level, 220)}/<green>{self.text.zfill(raider.ai_level, 30)}</green> " \
|
|
f"{raider.name} [<highlight>{raider.main_name or raider.name}</highlight>] - " \
|
|
f"{'<green>In Raid</green>' if raider.in_raid else '<red>Not in Raid</red>'}"
|
|
if raider.in_raid:
|
|
entry += f" - [{self.text.make_tellcmd('Kick', f'raid kick {raider.name} <no reason given>')}]"
|
|
else:
|
|
entry += f" - [{self.text.make_tellcmd('Add', f'raid add {raider.name}')}]"
|
|
blob += f"{entry}\n"
|
|
return ChatBlob("Raid list", blob)
|
|
|
|
@command(command="raid", params=[Const("kick"), Character("char"), Any("reason")],
|
|
description="Set raider as kicked with a reason", access_level="leader", sub_command="manage")
|
|
def raid_kick_cmd(self, request, _2, char: SenderObj, reason: str):
|
|
if self.raid is None:
|
|
return self.NO_RAID_RUNNING_RESPONSE
|
|
if not char.char_id:
|
|
return self.getresp("global", "char_not_found", {"char": char.name})
|
|
main_id = self.account_service.get_main(char.char_id).char_id
|
|
in_raid = self.is_in_raid(main_id)
|
|
|
|
if in_raid is not None:
|
|
if not in_raid.is_active:
|
|
return f"<highlight>{char.name}</highlight> is not an active participant of the raid."
|
|
|
|
in_raid.is_active = False
|
|
in_raid.was_kicked = int(time.time())
|
|
in_raid.was_kicked_reason = reason
|
|
name = self.character_service.resolve_char_to_name(in_raid.active_id)
|
|
if request:
|
|
self.account_service.add_log(main_id, "raid", f"[<notice>KICKED</notice>] by "
|
|
f"<highlight>{request.sender.name}</highlight> "
|
|
f"for {reason}",
|
|
request.sender.char_id)
|
|
self.account_service.add_log(self.account_service.get_main(request.sender.char_id).char_id, "raid",
|
|
f"[<notice>KICKED</notice>] <highlight>{char.name}</highlight> "
|
|
f"for {reason}",
|
|
request.sender.char_id)
|
|
else:
|
|
self.account_service.add_log(main_id, "raid",
|
|
f"[<notice>KICKED</notice>] by "
|
|
f"<highlight>{self.bot.get_char_name()}</highlight> for {reason}",
|
|
self.bot.get_char_id())
|
|
self.send_raid_msg("KICKED", f"<highlight>{name}</highlight> for: <notice>{reason}</notice>")
|
|
else:
|
|
return f"<highlight>{char.name}</highlight> is not participating."
|
|
|
|
@command(command="raid",
|
|
params=[Options(["unlock", "open", "lock", "close"])],
|
|
description="Open/close raid for new participants",
|
|
access_level="leader",
|
|
sub_command="manage")
|
|
def raid_open_close_cmd(self, request, action):
|
|
if not self.raid:
|
|
return self.NO_RAID_RUNNING_RESPONSE
|
|
|
|
if action in ["unlock", "open"]:
|
|
if self.raid.is_open:
|
|
return "Raid is already open."
|
|
self.raid.is_open = True
|
|
self.send_raid_msg("<green>unlocked</green>", f"by <highlight>{request.sender.name}</highlight>")
|
|
return
|
|
elif action in ["lock", "close"]:
|
|
if self.raid.is_open:
|
|
self.raid.is_open = False
|
|
self.send_raid_msg("<red>locked</red>", f"by <highlight>{request.sender.name}</highlight>")
|
|
|
|
return
|
|
return "Raid is already closed."
|
|
|
|
@command(command="raid",
|
|
params=[Options(["save", "end", "stop"])],
|
|
description="Save and log running raid",
|
|
access_level="leader",
|
|
sub_command="manage")
|
|
def raid_save_cmd(self, _1, _2):
|
|
if not self.raid:
|
|
return self.NO_RAID_RUNNING_RESPONSE
|
|
|
|
sql = "INSERT INTO raid_log (raid_name, started_by, raid_start, raid_end) VALUES (?,?,?,?)"
|
|
num_rows = self.db.exec(sql, [self.raid.raid_name,
|
|
self.raid.started_by.char_id,
|
|
self.raid.started_at,
|
|
int(time.time())])
|
|
if num_rows > 0:
|
|
raid_id = self.db.query_single("SELECT raid_id FROM raid_log ORDER BY raid_id DESC LIMIT 1").raid_id
|
|
|
|
for raider in self.raid.raiders:
|
|
sql = "INSERT INTO raid_log_participants (" \
|
|
"raid_id, raider_id, accumulated_points, " \
|
|
"left_raid, was_kicked, was_kicked_reason" \
|
|
") " \
|
|
"VALUES (?,?,?,?,?,?)"
|
|
self.db.exec(sql, [raid_id, raider.active_id,
|
|
raider.accumulated_points,
|
|
raider.left_raid,
|
|
raider.was_kicked,
|
|
raider.was_kicked_reason])
|
|
|
|
self.raid = None
|
|
self.leader.set_raid_leader(self.leader.leader, None)
|
|
return "Raid has ended, logs got saved. <notice>Raidleader cleared.</notice>"
|
|
|
|
else:
|
|
return "Failed to end raid. Try again."
|
|
|
|
@command(command="raid", params=[Const("logentry"), Int("raid_id"), Character("char", is_optional=True)],
|
|
description="Show log entry for raid, with possibility of narrowing down the log for character in raid",
|
|
access_level="member")
|
|
def raid_log_entry_cmd(self, _1, _2, raid_id: int, char: SenderObj):
|
|
log_entry_spec = None
|
|
if char:
|
|
sql = "SELECT * FROM raid_log r " \
|
|
"LEFT JOIN raid_log_participants p ON r.raid_id = p.raid_id " \
|
|
"WHERE r.raid_id = ? AND p.raider_id = ?"
|
|
log_entry_spec = self.db.query_single(sql, [raid_id, char.char_id])
|
|
|
|
sql = "SELECT * FROM raid_log r " \
|
|
"LEFT JOIN raid_log_participants p ON r.raid_id = p.raid_id " \
|
|
"WHERE r.raid_id = ? ORDER BY p.accumulated_points DESC"
|
|
log_entry = self.db.query(sql, [raid_id])
|
|
pts_sum = self.db.query_single("SELECT SUM(p.accumulated_points) AS sum FROM raid_log_participants p "
|
|
"WHERE p.raid_id = ?", [raid_id]).sum
|
|
|
|
if not log_entry:
|
|
return "No such log entry."
|
|
|
|
blob = f"Raid name: <highlight>{log_entry[0].raid_name}</highlight>\n"
|
|
blob += f"Started by: <highlight>{self.character_service.resolve_char_to_name(log_entry[0].started_by)}</highlight>\n"
|
|
blob += f"Start time: <highlight>{self.util.format_datetime(log_entry[0].raid_start)}</highlight>\n"
|
|
blob += f"End time: <highlight>{self.util.format_datetime(log_entry[0].raid_end)}</highlight>\n"
|
|
blob += f"Run time: " \
|
|
f"<highlight>{self.util.time_to_readable(log_entry[0].raid_end - log_entry[0].raid_start)}</highlight>\n"
|
|
blob += f"Total points: <highlight>{pts_sum}</highlight>\n\n"
|
|
|
|
if char and log_entry_spec:
|
|
raider_name = self.character_service.resolve_char_to_name(log_entry_spec.raider_id)
|
|
main_info = self.account_service.get_main(log_entry_spec.raider_id)
|
|
alt_link = f"Alt of {main_info.name}" if main_info.char_id != log_entry_spec.raider_id else "Alts"
|
|
alt_link = self.text.make_chatcmd(alt_link, f"/tell <myname> alts {main_info.name}")
|
|
blob += f"<header2>Log entry for {raider_name}</header2>\n"
|
|
blob += f"Raider: <highlight>{raider_name}</highlight> [{alt_link}]\n"
|
|
blob += "Left raid: %s\n" % ("n/a"
|
|
if log_entry_spec.left_raid is None
|
|
else self.util.format_datetime(log_entry_spec.left_raid))
|
|
blob += "Was kicked: %s\n" % ("No"
|
|
if log_entry_spec.was_kicked is None
|
|
else f"Yes [{self.util.format_datetime(log_entry_spec.was_kicked)}]")
|
|
blob += "Kick reason: %s\n\n" % ("n/a"
|
|
if log_entry_spec.was_kicked_reason is None
|
|
else log_entry_spec.was_kicked_reason)
|
|
|
|
blob += "<header2>Participants</header2>\n"
|
|
for raider in log_entry:
|
|
raider_name = self.character_service.resolve_char_to_name(raider.raider_id)
|
|
main_info = self.account_service.get_main(raider.raider_id)
|
|
alt_link = "Alt of %s" % main_info.name if main_info.char_id != raider.raider_id else "Alts"
|
|
alt_link = self.text.make_chatcmd(alt_link, "/tell <myname> alts %s" % main_info.name)
|
|
log_link = self.text.make_chatcmd("Log", "/tell <myname> raid logentry %d %s" % (raid_id, raider_name))
|
|
account_link = self.text.make_chatcmd("Account", "/tell <myname> account %s" % raider_name)
|
|
blob += f"{raider_name} - {raider.accumulated_points:d} points earned " \
|
|
f"[{log_link}] [{account_link}] [{alt_link}]\n"
|
|
|
|
log_entry_reference = "the raid %s" % log_entry[0].raid_name \
|
|
if char is None \
|
|
else "%s in raid %s" \
|
|
% (self.character_service.resolve_char_to_name(char.char_id), log_entry[0].raid_name)
|
|
return ChatBlob("Log entry for %s" % log_entry_reference, blob)
|
|
|
|
@command(command="raid", params=[Const("history")], description="Show a list of recent raids",
|
|
access_level="member")
|
|
def raid_history_cmd(self, _1, _2):
|
|
sql = "SELECT * FROM raid_log ORDER BY raid_end DESC LIMIT 30"
|
|
raids = self.db.query(sql)
|
|
|
|
blob = ""
|
|
for raid in raids:
|
|
participant_link = self.text.make_chatcmd("Log", "/tell <myname> raid logentry %d" % raid.raid_id)
|
|
timestamp = self.util.format_datetime(raid.raid_start)
|
|
leader_name = self.character_service.resolve_char_to_name(raid.started_by)
|
|
blob += f"[{raid.raid_id:d}] [{timestamp}] <highlight>{raid.raid_name}</highlight> " \
|
|
f"started by <highlight>{leader_name}</highlight> [{participant_link}]\n"
|
|
|
|
return ChatBlob("Raid history", blob)
|
|
|
|
def is_in_raid(self, main_id: int) -> Union[bool, Raider]:
|
|
if self.raid is None:
|
|
return True
|
|
|
|
for raider in self.raid.raiders:
|
|
if raider.main_id == main_id:
|
|
return raider
|
|
|
|
def send_raid_msg(self, msg_type, msg):
|
|
self.bot.send_private_channel_message(f"[<notice>Raid: {msg_type}</notice>] {msg}")
|
|
|
|
def get_raid_join_blob(self, link_txt: str):
|
|
blob = "<header2>1. Join the raid</header2>\n" \
|
|
"To join the current raid <highlight>%s</highlight>, send the following tell to <myname>\n" \
|
|
"<tab><tab><a href='chatcmd:///tell <myname> <symbol>raid join'>/tell <myname> raid join</a>\n" \
|
|
"\n" \
|
|
"<header2>2. Enable LFT</header2>\n" \
|
|
"When you have joined the raid, go lft with \"<myname>\" as description\n" \
|
|
"<tab><tab><a href='chatcmd:///lft <font color=#FFFF00>» <myname></font>'>/lft <myname></a>\n" \
|
|
"\n" \
|
|
"<header2>3. Announce</header2>\n" \
|
|
"You could announce to the raid leader, that you have enabled LFT\n" \
|
|
"<tab><tab><a href='chatcmd:///group <myname> I am on lft'>Announce</a> that you have enabled lft\n" \
|
|
"\n" \
|
|
"<header2>4. Rally with yer mateys</header2>\n" \
|
|
"Finally, move towards the starting location of the raid.\n" \
|
|
"<highlight>Ask for help</highlight> if you're in doubt of where to go." % self.raid.raid_name
|
|
|
|
return self.text.paginate_single(ChatBlob(link_txt, blob))
|
|
|
|
@timerevent(budatime="5m", description="announce raid")
|
|
def announce_raid(self, event_type, event_data):
|
|
if self.raid:
|
|
if self.raid.is_open:
|
|
self.bot.send_private_channel_message(f"<highlight>Raid Running</highlight> "
|
|
f"<yellow>::</yellow> <green>{self.raid.desc}</green> <yellow>::</yellow> %s" %
|
|
(
|
|
f"<a href=\"text://{self.raid.raid_name}\">"
|
|
f"{self.get_raid_join_blob('Click to Join')}"
|
|
f"</a>"))
|
|
else:
|
|
self.bot.send_private_channel_message("<highlight>Raid Running</highlight> <yellow>::</yellow> <green>%s</green> "
|
|
"<yellow>::</yellow> <red>Closed</red>" % self.raid.desc)
|
|
|
|
@timerevent(budatime="1m", description="No leader reminder")
|
|
def leader_auto_remove(self, _1, _2):
|
|
if self.raid:
|
|
leader = self.leader.leader
|
|
if not leader:
|
|
self.bot.send_private_channel_message(f"<red>::</red> No Leader set <red>::</red> "
|
|
f"use <highlight>!leader set</highlight>")
|
|
return
|
|
account = self.account_service.get_account(leader.char_id)
|
|
if not self.is_in_raid(account.main):
|
|
self.bot.send_private_channel_message(f"<red>::</red> Raidleader <highlight>{leader.name}</highlight> "
|
|
f"is not in raid <red>::</red>")
|