.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"] userToken.beatmapID = packetData["beatmapID"]
# Enqueue our new user panel and stats to us and our spectators # Enqueue our new user panel and stats to us and our spectators
recipients = [userID] recipients = [userToken]
if len(userToken.spectators) > 0: if len(userToken.spectators) > 0:
recipients += userToken.spectators recipients += userToken.spectators
for i in recipients: for i in recipients:
if i == userID: if i is not None:
# Save some loops
token = userToken
else:
token = glob.tokens.getTokenFromUserID(i)
if token is not None:
# Force our own packet # Force our own packet
force = True if token.userID == userID else False force = True if i == userToken else False
token.enqueue(serverPackets.userPanel(userID, force)) i.enqueue(serverPackets.userPanel(userID, force))
token.enqueue(serverPackets.userStats(userID, force)) i.enqueue(serverPackets.userStats(userID, force))
# Console output # Console output
log.info("{} changed action: {} [{}][{}][{}]".format(username, str(userToken.actionID), userToken.actionText, userToken.actionMd5, userToken.beatmapID)) 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) match.setHost(userID)
# Send match create packet to everyone in lobby # Send match create packet to everyone in lobby
for i in glob.matches.usersInLobby: glob.streams.broadcast("lobby", serverPackets.createMatch(matchID))
# Make sure this user is still connected
token = glob.tokens.getTokenFromUserID(i)
if token is not None:
token.enqueue(serverPackets.createMatch(matchID))
# Console output # Console output
log.info("MPROOM{}: Room created!".format(matchID)) log.info("MPROOM{}: Room created!".format(matchID))

View File

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

View File

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

View File

@ -7,7 +7,8 @@ def handle(userToken, packetData):
userID = userToken.userID userID = userToken.userID
# Send spectator frames to every spectator # 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 # Send to every user but host
if i != userID: if i != userID:
try: try:
@ -27,4 +28,4 @@ def handle(userToken, packetData):
except exceptions.stopSpectating: except exceptions.stopSpectating:
# Remove this user from spectators # Remove this user from spectators
userToken.removeSpectator(i) 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.log import logUtils as log
from common.ripple import userUtils
from constants import clientPackets from constants import clientPackets
from constants import exceptions from constants import exceptions
from constants import serverPackets
from helpers import chatHelper as chat
from objects import glob from objects import glob
def handle(userToken, packetData): def handle(userToken, packetData):
try: try:
# Get usertoken data
userID = userToken.userID
username = userToken.username
# Start spectating packet # Start spectating packet
packetData = clientPackets.startSpectating(packetData) 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 # Get host token
targetToken = glob.tokens.getTokenFromUserID(packetData["userID"]) targetToken = glob.tokens.getTokenFromUserID(packetData["userID"])
if targetToken is None: if targetToken is None:
raise exceptions.tokenNotFoundException raise exceptions.tokenNotFoundException
# Add us to host's spectators # Start spectating new user
targetToken.addSpectator(userID) userToken.startSpectating(targetToken)
# 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"])))
except exceptions.tokenNotFoundException: except exceptions.tokenNotFoundException:
# Stop spectating if token not found # Stop spectating if token not found
log.warning("Spectator start: 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) # (toclient is used clientwise for #multiplayer and #spectator channels)
channelClient = channel channelClient = channel
if channel == "#spectator": if channel == "#spectator":
if token.spectating == 0: if token.spectating is None:
s = userID s = userID
else: else:
s = token.spectating s = token.spectating.userID
channel = "#spect_{}".format(s) channel = "#spect_{}".format(s)
elif channel == "#multiplayer": elif channel == "#multiplayer":
channel = "#multi_{}".format(token.matchID) 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 is used clientwise for #multiplayer and #spectator channels)
toClient = to toClient = to
if to == "#spectator": if to == "#spectator":
if token.spectating == 0: if token.spectating is None:
s = userID s = userID
else: else:
s = token.spectating s = token.spectating.userID
to = "#spect_{}".format(s) to = "#spect_{}".format(s)
elif to == "#multiplayer": elif to == "#multiplayer":
to = "#multi_{}".format(token.matchID) to = "#multi_{}".format(token.matchID)

View File

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

View File

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

View File

@ -39,7 +39,7 @@ class token:
# Default variables # Default variables
self.spectators = [] self.spectators = []
self.spectating = 0 self.spectating = None
self.location = [0,0] self.location = [0,0]
self.joinedChannels = [] self.joinedChannels = []
self.ip = ip self.ip = ip
@ -141,42 +141,80 @@ class token:
""" """
return self.location[1] return self.location[1]
def startSpectating(self, userID): def startSpectating(self, host):
""" """
Set the spectating user to userID 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): def stopSpectating(self):
# Remove our userID from host's spectators # Remove our userID from host's spectators
target = self.spectating if self.spectating == None:
if self.spectating == 0:
return return
targetToken = glob.tokens.getTokenFromUserID(target) streamName = "spect/{}".format(self.spectating.userID)
if targetToken is not None:
# Remove us from host's spectators list
targetToken.removeSpectator(self.userID)
# Send the spectator left packet to host # Remove us from host's spectators list
targetToken.enqueue(serverPackets.removeSpectator(self.userID)) # and leave spectator stream
for c in targetToken.spectators: self.leaveStream(streamName)
spec = glob.tokens.getTokenFromUserID(c) self.spectating.spectators.remove(self)
spec.enqueue(serverPackets.fellowSpectatorLeft(self.userID))
# If nobody is spectating the host anymore, close #spectator channel # Send the spectator left packet to host
if len(targetToken.spectators) == 0: self.spectating.enqueue(serverPackets.removeSpectator(self.userID))
chat.partChannel(token=targetToken, channel="#spect_{}".format(target), kick=True)
# 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 # Part #spectator channel
chat.partChannel(token=self, channel="#spect_{}".format(target), kick=True) chat.partChannel(token=self, channel="#spect_{}".format(self.spectating.userID), kick=True)
# Set our spectating user to 0
self.spectating = 0
# Console output # 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): def partMatch(self):
# Make sure we are in a match # Make sure we are in a match
@ -199,15 +237,15 @@ class token:
# Set usertoken match to -1 # Set usertoken match to -1
self.matchID = -1 self.matchID = -1
def addSpectator(self, userID): '''def addSpectator(self, user):
""" """
Add userID to our spectators Add userID to our spectators
userID -- new spectator userID user -- user object
""" """
# Add userID to spectators if not already in # Add userID to spectators if not already in
if userID not in self.spectators: if user not in self.spectators:
self.spectators.append(userID) self.spectators.append(user)
def removeSpectator(self, userID): def removeSpectator(self, userID):
""" """
@ -217,7 +255,7 @@ class token:
""" """
# Remove spectator # Remove spectator
if userID in self.spectators: if userID in self.spectators:
self.spectators.remove(userID) self.spectators.remove(userID)'''
def setCountry(self, countryID): def setCountry(self, countryID):
""" """

View File

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

View File

@ -13,6 +13,7 @@ class streamList:
""" """
if name not in self.streams: if name not in self.streams:
self.streams[name] = stream.stream(name) self.streams[name] = stream.stream(name)
print(str(self.streams))
def remove(self, name): def remove(self, name):
""" """
@ -38,6 +39,17 @@ class streamList:
return return
self.streams[streamName].broadcast(data) 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): def join(self, streamName, client):
""" """
Add a client to a stream Add a client to a stream

3
pep.py
View File

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