text: import ctypes, threading, sys
  import logging
  from time import sleep
  from ProcessMemoryHandle import *
  import BaseAddressOffset
  from concurrent.futures import ThreadPoolExecutor
  
  
  class Offset:
      def __init__(self, is_steam: bool):
          """基址偏移\n
          is_steam bool:是否为steam版 True 是|False 不是
          """
          index = 0 if is_steam else 1
          self.WORLD_OFFSET = BaseAddressOffset.WORLD_OFFSET_TUNPLE[index]
          self.BLIP_OFFSET = BaseAddressOffset.BLIP_OFFSET_TUNPLE[index]
          self.REPLAYINTERFACE_OFFSET = BaseAddressOffset.REPLAYINTERFACE_OFFSET_TUNPLE[index]
          self.LOCALSCRIPTS_OFFSET = BaseAddressOffset.LOCALSCRIPTS_OFFSET_TUNPLE[index]
          self.GLOBAL_OFFSET = BaseAddressOffset.GLOBAL_OFFSET_TUNPLE[index]
          self.PLAYERCOUNT_OFFSET = BaseAddressOffset.PLAYERCOUNT_OFFSET_TUNPLE[index]
          self.PICKUPDATA_OFFSET = BaseAddressOffset.PICKUPDATA_OFFSET_TUNPLE[index]
  
  
  class GTAVPublic:
      def __init__(self, handle: Handle, offset: Offset):
          self.handle = handle
          self.offset = offset
          self.__X_POINTER = (offset.WORLD_OFFSET, 0x8, 0x90)  # 摄像机x座标
  
      def __global(self, offset: int):
          return self.handle.getMemoryAddress([self.offset.GLOBAL_OFFSET + 8 * ((offset >> 0x12) & 0x3F), 8 * (offset & 0x3FFFF)])
  
      def __joaat(self, params: str):
          """joaat 计算\n
          return int
          """
          try:
              lib = ctypes.WinDLL("gtaLib.dll")
              lib.joaat.argtypes = (ctypes.c_char_p,)
              lib.joaat.restype = ctypes.c_uint
          except Exception as e:
              logging.warning(e)
              return None
          else:
              return lib.joaat(params.lower().encode())  # 全部小写后，转成C字符串
  
      @property
      def location(self):
          """摄像机位置"""
          x_addr = self.handle.getMemoryAddress(self.__X_POINTER)
          y_addr = x_addr + 0x4
          z_addr = x_addr + 0x8
          x = self.handle.readMemoryValue(x_addr, ctypes.c_float())
          y = self.handle.readMemoryValue(y_addr, ctypes.c_float())
          z = self.handle.readMemoryValue(z_addr, ctypes.c_float())
          return (x, y, z)
  
      @location.setter
      def location(self, pos: "tuple[float, float, float]"):
          x_addr = self.handle.getMemoryAddress(self.__X_POINTER)
          y_addr = x_addr + 0x4
          z_addr = x_addr + 0x8
          x, y, z = pos
          self.handle.writeMemoryValue(x_addr, ctypes.c_float(x))
          self.handle.writeMemoryValue(y_addr, ctypes.c_float(y))
          self.handle.writeMemoryValue(z_addr, ctypes.c_float(z))
  
      @property
      def sellinnonpublic(self):
          """非公开战局出货\n
          status bool: True 开|False 关
          """
          address = self.__global(2453009 + 744)
          i = self.handle.readMemoryValue(address, ctypes.c_int())
          # print(f"{address:0X}")
          return True if i == 0 else False
  
      @sellinnonpublic.setter
      def sellinnonpublic(self, status: bool):
          """非公开战局出货\n
          status bool: True 开|False 关
          """
          address = self.__global(2453009 + 744)
          if status is True:
              self.handle.writeMemoryValue(address, ctypes.c_int(0))  # 0开启
          else:
              self.handle.writeMemoryValue(address, ctypes.c_int(1))  # 1关闭
  
      @property
      def session(self):
          pass
  
      @session.setter
      def session(self, value: int):
          """战局切换\n
          value int: 战局模式\n
          1:创建公共战局\n
          11:仅限邀请战局\n
          10:单人战局
          """
          if value == -1:
              valueAddress = self.__global(1574587 + 2)
              triggerAddress = self.__global(1574587)
              self.handle.writeMemoryValue(valueAddress, ctypes.c_int(value))
              self.handle.writeMemoryValue(triggerAddress, ctypes.c_int(1))  # 设定为1触发切换战局
              sleep(0.2)
              self.handle.writeMemoryValue(triggerAddress, ctypes.c_int(0))
          else:
              valueAddress = self.__global(1575004)
              triggerAddress = self.__global(1574587)
              self.handle.writeMemoryValue(valueAddress, ctypes.c_int(value))
              self.handle.writeMemoryValue(triggerAddress, ctypes.c_int(1))  # 设定为1触发切换战局
              sleep(0.2)
              self.handle.writeMemoryValue(triggerAddress, ctypes.c_int(0))
  
      def anti_afk(self):
          """挂机防踢"""
          offset = 262145
          self.handle.writeMemoryValue(self.__global(offset + 87), ctypes.c_uint(2000000000))  # 默认120000
          self.handle.writeMemoryValue(self.__global(offset + 88), ctypes.c_uint(2000000000))  # 默认300000
          self.handle.writeMemoryValue(self.__global(offset + 89), ctypes.c_uint(2000000000))  # 默认600000
          self.handle.writeMemoryValue(self.__global(offset + 90), ctypes.c_uint(2000000000))  # 默认900000
          self.handle.writeMemoryValue(self.__global(offset + 7955), ctypes.c_uint(2000000000))  # 默认60000
          self.handle.writeMemoryValue(self.__global(offset + 7956), ctypes.c_uint(2000000000))  # 默认90000
          self.handle.writeMemoryValue(self.__global(offset + 7957), ctypes.c_uint(2000000000))  # 默认120000
          self.handle.writeMemoryValue(self.__global(offset + 7958), ctypes.c_uint(2000000000))  # 默认30000
  
  
  class Heist(GTAVPublic):
      def __init__(self, handle: Handle, offset: Offset):
          super().__init__(handle, offset)
          # function Cayo(player) return GA(1973496+823+56+player) end
          # function Casino(player) return GA(1966718+2325+player) end
          # function CasinoPotential(id) return GA(262145+28452+id) end
          # function CasinoAI(id) return GA(262145+28464+id) end
          # function Doomsday(player) return GA(1962755+812+50+player) end
          # function Apart(player) return GA(1934631+3008+player) end
          self.heist_tuple = (
              {"name": "Cayo", "offset": 1973496 + 823 + 56},
              {"name": "Casino", "offset": 1966718 + 2325},
              {"name": "CasinoPotential", "offset": 262145 + 28452},
              {"name": "CasinoAI", "offset": 262145 + 28464},
              {"name": "Doomsday", "offset": 1962755 + 812 + 50},
              {"name": "Apart", "offset": 1934631 + 3008},
          )
  
      @property
      def cuts(self):
          for h in self.heist_tuple:
              i = 1 + h["offset"]
              address = self._GTAVPublic__global(i)
              players1 = self.handle.readMemoryValue(address)
              players2 = self.handle.readMemoryValue(address + 0x8)
              players3 = self.handle.readMemoryValue(address + 0x10)
              players4 = self.handle.readMemoryValue(address + 0x18)
              if players1 + players2 + players3 + players4 == 100:
                  self.players1 = players1
                  self.players2 = players2
                  self.players3 = players3
                  self.players4 = players4
                  self.address1 = address
                  self.address2 = address + 0x8
                  self.address3 = address + 0x10
                  self.address4 = address + 0x18
                  return (players1, players2, players3, players4)
          return (0, 0, 0, 0)
  
      @cuts.setter
      def cuts(self, cutIn: tuple):
          if type(cutIn) != tuple or len(cutIn) != 4:
              return None
          self.cuts
          (players1, players2, players3, players4) = cutIn
          if players1 + players2 + players3 + players4 == 100:
              self.players1 = players1
              self.players2 = players2
              self.players3 = players3
              self.players4 = players4
              self.handle.writeMemoryValue(self.address1, ctypes.c_int(players1))
              self.handle.writeMemoryValue(self.address2, ctypes.c_int(players2))
              self.handle.writeMemoryValue(self.address3, ctypes.c_int(players3))
              self.handle.writeMemoryValue(self.address4, ctypes.c_int(players4))
  
  
  class Weather(GTAVPublic):
      def __init__(self, handle: Handle, offset: Offset):
          super().__init__(handle, offset)
  
      @property
      def snow(self):
          address = self._GTAVPublic__global(262145 + 4723)
          return self.handle.readMemoryValue(address, ctypes.c_int())
  
      @snow.setter
      def snow(self, value: int):
          address = self._GTAVPublic__global(262145 + 4723)
          self.handle.writeMemoryValue(address, ctypes.c_int(value))
  
  
  class Player(GTAVPublic):
      """玩家类\n
      涉及 玩家生命、护甲、通缉、位置、安全带、无敌模式、在载具上
      """
  
      def __init__(self, handle: Handle, offset: Offset):
          super().__init__(handle, offset)
          self.__LIFE_POINTER = (offset.WORLD_OFFSET, 0x8, 0x280)  # 血量 float
          self.__MAX_LIFE_POINTER = (offset.WORLD_OFFSET, 0x8, 0x2A0)  # 最大血量 float
          self.__GOD_MODE_POINTER = (offset.WORLD_OFFSET, 0x8, 0x189)  # 无敌模式 byte
          self.__VEST_POINTER = (offset.WORLD_OFFSET, 0x8, 0x1530)  # 护甲 float
          self.__COPS_POINTER = (offset.WORLD_OFFSET, 0x8, 0x10C8, 0x888)  # 通缉等级 int
          self.__SEATBELT_POINTER = (offset.WORLD_OFFSET, 0x8, 0x145C)  # 安全带 byte -56:关闭 -55:开启
          self.__IN_VEHICLE_POINTER = (offset.WORLD_OFFSET, 0x8, 0xD30, 0xC62)  # 判断玩家是否在载具上 byte 1:在 0:不在
          self.__X_POINTER = (offset.WORLD_OFFSET, 0x8, 0x30, 0x50)  # 当前玩家x坐标 float
  
      @property
      def life(self):
          address = self.handle.getMemoryAddress(self.__LIFE_POINTER)
          return self.handle.readMemoryValue(address, ctypes.c_float())
  
      @life.setter
      def life(self, value: float):
          address = self.handle.getMemoryAddress(self.__LIFE_POINTER)
          self.handle.writeMemoryValue(address, ctypes.c_float(value))
  
      @property
      def maxLife(self):
          address = self.handle.getMemoryAddress(self.__MAX_LIFE_POINTER)
          return self.handle.readMemoryValue(address, ctypes.c_float())
  
      @maxLife.setter
      def maxLife(self, value: float):
          address = self.handle.getMemoryAddress(self.__MAX_LIFE_POINTER)
          self.handle.writeMemoryValue(address, ctypes.c_float(value))
  
      @property
      def vest(self):
          address = self.handle.getMemoryAddress(self.__VEST_POINTER)
          return self.handle.readMemoryValue(address, ctypes.c_float())
  
      @vest.setter
      def vest(self, value: float):
          address = self.handle.getMemoryAddress(self.__VEST_POINTER)
          self.handle.writeMemoryValue(address, ctypes.c_float(value))
  
      @property
      def cops(self):
          address = self.handle.getMemoryAddress(self.__COPS_POINTER)
          return self.handle.readMemoryValue(address, ctypes.c_int())
  
      @cops.setter
      def cops(self, value: int):
          address = self.handle.getMemoryAddress(self.__COPS_POINTER)
          self.handle.writeMemoryValue(address, ctypes.c_int(value))
  
      @property
      def seatbelt(self):
          address = self.handle.getMemoryAddress(self.__SEATBELT_POINTER)
          return self.handle.readMemoryValue(address, ctypes.c_byte())
  
      @seatbelt.setter
      def seatbelt(self, status: bool):
          """安全带\n
          value int: -55:开启 | -56:关闭
          """
          if status is True:
              value = -55
          else:
              value = -16
          address = self.handle.getMemoryAddress(self.__SEATBELT_POINTER)
          self.handle.writeMemoryValue(address, ctypes.c_byte(value))
  
      @property
      def location(self):
          x_addr = self.handle.getMemoryAddress(self.__X_POINTER)
          y_addr = x_addr + 0x4
          z_addr = x_addr + 0x8
          x = self.handle.readMemoryValue(x_addr, ctypes.c_float())
          y = self.handle.readMemoryValue(y_addr, ctypes.c_float())
          z = self.handle.readMemoryValue(z_addr, ctypes.c_float())
          return (x, y, z)
  
      @location.setter
      def location(self, pos: "tuple[float, float, float]"):
          x_addr = self.handle.getMemoryAddress(self.__X_POINTER)
          y_addr = x_addr + 0x4
          z_addr = x_addr + 0x8
          x, y, z = pos
          self.handle.writeMemoryValue(x_addr, ctypes.c_float(x))
          self.handle.writeMemoryValue(y_addr, ctypes.c_float(y))
          self.handle.writeMemoryValue(z_addr, ctypes.c_float(z))
  
      @property
      def god_mode(self):
          address = self.handle.getMemoryAddress(self.__GOD_MODE_POINTER)
          i = self.handle.readMemoryValue(address, ctypes.c_ubyte())
          return True if i == 1 else False
  
      @god_mode.setter
      def god_mode(self, status: bool):
          """无敌模式\n
          1开启 0关闭
          """
          i = 1 if status is True else 0
          address = self.handle.getMemoryAddress(self.__GOD_MODE_POINTER)
          self.handle.writeMemoryValue(address, ctypes.c_ubyte(i))
  
      @property
      def in_vehicle(self):
          """判断是否在载具上\n
          0x0在 0x10不在
          """
          address = self.handle.getMemoryAddress(self.__IN_VEHICLE_POINTER)
          i = self.handle.readMemoryValue(address, ctypes.c_byte())
          return False if i == 0x0 else True
  
      def get_in_personal_vehicle(self):
          """进入个人载具"""
          if self.in_vehicle is False:
              addr = self._GTAVPublic__global(2671444 + 8)
              if addr > 0:
                  self.handle.writeMemoryValue(addr, ctypes.c_int(1))
                  sleep(1)
                  self.handle.writeMemoryValue(addr, ctypes.c_int(0))
  
      def generate_vehicle(self, vehicleName: str):
          """刷出载具\n
          vehicleName str: 载具调用名 [kurumo2骷髅马装甲版]
          """
          offset = 2725260
          heading0 = self.handle.readMemoryValue(self.handle.getMemoryAddress((self.offset.WORLD_OFFSET, 0x8, 0x30, 0x20)), ctypes.c_float())
          heading1 = self.handle.readMemoryValue(self.handle.getMemoryAddress((self.offset.WORLD_OFFSET, 0x8, 0x30, 0x24)), ctypes.c_float())
          x, y, z = self.location
          x = x - (heading1 * 5)
          y = y + (heading0 * 5)
          z = z + 0.5
          self.handle.writeMemoryValue(self._GTAVPublic__global(offset + 7 + 0), ctypes.c_float(x))
          self.handle.writeMemoryValue(self._GTAVPublic__global(offset + 7 + 1), ctypes.c_float(y))
          self.handle.writeMemoryValue(self._GTAVPublic__global(offset + 7 + 2), ctypes.c_float(z))
          self.handle.writeMemoryValue(self._GTAVPublic__global(offset + 27 + 66), ctypes.c_int(self._GTAVPublic__joaat(vehicleName)))
          self.handle.writeMemoryValue(self._GTAVPublic__global(offset + 27 + 28), ctypes.c_int(1))
          self.handle.writeMemoryValue(self._GTAVPublic__global(offset + 27 + 60), ctypes.c_int(1))
          self.handle.writeMemoryValue(self._GTAVPublic__global(offset + 27 + 95), ctypes.c_int(14))
          self.handle.writeMemoryValue(self._GTAVPublic__global(offset + 27 + 94), ctypes.c_int(2))
          self.handle.writeMemoryValue(self._GTAVPublic__global(offset + 5), ctypes.c_int(1))
          self.handle.writeMemoryValue(self._GTAVPublic__global(offset + 2), ctypes.c_int(1))
          self.handle.writeMemoryValue(self._GTAVPublic__global(offset + 3), ctypes.c_int(0))
          self.handle.writeMemoryValue(self._GTAVPublic__global(offset + 27 + 74), ctypes.c_int(1))
          self.handle.writeMemoryValue(self._GTAVPublic__global(offset + 27 + 75), ctypes.c_int(1))
          self.handle.writeMemoryValue(self._GTAVPublic__global(offset + 27 + 76), ctypes.c_int(0))
          self.handle.writeMemoryValue(self._GTAVPublic__global(offset + 27 + 60), ctypes.c_int(4030726305))
          self.handle.writeMemoryValue(self._GTAVPublic__global(offset + 27 + 5), ctypes.c_int(-1))
          self.handle.writeMemoryValue(self._GTAVPublic__global(offset + 27 + 6), ctypes.c_int(-1))
          self.handle.writeMemoryValue(self._GTAVPublic__global(offset + 27 + 7), ctypes.c_int(-1))
          self.handle.writeMemoryValue(self._GTAVPublic__global(offset + 27 + 8), ctypes.c_int(-1))
          self.handle.writeMemoryValue(self._GTAVPublic__global(offset + 27 + 19), ctypes.c_int(4))
          self.handle.writeMemoryValue(self._GTAVPublic__global(offset + 27 + 21), ctypes.c_int(4))
          self.handle.writeMemoryValue(self._GTAVPublic__global(offset + 27 + 22), ctypes.c_int(3))
          self.handle.writeMemoryValue(self._GTAVPublic__global(offset + 27 + 23), ctypes.c_int(3))
          self.handle.writeMemoryValue(self._GTAVPublic__global(offset + 27 + 24), ctypes.c_int(58))
          self.handle.writeMemoryValue(self._GTAVPublic__global(offset + 27 + 26), ctypes.c_int(5))
          self.handle.writeMemoryValue(self._GTAVPublic__global(offset + 27 + 26), ctypes.c_int(1))
          self.handle.writeMemoryValue(self._GTAVPublic__global(offset + 27 + 65), ctypes.c_int(2))
          self.handle.writeMemoryValue(self._GTAVPublic__global(offset + 27 + 69), ctypes.c_int(-1))
          self.handle.writeMemoryValue(self._GTAVPublic__global(offset + 27 + 33), ctypes.c_int(-1))
          self.handle.writeMemoryValue(self._GTAVPublic__global(offset + 27 + 25), ctypes.c_int(8))
          self.handle.writeMemoryValue(self._GTAVPublic__global(offset + 27 + 19), ctypes.c_int(-1))
          self.handle.writeMemoryValue(self._GTAVPublic__global(offset + 27 + 77) + 1, ctypes.c_byte(2))
          self.handle.writeMemoryValue(self._GTAVPublic__global(offset + 27 + 77), ctypes.c_int(self._GTAVPublic__joaat(vehicleName)))
          # self.handle.writeMemoryValue(self._GTAVPublic__global(offset + 27 + 1), ctypes.create_string_buffer("KUN SHAO".encode()))
          self.handle.writeMemoryValue(self._GTAVPublic__global(offset + 27 + 1), ctypes.c_buffer(b"KUN SHAO"), 8)
  
      def generate_vehicle2(self, vehicleName: str):
          """刷出载具\n
          vehicleName str: 载具调用名 [kurumo2骷髅马装甲版]
          """
          offset = 2725260
          heading0 = self.handle.readMemoryValue(self.handle.getMemoryAddress((self.offset.WORLD_OFFSET, 0x8, 0x30, 0x20)), ctypes.c_float())
          heading1 = self.handle.readMemoryValue(self.handle.getMemoryAddress((self.offset.WORLD_OFFSET, 0x8, 0x30, 0x24)), ctypes.c_float())
          x, y, z = self.location
          x = x - (heading1 * 5)
          y = y + (heading0 * 5)
          z = z + 0.5
          self.handle.writeMemoryValue(self._GTAVPublic__global(offset + 27 + 66), ctypes.c_int(self._GTAVPublic__joaat(vehicleName)))
          self.handle.writeMemoryValue(self._GTAVPublic__global(offset + 121), ctypes.c_int(2))
          self.handle.writeMemoryValue(self._GTAVPublic__global(offset + 122), ctypes.c_int(14))
          self.handle.writeMemoryValue(self._GTAVPublic__global(offset + 27 + 6), ctypes.c_byte(-1))
          self.handle.writeMemoryValue(self._GTAVPublic__global(offset + 27 + 5), ctypes.c_byte(-1))
          self.handle.writeMemoryValue(self._GTAVPublic__global(offset + 7 + 0), ctypes.c_float(x))
          self.handle.writeMemoryValue(self._GTAVPublic__global(offset + 7 + 1), ctypes.c_float(y))
          self.handle.writeMemoryValue(self._GTAVPublic__global(offset + 7 + 2), ctypes.c_float(z))
          self.handle.writeMemoryValue(self._GTAVPublic__global(offset + 27 + 10), ctypes.c_int(1))
          self.handle.writeMemoryValue(self._GTAVPublic__global(offset + 27 + 11), ctypes.c_int(1))
          self.handle.writeMemoryValue(self._GTAVPublic__global(offset + 27 + 12), ctypes.c_int(1))
          self.handle.writeMemoryValue(self._GTAVPublic__global(offset + 27 + 13), ctypes.c_int(1))
          self.handle.writeMemoryValue(self._GTAVPublic__global(offset + 27 + 14), ctypes.c_int(1))
          self.handle.writeMemoryValue(self._GTAVPublic__global(offset + 27 + 15), ctypes.c_int(1))
          self.handle.writeMemoryValue(self._GTAVPublic__global(offset + 27 + 16), ctypes.c_int(1))
          self.handle.writeMemoryValue(self._GTAVPublic__global(offset + 27 + 17), ctypes.c_int(1))
          self.handle.writeMemoryValue(self._GTAVPublic__global(offset + 27 + 18), ctypes.c_int(1))
          self.handle.writeMemoryValue(self._GTAVPublic__global(offset + 27 + 19), ctypes.c_int(1))
          self.handle.writeMemoryValue(self._GTAVPublic__global(offset + 27 + 20), ctypes.c_int(1))
          self.handle.writeMemoryValue(self._GTAVPublic__global(offset + 27 + 21), ctypes.c_int(4))
          self.handle.writeMemoryValue(self._GTAVPublic__global(offset + 27 + 22), ctypes.c_int(3))
          self.handle.writeMemoryValue(self._GTAVPublic__global(offset + 27 + 23), ctypes.c_int(3))
          self.handle.writeMemoryValue(self._GTAVPublic__global(offset + 27 + 24), ctypes.c_int(57))
          self.handle.writeMemoryValue(self._GTAVPublic__global(offset + 27 + 25), ctypes.c_int(4))
          self.handle.writeMemoryValue(self._GTAVPublic__global(offset + 27 + 26), ctypes.c_int(5))
          self.handle.writeMemoryValue(self._GTAVPublic__global(offset + 27 + 28), ctypes.c_int(1))
          self.handle.writeMemoryValue(self._GTAVPublic__global(offset + 27 + 30), ctypes.c_int(1))
          self.handle.writeMemoryValue(self._GTAVPublic__global(offset + 27 + 32), ctypes.c_int(1))
          self.handle.writeMemoryValue(self._GTAVPublic__global(offset + 27 + 65), ctypes.c_int(1))
          self.handle.writeMemoryValue(self._GTAVPublic__global(offset + 2), ctypes.c_int(1))
          self.handle.writeMemoryValue(self._GTAVPublic__global(offset + 5), ctypes.c_int(1))
  
  
  class Vehicle(GTAVPublic):
      """载具类\n
      涉及 载具血量、能力、位置
      """
  
      def __init__(self, handle: Handle, offset: Offset):
          super().__init__(handle, offset)
          self.__LIFE_POINTER = (offset.WORLD_OFFSET, 0x8, 0xD30, 0x280)  # 载具血量
          self.__X_POINTER = (offset.WORLD_OFFSET, 0x8, 0xD30, 0x30, 0x50)  # 当前载具x坐标 float
          self.__ABILITY_POINTER = (offset.WORLD_OFFSET, 0x8, 0xD30, 0x20, 0x58B)  # 载具能力 int
  
      @property
      def life(self):
          address = self.handle.getMemoryAddress(self.__LIFE_POINTER)
          return self.handle.readMemoryValue(address, ctypes.c_float())
  
      @life.setter
      def life(self, value: float):
          """载具血量\n
          value float:血量 满血1000
          """
          address = self.handle.getMemoryAddress(self.__LIFE_POINTER)
          self.handle.writeMemoryValue(address, ctypes.c_float(value))
  
      @property
      def location(self):
          x_addr = self.handle.getMemoryAddress(self.__X_POINTER)
          y_addr = x_addr + 0x4
          z_addr = x_addr + 0x8
          x = self.handle.readMemoryValue(x_addr, ctypes.c_float())
          y = self.handle.readMemoryValue(y_addr, ctypes.c_float())
          z = self.handle.readMemoryValue(z_addr, ctypes.c_float())
          return (x, y, z)
  
      @location.setter
      def location(self, pos: "tuple[float, float, float]"):
          x_addr = self.handle.getMemoryAddress(self.__X_POINTER)
          y_addr = x_addr + 0x4
          z_addr = x_addr + 0x8
          x, y, z = pos
          self.handle.writeMemoryValue(x_addr, ctypes.c_float(x))
          self.handle.writeMemoryValue(y_addr, ctypes.c_float(y))
          self.handle.writeMemoryValue(z_addr, ctypes.c_float(z))
  
      @property
      def ability(self):
          pass
  
      @ability.setter
      def ability(self, i: int):
          """载具特殊能力\n
          value int: 0x0:普通 |0x40:助推器 |0x20:跳跃
          """
          if i == 0:
              value = 0x0
          elif i == 1:
              value = 0x40
          elif i == 2:
              value = 0x20
          address = self.handle.getMemoryAddress(self.__ABILITY_POINTER)
          self.handle.writeMemoryValue(address, ctypes.c_byte(value), 2)
          if value == 0x40:
              """助推器恢复速度"""
              address1 = self.handle.getMemoryAddress([self.offset.WORLD_OFFSET, 0x8, 0xD30, 0x324])
              self.handle.writeMemoryValue(address1, ctypes.c_float(10))
  
  
  class GTAVHax(GTAVPublic):
      def __init__(self, handle: Handle, offset: Offset):
          super().__init__(handle, offset)
  
      def stat_value(self, stat: str, value: int):
          """stat value GTAHax效果\n
          stat str: MPx_XXXX\n
          value int: 数值
          """
          if stat is None or value is None:
              return None
          try:
              PlayerNumber = self.handle.readMemoryValue(self._GTAVPublic__global(1574907))
              stat_p = stat.replace("MPx", f"MP{PlayerNumber}")
              newHash = self._GTAVPublic__joaat(stat_p)
          except Exception as e:
              logging.warning(e)
              return None
          try:
              addrLaunch = self._GTAVPublic__global(1644209 + 1139)
              addrHash = self._GTAVPublic__global(1655444 + 4)
              oldHash = self.handle.readMemoryValue(addrHash)
              addrValue = self._GTAVPublic__global(1020252 + 5526)
              oldValue = self.handle.readMemoryValue(addrValue)
              self.handle.writeMemoryValue(addrHash, ctypes.c_uint(newHash))
              self.handle.writeMemoryValue(addrValue, ctypes.c_int(value))
              self.handle.writeMemoryValue(addrLaunch, ctypes.c_int(-1))
              sleep(1)
              self.handle.writeMemoryValue(addrHash, ctypes.c_uint(oldHash))
              self.handle.writeMemoryValue(addrValue, ctypes.c_int(oldValue))
          except Exception as e:
              logging.warning(e)
              return None
  
      def set_level_30(self):
          """设置等级30级"""
          stats = (
              ("MPx_CHAR_ABILITY_1_UNLCK", 1),
              ("MPx_CHAR_ABILITY_2_UNLCK", 1),
              ("MPx_CHAR_ABILITY_3_UNLCK", 1),
              ("MPx_CHAR_FM_ABILITY_1_UNLCK", 1),
              ("MPx_CHAR_FM_ABILITY_2_UNLCK", 1),
              ("MPx_CHAR_FM_ABILITY_3_UNLCK", 1),
              ("MPx_CHAR_SET_RP_GIFT_ADMIN", 177100),  # 30级别
          )
          for tp in stats:
              self.stat_value(tp[0], tp[1])
          sleep(1)
          self.change_session(1)
  
  
  def withThread(function):
      """线程的饰器"""
  
      def Threads(*args):
          threading.Thread(target=function, args=args, daemon=True).start()
  
      return Threads
  
  
  class Data:
      """寄存状态数据"""
  
      def __init__(self):
          self.auto_cure = False
          self.seatbelt = False
          self.antiAFK = False
          self.god_mode = False
  
  
  class GTAV:
      def __init__(self):
          self.threadPool = ThreadPoolExecutor(max_workers=6)  # 最多6线程
          self.handle = Handle()
          hwnd = self.handle.find_window("grcWindow", "Grand Theft Auto V")
          if hwnd == 0:
              logging.error("获取窗口句柄失败")
              sys.exit()
          self.handle.get_window_thread_process_id(hwnd)
          if self.handle.pid == 0:
              logging.error("获取游戏句柄失败")
              sys.exit()
          self.handle.hProcess = self.handle.open_process(0x1F0FFF, c_bool(False), self.handle.pid)
          self.handle.addrProcess = self.handle.enum_process_modules(self.handle.hProcess)[0]
          is_steam = True if self.handle.query_module("steam_api64.dll") != 0 else False
          self.offset = Offset(is_steam)
          self.gtavpublic = GTAVPublic(self.handle, self.offset)
          self.weather = Weather(self.handle, self.offset)
          self.player = Player(self.handle, self.offset)
          self.vehicle = Vehicle(self.handle, self.offset)
          self.heist = Heist(self.handle, self.offset)
          self.hax = GTAVHax(self.handle, self.offset)
          self.read = self.handle.readMemoryValue
          self.write = self.handle.writeMemoryValue
          self.readPointer = self.handle.getMemoryAddress
          self.data = Data()
          self.refresh_data()
  
      def __global(self, offset: int):
          # r_dword_ptr res = read<r_dword_ptr>((r_dword_ptr)m_mod + ADDRESS_GLOBAL + 8 * ((val >> 0x12) & 0x3F));
          # return 8 * (val & 0x3FFFF) + res;
          return self.handle.getMemoryAddress([self.__GLOBAL_OFFSET + 8 * ((offset >> 0x12) & 0x3F), 8 * (offset & 0x3FFFF)])
  
      def __joaat(self, params: str):
          """joaat 计算\n
          return int
          """
          try:
              lib = ctypes.WinDLL("gtaLib.dll")
              lib.joaat.argtypes = (ctypes.c_char_p,)
              lib.joaat.restype = ctypes.c_uint
          except Exception as e:
              logging.warning(e)
              return None
          else:
              return lib.joaat(params.lower().encode())  # 全部小写后，转成C字符串
  
      @withThread
      def leave_me_alone(self, t: float = 0):
          """挂起进程卡单人公开战局\n
          t:float 秒钟
          """
          self.handle.suspend_process()
          sleep(t)
          self.handle.resume_process()
  
      @property
      def navigation_location(self):
          """获取导航定位座标\n
          return tunple[float,float,float]:(x, y ,z)
          """
          for i in range(2000):
              addr = self.handle.readMemoryValue(self.handle.addrProcess + self.offset.BLIP_OFFSET + i * 8, ctypes.c_ulonglong(), 8)
              if addr <= 0:
                  continue
              else:
                  if self.handle.readMemoryValue(addr + 0x40) == 0x8 and self.handle.readMemoryValue(addr + 0x48, ctypes.c_byte()) == 0x54:
                      x = self.handle.readMemoryValue(addr + 0x10, ctypes.c_float())
                      y = self.handle.readMemoryValue(addr + 0x14, ctypes.c_float())
                      z = self.handle.readMemoryValue(addr + 0x18, ctypes.c_float())
                      return (x, y, z)
          return (64000.0, 64000.0, 64000.0)
  
      def navigation_teleport(self):
          """导航传送"""
          self.teleport(self.navigation_location)
  
      @property
      def target_location(self):
          """获取任务点座标\n
          return tunple[float,float,float]:(x, y ,z)
          """
          for i in range(2000):
              addr = self.handle.readMemoryValue(self.handle.addrProcess + self.offset.BLIP_OFFSET + i * 8, ctypes.c_ulonglong(), 8)
              if addr <= 0:
                  continue
              else:
                  buf0 = self.handle.readMemoryValue(addr + 0x40)
                  buf1 = self.handle.readMemoryValue(addr + 0x48, ctypes.c_byte())
                  if buf0 == 1 and (buf1 == 5 or buf1 == 60 or buf1 == 66):
                      x = self.handle.readMemoryValue(addr + 0x10, ctypes.c_float())
                      y = self.handle.readMemoryValue(addr + 0x14, ctypes.c_float())
                      z = self.handle.readMemoryValue(addr + 0x18, ctypes.c_float())
                      return (x, y, z)
          return (64000.0, 64000.0, 64000.0)
  
      def target_teleport(self):
          """目标黄点传送"""
          self.teleport(self.target_location)
  
      def teleport(self, pos: tuple):
          """座标传送"""
          (x, y, z) = pos
          if (x, y, z) == (64000.0, 64000.0, 64000.0):
              return None
          try:
              z = -255.0 + 0.5 if z == 20.0 else z + 0.5
              if self.player.in_vehicle is True:
                  self.vehicle.location = (x, y, z)
              else:
                  self.player.location = (x, y, z)
              self.gtavpublic.location = (x, y, z)
          except Exception as e:
              logging.warning(e)
              return None
  
      def forward(self):
          """向前移动"""
          if self.player.in_vehicle is True:
              return None
          heading0 = self.handle.readMemoryValue(self.handle.getMemoryAddress((self.offset.WORLD_OFFSET, 0x8, 0x30, 0x20)), ctypes.c_float())
          heading1 = self.handle.readMemoryValue(self.handle.getMemoryAddress((self.offset.WORLD_OFFSET, 0x8, 0x30, 0x30)), ctypes.c_float())
          x, y, z = self.player.location
          x = x + heading1 * 2.5
          y = y + heading0 * 2.5
          try:
              self.player.location = (x, y, z)
              self.gtavpublic.location = (x, y, z)
          except Exception as e:
              logging.error(e)
              sys.exit()
  
      def set_ammo_type(self, value: int):
          """设置子弹类型\n
          value int: -1 默认| 18 MK2爆炸子弹
          """
          address0 = self.readPointer([self.offset.WORLD_OFFSET, 0x8, 0x10D8, 0x20, 0x24])
          address1 = address0 - 4
          impact = 5 if value == 18 else 3
          self.write(address1, ctypes.c_byte(impact), 2)
          self.write(address0, ctypes.c_int(value))
  
      def set_full_ammo(self):
          """补充当前枪械武器弹药\n
          不要子弹数量在持续变化中
          """
          address0 = self.readPointer([self.offset.WORLD_OFFSET, 0x8, 0x50, 0x48, 0x8, 0x180, 0x2E0, 0x54])
          if self.read(address0) == 0:
              return None
          address1 = address0 + 2
  
          def add_ammo():
              for i in range(100):
                  self.write(address1, ctypes.c_uint(9999), 2)
                  self.write(address0, ctypes.c_uint(9999), 2)
  
          self.threadPool.submit(add_ammo)
  
      @withThread
      def refresh_data(self):
          """更新状态数据"""
          # return None
          if self.player.maxLife < 200 or self.player.maxLife > 328:
              logging.warning("最大血量不在200-328范围内，可能版本基址过旧，最好不要使用。")
              sys.exit()
          try:
              while True:
                  if self.data.auto_cure is True:
                      self.player.life = self.player.maxLife
                      self.player.vest = 50
                  self.player.seatbelt = self.data.seatbelt  # 安全带
                  if self.data.antiAFK is True:  # 挂机防踢
                      self.gtavpublic.anti_afk()
                  self.player.god_mode = self.data.god_mode  # 无敌自检
                  sleep(0.1)
          except Exception as e:
              logging.error(e)
              sys.exit()
  
      def apartment_heist(self):
          """跳过公寓抢劫任务前置"""
          self.hax.stat_value("MPx_HEIST_PLANNING_STAGE", -1)  # 跳过准备前置 4人开始进入动画后触发生效
  
      def doomsday_cooldown(self):
          """末日3冷却"""
          self.hax.stat_value("MPx_HEISTCOOLDOWNTIMER2", -1)  # 末日3冷却
  
      def doomsday(self):
          """跳过末日前置"""
          self.hax.stat_value("MPx_GANGOPS_FLOW_MISSION_PROG", -1)  # 跳过前置，M-设施管理-关闭后开启抢劫策划大屏
  
      def casino(self):
          """赌场豪劫"""
          self.hax.stat_value("MPx_H3OPT_TARGET", 3)  # 目标钻石
  
      def perico(self):
          """佩里克岛豪劫"""
          stats = (
              ("MPx_H4CNF_BOLTCUT", 6276),  # 螺栓切割器
              ("MPx_H4CNF_UNIFORM", 4386),  # 保安服
              ("MPx_H4CNF_GRAPPEL", 16936),  # 抓钩
              ("MPx_H4CNF_TROJAN", 1),  # 卡车
              ("MPx_H4LOOT_CASH_I", 0),
              ("MPx_H4LOOT_CASH_I_SCOPED", 0),
              ("MPx_H4LOOT_CASH_C", 0),
              ("MPx_H4LOOT_CASH_C_SCOPED", 0),
              ("MPx_H4LOOT_COKE_I", 0),
              ("MPx_H4LOOT_COKE_I_SCOPED", 0),
              ("MPx_H4LOOT_COKE_C", 0),
              ("MPx_H4LOOT_COKE_C_SCOPED", 0),
              ("MPx_H4LOOT_GOLD_I", 16777215),
              ("MPx_H4LOOT_GOLD_I_SCOPED", 16777215),
              ("MPx_H4LOOT_GOLD_C", 255),
              ("MPx_H4LOOT_GOLD_C_SCOPED", 255),
              ("MPx_H4LOOT_WEED_I", 0),
              ("MPx_H4LOOT_WEED_I_SCOPED", 0),
              ("MPx_H4LOOT_WEED_C", 0),
              ("MPx_H4LOOT_WEED_C_SCOPED", 0),
              ("MPx_H4LOOT_PAINT", 0),
              ("MPx_H4LOOT_PAINT_SCOPED", 0),
              ("MPx_H4CNF_TARGET", 5),  # 主要目标设为猎豹雕像
              ("MPx_H4_PROGRESS", 131055),  # 困难模式
          )
          for tp in stats:
              self.hax.stat_value(tp[0], tp[1])
  
  
  if __name__ == "__main__":
      logging.basicConfig(format="%(asctime)s,%(levelname)s,%(module)s,%(funcName)s,%(lineno)d,%(message)s")
      gta = GTAV()
      # gta.player.life = 0
      # gta.player.god_mode = True  # 无敌模式
      # gta.player.generate_vehicle("lazer")