Example #1
0
	def test_buidling_updates(self):
		""" Test performance of building update messages for many players"""
		connections = list
		for i in range(100):
			connection = Connection(self.world, self.cache)
			connection.get_frame()

		self.pr.enable()
		self.clock.advance(1)
		self.pr.disable()
		print self.process_stats('test_buidling_updates.txt')
Example #2
0
	def test_get_update(self):
		""" Test raw execution performance of the 'get_update'"""
		self.connection = Connection(self.world, self.cache)
		archers = list()
		for i in range(50):
			archer = Archer(self.world, reactor=self.clock)
			archer.spawn(self.spawn_point)
			archer.want_move(directions['south'])
			archers.append(archer)
		self.pr.enable()
		for i in range(100):
			self.connection.get_update()
		self.pr.disable()
		print self.process_stats('test_get_update.txt')
Example #3
0
    def setUp(self):
        super(TestInterface, self).setUp()
        path = os.path.dirname(os.path.os.path.realpath(__file__))
        path = os.path.join(path, 'assets/test1.tmx')
        self.world = World(path)
        self.spawn_point = self.world.get_object_by_name('spawn1')

        self.world_update_task = task.LoopingCall(self.world.processing_step)
        self.world_update_task.clock = self.clock
        self.world_update_task.start(1.0 / 30)

        self.networking_task = task.LoopingCall(self.world.networking_step)
        self.networking_task.clock = self.clock
        self.networking_task.start(1.0 / 30)

        self.connection = Connection(self.world)
        self.last_callback_data = None
Example #4
0
    def onWantPlay(self):
        self.interface = Connection(self.factory.world, self.factory.cache)
        self.interface.on('update', self.send_messages)
        self.interface.on('frame', self.send_messages)
        self.interface.on('remove', self.send_messages)
        self.interface.on('meta', self.broadcast_meta_update)
        self.factory.register(self)

        #force initial full update
        self.interface.trigger('step')

        #then send all meta, probably should live somewhere else
        for conn in self.factory.clients:
            msg = simplejson.dumps(conn.interface.meta, separators=(',', ':'))
            self.sendMessage(msg)

        #finally send 'weclome msg', at this point game should be playable on the client-side
        welcome_pack = {
            "id": self.interface.archer.id,
            "session_id": self.interface.session_id.hex
        }
        self.sendMessage(simplejson.dumps(welcome_pack, separators=(',', ':')))
	def setUp(self):
		super(TestInterface, self).setUp()
		path = os.path.dirname(os.path.os.path.realpath(__file__))
		path = os.path.join(path, 'assets/test1.tmx')
		self.world = World(path)
		self.spawn_point = self.world.get_object_by_name('spawn1')
		
		self.world_update_task = task.LoopingCall(self.world.processing_step)
		self.world_update_task.clock = self.clock
		self.world_update_task.start(1.0/30)

		self.networking_task = task.LoopingCall(self.world.networking_step)
		self.networking_task.clock = self.clock
		self.networking_task.start(1.0/30)
		
		self.connection = Connection(self.world)
		self.last_callback_data = None
Example #6
0
	def onWantPlay(self):
		self.interface = Connection(self.factory.world, self.factory.cache)
		self.interface.on('update', self.send_messages)
		self.interface.on('frame', self.send_messages)
		self.interface.on('remove', self.send_messages)
		self.interface.on('meta', self.broadcast_meta_update)
		self.factory.register(self)

		#force initial full update
		self.interface.trigger('step')
	
		#then send all meta, probably should live somewhere else
		for conn in self.factory.clients:
			msg = simplejson.dumps(conn.interface.meta, separators=(',', ':'))
			self.sendMessage(msg)

		#finally send 'weclome msg', at this point game should be playable on the client-side
		welcome_pack = {
			"id": self.interface.archer.id,
			"session_id": self.interface.session_id.hex
		}
		self.sendMessage(simplejson.dumps(welcome_pack, separators=(',', ':')))
Example #7
0
class ProfileInterface(BaseTestCase):
	def setUp(self):
		super(ProfileInterface, self).setUp()
		self.pr = cProfile.Profile()
		self.path = os.path.dirname(os.path.os.path.realpath(__file__))
		path = os.path.join(self.path, '../../resources/map.tmx')
		self.world = World(path)
		self.cache = MessageCache(self.world)
		self.spawn_point = self.world.get_object_by_name('spawn1')

		self.world_update_task = task.LoopingCall(self.world.processing_step)
		self.world_update_task.clock = self.clock
		self.world_update_task.start(1.0/30)

		self.networking_task = task.LoopingCall(self.world.networking_step)
		self.networking_task.clock = self.clock
		self.networking_task.start(1.0/30)

	def process_stats(self, filename):
		self.ps = pstats.Stats(self.pr)
		f = open(os.path.join(self.path, 'data', filename), 'w')
		pstats.Stats(self.pr, stream=f).strip_dirs().sort_stats('cumulative').print_stats()
		f.close()
		return "%i calls" % self.ps.total_calls, "%.3f sec" % self.ps.total_tt


	def test_get_frame(self):
		""" Test raw execution performance of the 'get_frame'"""
		self.connection = Connection(self.world, self.cache)
		archers = list()
		for i in range(50):
			archer = Archer(self.world, reactor=self.clock)
			archer.spawn(self.spawn_point)
			archer.want_move(directions['south'])
			archers.append(archer)
		self.pr.enable()
		for i in range(100):
			self.connection.get_frame()
 		self.pr.disable()
		print self.process_stats('test_get_frame.txt')

	def test_building_frames(self):
		""" Test performance of building frame for many players """
		connections = list
		for i in range(100):
			connection = Connection(self.world, self.cache)
			connection.get_update()

		self.pr.enable()
		self.clock.advance(1)
		self.pr.disable()
		print self.process_stats('test_building_frames.txt')

	def test_get_update(self):
		""" Test raw execution performance of the 'get_update'"""
		self.connection = Connection(self.world, self.cache)
		archers = list()
		for i in range(50):
			archer = Archer(self.world, reactor=self.clock)
			archer.spawn(self.spawn_point)
			archer.want_move(directions['south'])
			archers.append(archer)
		self.pr.enable()
		for i in range(100):
			self.connection.get_update()
		self.pr.disable()
		print self.process_stats('test_get_update.txt')

	def test_buidling_updates(self):
		""" Test performance of building update messages for many players"""
		connections = list
		for i in range(100):
			connection = Connection(self.world, self.cache)
			connection.get_frame()

		self.pr.enable()
		self.clock.advance(1)
		self.pr.disable()
		print self.process_stats('test_buidling_updates.txt')
Example #8
0
class UserCommunication(WebSocketServerProtocol):
    # def __init__(self, world, *args, **kwargs):
    # 	self.world = world
    # 	# WebSocketServerProtocol.__init__(self)

    def onMessage(self, msg, binary):
        if (binary):
            messages = unpack_mesages(msg)

            if (not hasattr(self, "interface")):
                try:
                    if (messages[0]['action'] == 'init'):
                        self.onWantPlay()
                except (IndexError, KeyError):
                    logging.warning(
                        "Got garbage message {}, discarding".format(msg))
            else:
                for msg in messages:
                    self.interface.trigger('useraction', msg)
        else:
            try:
                msg = simplejson.loads(msg)
                self.interface.trigger('usermsg', msg)
            except Exception:
                #ping pong
                if (msg == "?"):
                    self.sendMessage("!")
                else:
                    logging.warning(
                        "Unable to decode meta msg %s coming from the client" %
                        msg)

    def onOpen(self):
        server_pack = {
            "players": len(self.factory.clients),
            "location": self.factory.game.config['location'],
            "maxPlayers": self.factory.game.config['maxplayers'],
            "map": self.factory.world.map.properties['name']
        }

        self.sendMessage(simplejson.dumps(server_pack, separators=(',', ':')))

    def onWantPlay(self):
        self.interface = Connection(self.factory.world, self.factory.cache)
        self.interface.on('update', self.send_messages)
        self.interface.on('frame', self.send_messages)
        self.interface.on('remove', self.send_messages)
        self.interface.on('meta', self.broadcast_meta_update)
        self.factory.register(self)

        #force initial full update
        self.interface.trigger('step')

        #then send all meta, probably should live somewhere else
        for conn in self.factory.clients:
            msg = simplejson.dumps(conn.interface.meta, separators=(',', ':'))
            self.sendMessage(msg)

        #finally send 'weclome msg', at this point game should be playable on the client-side
        welcome_pack = {
            "id": self.interface.archer.id,
            "session_id": self.interface.session_id.hex
        }
        self.sendMessage(simplejson.dumps(welcome_pack, separators=(',', ':')))

    def connectionLost(self, reason):
        WebSocketServerProtocol.connectionLost(self, reason)
        self.factory.unregister(self)

    def onClose(self, wasClean, code, reason):
        if (hasattr(self, 'interface')):
            self.interface.trigger('disconnect')

    def send_messages(self, messages):
        if (len(messages)):
            self.sendMessage(pack_messages(messages), True)

    def broadcast_meta_update(self, meta):
        msg = simplejson.dumps(meta, separators=(',', ':'))
        self.factory.broadcast(msg)
Example #9
0
class UserCommunication(WebSocketServerProtocol):
	# def __init__(self, world, *args, **kwargs):
	# 	self.world = world
	# 	# WebSocketServerProtocol.__init__(self)

	def onMessage(self, msg, binary):
		if(binary):
			messages = unpack_mesages(msg)

			if(not hasattr(self, "interface")):
				try:
					if(messages[0]['action'] == 'init'):
						self.onWantPlay()
				except (IndexError, KeyError):
					logging.warning("Got garbage message {}, discarding".format(msg))
			else:
				for msg in messages:
					self.interface.trigger('useraction', msg)
		else:
			try:
				msg = simplejson.loads(msg)
				self.interface.trigger('usermsg', msg)
			except Exception:
				#ping pong
				if(msg == "?"):
					self.sendMessage("!")
				else:
					logging.warning("Unable to decode meta msg %s coming from the client" % msg)
			

	def onOpen(self):
		server_pack = {
			"players": len(self.factory.clients),
			"location": self.factory.game.config['location'],
			"maxPlayers": self.factory.game.config['maxplayers'],
			"map": self.factory.world.map.properties['name']
		}

		self.sendMessage(simplejson.dumps(server_pack, separators=(',', ':')))


	def onWantPlay(self):
		self.interface = Connection(self.factory.world, self.factory.cache)
		self.interface.on('update', self.send_messages)
		self.interface.on('frame', self.send_messages)
		self.interface.on('remove', self.send_messages)
		self.interface.on('meta', self.broadcast_meta_update)
		self.factory.register(self)

		#force initial full update
		self.interface.trigger('step')
	
		#then send all meta, probably should live somewhere else
		for conn in self.factory.clients:
			msg = simplejson.dumps(conn.interface.meta, separators=(',', ':'))
			self.sendMessage(msg)

		#finally send 'weclome msg', at this point game should be playable on the client-side
		welcome_pack = {
			"id": self.interface.archer.id,
			"session_id": self.interface.session_id.hex
		}
		self.sendMessage(simplejson.dumps(welcome_pack, separators=(',', ':')))

	def connectionLost(self, reason):
		WebSocketServerProtocol.connectionLost(self, reason)
		self.factory.unregister(self)

	def onClose(self, wasClean, code, reason):
		if(hasattr(self, 'interface')):
			self.interface.trigger('disconnect')

	def send_messages(self, messages):
		if(len(messages)):
			self.sendMessage(pack_messages(messages), True)

	def broadcast_meta_update(self, meta):
		msg = simplejson.dumps(meta, separators=(',', ':'))
		self.factory.broadcast(msg)
Example #10
0
class TestInterface(BaseTestCase):

	def setUp(self):
		super(TestInterface, self).setUp()
		path = os.path.dirname(os.path.os.path.realpath(__file__))
		path = os.path.join(path, 'assets/test1.tmx')
		self.world = World(path)
		self.spawn_point = self.world.get_object_by_name('spawn1')
		
		self.world_update_task = task.LoopingCall(self.world.processing_step)
		self.world_update_task.clock = self.clock
		self.world_update_task.start(1.0/30)

		self.networking_task = task.LoopingCall(self.world.networking_step)
		self.networking_task.clock = self.clock
		self.networking_task.start(1.0/30)
		
		self.connection = Connection(self.world)
		self.last_callback_data = None

	def tearDown(self):
		self.world_update_task.stop()
		self.networking_task.stop()

	def get_items_expected(self, expected_attr):
		# items_expected = self.world.object_lookup_by_name
		items_expected = self.world.object_index
		items_expected = {k: v for k, v in items_expected.items() if hasattr(v, expected_attr)}
		return items_expected

	def callback(self, *args, **kwargs):
		self.last_callback_data = list(*args)

	def get_last_callback_arguments(self):
		tmp = self.last_callback_data
		self.last_callback_data = None
		return tmp

	def test_get_frame(self):
		self.archer = Archer(self.world, reactor=self.clock)
		self.archer.spawn(self.spawn_point)
		self.connection.on('frame', self.callback)
		self.clock.advance(1)
		frame = self.get_last_callback_arguments()
		items_expected = self.get_items_expected('get_frame_message')
		self.assertEqual(len(frame), len(items_expected))

		for message in frame:
			matching_expected_item = items_expected.pop(message['id'])
			self.assertEqual(message['x'], int(settings.PPM*matching_expected_item.get_position()['x']))
			self.assertEqual(message['y'], int(settings.PPM*matching_expected_item.get_position()['y']))
			self.assertEqual(message['direction'], matching_expected_item.get_direction())

		self.assertEqual(len(items_expected), 0)

			
		self.clock.advance(1)
		frame = self.get_last_callback_arguments()
		# Nothing has changed!
		self.assertEqual(len(frame), 0)
		self.archer.want_move(directions['south'])
		self.advance_clock(1)
		frame = self.get_last_callback_arguments()
		self.assertEqual(len(frame), 1)
		message = frame.pop()
		self.assertEqual(message['x'], int(settings.PPM*self.archer.get_position()['x']))
		self.assertEqual(message['y'], int(settings.PPM*self.archer.get_position()['y']))
		self.assertEqual(message['direction'], self.archer.get_direction())

	def test_get_update(self):
		self.connection.on('update', self.callback)
		self.clock.advance(1)
		items_expected = self.get_items_expected('get_update_message')
		update = self.get_last_callback_arguments()
		self.assertEqual(len(update), len(items_expected))
		for message in update:
			self.assertIsInstance(message, UpdateMessage)
			matching_expected_item = items_expected.pop(message['id'])
			self.assertEqual(message['id'], matching_expected_item.id)
			# self.assertEqual(message['center'], False)
			#TEST MORE
		self.assertEqual(len(items_expected), 0)

		self.clock.advance(1)
		update = self.get_last_callback_arguments()


		self.assertIsNone(update)
		self.archer = Archer(self.world, reactor=self.clock)
		self.archer.spawn(self.spawn_point)
		self.clock.advance(1)
		update = self.get_last_callback_arguments()
		self.assertEqual(len(update), 1)

	def get_fake_msg(self, x=1, y=3.33, direction=directions['south']):
		msg = FakeMessage()
		msg['x'] = x
		msg['y'] = y
		msg['direction'] = direction
		return msg

	def test_packing(self):
		msg = self.get_fake_msg()
		packed = msg.pack()
		self.assertEqual(packed[0:4], struct.pack('!I', 1))
		self.assertEqual(packed[4:8], struct.pack('!f', 3.33))
		self.assertEqual(packed[8:9], struct.pack('!B', DirectionMessageMixin.direction_lookup[directions['south']]))


	def test_dehydration(self):
		x = 12
		y = 4.44
		dir = DirectionMessageMixin.direction_lookup[directions['west']]
		dehydrated_item = [x, y, dir]
		msg = FakeMessage.from_dehydrated(dehydrated_item)

		self.assertEqual(msg['x'], x)
		self.assertEqual(msg['y'], y)
		self.assertEqual(msg['direction'], directions['west'])

	def test_unpacking(self):
		# packed = '\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x02\x02\n'
		x = 12
		y = 7.77
		dir = DirectionMessageMixin.direction_lookup[directions['west']]

		packed = struct.pack("!I", x) + struct.pack("!f", y) + struct.pack("!B", dir) + "\n"
		msg = FakeMessage.from_packed(packed)
		self.assertEqual(msg['x'], x)
		self.assertAlmostEqual(msg['y'], y, places=4)
		self.assertEqual(msg['direction'], directions['west'])

	def test_message_packing(self):
		msg = self.get_fake_msg()
		msg2 = self.get_fake_msg(x=5, direction=directions['east'])
		result = pack_messages([msg, msg2])
		expected_byte_length = 1 + 2 * msg.get_byte_length()
		self.assertEqual(len(result), expected_byte_length)

	def test_message_unpacking(self):
		x1 = 12
		y1 = 4.44
		dir1 = DirectionMessageMixin.direction_lookup[directions['west']]
		packed = struct.pack("!I", x1) + struct.pack("!f", y1) + struct.pack("!B", dir1)
		x2 = 42
		y2 = 9.987654
		dir2 = DirectionMessageMixin.direction_lookup[directions['north']]
		packed = packed + struct.pack("!I", x2) + struct.pack("!f", y2) + struct.pack("!B", dir2) + "\n"

		packed = struct.pack("!B", 255) + packed

		messages = unpack_mesages(packed, message_types=message_types)
		self.assertEqual(len(messages), 2)
		self.assertEqual(messages[0]['x'], x1)
		self.assertAlmostEqual(messages[0]['y'], y1, places=4)
		self.assertEqual(messages[0]['direction'], directions['west'])
		self.assertEqual(messages[1]['x'], x2)
		self.assertAlmostEqual(messages[1]['y'], y2, places=4)
		self.assertEqual(messages[1]['direction'], directions['north'])

	def test_eating_own_dog_food(self):
		msg = self.get_fake_msg(y=1.0) 
		packed = msg.pack()
		unpacked = FakeMessage.from_packed(packed)
		self.assertEqual(msg, unpacked)
Example #11
0
class TestInterface(BaseTestCase):
    def setUp(self):
        super(TestInterface, self).setUp()
        path = os.path.dirname(os.path.os.path.realpath(__file__))
        path = os.path.join(path, 'assets/test1.tmx')
        self.world = World(path)
        self.spawn_point = self.world.get_object_by_name('spawn1')

        self.world_update_task = task.LoopingCall(self.world.processing_step)
        self.world_update_task.clock = self.clock
        self.world_update_task.start(1.0 / 30)

        self.networking_task = task.LoopingCall(self.world.networking_step)
        self.networking_task.clock = self.clock
        self.networking_task.start(1.0 / 30)

        self.connection = Connection(self.world)
        self.last_callback_data = None

    def tearDown(self):
        self.world_update_task.stop()
        self.networking_task.stop()

    def get_items_expected(self, expected_attr):
        # items_expected = self.world.object_lookup_by_name
        items_expected = self.world.object_index
        items_expected = {
            k: v
            for k, v in items_expected.items() if hasattr(v, expected_attr)
        }
        return items_expected

    def callback(self, *args, **kwargs):
        self.last_callback_data = list(*args)

    def get_last_callback_arguments(self):
        tmp = self.last_callback_data
        self.last_callback_data = None
        return tmp

    def test_get_frame(self):
        self.archer = Archer(self.world, reactor=self.clock)
        self.archer.spawn(self.spawn_point)
        self.connection.on('frame', self.callback)
        self.clock.advance(1)
        frame = self.get_last_callback_arguments()
        items_expected = self.get_items_expected('get_frame_message')
        self.assertEqual(len(frame), len(items_expected))

        for message in frame:
            matching_expected_item = items_expected.pop(message['id'])
            self.assertEqual(
                message['x'],
                int(settings.PPM * matching_expected_item.get_position()['x']))
            self.assertEqual(
                message['y'],
                int(settings.PPM * matching_expected_item.get_position()['y']))
            self.assertEqual(message['direction'],
                             matching_expected_item.get_direction())

        self.assertEqual(len(items_expected), 0)

        self.clock.advance(1)
        frame = self.get_last_callback_arguments()
        # Nothing has changed!
        self.assertEqual(len(frame), 0)
        self.archer.want_move(directions['south'])
        self.advance_clock(1)
        frame = self.get_last_callback_arguments()
        self.assertEqual(len(frame), 1)
        message = frame.pop()
        self.assertEqual(message['x'],
                         int(settings.PPM * self.archer.get_position()['x']))
        self.assertEqual(message['y'],
                         int(settings.PPM * self.archer.get_position()['y']))
        self.assertEqual(message['direction'], self.archer.get_direction())

    def test_get_update(self):
        self.connection.on('update', self.callback)
        self.clock.advance(1)
        items_expected = self.get_items_expected('get_update_message')
        update = self.get_last_callback_arguments()
        self.assertEqual(len(update), len(items_expected))
        for message in update:
            self.assertIsInstance(message, UpdateMessage)
            matching_expected_item = items_expected.pop(message['id'])
            self.assertEqual(message['id'], matching_expected_item.id)
            # self.assertEqual(message['center'], False)
            #TEST MORE
        self.assertEqual(len(items_expected), 0)

        self.clock.advance(1)
        update = self.get_last_callback_arguments()

        self.assertIsNone(update)
        self.archer = Archer(self.world, reactor=self.clock)
        self.archer.spawn(self.spawn_point)
        self.clock.advance(1)
        update = self.get_last_callback_arguments()
        self.assertEqual(len(update), 1)

    def get_fake_msg(self, x=1, y=3.33, direction=directions['south']):
        msg = FakeMessage()
        msg['x'] = x
        msg['y'] = y
        msg['direction'] = direction
        return msg

    def test_packing(self):
        msg = self.get_fake_msg()
        packed = msg.pack()
        self.assertEqual(packed[0:4], struct.pack('!I', 1))
        self.assertEqual(packed[4:8], struct.pack('!f', 3.33))
        self.assertEqual(
            packed[8:9],
            struct.pack(
                '!B',
                DirectionMessageMixin.direction_lookup[directions['south']]))

    def test_dehydration(self):
        x = 12
        y = 4.44
        dir = DirectionMessageMixin.direction_lookup[directions['west']]
        dehydrated_item = [x, y, dir]
        msg = FakeMessage.from_dehydrated(dehydrated_item)

        self.assertEqual(msg['x'], x)
        self.assertEqual(msg['y'], y)
        self.assertEqual(msg['direction'], directions['west'])

    def test_unpacking(self):
        # packed = '\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x02\x02\n'
        x = 12
        y = 7.77
        dir = DirectionMessageMixin.direction_lookup[directions['west']]

        packed = struct.pack("!I", x) + struct.pack("!f", y) + struct.pack(
            "!B", dir) + "\n"
        msg = FakeMessage.from_packed(packed)
        self.assertEqual(msg['x'], x)
        self.assertAlmostEqual(msg['y'], y, places=4)
        self.assertEqual(msg['direction'], directions['west'])

    def test_message_packing(self):
        msg = self.get_fake_msg()
        msg2 = self.get_fake_msg(x=5, direction=directions['east'])
        result = pack_messages([msg, msg2])
        expected_byte_length = 1 + 2 * msg.get_byte_length()
        self.assertEqual(len(result), expected_byte_length)

    def test_message_unpacking(self):
        x1 = 12
        y1 = 4.44
        dir1 = DirectionMessageMixin.direction_lookup[directions['west']]
        packed = struct.pack("!I", x1) + struct.pack("!f", y1) + struct.pack(
            "!B", dir1)
        x2 = 42
        y2 = 9.987654
        dir2 = DirectionMessageMixin.direction_lookup[directions['north']]
        packed = packed + struct.pack("!I", x2) + struct.pack(
            "!f", y2) + struct.pack("!B", dir2) + "\n"

        packed = struct.pack("!B", 255) + packed

        messages = unpack_mesages(packed, message_types=message_types)
        self.assertEqual(len(messages), 2)
        self.assertEqual(messages[0]['x'], x1)
        self.assertAlmostEqual(messages[0]['y'], y1, places=4)
        self.assertEqual(messages[0]['direction'], directions['west'])
        self.assertEqual(messages[1]['x'], x2)
        self.assertAlmostEqual(messages[1]['y'], y2, places=4)
        self.assertEqual(messages[1]['direction'], directions['north'])

    def test_eating_own_dog_food(self):
        msg = self.get_fake_msg(y=1.0)
        packed = msg.pack()
        unpacked = FakeMessage.from_packed(packed)
        self.assertEqual(msg, unpacked)