def set_network_port(self, port):
     """Sets a new value for client network port"""
     # port is saved as string due to pychan limitations
     try:
         # 0 is not a valid port, but a valid value here (used for default)
         parse_port(port, allow_zero=True)
     except ValueError:
         headline = _("Invalid network port")
         descr = _("The port you specified is not valid. It must be a number between 1 and 65535.")
         advice = _("Please check the port you entered and make sure it is in the specified range.")
         horizons.main._modules.gui.show_error_popup(headline, descr, advice)
         # reset value and reshow settings dlg
         self.engine.set_uh_setting("NetworkPort", u"0")
         ExtScheduler().add_new_object(self._setting.onOptionsPress, self.engine, 0)
     else:
         # port is valid
         try:
             if NetworkInterface() is None:
                 NetworkInterface.create_instance()
             NetworkInterface().network_data_changed(connect=False)
         except Exception as e:
             headline = _(u"Failed to apply new network settings.")
             descr = _("Network features could not be initialized with the current configuration.")
             advice = _("Check the settings you specified in the network section.")
             if 0 < parse_port(port, allow_zero=True) < 1024:
                 # i18n This is advice for players seeing a network error with the current config
                 advice += u" " + _(
                     "Low port numbers sometimes require special access privileges, try 0 or a number greater than 1024."
                 )
             details = unicode(e)
             horizons.main._modules.gui.show_error_popup(headline, descr, advice, details)
             ExtScheduler().add_new_object(self._setting.onOptionsPress, self.engine, 0)
	def set_network_port(self, port):
		"""Sets a new value for client network port"""
		# port is saved as string due to pychan limitations
		try:
			# 0 is not a valid port, but a valid value here (used for default)
			parse_port(port)
		except ValueError:
			headline = _("Invalid network port")
			descr = _("The port you specified is not valid. It must be a number between 1 and 65535.")
			advice = _("Please check the port you entered and make sure it is in the specified range.")
			horizons.main._modules.gui.show_error_popup(headline, descr, advice)
			# reset value and reshow settings dlg
			self.engine.set_uh_setting("NetworkPort", u"0")
			ExtScheduler().add_new_object(self._setting.onOptionsPress, self.engine, 0)
		else:
			# port is valid
			try:
				if NetworkInterface() is None:
					NetworkInterface.create_instance()
				NetworkInterface().network_data_changed()
			except Exception as e:
				headline = _("Failed to apply new network settings.")
				descr = _("Network features could not be initialized with the current configuration.")
				advice = _("Check the settings you specified in the network section.")
				if 0 < parse_port(port) < 1024:
					#i18n This is advice for players seeing a network error with the current config
					advice += u" " + \
						_("Low port numbers sometimes require special access privileges, try 0 or a number greater than 1024.")
				details = unicode(e)
				horizons.main._modules.gui.show_error_popup(headline, descr, advice, details)
				ExtScheduler().add_new_object(self._setting.onOptionsPress, self.engine, 0)
    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()
Beispiel #4
0
	def _on_NetworkPort_changed(self, old, new):
		"""Sets a new value for client network port"""
		# port is saved as string due to pychan limitations
		try:
			# 0 is not a valid port, but a valid value here (used for default)
			parse_port(new)
		except ValueError:
			headline = T("Invalid network port")
			descr = T("The port you specified is not valid. It must be a number between 1 and 65535.")
			advice = T("Please check the port you entered and make sure it is in the specified range.")
			self._windows.open_error_popup(headline, descr, advice)
			# reset value and reshow settings dlg
			self._settings.set(SETTINGS.UH_MODULE, 'NetworkPort', u"0")
		else:
			# port is valid
			try:
				if NetworkInterface() is None:
					NetworkInterface.create_instance()
				NetworkInterface().network_data_changed()
			except Exception as e:
				headline = T("Failed to apply new network settings.")
				descr = T("Network features could not be initialized with the current configuration.")
				advice = T("Check the settings you specified in the network section.")
				if 0 < parse_port(new) < 1024:
					#i18n This is advice for players seeing a network error with the current config
					advice += u" " + \
						T("Low port numbers sometimes require special access privileges, try 0 or a number greater than 1024.")
				details = unicode(e)
				self._windows.open_error_popup(headline, descr, advice, details)
Beispiel #5
0
 def _on_NetworkPort_changed(self, old, new):
     """Sets a new value for client network port"""
     # port is saved as string due to pychan limitations
     try:
         # 0 is not a valid port, but a valid value here (used for default)
         parse_port(new)
     except ValueError:
         headline = _("Invalid network port")
         descr = _("The port you specified is not valid. It must be a number between 1 and 65535.")
         advice = _("Please check the port you entered and make sure it is in the specified range.")
         self._windows.open_error_popup(headline, descr, advice)
         # reset value and reshow settings dlg
         self._settings.set(SETTINGS.UH_MODULE, "NetworkPort", u"0")
     else:
         # port is valid
         try:
             if NetworkInterface() is None:
                 NetworkInterface.create_instance()
             NetworkInterface().network_data_changed()
         except Exception as e:
             headline = _("Failed to apply new network settings.")
             descr = _("Network features could not be initialized with the current configuration.")
             advice = _("Check the settings you specified in the network section.")
             if 0 < parse_port(new) < 1024:
                 # i18n This is advice for players seeing a network error with the current config
                 advice += u" " + _(
                     "Low port numbers sometimes require special access privileges, try 0 or a number greater than 1024."
                 )
             details = unicode(e)
             self._windows.open_error_popup(headline, descr, advice, details)
    def __join_game(self, game=None):
        """Joins a multiplayer game. Displays lobby for that specific game"""
        if game is None:
            game = self.__get_selected_game()
            if game is None:
                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
        if game.password:
            self.__enter_password_dialog(game)

        else:
            self.__actual_join(game)
	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 show_multi(self):
        """Shows main multiplayer menu"""
        if enet == None:
            headline = _(u"Unable to find pyenet")
            descr = _(
                u'The multiplayer feature requires the library "pyenet", which couldn\'t be found on your system.'
            )
            advice = (
                _(u"Linux users: Try to install pyenet through your package manager.")
                + "\n"
                + _(u"Windows users: There is currently no reasonable support for Windows.")
            )
            self.show_error_popup(headline, descr, advice)
            return

        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.show_error_popup(headline, descr, advice, unicode(e))
                return

        if not NetworkInterface().isconnected():
            connected = self.__connect_to_server()
            if not connected:
                return

        if NetworkInterface().isjoined():
            if not NetworkInterface().leavegame():
                return

        event_map = {
            "cancel": self.__cancel,
            "join": self.__join_game,
            "create": self.__show_create_game,
            "load": self.__show_load_game,
            "refresh": self.__refresh,
        }
        # store old name and color
        self.__apply_new_nickname()
        # reload because changing modes (not yet implemented) will need it
        self.widgets.reload("multiplayermenu")
        self._switch_current_widget("multiplayermenu", center=True, event_map=event_map, hide_old=True)

        refresh_worked = self.__refresh()
        if not refresh_worked:
            self.show_main()
            return
        self.current.findChild(name="gamelist").capture(self.__update_game_details)
        self.current.findChild(name="showonlyownversion").capture(self.__show_only_own_version_toggle)
        self.current.playerdata = PlayerDataSelection(self.current, self.widgets)

        self.current.show()

        self.on_escape = event_map["cancel"]
 def __get_selected_game(self):
     try:
         if NetworkInterface().isjoined():
             return NetworkInterface().get_game()
         else:
             index = self.current.collectData('gamelist')
             return self.games[index]
     except:
         return None
 def _get_unused_colors():
     """Returns unused colors list in a game """
     assigned = [
         p["color"]
         for p in NetworkInterface().get_game().get_player_list()
         if p["name"] != NetworkInterface().get_client_name()
     ]
     available = set(Color) - set(assigned)
     return available
	def __init__(self, windows):
		super(GameLobby, self).__init__(windows)

		self._gui = load_uh_widget('multiplayer_gamelobby.xml')
		self._gui.mapEvents({
			'cancel': self._cancel,
			'ready_btn': NetworkInterface().toggle_ready,
		})

		NetworkInterface().subscribe("game_prepare", self._prepare_game)
	def show_multi(self):
		"""Shows main multiplayer menu"""
		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

		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

		if not NetworkInterface().is_connected:
			connected = self.__connect_to_server()
			if not connected:
				return

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

		event_map = {
			'cancel'  : self.__cancel,
			'join'    : self.__join_game,
			'create'  : self.__show_create_game,
			'load'    : self.__show_load_game,
			'refresh' : Callback(self.__refresh, play_sound=True)
		}
		# store old name and color
		self.__apply_new_nickname()
		self.__apply_new_color()
		# reload because changing modes (not yet implemented) will need it
		self.widgets.reload('multiplayermenu')
		self.mainmenu._switch_current_widget('multiplayermenu', center=True, event_map=event_map, hide_old=True)
		self.current = self.mainmenu.current

		refresh_worked = self.__refresh()
		if not refresh_worked:
			self.mainmenu.show_main()
			return
		self.current.findChild(name='gamelist').capture(self.__update_game_details)
		self.current.findChild(name='showonlyownversion').capture(self.__show_only_own_version_toggle)
		self.current.playerdata = PlayerDataSelection(self.current, self.widgets)

		self.current.show()

		self.mainmenu.on_escape = event_map['cancel']
	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 = T("Unable to find pyenet")
			descr = T('The multiplayer feature requires the library "pyenet", '
			          "which could not be found on your system.")
			advice = T("For instructions on installing pyenet see:"
			           "https://github.com/unknown-horizons/unknown-horizons/wiki/Installing-PyEnet")
			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 = T("Failed to initialize networking.")
				descr = T("Network features could not be initialized with the current configuration.")
				advice = T("Check the settings you specified in the network section.")
				self._windows.open_error_popup(headline, descr, advice, str(e))
				return False

		if not NetworkInterface().is_connected:
			try:
				NetworkInterface().connect()
			except TypeError as terr:
				self._windows.close()
				headline = T("Pyenet type error")
				descr = T("You are probably using an incompatible pyenet installation")
				advice = T("For instructions on properly installing pyenet see: "
				           "https://github.com/unknown-horizons/unknown-horizons/wiki/Installing-PyEnet")
				self._windows.open_error_popup(headline, descr, advice, str(terr))
			except Exception as err:
				self._windows.close()
				headline = T("Fatal Network Error")
				descr = T("Could not connect to master server.")
				advice = T("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, str(err))
				return False

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

		return True
    def open(self):
        textfield = self._gui.findChild(name="chatTextField")
        textfield.capture(self._send_chat_message)
        welcome_string = T("Enter your message")

        def chatfield_clicked():
            if textfield.text == welcome_string:
                textfield.text = ""

        textfield.text = welcome_string
        textfield.capture(chatfield_clicked, event_name="mouseClicked")

        self._update_game_details()

        NetworkInterface().subscribe("lobbygame_chat", self._on_chat_message)
        NetworkInterface().subscribe("lobbygame_join", self._on_player_joined)
        NetworkInterface().subscribe("lobbygame_leave", self._on_player_left)
        NetworkInterface().subscribe("lobbygame_kick", self._on_player_kicked)
        NetworkInterface().subscribe("lobbygame_changename",
                                     self._on_player_changed_name)
        NetworkInterface().subscribe("lobbygame_changecolor",
                                     self._on_player_changed_color)
        NetworkInterface().subscribe("lobbygame_toggleready",
                                     self._on_player_toggled_ready)
        NetworkInterface().subscribe("game_details_changed",
                                     self._update_game_details)
        NetworkInterface().subscribe("error", self._on_error)

        self.show()
    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 close(self):
		self.hide()

		NetworkInterface().unsubscribe("lobbygame_chat", self._on_chat_message)
		NetworkInterface().unsubscribe("lobbygame_join", self._on_player_joined)
		NetworkInterface().unsubscribe("lobbygame_leave", self._on_player_left)
		NetworkInterface().unsubscribe("lobbygame_kick", self._on_player_kicked)
		NetworkInterface().unsubscribe("lobbygame_changename", self._on_player_changed_name)
		NetworkInterface().unsubscribe("lobbygame_changecolor", self._on_player_changed_color)
		NetworkInterface().unsubscribe("lobbygame_toggleready", self._on_player_toggled_ready)
		NetworkInterface().unsubscribe("game_details_changed", self._update_game_details)
		NetworkInterface().unsubscribe("game_prepare", self._prepare_game)
def prepare_multiplayer(game):
    """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.cursor.set(fife_module.CURSOR_IMAGE, fife.default_cursor_image)

    # 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
    random = sum(game.get_uuid().uuid)
    _modules.session = MPSession(_modules.gui,
                                 db,
                                 NetworkInterface(),
                                 rng_seed=random)
    # NOTE: this data passing is only temporary, maybe use a player class/struct
    _modules.session.load("content/maps/" + game.get_map_name() + ".sqlite", \
                          game.get_player_list())
Beispiel #18
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)
	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 _cancel(self):
        """When the lobby is cancelled, close the window and leave the game.

		We can't do this in `close`, because the window will be closed when a game starts
		as well, and we don't want to leave the game then.
		"""
        self._windows.close()
        NetworkInterface().leavegame()
    def __show_change_player_details_popup(self):
        """Shows a dialog where the player can change its name and/or color"""
        def _get_unused_colors():
            """Returns unused colors list in a game """
            assigned = [
                p["color"]
                for p in NetworkInterface().get_game().get_player_list()
                if p["name"] != NetworkInterface().get_client_name()
            ]
            available = set(Color) - set(assigned)
            return available

        set_player_details_dialog = self.widgets['set_player_details']
        #remove all children of color and name pop-up and then show them
        set_player_details_dialog.findChild(
            name="playerdataselectioncontainer").removeAllChildren()
        #assign playerdata to self.current.playerdata to use self.__apply_new_color() and __apply_new_nickname()
        self.current.playerdata = PlayerDataSelection(
            set_player_details_dialog,
            self.widgets,
            color_palette=_get_unused_colors())
        self.current.playerdata.set_player_name(
            NetworkInterface().get_client_name())
        self.current.playerdata.set_color(
            NetworkInterface().get_client_color())

        def _change_playerdata():
            self.__apply_new_nickname()
            self.__apply_new_color()
            set_player_details_dialog.hide()
            self.__update_game_details()

        def _cancel():
            set_player_details_dialog.hide()

        events = {
            OkButton.DEFAULT_NAME: _change_playerdata,
            CancelButton.DEFAULT_NAME: _cancel
        }
        self.on_escape = _cancel

        set_player_details_dialog.mapEvents(events)
        set_player_details_dialog.show()
        def _add_player_line(player):
            pname = Label(name="pname_%s" % player['name'])
            pname.helptext = _("Click here to change your name and/or color")
            pname.text = player['name']
            if player['name'] == NetworkInterface().get_client_name():
                pname.capture(Callback(
                    self.__show_change_player_details_popup))
            pname.min_size = pname.max_size = (130, 15)

            pcolor = Label(name="pcolor_%s" % player['name'], text=u"   ")
            pcolor.helptext = _("Click here to change your name and/or color")
            pcolor.background_color = player['color']
            if player['name'] == NetworkInterface().get_client_name():
                pcolor.capture(
                    Callback(self.__show_change_player_details_popup))
            pcolor.min_size = pcolor.max_size = (15, 15)

            pstatus = Label(name="pstatus_%s" % player['name'])
            pstatus.text = "\t\t\t" + player['status']
            pstatus.min_size = pstatus.max_size = (120, 15)

            picon = Icon(name="picon_%s" % player['name'])
            picon.image = "content/gui/images/background/hr.png"

            hbox = HBox()
            hbox.addChild(pname)
            hbox.addChild(pcolor)
            hbox.addChild(pstatus)

            if NetworkInterface().get_client_name() == game.get_creator(
            ) and player['name'] != game.get_creator():
                pkick = CancelButton(name="pkick_%s" % player['name'])
                pkick.helptext = _("Kick {player}").format(
                    player=player['name'])
                pkick.capture(Callback(NetworkInterface().kick, player['sid']))
                pkick.up_image = "content/gui/images/buttons/delete_small.png"
                pkick.down_image = "content/gui/images/buttons/delete_small.png"
                pkick.hover_image = "content/gui/images/buttons/delete_small_h.png"
                pkick.min_size = pkick.max_size = (20, 15)
                hbox.addChild(pkick)

            players_vbox.addChild(hbox)
            players_vbox.addChild(picon)
 def _on_ready_button_pressed(self):
     ready_button = self._gui.findChild(name="ready_btn")
     ready_button.toggle()
     ready_label = self._gui.findChild(name="ready_lbl")
     if ready_button.is_active:
         ready_label.text = _("Ready") + ":"
     else:
         ready_label.text = _("Not ready") + ":"
     ready_label.adaptLayout()
     NetworkInterface().toggle_ready()
 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 _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 _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 _add_player_line(player):
            name = player['name']
            pname = Label(name="pname_%s" % name)
            pname.helptext = _("Click here to change your name and/or color")
            pname.text = name
            pname.min_size = pname.max_size = (130, 15)

            if name == NetworkInterface().get_client_name():
                pname.capture(
                    Callback(self._show_change_player_details_popup, game))

            pcolor = Label(name="pcolor_%s" % name, text=u"   ")
            pcolor.helptext = _("Click here to change your name and/or color")
            pcolor.background_color = player['color']
            pcolor.min_size = pcolor.max_size = (15, 15)

            if name == NetworkInterface().get_client_name():
                pcolor.capture(
                    Callback(self._show_change_player_details_popup, game))

            pstatus = Label(name="pstatus_%s" % name)
            pstatus.text = "\t\t\t" + player['status']
            pstatus.min_size = pstatus.max_size = (120, 15)

            picon = HRule(name="picon_%s" % name)

            hbox = HBox()
            hbox.addChildren(pname, pcolor, pstatus)

            if NetworkInterface().get_client_name(
            ) == game.creator and name != game.creator:
                pkick = CancelButton(name="pkick_%s" % name)
                pkick.helptext = _("Kick {player}").format(player=name)
                pkick.capture(Callback(NetworkInterface().kick, player['sid']))
                pkick.path = "images/buttons/delete_small"
                pkick.min_size = pkick.max_size = (20, 15)
                hbox.addChild(pkick)

            players_vbox.addChildren(hbox, picon)
 def _on_player_toggled_ready(self, game, plold, plnew, myself):
     self._update_players_box(NetworkInterface().get_game())
     if myself:
         if plnew.ready:
             self._print_event(_("You are now ready"))
         else:
             self._print_event(_("You are not ready anymore"))
     else:
         if plnew.ready:
             self._print_event(
                 _("{player} is now ready").format(player=plnew.name))
         else:
             self._print_event(
                 _("{player} not ready anymore").format(player=plnew.name))
	def show(self):
		textfield = self._gui.findChild(name="chatTextField")
		textfield.capture(self._send_chat_message)

		self._update_game_details()

		NetworkInterface().subscribe("lobbygame_chat", self._on_chat_message)
		NetworkInterface().subscribe("lobbygame_join", self._on_player_joined)
		NetworkInterface().subscribe("lobbygame_leave", self._on_player_left)
		NetworkInterface().subscribe("lobbygame_kick", self._on_player_kicked)
		NetworkInterface().subscribe("lobbygame_changename", self._on_player_changed_name)
		NetworkInterface().subscribe("lobbygame_changecolor", self._on_player_changed_color)
		NetworkInterface().subscribe("lobbygame_toggleready", self._on_player_toggled_ready)
		NetworkInterface().subscribe("game_details_changed", self._update_game_details)

		self._gui.show()
	def _update_game_details(self):
		"""Set map name and other misc data"""
		game = NetworkInterface().get_game()

		#xgettext:python-format
		self._gui.findChild(name="game_map").text = _("Map: {map_name}").format(map_name=game.map_name)
		#xgettext:python-format
		self._gui.findChild(name="game_name").text = _("Name: {game_name}").format(game_name=game.name)
		#xgettext:python-format
		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)

		self._update_players_box(game)
		self._gui.findChild(name="game_info").adaptLayout()
	def act(self):
		mapindex = self._gui.collectData('maplist')
		mapname = self._maps_display[mapindex]
		maxplayers = self._gui.collectData('playerlimit') + 2 # 1 is the first entry
		gamename = self._gui.collectData('gamename')
		password = self._gui.collectData('password')
		maphash = ""

		password = hashlib.sha1(password).hexdigest() if password != "" else ""
		game = NetworkInterface().creategame(mapname, maxplayers, gamename, maphash, password)
		if game:
			# FIXME When canceling the lobby, I'd like the player to return to the main mp
			# menu, and not see the 'create game' again. We need to close this window, however,
			# this will trigger the display of the main gui, which will part the game in
			# `MultiplayerMenu._check_connection`
			#self._windows.close()
			window = GameLobby(self._windows)
			self._windows.show(window)
    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 __refresh(self, play_sound=False):
        """Refresh list of games.
		Only possible in multiplayer main menu state.
		@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.current.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.current.distributeInitialData({'gamelist': gamelist})
        self.current.distributeData({'gamelist': 0})  # select first map
        self.__update_game_details()
        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 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()
	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 __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()
Beispiel #38
0
def start(command_line_arguments):
	"""Starts the horizons.
	@param command_line_arguments: options object from optparse.OptionParser. see run_uh.py.
	"""
	global fife, db, debug, preloading
	# NOTE: globals are designwise the same thing as singletons. they don't look pretty.
	#       here, we only have globals that are either trivial, or only one instance may ever exist.

	from engine import Fife

	# handle commandline globals
	debug = command_line_arguments.debug

	if command_line_arguments.restore_settings:
		# just delete the file, Settings ctor will create a new one
		os.remove( PATHS.USER_CONFIG_FILE )

	if command_line_arguments.mp_master:
		try:
			mpieces = command_line_arguments.mp_master.partition(':')
			NETWORK.SERVER_ADDRESS = mpieces[0]
			# only change port if port is specified
			if len(mpieces[2]) > 0:
				NETWORK.SERVER_PORT = parse_port(mpieces[2], allow_zero=True)
		except ValueError:
			print _("Error: Invalid syntax in --mp-master commandline option. Port must be a number between 1 and 65535.")
			return False

	# init fife before mp_bind is parsed, since it's needed there
	fife = Fife()

	if command_line_arguments.mp_bind:
		try:
			mpieces = command_line_arguments.mp_bind.partition(':')
			NETWORK.CLIENT_ADDRESS = mpieces[0]
			fife.set_uh_setting("NetworkPort", parse_port(mpieces[2], allow_zero=True))
			print 'asdf', fife.get_uh_setting("NetworkPort2")
		except ValueError:
			print _("Error: Invalid syntax in --mp-bind commandline option. Port must be a number between 1 and 65535.")
			return False

	db = _create_db()

	# init game parts

	_init_gettext(fife)

	client_id = fife.get_uh_setting("ClientID")
	if client_id is None or len(client_id) == 0:
		# We need a new client id
		client_id = "".join("-" if c in (8, 13, 18, 23) else \
		                    random.choice("0123456789abcdef") for c in xrange(0, 36))
		from engine import UH_MODULE
		fife.settings.set(UH_MODULE, "ClientID", client_id)
		fife.settings.saveSettings()

	ExtScheduler.create_instance(fife.pump)
	fife.init()
	_modules.gui = Gui()
	SavegameManager.init()
	try:
		NetworkInterface.create_instance()
	except RuntimeError, e:
		headline = _(u"Failed to initialize networking.")
		descr = _(u"Networking couldn't be initialised with the current configuration.")
		advice = _(u"Check the data you entered in the Network section in the settings dialogue.")
		_modules.gui.show_error_popup(headline, descr, advice, unicode(e))
Beispiel #39
0
def start(command_line_arguments):
	"""Starts the horizons.
	@param command_line_arguments: options object from optparse.OptionParser. see run_uh.py.
	"""
	global fife, db, debug, preloading
	# NOTE: globals are designwise the same thing as singletons. they don't look pretty.
	#       here, we only have globals that are either trivial, or only one instance may ever exist.

	from engine import Fife

	# handle commandline globals
	debug = command_line_arguments.debug

	if command_line_arguments.restore_settings:
		# just delete the file, Settings ctor will create a new one
		os.remove( PATHS.USER_CONFIG_FILE )

	if command_line_arguments.mp_master:
		try:
			mpieces = command_line_arguments.mp_master.partition(':')
			NETWORK.SERVER_ADDRESS = mpieces[0]
			# only change port if port is specified
			if len(mpieces[2]) > 0:
				NETWORK.SERVER_PORT = int(mpieces[2])
				if NETWORK.SERVER_PORT < 1 or NETWORK.SERVER_PORT > 65535:
					raise ValueError
		except ValueError:
			print _("Error: Invalid syntax in --mp-master commandline option. Port must be a number between 0 and 65535.")
			return False

	if command_line_arguments.mp_bind:
		try:
			mpieces = command_line_arguments.mp_bind.partition(':')
			NETWORK.CLIENT_ADDRESS = mpieces[0]
			NETWORK.CLIENT_PORT = int(mpieces[2])
			if NETWORK.CLIENT_PORT < 1 or NETWORK.CLIENT_PORT  > 65535:
				raise ValueError
		except ValueError:
			print _("Error: Invalid syntax in --mp-bind commandline option. Port must be a number between 0 and 65535.")
			return False

	db = _create_db()

	# init game parts
	fife = Fife()

	_init_gettext(fife)

	client_id = fife.get_uh_setting("ClientID")
	if client_id is None or len(client_id) == 0:
		# We need a new client id
		client_id = "".join("-" if c in (8, 13, 18, 23) else \
		                    random.choice("0123456789abcdef") for c in xrange(0, 36))
		from engine import UH_MODULE
		fife.settings.set(UH_MODULE, "ClientID", client_id)
		fife.settings.saveSettings()

	ExtScheduler.create_instance(fife.pump)
	fife.init()
	_modules.gui = Gui()
	SavegameManager.init()
	try:
		NetworkInterface.create_instance()
		NetworkInterface().add_to_extscheduler()
	except RuntimeError, e:
		print "Error during network initialization: %s" % (e)
		return False