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
+122
View File
@@ -0,0 +1,122 @@
import time
from core.aochat.server_packets import PublicChannelMessage
from core.chat_blob import ChatBlob
from core.conn import Conn
from core.decorators import instance, command, event, timerevent
from core.dict_object import DictObject
from core.sender_obj import SenderObj
@instance()
class CloakController:
MESSAGE_SOURCE = "cloak_reminder"
CLOAK_EVENT = "cloak"
def inject(self, registry):
self.bot = registry.get_instance("bot")
self.db = registry.get_instance("db")
self.util = registry.get_instance("util")
self.character_service = registry.get_instance("character_service")
self.command_alias_service = registry.get_instance("command_alias_service")
self.timer_controller = registry.get_instance("timer_controller", is_optional=True)
self.event_service = registry.get_instance("event_service")
self.access_service = registry.get_instance("access_service")
self.message_hub_service = registry.get_instance("message_hub_service")
def pre_start(self):
self.bot.register_packet_handler(PublicChannelMessage.id, self.handle_public_message)
self.event_service.register_event_type(self.CLOAK_EVENT)
self.message_hub_service.register_message_source(self.MESSAGE_SOURCE)
def start(self):
self.db.exec("CREATE TABLE IF NOT EXISTS cloak_status ("
"char_id INT NOT NULL, "
"action VARCHAR(10) NOT NULL,"
" created_at INT NOT NULL)")
self.command_alias_service.add_alias("city", "cloak")
@command(command="cloak", params=[], access_level="member",
description="Show the current status of the city cloak and the cloak history")
def cloak_show_command(self, request):
data = self.db.query("SELECT c.*, p.name FROM cloak_status c "
"LEFT JOIN player p ON c.char_id = p.char_id "
"ORDER BY created_at DESC LIMIT 20")
if len(data) == 0:
return "Unknown status on cloak."
else:
msg = self.get_cloak_status(data[0])
request.reply(msg)
blob = ""
for row in data:
action = "<green>on</green>" if row.action == "on" else "<orange>off</orange>"
blob += f"{row.name} turned the device {action} at {self.util.format_datetime(row.created_at)}.\n"
return ChatBlob("Cloak History", blob)
@event(event_type=CLOAK_EVENT, description="Record when the city cloak is turned off and on", is_hidden=True)
def city_cloak_event(self, _, event_data):
self.db.exec("INSERT INTO cloak_status (char_id, action, created_at) VALUES (?, ?, ?)",
[event_data.sender.char_id, event_data.action, int(time.time())])
@timerevent(budatime="15m", description="Reminds the players to toggle the cloak")
def cloak_reminder_event(self, _, _1):
data = self.db.query("SELECT c.*, p.name FROM cloak_status c "
"LEFT JOIN player p ON c.char_id = p.char_id "
"ORDER BY created_at DESC LIMIT 1")
for row in data:
one_hour = 3600
t = int(time.time())
time_until_change = row.created_at + one_hour - t
if row.action == "off" and time_until_change <= 0:
time_str = self.util.time_to_readable(t - row.created_at)
msg = "The cloaking device is <orange>disabled</orange> but can be enabled. " \
"<highlight>%s</highlight> disabled it %s ago." % (row.name, time_str)
self.message_hub_service.send_message(self.MESSAGE_SOURCE, None, None, msg)
@event(event_type=CLOAK_EVENT, description="Set a timer for when cloak can be raised and lowered")
def city_cloak_timer_event(self, _, event_data):
if event_data.action == "off":
timer_name = "Raise City Cloak"
elif event_data.action == "on":
timer_name = "Lower City Cloak"
else:
raise Exception(f"Unknown cloak action '{event_data.action}'")
self.timer_controller.add_timer(timer_name, event_data.sender.char_id, "org", int(time.time()), 3600)
def get_cloak_status(self, row):
one_hour = 3600
time_until_change = row.created_at + one_hour - int(time.time())
time_string = self.util.time_to_readable(time_until_change)
if row.action == "off":
if time_until_change <= 0:
msg = "The cloaking device is <orange>disabled</orange>. It is possible to enable it."
else:
msg = f"The cloaking device is <orange>disabled</orange>. It is possible to enable it in {time_string}."
else:
if time_until_change <= 0:
msg = "The cloaking device is <green>enabled</green>. It is possible to disable it."
else:
msg = f"The cloaking device is <green>enabled</green>. It is possible to disable it in {time_string}."
return msg
def handle_public_message(self, conn: Conn, packet: PublicChannelMessage):
if conn.id != "main":
return
extended_message = packet.extended_message
if extended_message and extended_message.category_id == 1001 and extended_message.instance_id == 1:
char_name = extended_message.params[0]
char_id = self.character_service.resolve_char_to_id(char_name)
action = extended_message.params[1]
access_level = self.access_service.get_access_level(char_id)
self.event_service.fire_event(self.CLOAK_EVENT,
DictObject({"sender": SenderObj(char_id, char_name, access_level),
"action": action}))
+37
View File
@@ -0,0 +1,37 @@
from core.command_param_types import Const, Int, Any
from core.decorators import instance, command, event
from modules.standard.online.online_controller import OnlineController
@instance(name="online_controller", override=True)
class OrgOnlineController(OnlineController):
@event(event_type="org_member_logon", description="Change online channel", is_hidden=True)
def org_member_logon(self, _, event_data):
self.awaiting_data.put([event_data, 'org', True])
@event(event_type="org_member_logoff", description="Change online channel", is_hidden=True)
def org_member_logoff(self, _, event_data):
if self.bot.is_ready():
self.awaiting_data.put([event_data, 'org', False])
@command(command="online", params=[Const('all', is_optional=True),
Int("min_level", is_optional=True),
Any("profession", is_optional=True)],
description="shows online players",
access_level="member")
def online_all_cmd(self, request, const_all, min_level, profession):
query = ""
params = [self.bot.name, self.bot.get_char_id()]
if const_all:
query += "and channel_id IN (1, 2, 3) "
else:
query += "and channel_id IN (1, 2) "
if min_level:
query += "and p.level >= ? "
params.append(min_level)
if profession:
query += "and p.profession = ? "
params.append(self.util.get_profession(profession))
blob = self.online_display.format_by_channel_main(query, params)
request.reply(self.online_display.format_blob(blob))
+132
View File
@@ -0,0 +1,132 @@
from core.chat_blob import ChatBlob
from core.db import DB
from core.decorators import instance, event
from core.dict_object import DictObject
from core.logger import Logger
from core.public_channel_service import PublicChannelService
from core.setting_service import SettingService
from core.setting_types import BooleanSettingType
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.orgbot.org.org_roster_controller import OrgRosterController
from modules.standard.online.online_display import OnlineDisplay
@instance()
class OrgChannelController:
MESSAGE_SOURCE = "org_channel"
ORG_CHANNEL_PREFIX = "[<cyan>Org</cyan>]"
def __init__(self):
self.logger = Logger(__name__)
def inject(self, registry):
self.bot: Tyrbot = registry.get_instance("bot")
self.db: DB = registry.get_instance("db")
self.util: Util = registry.get_instance("util")
self.character_service = registry.get_instance("character_service")
self.message_hub_service = registry.get_instance("message_hub_service")
self.setting_service: SettingService = registry.get_instance("setting_service")
self.ban_service = registry.get_instance("ban_service")
self.log_controller = registry.get_instance("log_controller", is_optional=True)
self.online_controller = registry.get_instance("online_controller", is_optional=True)
self.text: Text = registry.get_instance("text")
self.account_service: AccountService = registry.get_instance("account_service")
def pre_start(self):
self.message_hub_service.register_message_source(self.MESSAGE_SOURCE)
def start(self):
self.message_hub_service.register_message_destination(
self.MESSAGE_SOURCE, self.handle_incoming_relay_message,
["private_channel", "discord", "websocket_relay", "tell_relay", "broadcast",
"raffle", "cloak_reminder", "wave_counter", "shutdown_notice", "raid"],
[self.MESSAGE_SOURCE])
self.setting_service.register_new(self.module_name, "prefix_org_priv", True, BooleanSettingType(),
"Should the prefix [org] be displayed in relayed messages")
def handle_incoming_relay_message(self, ctx):
self.bot.send_org_message(ctx.formatted_message, fire_outgoing_event=False)
@event(event_type=PublicChannelService.ORG_CHANNEL_MESSAGE_EVENT,
description="Relay messages from the org channel to the relay hub",
is_hidden=True)
def handle_org_message_event(self, _, event_data):
if event_data.char_id == self.bot.get_char_id() or self.ban_service.get_ban(event_data.char_id):
return
if event_data.extended_message:
message = event_data.extended_message.get_message()
else:
message = event_data.message
if event_data.char_id == 4294967295 or event_data.char_id == 0:
sender = None
formatted_message = "{org} {msg}".format(org=self.ORG_CHANNEL_PREFIX,
msg=message)
else:
char_name = self.character_service.resolve_char_to_name(event_data.char_id)
sender = DictObject({"char_id": event_data.char_id, "name": char_name})
formatted_message = "{org} {char}: {msg}".format(org=self.ORG_CHANNEL_PREFIX,
char=self.text.make_charlink(char_name),
msg=message)
self.message_hub_service.send_message(self.MESSAGE_SOURCE, sender, message, formatted_message)
@event(event_type=OrgRosterController.ORG_MEMBER_LOGON_EVENT, description="Notify when org member logs on")
def org_member_logon_event(self, _, event_data):
if not self.bot.is_ready():
return
main = self.account_service.get_account(event_data.char_info.char_id)
alt = f":: Alt of <highlight>{main.name}</highlight> " if event_data.account else ""
if main.char_id == event_data.char_info.char_id:
alt = ""
logon = f" :: <grey>{event_data.account.logon}<grey>" if event_data.account.logon else ""
msg = f"{self.text.format_char_info(event_data.char_info)} {alt}:: logged <green>on</green>.{logon}"
self.bot.send_org_message(msg, fire_outgoing_event=False)
self.message_hub_service.send_message(self.MESSAGE_SOURCE, None, None, "[<cyan>Org</cyan>] " + msg)
od = OnlineDisplay(self.text, self.util, self.db)
params = [self.bot.name, self.bot.get_char_id()]
self.bot.send_mass_message(event_data.packet.char_id,
od.format_blob(od.format_by_channel_main("and channel_id IN (1, 2) ", params)))
@event(event_type=OrgRosterController.ORG_MEMBER_LOGOFF_EVENT, description="Notify when org member logs off")
def org_member_logoff_event(self, _, event_data):
if not self.bot.is_ready():
return
char_name = self.character_service.resolve_char_to_name(event_data.packet.char_id)
logoff = f" :: <grey>{event_data.account.logon}<grey>" if event_data.account.logon else ""
msg = f"{char_name} logged <red>off</red>.{logoff}"
self.bot.send_org_message(msg, fire_outgoing_event=False)
self.message_hub_service.send_message(self.MESSAGE_SOURCE, None, None, "[<cyan>Org</cyan>] " + msg)
@event(event_type=Tyrbot.OUTGOING_ORG_MESSAGE_EVENT,
description="Relay commands from the org channel to the relay hub",
is_hidden=True)
def outgoing_org_message_event(self, _, event_data):
if isinstance(event_data.message, ChatBlob):
pages = self.text.paginate(ChatBlob(event_data.message.title, event_data.message.msg),
self.setting_service.get("org_channel_max_page_length").get_value())
if len(pages) < 4:
for page in pages:
message = "{org} {message}".format(org=self.ORG_CHANNEL_PREFIX, message=page)
self.message_hub_service.send_message(self.MESSAGE_SOURCE,
None,
page,
message)
else:
message = "{org} {message}".format(org=self.ORG_CHANNEL_PREFIX, message=event_data.message.title)
self.message_hub_service.send_message(self.MESSAGE_SOURCE,
None,
event_data.message.title,
message)
else:
message = "{org} {message}".format(org=self.ORG_CHANNEL_PREFIX, message=event_data.message)
self.message_hub_service.send_message(self.MESSAGE_SOURCE,
None,
event_data.message,
message)
+248
View File
@@ -0,0 +1,248 @@
import json
import time
import requests
from mysql.connector.cursor import CursorBase
from core.buddy_service import BuddyService
from core.cache_service import CacheService
from core.chat_blob import ChatBlob
from core.command_param_types import Int
from core.db import DB
from core.decorators import instance, command, event, timerevent
from core.dict_object import DictObject
from core.event_service import EventService
from core.logger import Logger
from core.lookup.character_service import CharacterService
from core.lookup.org_pork_service import OrgPorkService
from core.lookup.pork_service import PorkService
from core.public_channel_service import PublicChannelService
from core.tyrbot import Tyrbot
from core.util import Util
from modules.core.accounting.services.account_service import AccountService
@instance()
class OrgRosterController:
ORG_BUDDY_TYPE = "org_member"
ORG_ACCESS_LEVEL = "org_member"
MODE_ADD_AUTO = "add_auto"
MODE_REM_AUTO = "rem_auto"
MODE_ADD_MANUAL = "add_manual"
MODE_REM_MANUAL = "rem_manual"
ORG_MEMBER_LOGON_EVENT = "org_member_logon"
ORG_MEMBER_LOGOFF_EVENT = "org_member_logoff"
ORG_MEMBER_REMOVED_EVENT = "org_member_removed"
LEFT_ORG = [508, 45978487508, 45978487]
KICKED_FROM_ORG = [508, 37093479]
INVITED_TO_ORG = [508, 173558247]
KICKED_INACTIVE_FROM_ORG = [508, 20908201]
KICKED_ALIGNMENT_CHANGED = [501, 181448347]
JOINED_ORG = [508, 5146599]
def __init__(self):
self.logger = Logger(__name__)
def inject(self, registry):
self.bot: Tyrbot = registry.get_instance("bot")
self.db: DB = registry.get_instance("db")
self.text = registry.get_instance("text")
self.buddy_service: BuddyService = registry.get_instance("buddy_service")
self.public_channel_service: PublicChannelService = registry.get_instance("public_channel_service")
self.access_service = registry.get_instance("access_service")
self.org_pork_service: OrgPorkService = registry.get_instance("org_pork_service")
self.pork: PorkService = registry.get_instance("pork_service")
self.util: Util = registry.get_instance("util")
self.event_service: EventService = registry.get_instance("event_service")
self.character_service: CharacterService = registry.get_instance("character_service")
self.cache: CacheService = registry.get_instance("cache_service")
self.account_service: AccountService = registry.get_instance("account_service")
def pre_start(self):
self.db.exec("CREATE TABLE IF NOT EXISTS org_activity ("
"id int primary key AUTO_INCREMENT, "
"message varchar(32) NOT NULL, "
"time int not null)")
self.event_service.register_event_type(self.ORG_MEMBER_LOGON_EVENT)
self.event_service.register_event_type(self.ORG_MEMBER_LOGOFF_EVENT)
self.access_service.register_access_level(self.ORG_ACCESS_LEVEL, 60, self.check_org_member)
def check_org_member(self, char_id):
return (self.account_service.get_account(char_id) or {}).get("member", 0) == self.public_channel_service.org_id
@event("connect", "Adds all members to buddylist")
def connect(self, _, _1):
query = self.db.query("SELECT char_id, member from account where member IN (?, 0)",
[self.public_channel_service.org_id])
if query:
for player in query:
if player.member == self.public_channel_service.org_id:
self.buddy_service.add_buddy(player.char_id, "org_member")
else:
self.buddy_service.add_buddy(player.char_id, "member")
@event("buddy_logon", "fire orgmember logon event")
def orgmember_logon(self, _, data):
account = self.account_service.get_entry(data.char_id)
if not account:
return
if account.member == self.public_channel_service.org_id:
self.event_service.fire_event(self.ORG_MEMBER_LOGON_EVENT, DictObject(
{'account': account, 'char_info': self.pork.get_character_info(data.char_id), 'packet': data}))
@event("buddy_logoff", "fire orgmember logoff event")
def orgmember_logoff(self, _, data):
account = self.account_service.get_entry(data.char_id)
if not account:
return
if account.member == self.public_channel_service.org_id:
self.event_service.fire_event(self.ORG_MEMBER_LOGOFF_EVENT,
DictObject({'account': account, 'packet': data}))
@command(command="orgmembers", params=[], access_level="admin",
description="Show the list of org members")
def org_members_cmd(self, _):
data = self.db.query(
"SELECT * from account a left join player p on a.char_id = p.char_id where member=? order by p.name",
[self.public_channel_service.org_id])
blob = ""
for row in data:
blob += f"{self.text.zfill(row.level, 220)}/<green>{self.text.zfill(row.ai_level, 30)}</green> " \
f"{row.name} ({row.org_rank_name})\n"
return ChatBlob(f"Orgmembers ({len(data)})", blob)
@command(command="orgactivity", params=[Int('count', is_optional=True)], access_level="org_member",
description="Show the most recent org activity")
def org_activity(self, _, count):
data = self.db.query("SELECT * from org_activity order by id desc LIMIT ?", [count or 25])
return ChatBlob(f"Recent Activities ({len(data)})", "\n".join(
[f'<grey>[{self.util.format_datetime(x.time)}]</grey> {x.message}' for x in data]))
@timerevent("24h", "Update the orgroster on changes")
def update_roster(self, _, _1):
self.bot.send_org_message("Updating roster...")
cache = self.cache.retrieve('org_roster', f"{self.public_channel_service.org_id}.5.json")
if cache:
if cache.last_modified > time.time() - 16 * 60 * 60:
result = requests.get(self.org_pork_service.get_pork_url(5, self.public_channel_service.org_id)).json()
if result:
self.cache.store('org_roster', f"{self.public_channel_service.org_id}.5.json", json.dumps(result))
else:
result = json.loads(cache.data)
else:
result = json.loads(cache.data)
else:
result = requests.get(self.org_pork_service.get_pork_url(5, self.public_channel_service.org_id)).json()
if result:
self.cache.store('org_roster', f"{self.public_channel_service.org_id}.5.json", json.dumps(result))
data = []
accounts = []
for char_info in result[1]:
data.append((char_info["CHAR_INSTANCE"], char_info["NAME"], char_info["FIRSTNAME"],
char_info["LASTNAME"], char_info["LEVELX"], char_info["BREED"],
char_info["SEX"], result[0]["SIDE_NAME"], char_info["PROF"],
char_info["PROF_TITLE"], char_info["DEFENDER_RANK_TITLE"], char_info["ALIENLEVEL"],
result[0]["ORG_INSTANCE"], result[0]["NAME"], char_info["RANK_TITLE"],
char_info["RANK"], char_info["CHAR_DIMENSION"], char_info["HEADID"],
0, char_info["PVPTITLE"], "roster", int(time.time())))
accounts.append((char_info["CHAR_INSTANCE"], char_info["CHAR_INSTANCE"], result[0]["ORG_INSTANCE"],
time.time(), time.time()))
if buddy := self.buddy_service.get_buddy(char_info['CHAR_INSTANCE']):
if "org_member" in buddy['types']:
continue
self.buddy_service.add_buddy(char_info['CHAR_INSTANCE'], "org_member")
with self.db.lock:
with self.db.pool.get_connection() as conn:
with conn.cursor() as cur:
cur: CursorBase
cur.executemany("INSERT INTO player(char_id, name, first_name, last_name, level, "
"breed, gender, faction, profession, profession_title, ai_rank, "
"ai_level, org_id, org_name, org_rank_name, org_rank_id, dimension, "
"head_id, pvp_rating, pvp_title, source, last_updated) "
"VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) "
"ON DUPLICATE KEY UPDATE first_name=VALUE(first_name), last_name=VALUE(last_name), "
"level=VALUE(level), breed=VALUE(breed), gender=VALUE(gender), "
"faction=VALUE(faction), profession=VALUE(profession), "
"profession_title=VALUE(profession_title), ai_rank=VALUE(ai_rank), "
"ai_level=VALUE(ai_level), org_name=VALUE(org_name), org_id=VALUE(org_id), "
"org_rank_name=VALUE(org_rank_name), org_rank_id=VALUE(org_rank_id), "
"source=VALUE(source), last_updated=VALUE(last_updated)", data)
self.account_service.create_users(accounts)
users = self.db.query('SELECT * from account where member=? and last_updated < ?',
[self.public_channel_service.org_id, time.time() - 23 * 60 * 60])
for user in users:
self.buddy_service.remove_buddy(user.char_id, 'org_member')
cur.execute("UPDATE account set member=-1 where member=? and last_updated < ?",
[self.public_channel_service.org_id, time.time() - 23 * 60 * 60])
cur.execute("UPDATE account set member=-1 where member NOT IN (0, ?, -1)",
[self.public_channel_service.org_id])
conn.commit()
self.bot.send_org_message('Successfully updated the roster.')
@event(PublicChannelService.ORG_MSG_EVENT, "Update org roster when characters join or leave", is_hidden=True)
def org_msg_event(self, _, event_data):
ext_msg = event_data.extended_message
if [ext_msg.category_id, ext_msg.instance_id] == self.LEFT_ORG:
self.process_org_msg(ext_msg.params[0], self.MODE_REM_MANUAL, ext_msg)
elif [ext_msg.category_id, ext_msg.instance_id] == self.KICKED_FROM_ORG:
self.process_org_msg(ext_msg.params[1], self.MODE_REM_MANUAL, ext_msg.params[0])
elif [ext_msg.category_id, ext_msg.instance_id] == self.INVITED_TO_ORG:
self.process_org_msg(ext_msg.params[1], self.MODE_ADD_MANUAL, ext_msg.params[0])
elif [ext_msg.category_id, ext_msg.instance_id] == self.KICKED_INACTIVE_FROM_ORG:
self.process_org_msg(ext_msg.params[1], self.MODE_REM_MANUAL, ext_msg.params[0])
elif [ext_msg.category_id, ext_msg.instance_id] == self.KICKED_ALIGNMENT_CHANGED:
self.process_org_msg(ext_msg.params[0], self.MODE_REM_MANUAL)
elif [ext_msg.category_id, ext_msg.instance_id] == self.JOINED_ORG:
self.process_org_msg(ext_msg.params[0], self.MODE_ADD_MANUAL)
# noinspection SqlInsertValues
self.db.exec("INSERT INTO org_activity (message, time) VALUES(?, ?)", [ext_msg.get_message(), time.time()])
def process_org_msg(self, char_name, new_mode, actee=None):
char_id = self.character_service.resolve_char_to_id(char_name)
org_member = self.get_org_member(char_id)
self.process_update(char_id, org_member.member if org_member else None, new_mode, actee)
def get_org_member(self, char_id):
return self.db.query_single("SELECT char_id, member FROM account WHERE char_id = ?", [char_id])
def process_update(self, char_id, old_mode, new_mode, actee):
if old_mode == new_mode:
return
if new_mode in [self.MODE_REM_MANUAL, self.MODE_REM_AUTO]:
self.bot.send_org_message(f"<highlight>{self.character_service.get_char_name(char_id)}</highlight> "
f"left the org.")
main = self.account_service.get_main(char_id)
self.account_service.add_log(main.char_id, "system", f'Left the org '
f'{self.public_channel_service.get_org_name()} with '
f'{self.character_service.get_char_name(char_id)}',
main.char_id)
self.account_service.create_users(users=[(char_id, char_id, -1, time.time(), time.time())])
self.update_buddylist(char_id, self.MODE_REM_AUTO)
if new_mode in [self.MODE_ADD_MANUAL, self.MODE_ADD_AUTO]:
self.account_service.create_users(users=[(char_id, char_id,
self.public_channel_service.org_id,
time.time(),
time.time())])
main = self.account_service.get_main(char_id)
self.account_service.add_log(char_id, "system", f'Joined the org '
f'{self.public_channel_service.get_org_name()} with '
f'{self.character_service.get_char_name(char_id)}',
main.char_id)
self.bot.send_org_message(f"Please Welcome "
f"<highlight>{self.character_service.get_char_name(char_id)}</highlight>!!! ")
self.update_buddylist(char_id, self.MODE_ADD_AUTO)
def update_buddylist(self, char_id, mode):
if mode in [self.MODE_ADD_MANUAL, self.MODE_ADD_AUTO]:
self.buddy_service.remove_buddy(char_id, "member")
self.buddy_service.add_buddy(char_id, self.ORG_BUDDY_TYPE)
else:
self.buddy_service.remove_buddy(char_id, self.ORG_BUDDY_TYPE)
@@ -0,0 +1,52 @@
from core.decorators import instance, event
from core.public_channel_service import PublicChannelService
@instance()
class WaveCounterController:
MESSAGE_SOURCE = "wave_counter"
CITY_TARGETED = [1001, 3]
ALERT_TIMES = [105, 150, 90, 120, 120, 120, 120, 120, 120]
def __init__(self):
self.current_wave = None
self.scheduled_job_id = None
def inject(self, registry):
self.job_scheduler = registry.get_instance("job_scheduler")
self.message_hub_service = registry.get_instance("message_hub_service")
def pre_start(self):
self.message_hub_service.register_message_source(self.MESSAGE_SOURCE)
@event(event_type=PublicChannelService.ORG_CHANNEL_MESSAGE_EVENT,
description="Start wave counter when city is targeted by aliens")
def check_for_city_raid_start(self, _, event_data):
ext_msg = event_data.extended_message
if ext_msg:
if [ext_msg.category_id, ext_msg.instance_id] == self.CITY_TARGETED:
self.start_counter()
def start_counter(self):
if self.scheduled_job_id:
self.job_scheduler.cancel_job(self.scheduled_job_id)
self.send_message("Wave counter started. <red>DO NOT enter the city!</red>")
self.scheduled_job_id = self.job_scheduler.delayed_job(self.timer_alert, self.ALERT_TIMES[0], 0)
def timer_alert(self, t, wave_number):
wave_number += 1
if wave_number == 9:
self.send_message("General incoming. <red>DO NOT enter the city!</red>")
self.scheduled_job_id = None
else:
self.send_message("Wave <highlight>%d</highlight> incoming. "
"<red>DO NOT enter the city!</red>" % wave_number)
self.scheduled_job_id = self.job_scheduler.scheduled_job(self.timer_alert,
t + self.ALERT_TIMES[wave_number],
wave_number)
def send_message(self, msg):
self.message_hub_service.send_message(self.MESSAGE_SOURCE, None, None, msg)