def __init__(self, parent, game, game_info, game_settings, dynamic_settings_table, callback_start=None, callback_close=None): Gtk.Dialog.__init__(self, None, parent) self.callback_close = None if callback_close is not None: self.callback_close = callback_close self.game = game self.dynamic_settings_table = dynamic_settings_table preferences_grid_info = get_preferences_grid(game, game_settings, dynamic_settings_table) preferences_grid = preferences_grid_info["widget"] self.widget_option_mapping = preferences_grid_info["mapping"] if callback_start is not None: callback_start(self.game, self.widget_option_mapping, self.dynamic_settings_table) self.set_resizable(False) self.set_border_width(10) self.set_title(i18n._("%(game)s preferences") % {'game': game_info["name"]}) self.get_content_area().pack_start(preferences_grid, True, True, 0) button = self.add_button(i18n._("Save"), Gtk.ResponseType.CLOSE) button.connect("clicked", self.cb_close_button_clicked) self.show_all()
def __init__(self): self.game_table = GameTable(helpers.load_table(GAME_CONFIG_FILE)) try: import pygeoip try: open(GEOIP_DATA_FILE) helpers.debug_msg([ CORE_MSG, i18n. _("GeoIP data file %(geoip_data_file)s opened successfully." ) % { 'geoip_data_file': GEOIP_DATA_FILE } ]) self.geolocation = pygeoip except FileNotFoundError: helpers.debug_msg([ CORE_MSG, i18n._("GeoIP data file not found. Disabling geolocation.") ]) self.geolocation = None except ImportError: helpers.debug_msg([ CORE_MSG, i18n._("PyGeoIP not found. Disabling geolocation.") ]) self.geolocation = None
def get_entry_with_label(label_text="", tooltip_text=""): grid = Gtk.Grid() entry = Gtk.Entry() label = Gtk.Label() widget_object_dict = {"grid": grid, "entry": entry, "label": label} widget_property_dict = { "grid": { "column-homogeneous": True, "column-spacing": 5 }, "entry": { "tooltip-text": i18n._(tooltip_text), "halign": Gtk.Align.FILL, "hexpand-set": True, "hexpand": True }, "label": { "label": i18n._(label_text), "halign": Gtk.Align.END } } gtk_helpers.set_object_properties(widget_object_dict, widget_property_dict) grid.add(entry) widget_group = {"container": grid, "label": label, "substance": entry} return widget_group
def stat_master(game: str, game_info: dict, master_list: list, proxy=None) -> List[Dict[str, Union[str, int, bool]]]: """Stats the master server""" backend_config_object = helpers.load_table(BACKEND_CONFIG) protocol = backend_config_object["protocol"]["version"] server_table = [] for master_uri in master_list: master_page_uri = master_uri.strip('/') + '/?version=' + protocol try: master_page_object = requests.get(master_page_uri) master_page = master_page_object.text except: print(i18n._(RIGSOFRODS_MSG), i18n._("Accessing URI %(uri)s failed with error code %(code)s.") % {'uri': master_page_uri, 'code': "unknown"}) continue try: temp_table = adapt_server_list(game, master_page) except: print(i18n._(RIGSOFRODS_MSG), i18n._("Error parsing URI %(uri)s.") % {'uri': master_page_uri}) continue server_table += temp_table ping.add_rtt_info(server_table) if proxy is not None: for entry in server_table: proxy.append(entry) return server_table
def stat_master(game: str, game_info: dict, master_list: list): """Stats the master server""" server_table = [] backend_config_object = helpers.load_table(BACKEND_CONFIG) protocol = backend_config_object["protocol"]["version"] for master_uri in master_list: master_page_uri = master_uri.strip("/") + "/?version=" + protocol try: master_page_object = requests.get(master_page_uri) master_page = master_page_object.text except: print( i18n._(RIGSOFRODS_MSG), i18n._("Accessing URI %(uri)s failed with error code %(code)s.") % {"uri": master_page_uri, "code": "unknown"}, ) continue try: temp_table = adapt_server_list(game, master_page) except: print(i18n._(RIGSOFRODS_MSG), i18n._("Error parsing URI %(uri)s.") % {"uri": master_page_uri}) continue server_table += temp_table ping.add_rtt_info(server_table) return server_table, None
def on_shutdown(self, app): if self.status == "up": self.settings.save() self.status = "shutting down" helpers.debug_msg([GTK_MSG, i18n._("Shutting down")]) else: self.status = "start failed" helpers.debug_msg([GTK_MSG, i18n._("Initialization failed. Aborting.")])
def on_shutdown(self, app): if self.status == "up": self.settings.save() self.status = "shutting down" helpers.debug_msg([GTK_MSG, i18n._("Shutting down")]) else: self.status = "start failed" helpers.debug_msg( [GTK_MSG, i18n._("Initialization failed. Aborting.")])
def set_query_status(self, game, status): if game in ("", None): raise ValueError(i18n._("Invalid game specified.")) with self.__game_table as game_table: try: game_entry = game_table[game] except KeyError: raise ValueError(i18n._("Game not found: %(game)s") % {"game": game}) game_entry["query-status"] = status
def set_query_status(self, game, status): if game in ('', None): raise ValueError(i18n._('Invalid game specified.')) with self.__game_table as game_table: try: game_entry = game_table[game] except KeyError: raise ValueError( i18n._('Game not found: %(game)s') % {'game': game}) game_entry["query-status"] = status
def get_query_status(self, game: str): if game in ("", None): raise ValueError(i18n._("Invalid game specified.")) with self.__game_table as game_table: try: game_entry = game_table[game] except KeyError: raise ValueError(i18n._("Game not found: %(game)s") % {"game": game}) query_status = helpers.deepcopy(game_entry["query-status"]) return query_status
def adapt_master_entry(qstat_entry, game): master_server_uri = qstat_entry['@address'] master_server_status = qstat_entry['@status'] server_dict = None debug_message = None if master_server_status == 'UP': master_server_entry_count = qstat_entry['@servers'] debug_message = i18n._("Queried Master. Address: %(address)s, status: %(status)s, server count: %(servers)s.") % {'address': master_server_uri, 'status': master_server_status, 'servers': master_server_entry_count} else: debug_message = i18n._("Master query failed. Address: %(address)s, status: %(status)s.") % {'address': master_server_uri, 'status': master_server_status} return {'server_dict': server_dict, 'debug_msg': debug_message}
def get_json(master_page_uri): try: master_page_object = requests.get(master_page_uri) master_page = master_page_object.text except: raise ConnectionError(i18n._(MINETEST_MSG), i18n._("Accessing URI %(uri)s failed with error code %(code)s.") % {'uri': master_page_uri, 'code': "unknown"}) try: server_table = list(json.loads(master_page)["list"]) except ValueError as e: raise ValueError(i18n._(MINETEST_MSG), i18n._("Error parsing URI %(uri)s.: \n %(exception)s") % {'uri': master_page_uri, 'exception': e}) else: return server_table
def get_query_status(self, game: str): if game in ('', None): raise ValueError(i18n._('Invalid game specified.')) with self.__game_table as game_table: try: game_entry = game_table[game] except KeyError: raise ValueError( i18n._('Game not found: %(game)s') % {'game': game}) query_status = helpers.deepcopy(game_entry["query-status"]) return query_status
def get_json(master_page_uri): try: master_page_object = requests.get(master_page_uri) master_page = master_page_object.text except Exception as e: raise ConnectionError(i18n._("Accessing URI %(uri)s failed with error %(msg)s.") % {'uri': master_page_uri, 'msg': e.args[0]}) server_table = []; try: server_table = list(json.loads(master_page)["list"]) except ValueError as e: raise ValueError(i18n._("Error parsing URI %(uri)s.: %(msg)s") % {'uri': master_page_uri, 'msg': e.args[0]}) return server_table
def get_game_info(self, game): """ Returns information about the specified game. """ if game in ("", None): raise ValueError(i18n._("Invalid game specified.")) with self.__game_table as game_table: try: game_entry = game_table[game] except KeyError: raise ValueError(i18n._("Game not found: %(game)s") % {"game": game}) game_info = helpers.deepcopy(game_entry["info"]) return game_info
def on_startup(self, app): """ Startup function. Loads the GtkBuilder resources, settings and start the main loop. """ try: # Load settings helpers.debug_msg([GTK_MSG, i18n._("Obozrenie is starting")]) guiactions = self.guiactions self.status = "starting" guiactions.fill_game_store() self.settings.load( callback_postgenload=self.guiactions.cb_post_settings_genload) # Connect signals self.builder.connect_signals(self.guiactions) guiactions.gtk_widgets["server-list-filter"].set_visible_func( guiactions.server_filter_func) gtk_helpers.set_widget_value( self.guiactions.gtk_widgets["game-combobox"], self.settings.settings_table["common"] ["selected-game-browser"]) for entry in self.guiactions.filter_secure_list: guiactions.gtk_widgets["filter-secure"].append( entry["id"], entry["text"]) guiactions.cb_game_treeview_togglebutton_clicked() guiactions.cb_server_filters_changed() try: guiactions.cb_server_connect_data_changed() except ValueError: pass # Add main window main_window = self.guiactions.gtk_widgets["main-window"] self.add_window(main_window) # Create menu actions about_action = Gio.SimpleAction.new("about", None) quit_action = Gio.SimpleAction.new("quit", None) about_action.connect("activate", self.guiactions.cb_about, main_window) quit_action.connect("activate", self.guiactions.cb_quit, self) self.add_action(about_action) self.add_action(quit_action) self.set_app_menu(self.builder.get_object("app-menu")) gtk_helpers.set_object_properties(self.guiactions.gtk_widgets, GTK_STRING_TABLE) self.status = "up" except Exception as e: app.quit() raise e
def start_game(self, game: str, server: str, password: str) -> None: """Start game""" if game in ('', None): raise ValueError(i18n._('Please specify a valid game id.')) host = ":".join(server.split(":")[0:-1]) port = server.split(":")[-1] game_info = self.game_table.get_game_info(game) game_settings = self.game_table.get_game_settings(game) launch_pattern = game_info["launch_pattern"] steam_app_id = None # type: Union[None, str] try: if game_settings["steam_launch"] is True: try: steam_app_id = game_info["steam_app_id"] launch_pattern = "steam" except KeyError: pass except: pass launch_process = threading.Thread(target=launch.launch_game, args=(game, launch_pattern, game_settings, host, port, password, steam_app_id)) launch_process.daemon = True launch_process.start()
def get_game_info(self, game): """ Returns information about the specified game. """ if game in ('', None): raise ValueError(i18n._('Invalid game specified.')) with self.__game_table as game_table: try: game_entry = game_table[game] except KeyError: raise ValueError( i18n._('Game not found: %(game)s') % {'game': game}) game_info = helpers.deepcopy(game_entry["info"]) return game_info
def clear_servers_data(self, game: str) -> None: if game in ("", None): raise ValueError(i18n._("Please specify a valid game id.")) with self.__game_table as game_table: with game_table[game]["servers"] as server_list: server_list.clear()
def cb_info_button_clicked(self, *args): """Shows server information window.""" dialog = self.gtk_widgets["serverinfo-dialog"] game_table = self.core.game_table.get_game_table_copy() game = self.app.settings.settings_table["common"]["selected-game-connect"] server_list_table = game_table[game]["servers"] host = self.app.settings.settings_table["common"]["server-host"] server_entry_index = helpers.search_dict_table(server_list_table, "host", host) if server_entry_index is not None: server_entry = server_list_table[server_entry_index] player_model = self.gtk_widgets["player-list-model"] player_scrolledview = self.gtk_widgets["serverinfo-players-scrolledview"] gtk_helpers.set_widget_value(self.gtk_widgets["serverinfo-name"], server_entry["name"]) gtk_helpers.set_widget_value(self.gtk_widgets["serverinfo-host"], server_entry["host"]) gtk_helpers.set_widget_value(self.gtk_widgets["serverinfo-game"], game_table[server_entry["game_id"]]["info"]["name"]) gtk_helpers.set_widget_value(self.gtk_widgets['serverinfo-gameid'], server_entry['game_id']) gtk_helpers.set_widget_value(self.gtk_widgets["serverinfo-terrain"], server_entry["terrain"]) gtk_helpers.set_widget_value(self.gtk_widgets["serverinfo-players"], i18n._("%(player_count)s / %(player_limit)s") % {'player_count': str(server_entry["player_count"]), 'player_limit': str(server_entry["player_limit"])}) gtk_helpers.set_widget_value(self.gtk_widgets["serverinfo-ping"], server_entry["ping"]) player_model.clear() try: player_table = helpers.dict_to_list(server_entry["players"], self.player_list_model_format) for entry in player_table: player_model.append(entry) player_scrolledview.set_property("visible", True) except: player_scrolledview.set_property("visible", False) dialog.run() dialog.hide()
def get_checkbutton(label_text="", tooltip_text=""): checkbutton = Gtk.CheckButton.new() widget_object_dict = {"checkbutton": checkbutton} widget_property_dict = { "checkbutton": { "label": i18n._(label_text), "tooltip-text": i18n._(tooltip_text) } } gtk_helpers.set_object_properties(widget_object_dict, widget_property_dict) widget_group = {"container": checkbutton, "substance": checkbutton} return widget_group
def get_servers_data(self, game: str) -> dict: if game in ("", None): raise ValueError(i18n._("Please specify a valid game id.")) with self.__game_table as game_table: servers_data = helpers.deepcopy(game_table[game]["servers"]) return servers_data
def set_game_setting(self, game, option, value): faulty_param = None if game in ("", None): faulty_param = i18n._("game id") elif option in ("", None): faulty_param = i18n._("option") if faulty_param is not None: raise ValueError(i18n._("Invalid %(param)s specified.") % {"param": param}) with self.__game_table as game_table: try: game_entry = game_table[game] except KeyError: raise ValueError(i18n._("Game not found: %(game)s") % {"game": game}) game_entry["settings"][option] = value
def start_game(self, game: str, server: str, password: str) -> None: """Start game""" if game in ("", None): raise ValueError(i18n._("Please specify a valid game id.")) host = ":".join(server.split(":")[0:-1]) port = server.split(":")[-1] game_info = self.game_table.get_game_info(game) game_settings = self.game_table.get_game_settings(game) launch_pattern = game_info["launch_pattern"] steam_app_id = None # type: Union[None, str] try: if game_settings["steam_launch"] is True: try: steam_app_id = game_info["steam_app_id"] launch_pattern = "steam" except KeyError: pass except: pass launch_process = threading.Thread( target=launch.launch_game, args=(game, launch_pattern, game_settings, host, port, password, steam_app_id) ) launch_process.daemon = True launch_process.start()
def clear_servers_data(self, game: str) -> None: if game in ('', None): raise ValueError(i18n._('Please specify a valid game id.')) with self.__game_table as game_table: with game_table[game]["servers"] as server_list: server_list.clear()
def get_servers_data(self, game: str) -> dict: if game in ('', None): raise ValueError(i18n._('Please specify a valid game id.')) with self.__game_table as game_table: servers_data = helpers.deepcopy(game_table[game]["servers"]) return servers_data
def stat_master_target(self, game: str, callback=None) -> None: """Separate update thread. Strictly per-game.""" game_info = self.game_table.get_game_info(game) game_settings = self.game_table.get_game_settings(game) game_name = game_info["name"] master_list = list(game_settings["master_uri"]) adapter = game_info["adapter"] # Start query if it's not up already if self.game_table.get_query_status(game) != self.game_table.QUERY_STATUS.WORKING: self.game_table.set_query_status(game, self.game_table.QUERY_STATUS.WORKING) helpers.debug_msg([CORE_MSG, i18n._("Refreshing server list for %(game)s.") % {"game": game_name}]) stat_master_cmd = adapters.adapter_table[adapter].stat_master temp_list = None try: temp_list = stat_master_cmd(game, game_info, master_list) except Exception as e: helpers.debug_msg([CORE_MSG, e]) helpers.debug_msg( [CORE_MSG, i18n._("Internal backend error for %(game)s.") % {"game": game_name}, ERROR_MSG] ) self.game_table.set_query_status(game, self.game_table.QUERY_STATUS.ERROR) else: self.game_table.set_servers_data(game, temp_list) for entry in temp_list: entry["country"] = "unknown" if self.geolocation is not None: host = entry["host"].split(":")[0] try: entry["country"] = self.geolocation.GeoIP(GEOIP_DATA_FILE).country_code_by_addr(host) except OSError: try: entry["country"] = self.geolocation.GeoIP(GEOIP_DATA_FILE).country_code_by_name(host) except: entry["country"] = "" except: pass self.game_table.set_servers_data(game, temp_list) self.game_table.set_query_status(game, self.game_table.QUERY_STATUS.READY) # Call post-stat callback if callback is not None: callback(game)
def set_servers_data(self, game: str, servers_data) -> None: if game in ('', None): raise ValueError(i18n._('Please specify a valid game id.')) with self.__game_table as game_table: self.clear_servers_data(game) for entry in servers_data: game_table[game]["servers"].append(entry)
def set_servers_data(self, game: str, servers_data) -> None: if game in ("", None): raise ValueError(i18n._("Please specify a valid game id.")) with self.__game_table as game_table: self.clear_servers_data(game) for entry in servers_data: game_table[game]["servers"].append(entry)
def set_server_info(self, game: str, host: str, data) -> None: faulty_param = None if game in ("", None): faulty_param = i18n._("game id") elif host in ("", None): faulty_param = i18n._("hostname") elif isinstance(data, dict) is False: faulty_param = i18n._("server data") if faulty_param is not None: raise ValueError(i18n._("Invalid %(param)s specified.") % {"param": param}) with self.__game_table as game_table: server_entry_index = game_table[helpers.search_dict_table(helpers.deepcopy(game_table), "host", host)] if server_entry_index is None: self.append_server_info(game, data) else: game_table[server_entry_index] = data
def adapt_master_entry(qstat_entry, game): master_server_uri = qstat_entry["@address"] master_server_status = qstat_entry["@status"] server_dict = None debug_message = None if master_server_status == "UP": master_server_entry_count = qstat_entry["@servers"] debug_message = i18n._( "Queried Master. Address: %(address)s, status: %(status)s, server count: %(servers)s." ) % {"address": master_server_uri, "status": master_server_status, "servers": master_server_entry_count} else: debug_message = i18n._("Master query failed. Address: %(address)s, status: %(status)s.") % { "address": master_server_uri, "status": master_server_status, } return {"server_dict": server_dict, "debug_msg": debug_message}
def get_entry_with_label(label_text="", tooltip_text=""): grid = Gtk.Grid() entry = Gtk.Entry() label = Gtk.Label() widget_object_dict = {"grid": grid, "entry": entry, "label": label} widget_property_dict = {"grid": {"column-homogeneous": True, "column-spacing": 5}, "entry": {"tooltip-text": i18n._(tooltip_text), "halign": Gtk.Align.FILL, "hexpand-set": True, "hexpand": True}, "label": {"label": i18n._(label_text), "halign": Gtk.Align.END}} gtk_helpers.set_object_properties(widget_object_dict, widget_property_dict) grid.add(entry) widget_group = {"container": grid, "label": label, "substance": entry} return widget_group
def get_server_info(self, game: str, host: str) -> dict: faulty_param = None if game in ("", None): faulty_param = i18n._("game id") elif host in ("", None): faulty_param = i18n._("hostname") if faulty_param is not None: raise ValueError(i18n._("Invalid %(param)s specified.") % {"param": param}) with self.__game_table as game_table: try: game_entry = game_table[game] except KeyError: raise ValueError(i18n._("Game not found: %(game)s") % {"game": game}) server_table = helpers.deepcopy(game_entry["servers"]) server_entry = server_table[helpers.search_dict_table(server_table, "host", host)] return server_entry
def get_textview_with_label(label_text="", tooltip_text="Single entry per line", placeholder_text=""): grid = Gtk.Grid() text_view = Gtk.TextView() text_buffer = text_view.get_buffer() label = Gtk.Label() widget_object_dict = {"grid": grid, "text_view": text_view, "label": label} widget_property_dict = {"grid": {"column-homogeneous": True, "column-spacing": 5}, "text_view": {"tooltip-text": i18n._(tooltip_text), "halign": Gtk.Align.FILL, "hexpand-set": True, "hexpand": True, "left-margin": 8, "right-margin": 8}, "label": {"label": i18n._(label_text), "halign": Gtk.Align.END, "valign": Gtk.Align.START}} gtk_helpers.set_object_properties(widget_object_dict, widget_property_dict) grid.add(text_view) widget_group = {"container": grid, "label": label, "substance": text_buffer} return widget_group
def set_game_setting(self, game, option, value): faulty_param = None if game in ('', None): faulty_param = i18n._('game id') elif option in ('', None): faulty_param = i18n._('option') if faulty_param is not None: raise ValueError( i18n._('Invalid %(param)s specified.') % {'param': param}) with self.__game_table as game_table: try: game_entry = game_table[game] except KeyError: raise ValueError( i18n._('Game not found: %(game)s') % {'game': game}) game_entry["settings"][option] = value
def set_server_info(self, game: str, host: str, data) -> None: faulty_param = None if game in ('', None): faulty_param = i18n._('game id') elif host in ('', None): faulty_param = i18n._('hostname') elif isinstance(data, dict) is False: faulty_param = i18n._('server data') if faulty_param is not None: raise ValueError( i18n._('Invalid %(param)s specified.') % {'param': param}) with self.__game_table as game_table: server_entry_index = game_table[helpers.search_dict_table( helpers.deepcopy(game_table), "host", host)] if server_entry_index is None: self.append_server_info(game, data) else: game_table[server_entry_index] = data
def unit_parse_master_entry(cls): """Check QStat output parsing - masters""" xml_string = '<server type="Q2M" address="localhost:12345" status="UP" servers="44"></server>' func = cls.module.adapt_qstat_entry spec_args = {"qstat_entry": xmltodict.parse(xml_string)['server'], "game": "q2", "master_type": "Q2M", "server_type": "Q2S"} spec_result = {'server_dict': None, 'debug_msg': i18n._('Queried Master. Address: localhost:12345, status: UP, server count: 44.')} result = func(**spec_args) return {'expectation': spec_result, 'result': result}
def get_checkbutton(label_text="", tooltip_text=""): checkbutton = Gtk.CheckButton.new() widget_object_dict = {"checkbutton": checkbutton} widget_property_dict = {"checkbutton": {"label": i18n._(label_text), "tooltip-text": i18n._(tooltip_text)}} gtk_helpers.set_object_properties(widget_object_dict, widget_property_dict) widget_group = {"container": checkbutton, "substance": checkbutton} return widget_group
def get_server_info(self, game: str, host: str) -> dict: faulty_param = None if game in ('', None): faulty_param = i18n._('game id') elif host in ('', None): faulty_param = i18n._('hostname') if faulty_param is not None: raise ValueError( i18n._('Invalid %(param)s specified.') % {'param': param}) with self.__game_table as game_table: try: game_entry = game_table[game] except KeyError: raise ValueError( i18n._('Game not found: %(game)s') % {'game': game}) server_table = helpers.deepcopy(game_entry["servers"]) server_entry = server_table[helpers.search_dict_table( server_table, "host", host)] return server_entry
def get_textview_with_label(label_text="", tooltip_text="Single entry per line", placeholder_text=""): grid = Gtk.Grid() text_view = Gtk.TextView() text_buffer = text_view.get_buffer() label = Gtk.Label() widget_object_dict = {"grid": grid, "text_view": text_view, "label": label} widget_property_dict = { "grid": { "column-homogeneous": True, "column-spacing": 5 }, "text_view": { "tooltip-text": i18n._(tooltip_text), "halign": Gtk.Align.FILL, "hexpand-set": True, "hexpand": True, "left-margin": 8, "right-margin": 8 }, "label": { "label": i18n._(label_text), "halign": Gtk.Align.END, "valign": Gtk.Align.START } } gtk_helpers.set_object_properties(widget_object_dict, widget_property_dict) grid.add(text_view) widget_group = { "container": grid, "label": label, "substance": text_buffer } return widget_group
def on_startup(self, app): """ Startup function. Loads the GtkBuilder resources, settings and start the main loop. """ try: # Load settings helpers.debug_msg([GTK_MSG, i18n._("Obozrenie is starting")]) guiactions = self.guiactions self.status = "starting" guiactions.fill_game_store() self.settings.load(callback_postgenload=self.guiactions.cb_post_settings_genload) # Connect signals self.builder.connect_signals(self.guiactions) guiactions.gtk_widgets["server-list-filter"].set_visible_func(guiactions.server_filter_func) gtk_helpers.set_widget_value(self.guiactions.gtk_widgets["game-combobox"], self.settings.settings_table["common"]["selected-game-browser"]) for entry in self.guiactions.filter_secure_list: guiactions.gtk_widgets["filter-secure"].append(entry["id"], entry["text"]) guiactions.cb_game_treeview_togglebutton_clicked() guiactions.cb_server_filters_changed() try: guiactions.cb_server_connect_data_changed() except ValueError: pass # Add main window main_window = self.guiactions.gtk_widgets["main-window"] self.add_window(main_window) # Create menu actions about_action = Gio.SimpleAction.new("about", None) quit_action = Gio.SimpleAction.new("quit", None) about_action.connect("activate", self.guiactions.cb_about, main_window) quit_action.connect("activate", self.guiactions.cb_quit, self) self.add_action(about_action) self.add_action(quit_action) self.set_app_menu(self.builder.get_object("app-menu")) gtk_helpers.set_object_properties(self.guiactions.gtk_widgets, GTK_STRING_TABLE) self.status = "up" except Exception as e: app.quit() raise e
def get_json(master_page_uri): try: master_page_object = requests.get(master_page_uri) master_page = master_page_object.text except Exception as e: raise ConnectionError( i18n._("Accessing URI %(uri)s failed with error %(msg)s.") % { 'uri': master_page_uri, 'msg': e.args[0] }) server_table = [] try: server_table = list(json.loads(master_page)["list"]) except ValueError as e: raise ValueError( i18n._("Error parsing URI %(uri)s.: %(msg)s") % { 'uri': master_page_uri, 'msg': e.args[0] }) return server_table
def __init__(self): self.game_table = GameTable(helpers.load_table(GAME_CONFIG_FILE)) try: import pygeoip try: open(GEOIP_DATA_FILE) helpers.debug_msg( [ CORE_MSG, i18n._("GeoIP data file %(geoip_data_file)s opened successfully.") % {"geoip_data_file": GEOIP_DATA_FILE}, ] ) self.geolocation = pygeoip except FileNotFoundError: helpers.debug_msg([CORE_MSG, i18n._("GeoIP data file not found. Disabling geolocation.")]) self.geolocation = None except ImportError: helpers.debug_msg([CORE_MSG, i18n._("PyGeoIP not found. Disabling geolocation.")]) self.geolocation = None
def __init__(self, parent, game, game_info, game_settings, dynamic_settings_table, callback_start=None, callback_close=None): Gtk.Dialog.__init__(self, None, parent) self.callback_close = None if callback_close is not None: self.callback_close = callback_close self.game = game self.dynamic_settings_table = dynamic_settings_table preferences_grid_info = get_preferences_grid(game, game_settings, dynamic_settings_table) preferences_grid = preferences_grid_info["widget"] self.widget_option_mapping = preferences_grid_info["mapping"] if callback_start is not None: callback_start(self.game, self.widget_option_mapping, self.dynamic_settings_table) self.set_resizable(False) self.set_border_width(10) self.set_title( i18n._("%(game)s preferences") % {'game': game_info["name"]}) self.get_content_area().pack_start(preferences_grid, True, True, 0) button = self.add_button(i18n._("Save"), Gtk.ResponseType.CLOSE) button.connect("clicked", self.cb_close_button_clicked) self.show_all()
def stat_master(game: str, game_info: dict, master_list: list): """Stats the master server""" server_table = [] backend_config_object = helpers.load_table(BACKEND_CONFIG) protocol = backend_config_object["protocol"]["version"] for master_uri in master_list: master_page_uri = master_uri.strip('/') + '/?version=' + protocol try: master_page_object = requests.get(master_page_uri) master_page = master_page_object.text except: print( i18n._(RIGSOFRODS_MSG), i18n._( "Accessing URI %(uri)s failed with error code %(code)s.") % { 'uri': master_page_uri, 'code': "unknown" }) continue try: temp_table = adapt_server_list(game, master_page) except: print( i18n._(RIGSOFRODS_MSG), i18n._("Error parsing URI %(uri)s.") % {'uri': master_page_uri}) continue server_table += temp_table ping.add_rtt_info(server_table) return server_table, None
def adapt_master_entry(qstat_entry, game): master_server_uri = qstat_entry['@address'] master_server_status = qstat_entry['@status'] server_dict = None debug_message = None if master_server_status == 'UP': master_server_entry_count = qstat_entry['@servers'] debug_message = i18n._( "Queried Master. Address: %(address)s, status: %(status)s, server count: %(servers)s." ) % { 'address': master_server_uri, 'status': master_server_status, 'servers': master_server_entry_count } else: debug_message = i18n._( "Master query failed. Address: %(address)s, status: %(status)s." ) % { 'address': master_server_uri, 'status': master_server_status } return {'server_dict': server_dict, 'debug_msg': debug_message}
def cb_info_button_clicked(self, *args): """Shows server information window.""" dialog = self.gtk_widgets["serverinfo-dialog"] game_table = self.core.game_table.get_game_table_copy() game = self.app.settings.settings_table["common"][ "selected-game-connect"] server_list_table = game_table[game]["servers"] host = self.app.settings.settings_table["common"]["server-host"] server_entry_index = helpers.search_dict_table(server_list_table, "host", host) if server_entry_index is not None: server_entry = server_list_table[server_entry_index] player_model = self.gtk_widgets["player-list-model"] player_scrolledview = self.gtk_widgets[ "serverinfo-players-scrolledview"] gtk_helpers.set_widget_value(self.gtk_widgets["serverinfo-name"], server_entry["name"]) gtk_helpers.set_widget_value(self.gtk_widgets["serverinfo-host"], server_entry["host"]) gtk_helpers.set_widget_value( self.gtk_widgets["serverinfo-game"], game_table[server_entry["game_id"]]["info"]["name"]) gtk_helpers.set_widget_value(self.gtk_widgets['serverinfo-gameid'], server_entry['game_id']) gtk_helpers.set_widget_value( self.gtk_widgets["serverinfo-terrain"], server_entry["terrain"]) gtk_helpers.set_widget_value( self.gtk_widgets["serverinfo-players"], i18n._("%(player_count)s / %(player_limit)s") % { 'player_count': str(server_entry["player_count"]), 'player_limit': str(server_entry["player_limit"]) }) gtk_helpers.set_widget_value(self.gtk_widgets["serverinfo-ping"], server_entry["ping"]) player_model.clear() try: player_table = helpers.dict_to_list( server_entry["players"], self.player_list_model_format) for entry in player_table: player_model.append(entry) player_scrolledview.set_property("visible", True) except: player_scrolledview.set_property("visible", False) dialog.run() dialog.hide()
def get_option_widget(option_dict): name = option_dict["name"] description = option_dict["description"] widget_type = option_dict["gtk_type"] if widget_type == "CheckButton": widget = get_checkbutton(label_text=name, tooltip_text=description) elif widget_type == "Entry with Label": widget = get_entry_with_label(label_text=name+":", tooltip_text=description) elif widget_type == "Multiline Entry with Label": widget = get_textview_with_label(label_text=name+":", tooltip_text=description) else: print(i18n._("No widget generated for type %(widget_type)s") % {'widget_type': widget_type}) widget = None return widget
def get_option_widget(option_dict): name = option_dict["name"] description = option_dict["description"] widget_type = option_dict["gtk_type"] if widget_type == "CheckButton": widget = get_checkbutton(label_text=name, tooltip_text=description) elif widget_type == "Entry with Label": widget = get_entry_with_label(label_text=name + ":", tooltip_text=description) elif widget_type == "Multiline Entry with Label": widget = get_textview_with_label(label_text=name + ":", tooltip_text=description) else: print( i18n._("No widget generated for type %(widget_type)s") % {'widget_type': widget_type}) widget = None return widget
def adapt_server_list( qstat_string, game, game_name, qstat_master_type, qstat_server_type, server_game_name, server_game_type ): server_table = [] server_table_dict = json.loads(json.dumps(xmltodict.parse(qstat_string))) server_table_dict["qstat"]["server"] = helpers.enforce_array( server_table_dict["qstat"]["server"] ) # Enforce server array even if n=1 for qstat_entry in server_table_dict["qstat"]["server"]: # For every server... try: if server_table_dict["qstat"]["server"]["@type"] == qstat_master_type: debug_msg(game_name, i18n._("No valid masters specified. Please check your master server settings.")) break except TypeError: try: response = adapt_qstat_entry(qstat_entry, game, qstat_master_type, qstat_server_type) server_dict = response["server_dict"] msg = response["debug_msg"] debug_msg(game_name, msg) if server_dict is not None: appendable = True for filter_rule in ((server_game_name, "game_name"), (server_game_type, "game_type")): if filter_rule[0] is not None: if filter_rule[1] not in server_dict.keys(): appendable = False break else: if server_dict[filter_rule[1]] != filter_rule[0]: appendable = False break if appendable: server_table.append(server_dict) except Exception as e: debug_msg(game_name, str(e.args[0])) return server_table
def __repr__(self): return i18n._("<Game Table - games: %(game_num)i, id: %(gt_id)i>") % { "game_num": len(self.__game_table), "gt_id": id(self), }
def stat_master_target(self, game: str, callback=None) -> None: """Separate update thread. Strictly per-game.""" game_info = self.game_table.get_game_info(game) game_settings = self.game_table.get_game_settings(game) game_name = game_info["name"] master_list = list(game_settings["master_uri"]) adapter = game_info["adapter"] # Start query if it's not up already if self.game_table.get_query_status( game) != self.game_table.QUERY_STATUS.WORKING: self.game_table.set_query_status( game, self.game_table.QUERY_STATUS.WORKING) helpers.debug_msg([ CORE_MSG, i18n._("Refreshing server list for %(game)s.") % { 'game': game_name } ]) stat_master_cmd = adapters.adapter_table[adapter].stat_master temp_list = None try: temp_list = stat_master_cmd(game, game_info, master_list) except Exception as e: helpers.debug_msg([CORE_MSG, e]) helpers.debug_msg([ CORE_MSG, i18n._("Internal backend error for %(game)s.") % { 'game': game_name } ]) self.game_table.set_query_status( game, self.game_table.QUERY_STATUS.ERROR) else: self.game_table.set_servers_data(game, temp_list) for entry in temp_list: entry['country'] = "unknown" if self.geolocation is not None: host = entry["host"].split(':')[0] try: entry['country'] = self.geolocation.GeoIP( GEOIP_DATA_FILE).country_code_by_addr(host) except OSError: try: entry['country'] = self.geolocation.GeoIP( GEOIP_DATA_FILE).country_code_by_name(host) except: entry['country'] = "" except: pass self.game_table.set_servers_data(game, temp_list) self.game_table.set_query_status( game, self.game_table.QUERY_STATUS.READY) # Call post-stat callback if callback is not None: callback(game)
def __init__(self, app, builder, core_library): self.app = app self.builder = builder self.core = core_library self.gtk_widgets = {} self.gtk_widgets = gtk_helpers.get_object_dict( self.builder, { "game-list-store": "game-list-model", "server-list-filter": "server-list-filter", "server-list-sort": "server-list-sort", "server-list-store": "server-list-model", "player-list-store": "player-list-model", "Main_Window": "main-window", "Game_ComboBox": "game-combobox", "Game_TreeView": "game-treeview", "Game_TreeView_Column": "game-treeview-column", "Game_ComboBox_Revealer": "game-combobox-revealer", "Game_View_Revealer": "game-view-revealer", "Game_View_ToggleButton": "game-view-togglebutton", "Game_Preferences_Button": "game-preferences-button", "Update_Button": "action-update-button", "Info_Button": "action-info-button", "Connect_Button": "action-connect-button", "filters-revealer": "filters-revealer", "filters-button": "filters-button", "filter-mod-label": "filter-mod-label", "filter-type-label": "filter-type-label", "filter-terrain-label": "filter-terrain-label", "filter-ping-label": "filter-ping-label", "filter-secure-label": "filter-secure-label", "filter-mod-entry": "filter-mod", "filter-type-entry": "filter-type", "filter-terrain-entry": "filter-terrain", "filter-ping-adjustment": "filter-ping", "filter-secure-comboboxtext": "filter-secure", "filter-notfull-checkbutton": "filter-notfull", "filter-notempty-checkbutton": "filter-notempty", "filter-nopassword-checkbutton": "filter-nopassword", "ServerList_View": "serverlist-view", "Name_ServerList_TreeViewColumn": "serverlist-view-name-column", "Host_ServerList_TreeViewColumn": "serverlist-view-host-column", "Ping_ServerList_TreeViewColumn": "serverlist-view-ping-column", "Players_ServerList_TreeViewColumn": "serverlist-view-players-column", "GameMod_ServerList_TreeViewColumn": "serverlist-view-game_mod-column", "GameType_ServerList_TreeViewColumn": "serverlist-view-game_type-column", "Terrain_ServerList_TreeViewColumn": "serverlist-view-terrain-column", "ServerList_Notebook": "serverlist-notebook", "ServerList_ScrolledWindow": "serverlist-scrolledwindow", "ServerList_Welcome_Label": "serverlist-welcome-label", "ServerList_Refresh_Spinner": "serverlist-refresh-spinner", "Error_Grid": "error-grid", "Error_Message_Label": "error-message-label", "server-connect-game": "server-connect-game", "server-connect-host": "server-connect-host", "server-connect-pass": "******", "serverinfo-dialog": "serverinfo-dialog", "serverinfo-name-label": "serverinfo-name-label", "serverinfo-name-data": "serverinfo-name", "serverinfo-host-label": "serverinfo-host-label", "serverinfo-host-data": "serverinfo-host", "serverinfo-game-label": "serverinfo-game-label", "serverinfo-game-data": "serverinfo-game", "serverinfo-gameid-label": "serverinfo-gameid-label", "serverinfo-gameid-data": "serverinfo-gameid", "serverinfo-terrain-label": "serverinfo-terrain-label", "serverinfo-terrain-data": "serverinfo-terrain", "serverinfo-players-label": "serverinfo-players-label", "serverinfo-players-data": "serverinfo-players", "serverinfo-ping-label": "serverinfo-ping-label", "serverinfo-ping-data": "serverinfo-ping", "serverinfo-connect-button": "serverinfo-connect-button", "serverinfo-close-button": "serverinfo-close-button", "serverinfo-players-scrolledview": "serverinfo-players-scrolledview", "serverinfo-players-treeview": "serverinfo-players-view", "serverinfo-players-name-treeviewcolumn": "serverinfo-players-name-column", "serverinfo-players-score-treeviewcolumn": "serverinfo-players-score-column", "serverinfo-players-ping-treeviewcolumn": "serverinfo-players-ping-column" }) self.game_list_model_format = ("game_id", "name", "game_icon", "status_icon") self.server_list_model_format = ("host", "password", "player_count", "player_limit", "ping", "secure", "country", "name", "game_id", "game_mod", "game_type", "terrain", "game_icon", "password_icon", "secure_icon", "country_icon", "full", "empty") self.player_list_model_format = ("name", "score", "ping") self.filter_secure_list = ({ "id": "None", "text": i18n._("(all)") }, { "id": "True", "text": i18n._("True") }, { "id": "False", "text": i18n._("False") }) self.filter_criteria = [{ "column": "game_mod", "type": "in", "widget": "filter-mod" }, { "column": "game_type", "type": "in", "widget": "filter-type" }, { "column": "terrain", "type": "in", "widget": "filter-terrain" }, { "column": "ping", "type": "<=", "widget": "filter-ping" }, { "column": "secure", "type": "bool is ast bool", "widget": "filter-secure" }, { "column": "full", "type": "not true if true", "widget": "filter-notfull" }, { "column": "empty", "type": "not true if true", "widget": "filter-notempty" }, { "column": "password", "type": "not true if true", "widget": "filter-nopassword" }] self.serverlist_notebook_pages = gtk_helpers.get_notebook_page_dict( self.gtk_widgets["serverlist-notebook"], { "servers": self.gtk_widgets["serverlist-scrolledwindow"], "welcome": self.gtk_widgets["serverlist-welcome-label"], "loading": self.gtk_widgets["serverlist-refresh-spinner"], "error": self.gtk_widgets["error-grid"] }) self.gtk_widgets["serverlist-notebook"].set_property( "page", self.serverlist_notebook_pages["welcome"]) # Load flags try: country_db = self.core.geolocation.const.COUNTRY_CODES self.flag_icons = gtk_helpers.get_icon_dict( country_db, 'flag', ['svg'], ICON_FLAGS_DIR, 24, 18) except TypeError and AttributeError: self.flag_icons = {} game_list = self.core.game_table.get_game_set() self.game_icons = gtk_helpers.get_icon_dict(game_list, 'game', ['png', 'svg'], ICON_GAMES_DIR, 24, 24) try: self.logo = GdkPixbuf.Pixbuf.new_from_file(ICON_PATH) except (NameError, GLib.GError): pass
def __repr__(self): return i18n._("<Game Table - games: %(game_num)i, id: %(gt_id)i>") % { 'game_num': len(self.__game_table), 'gt_id': id(self) }
def get_game_options(): option_list = { 'path': { 'name': i18n._("Game path"), 'description': i18n._("Path to the game."), 'gtk_type': "Entry with Label" }, 'workdir': { 'name': i18n._("Working directory"), 'description': i18n._("Working directory of the game."), 'gtk_type': "Entry with Label" }, 'master_uri': { 'name': i18n._("Master URI list"), 'description': i18n._("List of master servers to query."), 'gtk_type': "Multiline Entry with Label" }, 'steam_launch': { 'name': i18n._("Launch via Steam"), 'description': i18n. _("Enables launching via Steam client. Required for VAC-enabled servers." ), 'gtk_type': "CheckButton" }, 'steam_path': { 'name': i18n._("Steam path"), 'description': i18n._("Steam client path."), 'gtk_type': "Entry with Label" }, 'nickname': { 'name': i18n._("Nickname"), 'description': i18n._("Your nickname."), 'gtk_type': "Entry with Label" } } return option_list
import os import re import json import subprocess import time import xmltodict from obozrenie.global_settings import * from obozrenie.global_strings import * import obozrenie.i18n as i18n import obozrenie.helpers as helpers BACKEND_CONFIG = os.path.join(SETTINGS_INTERNAL_BACKENDS_DIR, "qstat.toml") QSTAT_MSG = BACKENDCAT_MSG + i18n._("QStat") def debug_msg(game_name, msg=None): if msg is not None: helpers.debug_msg([QSTAT_MSG, game_name, msg]) def adapt_master_entry(qstat_entry, game): master_server_uri = qstat_entry['@address'] master_server_status = qstat_entry['@status'] server_dict = None debug_message = None if master_server_status == 'UP': master_server_entry_count = qstat_entry['@servers'] debug_message = i18n._(
def stat_master(game: str, game_info: dict, master_list: list): hosts_array = [] qstat_stdin_object = "" master_server_uri = None stat_start_time = None stat_end_time = None game_name = game_info["name"] backend_config_object = helpers.load_table(BACKEND_CONFIG) qstat_master_type = backend_config_object['game'][game]['master_type'] qstat_server_type = backend_config_object['game'][game]['server_type'] if "server_gamename" not in backend_config_object['game'][game].keys(): backend_config_object['game'][game]['server_gamename'] = None server_game_name = backend_config_object['game'][game]['server_gamename'] if "server_gamename" in backend_config_object['game'][game].keys(): server_game_name = backend_config_object['game'][game][ 'server_gamename'] server_game_type = None if "server_gametype" in backend_config_object['game'][game].keys(): server_game_type = backend_config_object['game'][game][ 'server_gametype'] for entry in master_list: entry = entry.strip() if '://' in entry: entry_protocol, entry_host = entry.split('://') else: entry_protocol = 'master' entry_host = entry hosts_array.append(entry_host) hosts_array = list(set(hosts_array)) qstat_cmd = [ "qstat", "-xml", "-utf8", "-maxsim", "9999", "-sendinterval", "1", "-R", "-P", "-f", "-" ] qstat_stdin_descriptor = backend_config_object['game'][game]['master_type'] if server_game_type is not None: qstat_stdin_descriptor = qstat_stdin_descriptor + ",game=" + server_game_type for entry in hosts_array: qstat_stdin_object = qstat_stdin_object + qstat_stdin_descriptor + " " + entry + "\n" debug_msg(game_name, i18n._("Requesting server info.")) stat_start_time = time.time() try: qstat_output_raw, _ = subprocess.Popen( qstat_cmd, stdin=subprocess.PIPE, stdout=subprocess.PIPE).communicate( input=qstat_stdin_object.strip().encode()) qstat_output = qstat_output_raw.decode() except Exception as e: raise Exception( helpers.debug_msg_str([QSTAT_MSG, game_name, e.args[0]])) stat_end_time = time.time() stat_total_time = stat_end_time - stat_start_time debug_msg( game_name, i18n._("Received server info. Elapsed time: %(stat_time)s s.") % {'stat_time': round(stat_total_time, 2)}) parse_start_time = time.time() server_table = adapt_server_list(qstat_output, game, game_name, qstat_master_type, qstat_server_type, server_game_name, server_game_type) parse_end_time = time.time() debug_msg( game_name, i18n._("Parsed QStat response. Elapsed time: %(parse_time)s ms") % {'parse_time': round((parse_end_time - parse_start_time) * 1000, 2)}) return server_table
for option in self.core.game_table.get_game_settings(game): value = default_game_settings_table[game][option] try: value = user_game_settings_table[game][option] except (ValueError, KeyError, TypeError): pass self.core.game_table.set_game_setting(game, option, value) def save(self) -> None: """Saves configuration.""" # Save common settings table helpers.save_table(self.user_common_settings_path, self.settings_table) # Compile game settings table user_game_settings_table = {} for game in self.core.game_table.get_game_set(): user_game_settings_table[game] = self.core.game_table.get_game_settings(game) # Save game settings helpers.save_table(self.user_game_settings_path, user_game_settings_table) if __name__ == "__main__": helpers.debug_msg( [ CORE_MSG, i18n._("This is the core module of Obozrenie Game Server Browser. Please run an appropriate UI instead."), ] )
import os import json import requests import xmltodict from obozrenie.global_settings import * from obozrenie.global_strings import * import obozrenie.i18n as i18n import obozrenie.helpers as helpers import obozrenie.ping as ping BACKEND_CONFIG = os.path.join(SETTINGS_INTERNAL_BACKENDS_DIR, "rigsofrods.toml") RIGSOFRODS_MSG = BACKENDCAT_MSG + i18n._("Rigs of Rods:") def parse_server_entry(entry: list) -> dict: players = entry[0]['#text'].split('/') try: password = bool(entry[1]['#text'].strip()) except KeyError: password = False server_dict = { 'player_count': int(players[0]), 'player_limit': int(players[1]),