CyberController手机外挂番外篇:源代码的二次修改

news2025/7/13 2:40:27

文章目录

  • 前言
  • 调试过程中的疑问
    • 为什么一段时间不使用CyberController,翻译就无法触发了?
    • 为什么连接成功了,但却依然无法进行语音识别和翻译?
    • 多长时间TCP连接就会挂掉
    • 连接正常与断开连接有什么区别?
    • 不停进行翻译,会断掉TCP连接吗?
    • 如何解决120秒socket通讯连接断掉的问题?
    • 为什么可以进行翻译,但是无法进行语音输入?
    • NameError: name 'key_down' is not defined
  • 修改
    • 修改翻译的触发快捷键
    • 关掉不停的打印按键
    • 关掉手机上麦克风图标
    • 电脑端翻译的代码是哪一段?
    • 手动往手机端发送数据
    • 手动进行保活
    • 自动进行保活
    • 这样只要电脑和手机连着同一局域网的WiFi,无论过多久都不会把这个TCP连接来杀掉

前言

本教程是 CyberController手机外挂 的番外篇,- CyberController的源码二次修改

  • 之前已经可以跑通demo了,但是有一些功能不符合自己的需求,需要进行进一步的修改,这部分因为涉及到源码修改,我没有办法仔细的讲解为什么那么修改,所以就需要读者有一定的Python基础了

调试过程中的疑问

为什么一段时间不使用CyberController,翻译就无法触发了?

  • 这个时候再重新在手机上进行一下语音输入,就又可以进行翻译了
  • 因为这个时候连接报错了
    • img
  • 应该是一段时间无使用,那么安卓系统就会好,这个软件和电脑端的TCP连接给杀掉,那么肯定无法进行翻译了。而当手机端使用语音输入的时候,相当于手机端主动和电脑端建立TCP连接,这个时候就可以再次正常进行翻译了
  • 解决方法其实很简单,只需要设置电池优化白名单

为什么连接成功了,但却依然无法进行语音识别和翻译?

  • 现象
    • img
    • img
  • 可能单纯的是网络不好吧
    • img
    • 查看一下手机能否打开其他网址,如果打不开其他网址的话,就重启一下手机
      • img
    • 查看一下代理延迟是不是太高了
      • 重新选择一个延迟比较低的节点
      • img
      • 之后就可以正常语音识别了
      • img
    • 2022.11.18-20:48:29
    • 重启一下手机之后,发现正常了
      • img
  • 可能是因为开了电池优化白名单
    • 我发现每次只要一开这个电池优化排名单,马上就无法联网了

多长时间TCP连接就会挂掉

  • 两分钟就会挂掉
  • Android中socket通信连接时长大概为120s,如果超过这个时间没有操作,就会断开连接

连接正常与断开连接有什么区别?

  • 连接正常
  • img
  • 断开连接

不停进行翻译,会断掉TCP连接吗?

  • 不会
    • 自己每30秒翻译一次,坚持了11分钟还没断掉
      • img
      • img

如何解决120秒socket通讯连接断掉的问题?

  • 这个暂时未解决,下面的方案,是网络上给出的解决方法

  • 手机端每隔一段时间往服务器转发一条不被解析的命令,这样可以使这个socket通讯一直保持畅通(但是自己对于java的编程不太擅长,如果有同学可以完成这部分工作的话,那就非常棒了)

  • 通过PowerManager设置电源模式

    • Android SocketClient休眠断开的问题 - 简书

    • PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE); 
      PowerManager.WakeLock wl = pm.newWakeLock(PowerManager.SCREEN_DIM_WAKE_LOCK, "My Tag"); 
      wl.acquire(); 
      ..screen will stay on during this section.. 
      wl.release();
      
    • 因为app使用activity,故在oncreate中wl.acquire();,在ondestroy中wl.release();

    • 加权限:android.permission.WAKE_LOCK

为什么可以进行翻译,但是无法进行语音输入?

  • 可以在手机端识别到对应的语音输入内容,但是无法发送到电脑端
  • 因为电脑端出错了
  • img
  • 在Controller.py文件中添加一行代码
  • from KeyboardManager import *
  • img
  • 之后就可以成功了

NameError: name ‘key_down’ is not defined

  • 出现这个错误,一般是在手机和电脑第一次建立连接的时候,不用管它,继续运行即可

  • img

  • 之后会发现,就算有这个错误,也不影响运行

    • img
    • img
    • 如果非要找原因的话,我们可以定位到对应的代码处查看
      • img
      • 应该是这个key_down按键脚本找不到了
        • img
      • 但实际上,在KeyboardListener.py文件中,这个函数是存在的
        • img
      • 我们新建一个测试脚本,把下面的代码输入进去,看能否运行成功
        • img
        • 但实际上是可以运行成功的。那么可能的原因应该就是因为这个key_down()函数是放在exec()字符中的,之前PyCharm自动清理的时候,将from KeyboardManager import * 这行代码清理掉了(因为PyCharm认为这个包没有用到,所以是无用的)
          • img
        • 因此我们在原始代码中,补充上这行代码就好了
          • img

修改

修改翻译的触发快捷键

  • 这里是使用了三次Ctrl+c的快捷键作为触发,但是每次想要翻译一个单词,都需要按三次键,感觉太繁琐,因此我将其修改为了使用一个Ctrl+Q的快捷键作为触发,只需要修改下面的代码

  • 将KeyboardListener.py-onKeyEvent()函数中的if修改为下面的代码

  • img

  • img

  • import pyautogui 
    if key.event_type == "down" \ 
            and key.name.lower() == "q" \ 
            and self.isCtrlHolding(): 
        pyautogui.hotkey('ctrl', 'c') 
     
        print("need trans") 
        if self.callback: 
            self.callback()
    
  • KeyboardListener.py的完整代码如下

  • import keyboard 
    import time 
    from screen_shot import ScreenCapture 
    import io 
    import pyautogui 
     
    class KeyboardListener: 
    	def __init__(self, tcpServer): 
    		self.tcpServer = tcpServer 
    		self.t = 0 
    		self.c = 0 
    		self.key_state_map={} 
    		self.screen_capture = None 
    		 
    	def listen_keyboard(self,callback): 
    		self.callback = callback 
    		keyboard.hook(self.onKeyEvent) 
    		keyboard.wait() 
     
    	def onImgCapture(self,pic):	 
    		imgByteArr = io.BytesIO() 
    		pic.save(imgByteArr, format='JPEG') 
    		bytes_data = imgByteArr.getvalue() 
    		self.tcpServer.send_img(bytes_data) 
     
    	def isCtrlHolding(self): 
    		return ('ctrl' in self.key_state_map and self.key_state_map['ctrl']=='down')\ 
    			or ('left ctrl' in self.key_state_map and self.key_state_map['left ctrl']=='down')\ 
    			or ('right ctrl' in self.key_state_map and self.key_state_map['right ctrl']=='down') 
     
    	def isAltHolding(self): 
    		return ('alt' in self.key_state_map and self.key_state_map['alt']=='down')\ 
    			or ('left alt' in self.key_state_map and self.key_state_map['left alt']=='down')\ 
    			or ('right alt' in self.key_state_map and self.key_state_map['right alt']=='down') 
     
    	def isKeyHolding(self,key): 
    		return (key in self.key_state_map and self.key_state_map[key]=='down') 
     
     
    	def onKeyEvent(self,key): 
    		#update key_state_map 
    		self.key_state_map[key.name.lower()]=key.event_type 
     
    		#is screenshoot? 
     
    		if  self.isKeyHolding("caps lock")\ 
    			and key.event_type=="down"\ 
    			and key.name.lower()=="a": 
    			self.screen_capture = ScreenCapture() 
    			self.screen_capture.are_capture(self.onImgCapture) 
     
    		#print(self.key_state_map) 
    		#is triple c? 
    		# if  key.event_type=="down" \ 
    		# 	and key.name.lower()=="c" \ 
    		# 	and self.isCtrlHolding(): 
    		# 
    		# 	if self.t == 0: 
    		# 		self.t=time.time() 
    		# 		self.c += 1 
    		# 		print("wait for nex c",self.c) 
    		# 		return 
    		# 
    		# 	if (time.time()-self.t<0.5): 
    		# 		self.t=time.time() 
    		# 		self.c += 1 
    		# 		print("wait for nex c:",self.c) 
    		# 
    		# 	else: 
    		# 		self.c = 0 
    		# 		self.t=0 
    		# 		print("wait for nex c",self.c) 
    		# 
    		# 	if self.c>=2: 
    		# 		self.c=0 
    		# 		print("need trans") 
    		# 		if self.callback: 
    		# 			self.callback() 
     
     
     
     
    		if  key.event_type=="down" \ 
    			and key.name.lower()=="q" \ 
    			and self.isCtrlHolding(): 
    			pyautogui.hotkey('ctrl', 'c') 
     
    			print("need trans") 
    			if self.callback: 
    				self.callback()
    

关掉不停的打印按键

  • 将这行代码注释掉即可
  • img

关掉手机上麦克风图标

  • 自己并不想要有这个麦克风的图标
  • img

电脑端翻译的代码是哪一段?

  • 这个onTrans()函数
  • img

手动往手机端发送数据

  • 程序不能直接运行,必须得有一个时间等待,否则手机和电脑端的TCP连接还没有建立上,会发送数据失败

  • img

  • import json 
    import time 
     
    from ComputerMonitor import ComputerMonitor 
    from KeyboardListener import KeyboardListener 
    from TcpServer import TcpServer 
    from service import * 
     
     
    def on_message_received(data): 
    	command_message = json.loads(data) 
    	script = command_message["script"] 
    	params = command_message["params"] 
    	exec(script) 
     
    def on_screen_locked(): 
    	print("screen locked") 
    	data = json.dumps({"command":2,"message":""}) 
    	print(data) 
    	tcpServer.send_text(data) 
     
    computerMonitor = ComputerMonitor(on_screen_locked) 
     
    def on_tcp_connected(): 
    	if not computerMonitor.started: 
    		computerMonitor.start() 
     
     
    tcpServer = TcpServer() 
    tcpServer.set_receive_listener(on_message_received) 
    tcpServer.connected_listener = on_tcp_connected 
    tcpServer.start() 
     
    keyboardListener = KeyboardListener(tcpServer) 
     
    def onTrans(): 
    	print("need trans1111") 
    	content = getClipContent() 
    	text = json.dumps({"command":1,"message":content}) 
     
    	tcpServer.send_text(text) 
     
     
    def Trans_alive():		#用来进行TCP保活 
    	print("need trans1111") 
    	content = getClipContent() 
    	text = json.dumps({"command":1,"message":content}) 
     
    	tcpServer.send_text(text) 
     
    #keyboardListener.listen_keyboard(onTrans) 
    time.sleep(5) 
    onTrans()
    

手动进行保活

  • 原理很简单,就是电脑端和手机端发空文本

  • import json 
    import time 
     
    from ComputerMonitor import ComputerMonitor 
    from KeyboardListener import KeyboardListener 
    from TcpServer import TcpServer 
    from service import * 
     
     
    def on_message_received(data): 
    	command_message = json.loads(data) 
    	script = command_message["script"] 
    	params = command_message["params"] 
    	exec(script) 
     
    def on_screen_locked(): 
    	print("screen locked") 
    	data = json.dumps({"command":2,"message":""}) 
    	print(data) 
    	tcpServer.send_text(data) 
     
    computerMonitor = ComputerMonitor(on_screen_locked) 
     
    def on_tcp_connected(): 
    	if not computerMonitor.started: 
    		computerMonitor.start() 
     
     
    tcpServer = TcpServer() 
    tcpServer.set_receive_listener(on_message_received) 
    tcpServer.connected_listener = on_tcp_connected 
    tcpServer.start() 
     
    keyboardListener = KeyboardListener(tcpServer) 
     
    def onTrans(): 
    	print("need trans1111") 
    	content = getClipContent() 
    	text = json.dumps({"command":1,"message":content}) 
     
    	tcpServer.send_text(text) 
     
     
    def Trans_alive():		#用来进行TCP保活 
    	print("need trans1111") 
    	content = '' 
    	text = json.dumps({"command":1,"message":content}) 
     
    	tcpServer.send_text(text) 
     
    #keyboardListener.listen_keyboard(onTrans) 
    time.sleep(5) 
    Trans_alive()
    

自动进行保活

  • 在Controller.py进入键盘监听循环之前添加下面一段代码

    • def Trans_alive():		#用来进行TCP保活 
      	content = '' 
      	# text = json.dumps({"command":1,"message":content}) 
      	text = json.dumps({"command":11,"message":content})		#这里之所以用11,而不是1,是因为原作者的command1对应的命令是翻译,会在手机端触发对应的翻译任务看,而11就只相当于是一条空命令了,既可以完成保活,又不会干扰手机端的命令执行,一举两得 
      	print("text:", text) 
      	tcpServer.send_text(text) 
       
      def run(): 
      	print('用来保活的,不用管我') 
      	t = threading.Timer(3, run) 
      	t.start() 
       
      	Trans_alive() 
       
       
      t = threading.Timer(3,run) 
      t.start()
      
    • img

  • 完整Controller.py代码

    • import json 
      import time 
       
      from ComputerMonitor import ComputerMonitor 
      from KeyboardListener import KeyboardListener 
      from TcpServer import TcpServer 
      from service import * 
      import threading 
       
      def on_message_received(data): 
      	command_message = json.loads(data) 
      	script = command_message["script"] 
      	params = command_message["params"] 
      	exec(script) 
       
      def on_screen_locked(): 
      	print("screen locked") 
      	data = json.dumps({"command":2,"message":""}) 
      	print(data) 
      	tcpServer.send_text(data) 
       
      computerMonitor = ComputerMonitor(on_screen_locked) 
       
      def on_tcp_connected(): 
      	if not computerMonitor.started: 
      		computerMonitor.start() 
       
       
      tcpServer = TcpServer() 
      tcpServer.set_receive_listener(on_message_received) 
      tcpServer.connected_listener = on_tcp_connected 
      tcpServer.start() 
       
      keyboardListener = KeyboardListener(tcpServer) 
       
      def onTrans(): 
      	print("need trans1111") 
      	content = getClipContent() 
      	text = json.dumps({"command":1,"message":content}) 
       
      	tcpServer.send_text(text) 
       
       
      def Trans_alive():		#用来进行TCP保活 
      	content = '' 
      	# text = json.dumps({"command":1,"message":content}) 
      	text = json.dumps({"command":11,"message":content})		#这里之所以用11,而不是1,是因为原作者的command1对应的命令是翻译,会在手机端触发对应的翻译任务看,而11就只相当于是一条空命令了,既可以完成保活,又不会干扰手机端的命令执行,一举两得 
      	print("text:", text) 
      	tcpServer.send_text(text) 
       
      def run(): 
      	print('用来保活的,不用管我') 
      	t = threading.Timer(3, run) 
      	t.start() 
       
      	Trans_alive() 
       
       
      t = threading.Timer(3,run) 
      t.start() 
       
      keyboardListener.listen_keyboard(onTrans)
      
  • 效果

    • 这样只要电脑和手机连着同一局域网的WiFi,无论过多久都不会把这个TCP连接来杀掉

  • 额外说明

    • 使用command为1进行发送的结果
      • 可以看到发送的字符串虽然没空,但终究是要进行翻译任务的,所以会把麦克风给掩盖掉,我感觉效果并不好了
      • img
    • 使用command为11进行发送的结果
      • 这个结果就很nice,也很干净了,压根儿查看不出来后台进行了数据发送与接收用来进行TCP socket保活
      • img

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/38907.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

现代密码学导论-18-伪随机置换

目录 伪随机置换 PROPOSITION 3.26 伪随机置换和伪随机函数的关系 DEFINITION 3.27 强伪随机置换 伪随机置换 我们称F是含参数k的置换&#xff0c;当且仅当 且对于所有k&#xff0c; Fk是一对一的&#xff0c;即是满射的。 其中 lin 称为F的块长度 对于给定的 k、x和k、y&…

76.【图】

图( 一).图的基本结构(1).无序偶对.(2).有序偶对(3).有向图和无向图(4).权(5).网图(二).图的基本术语(1).邻接.依附(2).有向完全图,无向完全图(3).顶点的度,入度,出度(4).路径 路径长度 回路(5).简单路径 简单回路(6).子图(7).连通图 连通分量(8).强连通图 强连通分量(三).图的…

改进粒子滤波的无人机三维航迹预测方法(基于Matlab代码实现)

&#x1f468;‍&#x1f393;个人主页&#xff1a;研学社的博客 &#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜…

骨传导耳机贴不紧咋办,推荐五款佩戴最稳固的骨传导蓝牙耳机

很多小伙伴都在反馈&#xff0c;骨传导耳机在佩戴时戴不稳&#xff0c;这关乎于耳机的材质有很大的关系&#xff0c;下面就给大家推荐几款佩戴十分牢固的骨传导耳机&#xff0c;不调人群使用哦~看看有没有自己喜欢的吧~ 1、南卡Runner Pro4骨传导蓝牙耳机 &#xffe5;1498 南…

图与图的深度优先遍历、广度优先遍历

文章目录&#x1f6a9;图的理解&#x1f341;无向图&#x1f341;有向图&#x1f341;完全图&#x1f341;常用性质&#x1f6a9;图的数据结构搭建&#x1f341;邻接矩阵&#x1f341;邻接表&#x1f341;邻接矩阵式存储的代码实现&#x1f341;邻接矩阵造图测试&#x1f341;邻…

从零开始打造一款基于SpringBoot+SpringCloud的后台权限管理系统

随着 Spring Boot 和 Spring Cloud 的诞生和流行&#xff0c;集智慧于大成的 Spring 技术体系成为行业开发的首选之一。市场代表需求&#xff0c;技术代表能力。显而易见&#xff0c;在当今开发领域中&#xff0c;谁能更好地掌握这些主流开发技术&#xff0c;谁就能在跟别人竞争…

SecXOps 技术体系

核心能力 为了加快安全分析能力更全面、更深入的自动化 &#xff0c;SecXOps 的目标在于创建一个集成的用于 Security 的 XOps 实践&#xff0c;提升安全分析的场景覆盖率和运营效率。SecXOps 技术并不 015 SecXOps 技术体系 是 Ops 技术在安全领域的简单加和&#xff0c;SecXO…

含分布式电源的配电网日前两阶段调度模型matlab程序(粒子群算法)

含分布式电源的配电网日前两阶段调度模型matlab程序&#xff08;粒子群算法&#xff09; 参考文献&#xff1a;含分布式电源的配电网日前两阶段优化调度模型 摘要&#xff1a;在电力市场环境下&#xff0c;供电公司通过对接入配电网的分布式电源(distributed generation&#…

MyBatis基础

一什么是MyBatis 1 什么是myBatis MyBatis框架也被称之为ORM&#xff08;Object/Relation Mapping&#xff0c;即对象关系映射&#xff09;框架。所谓的ORM就是一种为了解决面向对象与关系型数据库中数据类型不匹配的技术&#xff0c;它通过描述Java对象与数据库表之间的映射关…

Node.js 入门教程 6 V8 JavaScript 引擎

Node.js 入门教程 Node.js官方入门教程 Node.js中文网 本文仅用于学习记录&#xff0c;不存在任何商业用途&#xff0c;如侵删 文章目录Node.js 入门教程6 V8 JavaScript 引擎6.1 其他 JS 引擎6.2 追求性能6.3 编译6 V8 JavaScript 引擎 V8 是驱动 Google Chrome 的 JavaScrip…

【小5聊】纯javascript实现图片放大镜效果

实现图片放大镜效果&#xff0c;其实就是一个比例放大的效果 以下通过纯javascript方式对图片进行等比例放大&#xff0c;等比倍数和出界判断可自行实现 文章后面会附上全部代码 放大镜效果 1、 放大镜组成 1&#xff09;目标图片&#xff0c;一般是小图 2&#xff09;鼠标移…

【雷丰阳-谷粒商城 】【分布式基础篇-全栈开发篇】【01】分布式基础概念_环境搭建_Docker的使用

持续学习&持续更新中… 学习态度&#xff1a;守破离 【雷丰阳-谷粒商城 】【分布式基础篇-全栈开发篇】【01】分布式基础概念微服务集群&分布式&节点远程调用负载均衡服务注册/发现&注册中心配置中心服务熔断&降级API网关虚拟机环境搭建安装vagrant和virt…

gcc编译器

1. GCC工具 GCC编译器&#xff1a; GCC&#xff08;GNU Compiler Collection&#xff09;是由 GNU 开发的编程语言编译器。 GCC最初代表“GNU C Compiler”&#xff0c;当时只支持C语言。 后来又扩展能够支持更多编程语言&#xff0c;包括 C、Fortran 和 Java 等。 因此&#…

网站页面模仿学习

一、代码部分 <!DOCTYPE html> <html> <head><meta charset"utf-8"><title>cdcas</title> </head> <style>*{margin: 0;padding: 0;}.container{text-align: center;}.top{margin: auto;text-align: center;}.nav{…

pdf编辑器软件,分享一款考编用的pdf软件,挺合适的!

对于大部分人来说&#xff0c;最好的工作莫过于公务员、事业单位、国企&#xff0c;此类所谓的金饭碗、铁饭碗。工资收入处于中上水平&#xff0c;且朝九晚五。 不过想要获得这样的编制绝非易事&#xff0c;需要参加统考&#xff0c;经过层层选拔。很多年轻人感叹苦海无编&…

现代密码学导论-17-伪随机函数

目录 3.5.1伪随机函数的非正式定义 |Func_n| 有多大&#xff1f; DEFINITION 3.24 伪随机函数的正式定义 Example 3.25 一个不安全的反例 3.5.1伪随机函数的非正式定义 伪随机函数&#xff08;PRFs&#xff09;推广了伪随机发生器的概念。 F : {0, 1}∗ {0, 1}∗→ {0, 1…

Linux进程管理【进程的相关介绍片、ps、 kill 、pstree】【详细整理】

目录进程相关介绍显示系统执行的流程 psps 详解![请添加图片描述](https://img-blog.csdnimg.cn/cd9f10bf36684b419f2f94068afb9a03.png)案例终止进程kill 和 killall基本语法常见选型案例查看进程数pstreepstree [选项]&#xff0c;可以更加直观的来查看进程信息进程相关介绍 …

【无线传感器】使用 Mamdani 模糊推理系统改进无线传感器网络路由和数据包传递附Matlab代码

✅作者简介&#xff1a;热爱科研的Matlab仿真开发者&#xff0c;修心和技术同步精进&#xff0c;matlab项目合作可私信。 &#x1f34e;个人主页&#xff1a;Matlab科研工作室 &#x1f34a;个人信条&#xff1a;格物致知。 更多Matlab仿真内容点击&#x1f447; 智能优化算法 …

【语音去噪】谱减法+维纳滤波语音去噪(带面板+信噪比)【含GUI Matlab源码 1661期】

⛄一、简介 1 维纳滤波法 维纳滤波法(wiener filter)也是一个比较经典的传统做法&#xff0c;它的本质是估计出一个线性滤波器&#xff0c;也就是一个向量&#xff0c;这个滤波器会对不同的频段进行不同程度的抑制&#xff0c;其保真效果会比谱减法要好一些。 我们这里不会讲…

8.4 数据结构——选择排序

8.4.1 简单选择排序 基本思想&#xff1a;在待排序的数据中选出最大&#xff08;小&#xff09;的元素放在其开始的位置。 基本操作&#xff1a; &#xff08;1&#xff09;首先通过n-1次关键字比较&#xff0c;从n个记录中找出关键字最小的记录&#xff0c;将它与第一个交换…