本教程是 CyberController手机外挂 的番外篇,- CyberController的源码二次修改
这个暂时未解决,下面的方案,是网络上给出的解决方法
手机端每隔一段时间往服务器转发一条不被解析的命令,这样可以使这个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
出现这个错误,一般是在手机和电脑第一次建立连接的时候,不用管它,继续运行即可
之后会发现,就算有这个错误,也不影响运行
这里是使用了三次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()
程序不能直接运行,必须得有一个时间等待,否则手机和电脑端的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)
效果
额外说明