-> !wants
-> !orgs info
-> special cmd's
-> !assist
-> "afk" for players without active account
-> !loot add <item_ref> <count> => nolonger breaks !account
Changes:
-> grouped !tara, !gaunt, .. into !wb
-> Display the most recent news entry on logon (default: enabled)
-> improved grouping of !items
-> Added the option to authentificate WS connections (Datanet module). This is used in special cases, where the Websocket Server requires the clien tto authentificate itself. (Server sends "#auth", client responds with the auth string)
-> Add main name to relaying (priv <-> org) [default: disabled]
-> Added logon/logoff messages back
-> restricted default access to "dangerous" commands to moderator
-> Added optional logging (Private Channel, Org Channel, Tells, ... disabled by default)

Rewrite of the Tower Module.
-> More verbosity, if enabled in config. by default, GAS and Hot timer only.
-> !hot displays currently hot (and in penalty) sites, and these which go hot in < 60 minutes
-> !attacks filterable by PF and Site
-> display current contract QL's grouped by org: !contracts (requires managed cache)
This commit is contained in:
2021-11-25 14:09:43 +01:00
parent 2d7ecf4883
commit 17c776faec
44 changed files with 1669 additions and 1249 deletions
+67 -45
View File
@@ -1,31 +1,30 @@
import time
from core.chat_blob import ChatBlob
from core.command_alias_service import CommandAliasService
from core.command_param_types import Any
from core.decorators import instance, command, event
from core.dict_object import DictObject
from core.igncore import IgnCore
from core.job_scheduler import JobScheduler
from core.logger import Logger
from core.setting_service import SettingService
from core.setting_types import BooleanSettingType
from core.text import Text
from core.igncore import IgnCore
from core.util import Util
from modules.standard.datanet.ws_controller import WebsocketRelayController
@instance()
class WorldBossController:
# Timers are provided through an local websocket relay, which gets fed by an external API;
# If you intend to take advantage of this module,
# you **will** need to contact the API host of your choice to whitelist
# The IP Addresses with which you intend to access the API.
# Timers are provided through a local websocket relay, which gets fed by an external API.
# example timer data:
# [{"name":"Tarasque","time": <mortal time>},
# {"name":"Vizaresh","time": <mortal time>}]
timer_data = []
alerts = [480 * 60, 360 * 60, 240 * 60, 120 * 60, 60 * 60, 60 * 15,
60 * 5, 60 * 3, 60 * 2, 60, 30, 15, 10, 5, 4, 3, 2, 1, 0]
60 * 5, 60 * 3, 60 * 2, 60, 30, 15, 5, 0]
jobs = []
def inject(self, registry):
@@ -38,25 +37,46 @@ class WorldBossController:
self.setting_service: SettingService = registry.get_instance("setting_service")
def pre_start(self):
self.setting_service.register(self.module_name, 'timer_spam', True, BooleanSettingType(),
"should timers be spammed")
self.setting_service.register(self.module_name, 'timer_spam', False, BooleanSettingType(),
"should timers be spammed")
self.command_alias_service.add_alias("tara", "wb tara")
self.command_alias_service.add_alias("gaunt", "wb gaunt")
self.command_alias_service.add_alias("loren", "wb loren")
self.command_alias_service.add_alias("reaper", "wb reaper")
@event(WebsocketRelayController.WS_RELAY, "save most current timers")
@event(WebsocketRelayController.WS_RELAY, "save most current local_timers")
def get_timer(self, _, data):
if data.type == "timer":
self.timer_data = data.payload
def test(test_data):
if test_data:
if data.type != "timer":
return
local_timers = {}
spam = True if self.setting_service.get_value("timer_spam") == "1" else False
for x in self.timer_data:
local_timers[x['name']] = x['time']
for row in data.payload:
spawn = self.get_spawn(row)
if not spawn:
continue
if row['name'] not in local_timers:
self.timer_data.append(row)
if spam:
for x in self.jobs:
if x['name'] == row['name']:
self.job_scheduler.cancel_job(x['id'])
self.jobs.append(
{'name': row['name'], 'id': self.job_scheduler.delayed_job(self.timer_alert, 2, spawn)})
continue
elif (local_timers[row['name']] + 1) < row['time']:
for timer in self.timer_data:
if timer['name'] == row['name']:
timer['time'] = row['time']
if spam:
for job in self.jobs:
if job["name"] == test_data.name:
return
self.job_scheduler.delayed_job(self.timer_alert, 2, test_data)
if self.setting_service.get_value("timer_spam") == "1":
for row in self.timer_data:
data = self.get_spawn(row)
test(data)
if job['name'] == row['name']:
self.job_scheduler.cancel_job(job['id'])
alert_duration = self.get_next_alert(spawn.at - time.time())
job_id = self.job_scheduler.scheduled_job(self.timer_alert, 2,
spawn)
job['id'] = job_id
def get_spawn(self, timer):
timer = DictObject(timer)
@@ -108,26 +128,26 @@ class WorldBossController:
return duration - alert - 1
return duration
@command(command="gaunt", params=[], description="Displays the next Vizaresh pop time", access_level="member")
def show_gaunt(self, _):
for timer in self.timer_data:
if timer['name'] == "Vizaresh":
return self.show_user(timer)
return "Timer not found"
@command(command="loren", params=[], description="Displays the next Loren Warr pop time", access_level="member")
def show_loren(self, _):
for timer in self.timer_data:
if timer['name'] == "Loren Warr":
return self.show_user(timer)
return "Timer not found"
@command(command="tara", params=[], description="Displays the next Tara pop time", access_level="member")
def show_tara(self, _):
for timer in self.timer_data:
if timer['name'] == "Tarasque":
return self.show_user(timer)
return "Timer not found"
@command(command="wb", params=[Any("worldboss", is_optional=True)],
description="Displays the next worldboss spawns", access_level="member")
def show_worldboss(self, request, boss: str):
if boss:
boss = boss.lower()
if boss in ["tara", "tarasque"]:
boss = "Tarasque"
elif boss in ["viza", "vizaresh", "gaunt", "gauntlet"]:
boss = "Vizaresh"
elif boss in ["loren", "loren warr", "loren war", "lw"]:
boss = "Loren Warr"
elif boss in ["thr", "the hollow", "the hollow reaper", "reaper"]:
boss = "The Hollow Reaper"
for x in self.timer_data:
if x['name'] == boss:
return self.show_user(x)
else:
blob = "\n".join([self.show_user(x) for x in self.timer_data if
self.show_user(x) != "No timers cached; please try again later."])
return ChatBlob("Next Worldboss spawns", blob)
def show_user(self, timer):
timer = self.get_spawn(timer)
@@ -144,7 +164,9 @@ class WorldBossController:
for row in self.timer_data:
if row["name"] == timer.name:
timer = self.get_spawn(row)
alert_duration = self.get_next_alert(timer.at - t)
if not timer.at:
return
alert_duration = self.get_next_alert(timer.at - time.time())
if timer.at - time.time() < 1:
if timer.type == "mortal":
self.send_warn(f"<highlight>{timer.name}</highlight> :: is now mortal")
@@ -152,7 +174,7 @@ class WorldBossController:
elif timer.type == "spawn":
self.send_warn(f"<highlight>{timer.name}</highlight> :: has just spawned")
self.jobs = [x for x in self.jobs if x['name'] != timer.name]
else: # timer.at > time.time():
else:
if timer.type == "mortal":
self.send_warn(f"<highlight>{timer.name}</highlight> :: mortal in {self.util.format_time(timer.time)}")
elif timer.type == "spawn":
@@ -162,7 +184,7 @@ class WorldBossController:
for row in self.timer_data:
if row["name"] == timer.name:
timer = self.get_spawn(row)
job_id = self.job_scheduler.scheduled_job(self.timer_alert, t + alert_duration, timer)
job_id = self.job_scheduler.scheduled_job(self.timer_alert, time.time() + alert_duration, timer)
for job in self.jobs:
if job['name'] == timer.name:
job['id'] = job_id