Skip to content
This repository has been archived by the owner on Mar 28, 2023. It is now read-only.

Commit

Permalink
Make default ban duration configurable (#154)
Browse files Browse the repository at this point in the history
Also refactor of /ban command

Co-authored-by: oldmud0 <[email protected]>
  • Loading branch information
caleb-mabry and oldmud0 authored Jan 31, 2021
1 parent eb13a2c commit c766755
Show file tree
Hide file tree
Showing 3 changed files with 59 additions and 42 deletions.
3 changes: 3 additions & 0 deletions config_sample/config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -79,3 +79,6 @@ testimony_limit: 30

# Maximum number of characters can a message contain
max_chars: 256

# How long a ban will last when no duration is given
default_ban_duration: 6 hours
96 changes: 54 additions & 42 deletions server/commands/admin.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
import shlex

import arrow
import pytimeparse

from pytimeparse import parse

from server import database
from server.constants import TargetType
from server.exceptions import ClientError, ServerError, ArgumentError

from . import mod_only, list_commands, list_submodules, help

__all__ = [
Expand Down Expand Up @@ -72,7 +71,8 @@ def ooc_cmd_help(client, arg):
msg += list_commands(arg)
client.send_ooc(msg)
except AttributeError:
client.send_ooc('No such command or submodule has been found in the help docs.')
client.send_ooc(
'No such command or submodule has been found in the help docs.')


@mod_only()
Expand Down Expand Up @@ -102,14 +102,15 @@ def ooc_cmd_kick(client, arg):
except:
raise ClientError(f'{raw_ipid} does not look like a valid IPID.')
targets = client.server.client_manager.get_targets(client, TargetType.IPID,
ipid, False)
ipid, False)

if targets:
reason = ' '.join(args[1:])
if reason == '':
reason = 'N/A'
for c in targets:
database.log_misc('kick', client, target=c, data={'reason': reason})
database.log_misc('kick', client, target=c,
data={'reason': reason})
client.send_ooc("{} was kicked.".format(
c.char_name))
c.send_command('KK', reason)
Expand Down Expand Up @@ -139,55 +140,63 @@ def ooc_cmd_banhdid(client, arg):
kickban(client, arg, True)


def _convert_ipid_to_int(value):
try:
return int(value)
except ValueError:
raise ClientError(f'{value} does not look like a valid IPID.')


@mod_only()
def kickban(client, arg, ban_hdid):
def kickban(client, arg: str, ban_hdid):
args = shlex.split(arg)
ban_id = None
default_ban_duration = client.server.config['default_ban_duration']

if len(args) < 2:
raise ArgumentError('Not enough arguments.')

elif len(args) == 2:
ipid = _convert_ipid_to_int(args[0])
ban_id = args[1]
reason = None
ban_id = None
try:
ban_id = int(args[1])
unban_date = None
except ValueError:
reason = args[1]
unban_date = arrow.get().shift(hours=6).datetime
ban_duration = parse(str(default_ban_duration), granularity='hours')
unban_date = arrow.get().shift(hours=ban_duration).datetime

elif len(args) == 3:
ban_id = None
ipid = _convert_ipid_to_int(args[0])
reason = args[1]
if 'perma' in args[2]:
duration = args[2]
ban_duration = parse(str(duration), granularity='hours')

if duration is None:
raise ArgumentError('Invalid ban duration.')
elif 'perma' in duration.lower():
unban_date = None
else:
duration = pytimeparse.parse(args[2], granularity='hours')
if duration is None:
raise ArgumentError('Invalid ban duration.')
unban_date = arrow.get().shift(seconds=duration).datetime
if ban_duration is not None:
unban_date = arrow.get().shift(hours=ban_duration).datetime
else:
raise ArgumentError(f'{duration} is an invalid ban duration')

else:
raise ArgumentError(f'Ambiguous input: {arg}\nPlease wrap your arguments '
'in quotes.')

try:
raw_ipid = args[0]
ipid = int(raw_ipid)
except ValueError:
raise ClientError(f'{raw_ipid} does not look like a valid IPID.')
'in quotes.')

ban_id = database.ban(ipid, reason, ban_type='ipid', banned_by=client,
ban_id=ban_id, unban_date=unban_date)
ban_id = database.ban(ipid, reason, ban_type='ipid',
banned_by=client, ban_id=ban_id, unban_date=unban_date)

if ipid != None:
targets = client.server.client_manager.get_targets(
client, TargetType.IPID, ipid, False)
if targets:
for c in targets:
if ban_hdid:
database.ban(c.hdid, reason, ban_type='hdid', ban_id=ban_id)
c.send_command('KB', reason)
c.disconnect()
database.log_misc('ban', client, target=c, data={'reason': reason})
client.send_ooc(f'{len(targets)} clients were kicked.')
client.send_ooc(f'{ipid} was banned. Ban ID: {ban_id}')
targets = client.server.client_manager.get_targets(
client, TargetType.IPID, ipid, False)
if targets:
for c in targets:
if ban_hdid:
database.ban(c.hdid, reason, ban_type='hdid', ban_id=ban_id)
c.send_command('KB', reason)
c.disconnect()
database.log_misc('ban', client, target=c, data={'reason': reason})
client.send_ooc(f'{len(targets)} clients were kicked.')
client.send_ooc(f'{ipid} was banned. Ban ID: {ban_id}')


@mod_only()
Expand Down Expand Up @@ -378,6 +387,7 @@ def ooc_cmd_ooc_unmute(client, arg):
client.send_ooc('Unmuted {} existing client(s).'.format(
len(targets)))


@mod_only()
def ooc_cmd_bans(client, _arg):
"""
Expand All @@ -391,6 +401,7 @@ def ooc_cmd_bans(client, _arg):
f'{ban.ban_id} (\'{ban.reason}\')\n'
client.send_ooc(msg)


@mod_only()
def ooc_cmd_baninfo(client, arg):
"""
Expand All @@ -414,7 +425,8 @@ def ooc_cmd_baninfo(client, arg):
client.send_ooc('No ban found for this ID.')
else:
msg = f'Ban ID: {ban.ban_id}\n'
msg += 'Affected IPIDs: ' + ', '.join([str(ipid) for ipid in ban.ipids]) + '\n'
msg += 'Affected IPIDs: ' + \
', '.join([str(ipid) for ipid in ban.ipids]) + '\n'
msg += 'Affected HDIDs: ' + ', '.join(ban.hdids) + '\n'
msg += f'Reason: "{ban.reason}"\n'
msg += f'Banned by: {ban.banned_by_name} ({ban.banned_by})\n'
Expand Down
2 changes: 2 additions & 0 deletions server/tsuserver.py
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,8 @@ def load_config(self):
self.config['multiclient_limit'] = 16
if 'testimony_limit' not in self.config:
self.config['testimony_limit'] = 30
if 'default_ban_duration' not in self.config:
self.config['default_ban_duration'] = 6

def load_characters(self):
"""Load the character list from a YAML file."""
Expand Down

0 comments on commit c766755

Please sign in to comment.