.BANCHO. Add support for tournament client

This commit is contained in:
Nyo 2016-10-05 23:28:26 +02:00
parent 795b6f09be
commit 996287f871
13 changed files with 91 additions and 25 deletions

View File

@ -143,3 +143,12 @@ def transferHost(stream):
def matchInvite(stream):
return packetHelper.readPacketData(stream, [["userID", dataTypes.UINT32]])
def tournamentMatchInfoRequest(stream):
return packetHelper.readPacketData(stream, [["matchID", dataTypes.UINT32]])
def tournamentJoinMatchChannel(stream):
return packetHelper.readPacketData(stream, [["matchID", dataTypes.UINT32]])
def tournamentLeaveMatchChannel(stream):
return packetHelper.readPacketData(stream, [["matchID", dataTypes.UINT32]])

View File

@ -88,4 +88,7 @@ class loginLockedException(Exception):
pass
class unknownStreamException(Exception):
pass
class userTournamentException(Exception):
pass

View File

@ -74,7 +74,9 @@ server_channelInfoEnd = 89
client_matchChangePassword = 90
server_matchChangePassword = 91
server_silenceEnd = 92
client_specialMatchInfoRequest = 93
server_userSilenced = 94
server_userPresenceBundle = 96
client_userPanelRequest = 97
client_tournamentMatchInfoRequest = 93
client_tournamentJoinMatchChannel = 108
client_tournamentLeaveMatchChannel = 109

View File

@ -50,9 +50,10 @@ def mainMenuIcon(icon):
def userSupporterGMT(supporter, GMT):
result = 1
if supporter:
result += 4
result |= userRanks.SUPPORTER
if GMT:
result += 2
result |= userRanks.BAT
result |= userRanks.TOURNAMENT_STAFF
return packetHelper.buildPacket(packetIDs.server_supporterGMT, [[result, dataTypes.UINT32]])
def friendList(userID):
@ -78,9 +79,7 @@ def userLogout(userID):
def userPanel(userID, force = False):
# Connected and restricted check
userToken = glob.tokens.getTokenFromUserID(userID)
if userToken is None:
return bytes()
if userToken.restricted == True and force == False:
if userToken is None or ((userToken.restricted) and not force):
return bytes()
# Get user data
@ -93,16 +92,17 @@ def userPanel(userID, force = False):
# Get username color according to rank
# Only admins and normal users are currently supported
userRank = 0
if username == "FokaBot":
userRank = userRanks.MOD
userRank |= userRanks.MOD
elif userUtils.isInPrivilegeGroup(userID, "community manager"):
userRank = userRanks.MOD
userRank |= userRanks.MOD
elif userUtils.isInPrivilegeGroup(userID, "developer"):
userRank = userRanks.ADMIN
userRank |= userRanks.ADMIN
elif (userToken.privileges & privileges.USER_DONOR) > 0:
userRank = userRanks.SUPPORTER
userRank |= userRanks.SUPPORTER
else:
userRank = userRanks.NORMAL
userRank |= userRanks.NORMAL
return packetHelper.buildPacket(packetIDs.server_userPanel,
[
@ -120,10 +120,7 @@ def userPanel(userID, force = False):
def userStats(userID, force = False):
# Get userID's token from tokens list
userToken = glob.tokens.getTokenFromUserID(userID)
if userToken is None:
return bytes()
if (userToken.restricted == True or userToken.irc == True) and force == False:
if userToken is None or ((userToken.restricted or userToken.irc or userToken.tournament) and not force):
return bytes()
return packetHelper.buildPacket(packetIDs.server_userStats,
@ -204,6 +201,7 @@ def createMatch(matchID):
match = glob.matches.matches[matchID]
return packetHelper.buildPacket(packetIDs.server_newMatch, match.getMatchData())
# TODO: Add match object argument to save some CPU
def updateMatch(matchID):
# Make sure the match exists
if matchID not in glob.matches.matches:

View File

@ -1,8 +1,9 @@
"""Bancho user ranks"""
NORMAL = 0
PLAYER = 1
BAT = 2
SUPPORTER = 4
MOD = 6
PEPPY = 8
ADMIN = 16
TOURNAMENTSTAFF = 32
TOURNAMENT_STAFF = 32

View File

@ -104,8 +104,10 @@ def handle(tornadoRequest):
userUtils.logIP(userID, requestIP)
# Delete old tokens for that user and generate a new one
glob.tokens.deleteOldTokens(userID)
responseToken = glob.tokens.addToken(userID, requestIP, timeOffset=timeOffset)
isTournament = "tourney" in osuVersion
if not isTournament:
glob.tokens.deleteOldTokens(userID)
responseToken = glob.tokens.addToken(userID, requestIP, timeOffset=timeOffset, tournament=isTournament)
responseTokenString = responseToken.token
# Check restricted mode (and eventually send message)
@ -205,7 +207,7 @@ def handle(tornadoRequest):
if userUtils.getCountry(userID) == "XX":
userUtils.setCountry(userID, countryLetters)
# Send to everyone our userpanel if we are not restricted
# Send to everyone our userpanel if we are not restricted or tournament
if not responseToken.restricted:
glob.streams.broadcast("main", serverPackets.userPanel(userID))

View File

@ -0,0 +1,11 @@
from constants import clientPackets
from objects import glob
from helpers import chatHelper as chat
def handle(userToken, packetData):
packetData = clientPackets.tournamentJoinMatchChannel(packetData)
matchID = packetData["matchID"]
if matchID not in glob.matches.matches:
return
userToken.matchID = matchID
chat.joinChannel(token=userToken, channel="#multi_{}".format(matchID))

View File

@ -0,0 +1,11 @@
from constants import clientPackets
from objects import glob
from helpers import chatHelper as chat
def handle(userToken, packetData):
packetData = clientPackets.tournamentLeaveMatchChannel(packetData)
matchID = packetData["matchID"]
if matchID not in glob.matches.matches:
return
chat.partChannel(token=userToken, channel="#multi_{}".format(matchID))
userToken.matchID = 0

View File

@ -0,0 +1,10 @@
from constants import clientPackets
from constants import serverPackets
from objects import glob
def handle(userToken, packetData):
packetData = clientPackets.tournamentMatchInfoRequest(packetData)
matchID = packetData["matchID"]
if matchID not in glob.matches.matches:
return
userToken.enqueue(serverPackets.updateMatch(matchID))

View File

@ -51,6 +51,9 @@ from events import startSpectatingEvent
from events import stopSpectatingEvent
from events import userPanelRequestEvent
from events import userStatsRequestEvent
from events import tournamentMatchInfoRequestEvent
from events import tournamentJoinMatchChannelEvent
from events import tournamentLeaveMatchChannelEvent
from helpers import packetHelper
from objects import glob
@ -156,6 +159,10 @@ class handler(SentryMixin, requestsManager.asyncRequestHandler):
packetIDs.client_matchFailed: handleEvent(matchFailedEvent),
packetIDs.client_matchChangeTeam: handleEvent(matchChangeTeamEvent),
packetIDs.client_invite: handleEvent(matchInviteEvent),
packetIDs.client_tournamentMatchInfoRequest: handleEvent(tournamentMatchInfoRequestEvent),
packetIDs.client_tournamentJoinMatchChannel: handleEvent(tournamentJoinMatchChannelEvent),
packetIDs.client_tournamentLeaveMatchChannel: handleEvent(tournamentLeaveMatchChannelEvent),
}
# Packets processed if in restricted mode.

View File

@ -177,13 +177,17 @@ def sendMessage(fro = "", to = "", message = "", token = None, toIRC = True):
userID = token.userID
username = token.username
# Make sure this is not a tournament client
if token.tournament:
raise exceptions.userTournamentException()
# Make sure the user is not in restricted mode
if token.restricted:
raise exceptions.userRestrictedException
raise exceptions.userRestrictedException()
# Make sure the user is not silenced
if token.isSilenced():
raise exceptions.userSilencedException
raise exceptions.userSilencedException()
# Determine internal name if needed
# (toclient is used clientwise for #multiplayer and #spectator channels)
@ -242,9 +246,13 @@ def sendMessage(fro = "", to = "", message = "", token = None, toIRC = True):
if recipientToken is None:
raise exceptions.userNotFoundException
# Make sure the recipient is not a tournament client
if recipientToken.tournament:
raise exceptions.userTournamentException()
# Make sure the recipient is not restricted or we are FokaBot
if recipientToken.restricted == True and fro.lower() != "fokabot":
raise exceptions.userRestrictedException
raise exceptions.userRestrictedException()
# TODO: Make sure the recipient has not disabled PMs for non-friends or he's our friend
@ -290,6 +298,9 @@ def sendMessage(fro = "", to = "", message = "", token = None, toIRC = True):
except exceptions.userRestrictedException:
log.warning("{} tried to send a message {}, but the recipient is in restricted mode".format(username, to))
return 404
except exceptions.userTournamentException:
log.warning("{} tried to send a message {}, but the recipient is a tournament client".format(username, to))
return 404
except exceptions.userNotFoundException:
log.warning("User not connected to IRC/Bancho")
return 401

View File

@ -13,7 +13,7 @@ from objects import glob
class token:
def __init__(self, userID, token_ = None, ip ="", irc = False, timeOffset = 0):
def __init__(self, userID, token_ = None, ip ="", irc = False, timeOffset = 0, tournament = False):
"""
Create a token object and set userID and token
@ -36,6 +36,7 @@ class token:
self.timeOffset = timeOffset
self.lock = threading.Lock() # Sync primitive
self.streams = []
self.tournament = tournament
# Default variables
self.spectators = []

View File

@ -20,7 +20,7 @@ class tokenList:
"""
self.tokens = {}
def addToken(self, userID, ip = "", irc = False, timeOffset=0):
def addToken(self, userID, ip = "", irc = False, timeOffset=0, tournament=False):
"""
Add a token object to tokens list
@ -28,7 +28,7 @@ class tokenList:
irc -- if True, set this token as IRC client
return -- token object
"""
newToken = osuToken.token(userID, ip=ip, irc=irc, timeOffset=timeOffset)
newToken = osuToken.token(userID, ip=ip, irc=irc, timeOffset=timeOffset, tournament=tournament)
self.tokens[newToken.token] = newToken
return newToken