class SingleplayerMenu(Window):

	def __init__(self, windows):
		super(SingleplayerMenu, self).__init__(windows)

		self._mode = None

		self._gui = load_uh_widget('singleplayermenu.xml')
		self._gui.mapEvents({
			'cancel'   : self._windows.close,
			'okay'     : self.act,
			'scenario' : Callback(self._select_mode, 'scenario'),
			'random'   : Callback(self._select_mode, 'random'),
			'free_maps': Callback(self._select_mode, 'free_maps')
		})

		self._playerdata = PlayerDataSelection()
		self._aidata = AIDataSelection()
		self._gui.findChild(name="playerdataselectioncontainer").addChild(self._playerdata.get_widget())
		self._gui.findChild(name="aidataselectioncontainer").addChild(self._aidata.get_widget())

	def hide(self):
		# Save the player-data on hide so that other menus gets updated data
		self._playerdata.save_settings()
		self._gui.hide()

	def show(self):
		self._playerdata.update_data()
		self._gui.findChild(name='scenario').marked = True
		self._select_mode('scenario')

	def on_return(self):
		self.act()

	def _select_mode(self, mode):
		self._gui.hide()

		modes = {
			'random': RandomMapWidget,
			'free_maps': FreeMapsWidget,
			'scenario': ScenarioMapWidget,
		}

		# remove old widget
		if self._mode:
			self._mode.end()
			self._gui.findChild(name="right_side_box").removeChild(self._mode.get_widget())

		self._mode = modes[mode](self._windows, self, self._aidata)
		self._mode.show()

		self._gui.findChild(name="right_side_box").addChild(self._mode.get_widget())
		self._gui.show()

	def act(self):
		"""Start the game. Called when OK button is pressed."""
		player_color = self._playerdata.get_player_color()
		player_name = self._playerdata.get_player_name()

		if not player_name:
			self._windows.open_popup(_("Invalid player name"), _("You entered an invalid playername."))
			return

		horizons.globals.fife.set_uh_setting("Nickname", player_name)

		self._windows.close()
		self._mode.act(player_name, player_color)
class MultiplayerMenu(Window):
    def __init__(self, mainmenu, windows):
        super(MultiplayerMenu, self).__init__(windows)
        self._mainmenu = mainmenu
        self._gui = load_uh_widget('multiplayermenu.xml')
        self._gui.mapEvents({
            'cancel': self._windows.close,
            'join': self._join_game,
            'create': self._create_game,
            'refresh': Callback(self._refresh, play_sound=True)
        })

        self._gui.findChild(name='gamelist').capture(self._update_game_details)
        self._playerdata = PlayerDataSelection()
        self._gui.findChild(name="playerdataselectioncontainer").addChild(
            self._playerdata.get_widget())

        # to track if the menu window is opened or not.
        self._is_open = False

    def hide(self):
        # Save the player-data on hide so that other menus gets updated data
        self._playerdata.save_settings()
        self._gui.hide()
        ExtScheduler().rem_all_classinst_calls(self)

    def show(self):
        if not self._check_connection():
            return

        if not self._refresh():
            self._windows.close()
            return

        if not self._is_open:
            self._is_open = True
            # subscribe "error" when this menu window is firstly opened
            # only unsubscribe if this menu window is closed
            NetworkInterface().subscribe("error", self._on_error)

        # get updated player data
        self._playerdata.update_data()

        self._gui.show()

        # TODO: Remove once loading a game is implemented again
        self._gui.findChild(name='load').parent.hide()

        ExtScheduler().add_new_object(self._refresh, self, run_in=5, loops=-1)

    def close(self):
        # if the window is not open (due to connection errors), just do nothing
        if not self._is_open:
            return

        self.hide()

        NetworkInterface().unsubscribe("error", self._on_error)
        self._is_open = False

        # the window is also closed when a game starts, don't disconnect in that case
        if NetworkInterface(
        ).is_connected and not NetworkInterface().is_joined:
            NetworkInterface().disconnect()

    def on_return(self):
        self._join_game()

    def _check_connection(self):
        """
		Check if all dependencies for multiplayer games are met and we can connect to
		the master server. If any dependency is not met, the window is closed.
		"""
        # It is important to close this window before showing the error popup.
        # Otherwise closing the popup will trigger `show` again, a new attempt
        # to connect is made, which ends up in an endless loop.

        if enet is None:
            self._windows.close()
            headline = _("Unable to find pyenet")
            descr = _('The multiplayer feature requires the library "pyenet", '
                      "which could not be found on your system.")
            advice = _(
                "Linux users: Try to install pyenet through your package manager."
            )
            self._windows.open_error_popup(headline, descr, advice)
            return False

        if NetworkInterface() is None:
            try:
                NetworkInterface.create_instance()
            except RuntimeError as e:
                self._windows.close()
                headline = _("Failed to initialize networking.")
                descr = _(
                    "Network features could not be initialized with the current configuration."
                )
                advice = _(
                    "Check the settings you specified in the network section.")
                self._windows.open_error_popup(headline, descr, advice,
                                               unicode(e))
                return False

        if not NetworkInterface().is_connected:
            try:
                NetworkInterface().connect()
            except Exception as err:
                self._windows.close()
                headline = _("Fatal Network Error")
                descr = _("Could not connect to master server.")
                advice = _(
                    "Please check your Internet connection. If it is fine, "
                    "it means our master server is temporarily down.")
                self._windows.open_error_popup(headline, descr, advice,
                                               unicode(err))
                return False

        if NetworkInterface().is_joined:
            if not NetworkInterface().leavegame():
                self._windows.close()
                return False

        return True

    def _on_error(self, exception, fatal=True):
        """Error callback"""
        if not fatal:
            self._windows.open_popup(_("Error"), unicode(exception))
        else:
            self._windows.open_popup(
                _("Fatal Network Error"),
                _("Something went wrong with the network:") + u'\n' +
                unicode(exception))
            # FIXME: this shouldn't be necessary, the main menu window is still somewhere
            # in the stack and we just need to get rid of all MP related windows
            self._mainmenu.show_main()

    def _display_game_name(self, game):
        same_version = game.version == NetworkInterface().get_clientversion()
        template = u"{password}{gamename}: {name} ({players}, {limit}){version}"
        return template.format(
            password="******" if game.has_password else "",
            name=game.map_name,
            gamename=game.name,
            players=game.player_count,
            limit=game.player_limit,
            version=u" " + _("Version differs!") if not same_version else u"")

    def _refresh(self, play_sound=False):
        """Refresh list of games.

		@param play_sound: whether to play the refresh sound
		@return bool, whether refresh worked
		"""
        if play_sound:
            AmbientSoundComponent.play_special('refresh')

        self._games = NetworkInterface().get_active_games()
        if self._games is None:
            return False

        gamelist = [self._display_game_name(g) for g in self._games]
        self._gui.distributeInitialData({'gamelist': gamelist})
        self._gui.distributeData({'gamelist': 0})
        self._update_game_details()
        return True

    def _update_game_details(self):
        """Set map name and other misc data in a widget."""
        try:
            index = self._gui.collectData('gamelist')
            game = self._games[index]
        except IndexError:
            return

        self._gui.findChild(
            name="game_map").text = _("Map: {map_name}").format(
                map_name=game.map_name)
        self._gui.findChild(
            name="game_name").text = _("Name: {game_name}").format(
                game_name=game.name)
        self._gui.findChild(
            name="game_creator").text = _("Creator: {game_creator}").format(
                game_creator=game.creator)
        self._gui.findChild(name="game_playersnum").text = _(
            "Players: {player_amount}/{player_limit}").format(
                player_amount=game.player_count,
                player_limit=game.player_limit)

        vbox_inner = self._gui.findChild(name="game_info")
        vbox_inner.adaptLayout()

    def _join_game(self):
        """Joins a multiplayer game. Displays lobby for that specific game"""
        try:
            index = self._gui.collectData('gamelist')
            game = self._games[index]
        except IndexError:
            return

        if game.uuid == -1:  # -1 signals no game
            AmbientSoundComponent.play_special('error')
            return

        if game.version != NetworkInterface().get_clientversion():
            self._windows.open_popup(
                _("Wrong version"),
                _("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.version,
                       own_version=NetworkInterface().get_clientversion()))
            return

        NetworkInterface().change_name(self._playerdata.get_player_name())
        NetworkInterface().change_color(self._playerdata.get_player_color().id)

        if game.password:
            # ask the player for the password
            popup = PasswordInput(self._windows)
            password = self._windows.open(popup)
            if password is None:
                return
            password = hashlib.sha1(password).hexdigest()
            success = NetworkInterface().joingame(game.uuid, password)
            if not success:
                return
        elif not NetworkInterface().joingame(game.uuid, ''):
            return

        window = GameLobby(self._windows)
        self._windows.open(window)

    def _create_game(self):
        NetworkInterface().change_name(self._playerdata.get_player_name())
        NetworkInterface().change_color(self._playerdata.get_player_color().id)
        self._windows.open(CreateGame(self._windows))
class MultiplayerMenu(Window):

	def __init__(self, mainmenu, windows):
		super(MultiplayerMenu, self).__init__(windows)
		self._mainmenu = mainmenu

	def hide(self):
		self._gui.hide()

	def show(self):
		if not self._check_connection():
			return

		self._gui = load_uh_widget('multiplayermenu.xml')
		self._gui.mapEvents({
			'cancel' : self._windows.close,
			'join'   : self._join_game,
			'create' : self._create_game,
			'refresh': Callback(self._refresh, play_sound=True)
		})

		self._gui.findChild(name='gamelist').capture(self._update_game_details)
		self._playerdata = PlayerDataSelection()
		self._gui.findChild(name="playerdataselectioncontainer").addChild(self._playerdata.get_widget())

		refresh_worked = self._refresh()
		if not refresh_worked:
			self._windows.close()
			return

		# FIXME workaround for multiple callback registrations
		# this happens because subscription is done when the window is showed, unsubscription
		# only when it is closed. if new windows appear and disappear, show is called multiple
		# times. the error handler is used throughout the entire mp menu, that's why we can't
		# unsubscribe in hide. need to find a better solution.
		NetworkInterface().discard("error", self._on_error)
		NetworkInterface().subscribe("error", self._on_error)

		self._gui.show()

		# TODO Remove once loading a game is implemented again
		self._gui.findChild(name='load').parent.hide()

	def close(self):
		# when the connection to the master server fails, the window will be closed before
		# anything has been setup
		if not hasattr(self, '_gui'):
			return

		self.hide()

		NetworkInterface().unsubscribe("error", self._on_error)

		# the window is also closed when a game starts, don't disconnect in that case
		if NetworkInterface().is_connected and not NetworkInterface().is_joined:
			NetworkInterface().disconnect()

		NetworkInterface().change_name(self._playerdata.get_player_name())
		NetworkInterface().change_color(self._playerdata.get_player_color().id)

	def on_return(self):
		self._join_game()

	def _check_connection(self):
		"""
		Check if all dependencies for multiplayer games are met and we can connect to
		the master server. If any dependency is not met, the window is closed.
		"""
		# It is important to close this window before showing the error popup.
		# Otherwise closing the popup will trigger `show` again, a new attempt
		# to connect is made, which ends up in an endless loop.

		if enet is None:
			self._windows.close()
			headline = _("Unable to find pyenet")
			descr = _('The multiplayer feature requires the library "pyenet", '
			          "which could not be found on your system.")
			advice = _("Linux users: Try to install pyenet through your package manager.")
			self._windows.show_error_popup(headline, descr, advice)
			return False

		if NetworkInterface() is None:
			try:
				NetworkInterface.create_instance()
			except RuntimeError as e:
				self._windows.close()
				headline = _("Failed to initialize networking.")
				descr = _("Network features could not be initialized with the current configuration.")
				advice = _("Check the settings you specified in the network section.")
				self._windows.show_error_popup(headline, descr, advice, unicode(e))
				return False

		if not NetworkInterface().is_connected:
			try:
				NetworkInterface().connect()
			except Exception as err:
				self._windows.close()
				headline = _("Fatal Network Error")
				descr = _("Could not connect to master server.")
				advice = _("Please check your Internet connection. If it is fine, "
				           "it means our master server is temporarily down.")
				self._windows.show_error_popup(headline, descr, advice, unicode(err))
				return False

		if NetworkInterface().is_joined:
			if not NetworkInterface().leavegame():
				self._windows.close()
				return False

		return True

	def _on_error(self, exception, fatal=True):
		"""Error callback"""
		if not fatal:
			self._windows.show_popup(_("Error"), unicode(exception))
		else:
			self._windows.show_popup(_("Fatal Network Error"),
		                             _("Something went wrong with the network:") + u'\n' +
		                             unicode(exception) )
			# FIXME this shouldn't be necessary, the main menu window is still somewhere
			# in the stack and we just need to get rid of all MP related windows
			self._mainmenu.show_main()

	def _display_game_name(self, game):
		same_version = game.version == NetworkInterface().get_clientversion()
		template = u"{password}{gamename}: {name} ({players}, {limit}){version}"
		return template.format(
			password="******" if game.has_password else "",
			name=game.map_name,
			gamename=game.name,
			players=game.player_count,
			limit=game.player_limit,
			version=u" " + _("Version differs!") if not same_version else u"")

	def _refresh(self, play_sound=False):
		"""Refresh list of games.

		@param play_sound: whether to play the refresh sound
		@return bool, whether refresh worked
		"""
		if play_sound:
			AmbientSoundComponent.play_special('refresh')

		self._games = NetworkInterface().get_active_games()
		if self._games is None:
			return False

		gamelist = [self._display_game_name(g) for g in self._games]
		self._gui.distributeInitialData({'gamelist': gamelist})
		self._gui.distributeData({'gamelist': 0})
		self._update_game_details()
		return True

	def _update_game_details(self):
		"""Set map name and other misc data in a widget."""
		try:
			index = self._gui.collectData('gamelist')
			game = self._games[index]
		except IndexError:
			return

		self._gui.findChild(name="game_map").text = _("Map: {map_name}").format(map_name=game.map_name)
		self._gui.findChild(name="game_name").text = _("Name: {game_name}").format(game_name=game.name)
		self._gui.findChild(name="game_creator").text = _("Creator: {game_creator}").format(game_creator=game.creator)
		self._gui.findChild(name="game_playersnum").text = _("Players: {player_amount}/{player_limit}").format(
		                           player_amount=game.player_count,
		                           player_limit=game.player_limit)

		vbox_inner = self._gui.findChild(name="game_info")
		vbox_inner.adaptLayout()

	def _join_game(self):
		"""Joins a multiplayer game. Displays lobby for that specific game"""
		try:
			index = self._gui.collectData('gamelist')
			game = self._games[index]
		except IndexError:
			return

		if game.uuid == -1: # -1 signals no game
			AmbientSoundComponent.play_special('error')
			return

		if game.version != NetworkInterface().get_clientversion():
			self._windows.show_popup(_("Wrong version"),
			                          _("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.version,
			                            own_version=NetworkInterface().get_clientversion()))
			return

		NetworkInterface().change_name(self._playerdata.get_player_name())
		NetworkInterface().change_color(self._playerdata.get_player_color().id)

		if game.password:
			# ask the player for the password
			popup = PasswordInput(self._windows)
			password = self._windows.show(popup)
			if password is None:
				return
			password = hashlib.sha1(password).hexdigest()
			success = NetworkInterface().joingame(game.uuid, password)
			if not success:
				return
		elif not NetworkInterface().joingame(game.uuid, ''):
			return

		window = GameLobby(self._windows)
		self._windows.show(window)

	def _create_game(self):
		NetworkInterface().change_name(self._playerdata.get_player_name())
		NetworkInterface().change_color(self._playerdata.get_player_color().id)
		self._windows.show(CreateGame(self._windows)),
class SingleplayerMenu(object):

	def __init__(self, mainmenu):
		self._mainmenu = mainmenu

		self._mode = None

		self._gui = load_uh_widget('singleplayermenu.xml')
		self._gui.mapEvents({
			'cancel'   : self.cancel,
			'okay'     : self.act,
			'scenario' : Callback(self._select_mode, 'scenario'),
			'random'   : Callback(self._select_mode, 'random'),
			'free_maps': Callback(self._select_mode, 'free_maps')
		})

		self._playerdata = PlayerDataSelection()
		self._aidata = AIDataSelection()
		self._gui.findChild(name="playerdataselectioncontainer").addChild(self._playerdata.get_widget())
		self._gui.findChild(name="aidataselectioncontainer").addChild(self._aidata.get_widget())

	def hide(self):
		self._gui.hide()

	def cancel(self):
		self._mainmenu.show_main()

	def show(self):
		self._mainmenu.hide()
		self._mainmenu.current = self
		self._mainmenu.on_escape = self.cancel

		self._gui.findChild(name='scenario').marked = True
		self._select_mode('scenario')

	def _select_mode(self, mode):
		self._gui.hide()

		modes = {
			'random': RandomMapWidget,
			'free_maps': FreeMapsWidget,
			'scenario': ScenarioMapWidget,
		}

		# remove old widget
		if self._mode:
			self._mode.end()
			self._gui.findChild(name="right_side_box").removeChild(self._mode.get_widget())

		self._mode = modes[mode](self._mainmenu, self, self._aidata)
		self._mode.show()

		self._gui.findChild(name="right_side_box").addChild(self._mode.get_widget())
		self._gui.show()

	def act(self):
		"""Start the game. Called when OK button is pressed."""
		player_color = self._playerdata.get_player_color()
		player_name = self._playerdata.get_player_name()

		if not player_name:
			self._mainmenu.show_popup(_("Invalid player name"), _("You entered an invalid playername."))
			return

		horizons.globals.fife.set_uh_setting("Nickname", player_name)

		self._mode.act(player_name, player_color)
Exemple #5
0
class SingleplayerMenu(Window):
    def __init__(self, windows):
        super(SingleplayerMenu, self).__init__(windows)

        self._mode = None

        self._gui = load_uh_widget('singleplayermenu.xml')
        self._gui.mapEvents({
            'cancel':
            self._windows.close,
            'okay':
            self.act,
            'scenario':
            Callback(self._select_mode, 'scenario'),
            'random':
            Callback(self._select_mode, 'random'),
            'free_maps':
            Callback(self._select_mode, 'free_maps')
        })

        self._playerdata = PlayerDataSelection()
        self._aidata = AIDataSelection()
        self._gui.findChild(name="playerdataselectioncontainer").addChild(
            self._playerdata.get_widget())
        self._gui.findChild(name="aidataselectioncontainer").addChild(
            self._aidata.get_widget())

    def hide(self):
        # Save the player-data on hide so that other menus gets updated data
        self._playerdata.save_settings()
        self._gui.hide()

    def show(self):
        self._playerdata.update_data()
        self._gui.findChild(name='scenario').marked = True
        self._select_mode('scenario')

    def on_return(self):
        self.act()

    def _select_mode(self, mode):
        self._gui.hide()

        modes = {
            'random': RandomMapWidget,
            'free_maps': FreeMapsWidget,
            'scenario': ScenarioMapWidget,
        }

        # remove old widget
        if self._mode:
            self._mode.end()
            self._gui.findChild(name="right_side_box").removeChild(
                self._mode.get_widget())

        self._mode = modes[mode](self._windows, self, self._aidata)
        self._mode.show()

        self._gui.findChild(name="right_side_box").addChild(
            self._mode.get_widget())
        self._gui.show()

    def act(self):
        """Start the game. Called when OK button is pressed."""
        player_color = self._playerdata.get_player_color()
        player_name = self._playerdata.get_player_name()

        if not player_name:
            self._windows.open_popup(_("Invalid player name"),
                                     _("You entered an invalid playername."))
            return

        horizons.globals.fife.set_uh_setting("Nickname", player_name)

        self._windows.close()
        self._mode.act(player_name, player_color)
class MultiplayerMenu(object):

	def __init__(self, mainmenu):
		self._mainmenu = mainmenu

	def hide(self):
		self._gui.hide()

	def show(self):
		if not self._check_connection():
			return

		self._mainmenu.hide()
		self._mainmenu.current = self
		self._mainmenu.on_escape = self.close

		self._gui = load_uh_widget('multiplayermenu.xml')
		self._gui.mapEvents({
			'cancel' : self.close,
			'join'   : self._join_game,
			'create' : self._create_game,
			'refresh': Callback(self._refresh, play_sound=True)
		})

		self._gui.findChild(name='gamelist').capture(self._update_game_details)
		self._gui.findChild(name='showonlyownversion').capture(self._refresh)
		self._playerdata = PlayerDataSelection()
		self._gui.findChild(name="playerdataselectioncontainer").addChild(self._playerdata.get_widget())

		refresh_worked = self._refresh()
		if not refresh_worked:
			self.cancel()
			return

		NetworkInterface().subscribe("game_prepare", self._prepare_game)
		NetworkInterface().subscribe("game_starts", self._start_game)
		NetworkInterface().subscribe("error", self._on_error)

		self._gui.show()

		# TODO Remove once loading a game is implemented again
		self._gui.findChild(name='load').parent.hide()

	def close(self):
		self.hide()

		NetworkInterface().unsubscribe("game_prepare", self._prepare_game)
		NetworkInterface().unsubscribe("game_starts", self._start_game)
		NetworkInterface().unsubscribe("error", self._on_error)

		if NetworkInterface().is_connected:
			NetworkInterface().disconnect()

		NetworkInterface().change_name(self._playerdata.get_player_name())
		NetworkInterface().change_color(self._playerdata.get_player_color().id)
		self._mainmenu.show_main()

	def _check_connection(self):
		"""
		Check if all dependencies for multiplayer games are met and we can connect to
		the master server.
		"""
		if enet is None:
			headline = _(u"Unable to find pyenet")
			descr = _(u'The multiplayer feature requires the library "pyenet", '
			          u"which could not be found on your system.")
			advice = _(u"Linux users: Try to install pyenet through your package manager.")
			self._mainmenu.show_error_popup(headline, descr, advice)
			return False

		if NetworkInterface() is None:
			try:
				NetworkInterface.create_instance()
			except RuntimeError as e:
				headline = _(u"Failed to initialize networking.")
				descr = _("Network features could not be initialized with the current configuration.")
				advice = _("Check the settings you specified in the network section.")
				self._mainmenu.show_error_popup(headline, descr, advice, unicode(e))
				return False

		if not NetworkInterface().is_connected:
			try:
				NetworkInterface().connect()
			except Exception as err:
				headline = _(u"Fatal Network Error")
				descr = _(u"Could not connect to master server.")
				advice = _(u"Please check your Internet connection. If it is fine, "
						   u"it means our master server is temporarily down.")
				self._mainmenu.show_error_popup(headline, descr, advice, unicode(err))
				return False

		if NetworkInterface().is_joined:
			if not NetworkInterface().leavegame():
				return False

		return True

	def _on_error(self, exception, fatal=True):
		"""Error callback"""
		if fatal and self._mainmenu.session is not None:
			self._mainmenu.session.timer.ticks_per_second = 0
		if not fatal:
			self._mainmenu.show_popup(_("Error"), unicode(exception))
		else:
			self._mainmenu.show_popup(_("Fatal Network Error"),
		                             _("Something went wrong with the network:") + u'\n' +
		                             unicode(exception) )
			self._mainmenu.quit_session(force=True)

	def _display_game_name(self, game):
		same_version = game.version == NetworkInterface().get_clientversion()
		template = u"{password}{gamename}: {name} ({players}, {limit}){version}"
		return template.format(
			password="******" if game.has_password else "",
			name=game.map_name,
			gamename=game.name,
			players=game.player_count,
			limit=game.player_limit,
			version=u" " + _("Version differs!") if not same_version else u"")

	def _refresh(self, play_sound=False):
		"""Refresh list of games.

		@param play_sound: whether to play the refresh sound
		@return bool, whether refresh worked
		"""
		if play_sound:
			AmbientSoundComponent.play_special('refresh')

		only_this_version_allowed = self._gui.findChild(name='showonlyownversion').marked
		self._games = NetworkInterface().get_active_games(only_this_version_allowed)
		if self._games is None:
			return False

		gamelist = [self._display_game_name(g) for g in self._games]
		self._gui.distributeInitialData({'gamelist': gamelist})
		self._gui.distributeData({'gamelist': 0})
		self._update_game_details()
		return True

	def _update_game_details(self):
		"""Set map name and other misc data in a widget."""
		try:
			index = self._gui.collectData('gamelist')
			game = self._games[index]
		except IndexError:
			return

		#xgettext:python-format
		self._gui.findChild(name="game_map").text = _("Map: {map_name}").format(map_name=game.map_name)
		self._gui.findChild(name="game_name").text = _("Name: {game_name}").format(game_name=game.name)
		self._gui.findChild(name="game_creator").text = _("Creator: {game_creator}").format(game_creator=game.creator)
		#xgettext:python-format
		self._gui.findChild(name="game_playersnum").text = _("Players: {player_amount}/{player_limit}").format(
		                           player_amount=game.player_count,
		                           player_limit=game.player_limit)

		vbox_inner = self._gui.findChild(name="game_info")
		vbox_inner.adaptLayout()

	def _join_game(self):
		"""Joins a multiplayer game. Displays lobby for that specific game"""
		try:
			index = self._gui.collectData('gamelist')
			game = self._games[index]
		except IndexError:
			return

		if game.uuid == -1: # -1 signals no game
			AmbientSoundComponent.play_special('error')
			return

		if game.version != NetworkInterface().get_clientversion():
			self._mainmenu.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.version,
			                            own_version=NetworkInterface().get_clientversion()))
			return

		password = ""
		if game.password:
			# Repeatedly ask the player for the password
			success = False
			while not success:
				password = self._request_game_password(game)
				if password is None:
					break
				password = hashlib.sha1(password).hexdigest()
				success = NetworkInterface().joingame(game.uuid, password)

			if not success:
				return
		else:
			if not NetworkInterface().joingame(game.uuid, password):
				return

		self.show_lobby()

	def _request_game_password(self, game):
		"""Show dialog to ask player for a password."""
		dialog = load_uh_widget('set_password.xml')

		bind = {OkButton.DEFAULT_NAME: True, CancelButton.DEFAULT_NAME: False}
		retval = self._mainmenu.show_dialog(dialog, bind, modal=True, focus="password")

		if retval:
			return dialog.collectData("password")
		else:
			return None

	def _create_game(self):
		window = CreateGame(self._mainmenu, self)
		window.show()

	def show_lobby(self):
		window = GameLobby(self._mainmenu, self)
		window.show()

	def _prepare_game(self, game):
		self._mainmenu.show_loading_screen()
		horizons.main.prepare_multiplayer(game)

	def _start_game(self, game):
		# TODO listening for this event could be moved to MPSession
		horizons.main.start_multiplayer(game)