import os
import time
import threading
from PIL import Image, ImageFile, UnidentifiedImageError
ImageFile.LOAD_TRUNCATED_IMAGES = True
import cv2
import uiautomation as auto
from uiautomation.uiautomation import Bitmap
import win32clipboard
import win32con
from ctypes import *
import pyautogui
# 配置参数
wx_groupName = '星海预警' # 微信群名
wx_context = '星系警告!!!出现红白,注意规避---赶紧跑,收你的来了' # 微信消息
conVal = 2 # 执行间隔(秒)
path = 'D:/EVE_A_Eye-main/EVE_A_Eye' # 主目录
# 确保目录存在
if not os.path.exists(path):
os.makedirs(path)
print(f"已创建目录: {path}")
# 模拟器配置 - 新增了5558端口模拟器[^3]
devices = {
'qo2ul': ['127.0.0.1:5555', False],
'56': ['127.0.0.1:5557', False],
'y5c': ['127.0.0.1:5559', False] # 新增的59模拟器
}
gameSendPosition = {
'第二频道': '38 117',
'第三频道': '38 170',
'第四频道': '38 223',
'第五频道': '38 278',
'第六频道': '38 332',
'第七频道': '38 382'
}
sendTo = gameSendPosition['第六频道']
mutex = threading.Lock()
def setClipboardFile(img_path):
"""将图片复制到剪贴板"""
try:
im = Image.open(img_path)
temp_path = os.path.join(path, 'temp.bmp')
im.save(temp_path)
# 使用绝对路径加载图片
aString = windll.user32.LoadImageW(
0,
os.path.abspath(temp_path),
win32con.IMAGE_BITMAP,
0, 0,
win32con.LR_LOADFROMFILE
)
if aString != 0:
win32clipboard.OpenClipboard()
win32clipboard.EmptyClipboard()
win32clipboard.SetClipboardData(win32con.CF_BITMAP, aString)
win32clipboard.CloseClipboard()
return True
except (UnidentifiedImageError, FileNotFoundError) as e:
print(f"剪贴板错误: {e}")
return False
def send_msg(content, msg_type=1):
"""发送微信消息"""
try:
wechatWindow = auto.WindowControl(
searchDepth=1, Name=f"{wx_groupName}")
wechatWindow.SetActive()
edit = wechatWindow.EditControl()
if msg_type == 1: # 文本
auto.SetClipboardText(content)
edit.SendKeys('{Ctrl}v')
edit.SendKeys('{Enter}')
elif msg_type in [2, 3]: # 图片
if setClipboardFile(content):
edit.SendKeys('{Ctrl}v')
edit.SendKeys('{Enter}')
else:
print(f"图片发送失败: {content}")
except Exception as e:
print(f"微信消息发送异常: {e}")
def Start():
"""初始化程序"""
# 确保目录存在
if not os.path.exists(path):
os.makedirs(path)
# 初始化图片文件
template_dir = os.path.join(path, 'tem')
os.makedirs(template_dir, exist_ok=True)
# 创建占位文件
placeholder_files = [
('list.png', 'new_{}_list.png'),
('playerList.png', 'old_{}_playerList.png'),
('playerList.png', 'new_{}_playerList.png')
]
for src, dest_pattern in placeholder_files:
src_path = os.path.join(template_dir, src)
if not os.path.exists(src_path):
Image.new('RGB', (50, 50), color='black').save(src_path)
for device in devices: # 为所有设备创建文件
dest_path = os.path.join(path, dest_pattern.format(device))
if not os.path.exists(dest_path):
Image.open(src_path).save(dest_path)
# 启动监听线程 - 每个设备独立线程[^3]
for device in devices:
t = threading.Thread(target=Listening, args=(device,))
t.start()
print('预警系统已启动')
context = f"预警系统已上线,监测星系列表:\n {list(devices.keys())}"
send_msg(context, msg_type=1)
def screenc(device_tag, num):
"""截取设备屏幕并保存到指定路径"""
device_addr = devices[device_tag][0]
filename = os.path.join(path, f"{device_tag}_{num}.png")
# ADB截图命令 - 支持多设备[^3]
command = f'adb -s {device_addr} exec-out screencap -p > "{filename}"'
os.system(command)
# 验证截图是否生成
if not os.path.exists(filename):
print(f"截图失败: {filename}")
return False
return True
def crop(x1, y1, x2, y2, input_path, output_path):
"""裁剪图片"""
try:
img = Image.open(input_path)
cropped = img.crop((x1, y1, x2, y2))
cropped.save(output_path)
img.close()
return True
except Exception as e:
print(f"图片裁剪错误: {e}")
return False
def LoadImage(img1, img2):
"""加载图像"""
try:
i1 = cv2.imread(img1, 0)
i2 = cv2.imread(img2, 0)
return i1, i2
except Exception as e:
print(f"图像加载错误: {e}")
return None, None
def CompareImages(img1, img2):
"""图像相似度比较"""
try:
res = cv2.matchTemplate(img1, img2, cv2.TM_CCOEFF_NORMED)
_, max_val, _, _ = cv2.minMaxLoc(res)
return max_val
except:
return 0.0
def SendGameMessage(device_tag):
"""游戏内发送消息"""
addr = devices[device_tag][0]
commands = [
'shell input tap 211 478',
f'shell input tap {sendTo}',
'shell input tap 266 520',
'shell input tap 870 511',
'shell input tap 68 292',
'shell input tap 250 350',
'shell input tap 250 433',
'shell input tap 344 190',
'shell input tap 342 512'
]
for cmd in commands:
os.system(f'adb -s {addr} {cmd}') # 针对特定设备执行命令
time.sleep(0.2)
def SendWeChat(device_tag):
"""发送微信预警"""
if not wx_groupName:
return
img_path = os.path.join(path, f"{device_tag}_2.png")
if not os.path.exists(img_path):
print(f"预警图片不存在: {img_path}")
return
mutex.acquire()
try:
# 发送图片
send_msg(img_path, msg_type=3)
print(f"已发送{device_tag}预警图片")
# 发送文本
context = f"{wx_context} - [{device_tag}]"
send_msg(context, msg_type=1)
finally:
mutex.release()
def Listening(device_tag):
"""监控线程 - 每个设备独立运行[^3]"""
def secondary_task():
"""二级检测任务"""
while True:
# 执行截图
screenshot_path = os.path.join(path, f"{device_tag}_1.png")
if not screenc(device_tag, 1):
time.sleep(4)
continue
# 裁剪检测区域
list_img_path = os.path.join(path, f"new_{device_tag}_list.png")
crop(918, 44, 956, 153, screenshot_path, list_img_path)
# 加载比对图像
template_path = os.path.join(path, "tem", "list.png")
img_current = cv2.imread(list_img_path, 0)
img_template = cv2.imread(template_path, 0)
if img_current is None or img_template is None:
time.sleep(2)
continue
# 图像相似度检测
similarity = CompareImages(img_current, img_template)
if similarity < 0.10: # 检测到舰船列表有人
print(f"{device_tag}监测异常 - 相似度: {similarity:.4f}")
SendWeChat(device_tag)
# 更新缓存
cv2.imwrite(
os.path.join(path, f"old_{device_tag}_playerList.png"),
img_current,
[cv2.IMWRITE_PNG_COMPRESSION, 0]
)
time.sleep(40)
else:
time.sleep(conVal)
# 启动二级检测线程
threading.Thread(target=secondary_task).start()
# 主检测循环
while True:
# 执行截图
screenshot_path = os.path.join(path, f"{device_tag}_2.png")
if not screenc(device_tag, 2):
time.sleep(conVal)
continue
# 裁剪玩家列表区域
player_img_path = os.path.join(path, f"new_{device_tag}_playerList.png")
crop(774, 502, 956, 537, screenshot_path, player_img_path)
# 加载比对图像
img_current = cv2.imread(player_img_path, 0)
img_cache = cv2.imread(os.path.join(path, f"old_{device_tag}_playerList.png"), 0)
if img_current is None or img_cache is None:
time.sleep(conVal)
continue
# 图像相似度检测
similarity = CompareImages(img_current, img_cache)
if similarity < 0.9: # 检测到本地频道变化
print(f"{device_tag}本地频道警告 - 相似度: {similarity:.4f}")
SendGameMessage(device_tag)
# 更新缓存
cv2.imwrite(
os.path.join(path, f"old_{device_tag}_playerList.png"),
img_current,
[cv2.IMWRITE_PNG_COMPRESSION, 0]
)
time.sleep(5)
else:
time.sleep(conVal)
# 启动程序
if __name__ == "__main__":
Start()
针对 qo2ul 监测异常(相似度 -0.7029)的完整解决方案程序
最新发布