import time import typing from datetime import datetime from core.aochat.BaseModule import BaseModule from core.buddy_service import BuddyService from core.chat_blob import ChatBlob from core.command_alias_service import CommandAliasService from core.command_param_types import Options, Const from core.db import DB from core.decorators import instance, command, setting from core.job_scheduler import JobScheduler from core.logger import Logger from core.setting_types import TimeSettingType, NumberSettingType from core.text import Text from core.igncore import IgnCore from core.util import Util if typing.TYPE_CHECKING: from core.lookup.pork_service import PorkService from core.setting_service import SettingService from modules.core.accounting.preference_controller import PreferenceController from modules.core.accounting.services.account_service import AccountService from modules.core.ban.ban_service import BanService from modules.core.discord.discord_controller import DiscordController from modules.onlinebot.online.org_alias_controller import OrgAliasController @instance() class WeeklyController(BaseModule): # dates = {"ai": [1618704000, 1619395200], # "bs": [1619913600, 1620604800], # "dio": [1621123200, 1621814400], # } dates = {} duration = 60 * 60 * 24 * 42 # 3628800 def inject(self, registry): self.logger = Logger(__name__) self.bot: IgnCore = registry.get_instance("bot") self.db: DB = registry.get_instance("db") self.text: Text = registry.get_instance("text") self.ban: BanService = registry.get_instance("ban_service") self.util: Util = registry.get_instance("util") self.account_service: AccountService = registry.get_instance("account_service") self.pork: PorkService = registry.get_instance("pork_service") self.org_pork: PorkService = registry.get_instance("org_pork_service") self.command_alias_service: CommandAliasService = registry.get_instance("command_alias_service") self.buddy_service: BuddyService = registry.get_instance("buddy_service") self.setting_service: SettingService = registry.get_instance("setting_service") self.discord: DiscordController = registry.get_instance("discord_controller") self.job_schedule: JobScheduler = registry.get_instance("job_scheduler") self.preferences: PreferenceController = registry.get_instance("preference_controller") self.alias_controller: OrgAliasController = registry.get_instance("org_alias_controller") self.account_service: AccountService = registry.get_instance("account_service") def start(self): self.setup_timers(self.weekly_timer().get_value()) @setting("weekly_timer", 1659225600, "Basis timer for ICC Daily calculations") def weekly_timer(self): return NumberSettingType() @command(command="icc", params=[Const("set"), Options(["ai", "bs", "dio"])], description="Adjust the ICC Weekly timer (set currently active week)", access_level="moderator", sub_command="modify") def set_icc_cmd(self, _, _1, daily): # magic numbers: offset = 138240 no_weekly = 518400 daily = daily.lower() timer = time.time() new = (timer//offset) * offset if daily == "ai": pass elif daily == "bs": new -= 14*24*60*60 elif daily == "dio": new -= 2*14*24*60*60 new = int(new) self.setup_timers(new) self.weekly_timer().set_value(new) return f"ICC Weekly timers adjusted. Currently running mission: {daily.upper()}" def setup_timers(self, ai): basis = ai duration = 691200 none = 518400 self.dates.clear() for x in ['ai', 'bs', 'dio']: self.dates[x] = [basis, basis+duration] basis += duration+none @command(command="icc", params=[], description="ICC Weekly", access_level="member") def show_raids(self, _): events = [self.get_next_bs(), self.get_next_ai(), self.get_next_dio()] events = sorted(events, key=lambda event: event.start) current = "None" if events[0].is_running(): current = self.get_long_name(events[0].type) + \ f' [Ends in {self.util.time_to_readable(events[0].end - time.time())}]' blob = "" \ f"Current Mission: {current}\n" \ f"\n" \ f"Planned:\n" for i in events: blob += self.format_entry(i) return ChatBlob("ICC Weekly Missions", blob) # noinspection PyShadowingNames def time_to_readable(self, time): return datetime.utcfromtimestamp(time).strftime("%d.%m.%Y") def format_entry(self, event): return f"{self.get_long_name(event.type)}: {self.time_to_readable(event.start)} " \ f"-> {self.time_to_readable(event.end - 1)}\n" if not event.is_running() else "" def get_long_name(self, event_type): return {"ai": "Alien Weekly", "bs": "Battlestation Weekly", "dio": "Dust it Off Weekly"}.get(event_type) def get_next_event(self, event_type, now): cycle = (now - self.dates[event_type][0]) / self.duration cycle = round(cycle) event = WeeklyEvent(event_type, self.dates[event_type][0] + cycle * self.duration, self.dates[event_type][1] + cycle * self.duration) if event.end <= now: event.start += self.duration event.end += self.duration return event def get_next_dio(self, when=0): when = time.time() if when == 0 else when return self.get_next_event("dio", when) def get_next_bs(self, when=0): when = time.time() if when == 0 else when return self.get_next_event("bs", when) def get_next_ai(self, when=0): when = time.time() if when == 0 else when return self.get_next_event("ai", when) class WeeklyEvent: start = 0 end = 0 type = "" def __init__(self, event_type, start, end): self.start = start self.end = end self.type = event_type def is_running(self, when=0): when = time.time() if when == 0 else when return self.start <= when <= self.end