def _show_change_player_details_popup(self, game): """Shows a dialog where the player can change its name and/or color""" assigned = [p["color"] for p in NetworkInterface().get_game().get_player_list() if p["name"] != NetworkInterface().get_client_name()] unused_colors = set(Color) - set(assigned) playerdata = PlayerDataSelection(color_palette=unused_colors) playerdata.set_player_name(NetworkInterface().get_client_name()) playerdata.set_color(NetworkInterface().get_client_color()) dialog = load_uh_widget('set_player_details.xml') dialog.findChild(name="playerdataselectioncontainer").addChild(playerdata.get_widget()) def _change_playerdata(): NetworkInterface().change_name(playerdata.get_player_name()) NetworkInterface().change_color(playerdata.get_player_color().id) dialog.hide() self._update_game_details() def _cancel(): dialog.hide() dialog.mapEvents({ OkButton.DEFAULT_NAME: _change_playerdata, CancelButton.DEFAULT_NAME: _cancel }) dialog.show()
def _show_change_player_details_popup(self, game): """Shows a dialog where the player can change its name and/or color""" assigned = [ p["color"] for p in NetworkInterface().get_game().get_player_list() if p["name"] != NetworkInterface().get_client_name() ] unused_colors = set(Color) - set(assigned) playerdata = PlayerDataSelection(color_palette=unused_colors) playerdata.set_player_name(NetworkInterface().get_client_name()) playerdata.set_color(NetworkInterface().get_client_color()) dialog = load_uh_widget('set_player_details.xml') dialog.findChild(name="playerdataselectioncontainer").addChild( playerdata.get_widget()) def _change_playerdata(): NetworkInterface().change_name(playerdata.get_player_name()) NetworkInterface().change_color(playerdata.get_player_color().id) dialog.hide() self._update_game_details() def _cancel(): dialog.hide() dialog.mapEvents({ OkButton.DEFAULT_NAME: _change_playerdata, CancelButton.DEFAULT_NAME: _cancel }) dialog.show()
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)
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)