文章目录

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

前言

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

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

调试过程中的疑问

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

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

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

  • 现象

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

多长时间TCP连接就会挂掉

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

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

  • 连接正常
  • 断开连接

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

  • 不会

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

如何解决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

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

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

NameError: name ‘key_down’ is not defined

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

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

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

修改

修改翻译的触发快捷键

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

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

  • 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()
    

关掉不停的打印按键

  • 将这行代码注释掉即可

关掉手机上麦克风图标

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

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

  • 这个onTrans()函数

手动往手机端发送数据

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

  • 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()
      
  • 完整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进行发送的结果

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

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

  1. 数学建模番外篇6:二维/三维热力图绘制(matlab)

    效果 虽然PPT可以绘制大多数的图像,但对于这类图像绘制,用PPT则会有些吃力,而在matlab中则能够比较方便的解决, 源码 先放源码,后面分析. [x,y] = meshgrid(1:0.1:10 ...

  2. iOS冰与火之歌番外篇 - 在非越狱手机上进行App Hook(转载)

    作者简介:郑旻(花名蒸米),阿里巴巴移动安全部门资深安全工程师,香港中文大学移动安全(Android & iOS)方向博士,曾在腾讯.百度以及硅谷的FireEye实习.在博士期间发表了多篇移动 ...

  3. iOS冰与火之歌番外篇 - 在非越狱手机上进行App Hook

    作者简介:郑旻(花名蒸米),阿里巴巴移动安全部门资深安全工程师,香港中文大学移动安全(Android & iOS)方向博士,曾在腾讯.百度以及硅谷的FireEye实习.在博士期间发表了多篇移动 ...

  4. Airtest的UI自动化番外篇、安卓手机密码键盘在AirTest上黑屏

    Airtest的UI自动化番外篇.安卓手机密码键盘在AirTest上黑屏 在使用AirTest测试的过程中,涉及到密码的时候,会出现airtest监控的手机页面黑屏(手机没黑屏,只是电脑监控的页面黑屏 ...

  5. iOS冰与火之歌番外篇 - App Hook答疑以及iOS 9砸壳

    蒸米 · 2016/03/16 10:29 0x00 序 上一章我们讲到了在非越狱的iOS上进行App Hook.利用这个技术,你可以在非越狱的iOS系统上实现各种hook功能(e.g., 微信自动抢 ...

  6. 【番外篇】ASP.NET MVC快速入门之免费jQuery控件库(MVC5+EF6)

    目录 [第一篇]ASP.NET MVC快速入门之数据库操作(MVC5+EF6) [第二篇]ASP.NET MVC快速入门之数据注解(MVC5+EF6) [第三篇]ASP.NET MVC快速入门之安全策 ...

  7. clang static analyzer源码分析(番外篇):RegionStore以及evalCall()中的conservativeEvalCall

    引子 我们在上一篇文章<clang static analyzer源码分析(番外篇):evalCall()中的inline机制>中提及了clang如何创建CallGraph,如何进行函数i ...

  8. 理解TextView三部曲之番外篇:或许这会是最终的进化

    额,为什么会有番外篇呢..因为新版本上线后,别的同学用我的这个控件,描边显示出问题了-_-! 什么问题呢? 我把问题抽出来,同时把问题放大点,给大家看看(抹眼泪.png)   好嘛,问题不大..就是描 ...

  9. 神经网络学习小记录-番外篇——常见问题汇总

    神经网络学习小记录-番外篇--常见问题汇总 前言 问题汇总 1.下载问题 a.代码下载 b. 权值下载 c. 数据集下载 2.环境配置问题 a.20系列所用的环境 b.30系列显卡环境配置 c.CPU ...

最新文章

  1. linux能远程打开桌面版,如何从Linux上远程显示Windows桌面
  2. [WebService] xml WebService学习1
  3. 多个圆点,鼠标选取两个,求两个点的距离,用于计算像素尺寸(halcon实现)
  4. ionic+AnjularJs实现省市县三级联动效果
  5. qt实现QLabel上显示的文字有描边
  6. 浅谈Solr和ElasticSearch建索引性能优化策略
  7. 线程池之ThreadPool与ForkJoinPool
  8. Tomcat执行start文件后有乱码
  9. LINUX其他重要服务
  10. SQOOP 导出SQL SERVER中数据
  11. abb机器人写字程序实例_abb机器人程序实例
  12. LOCAL_MODULE_TAGS 选项说明
  13. [转载]未在本地计算机上注册“microsoft.ACE.oledb.12.0”提供程序。
  14. JSP版LCX:端口转发神器 KPortTran
  15. Oracle DBA之监听的静态注册与动态注册
  16. 2016十月新番简介
  17. 简支梁模型振动位移matlab,不同移动载荷速度下简支桥梁的变形及振动响应研究...
  18. 【资料分享】迪文屏使用经验分享
  19. ppt中插入和删除动画
  20. 网易易盾-滑块-fp参数-2022-9-5

热门文章

  1. 我的账号难道被盗号了?
  2. 洪飞计算机百度云,海天名师洪飞解读2011计算机考研大纲
  3. 那些年,追过的开源软件和技术[转载]
  4. pta 英文单词排序_PTA常用英语词汇及缩写
  5. android_基础_BigDecimal 更精准的计算
  6. win10无法播放测试音调怎么办?
  7. 启动kafka出现找不到或无法加载主类
  8. WaterDrop下载与安装
  9. 信合考试计算机知识,2015年陕西信合考试试题答案――计算机基础知识
  10. 2020读过的好书推荐