.BANCHO. Add !report command

This commit is contained in:
Nyo 2016-12-11 23:12:06 +01:00
parent b4d498c26c
commit daf457fc5c
5 changed files with 104 additions and 7 deletions

View File

@ -95,4 +95,10 @@ class userAlreadyInChannelException(Exception):
pass pass
class userNotInChannelException(Exception): class userNotInChannelException(Exception):
pass
class missingReportInfoException(Exception):
pass
class invalidUserException(Exception):
pass pass

View File

@ -1,7 +1,9 @@
import json import json
import random import random
import re
import requests import requests
import time
from common import generalUtils from common import generalUtils
from common.constants import mods from common.constants import mods
@ -14,6 +16,7 @@ from constants import serverPackets
from helpers import systemHelper from helpers import systemHelper
from objects import fokabot from objects import fokabot
from objects import glob from objects import glob
from helpers import chatHelper as chat
""" """
Commands callbacks Commands callbacks
@ -694,6 +697,64 @@ def updateBeatmap(fro, chan, message):
except: except:
return False return False
def report(fro, chan, message):
msg = ""
try:
# TODO: Rate limit
# Regex on message
reportRegex = re.compile("^(.+) \((.+)\)\:(?: )?(.+)?$")
result = reportRegex.search(" ".join(message))
# Make sure the message matches the regex
if result is None:
raise exceptions.invalidArgumentsException()
# Get username, report reason and report info
target, reason, additionalInfo = result.groups()
target = chat.fixUsernameForBancho(target)
# Make sure the target is not foka
if target.lower() == "fokabot":
raise exceptions.invalidUserException()
# Make sure the user exists
targetID = userUtils.getID(target)
if targetID == 0:
raise exceptions.userNotFoundException()
# Make sure that the user has specified additional info if report reason is 'Other'
if reason.lower() == "other" and additionalInfo is None:
raise exceptions.missingReportInfoException()
# Get the token if possible
chatlog = ""
token = glob.tokens.getTokenFromUsername(target)
if token is not None:
chatlog = token.getMessagesBufferString()
# Everything is fine, submit report
glob.db.execute("INSERT INTO reports (id, from_uid, to_uid, reason, chatlog, time) VALUES (NULL, %s, %s, %s, %s, %s)", [userUtils.getID(fro), targetID, "{reason} - ingame {info}".format(reason=reason, info="({})".format(additionalInfo) if additionalInfo is not None else ""), chatlog, int(time.time())])
msg = "You've reported {target} for {reason}{info}. A Community Manager will check your report as soon as possible. Every !report message you may see in chat wasn't sent to anyone, so nobody in chat, but admins, know about your report. Thank you for reporting!".format(target=target, reason=reason, info="" if additionalInfo is None else " (" + additionalInfo + ")")
adminMsg = "{user} has reported {target} for {reason} ({info})".format(user=fro, target=target, reason=reason, info=additionalInfo)
# Log report in #admin and on discord
chat.sendMessage("FokaBot", "#admin", adminMsg)
log.warning(adminMsg, discord="cm")
except exceptions.invalidUserException:
msg = "You can't report. I won't forget what you've tried to do. Watch out."
except exceptions.invalidArgumentsException:
msg = "Invalid report command syntax. To report an user, click on it and select 'Report user'."
except exceptions.userNotFoundException:
msg = "The user you've tried to report doesn't exist."
except exceptions.missingReportInfoException:
msg = "Please specify the reason of your report."
except:
raise
finally:
if msg != "":
chat.sendMessage("FokaBot", fro, msg)
return False
""" """
Commands list Commands list
@ -713,7 +774,7 @@ commands = [
"callback": faq "callback": faq
}, { }, {
"trigger": "!report", "trigger": "!report",
"response": "Report command isn't here yet :c" "callback": report
}, { }, {
"trigger": "!help", "trigger": "!help",
"response": "Click (here)[https://ripple.moe/index.php?p=16&id=4] for FokaBot's full command list" "response": "Click (here)[https://ripple.moe/index.php?p=16&id=4] for FokaBot's full command list"

View File

@ -175,6 +175,10 @@ def sendMessage(fro = "", to = "", message = "", token = None, toIRC = True):
if token.isSilenced(): if token.isSilenced():
raise exceptions.userSilencedException() raise exceptions.userSilencedException()
# Redirect !report to FokaBot
if message.startswith("!report"):
to = "FokaBot"
# Determine internal name if needed # Determine internal name if needed
# (toclient is used clientwise for #multiplayer and #spectator channels) # (toclient is used clientwise for #multiplayer and #spectator channels)
toClient = to toClient = to
@ -190,7 +194,6 @@ def sendMessage(fro = "", to = "", message = "", token = None, toIRC = True):
toClient = "#spectator" toClient = "#spectator"
elif to.startswith("#multi_"): elif to.startswith("#multi_"):
toClient = "#multiplayer" toClient = "#multiplayer"
# Truncate message if > 2048 characters # Truncate message if > 2048 characters
message = message[:2048]+"..." if len(message) > 2048 else message message = message[:2048]+"..." if len(message) > 2048 else message
@ -216,6 +219,9 @@ def sendMessage(fro = "", to = "", message = "", token = None, toIRC = True):
if glob.channels.channels[to].publicWrite == False and token.admin == False: if glob.channels.channels[to].publicWrite == False and token.admin == False:
raise exceptions.channelNoPermissionsException() raise exceptions.channelNoPermissionsException()
# Add message in buffer
token.addMessageInBuffer(to, message)
# Everything seems fine, build recipients list and send packet # Everything seems fine, build recipients list and send packet
glob.streams.broadcast("chat/{}".format(to), packet, but=[token.token]) glob.streams.broadcast("chat/{}".format(to), packet, but=[token.token])
else: else:

View File

@ -402,13 +402,15 @@ class Client:
self.replyCode(332, description, channel=channel) self.replyCode(332, description, channel=channel)
# Build connected users list # Build connected users list
users = glob.channels.channels[channel].connectedUsers[:] if "chat/{}".format(channel) not in glob.streams.streams:
self.reply403(channel)
continue
users = glob.streams.streams["chat/{}".format(channel)].clients
usernames = [] usernames = []
for user in users: for user in users:
token = glob.tokens.getTokenFromUserID(user) if user not in glob.tokens.tokens:
if token is None:
continue continue
usernames.append(chat.fixUsernameForIRC(token.username)) usernames.append(chat.fixUsernameForIRC(glob.tokens.tokens[user].username))
usernames = " ".join(usernames) usernames = " ".join(usernames)
# Send IRC users list # Send IRC users list

View File

@ -40,6 +40,7 @@ class token:
self.lock = threading.Lock() # Sync primitive self.lock = threading.Lock() # Sync primitive
self.streams = [] self.streams = []
self.tournament = tournament self.tournament = tournament
self.messagesBuffer = []
# Default variables # Default variables
self.spectators = [] self.spectators = []
@ -499,4 +500,25 @@ class token:
if self.awayMessage == "" or userID in self.sentAway: if self.awayMessage == "" or userID in self.sentAway:
return False return False
self.sentAway.append(userID) self.sentAway.append(userID)
return True return True
def addMessageInBuffer(self, chan, message):
"""
Add a message in messages buffer (10 messages, truncated at 50 chars).
Used as proof when the user gets reported.
:param chan: channel
:param message: message content
:return:
"""
if len(self.messagesBuffer) > 9:
self.messagesBuffer = self.messagesBuffer[1:]
self.messagesBuffer.append("{time} - {user}@{channel}: {message}".format(time=time.strftime("%M:%S", time.localtime()), user=self.username, channel=chan, message=message[:50]))
def getMessagesBufferString(self):
"""
Get the content of the messages buffer as a string
:return: messages buffer content as a string
"""
return "\n".join(x for x in self.messagesBuffer)