.BANCHO. Implemented packet streams for spectator and lobby

This commit is contained in:
Nyo 2016-10-04 22:10:07 +02:00
parent cd3054c83c
commit afbd8e7e8c
13 changed files with 105 additions and 108 deletions

View File

@ -48,22 +48,16 @@ if userToken.matchID != -1 and userToken.actionID != actions.MULTIPLAYING and us
userToken.beatmapID = packetData["beatmapID"]
# Enqueue our new user panel and stats to us and our spectators
recipients = [userID]
recipients = [userToken]
if len(userToken.spectators) > 0:
recipients += userToken.spectators
for i in recipients:
if i == userID:
# Save some loops
token = userToken
else:
token = glob.tokens.getTokenFromUserID(i)
if token is not None:
if i is not None:
# Force our own packet
force = True if token.userID == userID else False
token.enqueue(serverPackets.userPanel(userID, force))
token.enqueue(serverPackets.userStats(userID, force))
force = True if i == userToken else False
i.enqueue(serverPackets.userPanel(userID, force))
i.enqueue(serverPackets.userStats(userID, force))
# Console output
log.info("{} changed action: {} [{}][{}][{}]".format(username, str(userToken.actionID), userToken.actionText, userToken.actionMd5, userToken.beatmapID))

View File

@ -32,11 +32,7 @@ def handle(userToken, packetData):
match.setHost(userID)
# Send match create packet to everyone in lobby
for i in glob.matches.usersInLobby:
# Make sure this user is still connected
token = glob.tokens.getTokenFromUserID(i)
if token is not None:
token.enqueue(serverPackets.createMatch(matchID))
glob.streams.broadcast("lobby", serverPackets.createMatch(matchID))
# Console output
log.info("MPROOM{}: Room created!".format(matchID))

View File

@ -6,10 +6,9 @@ from objects import glob
def handle(userToken, _):
# Get userToken data
username = userToken.username
userID = userToken.userID
# Add user to users in lobby
glob.matches.lobbyUserJoin(userID)
userToken.joinStream("lobby")
# Send matches data
for key, _ in glob.matches.matches.items():

View File

@ -9,7 +9,7 @@ def handle(userToken, _):
username = userToken.username
# Remove user from users in lobby
glob.matches.lobbyUserPart(userID)
userToken.leaveStream("lobby")
# Part lobby channel
chat.partChannel(channel="#lobby", token=userToken, kick=True)

View File

@ -7,7 +7,8 @@ def handle(userToken, packetData):
userID = userToken.userID
# Send spectator frames to every spectator
for i in userToken.spectators:
glob.streams.broadcast("spect/{}".format(userID), serverPackets.spectatorFrames(packetData[7:]))
'''for i in userToken.spectators:
# Send to every user but host
if i != userID:
try:
@ -27,4 +28,4 @@ def handle(userToken, packetData):
except exceptions.stopSpectating:
# Remove this user from spectators
userToken.removeSpectator(i)
userToken.enqueue(serverPackets.removeSpectator(i))
userToken.enqueue(serverPackets.removeSpectator(i))'''

View File

@ -1,57 +1,20 @@
from common.log import logUtils as log
from common.ripple import userUtils
from constants import clientPackets
from constants import exceptions
from constants import serverPackets
from helpers import chatHelper as chat
from objects import glob
def handle(userToken, packetData):
try:
# Get usertoken data
userID = userToken.userID
username = userToken.username
# Start spectating packet
packetData = clientPackets.startSpectating(packetData)
# Stop spectating old user if needed
if userToken.spectating != 0:
oldTargetToken = glob.tokens.getTokenFromUserID(userToken.spectating)
oldTargetToken.enqueue(serverPackets.removeSpectator(userID))
userToken.stopSpectating()
# Start spectating new user
userToken.startSpectating(packetData["userID"])
# Get host token
targetToken = glob.tokens.getTokenFromUserID(packetData["userID"])
if targetToken is None:
raise exceptions.tokenNotFoundException
# Add us to host's spectators
targetToken.addSpectator(userID)
# Send spectator join packet to host
targetToken.enqueue(serverPackets.addSpectator(userID))
# Create and join #spectator (#spect_userid) channel
glob.channels.addTempChannel("#spect_{}".format(targetToken.userID))
chat.joinChannel(token=userToken, channel="#spect_{}".format(targetToken.userID))
if len(targetToken.spectators) == 1:
# First spectator, send #spectator join to host too
chat.joinChannel(token=targetToken, channel="#spect_{}".format(targetToken.userID))
# send fellowSpectatorJoined to all spectators
for spec in targetToken.spectators:
if spec is not userID:
c = glob.tokens.getTokenFromUserID(spec)
userToken.enqueue(serverPackets.fellowSpectatorJoined(c.userID))
c.enqueue(serverPackets.fellowSpectatorJoined(userID))
# Console output
log.info("{} are spectating {}".format(username, userUtils.getUsername(packetData["userID"])))
# Start spectating new user
userToken.startSpectating(targetToken)
except exceptions.tokenNotFoundException:
# Stop spectating if token not found
log.warning("Spectator start: token not found")

View File

@ -105,10 +105,10 @@ def partChannel(userID = 0, channel = "", token = None, toIRC = True, kick = Fal
# (toclient is used clientwise for #multiplayer and #spectator channels)
channelClient = channel
if channel == "#spectator":
if token.spectating == 0:
if token.spectating is None:
s = userID
else:
s = token.spectating
s = token.spectating.userID
channel = "#spect_{}".format(s)
elif channel == "#multiplayer":
channel = "#multi_{}".format(token.matchID)
@ -189,10 +189,10 @@ def sendMessage(fro = "", to = "", message = "", token = None, toIRC = True):
# (toclient is used clientwise for #multiplayer and #spectator channels)
toClient = to
if to == "#spectator":
if token.spectating == 0:
if token.spectating is None:
s = userID
else:
s = token.spectating
s = token.spectating.userID
to = "#spect_{}".format(s)
elif to == "#multiplayer":
to = "#multi_{}".format(token.matchID)

View File

@ -633,10 +633,7 @@ class match:
token.enqueue(serverPackets.updateMatch(self.matchID))
# Send to users in lobby
for i in glob.matches.usersInLobby:
token = glob.tokens.getTokenFromUserID(i)
if token is not None:
token.enqueue(serverPackets.updateMatch(self.matchID))
glob.streams.broadcast("lobby", serverPackets.updateMatch(self.matchID))
def checkTeams(self):
"""

View File

@ -3,14 +3,9 @@ from objects import glob
from constants import serverPackets
class matchList:
matches = {}
usersInLobby = []
lastID = 1
def __init__(self):
"""Initialize a matchList object"""
self.matches = {}
self.usersInLobby = []
self.lastID = 1
def createMatch(self, matchName, matchPassword, beatmapID, beatmapName, beatmapMD5, gameMode, hostUserID):
@ -32,7 +27,7 @@ class matchList:
self.matches[matchID] = match.match(matchID, matchName, matchPassword, beatmapID, beatmapName, beatmapMD5, gameMode, hostUserID)
return matchID
def lobbyUserJoin(self, userID):
'''def lobbyUserJoin(self, userID):
"""
Add userID to users in lobby
@ -52,7 +47,7 @@ class matchList:
# Make sure the user is in mp lobby
if userID in self.usersInLobby:
# Part lobby and #lobby channel
self.usersInLobby.remove(userID)
self.usersInLobby.remove(userID)'''
def disposeMatch(self, matchID):
"""
@ -68,7 +63,4 @@ class matchList:
self.matches.pop(matchID)
# Send match dispose packet to everyone in lobby
for i in self.usersInLobby:
token = glob.tokens.getTokenFromUserID(i)
if token is not None:
token.enqueue(serverPackets.disposeMatch(matchID))
glob.streams.broadcast("lobby", serverPackets.disposeMatch(matchID))

View File

@ -39,7 +39,7 @@ class token:
# Default variables
self.spectators = []
self.spectating = 0
self.spectating = None
self.location = [0,0]
self.joinedChannels = []
self.ip = ip
@ -141,42 +141,80 @@ class token:
"""
return self.location[1]
def startSpectating(self, userID):
def startSpectating(self, host):
"""
Set the spectating user to userID
userID -- target userID
user -- user object
"""
self.spectating = userID
# Stop spectating old client
self.stopSpectating()
# Set new spectator host
self.spectating = host
# Add us to host's spectator list
host.spectators.append(self)
# Create and join spectator stream
streamName = "spect/{}".format(self.spectating.userID)
glob.streams.add(streamName)
self.joinStream(streamName)
host.joinStream(streamName)
# Send spectator join packet to host
host.enqueue(serverPackets.addSpectator(self.userID))
# Create and join #spectator (#spect_userid) channel
glob.channels.addTempChannel("#spect_{}".format(host.userID))
chat.joinChannel(token=self, channel="#spect_{}".format(host.userID))
if len(host.spectators) == 1:
# First spectator, send #spectator join to host too
chat.joinChannel(token=host, channel="#spect_{}".format(host.userID))
# Send fellow spectator join to all clients
glob.streams.broadcast(streamName, serverPackets.fellowSpectatorJoined(self.userID))
# Get current spectators list
for i in host.spectators:
if i != self:
self.enqueue(serverPackets.fellowSpectatorJoined(i.userID))
# Log
log.info("{} are spectating {}".format(self.username, userUtils.getUsername(host.username)))
def stopSpectating(self):
# Remove our userID from host's spectators
target = self.spectating
if self.spectating == 0:
if self.spectating == None:
return
targetToken = glob.tokens.getTokenFromUserID(target)
if targetToken is not None:
# Remove us from host's spectators list
targetToken.removeSpectator(self.userID)
streamName = "spect/{}".format(self.spectating.userID)
# Send the spectator left packet to host
targetToken.enqueue(serverPackets.removeSpectator(self.userID))
for c in targetToken.spectators:
spec = glob.tokens.getTokenFromUserID(c)
spec.enqueue(serverPackets.fellowSpectatorLeft(self.userID))
# Remove us from host's spectators list
# and leave spectator stream
self.leaveStream(streamName)
self.spectating.spectators.remove(self)
# If nobody is spectating the host anymore, close #spectator channel
if len(targetToken.spectators) == 0:
chat.partChannel(token=targetToken, channel="#spect_{}".format(target), kick=True)
# Send the spectator left packet to host
self.spectating.enqueue(serverPackets.removeSpectator(self.userID))
# and to all other spectators
for i in self.spectating.spectators:
i.enqueue(serverPackets.fellowSpectatorLeft(self.userID))
# If nobody is spectating the host anymore, close #spectator channel
# and remove host from spect stream too
if len(self.spectating.spectators) == 0:
chat.partChannel(token=self.spectating, channel="#spect_{}".format(self.spectating.userID), kick=True)
self.spectating.leaveStream(streamName)
# Part #spectator channel
chat.partChannel(token=self, channel="#spect_{}".format(target), kick=True)
# Set our spectating user to 0
self.spectating = 0
chat.partChannel(token=self, channel="#spect_{}".format(self.spectating.userID), kick=True)
# Console output
log.info("{} are no longer spectating {}".format(self.username, target))
log.info("{} are no longer spectating {}".format(self.username, self.spectating.userID))
# Set our spectating user to 0
self.spectating = None
def partMatch(self):
# Make sure we are in a match
@ -199,15 +237,15 @@ class token:
# Set usertoken match to -1
self.matchID = -1
def addSpectator(self, userID):
'''def addSpectator(self, user):
"""
Add userID to our spectators
userID -- new spectator userID
user -- user object
"""
# Add userID to spectators if not already in
if userID not in self.spectators:
self.spectators.append(userID)
if user not in self.spectators:
self.spectators.append(user)
def removeSpectator(self, userID):
"""
@ -217,7 +255,7 @@ class token:
"""
# Remove spectator
if userID in self.spectators:
self.spectators.remove(userID)
self.spectators.remove(userID)'''
def setCountry(self, countryID):
"""

View File

@ -1,3 +1,5 @@
from common.log import logUtils as log
class stream:
def __init__(self, name):
"""
@ -16,6 +18,7 @@ class stream:
:return:
"""
if client not in self.clients:
log.info("{} has joined stream {}".format(client.username, self.name))
self.clients.append(client)
def removeClient(self, client):
@ -26,6 +29,7 @@ class stream:
:return:
"""
if client in self.clients:
log.info("{} has left stream {}".format(client.username, self.name))
self.clients.remove(client)
def broadcast(self, data):

View File

@ -13,6 +13,7 @@ class streamList:
"""
if name not in self.streams:
self.streams[name] = stream.stream(name)
print(str(self.streams))
def remove(self, name):
"""
@ -38,6 +39,17 @@ class streamList:
return
self.streams[streamName].broadcast(data)
def getClients(self, streamName):
"""
Get all clients in a stream
:param streamName: name of the stream
:return:
"""
if streamName not in self.streams:
return
return self.streams[streamName].clients
def join(self, streamName, client):
"""
Add a client to a stream

3
pep.py
View File

@ -128,8 +128,9 @@ if __name__ == "__main__":
consoleHelper.printDone()
# Initialize stremas
consoleHelper.printNoNl("> Creating main stream... ")
consoleHelper.printNoNl("> Creating packets streams... ")
glob.streams.add("main")
glob.streams.add("lobby")
consoleHelper.printDone()
# Start fokabot