首页 > 修改教程 > GG修改器游戏过检测_游戏为什么能检测到gg修改器
GG修改器游戏过检测_游戏为什么能检测到gg修改器
  • gg修改器最新版
  • 大小:19.91MB版本:v2.92
  • 语言:简体中文系统:Android
绿色无毒,安全可靠!部分设备误报拦截请通过!

GG修改器游戏过检测_游戏为什么能检测到gg修改器

作者:佚名 来源:网友分享 日期:2024-04-27 10:18:38

大家好,今天小编为大家分享关于GG修改器游戏过检测_游戏为什么能检测到gg修改器的内容,赶快来一起来看看吧。

文章目录

环境准备

操纵键鼠

驱动安装 链接库加载 代码准备和游戏外测试

toolkit.py

游戏内测试

键鼠监听

武器识别

如何简单且高效判断是否在游戏内

如何简单且高效判断背包状态 无武器/1号武器/2号武器

如何简单且高效判断武器子弹类别

如何简单且高效判断武器名称

如何简单且高效判断武器模式 全自动/连发/单发

何时触发识别

压枪思路

组织数据

第一阶段实现 能自动识别出所有武器

cfg.py

toolkit.py

apex.py

第二阶段实现 能自动识别出所有武器并采用对应压枪参数执行压枪

第三阶段实现 放弃抖枪术 转常规后座抵消法

本文为下面参考文章的学习与实践

[原文] FPS游戏自动枪械识别+压枪(以PUBG为例)

环境准备

Python Windows 开发环境搭建

说明

基础环境

从 python 官网下载安装包并安装, 配置环境变量后, 在命令行内可以执行 python 命令

包管理工具

虚拟环境

python 基础环境下, 不同的依赖只能存在一个版本, 而不同的项目可能依赖了同一个包的不同版本, 这样的项目就可能无法在同一个 python 基础环境下运行. 基于基础环境创建的虚拟环境是相互隔离的, 第三方依赖包可根据项目要求自行下载, 不同项目运行在不同的虚拟环境几下就可以避免以来冲突等问题

虚拟环境只能基于本地存在的基础环境来创建, 会继承基础环境自带的库, 可以选择是否继承基础环境的已安装的第三方包

我觉得可以借鉴学习 java maven 的依赖管理理念, 告别虚拟环境

虚拟环境管理工具

Conda

Conda
Conda
Miniconda
Anaconda

Conda 是一个开源的 环境和包管理系统, 它可以创建并管理完全隔离的不同版本的 python 环境, 也可以创建并管理某 python 版本的完全隔离的虚拟环境, 用了它就不必再安装基础环境了

默认配置下, Conda 可以安装和管理由 Anaconda® 构建、审查和维护的数千个包。版本通常低于最新版

基础环境搭建

Python 官网
Python Windows 下载

到官网找到 Windows 最新版下载并安装

pip 是 Python 包管理工具,该工具提供了对Python 包的查找、下载、安装、卸载的功能。

什么是 Python Launcher?

python 安装程序会自动在 path 环境变量中添加这两条目录

目录结构说明

vc dll 结构体_python的安装目录结构

Miniconda 环境搭建

Miniconda

红字提示, 不推荐勾选添加环境变量, 因为可能会导致因路径被添加到靠前的位置而造成问题. 如果是首次安装 python 相关环境, 可以选择添加到环境变量选项, 如果已经有在用的其他配置了 PATH 的 Conda 或者 Python 则不建议

确实在用户环境变量 PATH 里加了很多目录, 查看这些目录下都有哪些 exe, 根目录下有 python.exe

使用方式

安装完成后, 从开始菜单中找到并打开 [Anaconda Prompt], 运行 [conda list] 命令, 如果正确安装, 则会出现已安装的包列表

常用命令

Command reference
conda常用命令:安装,更新,创建,激活,关闭,查看,卸载,删除,清理,重命名,换源,问题
Anaconda /Miniconda 常用命令CONDA集合

查看帮助

conda -h
conda --help
conda install -h
conda install --help
conda env -h
12345

查看信息

conda info # 包含 conda, python, pip 等, 还有当前在 conda 命令行中激活的环境
1

列出环境

conda env list
conda info -e
12

新安装的 Conda 只有 base 基础环境, 没有虚拟环境

配置源

windows环境下conda更换为国内清华镜像源

编辑用户目录下的 .condarc 文件即可更换 conda 默认源。

# Windows 用户无法直接创建名为 .condarc 的文件,需要先执行如下命令,生成该文件后再修改。C:Users用户名.condarc
# 设置搜索时显示通道地址
conda config --set show_channel_urls yes
123

修改文件内容

channels:
- https://mirrors.tuna.tsinghua./anaconda/pkgs/free/
- https://mirrors.tuna.tsinghua./anaconda/pkgs/main/
- https://mirrors.tuna.tsinghua./anaconda/cloud/menpo/
- https://mirrors.tuna.tsinghua./anaconda/cloud/bioconda/
- https://mirrors.tuna.tsinghua./anaconda/cloud/msys2/
- https://mirrors.tuna.tsinghua./anaconda/cloud/conda-forge/
- https://mirrors.tuna.tsinghua./anaconda/cloud/pytorch/
- defaults
show_channel_urls: true
12345678910

运行 conda clean -i 清除索引缓存,保证用的是镜像站提供的索引。

运行 conda config –show 确认源信息

虚拟环境

# 创建虚拟环境
conda create -h
conda create -n testenv
conda create -n testenv2 python=3.8
conda create -n testenv3 python=3.10.7 # 貌似不能下 Anaconda 库中没有的 python 版本, 表现就是转圈很久
conda create -p C:mrathenadevelopworkspacepycharmyolov5-6.2venv
# 查看环境包
conda list # 查看当前激活环境的包, 默认激活的是 base 基础环境
conda list -n testenv # 查看指定虚拟环境的包
# 激活虚拟环境
conda activate testenv
conda activate C:mrathenadevelopworkspacepycharmyolov5-6.2venv
# 反激活
conda deactivate # 退出虚拟环境, 重新激活 base 基础环境
# 删除虚拟环境
conda remove -n testenv --all
conda remove -p C:mrathenadevelopworkspacepycharmyolov5-6.2venv --all
1234567891011121314151617

如果报错如下, 检查是否有开代理工具, 关闭代理, 重开工具就可以了

CondaHTTPError: HTTP 000 CONNECTION FAILED for url <https://mirrors.tuna.tsinghua./anaconda/pkgs/free/win-64/current_repodata.json>
1

创建虚拟环境的注意点

创建虚拟环境时, 一定要指定一个不同于 base python 版本的 python 版本

不然的话, 新的虚拟环境基本等同于没有创建, 使用的仍然是 base 环境, 执行 pip install 会污染 base 环境, 真是恶心

创建了一个不同于 base python 版本的虚拟环境后, 在虚拟环境中会实打实包含类似 base 的目录结构, 也包含对应的 pip.exe, 这时候再执行 pip install 就不会影响到 base 环境了

IDE PyCharm

pycharm的virtualenv、pipenv、conda详解

下载最新版如 pycharm-professional-2021.2.3.exe

以下选项自选

创建工程时, 建议每个工程都创建新的虚拟环境, 通过 Conda

测试

在 conda 命令行中也能看到 pycharm 中创建的虚拟环境, 但是没有名字

插件

Chinese (Simplified) Language Pack / 中文语言包

寻找文档

Pypi

在官网输入包名, 找到包, 点进去, 里面一般都会有项目说明, GitHub, 文档等内容

conda create -n apex python=3.9
1

操纵键鼠

由于绝地求生屏蔽了硬件驱动外的其他鼠标输入,因此我们无法直接通过py脚本来控制游戏内鼠标操作。为了实现游戏内的鼠标下移,我使用了罗技鼠标的驱动(ghub),而py通过调用ghub的链接库文件,将指令操作传递给ghub,最终实现使用硬件驱动的鼠标指令输入给游戏,从而绕过游戏的鼠标输入限制。值得一提的是,我们只是通过py代码调用链接库的接口将指令传递给罗技驱动的,跟实际使用的是何种鼠标没有关系,所以即便用户使用的是雷蛇、卓威、双飞燕等鼠标,对下面的代码并无任何影响。

驱动安装 链接库加载 代码准备和游戏外测试

罗技驱动使用 LGS_9.02.65_X64(请自行找资源安装,官网新版罗技驱动没找到对应的链接库文件),链接库文件在项目链接里面可以找到。下面是载入链接库的代码。

罗技驱动分LGS(老)和GHub(新), 必须装指定版本的LGS驱动(如已安装GHub可能需要卸载), 不然要么报未安装, 要么初始化成功但调用无效

LGS_9.02.65_x64_Logitech.exe, 网盘下载
其他地址1
其他地址2

try:
gm = CDLL(r’./ghub_device.dll’)
gmok = gm.device_open() == 1
if not gmok:
print(’未安装ghub或者lgs驱动!!!’)
else:
print(’初始化成功!’)
except FileNotFoundError:
print(’缺少文件’)
123456789

装了该驱动后, 无需重启电脑, 当下就生效了. 遗憾的是, 没有对应的文档, 只能猜测参数了

toolkit.py

import time
from ctypes import CDLL

import win32api # conda install pywin32

try:
driver = CDLL(r’mouse.device.lgs.dll’) # 在Python的string前面加上‘r’, 是为了告诉编译器这个string是个raw string(原始字符串),不要转义backslash(反斜杠) ’’
ok = driver.device_open() == 1
if not ok:
print(’初始化失败, 未安装lgs/ghub驱动’)
except FileNotFoundError:
print(’初始化失败, 缺少文件’)

class Mouse:

@staticmethod
def move(x, y, absolute=False):
if ok:
mx, my = x, y
if absolute:
ox, oy = win32api.GetCursorPos()
mx = x - ox
my = y - oy
driver.moveR(mx, my, True)

@staticmethod
def down(code):
if ok:
driver.mouse_down(code)

@staticmethod
def up(code):
if ok:
driver.mouse_up(code)

@staticmethod
def click(code):
"""
:param code: 1:左键, 2:中键, 3:右键, 4:侧下键, 5:侧上键, 6:DPI键
:return:
"""
if ok:
driver.mouse_down(code)
driver.mouse_up(code)

class Keyboard:

@staticmethod
def press(code):
if ok:
driver.key_down(code)

@staticmethod
def release(code):
if ok:
driver.key_up(code)

@staticmethod
def click(code):
"""
:param code: ’a’-’z’:A键-Z键, ’0’-’9’:0-9, 其他的没猜出来
:return:
"""
if ok:
driver.key_down(code)
driver.key_up(code)

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970

游戏内测试

在游戏里面试过后, 管用, 但是不准, 猜测可能和游戏内鼠标灵敏度/FOV等有关系

from toolkit import Mouse
import pynput # conda install pynput

def onClick(x, y, button, pressed):
if not pressed:
if pynput.mouse.Button.x2 == button:
Mouse.move(100, 100)

mouseListener = pynput.mouse.Listener(on_click=onClick)
mouseListener.start()
mouseListener.join()
123456789101112

键鼠监听

前面说到,要实现压枪就要对各种配件、状态做出识别。那么在写识别的函数之前,我们先要解决的是何时识别的问题。如果识别使用多线程多进程的一直持续检测,无疑是一种巨大的开销,因此就需要对键盘、鼠标的状态进行监听。只有按下特定按键时,才触发特定相应的识别请求。

这里我使用的钩子是Pynput,其他可使用的库还有Pyhook3

Pynput 说明

def onClick(x, y, button, pressed):
print(f’button {button} {"pressed" if pressed else "released"} at ({x},{y})’)
if pynput.mouse.Button.left == button:
return False # 正常不要返回False, 这样会结束监听并停止监听线程, 在关闭程序前返回False就好了
listener = pynput.mouse.Listener(on_click=onClick)
listener.start()

def onRelease(key):
print(f’{key} released’)
if key == pynput.keyboard.Key.end:
return False # 正常不要返回False, 这样会结束监听并停止监听线程, 在关闭程序前返回False就好了
listener = pynput.keyboard.Listener(on_release=onRelease)
listener.start()
1234567891011121314

Listener中绑定on_press和on_release的函数( on_key_press、on_key_release),它们返回False的时候是结束监听,下文鼠标监听的函数同理,所以不要随便返回False

键盘的特殊按键采用keyboard.Key.tab这种写法,普通按键用keyboard.KeyCode.from_char(‘c’)这种写法

这里有一点非常坑,on_press和on_release的参数只能有一个key,这个key就是对应键盘按下的哪颗按键。但这是不足以满足我们的需求的,因为我们应该在钩子函数内部,在按下指定按键时对信号量做出修改,但因为参数的限制,我们无法把信号量传进函数内部,这里我也是想了很久,最后才想到用嵌套函数的写法解决这个问题。

另外,钩子函数本身是阻塞的。也就是说钩子函数在执行的过程中,用户正常的键盘/鼠标操作是无法输入的。所以在钩子函数里面必须写成有限的操作(即O(1)时间复杂度的代码),也就是说像背包内配件及枪械识别,还有下文会讲到的鼠标压枪这类时间开销比较大或者持续时间长的操作,都不适合写在钩子函数里面。这也解释了为什么在检测到Tab(打开背包)、鼠标左键按下时,为什么只是改变信号量,然后把这些任务丢给别的进程去做的原因。

武器识别

如何简单且高效判断是否在游戏内

找几个特征点取色判断, 血条左上角和生存物品框左下角

一般能用于取色的点, 它的颜色RGB都是相同的, 这种点的颜色非常稳定

我原本以为屏幕点取色应该不会超过1ms的耗时, 结果万万没想到, 取个色居然要1-10ms, 效率奇低, 暂无其他优雅方法

如何简单且高效判断背包状态 无武器/1号武器/2号武器

看武器边框上红色圈住的部分颜色, 灰色说明没有武器, 上下不同色, 说明使用2号武器, 上下同色说明使用1号武器

如何简单且高效判断武器子弹类别

可以和上面的放在一起, 同一个点直接判断出背包状态和武器子弹类别

如何简单且高效判断武器名称

在分类后的基础上, 通过 背包状态 确定要检查颜色的位置(1号位/2号位), 通过 武器子弹类别 缩小判断范围, 在每个武器的名字上找一个纯白色的点, 确保这个点只有这把武器是纯白色, 然后逐个对比

如何简单且高效判断武器模式 全自动/连发/单发

需要压枪的只有全自动和半自动两种模式的武器, 单发不需要压枪(后面有可能做自动单发, 到时候在考虑), 喷子和狙不需要压枪

所以需要找一个能区分三种模式的点(不同模式这个点的颜色不同但是稳定), 且这个点不能受和平和三重的特殊标记影响

收起武器, 部分武器可以通过[V]标判断, 放弃

何时触发识别

键盘 1/2/3/E/V 释放, 鼠标 右键 按下, 这个如果不影响开枪就这个了, 影响的话就改成侧下键. 键位和键在游戏内的功能不冲突的

压枪思路

apex 的压枪有两个思路, 因为 apex 不同武器的弹道貌似是固定的, 其他游戏也是??

我先试试 抖枪大法

组织数据

武器数据, 通过子弹类型分组, 组里的每个成员指定序号, 名称, 压枪参数等信息

配置数据, 按分辨率分组, 再按是否在游戏中, 是否有武器, 武器位置, 武器子弹类型, 武器索引等信息分类

信号数据, 程序运行时, 进程线程间通讯

第一阶段实现 能自动识别出所有武器

目前测试下来, 一波识别大概六七十毫秒的样子, 最多也不超过一百毫秒, 主要耗时在取色函数(1-10ms), 性能已经够用了

cfg.py


mode = ’mode’
name = ’name’
game = ’game’
data = ’data’
pack = ’pack’ # 背包
color = ’color’
point = ’point’
index = ’index’
bullet = ’bullet’ # 子弹
differ = ’differ’
positive = ’positive’ # 肯定的
negative = ’negative’ # 否定的

# 检测数据
detect = {
"3440:1440": {
game: [ # 判断是否在游戏中
{
point: (236, 1344), # 点的坐标, 血条左上角
color: 0x00FFFFFF # 点的颜色, 255, 255, 255
},
{
point: (2692, 1372), # 生存物品右下角
color: 0x959595 # 149, 149, 149
}
],
pack: { # 背包状态, 有无武器, 选择的武器
point: (2900, 1372), # 两把武器时, 1号武器上面边框分界线的上半部分, y+1 就是1号武器上面边框分界线的下半部分
color: 0x808080, # 无武器时, 灰色, 128, 128, 128
’0x447bb4’: 1, # 轻型弹药武器, 子弹类型: 1/2/3/4/5/6/None(无武器)
’0x839b54’: 2, # 重型弹药武器
’0x3da084’: 3, # 能量弹药武器
’0xce5f6e’: 4, # 狙击弹药武器
’0xf339b’: 5, # 霰弹枪弹药武器
’0x5302ff’: 6, # 空投武器
},
mode: { # 武器模式, 全自动/半自动/单发/其他
point: (3148, 1349),
’0xf8f8f8’: 1, # 全自动
’0xfefefe’: 2 # 半自动
},
name: { # 武器名称判断
color: 0x00FFFFFF,
’1’: { # 1号武器
’1’: [ # 轻型弹药武器
(2959, 1386), # 1: RE-45 自动手枪
(2970, 1385), # 2: 转换者冲锋枪
(2972, 1386), # 3: R-301 卡宾枪
(2976, 1386), # 4: R-99 冲锋枪
(2980, 1386), # 5: P2020 手枪
(2980, 1384), # 6: 喷火轻机枪
(2987, 1387), # 7: G7 侦查枪
(3015, 1386), # 8: CAR (轻型弹药)
],
’2’: [ # 重型弹药武器
(2957, 1385), # 1: 赫姆洛克突击步枪
(2982, 1385), # 2: 猎兽冲锋枪
(2990, 1393), # 3: 平行步枪
(3004, 1386), # 4: 30-30
(3015, 1386), # 5: CAR (重型弹药)
],
’3’: [ # 能量弹药武器
(2955, 1386), # 1: L-STAR能量机枪
(2970, 1384), # 2: 三重式狙击枪
(2981, 1385), # 3: 电能冲锋枪
(2986, 1384), # 4: 专注轻机枪
(2980, 1384), # 5: 哈沃克步枪
],
’4’: [ # 狙击弹药武器
(2969, 1395), # 1: 哨兵狙击步枪
(2999, 1382), # 2: 充能步枪
(2992, 1385), # 3: 辅助手枪
(3016, 1383), # 4: 长弓
],
’5’: [ # 霰弹枪弹药武器
(2957, 1384), # 1: 和平捍卫者霰弹枪
(2995, 1382), # 2: 莫桑比克
(3005, 1386), # 3: EVA-8
],
’6’: [ # 空投武器
(2958, 1384), # 1: 克雷贝尔狙击枪
(2983, 1384), # 2: 敖犬霰弹枪
(3003, 1383), # 3: 波塞克
(3014, 1383), # 4: 暴走
]
},
’2’: {
differ: 195
}
}
},
"2560:1440": {

},
"2560:1080": {

},
"1920:1080": {

}
}

# 武器数据
weapon = {
’1’: { # 轻型弹药武器
’1’: {
name: ’RE-45 自动手枪’,
},
’2’: {
name: ’转换者冲锋枪’,
},
’3’: {
name: ’R-301 卡宾枪’,
},
’4’: {
name: ’R-99 冲锋枪’,
},
’5’: {
name: ’P2020 手枪’,
},
’6’: {
name: ’喷火轻机枪’,
},
’7’: {
name: ’G7 侦查枪’,
},
’8’: {
name: ’CAR (轻型弹药)’,
}
},
’2’: { # 重型弹药武器
’1’: {
name: ’赫姆洛克突击步枪’,
},
’2’: {
name: ’猎兽冲锋枪’,
},
’3’: {
name: ’平行步枪’,
},
’4’: {
name: ’30-30’,
},
’5’: {
name: ’CAR (重型弹药)’,
}
},
’3’: { # 能量弹药武器
’1’: {
name: ’L-STAR能量机枪’,
},
’2’: {
name: ’三重式狙击枪’,
},
’3’: {
name: ’电能冲锋枪’,
},
’4’: {
name: ’专注轻机枪’,
},
’5’: {
name: ’哈沃克步枪’,
},
},
’4’: { # 狙击弹药武器
’1’: {
name: ’哨兵狙击步枪’,
},
’2’: {
name: ’充能步枪’,
},
’3’: {
name: ’辅助手枪’,
},
’4’: {
name: ’长弓’,
},
},
’5’: { # 霰弹弹药武器
’1’: {
name: ’和平捍卫者霰弹枪’,
},
’2’: {
name: ’莫桑比克’,
},
’3’: {
name: ’EVA-8’,
},
},
’6’: { # 空投武器
’1’: {
name: ’克雷贝尔狙击枪’,
},
’2’: {
name: ’敖犬霰弹枪’,
},
’3’: {
name: ’波塞克’,
},
’4’: {
name: ’暴走’,
},
}
}

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206

toolkit.py

import mss # pip install mss
import ctypes

from ctypes import CDLL

import cfg
from cfg import detect, weapon

# 全局 dll
user32 = ctypes.windll.user32
gdi32 = ctypes.windll.gdi32
hdc = user32.GetDC(None)

try:
driver = CDLL(r’mouse.device.lgs.dll’) # 在Python的string前面加上‘r’, 是为了告诉编译器这个string是个raw string(原始字符串),不要转义backslash(反斜杠) ’’
ok = driver.device_open() == 1
if not ok:
print(’初始化失败, 未安装lgs/ghub驱动’)
except FileNotFoundError:
print(’初始化失败, 缺少文件’)

class Mouse:

@staticmethod
def point():
return user32.GetCursorPos()

@staticmethod
def move(x, y, absolute=False):
if ok:
mx, my = x, y
if absolute:
ox, oy = user32.GetCursorPos()
mx = x - ox
my = y - oy
driver.moveR(mx, my, True)

@staticmethod
def moveHumanoid(x, y, absolute=False):
"""
仿真移动(还没做好)
"""
if ok:
ox, oy = user32.GetCursorPos() # 原鼠标位置
mx, my = x, y # 相对移动距离
if absolute:
mx = x - ox
my = y - oy
tx, ty = ox + mx, oy + my
print(f’({ox},{oy}), ({tx},{ty}), x:{mx},y:{my}’)
# 以绝对位置方式移动(防止相对位置丢失精度)
adx, ady = abs(mx), abs(my)
if adx <= ady:
# 水平方向移动的距离短
for i in range(1, adx):
ix = i if mx > 0 else -i
temp = int(ady / adx * abs(ix))
iy = temp if my > 0 else -temp
Mouse.move(ox + ix, oy + iy, absolute=True)
# time.sleep(0.001)
else:
# 垂直方向移动的距离短
for i in range(1, ady):
iy = i if my > 0 else -i
temp = int(adx / ady * abs(iy))
ix = temp if mx > 0 else -temp
Mouse.move(ox + ix, oy + iy, absolute=True)
# time.sleep(0.001)

@staticmethod
def down(code):
if ok:
driver.mouse_down(code)

@staticmethod
def up(code):
if ok:
driver.mouse_up(code)

@staticmethod
def click(code):
"""
:param code: 1:左键, 2:中键, 3:右键, 4:侧下键, 5:侧上键, 6:DPI键
:return:
"""
if ok:
driver.mouse_down(code)
driver.mouse_up(code)

class Keyboard:

@staticmethod
def press(code):
if ok:
driver.key_down(code)

@staticmethod
def release(code):
if ok:
driver.key_up(code)

@staticmethod
def click(code):
"""
键盘按键函数中,传入的参数采用的是键盘按键对应的键码
:param code: ’a’-’z’:A键-Z键, ’0’-’9’:0-9, 其他的没猜出来
:return:
"""
if ok:
driver.key_down(code)
driver.key_up(code)

class Monitor:
"""
显示器
"""
sct = mss.mss()

@staticmethod
def grab(region):
"""
region: tuple, (left, top, width, height)
pip install mss
"""
left, top, width, height = region
return Monitor.sct.grab(monitor={’left’: left, ’top’: top, ’width’: width, ’height’: height})

@staticmethod
def pixel(x, y):
"""
效率很低且不稳定, 单点检测都要耗时1-10ms
获取颜色, COLORREF 格式, 0x00FFFFFF
结果是int,
可以通过 print(hex(color)) 查看十六进制值
可以通过 print(color == 0x00FFFFFF) 进行颜色判断
"""
# hdc = user32.GetDC(None)
return gdi32.GetPixel(hdc, x, y)

class Resolution:
"""
分辨率
"""

@staticmethod
def display():
"""
显示分辨率
"""
w = user32.GetSystemMetrics(0)
h = user32.GetSystemMetrics(1)
return w, h

@staticmethod
def virtual():
"""
多屏幕组合的虚拟显示器分辨率
"""
w = user32.GetSystemMetrics(78)
h = user32.GetSystemMetrics(79)
return w, h

@staticmethod
def physical():
"""
物理分辨率
"""
# hdc = user32.GetDC(None)
w = gdi32.GetDeviceCaps(hdc, 118)
h = gdi32.GetDeviceCaps(hdc, 117)
return w, h

class Game:
"""
游戏工具
"""

@staticmethod
def game():
"""
是否在游戏内
太耗时了, 所以不能调的多了
"""
w, h = Monitor.Resolution.display()
data = detect.get(f’{w}:{h}’).get(cfg.game)
for item in data:
x, y = item.get(cfg.point)
if Monitor.pixel(x, y) != item.get(cfg.color):
return False
return True

@staticmethod
def index():
"""
武器索引和子弹类型索引
:return: 武器位索引, 1:1号位, 2:2号位, None:无武器, 拳头(这个暂时无法判断)
子弹类型索引, 1:轻型, 2:重型, 3:能量, 4:狙击, 5:霰弹, 6:空投, None:无武器
"""
w, h = Monitor.Resolution.display()
data = detect.get(f’{w}:{h}’).get(cfg.pack)
x, y = data.get(cfg.point)
color = Monitor.pixel(x, y)
if data.get(cfg.color) == color:
return None, None
else:
bullet = data.get(hex(color))
return (1, bullet) if color == Monitor.pixel(x, y + 1) else (2, bullet)

@staticmethod
def weapon(index, bullet):
"""
通过武器位和子弹类型识别武器, 参考:config.detect.name
:param index: 武器位, 1:1号位, 2:2号位
:param bullet: 子弹类型, 1:轻型, 2:重型, 3:能量, 4:狙击, 5:霰弹, 6:空投
:return:
"""
w, h = Monitor.Resolution.display()
data = detect.get(f’{w}:{h}’).get(cfg.name)
color = data.get(cfg.color)
if index == 1:
lst = data.get(str(index)).get(str(bullet))
for i in range(len(lst)):
x, y = lst[i]
if color == Monitor.pixel(x, y):
return i + 1
elif index == 2:
differ = data.get(str(index)).get(cfg.differ)
lst = data.get(str(1)).get(str(bullet))
for i in range(len(lst)):
x, y = lst[i]
if color == Monitor.pixel(x + differ, y):
return i + 1
return None

@staticmethod
def mode():
"""
武器模式
:return: 1:全自动, 2:半自动, None:其他
"""
w, h = Monitor.Resolution.display()
data = detect.get(f’{w}:{h}’).get(cfg.mode)
x, y = data.get(cfg.point)
color = Monitor.pixel(x, y)
return data.get(hex(color))

@staticmethod
def detect():
"""
决策是否需要压枪, 向信号量写数据
"""
if Game.game() is False:
print(’not in game’)

return
index, bullet = Game.index()
if (index is None) | (bullet is None):
print(’no weapon’)

return
if Game.mode() is None:
print(’not in full auto or semi auto mode’)

return
arms = Game.weapon(index, bullet)
if arms is None:
print(’detect weapon failure’)

return
# 检测通过, 需要压枪
print(weapon.get(str(bullet)).get(str(arms)).get(cfg.name))
return weapon.get(str(bullet)).get(str(arms)).get(cfg.name)

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277

apex.py

import time

import pynput # conda install pynput

import toolkit

ExitFlag = False

def down(x, y, button, pressed):
global ExitFlag
if ExitFlag:
print(ExitFlag)
return False # 结束监听线程
if pressed: # 按下
if pynput.mouse.Button.right == button:
toolkit.Game.detect()

mouseListener = pynput.mouse.Listener(on_click=down)
mouseListener.start()

def release(key):
if key == pynput.keyboard.Key.end:
print(’end’)
global ExitFlag
ExitFlag = True
return False
if key == pynput.keyboard.KeyCode.from_char(’1’):
toolkit.Game.detect()
elif key == pynput.keyboard.KeyCode.from_char(’2’):
toolkit.Game.detect()
elif key == pynput.keyboard.KeyCode.from_char(’3’):
toolkit.Game.detect()
elif key == pynput.keyboard.KeyCode.from_char(’e’):
toolkit.Game.detect()
elif key == pynput.keyboard.KeyCode.from_char(’v’):
toolkit.Game.detect()

keyboardListener = pynput.keyboard.Listener(on_release=release)
keyboardListener.start()
keyboardListener.join()

123456789101112131415161718192021222324252627282930313233343536373839404142434445

第二阶段实现 能自动识别出所有武器并采用对应压枪参数执行压枪

第三阶段实现 放弃抖枪术 转常规后座抵消法


1

以上就是关于GG修改器游戏过检测_游戏为什么能检测到gg修改器的全部内容,希望对大家有帮助。

相关文章

热门下载

大家还在搜