from consts import * from hexview import HexView from backend import GameConquerorBackend import misc import locale # In some locale, ',' is used in float numbers locale.setlocale(locale.LC_NUMERIC, 'C') CLIPBOARD = Gtk.Clipboard.get(Gdk.SELECTION_CLIPBOARD) WORK_DIR = os.path.dirname(sys.argv[0]) DATA_WORKER_INTERVAL = 500 # for read(update)/write(lock) SCAN_RESULT_LIST_LIMIT = 1000 # maximal number of entries that can be displayed SCAN_VALUE_TYPES = misc.build_simple_str_liststore(['int', 'int8', 'int16', 'int32', 'int64', 'float', 'float32', 'float64', 'number', 'bytearray', 'string' ]) LOCK_FLAG_TYPES = misc.build_simple_str_liststore(['=', '+', '-']) LOCK_VALUE_TYPES = misc.build_simple_str_liststore(['int8', 'int16', 'int32', 'int64', 'float32', 'float64', 'bytearray', 'string' ]) SEARCH_SCOPE_NAMES = ['Basic', 'Normal', 'Full'] # convert type names used by scanmem into ours TYPENAMES_S2G = {'I64':'int64' ,'I64s':'int64' ,'I64u':'int64' ,'I32':'int32' ,'I32s':'int32' ,'I32u':'int32' ,'I16':'int16'
locale.setlocale(locale.LC_NUMERIC, 'C') locale.bindtextdomain(GETTEXT_PACKAGE, LOCALEDIR) gettext.install(GETTEXT_PACKAGE, LOCALEDIR, names=('_')) CLIPBOARD = Gtk.Clipboard.get(Gdk.SELECTION_CLIPBOARD) WORK_DIR = os.path.dirname(sys.argv[0]) PROGRESS_INTERVAL = 100 # for scan progress updates DATA_WORKER_INTERVAL = 500 # for read(update)/write(lock) SCAN_RESULT_LIST_LIMIT = 1000 # maximal number of entries that can be displayed SCAN_VALUE_TYPES = [ 'int', 'int8', 'int16', 'int32', 'int64', 'float', 'float32', 'float64', 'number', 'bytearray', 'string' ] LOCK_FLAG_TYPES = misc.build_simple_str_liststore(['=', '+', '-']) MEMORY_TYPES = [ 'int8', 'uint8', 'int16', 'uint16', 'int32', 'uint32', 'int64', 'uint64', 'float32', 'float64', 'bytearray', 'string' ] SEARCH_SCOPE_NAMES = ['Basic', 'Normal', 'Full'] # convert type names used by scanmem into ours TYPENAMES_S2G = { 'I64': 'int64', 'I64s': 'int64', 'I64u': 'uint64', 'I32': 'int32', 'I32s': 'int32',
def __init__(self): ################################## # init GUI self.builder = Gtk.Builder() self.builder.set_translation_domain(GETTEXT_PACKAGE) self.builder.add_from_file(os.path.join(WORK_DIR, 'GameConqueror.xml')) self.main_window = self.builder.get_object('MainWindow') self.main_window.set_title('GameConqueror %s' % (VERSION, )) self.about_dialog = self.builder.get_object('AboutDialog') # set version self.about_dialog.set_version(VERSION) self.process_list_dialog = self.builder.get_object('ProcessListDialog') self.addcheat_dialog = self.builder.get_object('AddCheatDialog') # init memory editor self.memoryeditor_window = self.builder.get_object( 'MemoryEditor_Window') self.memoryeditor_hexview = HexView() self.memoryeditor_window.get_child().pack_start( self.memoryeditor_hexview, True, True, 0) self.memoryeditor_hexview.show_all() self.memoryeditor_address_entry = self.builder.get_object( 'MemoryEditor_Address_Entry') self.memoryeditor_hexview.connect( 'char-changed', self.memoryeditor_hexview_char_changed_cb) self.found_count_label = self.builder.get_object('FoundCount_Label') self.process_label = self.builder.get_object('Process_Label') self.value_input = self.builder.get_object('Value_Input') self.scanoption_frame = self.builder.get_object('ScanOption_Frame') self.scanprogress_progressbar = self.builder.get_object( 'ScanProgress_ProgressBar') self.input_box = self.builder.get_object('Value_Input') self.scan_button = self.builder.get_object('Scan_Button') self.reset_button = self.builder.get_object('Reset_Button') ### # Set scan data type self.scan_data_type_combobox = self.builder.get_object( 'ScanDataType_ComboBoxText') for entry in SCAN_VALUE_TYPES: self.scan_data_type_combobox.append_text(entry) # apply setting misc.combobox_set_active_item(self.scan_data_type_combobox, SETTINGS['scan_data_type']) ### # set search scope self.search_scope_scale = self.builder.get_object('SearchScope_Scale') # apply setting self.search_scope_scale.set_value(SETTINGS['search_scope']) # init scanresult treeview # we may need a cell data func here # create model self.scanresult_tv = self.builder.get_object('ScanResult_TreeView') # liststore contents: addr, value, type, valid, offset, region type, match_id self.scanresult_liststore = Gtk.ListStore(GObject.TYPE_UINT64, str, str, bool, GObject.TYPE_UINT64, str, int) self.scanresult_tv.set_model(self.scanresult_liststore) # init columns misc.treeview_append_column(self.scanresult_tv, _('Address'), 0, hex_col=0, attributes=(('text', 0), ), properties=(('family', 'monospace'), )) misc.treeview_append_column(self.scanresult_tv, _('Value'), 1, attributes=(('text', 1), ), properties=(('family', 'monospace'), )) misc.treeview_append_column(self.scanresult_tv, _('Offset'), 4, hex_col=4, attributes=(('text', 4), ), properties=(('family', 'monospace'), )) misc.treeview_append_column(self.scanresult_tv, _('Region Type'), 5, attributes=(('text', 5), ), properties=(('family', 'monospace'), )) # init CheatList TreeView self.cheatlist_tv = self.builder.get_object('CheatList_TreeView') # cheatlist contents: lockflag, locked, description, addr, type, value, valid self.cheatlist_liststore = Gtk.ListStore(str, bool, str, GObject.TYPE_UINT64, str, str, bool) self.cheatlist_tv.set_model(self.cheatlist_liststore) self.cheatlist_editing = False # Lock Flag misc.treeview_append_column( self.cheatlist_tv, '', 0, renderer_class=Gtk.CellRendererCombo, attributes=(('text', 0), ), properties=(('editable', True), ('has-entry', False), ('model', LOCK_FLAG_TYPES), ('text-column', 0)), signals=( ('edited', self.cheatlist_toggle_lock_flag_cb), ('editing-started', self.cheatlist_edit_start), ('editing-canceled', self.cheatlist_edit_cancel), )) # Lock misc.treeview_append_column( self.cheatlist_tv, _('Lock'), 1, renderer_class=Gtk.CellRendererToggle, attributes=(('active', 1), ), properties=(('activatable', True), ('radio', False), ('inconsistent', False)), signals=(('toggled', self.cheatlist_toggle_lock_cb), )) # Description misc.treeview_append_column( self.cheatlist_tv, _('Description'), 2, attributes=(('text', 2), ), properties=(('editable', True), ), signals=( ('edited', self.cheatlist_edit_description_cb), ('editing-started', self.cheatlist_edit_start), ('editing-canceled', self.cheatlist_edit_cancel), )) # Address misc.treeview_append_column(self.cheatlist_tv, _('Address'), 3, hex_col=3, attributes=(('text', 3), ), properties=(('family', 'monospace'), )) # Type misc.treeview_append_column( self.cheatlist_tv, _('Type'), 4, renderer_class=Gtk.CellRendererCombo, attributes=(('text', 4), ), properties=(('editable', True), ('has-entry', False), ('model', misc.build_simple_str_liststore(MEMORY_TYPES)), ('text-column', 0)), signals=( ('edited', self.cheatlist_edit_type_cb), ('editing-started', self.cheatlist_edit_start), ('editing-canceled', self.cheatlist_edit_cancel), )) # Value misc.treeview_append_column( self.cheatlist_tv, _('Value'), 5, attributes=(('text', 5), ), properties=(('editable', True), ('family', 'monospace')), signals=( ('edited', self.cheatlist_edit_value_cb), ('editing-started', self.cheatlist_edit_start), ('editing-canceled', self.cheatlist_edit_cancel), )) # init ProcessList self.processfilter_input = self.builder.get_object( 'ProcessFilter_Input') self.userfilter_input = self.builder.get_object('UserFilter_Input') # init ProcessList_TreeView self.processlist_tv = self.builder.get_object('ProcessList_TreeView') self.processlist_liststore = Gtk.ListStore(int, str, str) self.processlist_filter = self.processlist_liststore.filter_new( root=None) self.processlist_filter.set_visible_func(self.processlist_filter_func, data=None) self.processlist_tv.set_model( Gtk.TreeModelSort(model=self.processlist_filter)) self.processlist_tv.set_search_column(1) # first col misc.treeview_append_column(self.processlist_tv, 'PID', 0, attributes=(('text', 0), )) # second col misc.treeview_append_column(self.processlist_tv, _('User'), 1, attributes=(('text', 1), )) # third col misc.treeview_append_column(self.processlist_tv, _('Process'), 2, attributes=(('text', 2), )) # get list of things to be disabled during scan self.disablelist = [] self.disablelist.append(self.cheatlist_tv) self.disablelist.append(self.scanresult_tv) self.disablelist.append(self.builder.get_object('processGrid')) self.disablelist.append(self.builder.get_object('searchGrid')) self.disablelist.append(self.builder.get_object('buttonGrid')) self.disablelist.append(self.memoryeditor_window) # init AddCheatDialog self.addcheat_address_input = self.builder.get_object('Address_Input') self.addcheat_address_input.override_font( gi.repository.Pango.FontDescription("Monospace")) self.addcheat_description_input = self.builder.get_object( 'Description_Input') self.addcheat_length_spinbutton = self.builder.get_object( 'Length_SpinButton') self.addcheat_type_combobox = self.builder.get_object( 'Type_ComboBoxText') for entry in MEMORY_TYPES: self.addcheat_type_combobox.append_text(entry) misc.combobox_set_active_item(self.addcheat_type_combobox, SETTINGS['lock_data_type']) self.Type_ComboBoxText_changed_cb(self.addcheat_type_combobox) # init popup menu for scanresult self.scanresult_popup = Gtk.Menu() misc.menu_append_item(self.scanresult_popup, _('Add to cheat list'), self.scanresult_popup_cb, 'add_to_cheat_list') misc.menu_append_item(self.scanresult_popup, _('Browse this address'), self.scanresult_popup_cb, 'browse_this_address') misc.menu_append_item(self.scanresult_popup, _('Scan for this address'), self.scanresult_popup_cb, 'scan_for_this_address') misc.menu_append_item(self.scanresult_popup, _('Remove this match'), self.scanresult_delete_selected_matches) self.scanresult_popup.show_all() # init popup menu for cheatlist self.cheatlist_popup = Gtk.Menu() misc.menu_append_item(self.cheatlist_popup, _('Browse this address'), self.cheatlist_popup_cb, 'browse_this_address') misc.menu_append_item(self.cheatlist_popup, _('Copy address'), self.cheatlist_popup_cb, 'copy_address') misc.menu_append_item(self.cheatlist_popup, _('Remove this entry'), self.cheatlist_popup_cb, 'remove_entry') self.cheatlist_popup.show_all() self.builder.connect_signals(self) self.main_window.connect('destroy', self.exit) ########################### # init others (backend, flag...) self.pid = 0 # target pid self.maps = [] self.last_hexedit_address = (0, 0) # used for hexview self.is_scanning = False self.exit_flag = False # currently for data_worker only, other 'threads' may also use this flag self.backend = GameConquerorBackend( os.path.join(LIBDIR, 'libscanmem.so.1')) self.check_backend_version() self.is_first_scan = True GLib.timeout_add(DATA_WORKER_INTERVAL, self.data_worker) self.command_lock = threading.RLock()
import locale import gettext # In some locale, ',' is used in float numbers locale.setlocale(locale.LC_NUMERIC, 'C') locale.bindtextdomain(GETTEXT_PACKAGE, LOCALEDIR) gettext.install(GETTEXT_PACKAGE, LOCALEDIR, names=('_')) CLIPBOARD = Gtk.Clipboard.get(Gdk.SELECTION_CLIPBOARD) WORK_DIR = os.path.dirname(sys.argv[0]) PROGRESS_INTERVAL = 100 # for scan progress updates DATA_WORKER_INTERVAL = 500 # for read(update)/write(lock) SCAN_RESULT_LIST_LIMIT = 1000 # maximal number of entries that can be displayed SCAN_VALUE_TYPES = misc.build_simple_str_liststore([ 'int', 'int8', 'int16', 'int32', 'int64', 'float', 'float32', 'float64', 'number', 'bytearray', 'string' ]) LOCK_FLAG_TYPES = misc.build_simple_str_liststore(['=', '+', '-']) LOCK_VALUE_TYPES = misc.build_simple_str_liststore([ 'int8', 'int16', 'int32', 'int64', 'float32', 'float64', 'bytearray', 'string' ]) SEARCH_SCOPE_NAMES = ['Basic', 'Normal', 'Full'] # convert type names used by scanmem into ours TYPENAMES_S2G = { 'I64': 'int64', 'I64s': 'int64',