Ejemplo n.º 1
0
 def handleHostReceive(self, stream: SendStream,
                       clientSocket: ClientSocket):
     try:
         command = stream.readBytes()
         if command == b'start':
             self.state = Session.StateInit
             # forward file list to clients
             data = stream.data()
             for socket in self.clients.values():
                 if socket != self.hostSocket:
                     writeData(socket.socket, data)
             self.init = Session.InitData(len(self.clients) - 1)
             for i in range(stream.readInt()):
                 stream.readString()  # filename
                 fileHash = stream.readBytes()
                 if fileHash not in fileHashDict:
                     self.init.missingFileHashes.append(fileHash)
             sendStream = clientSocket.sendStream
             sendStream.writeBytes(b'missing')
             sendStream.writeInt(len(self.init.missingFileHashes))
             for hash in self.init.missingFileHashes:
                 sendStream.writeBytes(hash)
             sendStream.send()
         elif command == b'data':
             count = stream.readInt()
             if count != len(self.init.missingFileHashes):
                 self.abortSession()
                 return
             for hash in self.init.missingFileHashes:
                 fileData = stream.readBytes()
                 fileHashDict[hash] = fileData
                 f = open(cacheFolder + '/' + hash.decode(), 'wb')
                 f.write(fileData)
             self.init.missingFileHashes = None
             self.init.gameData = stream.readBytes()
             self.init.state = stream.readBytes()
             for clientSocket, missingHashes in self.init.missingClientHashes.items(
             ):
                 self.sendMissingClientData(clientSocket, missingHashes)
             activeSessions[self.id] = self
             self.state = Session.StateActive
             del openSessions[self.id]
             self.hostSocket.setDisconnectHandler(
                 self.handleClientDisconnect)
             self.hostSocket.setReceiveHandler(self.handleClientReceive)
     except Exception as e:
         self.abortSession()
         log('session error 2 : ' + str(e) + ' - ' + traceback.format_exc())
         raise e
Ejemplo n.º 2
0
 def handleClientReceive(self, stream: SendStream, socket: ClientSocket):
     try:
         command = stream.readBytes()
         if command == b'update':
             finished = stream.readBool()
             stream.readBytes()  # state
             data = stream.data()
             for othername, othersocket in self.clients.items():
                 if othername != socket.name:
                     writeData(othersocket.socket, data)
                     if finished:
                         othersocket.setDisconnectHandler(None)
                         othersocket.disconnectWhenWritten()
             if finished:
                 socket.setDisconnectHandler(None)
                 socket.disconnect()
                 del activeSessions[self.id]
         elif command == b'message':
             stream.readString()  # title
             stream.readString()  # text
             data = stream.data()
             for othername, othersocket in self.clients.items():
                 if othername != socket.name:
                     writeData(othersocket.socket, data)
         elif command == b'disjoin':
             if len(self.clients) == self.maxPlayers:
                 self.announceLater()
             self.handleClientDisconnect(socket)
             socket.register(joiningClients)
             socket.setReceiveHandler(self.handleJoiningReceive)
         elif command == b'data':
             count = stream.readInt()
             if not self.init:
                 socket.socket.disconnect()
                 return
             missingClientHashes = []
             for i in range(count):
                 missingClientHashes.append(stream.readBytes())
             if self.init.missingFileHashes is None:
                 self.sendMissingClientData(socket, missingClientHashes)
             else:
                 self.init.missingClientHashes[socket] = missingClientHashes
     except Exception as e:
         self.abortSession()
         log('session error 3 : ' + str(e) + ' - ' + traceback.format_exc())
         raise HandledError()
Ejemplo n.º 3
0
def handleValidatedReceive(stream : SendStream, socket : ClientSocket):
    socket.unregister()
    protocolVersion = stream.readInt()
    if protocolVersion != sessionProtocolVersion:
        if protocolVersion < sessionProtocolVersion:
            text = 'Client uses outdated protocol version. Please update the client.'
        else:
            text = 'Client uses newer protocol version. Please inform the server provider that the server is outdated.'
        stream = socket.sendStream
        stream.writeBytes(b'error')
        stream.writeString(text)
        stream.send()
        socket.disconnectWhenWritten()
        raise HandledError()
    socket.name = stream.readString()
    socket.secret = stream.readString()
    Session.startHandling(stream, socket)
Ejemplo n.º 4
0
 def handleErrorWhenOpen(self, text):
     stream = SendStream()
     stream.writeBytes(b'error')
     stream.writeString(text)
     for socket in self.clients.values():
         socket.send(stream)
         socket.disconnectWhenWritten()
     if self.id in openSessions:
         del openSessions[self.id]
Ejemplo n.º 5
0
    def __init__(self, stream: SendStream, hostSocket: ClientSocket):
        self.gameName = stream.readString()
        self.minPlayers = stream.readInt()
        self.maxPlayers = stream.readInt()
        self.playerCanLeave = stream.readBool()
        returnId = stream.readBool()
        self.hostSocket = hostSocket
        self.hostName = hostSocket.name
        self.secret = hostSocket.secret
        self.clients = {hostSocket.name: hostSocket}  # map names to sockets
        self.state = Session.StateOpen
        self.lastAnnounced = None
        self.announcePending = False
        self.init = None  # holds during the init state some objects
        Session.IdCounter += 1
        self.id = Session.IdCounter

        if returnId:
            hostSocket.sendStream.writeBytes(b'id')
            hostSocket.sendStream.writeInt(self.id)

        hostSocket.setReceiveHandler(self.handleHostReceive)
        hostSocket.setDisconnectHandler(self.handleHostDisconnect)
        self.announce()
Ejemplo n.º 6
0
 def handleHostDisconnect(self, socket: ClientSocket):
     self.announceLater()
     del self.clients[self.hostName]
     if self.state == Session.StateOpen:
         stream = SendStream()
         stream.writeBytes(b'cancel')
         stream.writeString('The host has been disconnected.')
         for socket in self.clients.values():
             socket.send(stream)
             socket.register(joiningClients)
             socket.setReceiveHandler(self.handleJoiningReceive)
         self.state = Session.StateDone
         del openSessions[self.id]
     elif self.init:
         if self.init.missingFileHashes:  # host disconnected before sending files
             self.handleErrorWhenOpen('Connection to host has been lost.')
         else:
             self.handleClientLeftDuringInit(socket)
     else:
         pass  # this case should not occur
Ejemplo n.º 7
0
 def startHandling(cls, stream: SendStream, socket: ClientSocket):
     socket.register(joiningClients)
     socket.setReceiveHandler(cls.handleJoiningReceive)
     if not stream.atEnd():
         cls.handleJoiningReceive(stream, socket)
Ejemplo n.º 8
0
 def handleJoiningReceive(stream: SendStream, socket: ClientSocket):
     command = stream.readBytes()
     if command == b'host':
         socket.unregister()
         session = Session(stream, socket)
         openSessions[session.id] = session
     elif command == b'join':
         sessionId = stream.readInt()
         session = openSessions.get(sessionId, None)
         if session:
             error = session.addClient(socket)
             if not error:
                 return
         else:
             error = 'The session has been canceled.'
         sendStream = SendStream()
         sendStream.writeBytes(b'cancel')
         sendStream.writeString(error)
         sendStream.send(socket.socket)
     elif command == b'client':
         freeSessions = [
             x for x in openSessions.values()
             if len(x.clients) < x.maxPlayers and socket.secret == x.secret
         ]
         sendStream = socket.sendStream
         sendStream.writeBytes(b'addsessions')
         sendStream.writeInt(len(freeSessions))
         for session in freeSessions:
             sendStream.writeInt(session.id)
             sendStream.writeString(session.hostName)
             sendStream.writeString(session.gameName)
         sendStream.send()
Ejemplo n.º 9
0
 def announce(self):
     self.announcePending = False
     stream = None
     if self.state == Session.StateOpen and len(self.clients) < self.maxPlayers and \
        self.hostSocket.socket.state() == QTcpSocket.ConnectedState:
         if not self.lastAnnounced:
             self.lastAnnounced = True
             stream = SendStream()
             stream.writeBytes(b'addsessions')
             stream.writeInt(1)
             stream.writeInt(self.id)
             stream.writeString(self.hostName)
             stream.writeString(self.gameName)
     else:
         if self.lastAnnounced:
             self.lastAnnounced = False
             stream = SendStream()
             stream.writeBytes(b'rmsession')
             stream.writeInt(self.id)
     if not stream:
         return
     for socket in joiningClients:
         if socket.secret == self.secret:
             socket.send(stream)
     for session in openSessions.values():
         if session != self:
             for socket in session.clients.values():
                 if socket.name != session.hostName and socket.secret == self.secret:
                     socket.send(stream)
Ejemplo n.º 10
0
 def handleClientDisconnect(self, socket: ClientSocket):
     del self.clients[socket.name]
     if self.state == Session.StateOpen:
         if len(self.clients) < self.maxPlayers:
             self.announceLater()
         stream = SendStream()
         stream.writeBytes(b'disjoin')
         stream.writeString(socket.name)
         stream.send(self.hostSocket.socket)
     elif self.state == Session.StateInit:
         if socket in self.init.missingClientHashes:
             self.init.missingClientCount -= 1
             del self.init.missingClientHashes[socket]
         self.handleClientLeftDuringInit(socket)
     else:  # game phase
         sendStream = SendStream()
         sendStream.writeBytes(b'left')
         sendStream.writeString(socket.name)
         for socket in self.clients.values():
             socket.send(sendStream)
         if not self.clients and self.id in activeSessions:
             del activeSessions[self.id]