Merged with upstream
This commit is contained in:
commit
2cd69a9a63
3
.gitignore
vendored
3
.gitignore
vendored
|
@ -6,4 +6,5 @@ filters.txt
|
|||
.idea
|
||||
redistest.py
|
||||
*.c
|
||||
*.so
|
||||
*.so
|
||||
.pyenv
|
|
@ -40,10 +40,10 @@ def instantRestart(fro, chan, message):
|
|||
return False
|
||||
|
||||
def faq(fro, chan, message):
|
||||
if message[0] in glob.conf.extra["faq"]:
|
||||
return glob.conf.extra["faq"][message[0]]
|
||||
|
||||
return False
|
||||
key = message[0].lower()
|
||||
if key not in glob.conf.extra["faq"]:
|
||||
return False
|
||||
return glob.conf.extra["faq"][key]
|
||||
|
||||
def roll(fro, chan, message):
|
||||
maxPoints = 100
|
||||
|
@ -58,8 +58,8 @@ def roll(fro, chan, message):
|
|||
# return random.choice(["yes", "no", "maybe"])
|
||||
|
||||
def alert(fro, chan, message):
|
||||
msg = ' '.join(message[:])
|
||||
if not msg.strip():
|
||||
msg = ' '.join(message[:]).strip()
|
||||
if not msg:
|
||||
return False
|
||||
glob.streams.broadcast("main", serverPackets.notification(msg))
|
||||
return False
|
||||
|
@ -68,8 +68,8 @@ def alertUser(fro, chan, message):
|
|||
target = message[0].lower()
|
||||
targetToken = glob.tokens.getTokenFromUsername(userUtils.safeUsername(target), safe=True)
|
||||
if targetToken is not None:
|
||||
msg = ' '.join(message[1:])
|
||||
if not msg.strip():
|
||||
msg = ' '.join(message[1:]).strip()
|
||||
if not msg:
|
||||
return False
|
||||
targetToken.enqueue(serverPackets.notification(msg))
|
||||
return False
|
||||
|
@ -137,12 +137,15 @@ def fokabotReconnect(fro, chan, message):
|
|||
return False
|
||||
|
||||
def silence(fro, chan, message):
|
||||
for i in message:
|
||||
i = i.lower()
|
||||
message = [x.lower() for x in message]
|
||||
target = message[0]
|
||||
amount = message[1]
|
||||
unit = message[2]
|
||||
reason = ' '.join(message[3:])
|
||||
reason = ' '.join(message[3:]).strip()
|
||||
if not reason:
|
||||
return "Please provide a valid reason."
|
||||
if not amount.isdigit():
|
||||
return "The amount must be a number."
|
||||
|
||||
# Get target user ID
|
||||
targetUserID = userUtils.getIDSafe(target)
|
||||
|
@ -758,7 +761,10 @@ def multiplayer(fro, chan, message):
|
|||
def mpMake():
|
||||
if len(message) < 2:
|
||||
raise exceptions.invalidArgumentsException("Wrong syntax: !mp make <name>")
|
||||
matchID = glob.matches.createMatch(" ".join(message[1:]), generalUtils.stringMd5(generalUtils.randomString(32)), 0, "Tournament", "", 0, -1, isTourney=True)
|
||||
matchName = " ".join(message[1:]).strip()
|
||||
if not matchName:
|
||||
raise exceptions.invalidArgumentsException("Match name must not be empty!")
|
||||
matchID = glob.matches.createMatch(matchName, generalUtils.stringMd5(generalUtils.randomString(32)), 0, "Tournament", "", 0, -1, isTourney=True)
|
||||
glob.matches.matches[matchID].sendUpdates()
|
||||
return "Tourney match #{} created!".format(matchID)
|
||||
|
||||
|
@ -812,7 +818,9 @@ def multiplayer(fro, chan, message):
|
|||
def mpHost():
|
||||
if len(message) < 2:
|
||||
raise exceptions.invalidArgumentsException("Wrong syntax: !mp host <username>")
|
||||
username = message[1]
|
||||
username = message[1].strip()
|
||||
if not username:
|
||||
raise exceptions.invalidArgumentsException("Please provide a username")
|
||||
userID = userUtils.getIDSafe(username)
|
||||
if userID is None:
|
||||
raise exceptions.userNotFoundException("No such user")
|
||||
|
@ -877,7 +885,9 @@ def multiplayer(fro, chan, message):
|
|||
def mpInvite():
|
||||
if len(message) < 2:
|
||||
raise exceptions.invalidArgumentsException("Wrong syntax: !mp invite <username>")
|
||||
username = message[1]
|
||||
username = message[1].strip()
|
||||
if not username:
|
||||
raise exceptions.invalidArgumentsException("Please provide a username")
|
||||
userID = userUtils.getIDSafe(username)
|
||||
if userID is None:
|
||||
raise exceptions.userNotFoundException("No such user")
|
||||
|
@ -944,7 +954,9 @@ def multiplayer(fro, chan, message):
|
|||
def mpKick():
|
||||
if len(message) < 2:
|
||||
raise exceptions.invalidArgumentsException("Wrong syntax: !mp kick <username>")
|
||||
username = message[1]
|
||||
username = message[1].strip()
|
||||
if not username:
|
||||
raise exceptions.invalidArgumentsException("Please provide a username")
|
||||
userID = userUtils.getIDSafe(username)
|
||||
if userID is None:
|
||||
raise exceptions.userNotFoundException("No such user")
|
||||
|
@ -957,7 +969,7 @@ def multiplayer(fro, chan, message):
|
|||
return "{} has been kicked from the match.".format(username)
|
||||
|
||||
def mpPassword():
|
||||
password = "" if len(message) < 2 else message[1]
|
||||
password = "" if len(message) < 2 or not message[1].strip() else message[1]
|
||||
_match = glob.matches.matches[getMatchIDFromChannel(chan)]
|
||||
_match.changePassword(password)
|
||||
return "Match password has been changed!"
|
||||
|
@ -1001,7 +1013,9 @@ def multiplayer(fro, chan, message):
|
|||
def mpTeam():
|
||||
if len(message) < 3:
|
||||
raise exceptions.invalidArgumentsException("Wrong syntax: !mp team <username> <colour>")
|
||||
username = message[1]
|
||||
username = message[1].strip()
|
||||
if not username:
|
||||
raise exceptions.invalidArgumentsException("Please provide a username")
|
||||
colour = message[2].lower().strip()
|
||||
if colour not in ["red", "blue"]:
|
||||
raise exceptions.invalidArgumentsException("Team colour must be red or blue")
|
||||
|
@ -1068,7 +1082,7 @@ def multiplayer(fro, chan, message):
|
|||
if requestedSubcommand not in subcommands:
|
||||
raise exceptions.invalidArgumentsException("Invalid subcommand")
|
||||
return subcommands[requestedSubcommand]()
|
||||
except (exceptions.invalidArgumentsException, exceptions.userNotFoundException) as e:
|
||||
except (exceptions.invalidArgumentsException, exceptions.userNotFoundException, exceptions.invalidUserException) as e:
|
||||
return str(e)
|
||||
except exceptions.wrongChannelException:
|
||||
return "This command only works in multiplayer chat channels"
|
||||
|
@ -1080,7 +1094,9 @@ def multiplayer(fro, chan, message):
|
|||
def switchServer(fro, chan, message):
|
||||
# Get target user ID
|
||||
target = message[0]
|
||||
newServer = message[1]
|
||||
newServer = message[1].strip()
|
||||
if not newServer:
|
||||
return "Invalid server IP"
|
||||
targetUserID = userUtils.getIDSafe(target)
|
||||
userID = userUtils.getID(fro)
|
||||
|
||||
|
@ -1098,7 +1114,9 @@ def switchServer(fro, chan, message):
|
|||
|
||||
def rtx(fro, chan, message):
|
||||
target = message[0]
|
||||
message = " ".join(message[1:])
|
||||
message = " ".join(message[1:]).strip()
|
||||
if not message:
|
||||
return "Invalid message"
|
||||
targetUserID = userUtils.getIDSafe(target)
|
||||
if not targetUserID:
|
||||
return "{}: user not found".format(target)
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
from common.log import logUtils as log
|
||||
from constants import clientPackets
|
||||
from constants import clientPackets, serverPackets
|
||||
from constants import exceptions
|
||||
from objects import glob
|
||||
|
||||
|
@ -12,9 +12,14 @@ def handle(userToken, packetData):
|
|||
# Read packet data
|
||||
packetData = clientPackets.createMatch(packetData)
|
||||
|
||||
# Make sure the name is valid
|
||||
matchName = packetData["matchName"].strip()
|
||||
if not matchName:
|
||||
raise exceptions.matchCreateError()
|
||||
|
||||
# Create a match object
|
||||
# TODO: Player number check
|
||||
matchID = glob.matches.createMatch(packetData["matchName"], packetData["matchPassword"], packetData["beatmapID"], packetData["beatmapName"], packetData["beatmapMD5"], packetData["gameMode"], userID)
|
||||
matchID = glob.matches.createMatch(matchName, packetData["matchPassword"].strip(), packetData["beatmapID"], packetData["beatmapName"], packetData["beatmapMD5"], packetData["gameMode"], userID)
|
||||
|
||||
# Make sure the match has been created
|
||||
if matchID not in glob.matches.matches:
|
||||
|
@ -30,3 +35,4 @@ def handle(userToken, packetData):
|
|||
match.changePassword(packetData["matchPassword"])
|
||||
except exceptions.matchCreateError:
|
||||
log.error("Error while creating match!")
|
||||
userToken.enqueue(serverPackets.matchJoinFail())
|
||||
|
|
|
@ -79,7 +79,7 @@ def partChannel(userID = 0, channel = "", token = None, toIRC = True, kick = Fal
|
|||
token = glob.tokens.getTokenFromUserID(userID)
|
||||
# Make sure the token exists
|
||||
if token is None:
|
||||
raise exceptions.userNotFoundException
|
||||
raise exceptions.userNotFoundException()
|
||||
else:
|
||||
token = token
|
||||
|
||||
|
@ -157,7 +157,7 @@ def sendMessage(fro = "", to = "", message = "", token = None, toIRC = True):
|
|||
if token is None:
|
||||
token = glob.tokens.getTokenFromUsername(fro)
|
||||
if token is None:
|
||||
raise exceptions.userNotFoundException
|
||||
raise exceptions.userNotFoundException()
|
||||
else:
|
||||
# token object alredy passed, get its string and its username (fro)
|
||||
fro = token.username
|
||||
|
@ -194,6 +194,11 @@ def sendMessage(fro = "", to = "", message = "", token = None, toIRC = True):
|
|||
toClient = "#spectator"
|
||||
elif to.startswith("#multi_"):
|
||||
toClient = "#multiplayer"
|
||||
|
||||
# Make sure the message is valid
|
||||
if not message.strip():
|
||||
raise exceptions.invalidArgumentsException()
|
||||
|
||||
# Truncate message if > 2048 characters
|
||||
message = message[:2048]+"..." if len(message) > 2048 else message
|
||||
|
||||
|
@ -297,6 +302,9 @@ def sendMessage(fro = "", to = "", message = "", token = None, toIRC = True):
|
|||
except exceptions.userNotFoundException:
|
||||
log.warning("User not connected to IRC/Bancho")
|
||||
return 401
|
||||
except exceptions.invalidArgumentsException:
|
||||
log.warning("{} tried to send an invalid message to {}".format(token.username, to))
|
||||
return 404
|
||||
|
||||
|
||||
""" IRC-Bancho Connect/Disconnect/Join/Part interfaces"""
|
||||
|
|
|
@ -28,7 +28,7 @@ def printServerStartHeader(asciiArt=True):
|
|||
|
||||
printColored("> Welcome to pep.py osu!bancho server v{}".format(glob.VERSION), bcolors.GREEN)
|
||||
printColored("> Made by the Ripple team", bcolors.GREEN)
|
||||
printColored("> {}https://git.zxq.co/ripple/pep.py".format(bcolors.UNDERLINE), bcolors.GREEN)
|
||||
printColored("> {}https://zxq.co/ripple/pep.py".format(bcolors.UNDERLINE), bcolors.GREEN)
|
||||
printColored("> Press CTRL+C to exit\n", bcolors.GREEN)
|
||||
|
||||
def printNoNl(string):
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
import copy
|
||||
import json
|
||||
import threading
|
||||
|
||||
import time
|
||||
|
||||
from common.log import logUtils as log
|
||||
from constants import dataTypes
|
||||
from constants import matchModModes
|
||||
|
@ -62,6 +65,7 @@ class match:
|
|||
self.isLocked = False # if True, users can't change slots/teams. Used in tourney matches
|
||||
self.isStarting = False
|
||||
self._lock = threading.Lock()
|
||||
self.createTime = int(time.time())
|
||||
|
||||
# Create all slots and reset them
|
||||
self.slots = []
|
||||
|
|
|
@ -1,3 +1,6 @@
|
|||
import threading
|
||||
import time
|
||||
|
||||
from objects import match
|
||||
from objects import glob
|
||||
from constants import serverPackets
|
||||
|
@ -62,4 +65,32 @@ class matchList:
|
|||
# Send match dispose packet to everyone in lobby
|
||||
glob.streams.broadcast("lobby", serverPackets.disposeMatch(matchID))
|
||||
del self.matches[matchID]
|
||||
log.info("MPROOM{}: Room disposed manually".format(_match.matchID))
|
||||
log.info("MPROOM{}: Room disposed manually".format(_match.matchID))
|
||||
|
||||
def cleanupLoop(self):
|
||||
"""
|
||||
Start match cleanup loop.
|
||||
Empty matches that have been created more than 60 seconds ago will get deleted.
|
||||
Useful when people create useless lobbies with `!mp make`.
|
||||
The check is done every 30 seconds.
|
||||
This method starts an infinite loop, call it only once!
|
||||
:return:
|
||||
"""
|
||||
log.debug("Checking empty matches")
|
||||
t = int(time.time())
|
||||
emptyMatches = []
|
||||
|
||||
# Collect all empty matches
|
||||
for key, m in self.matches.items():
|
||||
if [x for x in m.slots if x.user is not None]:
|
||||
continue
|
||||
if t - m.createTime >= 120:
|
||||
log.debug("Match #{} marked for cleanup".format(m.matchID))
|
||||
emptyMatches.append(m.matchID)
|
||||
|
||||
# Dispose all empty matches
|
||||
for matchID in emptyMatches:
|
||||
self.disposeMatch(matchID)
|
||||
|
||||
# Schedule a new check (endless loop)
|
||||
threading.Timer(30, self.cleanupLoop).start()
|
|
@ -171,19 +171,16 @@ class tokenList:
|
|||
for _, value in self.tokens.items():
|
||||
value.enqueue(packet)
|
||||
|
||||
def usersTimeoutCheckLoop(self, timeoutTime = 100, checkTime = 100):
|
||||
def usersTimeoutCheckLoop(self):
|
||||
"""
|
||||
Start timed out users disconnect loop.
|
||||
This function will be called every `checkTime` seconds and so on, forever.
|
||||
CALL THIS FUNCTION ONLY ONCE!
|
||||
|
||||
:param timeoutTime: seconds of inactivity required to disconnect someone. Default: 100
|
||||
:param checkTime: seconds between loops. Default: 100
|
||||
:return:
|
||||
"""
|
||||
log.debug("Checking timed out clients")
|
||||
timedOutTokens = [] # timed out users
|
||||
timeoutLimit = int(time.time())-timeoutTime
|
||||
timeoutLimit = int(time.time()) - 100
|
||||
for key, value in self.tokens.items():
|
||||
# Check timeout (fokabot is ignored)
|
||||
if value.pingTime < timeoutLimit and value.userID != 999 and value.irc == False and value.tournament == False:
|
||||
|
@ -200,7 +197,7 @@ class tokenList:
|
|||
del timedOutTokens
|
||||
|
||||
# Schedule a new check (endless loop)
|
||||
threading.Timer(checkTime, self.usersTimeoutCheckLoop, [timeoutTime, checkTime]).start()
|
||||
threading.Timer(100, self.usersTimeoutCheckLoop).start()
|
||||
|
||||
def spamProtectionResetLoop(self):
|
||||
"""
|
||||
|
|
5
pep.py
5
pep.py
|
@ -187,6 +187,11 @@ if __name__ == "__main__":
|
|||
glob.tokens.spamProtectionResetLoop()
|
||||
consoleHelper.printDone()
|
||||
|
||||
# Initialize multiplayer cleanup loop
|
||||
consoleHelper.printNoNl("> Initializing multiplayer cleanup loop... ")
|
||||
glob.matches.cleanupLoop()
|
||||
consoleHelper.printDone()
|
||||
|
||||
# Localize warning
|
||||
glob.localize = generalUtils.stringToBool(glob.conf.config["localize"]["enable"])
|
||||
if not glob.localize:
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
requests
|
||||
tornado
|
||||
mysqlclient
|
||||
psutil
|
||||
raven
|
||||
bcrypt>=3.1.1
|
||||
dill
|
||||
redis
|
||||
cython
|
||||
datadog
|
||||
requests==2.18.1
|
||||
tornado==4.4.2
|
||||
mysqlclient==1.3.9
|
||||
psutil==5.2.2
|
||||
raven==5.32.0
|
||||
bcrypt==3.1.1
|
||||
dill==0.2.7.1
|
||||
redis==2.10.5
|
||||
cython==0.27.3
|
||||
datadog==0.14.0
|
Loading…
Reference in New Issue
Block a user