c04f76c0db
Fixed command & event threading Events are now threaded by event_type (i.e. all buddy_logon events get ran in the same one) Added default preferences Fixed recipe loading for multiple installs (i.e. on different machines)
285 lines
15 KiB
Python
285 lines
15 KiB
Python
import textwrap
|
|
import time
|
|
from datetime import datetime, timezone
|
|
|
|
from core import command_request
|
|
from core.buddy_service import BuddyService
|
|
from core.command_alias_service import CommandAliasService
|
|
from core.command_param_types import Any, Int, Const
|
|
from core.db import DB
|
|
from core.decorators import instance, command, timerevent
|
|
from core.logger import Logger
|
|
from core.lookup.pork_service import PorkService
|
|
from core.private_channel_service import PrivateChannelService
|
|
from core.setting_service import SettingService
|
|
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.core.ban.ban_service import BanService
|
|
|
|
|
|
# noinspection SqlResolve
|
|
|
|
|
|
class Raid:
|
|
leader = {}
|
|
raid_desc = "[No description set]"
|
|
raid_time = "[unknown]"
|
|
min_level = 200
|
|
leader_rank = {}
|
|
last_spam = 0
|
|
last_action = 0
|
|
bot = ""
|
|
|
|
def __init__(self, leader, rank):
|
|
self.leader = leader
|
|
self.leader_rank = rank
|
|
self.last_action = time.time()
|
|
|
|
|
|
# noinspection SqlResolve,DuplicatedCode,PyAttributeOutsideInit
|
|
@instance()
|
|
class RaidController:
|
|
profs = {"Meta-Physicist": 16308, "Adventurer": 84203, "Engineer": 16252, "Soldier": 16237, "Keeper": 84197,
|
|
"Shade": 39290, "Fixer": 16300, "Agent": 16186, "Trader": 117993, "Doctor": 44235, "Enforcer": 100998,
|
|
"Bureaucrat": 16341, "Martial Artist": 16196, "Nano-Technician": 16283}
|
|
legal_bots = ["allianceraid", "aapf", "theallianz", "igncom", "ignraid"]
|
|
|
|
def __init__(self):
|
|
# noinspection PyTypeChecker
|
|
self.raid: Raid = None
|
|
|
|
def inject(self, registry):
|
|
self.logger = Logger(__name__)
|
|
self.bot: Tyrbot = registry.get_instance("bot")
|
|
self.db: DB = registry.get_instance("db")
|
|
self.text: Text = registry.get_instance("text")
|
|
self.util: Util = registry.get_instance("util")
|
|
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.ban: BanService = registry.get_instance("ban_service")
|
|
self.private_channel_service: PrivateChannelService = registry.get_instance("private_channel_service")
|
|
self.account_service: AccountService = registry.get_instance("account_service")
|
|
|
|
@command(command="raid", params=[Const("desc"), Any("<description>")],
|
|
description="Change the title of the Raid", access_level="leader")
|
|
def raid_set_name(self, request: command_request, _, desc):
|
|
if not self.raid:
|
|
return "There's no raid running."
|
|
if request.sender.access_level["level"] <= self.raid.leader_rank:
|
|
self.raid.raid_desc = desc
|
|
self.raid.last_action = time.time()
|
|
return f"Successfully changed the raid description to <highlight>{desc}</highlight>"
|
|
return f"Error! You cant do that. Your accesslevel must be equal or higher than " \
|
|
f"<highlight>{self.raid.leader.name}</highlight>'s rank."
|
|
|
|
@command(command="raid", params=[Const("bot"), Any("<botname>")],
|
|
description="Change the master Raidbot", access_level="leader")
|
|
def raid_set_bot(self, request: command_request, _, bot):
|
|
if not self.raid:
|
|
return "There's no raid running."
|
|
if request.sender.access_level["level"] <= self.raid.leader_rank:
|
|
if bot in self.legal_bots:
|
|
self.raid.bot = bot
|
|
self.raid.last_action = time.time()
|
|
return f"Successfully changed the raidbot to <highlight>{bot}</highlight>"
|
|
else:
|
|
return f"The bot <highlight>{bot}</highlight> is not whitelisted, you cannot use it as a raidbot. "
|
|
return f"Error! You cant do that. Your accesslevel must be equal or higher than " \
|
|
f"<highlight>{self.raid.leader.name}</highlight>'s rank."
|
|
|
|
@command(command="raid", params=[Const("level"), Int("<min_level>")],
|
|
description="Change the minimal level of the Raid", access_level="leader")
|
|
def raid_set_level(self, request: command_request, _, level):
|
|
if not self.raid:
|
|
return "There's no raid running."
|
|
if request.sender.access_level["level"] <= self.raid.leader_rank:
|
|
self.raid.min_level = level
|
|
self.raid.last_action = time.time()
|
|
return f"Successfully changed the minimum raid level to <highlight>{level}</highlight>"
|
|
return f"Error! You cant do that. Your accesslevel must be equal or higher than " \
|
|
f"<highlight>{self.raid.leader.name}</highlight>'s rank."
|
|
|
|
@command(command="raid", params=[Const("time"), Any("<stepping_time>")],
|
|
description="Change the stepping time of the Raid", access_level="leader")
|
|
def raid_set_time(self, request: command_request, _, step):
|
|
if not self.raid:
|
|
return "There's no raid running."
|
|
if request.sender.access_level["level"] <= self.raid.leader_rank:
|
|
self.raid.raid_time = step
|
|
self.raid.last_action = time.time()
|
|
return f"Successfully changed the stepping time to <highlight>{step}</highlight>"
|
|
return f"Error! You cant do that. Your accesslevel must be equal or higher than " \
|
|
f"<highlight>{self.raid.leader.name}</highlight>'s rank."
|
|
|
|
@command(command="raid", params=[Const("start")], description="Start a raid", access_level="leader")
|
|
def raid_start(self, request: command_request, _):
|
|
if self.raid:
|
|
return "There's already a raid running."
|
|
self.raid = Raid(request.sender, request.sender.access_level["level"])
|
|
# after I saw myself sending raid invites with the wrong bot reference by accident atleast once,
|
|
# the default is being set to allianceraid again.
|
|
self.raid.bot = "allianceraid" # self.bot.get_char_name()
|
|
self.raid.last_action = time.time()
|
|
spam = f"""
|
|
________________
|
|
<yellow>
|
|
You started a raid... but I need some more details about it,
|
|
please fill in this form: {self.raid_settings(request, "")}
|
|
</yellow>
|
|
________________
|
|
"""
|
|
return spam
|
|
|
|
@command(command="raid", params=[Const("stop")], description="Stop the raid", access_level="leader")
|
|
def raid_stop(self, _, _1):
|
|
if not self.raid:
|
|
return "There's no raid running."
|
|
self.raid = None
|
|
return "You stopped the raid."
|
|
|
|
# noinspection LongLine
|
|
@command(command="raid", params=[Const("invite")], description="Send the Spam to the defined Audience",
|
|
access_level="leader")
|
|
def send_tha_spam(self, request, _):
|
|
if not self.raid:
|
|
return "There's no raid running."
|
|
|
|
def blob(label, msg):
|
|
return f"<a href=\"text://{textwrap.dedent(msg)}\">{textwrap.dedent(label)}</a>"
|
|
|
|
last = time.time()
|
|
if self.raid.last_spam + 5 * 60 > last:
|
|
return f"There was an invite in the last 5 minutes; please wait " \
|
|
f"<highlight>{self.util.time_to_readable(self.raid.last_spam + 5 * 60 - last)}</highlight> " \
|
|
f"before sending another one."
|
|
click_here = blob("click here",
|
|
f"""
|
|
<header>How to join the Raid</header>
|
|
|
|
<notice>Step 1:</notice>
|
|
- Please join {self.raid.bot}: [{self.text.make_chatcmd("Join", f"/tell {self.raid.bot} join")}]
|
|
|
|
<notice>Step 2:</notice>
|
|
- Please go LFT, to show your interest: [{self.text.make_chatcmd("Go LFT", f"/lft » <green>{self.raid.bot}</green>")}]
|
|
|
|
<notice>Step 3:</notice>
|
|
Wait at the raid starting location.
|
|
Stepping is scheduled for <highlight>{self.raid.raid_time}</highlight>
|
|
Currently it is <highlight>{(datetime.now(timezone.utc).strftime("%H:%M"))} GMT-0</highlight>
|
|
""")
|
|
spam = f"""
|
|
________________
|
|
|
|
<yellow><green>{request.sender.name}</green> has invited you to join a <notice>{self.raid.raid_desc}</notice> Raid
|
|
Type <notice>/tell {self.raid.bot} join</notice> to participate
|
|
or {click_here}</yellow>
|
|
________________
|
|
"""
|
|
subtile = f"""<yellow>[<green>{request.sender.name}</green>]: Raid Starting: <notice>{self.raid.raid_desc}</notice> -- use <notice>/tell {self.raid.bot} join</notice> to participate or {click_here}</yellow></yellow> """
|
|
# noinspection SqlAggregates
|
|
players = self.db.query("SELECT p.*, a.subtile_spam, a.raid_invite, a.raid_spam, a.main, a.disabled, a.member from online o "
|
|
"left join player p on o.char_id = p.char_id "
|
|
"left join account a on a.char_id=(select main from account where char_id=o.char_id) "
|
|
"where p.level >= ? AND ((a.raid_invite=1 or a.raid_spam = 1) "
|
|
"and a.disabled = 0 "
|
|
"and a.member != -1 "
|
|
"AND a.char_id NOT IN (SELECT char_id FROM org_bots) "
|
|
"AND o.char_id NOT IN (SELECT char_id FROM org_bots)) "
|
|
"AND o.bot=? group by o.char_id "
|
|
"ORDER BY p.profession, p.name, p.level, p.org_rank_id;",
|
|
[self.raid.min_level, self.bot.get_char_id()])
|
|
self.bot.send_mass_message(request.sender.char_id, f"Attempting to send {len(players)} invites...")
|
|
info = "Sent invites to:"
|
|
prof = ""
|
|
count = len(players)
|
|
for i in players:
|
|
if not self.account_service.simple_checks(i):
|
|
count -= 1
|
|
continue
|
|
if prof != i.profession:
|
|
info += "\n\n<img src=tdb://id:GFX_GUI_FRIENDLIST_SPLITTER>"
|
|
info += "\n" + f"<img src=rdb://{self.profs.get(i.profession)}><tab><green>{i.profession}<end>\n"
|
|
info += "<img src=tdb://id:GFX_GUI_FRIENDLIST_SPLITTER>"
|
|
prof = i.profession
|
|
|
|
if i.raid_spam == 1:
|
|
self.bot.send_mass_message(i.char_id, spam if i.subtile_spam == 0 else subtile)
|
|
# if i.raid_invite == 1:
|
|
# if self.raid.bot == self.bot.get_char_name():
|
|
# if not self.private_channel_service.in_private_channel(i.char_id):
|
|
# self.private_channel_service.invite(i.char_id)
|
|
info += f"\n - {i.name: <13} ({i.level: >3}/<green>{i.ai_level: >2}</green>) - {i.org_name}"
|
|
self.raid.last_action = time.time()
|
|
self.raid.last_spam = time.time()
|
|
self.bot.send_mass_message(request.sender.char_id,
|
|
f"Successfully sent {count} invite{'s' if count != 1 else ''}! [{self.text.format_page('More', info)}]")
|
|
|
|
@command(command="raid", params=[Const("settings")],
|
|
description="Change the title of the Raid", access_level="leader")
|
|
def raid_settings(self, request: command_request, _):
|
|
if not self.raid:
|
|
return "There's no raid running."
|
|
if request.sender.access_level["level"] <= self.raid.leader_rank:
|
|
level_rest = " -"
|
|
for i in [0, 200, 205, 210, 215, 220]:
|
|
level_rest += f" [{self.text.make_chatcmd(i, '/tell <myname> raid level ' + str(i))}]"
|
|
|
|
bots = " -"
|
|
for i in ["allianceraid", "aapf", "theallianz"]:
|
|
bots += f" [{self.text.make_chatcmd(i, '/tell <myname> raid bot ' + str(i))}]"
|
|
|
|
description = " -"
|
|
for i in ["S42", "Pandemonium", "APF's"]:
|
|
description += f" [{self.text.make_chatcmd(i, '/tell <myname> raid desc ' + str(i))}]"
|
|
step = " -"
|
|
count = 0
|
|
|
|
for i in ["19:00 GMT-0", "19:30 GMT-0", "20:00 GMT-0", "20:30 GMT-0", "21:00 GMT-0", "21:30 GMT-0"]:
|
|
if count == 2:
|
|
count = 0
|
|
step += "<br> -"
|
|
step += f" [{self.text.make_chatcmd(i, '/tell <myname> raid time ' + str(i))}]"
|
|
count += 1
|
|
# noinspection LongLine
|
|
settings = self.text.format_page("Raid Settings",
|
|
textwrap.dedent(
|
|
f"""
|
|
<header>Raid Settings</header>
|
|
|
|
<notice>Set the minimum level [<yellow>{self.raid.min_level}</yellow>]:</notice>
|
|
{level_rest}
|
|
|
|
<notice>Change the Description [<yellow>{self.raid.raid_desc}</yellow>]:</notice>
|
|
{description}
|
|
|
|
<notice>Change the Raidbot [<yellow>{self.raid.bot}</yellow>]:</notice>
|
|
{bots}
|
|
|
|
<notice>Change the raid stepping time [<yellow>{self.raid.raid_time}</yellow>]:</notice>
|
|
-> Current Time: {(datetime.now(timezone.utc).strftime("%H:%M"))} GMT-0
|
|
{step}
|
|
|
|
<notice>Send the invites!</notice>
|
|
[{self.text.make_chatcmd("send the spam!", "/tell <myname> raid invite")}]
|
|
|
|
<notice>End the raid</notice>
|
|
[{self.text.make_chatcmd("stop it", "/tell <myname> raid stop")}]
|
|
"""))
|
|
return settings
|
|
return f"Error! You cant do that. Your accesslevel must be equal or higher than " \
|
|
f"<highlight>{self.raid.leader.name}</highlight>'s rank."
|
|
|
|
@timerevent(budatime="15m", description="Stop raid if inactive")
|
|
def clear_raid(self, _, _1):
|
|
if self.raid:
|
|
if self.raid.last_action + 60 * 60 < time.time():
|
|
self.bot.send_mass_message(self.raid.leader.char_id,
|
|
f"There was no interaction for more then 60 minutes for your Raid "
|
|
f"<highlight>{self.raid.raid_desc}</highlight>; I'll stop it for you.")
|
|
self.raid = None
|