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)
228 lines
11 KiB
Python
228 lines
11 KiB
Python
import time
|
|
from datetime import datetime
|
|
|
|
from core.buddy_service import BuddyService
|
|
from core.chat_blob import ChatBlob
|
|
from core.command_param_types import Options, Int, Any, Character, Const
|
|
from core.db import DB
|
|
from core.decorators import instance, event, command
|
|
from core.dict_object import DictObject
|
|
from core.job_scheduler import JobScheduler
|
|
from core.logger import Logger
|
|
from core.text import Text
|
|
from core.tyrbot import Tyrbot
|
|
from modules.core.accounting.services.account_service import AccountService
|
|
from modules.core.ban.ban_service import BanService
|
|
|
|
|
|
@instance()
|
|
class MailController:
|
|
|
|
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.ban: BanService = registry.get_instance("ban_service")
|
|
self.buddy_service: BuddyService = registry.get_instance("buddy_service")
|
|
self.job_schedule: JobScheduler = registry.get_instance("job_scheduler")
|
|
self.account_service: AccountService = registry.get_instance("account_service")
|
|
|
|
def pre_start(self):
|
|
self.db.exec(
|
|
"CREATE TABLE IF NOT EXISTS mail("
|
|
"id int primary key auto_increment, "
|
|
"text text, "
|
|
"recipient int not null, "
|
|
"sender int not null, "
|
|
"sent_at int not null, "
|
|
"`read` int not null default 0)")
|
|
|
|
@event(event_type="connect", description="register players with pending mails")
|
|
def connect_event(self, _, _1):
|
|
data = self.db.query(
|
|
"SELECT a.char_id from mail m "
|
|
"left join account a ON a.main = m.recipient "
|
|
"WHERE `read` = 0 and (a.disabled = 0 and a.member=1) "
|
|
"group by a.char_id")
|
|
for row in data:
|
|
self.buddy_service.add_buddy(row.char_id, "mail")
|
|
|
|
@event(event_type="member_logon", description="Send mails on logon")
|
|
def logon_event(self, _, data):
|
|
if not self.bot.is_ready():
|
|
return
|
|
if not self.account_service.simple_checks(data.account):
|
|
return
|
|
if "mail" in self.buddy_service.get_buddy(data.packet.char_id)["types"]:
|
|
self.job_schedule.delayed_job(self.send_mail, 16, data.packet.char_id, self.get_mails(data.packet.char_id))
|
|
|
|
def send_mail(self, _, sender, mail, greeting="Hey, you got some mails!"):
|
|
if self.buddy_service.get_buddy(sender)["online"] == 0:
|
|
return
|
|
# hotfix for
|
|
if len(mail) < 10:
|
|
self.buddy_service.remove_buddy(sender, "mail")
|
|
return
|
|
self.bot.send_mass_message(sender, f"<red>{greeting}</red> <yellow>::</yellow> " +
|
|
self.text.paginate_single(ChatBlob("Your mails", mail)))
|
|
|
|
#####################
|
|
# Mail Management #
|
|
#####################
|
|
|
|
@command(command="mail", params=[Const('all', is_optional=True)], description="Show your mails",
|
|
access_level="member")
|
|
def mail_show(self, sender, const_all):
|
|
if const_all:
|
|
mails = self.get_mails(sender.sender.char_id, True)
|
|
if mails:
|
|
self.bot.send_private_message(sender.sender.char_id, ChatBlob("All your recent Mails", mails))
|
|
else:
|
|
return "You dont have any mails."
|
|
else:
|
|
mails = self.get_mails(sender.sender.char_id)
|
|
if mails:
|
|
self.bot.send_private_message(sender.sender.char_id, ChatBlob("Your unread mails", mails))
|
|
else:
|
|
return "You dont have any unread mails."
|
|
|
|
@command(command="mail", params=[Options(["read"]), Int("ID")],
|
|
description="mark a mail as read", access_level="member")
|
|
def mail_read(self, sender, _, mail_id):
|
|
row = self.db.exec(
|
|
"UPDATE mail set `read` = 1 where recipient=(SELECT main from account where char_id=? LIMIT 1) and id=?",
|
|
[sender.sender.char_id, mail_id])
|
|
if len(self.get_mails(sender.sender.char_id)) < 10:
|
|
alts = self.account_service.get_alts(sender.sender.char_id)
|
|
for i in alts:
|
|
self.buddy_service.remove_buddy(i.char_id, "mail")
|
|
if row == 0:
|
|
return f"You dont have an unread mail with the ID <highlight>{mail_id}</highlight>."
|
|
elif row == 1:
|
|
return f"The mail with the ID <highlight>{mail_id}</highlight> has been marked as read."
|
|
else:
|
|
return "Something went wrong. please contact an administrator."
|
|
|
|
@command(command="mail", params=[Options(["delete"]), Int("ID")],
|
|
description="mark a mail as read", access_level="member")
|
|
def mail_delete(self, sender, _, mail_id):
|
|
row = self.db.exec(
|
|
"DELETE FROM mail where recipient=(SELECT main from account where char_id=? LIMIT 1) and id=?",
|
|
[sender.sender.char_id, mail_id])
|
|
if len(self.get_mails(sender.sender.char_id)) < 10:
|
|
alts = self.account_service.get_alts(sender.sender.char_id)
|
|
for i in alts:
|
|
self.buddy_service.remove_buddy(i.char_id, "mail")
|
|
if row == 0:
|
|
return f"You dont have a mail with the ID <highlight>{mail_id}</highlight>."
|
|
elif row == 1:
|
|
return f"The mail with the ID <highlight>{mail_id}</highlight> has been deleted."
|
|
else:
|
|
return "Something went wrong. please contact an administrator."
|
|
|
|
@command(command="mail", params=[Options(["send"]), Character("recipient"), Any("text")],
|
|
description="Send a mail to someone", access_level="member")
|
|
def mail_send(self, sender, _, receiver, message):
|
|
if not receiver.char_id:
|
|
return f"Character <highlight>{receiver.name}</highlight> not found."
|
|
recipient = self.account_service.get_account(receiver.char_id)
|
|
if not recipient:
|
|
return f"No account for <highlight>{receiver.name}</highlight> found."
|
|
|
|
# if recipient.member == -1 or recipient.disabled == 1:
|
|
if not self.account_service.simple_checks(recipient):
|
|
return f"The Character <highlight>{recipient.name}</highlight> has " \
|
|
f"no active account in <highlight><myname></highlight>."
|
|
self.db.exec("INSERT INTO mail(sender, recipient, text, sent_at) VALUES(?, ?, ?, ?)",
|
|
[sender.sender.char_id, recipient.main, message, time.time()])
|
|
alts = self.account_service.get_alts(recipient.char_id)
|
|
for i in alts:
|
|
buddy = self.buddy_service.get_buddy(i.char_id) or []
|
|
if "mail" not in buddy:
|
|
if i.member == -1:
|
|
continue
|
|
self.buddy_service.add_buddy(i.char_id, "mail")
|
|
if self.buddy_service.is_online(i.char_id):
|
|
self.send_mail(0, i.char_id, self.get_mails(i.char_id),
|
|
f"{sender.sender.name} just sent you a mail, please read it")
|
|
return "Mail sent successfully."
|
|
|
|
@command(command="mail", params=[Const("group"), Any("group"), Any("text")],
|
|
description="Send a mail to a group of players", sub_command='sendgroup', access_level="moderator")
|
|
def mail_send_group(self, sender, _, recipient, message):
|
|
group = self.account_service.get_group_tag(recipient)
|
|
users = []
|
|
if group:
|
|
# if group == "all":
|
|
# if sender.sender.access_level['level'] > 20:
|
|
# return "This group is unavailable."
|
|
# users = self.account_service.get_all_members()
|
|
# else:
|
|
users = self.account_service.get_by_group(group)
|
|
|
|
elif not group:
|
|
return f"Sorry, but the group <highlight>{recipient}</highlight> does not exist. " \
|
|
f"The following groups are defined: " \
|
|
f"<highlight>admin, council, [all - admin only group], moderator</highlight> " \
|
|
f"and <highlight>leaders</highlight>."
|
|
|
|
count = 0
|
|
readers = []
|
|
if group != "all":
|
|
message += f"<br><tab><header>» This mail has been sent to the " \
|
|
f"<highlight>{group}</highlight> group.</header>"
|
|
else:
|
|
message += f"<br><tab><header>» This mail has been sent to <highlight>everyone</highlight>.</header>"
|
|
mails = []
|
|
for user in users:
|
|
if user.main == user.char_id:
|
|
mails.append((sender.sender.char_id, user.main, message, time.time()))
|
|
count += 1
|
|
if user.online == 1:
|
|
readers.append(DictObject({"name": user.name, "char_id": user.char_id}))
|
|
with self.db.pool.get_connection() as conn:
|
|
with conn.cursor() as cur:
|
|
cur.executemany("INSERT INTO mail(sender, recipient, text, sent_at) VALUES(?, ?, ?, ?)", mails)
|
|
for user in readers:
|
|
self.send_mail(0, user.char_id, self.get_mails(user.char_id),
|
|
greeting=f"<highlight>{sender.sender.name}</highlight> just sent you a group mail, "
|
|
f"please read it!")
|
|
|
|
return f"I've sent the <highlight>{count}</highlight> mails to the group " \
|
|
f"<highlight>{group}</highlight> for you. " \
|
|
f"A total of <highlight>{len(readers)}</highlight> characters from this group are online, " \
|
|
f"the have been notified."
|
|
|
|
def get_single_mail(self, char_id, mail_id):
|
|
return ChatBlob(f"Your Mail with the ID {mail_id}", self.format_mail(self.db.query_single(
|
|
"SELECT * FROM mail where recipient=(SELECT main from account where char_id=?) and id = ?", [char_id, id])))
|
|
|
|
def get_mails(self, char_id, all_mails=False):
|
|
if all_mails:
|
|
data = self.db.query(
|
|
"SELECT * FROM mail where recipient=(SELECT main from account where char_id=?) order by id desc",
|
|
[char_id])
|
|
else:
|
|
data = self.db.query(
|
|
"SELECT * FROM mail where recipient=(SELECT main from account where char_id=?) and `read`=0 "
|
|
"order by id desc",
|
|
[char_id])
|
|
blob = ""
|
|
for row in data:
|
|
blob += self.format_mail(row) + "<br>"
|
|
return blob
|
|
|
|
def format_mail(self, mail):
|
|
# noinspection LongLine
|
|
return \
|
|
f"""
|
|
<notice>{self.bot.character_service.resolve_char_to_name(mail.sender) if mail.sender != 0 else "IGNCOM"}</notice> sent you a mail on <highlight>{datetime.utcfromtimestamp(mail.sent_at).strftime("%d.%m.%Y - %H:%M:%S")}</highlight>:
|
|
<white>{mail.text}</white>
|
|
- <green>[{self.text.make_tellcmd('Mark as read', f'mail read {mail.id}')}] [{self.text.make_tellcmd('DELETE', f'mail delete {mail.id}')}]</green>
|
|
"""
|
|
|
|
@event(event_type="main_changed", description="Fix mails")
|
|
def fix_mails(self, _, data):
|
|
self.db.exec("UPDATE mail set recipient=? where recipient=?", [data.new_main_id, data.old_main_id])
|