def do_4330(self, room): """ Notify people INSIDE room of ip,ports and participation status """ for otherUsr in room.players: if otherUsr == self._user: continue data = (b'%(pad1)s%(ip1)s%(port1)s' b'%(ip2)s%(port2)s%(id)s' b'%(someField)s%(participate)s') % { b'pad1': b'\0' * 36, b'ip1': util.padWithZeros(self._user.state.ip1, 16), b'port1': struct.pack('!H', self._user.state.udpPort1), b'ip2': util.padWithZeros(self._user.state.ip2, 16), b'port2': struct.pack('!H', self._user.state.udpPort2), b'id': struct.pack('!i', self._user.profile.id), b'someField': struct.pack('!H', 0), b'participate': struct.pack('!B', room.getPlayerParticipate( self._user)), } otherUsr.sendData(0x4330, data)
def getStunInfo_4345(self, pkt): self.sendZeros(0x4346, 0) roomId = struct.unpack('!i', pkt.data[0:4])[0] thisLobby = self.factory.getLobbies()[self._user.state.lobbyId] room = thisLobby.getRoomById(roomId) if room is not None: # send stun info of players in room to requester for usr in room.players: data = (b'%(pad1)s%(ip1)s%(port1)s' b'%(ip2)s%(port2)s%(id)s' b'%(someField)s%(participate)s') % { b'pad1': b'\0' * 32, b'ip1': util.padWithZeros(usr.state.ip1, 16), b'port1': struct.pack('!H', usr.state.udpPort1), b'ip2': util.padWithZeros(usr.state.ip2, 16), b'port2': struct.pack('!H', usr.state.udpPort2), b'id': struct.pack('!i', usr.profile.id), b'someField': struct.pack('!H', 0), b'participate': struct.pack('!B', room.getPlayerParticipate(usr)), } self.sendData(0x4347, data) self.do_4330(room) self.sendZeros(0x4348, 0)
def joinRoom_4320(self, pkt): roomId = struct.unpack('!i', pkt.data[0:4])[0] thisLobby = self.factory.getLobbies()[self._user.state.lobbyId] room = thisLobby.getRoomById(roomId) if room is None: log.msg('ERROR: Room (id=%d) does not exist.' % roomId) self.sendData(0x4321, b'\0\0\0\1') else: if room.usePassword: enteredPassword = util.stripZeros(pkt.data[4:19]) if enteredPassword != room.password: log.msg('ERROR: Room (id=%d) password does not match.' % roomId) self.sendData(0x4321, b'\xff\xff\xfd\xda') else: room.enter(self._user) else: room.enter(self._user) self.sendRoomUpdate(room) self.sendPlayerUpdate(room.id) data = b'\0\0\0\0' if room.matchSettings: data += room.matchSettings.match_time self.sendData(0x4321, data) # give players in room stun of joiner # special 4330 packet self.do_4330(room) # give joiner stun of players in room self.sendZeros(0x4346, 0) for otherUsr in room.players: if otherUsr == self._user: continue data = (b'%(pad1)s%(ip1)s%(port1)s' b'%(ip2)s%(port2)s%(id)s' b'%(someField)s%(participate)s') % { b'pad1': b'\0' * 32, b'ip1': util.padWithZeros(otherUsr.state.ip1, 16), b'port1': struct.pack('!H', otherUsr.state.udpPort1), b'ip2': util.padWithZeros(otherUsr.state.ip2, 16), b'port2': struct.pack('!H', otherUsr.state.udpPort2), b'id': struct.pack('!i', otherUsr.profile.id), b'someField': struct.pack('!H', 0), b'participate': struct.pack('!B', room.getPlayerParticipate(otherUsr)), } self.sendData(0x4347, data) self.sendZeros(0x4348, 0)
def formatProfileInfo(self, profile, stats): if not self.factory.serverConfig.ShowStats: profile = self.makePristineProfile(profile) return ('%(id)s%(name)s%(groupid)s%(groupname)s' '%(groupmemberstatus)s%(division)s' '%(points)s%(rating)s%(matches)s' '%(wins)s%(losses)s%(draws)s%(win-strk)s' '%(win-best)s%(disconnects)s' '%(goals-scored)s%(goals-allowed)s' '%(comment)s%(rank)s' '%(competition-gold-medals)s%(competition-silver-medals)s' '%(unknown1)s' '%(winnerscup-gold-medals)s%(winnerscup-silver-medals)s' '%(unknown2)s%(unknown3)s' '%(language)s%(recent-used-teams)s' % { 'id': struct.pack('!i',profile.id), 'name': util.padWithZeros(profile.name,48), 'groupid': struct.pack('!i',0), 'groupname': util.padWithZeros('Playmakers',48), 'groupmemberstatus': struct.pack('!B',1), 'division': struct.pack('!B', self.factory.ratingMath.getDivision(profile.points)), 'points': struct.pack('!i',profile.points), 'rating': struct.pack('!H',profile.rating), 'matches': struct.pack('!H', stats.wins + stats.losses + stats.draws), 'wins': struct.pack('!H',stats.wins), 'losses': struct.pack('!H',stats.losses), 'draws': struct.pack('!H',stats.draws), 'win-strk': struct.pack('!H', stats.streak_current), 'win-best': struct.pack('!H', stats.streak_best), 'disconnects': struct.pack( '!H', profile.disconnects), 'goals-scored': struct.pack('!i', stats.goals_scored), 'goals-allowed': struct.pack('!i', stats.goals_allowed), 'comment': util.padWithZeros(( profile.comment or 'Fiveserver rules!'), 256), 'rank': struct.pack('!i',profile.rank), 'competition-gold-medals': struct.pack('!H', 0), 'competition-silver-medals': struct.pack('!H', 0), 'unknown1': struct.pack('!H', 0), 'winnerscup-gold-medals': struct.pack('!H', 0), 'winnerscup-silver-medals': struct.pack('!H', 0), 'unknown2': struct.pack('!H', 0), 'unknown3': struct.pack('!B', 0), 'language': struct.pack('!B', 0), 'recent-used-teams': ''.join([struct.pack('!H', team) for team in stats.teams]) + '\xff\xff'*(5-len(stats.teams)) })
def formatRoomInfo(self, room): n = len(room.players) if room.match: match_state = room.match.state match_clock = room.match.clock else: match_state, match_clock = 0, 0 return '%s%s%s%s%s%s%s%s%s%s%s' % ( struct.pack('!i',room.id), struct.pack('!B',room.phase), struct.pack('!B',match_state), util.padWithZeros(room.name,64), struct.pack('!B',match_clock), ''.join(['%s%s%s%s%s%s%s' % ( struct.pack('!i',usr.profile.id), struct.pack('!B',room.isOwner(usr)), # matchstarter or 1st host? struct.pack('!B',room.isMatchStarter(usr)), struct.pack('!B',self.formatHomeOrAway(room, usr)), # team struct.pack('!B',usr.state.spectator), # spectator struct.pack('!B',room.getPlayerPosition(usr)), # pos in room struct.pack('!B',room.getPlayerParticipate(usr))) # participate for usr in room.players]), '\0\0\0\0\0\0\xff\0\0\xff'*(4-n), # empty players self.formatTeamsAndGoals(room), '\0', #padding struct.pack('!B', int(room.usePassword)), # room locked '\0\x02\0\0') # competition flag, match chat setting, 2 unknowns
def getProfiles_3010(self, pkt): if self.factory.serverConfig.ShowStats: results = yield defer.DeferredList([ self.factory.matchData.getGames( profile.id) for profile in self._user.profiles]) profiles = self._user.profiles else: # hide all stats results = yield defer.succeed([(True, 0) for profile in self._user.profiles]) profiles = [self.makePristineProfile(profile) for profile in self._user.profiles] data = '\0'*4 + ''.join([ '%(index)s%(id)s%(name)s%(playTime)s' '%(division)s%(points)s%(rating)s%(games)s' % { 'index':struct.pack('!B', i), 'id':struct.pack('!i', profile.id), 'name':util.padWithZeros(profile.name, 48), 'division':struct.pack('!B', self.factory.ratingMath.getDivision(profile.points)), 'playTime':struct.pack('!i', profile.playTime.total_seconds), 'points':struct.pack('!i', profile.points), 'games':struct.pack('!H', games), 'rating':struct.pack('!H',profile.rating), } for (_, games), (i, profile) in zip( results, enumerate(profiles))]) self.sendData(0x3012, data) defer.returnValue(None)
def __bytes__(self): """ return serialized representation to be used in packets """ return b'%s%s%s' % ( struct.pack('!B',self.typeCode), util.padWithZeros(self.name,32), struct.pack('!H',len(self.players)))
def broadcastRoomChat(self, room, text): chatMessage = lobby.ChatMessage(lobby.SYSTEM_PROFILE, text) for usr in room.players: data = b'%s%s%s%s%s' % ( b'\x01\x08', b'\0\0\0\0', struct.pack('!i', chatMessage.fromProfile.id), util.padWithZeros(chatMessage.fromProfile.name, 48), chatMessage.text.encode('utf-8')[:126] + b'\0\0') usr.sendData(0x4402, data)
def broadcastSystemChat(self, aLobby, text): chatMessage = lobby.ChatMessage(lobby.SYSTEM_PROFILE, text) for usr in aLobby.players.values(): data = b'%s%s%s%s%s' % ( b'\0\1', b'\0\0\0\0', struct.pack('!i', chatMessage.fromProfile.id), util.padWithZeros(chatMessage.fromProfile.name, 48), chatMessage.text.encode('utf-8')[:126] + b'\0\0') usr.sendData(0x4402, data) aLobby.addToChatHistory(chatMessage)
def chat_4400(self, pkt): thisLobby = self.factory.getLobbies()[self._user.state.lobbyId] chatType = pkt.data[0:2] message = util.stripZeros(pkt.data[10:]) data = '%s%s%s%s%s' % ( chatType, pkt.data[2:6], struct.pack('!i',self._user.profile.id), util.padWithZeros(self._user.profile.name,48), #util.padWithZeros(message, 128)) message[:126]+'\0\0') if chatType=='\x00\x01': # add to lobby chat history thisLobby.addToChatHistory( lobby.ChatMessage(self._user.profile, message)) # lobby chat for usr in thisLobby.players.itervalues(): usr.sendData(0x4402, data) elif chatType=='\x01\x08': # room chat room = self._user.state.room if room: for usr in room.players: usr.sendData(0x4402, data) elif chatType=='\x00\x02': # private message profileId = struct.unpack('!i',pkt.data[6:10])[0] usr = thisLobby.getPlayerByProfileId(profileId) if usr: # add to lobby chat history thisLobby.addToChatHistory( lobby.ChatMessage( self._user.profile, message, usr.profile, pkt.data[2:6])) usr.sendData(0x4402, data) if usr != self._user: self._user.sendData(0x4402, data) # echo to self else: log.msg( 'WARN: user with profile id = ' '%d not found.' % profileId) elif chatType=='\x01\x05': # match chat room = self._user.state.room if room: for usr in room.players: usr.sendData(0x4402, data) elif chatType=='\x01\x07': # stadium chat room = self._user.state.room if room: for usr in room.players: usr.sendData(0x4402, data)
def startMatch_4360(self, pkt): thisLobby = self.factory.getLobbies()[self._user.state.lobbyId] room = self._user.state.room if room: data = b'%s%s' % (b'\x02', b''.join([ b'%s' % (struct.pack('!i', usr.profile.id)) for usr in room.participatingPlayers ])) data = util.padWithZeros(data, 37) for player in room.players: player.sendData(0x4362, data) # Tell everyone of new phase of room room.phase = lobby.RoomState.ROOM_MATCH_SIDE_SELECT room.setMatchStarter(self._user) room.readyCount = 0 self.sendRoomUpdate(room) self.sendZeros(0x4361, 4)
def sendChatHistory(self, aLobby, who): if aLobby is None or who is None: return for chatMessage in list(aLobby.chatHistory): chatType = '\0\1' if chatMessage.toProfile is not None: if who.profile.id not in [ chatMessage.fromProfile.id, chatMessage.toProfile.id]: continue special = chatMessage.special else: special = '\0\0\0\0' data = '%s%s%s%s%s' % ( chatType, special, struct.pack('!i', chatMessage.fromProfile.id), util.padWithZeros(chatMessage.fromProfile.name,48), chatMessage.text[:126]+'\0\0') who.sendData(0x4402, data)
def formatPlayerInfo(self, usr, roomId, stats=None): if stats is None: stats = user.Stats(usr.profile.id, 0, 0, 0, 0, 0, 0, 0) return ( b'%(id)s%(name)s%(groupid)s%(groupname)s' b'%(groupmemberstatus)s%(division)s%(roomid)s' b'%(points)s%(rating)s%(matches)s%(wins)s' b'%(losses)s%(draws)s%(pad1)s' % { b'id': struct.pack('!i', usr.profile.id), b'name': util.padWithZeros(usr.profile.name, 48), b'groupid': struct.pack('!i', 0), b'groupname': b'\0' * 48, b'groupmemberstatus': struct.pack('!B', 0), b'division': struct.pack( '!B', self.factory.ratingMath.getDivision(usr.profile.points)), b'roomid': struct.pack('!i', roomId), b'points': struct.pack('!i', usr.profile.points), b'rating': struct.pack('!H', 0), b'matches': struct.pack('!H', stats.wins + stats.losses + stats.draws), b'wins': struct.pack('!H', stats.wins), b'losses': struct.pack('!H', stats.losses), b'draws': struct.pack('!H', stats.draws), b'pad1': b'\0' * 3, })