Improvements to moderation handlers

This commit is contained in:
Ben 2019-12-02 23:33:38 +00:00
parent 9bc18b5b34
commit 576f79c8b7
3 changed files with 100 additions and 61 deletions

View File

@ -707,6 +707,7 @@ CREATE TABLE ban (
moderator_id INT DEFAULT NULL,
reason SMALLINT NOT NULL,
comment TEXT DEFAULT NULL,
message TEXT DEFAULT NULL,
PRIMARY KEY (penguin_id, issued, expires),
CONSTRAINT ban_ibfk_1 FOREIGN KEY (penguin_id) REFERENCES penguin (id) ON DELETE RESTRICT ON UPDATE CASCADE,
CONSTRAINT ban_ibfk_2 FOREIGN KEY (moderator_id) REFERENCES penguin (id) ON DELETE RESTRICT ON UPDATE CASCADE
@ -725,6 +726,7 @@ COMMENT ON COLUMN ban.expires IS 'Expiry date';
COMMENT ON COLUMN ban.moderator_id IS 'Moderator penguin ID';
COMMENT ON COLUMN ban.reason IS 'Ban reason';
COMMENT ON COLUMN ban.comment IS 'Ban comment';
COMMENT ON COLUMN ban.message IS 'Banned for message';
DROP TABLE IF EXISTS warning;
CREATE TABLE warning (

View File

@ -11,6 +11,7 @@ class Ban(db.Model):
moderator_id = db.Column(db.ForeignKey('penguin.id', ondelete='CASCADE', onupdate='CASCADE'), index=True)
reason = db.Column(db.SmallInteger, nullable=False)
comment = db.Column(db.Text)
message = db.Column(db.Text)
class Warning(db.Model):
@ -19,6 +20,7 @@ class Warning(db.Model):
penguin_id = db.Column(db.ForeignKey('penguin.id', ondelete='CASCADE', onupdate='CASCADE'), primary_key=True,
nullable=False)
expires = db.Column(db.DateTime, primary_key=True, nullable=False)
issued = db.Column(db.DateTime, primary_key=True, nullable=False)
class Report(db.Model):

View File

@ -2,59 +2,66 @@ from houdini import handlers
from houdini.data import db
from houdini.handlers import XTPacket
from houdini.data.moderator import Ban, Warning, Report
from houdini.data.penguin import Penguin
from houdini.constants import ClientType
import datetime
@handlers.handler(XTPacket('o', 'k'))
async def handle_kick_player(p, penguin_id: int):
if p.data.moderator:
if p.moderator:
await moderator_kick(p, penguin_id)
@handlers.handler(XTPacket('o', 'b'))
@handlers.handler(XTPacket('o', 'b'), client=ClientType.Legacy)
async def handle_ban_player(p, penguin_id: int, message: str):
if p.data.moderator:
if p.moderator:
await moderator_ban(p, penguin_id, comment=message)
@handlers.handler(XTPacket('o', 'm'))
async def handle_mute_player(p, penguin_id: int):
if p.data.moderator:
if p.moderator:
if penguin_id in p.server.penguins_by_id:
player = p.server.penguins_by_id[penguin_id]
if not player.data.moderator:
if not player.moderator:
player.muted = True
@handlers.handler(XTPacket('o', 'initban'))
@handlers.handler(XTPacket('o', 'initban'), client=ClientType.Vanilla)
@handlers.player_attribute(moderator=True)
async def handle_init_ban(p, penguin_id: int, message: str):
if penguin_id in p.server.penguins_by_id and p.data.moderator:
player = p.server.penguins_by_id[penguin_id]
player = p.server.penguins_by_id[penguin_id] if penguin_id in p.server.penguins_by_id \
else await Penguin.get(penguin_id)
if not player.moderator:
number_bans = await db.select([db.func.count(Ban.penguin_id)]).where(
Ban.penguin_id == player.id).gino.scalar()
if not player.data.moderator:
number_bans = await db.select([db.func.count(Ban.penguin_id)]).where(
Ban.penguin_id == player.data.id).gino.scalar()
await p.send_xt('initban', penguin_id, 0, number_bans, message, player.data.username)
await p.send_xt('initban', penguin_id, 0, number_bans, message, player.username)
@handlers.handler(XTPacket('o', 'ban'))
@handlers.handler(XTPacket('o', 'ban'), client=ClientType.Vanilla)
@handlers.player_attribute(moderator=True)
async def handle_moderator_ban(p, penguin_id: int, ban_type: int, reason: int, duration: int, message: str, notes: str):
if p.data.moderator:
player = p.server.penguins_by_id[penguin_id] if penguin_id in p.server.penguins_by_id \
else await Penguin.get(penguin_id)
if not player.moderator:
date_issued = datetime.datetime.now()
date_expires = date_issued + datetime.timedelta(hours=duration)
if duration == 0:
await player.update(permaban=True).apply()
await Ban.create(penguin_id=player.id, issued=date_issued, expires=date_expires,
moderator_id=p.id, reason=reason, comment=notes, message=message)
if penguin_id in p.server.penguins_by_id:
player = p.server.penguins_by_id[penguin_id]
if not player.data.moderator:
date_issued = datetime.datetime.now()
date_expires = date_issued + datetime.timedelta(hours=duration)
if duration == 0:
await player.data.update(permaban=True).apply()
await Ban.create(penguin_id=player.data.id, issued=date_issued, expires=date_expires,
moderator_id=p.data.id, reason=reason, comment=notes)
if player.is_vanilla_client:
await player.send_xt('ban', ban_type, reason, duration, notes)
await player.close()
else:
await player.send_error(610, message)
await player.close()
@handlers.handler(XTPacket('m', 'r'))
@ -64,52 +71,80 @@ async def handle_report(p, penguin_id: int, reason: int = 0):
date=date_now, server_id=p.server.config.id, room_id=p.room.id)
@handlers.handler(XTPacket('o', 'moderatormessage'))
async def handle_moderator_message(p, type: int, penguin_id: int):
if p.data.moderator:
@handlers.handler(XTPacket('o', 'moderatormessage'), client=ClientType.Vanilla)
@handlers.player_attribute(moderator=True)
async def handle_moderator_message(p, warning_type: int, penguin_id: int):
player = p.server.penguins_by_id[penguin_id] if penguin_id in p.server.penguins_by_id \
else await Penguin.get(penguin_id)
date_issued = datetime.datetime.now()
date_expires = date_issued + datetime.timedelta(hours=48)
warning_count = await db.select([db.func.count(Warning.expires)]).where(
(Warning.penguin_id == player.id) & (Warning.expires >= date_issued)).gino.scalar()
if warning_count >= 3:
return await moderator_ban(p, player.id, message='Exceeded warning limit')
await player.send_xt('moderatormessage', warning_type)
await Warning.create(penguin_id=player.id, issued=date_issued, expires=date_expires)
async def cheat_kick(p, penguin_id):
if penguin_id in p.server.penguins_by_id:
await p.server.penguins_by_id[penguin_id].send_error_and_disconnect(800)
async def cheat_ban(p, penguin_id, hours=24, comment=''):
if penguin_id in p.server.penguins_by_id:
player = p.server.penguins_by_id[penguin_id]
number_bans = await db.select([db.func.count(Ban.penguin_id)]).where(
Ban.penguin_id == player.id).gino.scalar()
date_issued = datetime.datetime.now()
date_expires = date_issued + datetime.timedelta(hours=hours)
if number_bans >= 3:
await player.update(permaban=True).apply()
await Ban.create(penguin_id=player.id, issued=date_issued, expires=date_expires,
moderator_id=p.id, reason=1, comment=comment, message='Cheat ban')
if penguin_id in p.server.penguins_by_id:
player = p.server.penguins_by_id[penguin_id]
date_issued = datetime.datetime.now()
date_expires = date_issued + datetime.timedelta(hours=48)
warning_count = await db.select([db.func.count(Warning.expires)]).where(
(Warning.penguin_id == player.data.id) & (Warning.expires >= date_issued)).gino.scalar()
if warning_count >= 3:
return await moderator_ban(p, player.data.id, comment='Exceeded warning limit')
await player.send_xt('moderatormessage', type)
await Warning.create(penguin_id=player.data.id, expires=date_expires)
await player.send_error_and_disconnect(611, comment)
async def moderator_kick(p, penguin_id):
if penguin_id in p.server.penguins_by_id and p.data.moderator:
if penguin_id in p.server.penguins_by_id:
player = p.server.penguins_by_id[penguin_id]
if not player.data.moderator:
if not player.moderator:
for penguin in p.server.penguins_by_id.values():
if penguin.data.moderator:
await penguin.send_xt('ma', 'k', penguin_id, player.data.username)
if penguin.moderator:
await penguin.send_xt('ma', 'k', penguin_id, player.username)
await player.send_error_and_disconnect(5)
async def moderator_ban(p, penguin_id, hours=24, comment=''):
if penguin_id in p.server.penguins_by_id and p.data.moderator:
player = p.server.penguins_by_id[penguin_id]
if not player.data.moderator:
for penguin in p.server.penguins_by_id.values():
if penguin.data.moderator:
await penguin.send_xt('ma', 'b', penguin_id, player.data.username)
async def moderator_ban(p, penguin_id, hours=24, comment='', message=''):
player = p.server.penguins_by_id[penguin_id] if penguin_id in p.server.penguins_by_id \
else await Penguin.get(penguin_id)
if not player.moderator:
for penguin in p.server.penguins_by_id.values():
if penguin.moderator:
await penguin.send_xt('ma', 'b', penguin_id, player.username)
number_bans = await db.select([db.func.count(Ban.penguin_id)]).where(
Ban.penguin_id == player.data.id).gino.scalar()
number_bans = await db.select([db.func.count(Ban.penguin_id)]).where(
Ban.penguin_id == player.id).gino.scalar()
date_issued = datetime.datetime.now()
date_expires = date_issued + datetime.timedelta(hours=hours)
date_issued = datetime.datetime.now()
date_expires = date_issued + datetime.timedelta(hours=hours)
if number_bans >= 3:
await player.data.update(permaban=True).apply()
if number_bans >= 3:
await player.update(permaban=True).apply()
await Ban.create(penguin_id=player.data.id, issued=date_issued, expires=date_expires,
moderator_id=p.data.id, reason=1, comment=comment)
await Ban.create(penguin_id=player.id, issued=date_issued, expires=date_expires,
moderator_id=p.id, reason=2, comment=comment, message=message)
await player.send_error_and_disconnect(610, comment)
await player.close()
if penguin_id in p.server.penguins_by_id:
if player.is_vanilla_client:
await player.send_xt('ban', 612, 2, hours, comment)
else:
await player.send_error_and_disconnect(610, comment)