import time
from core.command_alias_service import CommandAliasService
from core.command_param_types import Const, Character, Options
from core.db import DB
from core.decorators import instance, command, timerevent, event
from core.lookup.character_service import CharacterService
from core.private_channel_service import PrivateChannelService
from core.setting_service import SettingService
from core.setting_types import ColorSettingType, BooleanSettingType
from core.text import Text
from core.igncore import IgnCore
from modules.core.accounting.services.access_service import AccessService
@instance()
class LeaderController:
NOT_LEADER_MSG = "Error! You must be raid leader, or have higher access " \
"level than the raid leader to use this command."
def __init__(self):
self.leader = None
self.last_activity = None
self.echo = False
def inject(self, registry):
self.db: DB = registry.get_instance("db")
self.text: Text = registry.get_instance("text")
self.access_service: AccessService = registry.get_instance("access_service")
self.character_service: CharacterService = registry.get_instance("character_service")
self.bot: IgnCore = registry.get_instance("bot")
self.setting_service: SettingService = registry.get_instance("setting_service")
self.command_alias_service: CommandAliasService = registry.get_instance("command_alias_service")
def pre_start(self):
self.command_alias_service.add_alias("repeat", "leader echo")
self.setting_service.register(self.module_name, "leader_echo_color", "#00FF00", ColorSettingType(),
"Color with which the leader's messages will be echoed with")
self.setting_service.register(self.module_name, "leader_auto_echo", True, BooleanSettingType(),
"If turned on, when someone assume the leader role, "
"leader echo will automatically be activated for said person")
@command(command="leader", params=[], access_level="member",
description="Show the current raid leader")
def leader_show_command(self, _):
if self.leader:
return "The current raid leader is {leader}.".format(leader=self.leader.name)
else:
return "There is no current raid leader. Use leader set to become the raid leader."
@command(command="leader", params=[Const("echo"), Options(["on", "off"])], access_level="leader",
description="Echo whatever the current leader types in channel, in a distinctive color", sub_command="mgn")
def leader_echo_command(self, request, _2, switch_to):
if self.leader:
if self.can_use_command(request.sender.char_id):
self.echo = switch_to == "on"
return f"Raidleader echo for {self.leader.name} has been turned " \
f"{switch_to}."
else:
return "Insufficient access level."
elif self.leader is None and switch_to == "on":
return "No current leader set, can't turn on leader echo."
@command(command="leader", params=[Const("echo")], access_level="leader",
description="See the current status for leader echoing", sub_command="mgn")
def leader_echo_status_command(self, _1, _2):
if self.leader:
on_off = "on" if self.echo else "off"
return f"{self.leader.name} is set as leader, leader echo is {on_off}"
else:
return "No current leader set, echo is off."
@command(command="leader", params=[Const("clear")], access_level="leader",
description="Clear the current raid leader", sub_command="mgn")
def leader_clear_command(self, request, _):
return self.set_raid_leader(request.sender, None)
@command(command="leader", params=[Const("set")], access_level="leader", sub_command="mgn",
description="Set (or unset) yourself as raid leader")
def leader_set_self_command(self, request, _):
return self.set_raid_leader(request.sender, request.sender)
@command(command="leader",
params=[Const("set", is_optional=True), Character("character")],
access_level="leader",
sub_command="mgn1",
description="Set another character as raid leader")
def leader_set_other_command(self, request, _, char):
if not char.char_id:
return "Could not find {player}.".format(player=char)
return self.set_raid_leader(request.sender, char)
@timerevent(budatime="15m", description="Remove raid leader if raid leader hasn't been active for more than 1 hour")
def purge_leader_on_inactivity(self, _1, _2):
if self.last_activity:
if self.last_activity - int(time.time()) > 3600:
self.leader = None
self.last_activity = None
self.echo = False
self.bot.send_private_channel_message("Raid leader has been cleared automatically "
"because of inactivity.")
@event(PrivateChannelService.LEFT_PRIVATE_CHANNEL_EVENT, "Remove raid leader if raid leader leaves private channel")
def leader_remove_on_leave_private(self, _, event_data):
if self.leader:
if self.leader.char_id == event_data.char_id:
self.leader = None
self.last_activity = None
self.echo = False
self.bot.send_private_channel_message(
f"{self.character_service.resolve_char_to_name(event_data.char_id)} "
f"left private channel, and has been cleared as raid leader.")
@event(PrivateChannelService.PRIVATE_CHANNEL_MESSAGE_EVENT, "Echo leader messages from private channel",
is_hidden=True)
def leader_echo_private_event(self, _, event_data):
if self.leader and self.echo:
if self.leader.char_id == event_data.char_id:
if self.setting_service.get("symbol").get_value() != event_data.message[0]:
self.leader_echo(event_data.char_id, event_data.message)
def leader_echo(self, char_id, message):
sender = self.character_service.resolve_char_to_name(char_id)
color = self.setting_service.get("leader_echo_color").get_value()
self.bot.send_private_channel_message(f"{sender}: {message}",
fire_outgoing_event=False)
self.activity_done()
def activity_done(self):
self.last_activity = int(time.time())
def can_use_command(self, char_id):
if not self.leader or self.access_service.has_sufficient_access_level(char_id, self.leader.char_id):
self.activity_done()
return True
return False
def set_raid_leader(self, sender, set_to):
if set_to is None:
if not self.leader:
return "There is no current raid leader."
elif self.leader.char_id == sender.char_id:
self.leader = None
self.echo = False
return "You have been removed as raid leader."
elif self.can_use_command(sender.char_id):
old_leader = self.leader
self.leader = None
self.echo = False
self.bot.send_private_message(old_leader.char_id,
f"You have been removed as raid leader "
f"by {sender.name}.")
return f"You have removed {old_leader.name} as raid leader."
else:
return f"You do not have a high enough access level to remove raid leader " \
f"from {self.leader.name}."
elif sender.char_id == set_to.char_id:
if not self.leader:
self.leader = sender
self.echo = self.setting_service.get("leader_auto_echo").get_value()
reply = "You have been set as raid leader."
if self.echo:
reply += " Leader echo is enabled."
return reply
elif self.leader.char_id == sender.char_id:
self.leader = None
self.echo = False
return "You have been removed as raid leader."
elif self.can_use_command(sender.char_id):
old_leader = self.leader
self.leader = sender
self.echo = self.setting_service.get("leader_auto_echo").get_value()
reply = f"{sender.name} has taken raid leader from you."
if self.echo:
reply += " Leader echo is enabled."
self.bot.send_private_message(old_leader.char_id, reply)
reply = f"You have taken raid leader from {old_leader.name}."
if self.echo:
reply += " Leader echo is enabled."
return reply
else:
return f"You do not have a high enough access level to " \
f"take raid leader from {self.leader.name}."
else:
if self.can_use_command(sender.char_id):
self.leader = set_to
self.echo = self.setting_service.get("leader_auto_echo").get_value()
reply = f"{sender.name} has set you as raid leader."
if self.echo:
reply += " Leader echo is enabled."
self.bot.send_private_message(set_to.char_id, reply)
reply = f"{set_to.name} has been set as raid leader by {sender.name}."
if self.echo:
reply += " Leader echo is enabled."
return reply
else:
return f"You do not have a high enough access level to " \
f"take raid leader from {self.leader.name}."