Ejemplo n.º 1
0
class TekkenGameReader:
    def __init__(self):
        self.pid = -1
        self.needReaquireGameState = True
        self.needReacquireModule = True
        self.module_address = 0
        self.original_facing = None
        self.config_reader = ConfigReader('memory_address')
        self.player_data_pointer_offset = self.config_reader.get_property(
            'player_data_pointer_offset',
            MemoryAddressOffsets.player_data_pointer_offset.value,
            lambda x: int(x, 16))

    def GetValueFromAddress(self,
                            processHandle,
                            address,
                            isFloat=False,
                            is64bit=False):
        data = c.c_ulonglong()
        bytesRead = c.c_ulonglong()
        successful = ReadProcessMemory(processHandle, address, c.byref(data),
                                       c.sizeof(data), c.byref(bytesRead))
        if not successful:
            e = GetLastError()
            print("ReadProcessMemory Error: Code " + str(e))
            self.needReacquireModule = True
            self.needReaquireGameState = True
            self.pid = -1

        if not is64bit:
            value = int(data.value) % pow(2, 32)
        else:
            value = int(data.value)

        if not isFloat:
            return (value)
        else:
            return struct.unpack("<f", struct.pack("<I", (value)))[0]

    def IsForegroundPID(self):
        pid = c.wintypes.DWORD()
        active = c.windll.user32.GetForegroundWindow()
        active_window = c.windll.user32.GetWindowThreadProcessId(
            active, c.byref(pid))
        return pid.value == self.pid

    def GetWindowRect(self):
        if self.IsForegroundPID():
            rect = c.wintypes.RECT()
            c.windll.user32.GetWindowRect(
                c.windll.user32.GetForegroundWindow(), c.byref(rect))
            return rect
        else:
            return None

    def HasWorkingPID(self):
        return self.pid > -1

    def GetUpdatedState(self):
        gameSnapshot = None

        if not self.HasWorkingPID():
            self.pid = PIDSearcher.GetPIDByName(
                b'TekkenGame-Win64-Shipping.exe')
            if self.HasWorkingPID():
                print("Tekken pid acquired: " + str(self.pid))
            else:
                print("Tekken pid not acquired. Trying to acquire...")

            return gameSnapshot

        if (self.needReacquireModule):
            print("Trying to acquire Tekken library in pid: " + str(self.pid))
            self.module_address = ModuleEnumerator.GetModuleAddressByPIDandName(
                self.pid, 'TekkenGame-Win64-Shipping.exe')
            if self.module_address == None:
                print(
                    "TekkenGame-Win64-Shipping.exe not found. Likely wrong process id."
                )
            elif (self.module_address != 0x140000000):
                print(
                    "Unrecognized location for TekkenGame-Win64-Shipping.exe module. Tekken.exe Patch? Wrong process id?"
                )
            else:
                print("Found TekkenGame-Win64-Shipping.exe")
                self.needReacquireModule = False

        if self.module_address != None:
            processHandle = OpenProcess(0x10, False, self.pid)
            try:
                player_data_base_address = self.GetValueFromAddress(
                    processHandle,
                    self.module_address + self.player_data_pointer_offset,
                    is64bit=True)
                if player_data_base_address == 0:
                    print("No fight detected. Gamestate not updated.")
                    self.needReaquireGameState = True

                else:
                    player_data_second_address = 0
                    best_frame_count = -1
                    second_address_base = self.GetValueFromAddress(
                        processHandle, player_data_base_address, is64bit=True)
                    for i in range(
                            8
                    ):  # for rollback purposes, there are 8 copies of the game state, each one updatating once every 8 frames
                        potential_second_address = second_address_base + (
                            i *
                            MemoryAddressOffsets.rollback_frame_offset.value)
                        potential_frame_count = self.GetValueFromAddress(
                            processHandle, potential_second_address +
                            GameDataAddress.frame_count.value)
                        if potential_frame_count > best_frame_count:
                            player_data_second_address = potential_second_address
                            best_frame_count = potential_frame_count

                    p1_bot = BotSnapshot()
                    p2_bot = BotSnapshot()

                    for data in PlayerDataAddress:
                        p1_value = self.GetValueFromAddress(
                            processHandle,
                            player_data_second_address + data.value,
                            IsDataAFloat(data))
                        p2_value = self.GetValueFromAddress(
                            processHandle, player_data_second_address +
                            MemoryAddressOffsets.p2_data_offset.value +
                            data.value, IsDataAFloat(data))
                        p1_bot.player_data_dict[data] = p1_value
                        p2_bot.player_data_dict[data] = p2_value

                    bot_facing = self.GetValueFromAddress(
                        processHandle, player_data_second_address +
                        GameDataAddress.facing.value, IsDataAFloat(data))

                    #positionArrays = {}
                    #for startingAddress in valuesOfPositionArrays:
                    #    positionArrays[startingAddress[0]] = []
                    #    for i in range(16):
                    #        positionOffset = 32 #our xyz coordinate is 32 bytes, a 4 byte x, y, and z value followed by five 4 byte values that don't change
                    #        positionArrays[startingAddress[0]].append(TekkenGameReader.GetValueFromAddress(processHandle, player_data_second_address + startingAddress[1] + (i * positionOffset), startingAddress[2]))

                    #for key in positionArrays:
                    #    positionArray = positionArrays[key]
                    #    gameData[key] = sum(positionArray)/float(len(positionArray))

                    if self.original_facing == None and best_frame_count > 0:
                        self.original_facing = bot_facing > 0

                    self.needReaquireGameState = False

                    p1_bot.Bake()
                    p2_bot.Bake()
                    gameSnapshot = GameSnapshot(p1_bot, p2_bot,
                                                best_frame_count, bot_facing)
            finally:
                CloseHandle(processHandle)

        return gameSnapshot

    def GetNeedReacquireState(self):
        return self.needReaquireGameState
Ejemplo n.º 2
0
class Overlay:
    def __init__(self, master, xy_size, window_name):
        print("Launching {}".format(window_name))
        config_filename = "frame_data_overlay"
        self.tekken_config = ConfigReader(config_filename)
        is_windows_7 = 'Windows-7' in platform.platform()
        self.is_draggable_window = self.tekken_config.get_property(DisplaySettings.config_name(), DisplaySettings.overlay_as_draggable_window.name, False)
        self.is_minimize_on_lost_focus = self.tekken_config.get_property(DisplaySettings.config_name(), DisplaySettings.only_appears_when_Tekken_7_has_focus.name, True)
        self.is_transparency = self.tekken_config.get_property(DisplaySettings.config_name(), DisplaySettings.transparent_background.name, not is_windows_7)
        self.is_overlay_on_top = not self.tekken_config.get_property(DisplaySettings.config_name(), DisplaySettings.overlay_on_bottom.name, False)



        self.overlay_visible = False
        if master == None:
            self.toplevel = Tk()
        else:
            self.toplevel = Toplevel()

        self.toplevel.wm_title(window_name)

        self.toplevel.attributes("-topmost", True)

        self.background_color = CurrentColorScheme.dict[ColorSchemeEnum.background]

        if self.is_transparency:
            self.tranparency_color = CurrentColorScheme.dict[ColorSchemeEnum.transparent]
            self.toplevel.wm_attributes("-transparentcolor", self.tranparency_color)
            self.toplevel.attributes("-alpha", "0.75")
        else:
            if is_windows_7:
                print("Windows 7 detected. Disabling transparency.")
            self.tranparency_color = self.background_color
        self.toplevel.configure(background=self.tranparency_color)

        self.toplevel.iconbitmap('TekkenData/tekken_bot_close.ico')
        if not self.is_draggable_window:
            self.toplevel.overrideredirect(True)

        self.w = xy_size[0]
        self.h = xy_size[1]

        self.toplevel.geometry(str(self.w) + 'x' + str(self.h))


    def update_location(self):
        if not self.is_draggable_window:
            tekken_rect = self.launcher.gameState.gameReader.GetWindowRect()
            if tekken_rect != None:
                x = (tekken_rect.right + tekken_rect.left) / 2 - self.w / 2
                if self.is_overlay_on_top:
                    y = tekken_rect.top
                else:
                    y = tekken_rect.bottom - self.h - 10
                self.toplevel.geometry('%dx%d+%d+%d' % (self.w, self.h, x, y))
                if not self.overlay_visible:
                    self.show()
            else:
                if self.overlay_visible:
                    self.hide()

    def update_state(self):
        pass

    def hide(self):
        if self.is_minimize_on_lost_focus and not self.is_draggable_window:
            self.toplevel.withdraw()
            self.overlay_visible = False

    def show(self):
        self.toplevel.deiconify()
        self.overlay_visible = True

    def write_config_file(self):
        self.tekken_config.write()
Ejemplo n.º 3
0
class GUI_FrameDataOverlay():
    def __init__(self, master):
        print("Tekken Bot Starting...")

        is_windows_7 = 'Windows-7' in platform.platform()
        self.tekken_config = ConfigReader("frame_data_overlay")
        self.is_draggable_window = self.tekken_config.get_property(
            DisplaySettings.config_name(),
            DisplaySettings.overlay_as_draggable_window.name, False)
        self.is_minimize_on_lost_focus = self.tekken_config.get_property(
            DisplaySettings.config_name(),
            DisplaySettings.only_appears_when_Tekken_7_has_focus.name, True)
        self.is_transparency = self.tekken_config.get_property(
            DisplaySettings.config_name(),
            DisplaySettings.transparent_background.name, not is_windows_7)
        self.is_overlay_on_top = not self.tekken_config.get_property(
            DisplaySettings.config_name(),
            DisplaySettings.overlay_on_bottom.name, False)
        self.enable_nerd_data = self.tekken_config.get_property(
            DisplaySettings.config_name(), "data_for_nerds", False)
        self.show_live_framedata = self.tekken_config.get_property(
            DisplaySettings.config_name(),
            DisplaySettings.tiny_live_frame_data_numbers.name, True)
        self.mode = OverlayMode.FrameData

        self.launcher = FrameDataLauncher(self.enable_nerd_data)

        self.overlay_visible = False
        if master == None:
            self.toplevel = Tk()
        else:
            self.toplevel = Toplevel()

        self.toplevel.wm_title("Tekken Bot: Frame Data Overlay")

        self.toplevel.attributes("-topmost", True)

        self.background_color = CurrentColorScheme.dict[
            ColorSchemeEnum.background]

        if self.is_transparency:
            self.tranparency_color = CurrentColorScheme.dict[
                ColorSchemeEnum.transparent]
            self.toplevel.wm_attributes("-transparentcolor",
                                        self.tranparency_color)
            self.toplevel.attributes("-alpha", "0.75")
        else:
            if is_windows_7:
                print("Windows 7 detected. Disabling transparency.")
            self.tranparency_color = self.background_color
        self.toplevel.configure(background=self.tranparency_color)

        self.w = 1000
        self.h = 86

        if self.enable_nerd_data:
            self.w += 400

        self.toplevel.geometry(str(self.w) + 'x' + str(self.h))

        self.toplevel.iconbitmap('TekkenData/tekken_bot_close.ico')
        if not self.is_draggable_window:
            self.toplevel.overrideredirect(True)

        self.s = Style()
        self.s.theme_use('alt')
        self.s.configure('.', background=self.background_color)
        self.s.configure(
            '.',
            foreground=CurrentColorScheme.dict[ColorSchemeEnum.advantage_text])

        Grid.columnconfigure(self.toplevel, 0, weight=0)
        Grid.columnconfigure(self.toplevel, 1, weight=0)
        Grid.columnconfigure(self.toplevel, 2, weight=0)
        Grid.columnconfigure(self.toplevel, 3, weight=1)
        Grid.columnconfigure(self.toplevel, 4, weight=0)
        Grid.columnconfigure(self.toplevel, 5, weight=0)
        Grid.columnconfigure(self.toplevel, 6, weight=0)
        Grid.rowconfigure(self.toplevel, 0, weight=1)
        Grid.rowconfigure(self.toplevel, 1, weight=0)

        self.s.configure('TFrame', background=self.tranparency_color)
        self.fa_p1_var, fa_p1_label = self.create_frame_advantage_label(1)
        self.fa_p2_var, fa_p2_label = self.create_frame_advantage_label(5)

        self.l_margin = self.create_padding_frame(0)
        self.r_margin = self.create_padding_frame(6)
        self.l_seperator = self.create_padding_frame(2)
        self.r_seperator = self.create_padding_frame(4)

        if self.show_live_framedata:
            self.l_live_recovery = self.create_live_recovery(fa_p1_label, 0)
            self.r_live_recovery = self.create_live_recovery(fa_p2_label, 0)

        self.text = self.create_textbox(3)

        self.stdout = sys.stdout
        self.redirector = TextRedirector(self.stdout, self.text, self.s,
                                         self.fa_p1_var, self.fa_p2_var)
        self.text.configure(state="normal")
        self.text.delete("1.0", "end")
        #self.text.insert("1.0", "{:^5}|{:^8}|{:^9}|{:^7}|{:^5}|{:^5}|{:^8}|{:^5}|{:^5}|{:^7}|{:^5}|{}\n".format(" input ", "type", "startup", "block", "hit", "CH", "active", "track", "tot", "rec", "stun", "notes"))
        #self.redirector.populate_column_names(self.get_data_columns())
        self.redirector.set_columns_to_print(self.get_data_columns())

        self.text.configure(state="disabled")

    def get_data_columns(self):
        booleans_for_columns = []
        for enum in DataColumns:
            bool = self.tekken_config.get_property(DataColumns.config_name(),
                                                   enum.name, True)
            booleans_for_columns.append(bool)
        return booleans_for_columns

    def redirect_stdout(self):
        sys.stdout = self.redirector

    def restore_stdout(self):
        sys.stdout = self.stdout

    def create_padding_frame(self, col):
        padding = Frame(self.toplevel, width=10)
        padding.grid(row=0, column=col, rowspan=2, sticky=N + S + W + E)
        return padding

    def create_live_recovery(self, parent, col):
        live_recovery_var = StringVar()
        live_recovery_var.set('??')
        live_recovery_label = Label(parent,
                                    textvariable=live_recovery_var,
                                    font=("Segoe UI", 12),
                                    width=5,
                                    anchor='c')
        #live_recovery_label.grid(row=0, column=col, sticky =S+W)
        live_recovery_label.place(rely=0.0, relx=0.0, x=4, y=4, anchor=NW)
        return live_recovery_var

    def create_frame_advantage_label(self, col):
        frame_advantage_var = StringVar()
        frame_advantage_var.set('?')
        frame_advantage_label = Label(self.toplevel,
                                      textvariable=frame_advantage_var,
                                      font=("Consolas", 44),
                                      width=4,
                                      anchor='c',
                                      borderwidth=4,
                                      relief='ridge')
        frame_advantage_label.grid(row=0, column=col)
        return frame_advantage_var, frame_advantage_label

    def create_attack_type_label(self, col):
        attack_type_var = StringVar()
        attack_type_var.set('?')
        attack_type_label = Label(self.toplevel,
                                  textvariable=attack_type_var,
                                  font=("Verdana", 12),
                                  width=10,
                                  anchor='c',
                                  borderwidth=4,
                                  relief='ridge')
        attack_type_label.grid(row=1, column=col)
        return attack_type_var

    def create_textbox(self, col):
        textbox = Text(self.toplevel,
                       font=("Consolas, 14"),
                       wrap=NONE,
                       highlightthickness=0,
                       pady=0,
                       relief='flat')
        # self.text.pack(side="top", fill="both", expand=True)
        textbox.grid(row=0, column=col, rowspan=2, sticky=N + S + W + E)
        #textbox.configure(background='black')
        #textbox.configure(background='white')
        textbox.configure(background=self.background_color)

        textbox.configure(
            foreground=CurrentColorScheme.dict[ColorSchemeEnum.system_text])
        #textbox.configure(foreground='dark khaki')
        #textbox.configure(foreground='#839496')
        #textbox.configure(foreground='#657B83')
        return textbox

    def update_launcher(self):
        time1 = time.time()
        self.launcher.Update()

        if self.show_live_framedata:
            if len(self.launcher.gameState.stateLog) > 1:
                l_recovery = str(
                    self.launcher.gameState.GetOppFramesTillNextMove() -
                    self.launcher.gameState.GetBotFramesTillNextMove())
                r_recovery = str(
                    self.launcher.gameState.GetBotFramesTillNextMove() -
                    self.launcher.gameState.GetOppFramesTillNextMove())
                if not '-' in l_recovery:
                    l_recovery = '+' + l_recovery
                if not '-' in r_recovery:
                    r_recovery = '+' + r_recovery
                self.l_live_recovery.set(l_recovery)
                self.r_live_recovery.set(r_recovery)

        if not self.is_draggable_window:
            tekken_rect = self.launcher.gameState.gameReader.GetWindowRect()
            if tekken_rect != None:
                x = (tekken_rect.right + tekken_rect.left) / 2 - self.w / 2
                if self.is_overlay_on_top:
                    y = tekken_rect.top
                else:
                    y = tekken_rect.bottom - self.h - 10
                self.toplevel.geometry('%dx%d+%d+%d' % (self.w, self.h, x, y))
                if not self.overlay_visible:
                    self.show()
            else:
                if self.overlay_visible:
                    self.hide()

        if self.launcher.gameState.gameReader.GetNeedReacquireState():
            self.restore_stdout()
        else:
            self.redirect_stdout()

        time2 = time.time()
        elapsed_time = 1000 * (time2 - time1)
        self.toplevel.after(max(2, 8 - int(round(elapsed_time))),
                            self.update_launcher)

    def hide(self):
        if self.is_minimize_on_lost_focus and not self.is_draggable_window:
            self.toplevel.withdraw()
            self.overlay_visible = False

    def show(self):
        self.toplevel.deiconify()
        self.overlay_visible = True

    def set_columns_to_print(self, columns_to_print):
        self.redirector.set_columns_to_print(columns_to_print)

    def update_column_to_print(self, enum, value):
        self.tekken_config.set_property(DataColumns.config_name(), enum.name,
                                        value)
        self.write_config_file()

    def write_config_file(self):
        self.tekken_config.write()
Ejemplo n.º 4
0
class GUI_FrameDataOverlay(Tk):
    def __init__(self):
        print("Tekken Bot Starting...")

        is_windows_7 = 'Windows-7' in platform.platform()
        self.tekken_config = ConfigReader("frame_data_overlay")
        self.is_draggable_window = self.tekken_config.get_property("independent_window_mode", True, lambda x: not "0" in str(x))
        self.is_minimize_on_lost_focus = self.tekken_config.get_property("minimize_on_lost_focus", True, lambda x: not "0" in str(x))
        self.is_transparency = self.tekken_config.get_property("transparency", not is_windows_7, lambda x: not "0" in str(x))
        self.enable_nerd_data = self.tekken_config.get_property("data_for_nerds", False, lambda x: not "0" in str(x))

        self.launcher = FrameDataLauncher(self.enable_nerd_data)

        self.overlay_visible = False

        Tk.__init__(self)

        self.wm_title("Tekken Bot: Frame Data Overlay")

        self.attributes("-topmost", True)

        #self.background_color = '#002B36'
        self.background_color = 'gray10'

        if self.is_transparency:
            self.wm_attributes("-transparentcolor", "white")
            self.attributes("-alpha", "0.75")
            self.tranparency_color = 'white'
        else:
            if is_windows_7:
                print("Windows 7 detected. Disabling transparency.")
            self.tranparency_color = self.background_color
        self.configure(background=self.tranparency_color)



        self.w = 820
        self.h = 96

        if self.enable_nerd_data:
            self.w += 400

        self.geometry( str(self.w) + 'x' + str(self.h))

        self.iconbitmap('TekkenData/tekken_bot_close.ico')
        if not self.is_draggable_window:
            self.overrideredirect(True)


        self.s = Style()
        self.s.theme_use('alt')
        self.s.configure('.', background=self.background_color)
        self.s.configure('.', foreground='black')

        Grid.columnconfigure(self, 0, weight=0)
        Grid.columnconfigure(self, 1, weight=0)
        Grid.columnconfigure(self, 2, weight=0)
        Grid.columnconfigure(self, 3, weight=1)
        Grid.columnconfigure(self, 4, weight=0)
        Grid.columnconfigure(self, 5, weight=0)
        Grid.columnconfigure(self, 6, weight=0)
        Grid.rowconfigure(self, 0, weight=1)
        Grid.rowconfigure(self, 1, weight=0)

        self.s.configure('TFrame', background=self.tranparency_color)
        self.fa_p1_var = self.create_frame_advantage_label(1)
        self.fa_p2_var = self.create_frame_advantage_label(5)

        self.l_margin = self.create_padding_frame(0)
        self.r_margin = self.create_padding_frame(2)
        self.l_seperator = self.create_padding_frame(4)
        self.r_seperator = self.create_padding_frame(6)


        self.text = self.create_textbox(3)

        self.stdout = sys.stdout
        self.redirector = TextRedirector(self.stdout, self.text, self.s, self.fa_p1_var, self.fa_p2_var)
        self.text.configure(state="normal")
        self.text.delete("1.0", "end")
        self.text.insert("1.0", "{:^5}|{:^8}|{:^9}|{:^8}|{:^5}|{:^5}|{:^5}|{}\n".format(" input ", "type", "startup", "block", "hit", "CH", "active", "notes"))

        self.text.configure(state="disabled")

    def redirect_stdout(self):
        sys.stdout = self.redirector

    def restore_stdout(self):
        sys.stdout = self.stdout

    def create_padding_frame(self, col):
        padding = Frame(width=10)
        padding.grid(row=0, column=col, rowspan=2, sticky=N + S + W + E)
        return padding

    def create_frame_advantage_label(self, col):
        frame_advantage_var = StringVar()
        frame_advantage_var.set('??')
        frame_advantage_label = Label(self, textvariable=frame_advantage_var, font=("Consolas", 44), width=4, anchor='c',
                                        borderwidth=4, relief='ridge')
        frame_advantage_label.grid(row=0, column=col)
        return frame_advantage_var

    def create_attack_type_label(self, col):
        attack_type_var = StringVar()
        attack_type_var.set('??')
        attack_type_label = Label(self, textvariable=attack_type_var, font=("Verdana", 12), width=10, anchor='c',
                                    borderwidth=4, relief='ridge')
        attack_type_label.grid(row=1, column=col)
        return attack_type_var

    def create_textbox(self, col):
        textbox = Text(self, font=("Consolas, 14"), wrap=NONE, highlightthickness=0, relief='flat')
        # self.text.pack(side="top", fill="both", expand=True)
        textbox.grid(row=0, column=col, rowspan=2, sticky=N + S + W + E)
        #textbox.configure(background='black')
        #textbox.configure(background='white')
        textbox.configure(background=self.background_color)

        textbox.configure(foreground='lawn green')
        #textbox.configure(foreground='dark khaki')
        #textbox.configure(foreground='#839496')
        #textbox.configure(foreground='#657B83')
        return textbox


    def update_launcher(self):
        time1 = time.time()
        self.launcher.Update()
        time2 = time.time()
        elapsed_time = 1000 * (time2 - time1)

        if not self.is_draggable_window:
            tekken_rect = self.launcher.gameState.gameReader.GetWindowRect()
            if tekken_rect != None:
                x = (tekken_rect.right + tekken_rect.left)/2 - self.w/2
                y = tekken_rect.top
                self.geometry('%dx%d+%d+%d' % (self.w, self.h, x, y))
                if not self.overlay_visible:
                    self.show()
            else:
                if self.overlay_visible:
                    self.hide()

        if self.launcher.gameState.gameReader.GetNeedReacquireState():
            self.restore_stdout()
        else:
            self.redirect_stdout()
        #print(10 - int(round(elapsed_time)))
        self.after(max(2, 8 - int(round(elapsed_time))), self.update_launcher)

    def hide(self):
        if self.is_minimize_on_lost_focus and not self.is_draggable_window:
            self.withdraw()
            self.overlay_visible = False

    def show(self):
        self.deiconify()
        self.overlay_visible = True
Ejemplo n.º 5
0
class GUI_FrameDataOverlay(Tk):
    def __init__(self):
        print("Tekken Bot Starting...")

        self.tekken_config = ConfigReader("frame_data_overlay")

        self.launcher = FrameDataLauncher()

        self.overlay_visible = False

        Tk.__init__(self)

        self.wm_title("Tekken Bot: Frame Data Overlay")
        self.wm_attributes("-transparentcolor", "white")
        self.attributes("-topmost", True)
        self.attributes("-alpha", "0.75")

        self.iconbitmap('TekkenData/tekken_bot_close.ico')
        self.overrideredirect(True)
        self.configure(background='white')

        self.s = Style()
        self.s.theme_use('alt')
        self.s.configure('.', background='black')
        self.s.configure('.', foreground='black')

        Grid.columnconfigure(self, 0, weight=0)
        Grid.columnconfigure(self, 1, weight=1)
        Grid.columnconfigure(self, 2, weight=0)
        Grid.rowconfigure(self, 0, weight=1)
        Grid.rowconfigure(self, 1, weight=0)

        self.fa_p1_var = self.create_frame_advantage_label(0)
        self.fa_p2_var = self.create_frame_advantage_label(2)


        self.at_p1_var = self.create_attack_type_label(0)
        self.at_p2_var = self.create_attack_type_label(2)

        self.text = self.create_textbox()

        self.stdout = sys.stdout
        self.redirector = TextRedirector(self.stdout, self.text, self.s, self.fa_p1_var, self.fa_p2_var, self.at_p1_var, self.at_p2_var)
        self.redirect_stdout()
        print("move | type | startup | damage | block | hit | active")
        self.restore_stdout()

    def redirect_stdout(self):
        sys.stdout = self.redirector

    def restore_stdout(self):
        sys.stdout = self.stdout

    def create_frame_advantage_label(self, col):
        frame_advantage_var = StringVar()
        frame_advantage_var.set('??')
        frame_advantage_label = Label(self, textvariable=frame_advantage_var, font=("Consolas", 44), width=4, anchor='c',
                                        borderwidth=4, relief='ridge')
        frame_advantage_label.grid(row=0, column=col, sticky=E + W + N)
        return frame_advantage_var

    def create_attack_type_label(self, col):
        attack_type_var = StringVar()
        attack_type_var.set('??')
        attack_type_label = Label(self, textvariable=attack_type_var, font=("Verdana", 14), width=9, anchor='c',
                                    borderwidth=4, relief='ridge')
        attack_type_label.grid(row=1, column=col)
        return attack_type_var

    def create_textbox(self):
        textbox = Text(self, font=("Consolas, 13"), wrap="word", highlightthickness=2, relief='ridge')
        # self.text.pack(side="top", fill="both", expand=True)
        textbox.grid(row=0, column=1, rowspan=2, sticky=N + S + W + E)
        textbox.configure(background='black')
        textbox.configure(foreground='green')
        return textbox


    def update_launcher(self):
        self.launcher.Update()

        tekken_rect = self.launcher.gameState.gameReader.GetWindowRect()
        if tekken_rect != None:
            w = 720
            h = 120
            x = (tekken_rect.right + tekken_rect.left)/2 - w/2
            y = tekken_rect.top
            self.geometry('%dx%d+%d+%d' % (w, h, x, y))
            if not self.overlay_visible:
                self.show()
        else:
            if self.overlay_visible:
                self.hide()

        if self.launcher.gameState.gameReader.GetNeedReacquireState():
            self.restore_stdout()
        else:
            self.redirect_stdout()

        self.after(7, self.update_launcher)

    def hide(self):
        if self.tekken_config.get_property("minimize_on_lost_focus", True, lambda x: not "0" in str(x) ):
            self.withdraw()
            self.overlay_visible = False

    def show(self):
        self.deiconify()
        self.overlay_visible = True
Ejemplo n.º 6
0
class TekkenGameReader:
    def __init__(self):
        self.pid = -1
        self.needReaquireGameState = True
        self.needReacquireModule = True
        self.module_address = 0
        self.original_facing = None
        self.config_reader = ConfigReader('memory_address')
        self.player_data_pointer_offset = self.config_reader.get_property(
            'player_data_pointer_offset',
            MemoryAddressOffsets.player_data_pointer_offset.value,
            lambda x: int(x, 16))

    def ReacquireEverything(self):
        self.needReacquireModule = True
        self.needReaquireGameState = True
        self.pid = -1

    def GetValueFromAddress(self,
                            processHandle,
                            address,
                            isFloat=False,
                            is64bit=False):
        data = c.c_ulonglong()
        bytesRead = c.c_ulonglong()
        successful = ReadProcessMemory(processHandle, address, c.byref(data),
                                       c.sizeof(data), c.byref(bytesRead))
        if not successful:
            e = GetLastError()
            print("ReadProcessMemory Error: Code " + str(e))
            self.ReacquireEverything()

        if not is64bit:
            value = int(data.value) % pow(2, 32)
        else:
            value = int(data.value)

        if not isFloat:
            return (value)
        else:
            return struct.unpack("<f", struct.pack("<I", (value)))[0]

    def GetPlayerDataFrame(self, processHandle, address):
        data = c.create_string_buffer(
            MemoryAddressOffsets.rollback_frame_offset.value)
        bytesRead = c.c_ulonglong(
            MemoryAddressOffsets.rollback_frame_offset.value)
        successful = ReadProcessMemory(processHandle, address, c.byref(data),
                                       c.sizeof(data), c.byref(bytesRead))
        if not successful:
            e = GetLastError()
            print("Getting Player Data Error: Code " + str(e))
        #print('{} : {}'.format(address, self.GetValueFromFrame(data, PlayerDataAddress.simple_move_state)))
        return data

    def GetValueFromFrame(self, frame, offset, is_player_2, is_float=False):
        address = offset
        if is_player_2:
            address += MemoryAddressOffsets.p2_data_offset.value
        bytes = frame[address:address + 4]
        if not is_float:
            return struct.unpack("<I", bytes)[0]
        else:
            return struct.unpack("<f", bytes)[0]

    def IsForegroundPID(self):
        pid = c.wintypes.DWORD()
        active = c.windll.user32.GetForegroundWindow()
        active_window = c.windll.user32.GetWindowThreadProcessId(
            active, c.byref(pid))
        return pid.value == self.pid

    def GetWindowRect(self):
        if self.IsForegroundPID():
            rect = c.wintypes.RECT()
            c.windll.user32.GetWindowRect(
                c.windll.user32.GetForegroundWindow(), c.byref(rect))
            return rect
        else:
            return None

    def HasWorkingPID(self):
        return self.pid > -1

    def GetUpdatedState(self, rollback_frame=0):
        gameSnapshot = None

        if not self.HasWorkingPID():
            self.pid = PIDSearcher.GetPIDByName(
                b'TekkenGame-Win64-Shipping.exe')
            if self.HasWorkingPID():
                print("Tekken pid acquired: " + str(self.pid))
            else:
                print("Tekken pid not acquired. Trying to acquire...")

            return gameSnapshot

        if (self.needReacquireModule):
            print("Trying to acquire Tekken library in pid: " + str(self.pid))
            self.module_address = ModuleEnumerator.GetModuleAddressByPIDandName(
                self.pid, 'TekkenGame-Win64-Shipping.exe')
            if self.module_address == None:
                print(
                    "TekkenGame-Win64-Shipping.exe not found. Likely wrong process id. Reacquiring pid."
                )
                self.ReacquireEverything()
            elif (self.module_address != 0x140000000):
                print(
                    "Unrecognized location for TekkenGame-Win64-Shipping.exe module. Tekken.exe Patch? Wrong process id?"
                )
            else:
                print("Found TekkenGame-Win64-Shipping.exe")
                self.needReacquireModule = False

        if self.module_address != None:
            processHandle = OpenProcess(0x10, False, self.pid)
            try:
                player_data_base_address = self.GetValueFromAddress(
                    processHandle,
                    self.module_address + self.player_data_pointer_offset,
                    is64bit=True)
                if player_data_base_address == 0:
                    if not self.needReaquireGameState:
                        print("No fight detected. Gamestate not updated.")
                    self.needReaquireGameState = True

                else:
                    last_eight_frames = []

                    second_address_base = self.GetValueFromAddress(
                        processHandle, player_data_base_address, is64bit=True)
                    for i in range(
                            8
                    ):  # for rollback purposes, there are 8 copies of the game state, each one updatating once every 8 frames
                        potential_second_address = second_address_base + (
                            i *
                            MemoryAddressOffsets.rollback_frame_offset.value)
                        potential_frame_count = self.GetValueFromAddress(
                            processHandle, potential_second_address +
                            GameDataAddress.frame_count.value)
                        last_eight_frames.append(
                            (potential_frame_count, potential_second_address))

                    if rollback_frame >= len(last_eight_frames):
                        print(
                            "ERROR: requesting {} frame of {} long rollback frame"
                            .format(rollback_frame, len(last_eight_frames)))
                        rollback_frame = len(last_eight_frames) - 1

                    best_frame_count, player_data_second_address = sorted(
                        last_eight_frames, key=lambda x: -x[0])[rollback_frame]

                    p1_bot = BotSnapshot()
                    p2_bot = BotSnapshot()

                    player_data_frame = self.GetPlayerDataFrame(
                        processHandle, player_data_second_address)

                    for offset_enum in PlayerDataAddress:
                        #p1_value = self.GetValueFromAddress(processHandle, player_data_second_address + data.value, IsDataAFloat(data))
                        #p2_value = self.GetValueFromAddress(processHandle, player_data_second_address + MemoryAddressOffsets.p2_data_offset.value + data.value, IsDataAFloat(data))
                        p1_value = self.GetValueFromFrame(
                            player_data_frame, offset_enum.value, False)
                        p2_value = self.GetValueFromFrame(
                            player_data_frame, offset_enum.value, True)
                        p1_bot.player_data_dict[offset_enum] = p1_value
                        p2_bot.player_data_dict[offset_enum] = p2_value

                    #bot_facing = self.GetValueFromAddress(processHandle, player_data_second_address + GameDataAddress.facing.value, IsDataAFloat(offset_enum))
                    bot_facing = self.GetValueFromFrame(
                        player_data_frame, GameDataAddress.facing.value, False)

                    #for startingAddress in (PlayerDataAddress.x, PlayerDataAddress.y, PlayerDataAddress.z):
                    #    positionOffset = 32  # our xyz coordinate is 32 bytes, a 4 byte x, y, and z value followed by five 4 byte values that don't change
                    #    p1_coord_array = []
                    #    p2_coord_array = []
                    #    for i in range(16):
                    #        #p1_coord_array.append(self.GetValueFromAddress(processHandle, player_data_second_address + startingAddress.value + (i * positionOffset), True))
                    #        #p2_coord_array.append(self.GetValueFromAddress(processHandle, player_data_second_address + startingAddress.value + (i * positionOffset) + MemoryAddressOffsets.p2_data_offset.value, True))
                    #        p1_coord_array.append(self.GetValueFromFrame(player_data_frame, startingAddress.value + (i * positionOffset), False, True))
                    #        p2_coord_array.append(self.GetValueFromFrame(player_data_frame, startingAddress.value + (i * positionOffset), True, True))
                    #    p1_bot.player_data_dict[startingAddress] = p1_coord_array
                    #    p2_bot.player_data_dict[startingAddress] = p2_coord_array
                    #    #print("numpy.array([" + xyz_coord + "])")
                    ##print("--------------------")

                    if self.original_facing == None and best_frame_count > 0:
                        self.original_facing = bot_facing > 0

                    if self.needReaquireGameState:
                        print("Fight detected. Updating gamestate.")
                    self.needReaquireGameState = False

                    p1_bot.Bake()
                    p2_bot.Bake()
                    gameSnapshot = GameSnapshot(p1_bot, p2_bot,
                                                best_frame_count, bot_facing)
            finally:
                CloseHandle(processHandle)

        return gameSnapshot

    def GetNeedReacquireState(self):
        return self.needReaquireGameState