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











这个暂时未解决,下面的方案,是网络上给出的解决方法
手机端每隔一段时间往服务器转发一条不被解析的命令,这样可以使这个socket通讯一直保持畅通(但是自己对于java的编程不太擅长,如果有同学可以完成这部分工作的话,那就非常棒了)
通过PowerManager设置电源模式
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)
效果
额外说明

