226 lines
11 KiB
Python
226 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 data.account.disabled == 1:
|
|
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:
|
|
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])
|