def __init__(self, *arg, **kw): # +2 to allow server->master and master->server connection since enet # allocates peers for both clients and hosts. this is done at # enet-level, not application-level, so even for masterless-servers, # this should not allow additional players. self.max_connections = self.max_players + 2 BaseProtocol.__init__(self, *arg, **kw) self.entities = [] self.players = {} self.player_ids = IDPool() self._create_teams() self.world = world.World() self.set_master() # safe position LUT # # Generates a LUT to check for safe positions. The slighly weird # sorting is used to sort by increasing distance so the nearest spots # get chosen first # product(repeat=3) is the equivalent of 3 nested for loops self.pos_table = list(product(range(-5, 6), repeat=3)) self.pos_table.sort(key=lambda vec: abs(vec[0] * 1.03) + abs(vec[1] * 1.02) + abs(vec[2] * 1.01))
def update(self): self.loop_count += 1 BaseProtocol.update(self) for player in self.connections.values(): if (player.map_data is not None and not player.peer.reliableDataInTransit): player.continue_map_transfer() self.world.update(UPDATE_FREQUENCY) self.on_world_update() if self.loop_count % int(UPDATE_FPS / NETWORK_FPS) == 0: self.update_network()
async def update(self): while True: start_time = time.monotonic() # Notify if update starts more than 4ms later than requested lag = start_time - self.world_time - UPDATE_FREQUENCY if lag > 0.004: log.debug("LAG before world update: {lag:.0f} ms", lag=lag * 1000) BaseProtocol.update(self) # Map transfer for player in self.connections.values(): if (player.map_data is not None and not player.peer.reliableDataInTransit): player.continue_map_transfer() # Update world while (time.monotonic() - self.world_time) > UPDATE_FREQUENCY: self.loop_count += 1 self.world.update(UPDATE_FREQUENCY) try: self.on_world_update() except Exception: traceback.print_exc() self.world_time += UPDATE_FREQUENCY # Update network if time.monotonic() - self.last_network_update >= 1 / NETWORK_FPS: self.last_network_update = self.world_time self.update_network() # Notify if update uses more than 70% of time budget lag = time.monotonic() - start_time if lag > (UPDATE_FREQUENCY * 0.7): log.debug("world update LAG: {lag:.0f} ms", lag=lag * 1000) delay = self.world_time + UPDATE_FREQUENCY - time.monotonic() await asyncio.sleep(delay)