Files
igncore/modules/raidbot/raid/raidbot_controller.py
T
Minidodo 810c2c8c4d Fix for mrelay - some bots are sending malformed messages, caused by wrong usage of their modules.
Accessing an external service through the bot for gathering tower data is nolonger supported; and should be done via external scripts.
Fix for callers, and missing alias'es for loot tables.
!accounts will only show mains now.
the character order of all alt lists has been reversed: [main] high => low instead of [main] low => high
!account add <name> also marks accounts as type 0, if an account gets re-enabled. might cause strange behaviour with member-logs, if used in onlinebots.
Member type is being displayed in !account now. [Member (X)]
2021-09-19 14:09:44 +02:00

601 lines
32 KiB
Python

import time
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.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.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")
def pre_start(self):
self.event_service.register_event_type("RAID_END")
@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}<end>\n"
blob += f"Minimum Level: <highlight>{self.raid.level}</highlight>\n"
blob += f"Started By: <highlight>{self.raid.started_by.name}<end>\n"
blob += f"Raidleader: " \
f"<highlight>" \
f"{self.leader.leader.name if self.leader.leader else '<red>not set - use !leader set<end>'}" \
f"<end>\n"
blob += f"Started At: <highlight>{self.util.format_datetime(self.raid.started_at)}<end> " \
f"({self.util.time_to_readable(t - self.raid.started_at)} ago)\n"
if self.raid.is_open:
blob += f"Status: <green>Open<end> [{self.text.make_chatcmd('Join', '/tell <myname> raid join')}] " \
f"<red>[{self.text.make_chatcmd('Lock', '/tell <myname> raid lock')}]<end>"
else:
blob += f"Status: <red>Closed<end> " \
f"<green>[{self.text.make_chatcmd('Unlock', '/tell <myname> raid open')}]<end>"
blob += "\n\n"
if self.raid.raid_orders:
blob += "<header2>Orders<end>\n"
blob += self.raid.raid_orders + "\n\n"
blob += "<header2>Raiders<end>\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<end> 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 ]────────<end>\n" \
f"Initiator: <highlight>{request.sender.name}<end>\n" \
f"Raid Name: <highlight>{raid_name}<end>\n" \
f"{join_link} to join\n" \
f"<highlight>────────[ Raid starting ]────────<end>"
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<end> Raidleader. " \
"Set another Raidleader by using <notice>!leader set &lt;name&gt;<end>"
else:
return f"{request.sender.name} has been set as the <notice>active<end> 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. Could not add him."
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}<end> 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}<end> is already participating in the raid with the char " \
f"<highlight>{former_active_name}<end>"
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<end> 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<end> 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 += "<highlight>%s<end> [%s] [%s]\n" % (raider_name, akick_link, warn_link)
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("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 "<highlight>%s<end> is not an active participant of the raid." % char.name
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 "<highlight>%s<end> is not participating." % char.name
@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.<end>"
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}<end>\n"
blob += f"Started by: <highlight>{self.character_service.resolve_char_to_name(log_entry[0].started_by)}<end>\n"
blob += f"Start time: <highlight>{self.util.format_datetime(log_entry[0].raid_start)}<end>\n"
blob += f"End time: <highlight>{self.util.format_datetime(log_entry[0].raid_end)}<end>\n"
blob += f"Run time: " \
f"<highlight>{self.util.time_to_readable(log_entry[0].raid_end - log_entry[0].raid_start)}<end>\n"
blob += f"Total points: <highlight>{pts_sum}<end>\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}<end>\n"
blob += f"Raider: <highlight>{raider_name}<end> [{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<end>\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}<end> " \
f"started by <highlight>{leader_name}<end> [{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<end>\n" \
"To join the current raid <highlight>%s<end>, 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<end>\n" \
"When you have joined the raid, go lft with \"<myname>\" as description\n" \
"<tab><tab><a href='chatcmd:///lft <font color=#FFFF00>» <myname><end>'>/lft <myname></a>\n" \
"\n" \
"<header2>3. Announce<end>\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<end>\n" \
"Finally, move towards the starting location of the raid.\n" \
"<highlight>Ask for help<end> 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<end> "
f"<yellow>::<end> <green>{self.raid.desc}<end> <yellow>::<end> %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<end> <yellow>::<end> <green>%s<end> "
"<yellow>::<end> <red>Closed<end>" % 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>")