.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
class userNotInChannelException(Exception):
pass
class missingReportInfoException(Exception):
pass
class invalidUserException(Exception):
pass

View File

@ -1,7 +1,9 @@
import json
import random
import re
import requests
import time
from common import generalUtils
from common.constants import mods
@ -14,6 +16,7 @@ from constants import serverPackets
from helpers import systemHelper
from objects import fokabot
from objects import glob
from helpers import chatHelper as chat
"""
Commands callbacks
@ -694,6 +697,64 @@ def updateBeatmap(fro, chan, message):
except:
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
@ -713,7 +774,7 @@ commands = [
"callback": faq
}, {
"trigger": "!report",
"response": "Report command isn't here yet :c"
"callback": report
}, {
"trigger": "!help",
"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():
raise exceptions.userSilencedException()
# Redirect !report to FokaBot
if message.startswith("!report"):
to = "FokaBot"
# Determine internal name if needed
# (toclient is used clientwise for #multiplayer and #spectator channels)
toClient = to
@ -190,7 +194,6 @@ def sendMessage(fro = "", to = "", message = "", token = None, toIRC = True):
toClient = "#spectator"
elif to.startswith("#multi_"):
toClient = "#multiplayer"
# Truncate message if > 2048 characters
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:
raise exceptions.channelNoPermissionsException()
# Add message in buffer
token.addMessageInBuffer(to, message)
# Everything seems fine, build recipients list and send packet
glob.streams.broadcast("chat/{}".format(to), packet, but=[token.token])
else:

View File

@ -402,13 +402,15 @@ class Client:
self.replyCode(332, description, channel=channel)
# 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 = []
for user in users:
token = glob.tokens.getTokenFromUserID(user)
if token is None:
if user not in glob.tokens.tokens:
continue
usernames.append(chat.fixUsernameForIRC(token.username))
usernames.append(chat.fixUsernameForIRC(glob.tokens.tokens[user].username))
usernames = " ".join(usernames)
# Send IRC users list

View File

@ -40,6 +40,7 @@ class token:
self.lock = threading.Lock() # Sync primitive
self.streams = []
self.tournament = tournament
self.messagesBuffer = []
# Default variables
self.spectators = []
@ -499,4 +500,25 @@ class token:
if self.awayMessage == "" or userID in self.sentAway:
return False
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)