Exemple #1
0
def prepare_multiplayer(game, trader_enabled = True, pirate_enabled = True, natural_resource_multiplier = 1):
	"""Starts a multiplayer game server
	TODO: acctual game data parameter passing
	"""
	global fife, preloading, db

	preload_game_join(preloading)

	# remove cursor while loading
	fife.cursor.set(fife_module.CURSOR_NONE)
	fife.engine.pump()
	fife.set_cursor_image('default')

	# hide whatever is displayed before the game starts
	_modules.gui.hide()

	# destruct old session (right now, without waiting for gc)
	if _modules.session is not None and _modules.session.is_alive:
		_modules.session.end()
	# start new session
	from mpsession import MPSession
	# get random seed for game
	uuid = game.get_uuid()
	random = sum([ int(uuid[i : i + 2], 16) for i in range(0, len(uuid), 2) ])
	_modules.session = MPSession(_modules.gui, db, NetworkInterface(), rng_seed=random)
	# NOTE: this data passing is only temporary, maybe use a player class/struct
	if game.load:
		map_file = SavegameManager.get_multiplayersave_map( game.get_map_name() )
	else:
		map_file = SavegameManager.get_map( game.get_map_name() )

	_modules.session.load(map_file,
	                      game.get_player_list(), trader_enabled, pirate_enabled, natural_resource_multiplier)
Exemple #2
0
def prepare_multiplayer(game, trader_enabled=True, pirate_enabled=True, natural_resource_multiplier=1):
	"""Starts a multiplayer game server
	TODO: actual game data parameter passing
	"""
	_modules.gui.show_loading_screen()

	preloader.wait_for_finish()

	# remove cursor while loading
	horizons.globals.fife.cursor.set(fife_module.CURSOR_NONE)
	horizons.globals.fife.engine.pump()
	horizons.globals.fife.set_cursor_image('default')

	# destruct old session (right now, without waiting for gc)
	if _modules.session is not None and _modules.session.is_alive:
		_modules.session.end()
	# start new session
	from horizons.mpsession import MPSession
	# get random seed for game
	uuid = game.uuid
	random = sum([int(uuid[i : i + 2], 16) for i in range(0, len(uuid), 2)])
	_modules.session = MPSession(horizons.globals.db, NetworkInterface(), rng_seed=random)

	# NOTE: this data passing is only temporary, maybe use a player class/struct
	if game.is_savegame:
		map_file = SavegameManager.get_multiplayersave_map(game.map_name)
	else:
		map_file = SavegameManager.get_map(game.map_name)

	options = StartGameOptions.create_start_multiplayer(map_file, game.get_player_list(), not game.is_savegame)
	_modules.session.load(options)
Exemple #3
0
def prepare_multiplayer(game, trader_enabled=True, pirate_enabled=True, natural_resource_multiplier=1):
	"""Starts a multiplayer game server
	TODO: actual game data parameter passing
	"""
	_modules.gui.show_loading_screen()

	global preloading
	preload_game_join(preloading)

	# remove cursor while loading
	horizons.globals.fife.cursor.set(fife_module.CURSOR_NONE)
	horizons.globals.fife.engine.pump()
	horizons.globals.fife.set_cursor_image('default')

	# destruct old session (right now, without waiting for gc)
	if _modules.session is not None and _modules.session.is_alive:
		_modules.session.end()
	# start new session
	from horizons.mpsession import MPSession
	# get random seed for game
	uuid = game.uuid
	random = sum([ int(uuid[i : i + 2], 16) for i in range(0, len(uuid), 2) ])
	_modules.session = MPSession(horizons.globals.db, NetworkInterface(), rng_seed=random)

	# NOTE: this data passing is only temporary, maybe use a player class/struct
	if game.is_savegame:
		map_file = SavegameManager.get_multiplayersave_map(game.map_name)
	else:
		map_file = SavegameManager.get_map(game.map_name)

	options = StartGameOptions.create_start_multiplayer(map_file, game.get_player_list(), not game.is_savegame)
	_modules.session.load(options)
	def __create_game(self, load=None, chosen_map=None):
		"""
		Actually create a game, join it, and display the lobby.

		@param load: game data tuple for creating loaded games
		@param chosen_map: the name of the map to start a new game on (overrides the gui)
		"""
		# create the game
		if load:
			mapname, gamename = load
			path = SavegameManager.get_multiplayersave_map(mapname)
			maxplayers = SavegameAccessor.get_players_num(path)
			load = SavegameAccessor.get_hash(path)
		else:
			mapindex = None
			if chosen_map is not None:
				for i, map in enumerate(self.maps_display):
					if map == chosen_map:
						mapindex = i
						break

			if mapindex is None:
				mapindex = self.current.collectData('maplist')
			mapname = self.maps_display[mapindex]
			maxplayers = self.current.collectData('playerlimit') + 2 # 1 is the first entry
			gamename = self.current.collectData('gamename')
			load = None

		game = NetworkInterface().creategame(mapname, maxplayers, gamename, load)
		if game is None:
			return

		self.__show_gamelobby()
 def __join_game(self, game=None):
     """Joins a multiplayer game. Displays lobby for that specific game"""
     if game == None:
         game = self.__get_selected_game()
     if (
         game.load is not None
         and SavegameAccessor.get_hash(SavegameManager.get_multiplayersave_map(game.mapname)) != game.load
     ):
         self.show_popup(_("Error"), self.current.findChild(name="save_missing_help_button").btn_text, size=1)
         return
     if game.get_uuid() == -1:  # -1 signals no game
         AmbientSoundComponent.play_special("error")
         return
     if game.get_version() != NetworkInterface().get_clientversion():
         self.show_popup(
             _("Wrong version"),
             # xgettext:python-format
             _(
                 "The game's version differs from your version. Every player in a multiplayer game must use the same version. This can be fixed by every player updating to the latest version. Game version: {game_version} Your version: {own_version}"
             ).format(game_version=game.get_version(), own_version=NetworkInterface().get_clientversion()),
         )
         return
         # actual join
     join_worked = NetworkInterface().joingame(game.get_uuid())
     if not join_worked:
         return
     self.__apply_new_nickname()
     self.__show_gamelobby()
    def __update_game_details(self, game=None):
        """Set map name and other misc data in a widget. Only possible in certain states"""
        if game == None:
            game = self.__get_selected_game()
            # xgettext:python-format
        self.current.findChild(name="game_map").text = _("Map: {map_name}").format(map_name=game.get_map_name())
        self.current.findChild(name="game_name").text = _("Name: {game_name}").format(game_name=game.get_name())
        # xgettext:python-format
        self.current.findChild(name="game_playersnum").text = _("Players: {player_amount}/{player_limit}").format(
            player_amount=game.get_player_count(), player_limit=game.get_player_limit()
        )
        creator_text = self.current.findChild(name="game_creator")
        # xgettext:python-format
        creator_text.text = _("Creator: {player}").format(player=game.get_creator())
        creator_text.adaptLayout()
        vbox_inner = self.current.findChild(name="game_info")
        if game.load is not None:  # work around limitations of current systems via messages
            path = SavegameManager.get_multiplayersave_map(game.mapname)
            if SavegameAccessor.get_hash(path) != game.load:
                text = ""
                btn_name = "save_missing_help_button"
                btn = vbox_inner.findChild(name=btn_name)
                if btn is None:
                    btn = pychan.widgets.Button(name=btn_name, text=_("This savegame is missing (click here)"))
                    last_elem = vbox_inner.findChild(name="game_info_last")
                    if last_elem is None:  # no last elem -> we are last
                        vbox_inner.addChild(btn)
                    else:
                        vbox_inner.insertChildBefore(btn, last_elem)
                btn_text = (
                    _(
                        u"For multiplayer load, it is currently necessary for you to ensure you have the correct savegame file."
                    )
                    + u"\n"
                )
                btn_text += _(u"This is not nice and we hope to offer a more convenient solution very soon.") + u"\n"
                btn_text += _(
                    u"Meanwhile, please request the file {path} from the game creator and put it in {map_directory} ."
                ).format(path=os.path.basename(path), map_directory=os.path.dirname(path))
                btn.btn_text = btn_text

                def show():
                    self.show_popup(_("Help"), btn_text, size=1)

                btn.capture(show)

            else:
                text = _(u"This is a savegame.")

            if text:
                self.current.findChild(name="game_isloaded").text = text
        textplayers = self.current.findChild(name="game_players")
        if textplayers is not None:
            textplayers.text = u", ".join(game.get_players())

        vbox_inner.adaptLayout()  # inner vbox always exists
        vbox = self.current.findChild(name="gamedetailsbox")
        if vbox is not None:
            vbox.adaptLayout()
	def __send_toggle_ready(self):
		game = NetworkInterface().get_game()

		if game.load is not None and \
		SavegameAccessor.get_hash(SavegameManager.get_multiplayersave_map(game.mapname)) != game.load:
			self.__print_event_message("You are fetching savegame data. You must wait for it")
			return

		NetworkInterface().send_toggle_ready(NetworkInterface().get_client_name())
	def __update_game_details(self, game=None):
		"""Set map name and other misc data in a widget. Only possible in certain states"""
		if game is None:
			game = self.__get_selected_game()
			if game is None:
				return
		#xgettext:python-format
		self.current.findChild(name="game_map").text = _("Map: {map_name}").format(map_name=game.get_map_name())
		self.current.findChild(name="game_name").text = _("Name: {game_name}").format(game_name=game.get_name())
		self.current.findChild(name="game_creator").text = _("Creator: {game_creator}").format(game_creator=game.get_creator())
		#xgettext:python-format
		self.current.findChild(name="game_playersnum").text = _("Players: {player_amount}/{player_limit}").format(
		                           player_amount=game.get_player_count(),
		                           player_limit=game.get_player_limit())
		vbox_inner = self.current.findChild(name="game_info")
		if game.is_savegame(): # work around limitations of current systems via messages
			path = SavegameManager.get_multiplayersave_map(game.mapname)
			btn_name = "save_missing_help_button"
			btn = vbox_inner.findChild(name=btn_name)
			if SavegameAccessor.get_hash(path) != game.get_map_hash():
				text = ""
				if btn is None:
					btn = Button(name=btn_name)
					btn.text = _("This savegame is missing (click here)")
					last_elem = vbox_inner.findChild(name="game_info_last")
					if last_elem is None: # no last elem -> we are last
						vbox_inner.addChild( btn )
					else:
						vbox_inner.insertChildBefore( btn, last_elem )
				btn_text = _(u"For multiplayer load, it is necessary for you to have the correct savegame file.") + u"\n"
				btn_text += _(u"The file will be downloaded when the game starts.")
				btn.btn_text = btn_text
				def show():
					self.show_popup(_("Help"), btn_text, size=1)
				btn.capture(show)

			else:
				text = _(u"This is a savegame.")
				if btn is not None:
					btn.hide()

			if text:
				self.current.findChild(name="game_isloaded").text = text

		self.__update_players_box(game)

		vbox_inner.adaptLayout() # inner vbox always exists
		vbox = self.current.findChild(name="gamedetailsbox")
		if vbox is not None:
			vbox.adaptLayout()
	def __actual_join(self, game=None, password=""):
		"""Does the actual joining to the game.

		 This method is called after everything is OK for joining."""
		if game is None:
			return False

		self.__apply_new_nickname()
		self.__apply_new_color()

		fetch = False
		if game.is_savegame() and SavegameAccessor.get_hash(SavegameManager.get_multiplayersave_map(game.mapname)) != game.get_map_hash():
			fetch = True

		if not NetworkInterface().joingame(game.get_uuid(), password, fetch):
			return False
		self.__show_gamelobby()
		return True
    def __actual_join(self, game=None, password=""):
        """Does the actual joining to the game.

		 This method is called after everything is OK for joining."""
        if game is None:
            return False

        self.__apply_new_nickname()
        self.__apply_new_color()

        fetch = False
        if game.is_savegame() and SavegameAccessor.get_hash(
                SavegameManager.get_multiplayersave_map(
                    game.mapname)) != game.get_map_hash():
            fetch = True

        if not NetworkInterface().joingame(game.get_uuid(), password, fetch):
            return False
        self.__show_gamelobby()
        return True
    def __create_game(self, load=None, chosen_map=None):
        """
		Actually create a game, join it, and display the lobby.

		@param load: game data tuple for creating loaded games
		@param chosen_map: the name of the map to start a new game on (overrides the gui)
		"""
        # create the game
        if load:
            mapname, gamename, gamepassword = load
            path = SavegameManager.get_multiplayersave_map(mapname)
            maxplayers = SavegameAccessor.get_players_num(path)
            password = gamepassword
            maphash = SavegameAccessor.get_hash(path)
        else:
            mapindex = None
            if chosen_map is not None:
                for i, map in enumerate(self.maps_display):
                    if map == chosen_map:
                        mapindex = i
                        break

            if mapindex is None:
                mapindex = self.current.collectData('maplist')
            mapname = self.maps_display[mapindex]
            maxplayers = self.current.collectData(
                'playerlimit') + 2  # 1 is the first entry
            gamename = self.current.collectData('gamename')
            password = self.current.collectData('password')
            maphash = ""

        password = hashlib.sha1(password).hexdigest() if password != "" else ""
        game = NetworkInterface().creategame(mapname, maxplayers, gamename,
                                             maphash, password)
        if game is None:
            return

        self.__show_gamelobby()
	def __join_game(self, game=None):
		"""Joins a multiplayer game. Displays lobby for that specific game"""
		if game == None:
			game = self.__get_selected_game()
		if game.load is not None and SavegameAccessor.get_hash(SavegameManager.get_multiplayersave_map(game.mapname)) != game.load:
			NetworkInterface().send_fetch_game(NetworkInterface().get_clientversion(), game.get_uuid())

		if game.get_uuid() == -1: # -1 signals no game
			AmbientSoundComponent.play_special('error')
			return
		if game.get_version() != NetworkInterface().get_clientversion():
			self.show_popup(_("Wrong version"),
			                   #xgettext:python-format
			                _("The game's version differs from your version. Every player in a multiplayer game must use the same version. This can be fixed by every player updating to the latest version. Game version: {game_version} Your version: {own_version}").format(
			                  game_version=game.get_version(),
			                  own_version=NetworkInterface().get_clientversion()))
			return

		# actual join
		if game.password:
			self.__enter_password_dialog(game)

		else:
			self.__actual_join(game)
    def __update_game_details(self, game=None):
        """Set map name and other misc data in a widget. Only possible in certain states"""
        if game is None:
            game = self.__get_selected_game()
            if game is None:
                return
        #xgettext:python-format
        self.current.findChild(
            name="game_map").text = _("Map: {map_name}").format(
                map_name=game.get_map_name())
        self.current.findChild(
            name="game_name").text = _("Name: {game_name}").format(
                game_name=game.get_name())
        self.current.findChild(
            name="game_creator").text = _("Creator: {game_creator}").format(
                game_creator=game.get_creator())
        #xgettext:python-format
        self.current.findChild(name="game_playersnum").text = _(
            "Players: {player_amount}/{player_limit}").format(
                player_amount=game.get_player_count(),
                player_limit=game.get_player_limit())
        vbox_inner = self.current.findChild(name="game_info")
        if game.is_savegame(
        ):  # work around limitations of current systems via messages
            path = SavegameManager.get_multiplayersave_map(game.mapname)
            btn_name = "save_missing_help_button"
            btn = vbox_inner.findChild(name=btn_name)
            if SavegameAccessor.get_hash(path) != game.get_map_hash():
                text = ""
                if btn is None:
                    btn = Button(name=btn_name)
                    btn.text = _("This savegame is missing (click here)")
                    last_elem = vbox_inner.findChild(name="game_info_last")
                    if last_elem is None:  # no last elem -> we are last
                        vbox_inner.addChild(btn)
                    else:
                        vbox_inner.insertChildBefore(btn, last_elem)
                btn_text = _(
                    u"For multiplayer load, it is necessary for you to have the correct savegame file."
                ) + u"\n"
                btn_text += _(
                    u"The file will be downloaded when the game starts.")
                btn.btn_text = btn_text

                def show():
                    self.show_popup(_("Help"), btn_text, size=1)

                btn.capture(show)

            else:
                text = _(u"This is a savegame.")
                if btn is not None:
                    btn.hide()

            if text:
                self.current.findChild(name="game_isloaded").text = text

        self.__update_players_box(game)

        vbox_inner.adaptLayout()  # inner vbox always exists
        vbox = self.current.findChild(name="gamedetailsbox")
        if vbox is not None:
            vbox.adaptLayout()
	def process_async_packet(self, packet):
		if packet is None:
			return True
		if isinstance(packet[1], packets.server.cmd_chatmsg):
			# ignore packet if we are not a game lobby
			if self.game is None:
				return True
			self.call_callbacks("lobbygame_chat", self.game, packet[1].playername, packet[1].chatmsg)
		elif isinstance(packet[1], packets.server.data_gamestate):
			# ignore packet if we are not a game lobby
			if self.game is None:
				return True
			self.call_callbacks("lobbygame_state", self.game, packet[1].game)

			#if there is more ready player then show it as chat message
			if len(self.game.ready_players) < len(packet[1].game.ready_players):
				self.game = packet[1].game
				self.call_callbacks("lobbygame_toggleready", self.game, packet[1].game.ready_players[-1])
				return True
			#if there is less ready player then show it as chat message
			elif len(self.game.ready_players) > len(packet[1].game.ready_players):
				for nonready in self.game.ready_players:
					if nonready not in packet[1].game.ready_players:
						self.game = packet[1].game
						self.call_callbacks("lobbygame_toggleready", self.game, nonready)
						return True

			oldplayers = list(self.game.players)
			self.game = packet[1].game

			# calculate changeset
			for pnew in self.game.players:
				found = None
				for pold in oldplayers:
					if pnew.sid == pold.sid:
						found = pold
						myself = pnew.sid == self.sid
						if pnew.name != pold.name:
							self.call_callbacks("lobbygame_changename", self.game, pold, pnew, myself)
						if pnew.color != pold.color:
							self.call_callbacks("lobbygame_changecolor", self.game, pold, pnew, myself)
						break
				if found is None:
					self.call_callbacks("lobbygame_join", self.game, pnew)
				else:
					oldplayers.remove(found)
			for pold in oldplayers:
				self.call_callbacks("lobbygame_leave", self.game, pold)
			return True
		elif isinstance(packet[1], packets.server.cmd_preparegame):
			# ignore packet if we are not a game lobby
			if self.game is None:
				return True
			self.ongameprepare()
		elif isinstance(packet[1], packets.server.cmd_startgame):
			# ignore packet if we are not a game lobby
			if self.game is None:
				return True
			self.ongamestart()
		elif isinstance(packet[1], packets.client.game_data):
			self.log.debug("[GAMEDATA] from %s" % (packet[0].address))
			self.call_callbacks("game_data", packet[1].data)
		elif isinstance(packet[1], packets.server.cmd_kick_player):
			self.call_callbacks("lobbygame_kickplayer", self.game, packet[1].player)
		elif isinstance(packet[1], packets.server.cmd_fetch_game):
			if self.game is None:
				return True
			path = SavegameManager.get_multiplayersave_map(self.game.mapname)
			compressed_data = bz2.compress(open(path).read())
			self.send(packets.client.savegame_data(compressed_data, packet[1].psid))
		elif isinstance(packet[1], packets.server.savegame_data):
			open(SavegameManager.get_multiplayersave_map(packet[1].mapname), "w").write(bz2.decompress(packet[1].data))
			self.call_callbacks("savegame_data", self.game)

		return False