def readUdpPackets(udpSocket): print "--- reading UDP packets" # all received packet ids receivedIds = set(); while udpKeepRunning: try: data, addr = udpSocket.recvfrom(2048) except: break print "--- read %d bytes from %s:%d" % (len(data), addr[0], addr[1]) (packetType,) = struct.unpack_from('>B', data, 0) if packetType == packet.Packet.UDP_PONG: (oldTime,) = struct.unpack_from('>L', data, struct.calcsize('>B')) now = datetime.datetime.now() milliseconds = (now.day * 24 * 60 * 60 + now.second) * 1000 + now.microsecond / 1000 print "--- pong received, time: %d ms" % (milliseconds - oldTime) elif packetType == packet.Packet.UDP_DATA_START_ACTION: print "--- start action, starting simulator" # create the simulator and start it global simulator simulator = Simulator( units, udpSocket, udpAddress ) simulator.start() elif packetType == packet.Packet.UDP_DATA: (packetType, subPacketType, packetId,) = struct.unpack_from('>BBI', data, 0) offset = struct.calcsize('>BBL') print "--- UDP data type %d, packet id: %d, total bytes: %d" % (subPacketType, packetId, len(data)) # already received this? if packetId in receivedIds: # skip this print "--- ignoring duplicate packet %d" % packetId continue receivedIds.add( packetId ) if subPacketType == packet.Packet.UDP_DATA_MISSION: (unitCount,) = struct.unpack_from('>B', data, offset) offset += struct.calcsize('>B') print "--- mission data, %d units" % unitCount for count in range( unitCount ): (unitId, missionType, ) = struct.unpack_from('>hB', data, offset) offset += struct.calcsize('>hB') print "--- unit %d, mission %d" % (unitId, missionType ) elif subPacketType == packet.Packet.UDP_DATA_UNIT_STATS: (unitCount,) = struct.unpack_from('>B', data, offset) offset += struct.calcsize('>B') print "--- unit stats, %d units" % unitCount for count in range( unitCount ): (unitId, men, mode, missionType, morale, fatigue, ammo, x, y, facing, ) = struct.unpack_from('>hBBBBBBhhh', data, offset) offset += struct.calcsize('>hBBBBBBhhh') # convert some data back x /= 10 y /= 10 facing /= 10 print "--- unit %d, men: %d, mode: %d, mission %d, morale: %d, fatigue: %d, ammo: %d pos: %d,%d, facing: %d" \ % (unitId, men, mode, missionType, morale, fatigue, ammo, x, y, facing) elif subPacketType == packet.Packet.UDP_DATA_FIRE: (attackerId, x, y, ) = struct.unpack_from('>hhh', data, offset) offset += struct.calcsize('>hhh') x /= 10 y /= 10 # any targets left? if offset == len(data): print "--- smoke, %d fires smoke at %d,%d" % (attackerId, x, y ) else: (targetCount, ) = struct.unpack_from('>B', data, offset) offset += struct.calcsize('>B') print "--- fire, %d fires at %d,%d, hitting %d units" % (attackerId, x, y, targetCount ) for count in range( targetCount ): (targetId, casualties, type, targetMoraleChange ) = struct.unpack_from('>hBBh', data, offset) offset += struct.calcsize('>hBBh') targetMoraleChange /= 10.0 print " target %d lost %d men, type: %d, target morale: %.1f" % (targetId, casualties, type, targetMoraleChange) for unit in units: if unit.id == targetId: unit.men = max( 0, unit.men - casualties ) unit.morale = max( 0, unit.morale - targetMoraleChange ) elif subPacketType == packet.Packet.UDP_DATA_MELEE: (attackerId, targetId, missionType, casualties, targetMoraleChange ) = struct.unpack_from('>hhBBh', data, offset) offset += struct.calcsize('>hhBBh') targetMoraleChange /= 10.0 print " %d melees with %d, target lost %d men, type: %d, target morale: %.1f" % (attackerId, targetId, casualties, type, targetMoraleChange) for unit in units: if unit.id == targetId: unit.mission = missionType unit.morale = max( 0, unit.morale - targetMoraleChange ) elif subPacketType == packet.Packet.UDP_DATA_SET_MISSION: (unitId, missionType ) = struct.unpack_from('>hB', data, offset) offset += struct.calcsize('>hB') print " %d gets mission %d" % (unitId, missionType) for unit in units: if unit.id == unitId: unit.mission = missionType elif subPacketType == packet.Packet.UDP_DATA_PLAYER_PING: (ms, ) = struct.unpack_from('>L', data, offset) offset += struct.calcsize('>L') print "--- player ping, their time: %d, sending response" % ms udpSocket.sendto(packet.UdpPlayerPongPacket( ms, simulator.getPacketId()).message, udpAddress) elif subPacketType == packet.Packet.UDP_DATA_SMOKE: (smokeCount, ) = struct.unpack_from('>h', data, offset) offset += struct.calcsize('>h') print "--- got data for %d smokes" % smokeCount for count in range( smokeCount ): (x, y, opacity, ) = struct.unpack_from('>hhB', data, offset) offset += struct.calcsize('>hhB') x /= 10 y /= 10 print "--- smoke %d at %d,%d, opacity: %d" % (count, x, y, opacity) print "--- UDP handler stopped"