├── .gitignore
├── puppet
├── src
│ ├── main
│ │ ├── java
│ │ │ ├── META-INF
│ │ │ │ └── MANIFEST.MF
│ │ │ └── cn
│ │ │ │ └── yang
│ │ │ │ └── puppet
│ │ │ │ └── client
│ │ │ │ ├── constant
│ │ │ │ ├── PuppetDynamicSetting.java
│ │ │ │ ├── MessageConstants.java
│ │ │ │ ├── ConfigConstants.java
│ │ │ │ └── ExceptionMessageConstants.java
│ │ │ │ ├── exception
│ │ │ │ ├── HeartBeatException.java
│ │ │ │ ├── NullValueException.java
│ │ │ │ └── PuppetClientException.java
│ │ │ │ ├── commandhandler
│ │ │ │ ├── ControlCommandHandler.java
│ │ │ │ ├── TerminateCommandHandler.java
│ │ │ │ ├── QualityCommandHandler.java
│ │ │ │ ├── KeyBoardEventCommandHandler.java
│ │ │ │ ├── MouseEventCommandHandler.java
│ │ │ │ └── AbstractPuppetCommandHandler.java
│ │ │ │ ├── ui
│ │ │ │ ├── impl
│ │ │ │ │ └── PuppetDesktop.java
│ │ │ │ ├── MessageDialog.java
│ │ │ │ └── IReplay.java
│ │ │ │ ├── PuppetStarter.java
│ │ │ │ ├── netty
│ │ │ │ ├── PuppetNettyClientHandler.java
│ │ │ │ └── PuppetNettyClient.java
│ │ │ │ └── robot
│ │ │ │ ├── JavaRobotReplay.java
│ │ │ │ └── GoRobotReplay.java
│ │ ├── resources
│ │ │ ├── log4j.properties
│ │ │ ├── META-INF
│ │ │ │ └── commandhandlers
│ │ │ ├── puppet-config.txt
│ │ │ └── puppet-beans.xml
│ │ └── proto
│ │ │ └── go_robot.proto
│ └── test
│ │ └── java
│ │ └── GoRobotReplayTest.java
├── dependency-reduced-pom.xml
├── pom.xml
└── puppet.iml
├── .idea
├── markdown-navigator
│ └── profiles_settings.xml
├── vcs.xml
├── misc.xml
├── libraries
│ ├── Maven__log4j_log4j_1_2_17.xml
│ ├── Maven__org_objenesis_objenesis_2_1.xml
│ ├── Maven__org_slf4j_slf4j_api_1_7_25.xml
│ ├── Maven__org_slf4j_slf4j_log4j12_1_7_25.xml
│ ├── Maven__net_coobird_thumbnailator_0_4_8.xml
│ ├── Maven__com_dyuproject_protostuff_protostuff_api_1_0_8.xml
│ ├── Maven__org_springframework_spring_aop_5_0_6_RELEASE.xml
│ ├── Maven__com_dyuproject_protostuff_protostuff_core_1_0_8.xml
│ ├── Maven__org_springframework_spring_beans_5_0_6_RELEASE.xml
│ ├── Maven__com_dyuproject_protostuff_protostuff_runtime_1_0_8.xml
│ ├── Maven__org_springframework_spring_context_5_0_6_RELEASE.xml
│ ├── Maven__org_springframework_spring_expression_5_0_6_RELEASE.xml
│ └── Maven__com_dyuproject_protostuff_protostuff_collectionschema_1_0_8.xml
├── modules.xml
├── compiler.xml
├── artifacts
│ ├── desktop_control_master.xml
│ └── desktop_control_puppet.xml
└── markdown-navigator.xml
├── master
├── src
│ └── main
│ │ ├── resources
│ │ ├── log4j.properties
│ │ ├── master-config.txt
│ │ ├── META-INF
│ │ │ └── commandhandlers
│ │ └── master-beans.xml
│ │ └── java
│ │ └── cn
│ │ └── yang
│ │ └── master
│ │ └── client
│ │ ├── exception
│ │ ├── ConnectionException.java
│ │ ├── FireCommandHandlerException.java
│ │ ├── MasterClientException.java
│ │ └── MasterChannelHandlerException.java
│ │ ├── constant
│ │ ├── MessageConstants.java
│ │ ├── ConfigConstants.java
│ │ └── ExceptionMessageConstants.java
│ │ ├── ui
│ │ ├── IDisplayPuppet.java
│ │ ├── IMasterDesktop.java
│ │ ├── listener
│ │ │ ├── KeyBoardListener.java
│ │ │ └── MouseListener.java
│ │ └── impl
│ │ │ ├── AbstractDisplayPuppet.java
│ │ │ └── PuppetScreen.java
│ │ ├── commandhandler
│ │ ├── ConnectCommandHandler.java
│ │ ├── AbstractMasterFireCommandHandler.java
│ │ ├── ScreenCommandHandler.java
│ │ ├── ControlFireCommandHandler.java
│ │ ├── CommonFireCommandHandler.java
│ │ └── AbstractMasterCommandHandler.java
│ │ ├── MasterStarter.java
│ │ └── netty
│ │ ├── MasterNettyClientHandler.java
│ │ └── MasterNettyClient.java
├── dependency-reduced-pom.xml
├── pom.xml
└── master.iml
├── server
├── src
│ └── main
│ │ ├── resources
│ │ ├── log4j.properties
│ │ ├── server-config.txt
│ │ ├── META-INF
│ │ │ └── commandhandlers
│ │ └── server-beans.xml
│ │ └── java
│ │ └── cn
│ │ └── yang
│ │ └── server
│ │ ├── constant
│ │ ├── MessageConstants.java
│ │ └── ConfigConstants.java
│ │ ├── commandhandler
│ │ ├── HeartBeatCommandHandler.java
│ │ ├── CommonFireCommandHandler.java
│ │ ├── TerminateCommandHandler.java
│ │ ├── ScreenCommandHandler.java
│ │ ├── AbstractServerCommandHandler.java
│ │ ├── ControlCommandHandler.java
│ │ └── ConnectionCommandHandler.java
│ │ ├── netty
│ │ ├── ChannelPair.java
│ │ ├── NettyServerHandler.java
│ │ └── NettyServer.java
│ │ └── ServerStarter.java
├── dependency-reduced-pom.xml
├── pom.xml
└── server.iml
├── common
├── src
│ └── main
│ │ └── java
│ │ └── cn
│ │ └── yang
│ │ └── common
│ │ ├── netty
│ │ ├── INettyClient.java
│ │ └── ChannelInitializer.java
│ │ ├── exception
│ │ ├── ConfigParseException.java
│ │ ├── TaskExecutorException.java
│ │ ├── ConnectionException.java
│ │ ├── CommandHandlerException.java
│ │ ├── ResponseHandleException.java
│ │ ├── CommandHandlerLoaderException.java
│ │ └── ServerException.java
│ │ ├── generator
│ │ ├── SequenceGenerate.java
│ │ ├── PuppetNameGenerate.java
│ │ └── impl
│ │ │ ├── SimplePuppetNameGenerator.java
│ │ │ └── SimpleSequenceGenerator.java
│ │ ├── constant
│ │ ├── Constants.java
│ │ └── ExceptionMessageConstants.java
│ │ ├── command
│ │ ├── handler
│ │ │ └── ICommandHandler.java
│ │ └── Commands.java
│ │ ├── dto
│ │ ├── Request.java
│ │ ├── Response.java
│ │ └── Invocation.java
│ │ ├── InputEvent
│ │ ├── MouseButton.java
│ │ ├── MasterKeyEvent.java
│ │ └── MasterMouseEvent.java
│ │ ├── util
│ │ ├── BeanUtil.java
│ │ ├── MacUtils.java
│ │ ├── TaskExecutors.java
│ │ ├── PropertiesUtil.java
│ │ ├── SerializationUtil.java
│ │ └── CommandHandlerLoader.java
│ │ └── serialization
│ │ ├── ProtobufEncoder.java
│ │ └── ProtobufDecoder.java
├── pom.xml
└── common.iml
├── desktop-control-parent.iml
└── pom.xml
/.gitignore:
--------------------------------------------------------------------------------
1 | .idea
2 | common/target
3 | master/target
4 | puppet/target
5 | server/target
--------------------------------------------------------------------------------
/puppet/src/main/java/META-INF/MANIFEST.MF:
--------------------------------------------------------------------------------
1 | Manifest-Version: 1.0
2 | Main-Class: cn.yang.puppet.client.PuppetStarter
3 |
4 |
--------------------------------------------------------------------------------
/.idea/markdown-navigator/profiles_settings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/master/src/main/resources/log4j.properties:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Cool-Coding/remote-desktop-control/HEAD/master/src/main/resources/log4j.properties
--------------------------------------------------------------------------------
/puppet/src/main/resources/log4j.properties:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Cool-Coding/remote-desktop-control/HEAD/puppet/src/main/resources/log4j.properties
--------------------------------------------------------------------------------
/server/src/main/resources/log4j.properties:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Cool-Coding/remote-desktop-control/HEAD/server/src/main/resources/log4j.properties
--------------------------------------------------------------------------------
/.idea/vcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/master/src/main/resources/master-config.txt:
--------------------------------------------------------------------------------
1 | #鼠标双击检测延迟间隔时间
2 | mouse.double.check.delay=2000
3 |
4 | #服务器IP地址
5 | #server.ip=144.34.157.127
6 | server.ip=192.168.254.1
7 |
8 | #服务器端口号
9 | server.port=1234
10 |
--------------------------------------------------------------------------------
/common/src/main/java/cn/yang/common/netty/INettyClient.java:
--------------------------------------------------------------------------------
1 | package cn.yang.common.netty;
2 |
3 | /**
4 | * @author Cool-Coding
5 | * 2018/8/3
6 | */
7 | public interface INettyClient {
8 | /**
9 | * 连接服务器
10 | */
11 | void connect() throws Exception;
12 | }
13 |
--------------------------------------------------------------------------------
/server/src/main/resources/server-config.txt:
--------------------------------------------------------------------------------
1 | #控制端控制傀儡端重试时间间隔(ms)
2 | master.connect.puppetName.retry.interval=1000
3 |
4 | #控制端控制傀儡端重试次数
5 | master.connect.puppetName.retry.times=10
6 |
7 | #服务器IP
8 | #server.ip=144.34.157.127
9 | server.ip=192.168.254.1
10 |
11 | #服务器端口
12 | server.port=1234
--------------------------------------------------------------------------------
/common/src/main/java/cn/yang/common/exception/ConfigParseException.java:
--------------------------------------------------------------------------------
1 | package cn.yang.common.exception;
2 |
3 | public class ConfigParseException extends RuntimeException {
4 |
5 | public ConfigParseException(String message, Throwable cause) {
6 | super(message,cause);
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/common/src/main/java/cn/yang/common/generator/SequenceGenerate.java:
--------------------------------------------------------------------------------
1 | package cn.yang.common.generator;
2 |
3 | /**
4 | * @author Cool-Coding
5 | * 2018/7/25
6 | */
7 | public interface SequenceGenerate {
8 |
9 | /**
10 | * 生成下一个序号
11 | * @return
12 | */
13 | int next();
14 | }
15 |
--------------------------------------------------------------------------------
/puppet/src/main/java/cn/yang/puppet/client/constant/PuppetDynamicSetting.java:
--------------------------------------------------------------------------------
1 | package cn.yang.puppet.client.constant;
2 |
3 | import cn.yang.common.constant.Constants;
4 |
5 | public class PuppetDynamicSetting {
6 | /**
7 | * 清晰度[10,100]
8 | */
9 | public static int quality = Constants.SCREEN_QUALITY;
10 | }
11 |
--------------------------------------------------------------------------------
/common/src/main/java/cn/yang/common/generator/PuppetNameGenerate.java:
--------------------------------------------------------------------------------
1 | package cn.yang.common.generator;
2 |
3 | import io.netty.channel.ChannelHandlerContext;
4 |
5 | /**
6 | * @author Cool-Coding
7 | * 2018/8/3
8 | */
9 | public interface PuppetNameGenerate {
10 | String getPuppetName(ChannelHandlerContext ctx);
11 | }
12 |
--------------------------------------------------------------------------------
/common/src/main/java/cn/yang/common/constant/Constants.java:
--------------------------------------------------------------------------------
1 | package cn.yang.common.constant;
2 |
3 | /**
4 | * @author cool-coding
5 | * @date 2018/7/24
6 | */
7 | public class Constants {
8 | public static final char MASTER='M';
9 | public static final char PUPPET='P';
10 | public static final int SCREEN_QUALITY=50;
11 |
12 | }
13 |
--------------------------------------------------------------------------------
/common/src/main/java/cn/yang/common/exception/TaskExecutorException.java:
--------------------------------------------------------------------------------
1 | package cn.yang.common.exception;
2 |
3 | /**
4 | * @author Cool-Coding
5 | * @date 2018/7/25
6 | */
7 | public class TaskExecutorException extends Exception {
8 | public TaskExecutorException(String msg, Exception e) {
9 | super(msg, e);
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/puppet/src/main/java/cn/yang/puppet/client/exception/HeartBeatException.java:
--------------------------------------------------------------------------------
1 | package cn.yang.puppet.client.exception;
2 |
3 | /**
4 | * @author Cool-Coding
5 | * 2018/7/25
6 | */
7 | public class HeartBeatException extends Exception {
8 | public HeartBeatException(String msg,Exception e){
9 | super(msg,e);
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/server/src/main/java/cn/yang/server/constant/MessageConstants.java:
--------------------------------------------------------------------------------
1 | package cn.yang.server.constant;
2 |
3 | /**
4 | * @author Cool-Coding
5 | * 2018/8/2
6 | */
7 | public class MessageConstants {
8 | public static final String CONNECTION_SUCCEED="connect successfully";
9 | public static final String RECEIVE_A_HEARTBEAT="receive a heart beat from puppet";
10 | }
11 |
--------------------------------------------------------------------------------
/common/src/main/java/cn/yang/common/exception/ConnectionException.java:
--------------------------------------------------------------------------------
1 | package cn.yang.common.exception;
2 |
3 | /**
4 | * @author Cool-Coding
5 | * 2018/7/27
6 | */
7 | public class ConnectionException extends Exception {
8 | public ConnectionException(String msg){
9 | super(msg);
10 | }
11 |
12 | public ConnectionException(String msg, Exception obj){
13 | super(msg,obj);
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/puppet/src/main/java/cn/yang/puppet/client/exception/NullValueException.java:
--------------------------------------------------------------------------------
1 | package cn.yang.puppet.client.exception;
2 |
3 | /**
4 | * @author Cool-Coding
5 | * 2018/7/27
6 | */
7 | public class NullValueException extends Exception {
8 | public NullValueException(String msg){
9 | super(msg);
10 | }
11 |
12 | public NullValueException(String msg, Exception obj){
13 | super(msg,obj);
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/common/src/main/java/cn/yang/common/exception/CommandHandlerException.java:
--------------------------------------------------------------------------------
1 | package cn.yang.common.exception;
2 |
3 | /**
4 | * @author Cool-Coding
5 | * 2018/7/27
6 | */
7 | public class CommandHandlerException extends Exception {
8 | public CommandHandlerException(String msg){
9 | super(msg);
10 | }
11 |
12 | public CommandHandlerException(String msg,Exception obj){
13 | super(msg,obj);
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/common/src/main/java/cn/yang/common/exception/ResponseHandleException.java:
--------------------------------------------------------------------------------
1 | package cn.yang.common.exception;
2 |
3 | /**
4 | * @author Cool-Coding
5 | * 2018/7/27
6 | */
7 | public class ResponseHandleException extends Exception {
8 | public ResponseHandleException(String msg, Exception e){
9 | super(msg,e);
10 | }
11 |
12 | public ResponseHandleException(String msg){
13 | super(msg);
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/master/src/main/java/cn/yang/master/client/exception/ConnectionException.java:
--------------------------------------------------------------------------------
1 | package cn.yang.master.client.exception;
2 |
3 | /**
4 | * @author Cool-Coding
5 | * 2018/7/27
6 | */
7 | public class ConnectionException extends Exception {
8 | public ConnectionException(String msg){
9 | super(msg);
10 | }
11 |
12 | public ConnectionException(String msg, Exception obj){
13 | super(msg,obj);
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/master/src/main/java/cn/yang/master/client/exception/FireCommandHandlerException.java:
--------------------------------------------------------------------------------
1 | package cn.yang.master.client.exception;
2 |
3 | /**
4 | * @author cool-coding
5 | * @date 2018/7/26
6 | */
7 | public class FireCommandHandlerException extends Exception{
8 | public FireCommandHandlerException(String msg){
9 | super(msg);
10 | }
11 | public FireCommandHandlerException(Exception e){
12 | super(e);
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/master/src/main/java/cn/yang/master/client/exception/MasterClientException.java:
--------------------------------------------------------------------------------
1 | package cn.yang.master.client.exception;
2 |
3 | /**
4 | * @author Cool-Coding
5 | * 2018/7/27
6 | */
7 | public class MasterClientException extends Exception {
8 | public MasterClientException(String msg){
9 | super(msg);
10 | }
11 |
12 | public MasterClientException(String msg, Exception obj){
13 | super(msg,obj);
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/puppet/src/main/java/cn/yang/puppet/client/exception/PuppetClientException.java:
--------------------------------------------------------------------------------
1 | package cn.yang.puppet.client.exception;
2 |
3 | /**
4 | * @author Cool-Coding
5 | * 2018/7/27
6 | */
7 | public class PuppetClientException extends Exception {
8 | public PuppetClientException(String msg){
9 | super(msg);
10 | }
11 |
12 | public PuppetClientException(String msg, Exception obj){
13 | super(msg,obj);
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/puppet/src/main/resources/META-INF/commandhandlers:
--------------------------------------------------------------------------------
1 | CONNECT=cn.yang.puppet.client.commandhandler.ConnectCommandHandler
2 | CONTROL=cn.yang.puppet.client.commandhandler.ControlCommandHandler
3 | KEYBOARD=cn.yang.puppet.client.commandhandler.KeyBoardEventCommandHandler
4 | MOUSE=cn.yang.puppet.client.commandhandler.MouseEventCommandHandler
5 | TERMINATE=cn.yang.puppet.client.commandhandler.TerminateCommandHandler
6 | QUALITY=cn.yang.puppet.client.commandhandler.QualityCommandHandler
--------------------------------------------------------------------------------
/common/src/main/java/cn/yang/common/exception/CommandHandlerLoaderException.java:
--------------------------------------------------------------------------------
1 | package cn.yang.common.exception;
2 |
3 | /**
4 | * @author Cool-Coding
5 | * 2018/7/27
6 | */
7 | public class CommandHandlerLoaderException extends Exception {
8 | public CommandHandlerLoaderException(String msg){
9 | super(msg);
10 | }
11 |
12 | public CommandHandlerLoaderException(String msg, Exception e){
13 | super(msg,e);
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/master/src/main/java/cn/yang/master/client/constant/MessageConstants.java:
--------------------------------------------------------------------------------
1 | package cn.yang.master.client.constant;
2 |
3 | /**
4 | * @author Cool-Coding
5 | * 2018/8/2
6 | */
7 | public class MessageConstants {
8 | public static final String RECEIVE_SCREEN_SNAPSHOT="receive a snapshot from puppet";
9 | public static final String CONNECT_SUCCESSFULLY="connect successfully";
10 | public static final String PREPARING_TO_FIRE="is preparing to fire";
11 | }
12 |
--------------------------------------------------------------------------------
/master/src/main/java/cn/yang/master/client/exception/MasterChannelHandlerException.java:
--------------------------------------------------------------------------------
1 | package cn.yang.master.client.exception;
2 |
3 | /**
4 | * @author cool-coding
5 | * @date 2018/7/26
6 | */
7 | public class MasterChannelHandlerException extends RuntimeException{
8 | public MasterChannelHandlerException(String msg){
9 | super(msg);
10 | }
11 |
12 | public MasterChannelHandlerException(String msg,Exception e){
13 | super(msg,e);
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/puppet/src/main/java/cn/yang/puppet/client/constant/MessageConstants.java:
--------------------------------------------------------------------------------
1 | package cn.yang.puppet.client.constant;
2 |
3 | /**
4 | * @author cool-coding
5 | * @date 2018/7/24
6 | */
7 | public class MessageConstants {
8 | public static final String SEND_A_HEARTBEAT="send a heartbeat to";
9 | public static final String SEND_A_SCREENSNAPSHOT="send a snapshot to";
10 | public static final String PUPPET_NAME_FROM_SERVER="Please remember that the puppet's name is";
11 |
12 | }
13 |
--------------------------------------------------------------------------------
/.idea/misc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/master/src/main/java/cn/yang/master/client/ui/IDisplayPuppet.java:
--------------------------------------------------------------------------------
1 | package cn.yang.master.client.ui;
2 |
3 | /**
4 | * @author Cool-Coding
5 | * 2018/8/2
6 | * 傀儡控制屏幕接口
7 | */
8 | public interface IDisplayPuppet {
9 | /**
10 | * 启动窗口显示傀儡桌面
11 | */
12 | void launch();
13 |
14 | /**
15 | * 刷新桌面
16 | * @param bytes
17 | */
18 | void refresh(byte[] bytes);
19 |
20 | /**
21 | *
22 | * @return 傀儡名称
23 | */
24 | String getPuppetName();
25 | }
26 |
--------------------------------------------------------------------------------
/common/src/main/java/cn/yang/common/command/handler/ICommandHandler.java:
--------------------------------------------------------------------------------
1 | package cn.yang.common.command.handler;
2 |
3 | import io.netty.channel.ChannelHandlerContext;
4 |
5 | /**
6 | * @author Cool-Coding
7 | * 2018/7/27
8 | */
9 | public interface ICommandHandler {
10 | /**
11 | *
12 | * @param ctx 当前channel处理器上下文
13 | * @param inbound channel输入对象
14 | * @throws Exception 异常
15 | */
16 | void handle(ChannelHandlerContext ctx,T inbound) throws Exception;
17 | }
18 |
--------------------------------------------------------------------------------
/common/src/main/java/cn/yang/common/dto/Request.java:
--------------------------------------------------------------------------------
1 | package cn.yang.common.dto;
2 |
3 | /**
4 | * @author Cool-Coding 2018/7/24
5 | * 请求封装类
6 | */
7 | public class Request extends Invocation {
8 | @Override
9 | public String toString() {
10 | return "Request{" +
11 | "id='" + getId() + '\'' +
12 | ", puppetName='" + getPuppetName() + '\'' +
13 | ", command=" + getCommand() +
14 | ", value=" + getValue() +
15 | '}';
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/master/src/main/resources/META-INF/commandhandlers:
--------------------------------------------------------------------------------
1 | CONNECT=cn.yang.master.client.commandhandler.ConnectCommandHandler
2 | CONTROL=cn.yang.master.client.commandhandler.ControlFireCommandHandler
3 | SCREEN=cn.yang.master.client.commandhandler.ScreenCommandHandler
4 | KEYBOARD=cn.yang.master.client.commandhandler.CommonFireCommandHandler
5 | MOUSE=cn.yang.master.client.commandhandler.CommonFireCommandHandler
6 | TERMINATE=cn.yang.master.client.commandhandler.CommonFireCommandHandler
7 | QUALITY=cn.yang.master.client.commandhandler.CommonFireCommandHandler
--------------------------------------------------------------------------------
/.idea/libraries/Maven__log4j_log4j_1_2_17.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/puppet/src/main/java/cn/yang/puppet/client/commandhandler/ControlCommandHandler.java:
--------------------------------------------------------------------------------
1 | package cn.yang.puppet.client.commandhandler;
2 |
3 | import cn.yang.common.dto.Response;
4 | import io.netty.channel.ChannelHandlerContext;
5 |
6 | /**
7 | * @author Cool-Coding
8 | * 2018/7/27
9 | */
10 | public class ControlCommandHandler extends AbstractPuppetCommandHandler {
11 | @Override
12 | protected void handle0(ChannelHandlerContext ctx, Response request) throws Exception {
13 | startUnderControlled();
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/puppet/src/main/java/cn/yang/puppet/client/commandhandler/TerminateCommandHandler.java:
--------------------------------------------------------------------------------
1 | package cn.yang.puppet.client.commandhandler;
2 |
3 | import cn.yang.common.dto.Response;
4 | import io.netty.channel.ChannelHandlerContext;
5 |
6 | /**
7 | * @author Cool-Coding
8 | * 2018/7/27
9 | */
10 | public class TerminateCommandHandler extends AbstractPuppetCommandHandler {
11 | @Override
12 | protected void handle0(ChannelHandlerContext ctx, Response response) throws Exception {
13 | stopUnderControlled();
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/master/src/main/java/cn/yang/master/client/commandhandler/ConnectCommandHandler.java:
--------------------------------------------------------------------------------
1 | package cn.yang.master.client.commandhandler;
2 |
3 | import cn.yang.common.dto.Response;
4 | import io.netty.channel.ChannelHandlerContext;
5 |
6 | /**
7 | * @author Cool-Coding
8 | * 2018/7/27
9 | */
10 | public class ConnectCommandHandler extends AbstractMasterCommandHandler {
11 | @Override
12 | protected void handle0(ChannelHandlerContext ctx, Response response) throws Exception {
13 | setChannelHandlerConext(ctx);
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/server/src/main/resources/META-INF/commandhandlers:
--------------------------------------------------------------------------------
1 | CONNECT=cn.yang.server.commandhandler.ConnectionCommandHandler
2 | CONTROL=cn.yang.server.commandhandler.ControlCommandHandler
3 | HEARTBEAT=cn.yang.server.commandhandler.HeartBeatCommandHandler
4 | SCREEN=cn.yang.server.commandhandler.ScreenCommandHandler
5 | KEYBOARD=cn.yang.server.commandhandler.CommonFireCommandHandler
6 | MOUSE=cn.yang.server.commandhandler.CommonFireCommandHandler
7 | QUALITY=cn.yang.server.commandhandler.CommonFireCommandHandler
8 | TERMINATE=cn.yang.server.commandhandler.TerminateCommandHandler
--------------------------------------------------------------------------------
/common/src/main/java/cn/yang/common/exception/ServerException.java:
--------------------------------------------------------------------------------
1 | package cn.yang.common.exception;
2 |
3 | import java.io.Serializable;
4 |
5 | /**
6 | * @author Cool-Coding
7 | * 2018/7/27
8 | */
9 | public class ServerException extends Exception implements Serializable {
10 |
11 | private static final long serialVersionUID = -7515877337663696708L;
12 |
13 | public ServerException(String msg, Exception e){
14 | super(msg,e);
15 | }
16 |
17 | public ServerException(String msg){
18 | super(msg);
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/common/src/main/java/cn/yang/common/generator/impl/SimplePuppetNameGenerator.java:
--------------------------------------------------------------------------------
1 | package cn.yang.common.generator.impl;
2 |
3 | import cn.yang.common.generator.PuppetNameGenerate;
4 | import io.netty.channel.ChannelHandlerContext;
5 |
6 | import java.util.UUID;
7 |
8 | /**
9 | * @author Cool-Coding
10 | * 2018/8/3
11 | */
12 | public class SimplePuppetNameGenerator implements PuppetNameGenerate {
13 | @Override
14 | public String getPuppetName(ChannelHandlerContext ctx) {
15 | return UUID.randomUUID().toString();
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/puppet/src/main/resources/puppet-config.txt:
--------------------------------------------------------------------------------
1 | #心跳间隔时间(ms)
2 | heartbeat.interval=2000
3 |
4 | #重新连接服务器间隔时间(ms)
5 | reconnect.interval=2000
6 |
7 | #向控制端发送屏幕截图间隔时间(ms)
8 | screen.refresh.frequency=200
9 |
10 | #心跳或发送屏幕截图任务检查时间间隔(ms)
11 | task.check.interval=200
12 |
13 | #服务器IP地址
14 | #server.ip=144.34.157.127
15 | server.ip=192.168.254.1
16 |
17 | #服务器端口号
18 | server.port=1234
19 |
20 | #接收到服务器错误消息超过这个阀值就断开连接
21 | error.count=5
22 |
23 | #robot的实例方式;可选javaRobot、goRobot
24 | robot=goRobot
25 |
26 | #goRobot的IP:PORT,只有当robot实现方式是goRobot时才有意义
27 | go.robot.endpoint=127.0.0.1:12345
--------------------------------------------------------------------------------
/.idea/libraries/Maven__org_objenesis_objenesis_2_1.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__org_slf4j_slf4j_api_1_7_25.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/common/src/main/java/cn/yang/common/generator/impl/SimpleSequenceGenerator.java:
--------------------------------------------------------------------------------
1 | package cn.yang.common.generator.impl;
2 |
3 | import cn.yang.common.generator.SequenceGenerate;
4 |
5 | import java.util.concurrent.atomic.AtomicInteger;
6 |
7 | /**
8 | * @author Cool-Coding
9 | * 2018/7/25
10 | */
11 | public class SimpleSequenceGenerator implements SequenceGenerate {
12 | /**
13 | * 简单的序号生成器
14 | */
15 | private final AtomicInteger sequence=new AtomicInteger();
16 |
17 | @Override
18 | public int next() {
19 | return sequence.getAndIncrement();
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__org_slf4j_slf4j_log4j12_1_7_25.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/server/src/main/java/cn/yang/server/constant/ConfigConstants.java:
--------------------------------------------------------------------------------
1 | package cn.yang.server.constant;
2 |
3 | /**
4 | * @author Cool-Coding
5 | * @date 2018/7/25
6 | */
7 | public class ConfigConstants {
8 |
9 | public static final String CONFIG_FILE_PATH= "server-config.txt";
10 | public static final String MASTER_CONNECT_PUPPET_RETRY_INTERVAL="master.connect.puppet.retry.interval";
11 | public static final String MASTER_CONNECT_PUPPET_RETRY_TIMES="master.connect.puppet.retry.times";
12 | public static final String SERVER_IP="server.ip";
13 | public static final String SERVER_PORT="server.port";
14 | }
15 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__net_coobird_thumbnailator_0_4_8.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/master/src/main/java/cn/yang/master/client/MasterStarter.java:
--------------------------------------------------------------------------------
1 | package cn.yang.master.client;
2 |
3 | import cn.yang.master.client.ui.IMasterDesktop;
4 | import org.springframework.context.support.ClassPathXmlApplicationContext;
5 |
6 |
7 | /**
8 | * @author Cool-Coding
9 | * 2018/7/25
10 | *Master启动器
11 | */
12 | public class MasterStarter {
13 |
14 | public static void main(String[] args){
15 | final ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("master-beans.xml");
16 | context.start();
17 | context.getBean(IMasterDesktop.class).lanuch();
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/puppet/src/main/java/cn/yang/puppet/client/ui/impl/PuppetDesktop.java:
--------------------------------------------------------------------------------
1 | package cn.yang.puppet.client.ui.impl;
2 |
3 |
4 | import cn.yang.common.netty.INettyClient;
5 | import cn.yang.puppet.client.netty.PuppetNettyClient;
6 |
7 | /**
8 | * @author Cool-Coding
9 | * 2018/7/25
10 | */
11 | public class PuppetDesktop implements INettyClient {
12 |
13 | private INettyClient puppetClient;
14 |
15 |
16 | @Override
17 | public void connect() throws Exception{
18 | puppetClient.connect();
19 | }
20 |
21 | public void setPuppetClient(PuppetNettyClient puppetClient) {
22 | this.puppetClient = puppetClient;
23 | }
24 |
25 | }
26 |
--------------------------------------------------------------------------------
/server/src/main/java/cn/yang/server/commandhandler/HeartBeatCommandHandler.java:
--------------------------------------------------------------------------------
1 | package cn.yang.server.commandhandler;
2 |
3 | import cn.yang.common.dto.Request;
4 | import cn.yang.server.constant.MessageConstants;
5 | import io.netty.channel.ChannelHandlerContext;
6 |
7 | /**
8 | * @author Cool-Coding
9 | * 2018/7/27
10 | */
11 | public class HeartBeatCommandHandler extends AbstractServerCommandHandler {
12 | @Override
13 | public void handle0(ChannelHandlerContext ctx, Request request) throws Exception {
14 | final String puppetName = request.getPuppetName();
15 | debug(request, MessageConstants.RECEIVE_A_HEARTBEAT,puppetName);
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__com_dyuproject_protostuff_protostuff_api_1_0_8.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__org_springframework_spring_aop_5_0_6_RELEASE.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/master/src/main/java/cn/yang/master/client/constant/ConfigConstants.java:
--------------------------------------------------------------------------------
1 | package cn.yang.master.client.constant;
2 |
3 | /**
4 | * @author Cool-Coding
5 | * 2018/7/25
6 | */
7 | public class ConfigConstants {
8 | /**
9 | * 配置文件名
10 | */
11 | public static final String CONFIG_FILE_PATH= "master-config.txt";
12 |
13 | /**
14 | * 判断鼠标是否双击延迟的时间
15 | */
16 | public static final String MOUSE_DOUBLE_CHECK_DELAY="mouse.double.check.delay";
17 |
18 | /**
19 | * 连接的服务器IP
20 | */
21 | public static final String SERVER_IP="server.ip";
22 |
23 | /**
24 | * 连接的服务器端口
25 | */
26 | public static final String SERVER_PORT="server.port";
27 | }
28 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__com_dyuproject_protostuff_protostuff_core_1_0_8.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/common/src/main/java/cn/yang/common/InputEvent/MouseButton.java:
--------------------------------------------------------------------------------
1 | package cn.yang.common.InputEvent;
2 |
3 |
4 | /**
5 | * @author cool-coding
6 | * @date 2018/7/28
7 | */
8 | public enum MouseButton {
9 | /**
10 | * 鼠标左键
11 | */
12 | LEFT,
13 |
14 | /**
15 | * 鼠标右键
16 | */
17 | RIGHT,
18 |
19 | /**
20 | * 鼠标滚轮
21 | */
22 | MIDDLE,
23 |
24 | /**
25 | * 拖动
26 | */
27 | DRAGGED,
28 |
29 | /**
30 | * 滚轮
31 | */
32 | WHEEL,
33 |
34 | /**
35 | * 单击
36 | */
37 | CLICK,
38 |
39 | /**
40 | * 按下
41 | */
42 | PRESSED,
43 |
44 | /**
45 | * 释放
46 | */
47 | RELEASED
48 | }
49 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__org_springframework_spring_beans_5_0_6_RELEASE.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__com_dyuproject_protostuff_protostuff_runtime_1_0_8.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__org_springframework_spring_context_5_0_6_RELEASE.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__org_springframework_spring_expression_5_0_6_RELEASE.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/modules.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__com_dyuproject_protostuff_protostuff_collectionschema_1_0_8.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/common/src/main/java/cn/yang/common/command/Commands.java:
--------------------------------------------------------------------------------
1 | package cn.yang.common.command;
2 |
3 | /**
4 | * @author cool-coding
5 | * 2018/7/27
6 | * 命令
7 | */
8 | public enum Commands{
9 | /**
10 | * 控制端或傀儡端连接服务器时的命令
11 | */
12 | CONNECT,
13 |
14 | /**
15 | * 控制命令
16 | * 1.主人向服务器发送控制请求
17 | * 2.服务器将控制命令发给傀儡
18 | * 3.傀儡收到控制命令,将向服务器发送截屏
19 | */
20 | CONTROL,
21 |
22 | /**
23 | * 傀儡发送心跳给服务器
24 | */
25 | HEARTBEAT,
26 |
27 | /**
28 | * 傀儡发送屏幕截图命令
29 | */
30 | SCREEN,
31 |
32 | /**
33 | * 控制端发送键盘事件
34 | */
35 | KEYBOARD,
36 |
37 | /**
38 | * 控制端发送鼠标事件
39 | */
40 | MOUSE,
41 |
42 | /**
43 | * 断开控制傀儡
44 | */
45 | TERMINATE,
46 |
47 | /**
48 | * 清晰度
49 | */
50 | QUALITY
51 | }
52 |
--------------------------------------------------------------------------------
/server/src/main/java/cn/yang/server/netty/ChannelPair.java:
--------------------------------------------------------------------------------
1 | package cn.yang.server.netty;
2 |
3 | import io.netty.channel.Channel;
4 |
5 | /**
6 | * @author Cool-Coding
7 | * @date 2018/7/24
8 | */
9 | public class ChannelPair {
10 | /**
11 | * 控制端通道
12 | */
13 | Channel masterChannel;
14 |
15 | /**
16 | * 傀儡端通道
17 | */
18 | Channel puppetChannel;
19 |
20 | public Channel getMasterChannel() {
21 | return masterChannel;
22 | }
23 |
24 | public void setMasterChannel(Channel masterChannel) {
25 | this.masterChannel = masterChannel;
26 | }
27 |
28 | public Channel getPuppetChannel() {
29 | return puppetChannel;
30 | }
31 |
32 | public void setPuppetChannel(Channel puppetChannel) {
33 | this.puppetChannel = puppetChannel;
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/common/src/main/java/cn/yang/common/dto/Response.java:
--------------------------------------------------------------------------------
1 | package cn.yang.common.dto;
2 |
3 | import cn.yang.common.exception.ServerException;
4 |
5 | /**
6 | * @author: cool coding
7 | * @date: 2018/1/7
8 | * 请求响应结果
9 | */
10 | public class Response extends Invocation {
11 | /**
12 | * 异常
13 | */
14 | private ServerException error;
15 |
16 | public ServerException getError() {
17 | return error;
18 | }
19 |
20 | public void setError(ServerException error) {
21 | this.error = error;
22 | }
23 |
24 | @Override
25 | public String toString() {
26 | return "Response{" +
27 | "id='" + getId() + '\'' +
28 | ", puppetName='" + getPuppetName() + '\'' +
29 | ", error=" + error +
30 | ", command=" + getCommand() +
31 | ", value=" + getValue() +
32 | '}';
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/server/src/main/java/cn/yang/server/ServerStarter.java:
--------------------------------------------------------------------------------
1 | package cn.yang.server;
2 |
3 | import cn.yang.server.netty.NettyServer;
4 | import org.slf4j.Logger;
5 | import org.slf4j.LoggerFactory;
6 | import org.springframework.context.support.ClassPathXmlApplicationContext;
7 |
8 |
9 | /**
10 | * @author Cool-Coding
11 | * 2018/7/25
12 | */
13 | public class ServerStarter {
14 | /** logger */
15 | private static final Logger LOGGER = LoggerFactory.getLogger(ServerStarter.class);
16 |
17 | public static void main(String[] args){
18 | final ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("server-beans.xml");
19 | context.start();
20 | /*
21 | * 将启动服务器放在spring初始化bean后,以便阻塞
22 | */
23 | try {
24 | context.getBean(NettyServer.class).start();
25 | }catch (Exception e){
26 | LOGGER.error(e.getMessage());
27 | }
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/master/src/main/java/cn/yang/master/client/constant/ExceptionMessageConstants.java:
--------------------------------------------------------------------------------
1 | package cn.yang.master.client.constant;
2 |
3 | /**
4 | * @author cool-coding
5 | * @date 2018/7/26
6 | */
7 | public class ExceptionMessageConstants {
8 | public static final String HANDLER_NOT_SUPPORTED = "Not supported channelHandler";
9 | public static final String PUPPET_NAME_EMPTY = "The puppet's name is required";
10 | public static final String MASTER_FIRE_COMMAND_ERROR = "Master can't handle this command";
11 | public static final String FIRE_COMMAND_HANDLE_ERROR = "Command is not a subclass of AbstractMasterFireCommandHandler";
12 | public static final String CONTRL_COMMAND_RESULT_ERROR= "The result of control command is not right.it should be a puppet name";
13 | public static final String CONNECTION_SERVER_FAILED = "Connecting to server is failed";
14 | public static final String LAUNCH_FAILED = "Startup error";
15 | }
16 |
--------------------------------------------------------------------------------
/puppet/src/main/proto/go_robot.proto:
--------------------------------------------------------------------------------
1 | syntax = "proto3";
2 | package service;
3 |
4 | message Point {
5 | uint32 x = 1;
6 | uint32 y = 2;
7 | }
8 |
9 | message MouseButton {
10 | uint32 x = 1;
11 | }
12 |
13 | message MouseScrolledRequest {
14 | uint32 distance = 2;
15 | }
16 |
17 | message Empty {
18 |
19 | }
20 |
21 | message CaptureScreenRequest {
22 | uint32 width = 1;
23 | uint32 height = 2;
24 | }
25 |
26 | message CaptureScreenResponse {
27 | bytes bitmap = 1;
28 | }
29 |
30 | service GoRobot {
31 | rpc MouseMove(Point) returns(Empty) {};
32 | rpc MouseClick(MouseButton) returns(Empty) {};
33 | rpc MouseDoubleClick(MouseButton) returns(Empty) {};
34 | rpc MousePressed(MouseButton) returns(Empty) {};
35 | rpc MouseReleased(MouseButton) returns(Empty) {};
36 | rpc MouseScrolledUp(MouseScrolledRequest) returns(Empty) {};
37 | rpc MouseScrolledDown(MouseScrolledRequest) returns(Empty) {};
38 | rpc CaptureScreen(CaptureScreenRequest) returns(stream CaptureScreenResponse) {};
39 | }
--------------------------------------------------------------------------------
/.idea/compiler.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/puppet/src/main/java/cn/yang/puppet/client/ui/MessageDialog.java:
--------------------------------------------------------------------------------
1 | package cn.yang.puppet.client.ui;
2 |
3 | import javax.swing.*;
4 | import java.awt.*;
5 |
6 | /**
7 | * @author Cool-Coding
8 | * 2018/8/3
9 | */
10 | public class MessageDialog extends JDialog {
11 | private JTextField message;
12 |
13 | public MessageDialog(String title) {
14 | setSize(400, 200);
15 | final Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
16 | setLocation(screenSize.width / 2, screenSize.height / 2);
17 | message = new JTextField();
18 | message.setFont(new Font("宋体", Font.PLAIN, 20));
19 | setTitle(title);
20 | add(message);
21 | setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
22 | }
23 |
24 | public void showMessage(String message) {
25 | SwingUtilities.invokeLater(() -> {
26 | this.message.setText(message);
27 | MessageDialog.this.setVisible(true);
28 | });
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/puppet/src/main/java/cn/yang/puppet/client/constant/ConfigConstants.java:
--------------------------------------------------------------------------------
1 | package cn.yang.puppet.client.constant;
2 |
3 | /**
4 | * @author Cool-Coding
5 | * 2018/7/25
6 | */
7 | public class ConfigConstants {
8 | /**
9 | * 配置文件名
10 | */
11 | public static final String CONFIG_FILE_PATH= "puppet-config.txt";
12 |
13 | public static final String HEARTBEAT_INTERVAL="heartbeat.interval";
14 | public static final String RECONNECT_INTERVAL="reconnect.interval";
15 | public static final String TASK_CHECK_INTERVAL="task.check.interval";
16 | public static final String SERVER_IP="server.ip";
17 | public static final String SERVER_PORT="server.port";
18 | public static final String ERROR_COUNT="error.count";
19 | public static final String SCREEN_REFRESH_FREQUENCY="screen.refresh.frequency";
20 |
21 | /**
22 | * goRobot 使用robotgo实现
23 | * javaRobot 使用java自带robot实现
24 | */
25 | public static final String ROBOT = "robot";
26 | public static final String GO_ROBOT_ENDPOINT = "go.robot.endpoint";
27 |
28 | }
29 |
--------------------------------------------------------------------------------
/master/src/main/java/cn/yang/master/client/commandhandler/AbstractMasterFireCommandHandler.java:
--------------------------------------------------------------------------------
1 | package cn.yang.master.client.commandhandler;
2 |
3 | import cn.yang.common.command.Commands;
4 | import cn.yang.common.dto.Response;
5 | import cn.yang.master.client.constant.ExceptionMessageConstants;
6 | import cn.yang.master.client.exception.FireCommandHandlerException;
7 | import io.netty.channel.ChannelHandlerContext;
8 |
9 | /**
10 | * @author Cool-Coding
11 | * 2018/7/27
12 | */
13 | public abstract class AbstractMasterFireCommandHandler extends AbstractMasterCommandHandler {
14 |
15 | @Override
16 | protected void handle0(ChannelHandlerContext ctx, Response response) throws Exception {
17 | throw new UnsupportedOperationException(String.format("%s %s", ExceptionMessageConstants.MASTER_FIRE_COMMAND_ERROR,response.getCommand()));
18 | }
19 |
20 | /**
21 | * 控制端向服务器发送命令
22 | * @param puppetName 傀儡名称
23 | * @param command 命令
24 | * @param data 数据
25 | *
26 | */
27 | public abstract void fire(String puppetName, Enum command, T data) throws FireCommandHandlerException;
28 | }
29 |
--------------------------------------------------------------------------------
/common/src/main/java/cn/yang/common/util/BeanUtil.java:
--------------------------------------------------------------------------------
1 | package cn.yang.common.util;
2 |
3 | import org.springframework.beans.BeansException;
4 | import org.springframework.beans.factory.BeanFactory;
5 | import org.springframework.beans.factory.BeanFactoryAware;
6 |
7 | /**
8 | * @author cool-coding
9 | * 2018/7/27
10 | * 获取bean的工作类
11 | */
12 | public class BeanUtil implements BeanFactoryAware {
13 | private static BeanFactory beanFactory;
14 |
15 | @Override
16 | public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
17 | BeanUtil.beanFactory=beanFactory;
18 |
19 | }
20 |
21 | @SuppressWarnings("unchecked")
22 | public static T getBean(Class aclass,String beanName){
23 | return (T)beanFactory.getBean(aclass,beanName);
24 | }
25 |
26 | public static T getBean(Class aclass){
27 | return (T)beanFactory.getBean(aclass);
28 | }
29 |
30 | public static T getBean(String name){
31 | return (T)beanFactory.getBean(name);
32 | }
33 |
34 | public static T getBean(Class aclass,Object... args){
35 | return (T)beanFactory.getBean(aclass,args);
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/puppet/src/main/java/cn/yang/puppet/client/constant/ExceptionMessageConstants.java:
--------------------------------------------------------------------------------
1 | package cn.yang.puppet.client.constant;
2 |
3 | /**
4 | * @author Cool-Coding
5 | * 2018/7/26
6 | */
7 | public class ExceptionMessageConstants {
8 | public static final String PUPPET_HANDLER_ERROR = "the puppet netty client handler must be PuppetNettyClientHandler";
9 | public static final String KEYBOARD_EVENT_ERROR = "The type of keyevent from server is wrong";
10 | public static final String KEYBOARD_EVENT_NULL = "The value of keyevent from server is null";
11 | public static final String MOUSE_EVENT_ERROR = "The type of mouseevent from server is wrong";
12 | public static final String MOUSE_EVENT_NULL = "The value of mouseevent from server is null";
13 | public static final String QUALITY_EVENT_VALUE_ERROR = "The value of quality from server is not the type Integer";
14 | public static final String QUALITY_EVENT_VALUE_NULL = "The value of quality from server is null";
15 | public static final String DISCONNECT_TO_SERVER = "Disconnect to server {}:{},will be reconnect to server in {} milliseconds";
16 | public static final String CAPTURE_SCREEN_ERROR = "capturing the screen is error";
17 |
18 | }
19 |
--------------------------------------------------------------------------------
/puppet/src/main/java/cn/yang/puppet/client/commandhandler/QualityCommandHandler.java:
--------------------------------------------------------------------------------
1 | package cn.yang.puppet.client.commandhandler;
2 |
3 | import cn.yang.common.dto.Response;
4 | import cn.yang.puppet.client.constant.ExceptionMessageConstants;
5 | import cn.yang.puppet.client.constant.PuppetDynamicSetting;
6 | import cn.yang.puppet.client.exception.NullValueException;
7 | import io.netty.channel.ChannelHandlerContext;
8 |
9 | /**
10 | * @author Cool-Coding
11 | * 2018/7/27
12 | */
13 | public class QualityCommandHandler extends AbstractPuppetCommandHandler {
14 |
15 |
16 | @Override
17 | protected void handle0(ChannelHandlerContext ctx, Response request) throws Exception {
18 | final Object result = request.getValue();
19 | if (result==null){
20 | error(request,ExceptionMessageConstants.QUALITY_EVENT_VALUE_NULL);
21 | throw new NullValueException(ExceptionMessageConstants.QUALITY_EVENT_VALUE_NULL);
22 | }
23 |
24 | if (!(request.getValue() instanceof Integer)){
25 | error(request,ExceptionMessageConstants.QUALITY_EVENT_VALUE_ERROR);
26 | throw new ClassCastException(ExceptionMessageConstants.QUALITY_EVENT_VALUE_ERROR);
27 | }
28 |
29 | PuppetDynamicSetting.quality = ((Integer)result);
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/server/src/main/java/cn/yang/server/netty/NettyServerHandler.java:
--------------------------------------------------------------------------------
1 | package cn.yang.server.netty;
2 |
3 | import cn.yang.common.command.handler.ICommandHandler;
4 | import cn.yang.common.dto.Request;
5 | import cn.yang.common.util.CommandHandlerLoader;
6 | import io.netty.channel.ChannelHandler;
7 | import io.netty.channel.ChannelHandlerContext;
8 | import io.netty.channel.SimpleChannelInboundHandler;
9 | import org.slf4j.Logger;
10 | import org.slf4j.LoggerFactory;
11 |
12 | /**
13 | * @author Cool-Coding 2018/7/24
14 | */
15 | @ChannelHandler.Sharable
16 | public class NettyServerHandler extends SimpleChannelInboundHandler {
17 |
18 | /** logger */
19 | private static final Logger LOGGER = LoggerFactory.getLogger(NettyServerHandler.class);
20 |
21 | @SuppressWarnings("unchecked")
22 | @Override
23 | protected void channelRead0(ChannelHandlerContext ctx, Request msg) throws Exception {
24 | LOGGER.debug(msg.toString());
25 | final ICommandHandler commandHandler = CommandHandlerLoader.getCommandHandler(msg.getCommand());
26 | commandHandler.handle(ctx,msg);
27 | }
28 |
29 | @Override
30 | public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
31 | LOGGER.info(cause.getMessage());
32 | ctx.close();
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/master/src/main/java/cn/yang/master/client/ui/IMasterDesktop.java:
--------------------------------------------------------------------------------
1 | package cn.yang.master.client.ui;
2 |
3 | import cn.yang.common.command.Commands;
4 | import cn.yang.common.netty.INettyClient;
5 | import cn.yang.master.client.exception.MasterClientException;
6 |
7 | /**
8 | * @author cool-coding
9 | * @date 2018/8/2
10 | */
11 | public interface IMasterDesktop extends INettyClient{
12 | /**
13 | * 桌面窗体设置
14 | */
15 | void setting();
16 |
17 | /**
18 | * 菜单
19 | */
20 | void initMenu();
21 |
22 | /**
23 | * 窗体
24 | */
25 | void initBody();
26 |
27 | /**
28 | * 启动
29 | */
30 | void lanuch();
31 |
32 | /**
33 | * 启动远程傀儡的屏幕
34 | * @param puppetName
35 | */
36 | void lanuch(String puppetName);
37 |
38 | /**
39 | * 刷新远程屏幕
40 | * @param puppetName 傀儡名
41 | * @param bytes 截屏字节数组或截屏部分字节
42 | */
43 | void refreshScreen(String puppetName,byte[] bytes);
44 |
45 | /**
46 | * 终止远程
47 | * @param puppetName 傀儡名
48 | */
49 | void terminate(String puppetName);
50 |
51 | /**
52 | * 发送命令
53 | * @param puppetName 傀儡名
54 | * @param command 命令
55 | * @param data 数据
56 | */
57 | void fireCommand(String puppetName,Enum command,Object data) throws MasterClientException;
58 | }
59 |
--------------------------------------------------------------------------------
/common/src/main/java/cn/yang/common/util/MacUtils.java:
--------------------------------------------------------------------------------
1 | package cn.yang.common.util;
2 |
3 | import org.slf4j.Logger;
4 | import org.slf4j.LoggerFactory;
5 |
6 | import java.net.NetworkInterface;
7 | import java.net.SocketException;
8 | import java.util.Enumeration;
9 |
10 | /**
11 | * @author Cool-Coding
12 | * 2018/7/25
13 | */
14 | public class MacUtils {
15 |
16 | /** logger */
17 | private static final Logger LOGGER = LoggerFactory.getLogger(MacUtils.class);
18 |
19 | public static String getMAC(){
20 | Enumeration el;
21 | String mac_s = "";
22 | try {
23 | el = NetworkInterface.getNetworkInterfaces();
24 | while (el.hasMoreElements()) {
25 | byte[] mac = el.nextElement().getHardwareAddress();
26 | if (mac == null) {
27 | continue;
28 | }
29 | mac_s = hexByte(mac[0]) + "-" + hexByte(mac[1]) + "-"
30 | + hexByte(mac[2]) + "-" + hexByte(mac[3]) + "-"
31 | + hexByte(mac[4]) + "-" + hexByte(mac[5]);
32 | }
33 | } catch (SocketException e1) {
34 | LOGGER.error(e1.getMessage(),e1);
35 | }
36 | return mac_s;
37 |
38 | }
39 |
40 | private static String hexByte(byte b) {
41 | String s = "000000" + Integer.toHexString(b);
42 | return s.substring(s.length() - 2);
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/server/dependency-reduced-pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | desktop-control-parent
5 | cn.yang.remote
6 | 1.0-SNAPSHOT
7 |
8 | 4.0.0
9 | server
10 |
11 | server
12 |
13 |
14 | maven-compiler-plugin
15 |
16 | 1.8
17 | 1.8
18 |
19 |
20 |
21 | maven-shade-plugin
22 | 3.2.1
23 |
24 |
25 | package
26 |
27 | shade
28 |
29 |
30 |
31 |
32 | cn.yang.server.ServerStarter
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
--------------------------------------------------------------------------------
/server/src/main/java/cn/yang/server/commandhandler/CommonFireCommandHandler.java:
--------------------------------------------------------------------------------
1 | package cn.yang.server.commandhandler;
2 |
3 | import cn.yang.common.constant.ExceptionMessageConstants;
4 | import cn.yang.common.dto.Request;
5 | import cn.yang.common.dto.Response;
6 | import cn.yang.server.netty.ChannelPair;
7 | import io.netty.channel.Channel;
8 | import io.netty.channel.ChannelHandlerContext;
9 |
10 | import static cn.yang.common.constant.ExceptionMessageConstants.PUPPET_CONNECTION_LOST;
11 |
12 | /**
13 | * @author Cool-Coding
14 | * 2018/7/27
15 | */
16 | public class CommonFireCommandHandler extends AbstractServerCommandHandler{
17 | @Override
18 | public void handle0(ChannelHandlerContext ctx, Request request) throws Exception {
19 | final String puppetName = request.getPuppetName();
20 |
21 | //检查傀儡端连接是否正常
22 | ChannelPair channelPair = CONNECTED_CHANNELPAIRS.get(puppetName);
23 | if (channelPair==null || channelPair.getPuppetChannel()==null || !channelPair.getPuppetChannel().isOpen()){
24 | error(request, ExceptionMessageConstants.PUPPET_CONNECTION_LOST);
25 | sendError(request, ctx,PUPPET_CONNECTION_LOST);
26 | return;
27 | }
28 |
29 | //发送数据
30 | final Channel puppetChannel = channelPair.getPuppetChannel();
31 | Response response;
32 | response = buildResponse(request,request.getCommand(),request.getValue());
33 | puppetChannel.writeAndFlush(response);
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/master/dependency-reduced-pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | desktop-control-parent
5 | cn.yang.remote
6 | 1.0-SNAPSHOT
7 |
8 | 4.0.0
9 | master
10 |
11 | master
12 |
13 |
14 | maven-compiler-plugin
15 |
16 | 1.8
17 | 1.8
18 |
19 |
20 |
21 | maven-shade-plugin
22 | 3.2.1
23 |
24 |
25 | package
26 |
27 | shade
28 |
29 |
30 |
31 |
32 | cn.yang.master.client.MasterStarter
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
--------------------------------------------------------------------------------
/master/src/main/java/cn/yang/master/client/commandhandler/ScreenCommandHandler.java:
--------------------------------------------------------------------------------
1 | package cn.yang.master.client.commandhandler;
2 |
3 | import cn.yang.common.dto.Response;
4 | import cn.yang.common.util.BeanUtil;
5 | import cn.yang.master.client.constant.MessageConstants;
6 | import cn.yang.master.client.ui.IMasterDesktop;
7 | import io.netty.channel.ChannelHandlerContext;
8 |
9 | /**
10 | * @author Cool-Coding
11 | * 2018/7/27
12 | *傀儡传过来的屏幕命令处理逻辑
13 | */
14 | public class ScreenCommandHandler extends AbstractMasterCommandHandler {
15 |
16 | @Override
17 | protected void handle0(ChannelHandlerContext ctx, Response response) throws Exception {
18 | refreshScreen(response);
19 | }
20 |
21 | private void refreshScreen(Response response){
22 | RefreshTask refreshTask = new RefreshTask(response);
23 | new Thread(refreshTask).start();
24 | }
25 |
26 | class RefreshTask implements Runnable {
27 | Response response;
28 |
29 | RefreshTask(Response response) {
30 | this.response = response;
31 | }
32 |
33 | @Override
34 | public void run() {
35 | debug(response, MessageConstants.RECEIVE_SCREEN_SNAPSHOT);
36 | if(response.getValue() instanceof byte[]) {
37 | byte[] bytes=(byte[])response.getValue();
38 | final IMasterDesktop desktop = BeanUtil.getBean(IMasterDesktop.class);
39 | desktop.refreshScreen(response.getPuppetName(),bytes);
40 | }
41 | }
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/puppet/src/main/java/cn/yang/puppet/client/commandhandler/KeyBoardEventCommandHandler.java:
--------------------------------------------------------------------------------
1 | package cn.yang.puppet.client.commandhandler;
2 |
3 | import cn.yang.common.InputEvent.MasterKeyEvent;
4 | import cn.yang.common.dto.Response;
5 | import cn.yang.puppet.client.constant.ExceptionMessageConstants;
6 | import cn.yang.puppet.client.exception.NullValueException;
7 | import io.netty.channel.ChannelHandlerContext;
8 |
9 | /**
10 | * @author Cool-Coding
11 | * 2018/7/27
12 | */
13 | public class KeyBoardEventCommandHandler extends AbstractPuppetCommandHandler {
14 |
15 |
16 | @Override
17 | protected void handle0(ChannelHandlerContext ctx, Response response) throws Exception {
18 | Object obj=response.getValue();
19 |
20 | if (obj==null){
21 | error(response, ExceptionMessageConstants.KEYBOARD_EVENT_NULL);
22 | throw new NullValueException(ExceptionMessageConstants.KEYBOARD_EVENT_NULL);
23 | }
24 |
25 | if (!(obj instanceof MasterKeyEvent)){
26 | error(response, ExceptionMessageConstants.KEYBOARD_EVENT_ERROR);
27 | throw new ClassCastException(ExceptionMessageConstants.KEYBOARD_EVENT_ERROR);
28 | }
29 |
30 | MasterKeyEvent keyEvent=(MasterKeyEvent)obj;
31 | debug(response,keyEvent.toString());
32 | if(keyEvent.isPressed()){
33 | REPLAY.keyPress(keyEvent);
34 | REPLAY.keyRelease(keyEvent);
35 | }else{
36 | //为了处理pressed之后的延迟,press后立即释放
37 | //REPLAY.keyRelease(keyEvent);
38 | }
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/server/src/main/java/cn/yang/server/commandhandler/TerminateCommandHandler.java:
--------------------------------------------------------------------------------
1 | package cn.yang.server.commandhandler;
2 |
3 | import cn.yang.common.constant.ExceptionMessageConstants;
4 | import cn.yang.common.dto.Request;
5 | import cn.yang.common.dto.Response;
6 | import cn.yang.server.netty.ChannelPair;
7 | import io.netty.channel.Channel;
8 | import io.netty.channel.ChannelHandlerContext;
9 |
10 | import static cn.yang.common.constant.ExceptionMessageConstants.PUPPET_CONNECTION_LOST;
11 |
12 | /**
13 | * @author Cool-Coding
14 | * 2018/7/27
15 | */
16 | public class TerminateCommandHandler extends AbstractServerCommandHandler{
17 | @Override
18 | public void handle0(ChannelHandlerContext ctx, Request request) throws Exception {
19 | final String puppetName = request.getPuppetName();
20 |
21 | //检查傀儡端连接是否正常
22 | ChannelPair channelPair = CONNECTED_CHANNELPAIRS.get(puppetName);
23 | if (channelPair==null || channelPair.getPuppetChannel()==null || !channelPair.getPuppetChannel().isOpen()){
24 | error(request, ExceptionMessageConstants.PUPPET_CONNECTION_LOST);
25 | sendError(request, ctx,PUPPET_CONNECTION_LOST);
26 | return;
27 | }
28 |
29 | // 删除链接
30 | channelPair.setMasterChannel(null);
31 |
32 | //发送数据
33 | final Channel puppetChannel = channelPair.getPuppetChannel();
34 | Response response=null;
35 | response = buildResponse(request,request.getCommand(),request.getValue());
36 | puppetChannel.writeAndFlush(response);
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/common/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 | desktop-control-parent
7 | cn.yang.remote
8 | 1.0-SNAPSHOT
9 |
10 | 4.0.0
11 |
12 | common
13 |
14 |
15 |
16 |
17 |
18 | com.dyuproject.protostuff
19 | protostuff-core
20 | 1.0.8
21 |
22 |
23 |
24 | com.dyuproject.protostuff
25 | protostuff-runtime
26 | 1.0.8
27 |
28 |
29 |
30 |
31 | org.objenesis
32 | objenesis
33 | 2.1
34 |
35 |
36 |
37 |
38 | net.coobird
39 | thumbnailator
40 | 0.4.8
41 |
42 |
43 |
--------------------------------------------------------------------------------
/puppet/src/main/java/cn/yang/puppet/client/ui/IReplay.java:
--------------------------------------------------------------------------------
1 | package cn.yang.puppet.client.ui;
2 |
3 | import cn.yang.common.InputEvent.MasterKeyEvent;
4 | import cn.yang.common.InputEvent.MasterMouseEvent;
5 |
6 | /**
7 | * @author Cool-Coding
8 | * 2018/8/2
9 | */
10 | public interface IReplay {
11 | /**
12 | * 键按下
13 | * @param keyEvent
14 | */
15 | void keyPress(MasterKeyEvent keyEvent);
16 |
17 | /**
18 | * 键释放
19 | * @param keyEvent
20 | */
21 | void keyRelease(MasterKeyEvent keyEvent);
22 |
23 | /**
24 | * 鼠标单击
25 | * @param mouseEvent
26 | */
27 | void mouseClick(MasterMouseEvent mouseEvent);
28 |
29 | /**
30 | * 滚轮滚动
31 | * @param mouseEvent
32 | */
33 | void mouseWheel(MasterMouseEvent mouseEvent);
34 |
35 | /**
36 | * 鼠标键按下
37 | * @param mouseEvent
38 | */
39 | void mousePress(MasterMouseEvent mouseEvent);
40 |
41 | /**
42 | * 鼠标键释放
43 | * @param mouseEvent
44 | */
45 | void mouseRelease(MasterMouseEvent mouseEvent);
46 |
47 | /**
48 | * 鼠标移动
49 | * @param site
50 | */
51 | void mouseMove(int[] site);
52 |
53 | /**
54 | * 鼠标双击
55 | * @param mouseEvent
56 | */
57 | void mouseDoubleClick(MasterMouseEvent mouseEvent);
58 |
59 | /**
60 | * 鼠标拖动
61 | * @param mouseEvent
62 | * @param site
63 | */
64 | void mouseDragged(MasterMouseEvent mouseEvent, int[] site);
65 |
66 |
67 | /**
68 | * 截屏
69 | * @return 图像字节数组
70 | */
71 | byte[] getScreenSnapshot();
72 | }
73 |
--------------------------------------------------------------------------------
/common/src/main/java/cn/yang/common/serialization/ProtobufEncoder.java:
--------------------------------------------------------------------------------
1 | package cn.yang.common.serialization;
2 |
3 | import cn.yang.common.dto.Request;
4 | import cn.yang.common.dto.Response;
5 | import cn.yang.common.util.SerializationUtil;
6 | import io.netty.buffer.ByteBuf;
7 | import io.netty.channel.ChannelHandlerContext;
8 | import io.netty.handler.codec.MessageToByteEncoder;
9 | import org.slf4j.Logger;
10 | import org.slf4j.LoggerFactory;
11 |
12 | /**
13 | * User:cool coding
14 | * Date:2018/1/7
15 | * Time:21:33
16 | * 编码
17 | */
18 | public class ProtobufEncoder extends MessageToByteEncoder {
19 | private Class> genericClass;
20 |
21 | public ProtobufEncoder(Class> genericClass) {
22 | this.genericClass = genericClass;
23 | }
24 | private static final Logger LOGGER= LoggerFactory.getLogger(ProtobufEncoder.class);
25 |
26 | @Override
27 | protected void encode(ChannelHandlerContext ctx, Object in, ByteBuf out) throws Exception {
28 | if(genericClass.isInstance(in)){
29 | byte[] data= SerializationUtil.serialize(in);
30 | int length=data.length;
31 | out.writeInt(length);
32 | out.writeBytes(data);
33 | if (genericClass== Request.class) {
34 | LOGGER.debug("send data to server,size:{}", length);
35 | }else if(genericClass== Response.class){
36 | LOGGER.debug("send data to client,size:{}",length);
37 | }
38 |
39 | }
40 | }
41 |
42 | @Override
43 | public boolean isSharable() {
44 | return super.isSharable();
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/server/src/main/resources/server-beans.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
--------------------------------------------------------------------------------
/desktop-control-parent.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/common/src/main/java/cn/yang/common/dto/Invocation.java:
--------------------------------------------------------------------------------
1 | package cn.yang.common.dto;
2 |
3 | import cn.yang.common.command.Commands;
4 |
5 | import java.io.Serializable;
6 |
7 | /**
8 | * @author: cool coding
9 | * @date: 2018/1/7
10 | * 控制端/服务器/傀儡端 三者之间传输的对象
11 | */
12 | public class Invocation implements Serializable {
13 |
14 | /**
15 | * ID(客户端标识(控制端为'M',傀儡端为'P')+MAC地址+序列号)
16 | */
17 | private String id;
18 |
19 | /**
20 | * 傀儡名
21 | */
22 | private String puppetName;
23 |
24 |
25 | /**
26 | * 命令
27 | */
28 | private Enum command;
29 |
30 | /**
31 | * 值
32 | */
33 | private Object value;
34 |
35 | public String getId() {
36 | return id;
37 | }
38 |
39 | public void setId(String id) {
40 | this.id = id;
41 | }
42 |
43 | public void setValue(Object value) {
44 | this.value = value;
45 | }
46 |
47 | public Enum getCommand() {
48 | return command;
49 | }
50 |
51 | public void setCommand(Enum command) {
52 | this.command = command;
53 | }
54 |
55 | public Object getValue() {
56 | return value;
57 | }
58 |
59 | public String getPuppetName() {
60 | return puppetName;
61 | }
62 |
63 | public void setPuppetName(String puppetName) {
64 | this.puppetName = puppetName;
65 | }
66 |
67 | @Override
68 | public String toString() {
69 | return "Invocation{" +
70 | "id='" + id + '\'' +
71 | ", puppetName='" + puppetName + '\'' +
72 | ", command=" + command +
73 | ", value=" + value +
74 | '}';
75 | }
76 | }
77 |
--------------------------------------------------------------------------------
/common/src/main/java/cn/yang/common/netty/ChannelInitializer.java:
--------------------------------------------------------------------------------
1 | package cn.yang.common.netty;
2 |
3 | import cn.yang.common.serialization.ProtobufDecoder;
4 | import cn.yang.common.serialization.ProtobufEncoder;
5 | import io.netty.channel.ChannelHandler;
6 | import io.netty.channel.socket.SocketChannel;
7 |
8 | /**
9 | * @author Cool-Coding
10 | * 2018/7/25
11 | * 使用单例,由Spring管理
12 | */
13 | public class ChannelInitializer extends io.netty.channel.ChannelInitializer {
14 |
15 | /**
16 | * 处理器
17 | */
18 | private ChannelHandler channelHandler;
19 |
20 | private Class> requestClass;
21 | private Class> responseClass;
22 |
23 | public ChannelInitializer(Class> requestClass, Class> responseClass){
24 | this.requestClass=requestClass;
25 | this.responseClass=responseClass;
26 | }
27 |
28 | /**
29 | * 每新建一个连接,都添加一遍encode/decoder/channelHandler,会报错:不是@Sharable
30 | * 但是如果在每个类上添加@Shareable注解,由于encoder、decoder继承ByteToMessageDecoder,
31 | * 而ByteToMessageDecoder的子类不允许有@Sharable注解,所以encoder和decoder采用新建对象的方式
32 | * @param ch
33 | * @throws Exception
34 | */
35 | @Override
36 | protected void initChannel(SocketChannel ch) throws Exception {
37 | ch.pipeline()
38 | .addLast(new ProtobufDecoder(requestClass))
39 | .addLast(new ProtobufEncoder(responseClass))
40 | .addLast(channelHandler);
41 | }
42 |
43 | public void setChannelHandler(ChannelHandler channelHandler) {
44 | this.channelHandler = channelHandler;
45 | }
46 |
47 | public ChannelHandler getChannelHandler() {
48 | return channelHandler;
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/common/src/main/java/cn/yang/common/InputEvent/MasterKeyEvent.java:
--------------------------------------------------------------------------------
1 | package cn.yang.common.InputEvent;
2 |
3 | /**
4 | * @author Cool-Coding
5 | * 2018/7/26
6 | */
7 | public class MasterKeyEvent {
8 |
9 | /**
10 | * 按键状态
11 | * TRUE.按下
12 | * FALSE.释放
13 | */
14 | private boolean pressed;
15 |
16 | private boolean altDown;
17 | private boolean ctrlDown;
18 | private boolean shiftDown;
19 |
20 | private int keyCode;
21 |
22 | public boolean isPressed() {
23 | return pressed;
24 | }
25 |
26 | public void setPressed(boolean pressed) {
27 | this.pressed = pressed;
28 | }
29 |
30 | public boolean isAltDown() {
31 | return altDown;
32 | }
33 |
34 | public void setAltDown(boolean altDown) {
35 | this.altDown = altDown;
36 | }
37 |
38 | public boolean isCtrlDown() {
39 | return ctrlDown;
40 | }
41 |
42 | public void setCtrlDown(boolean ctrlDown) {
43 | this.ctrlDown = ctrlDown;
44 | }
45 |
46 | public boolean isShiftDown() {
47 | return shiftDown;
48 | }
49 |
50 | public void setShiftDown(boolean shiftDown) {
51 | this.shiftDown = shiftDown;
52 | }
53 |
54 | public int getKeyCode() {
55 | return keyCode;
56 | }
57 |
58 | public void setKeyCode(int keyCode) {
59 | this.keyCode = keyCode;
60 | }
61 |
62 | @Override
63 | public String toString() {
64 | return "MasterKeyEvent{" +
65 | "pressed=" + pressed +
66 | ", altDown=" + altDown +
67 | ", ctrlDown=" + ctrlDown +
68 | ", shiftDown=" + shiftDown +
69 | ", keyCode=" + keyCode +
70 | '}';
71 | }
72 | }
73 |
--------------------------------------------------------------------------------
/common/src/main/java/cn/yang/common/constant/ExceptionMessageConstants.java:
--------------------------------------------------------------------------------
1 | package cn.yang.common.constant;
2 |
3 | /**
4 | * @author Cool-Coding
5 | * @date 2018/7/24
6 | */
7 | public class ExceptionMessageConstants {
8 | public static final String WRONG_CLIENT_TYPE ="reqestId must start with 'M'(master) 或 'P'(puppet)";
9 | public static final String REQUIRED_REQUESTID ="requestId is required";
10 | public static final String CONNECTION_EXIST ="the same connection exists";
11 | public static final String WRONG_CONNECT_VALUE ="wrong connection value";
12 | public static final String MASTER_CONNECTION_LOST ="connection of master is lost";
13 | public static final String PUPPET_CONNECTION_LOST ="connection of puppet is lost";
14 | public static final String CONNECT_PUPPET_FAILED ="connect puppet failed";
15 | public static final String REQUIRED_PUPPET_NAME ="the puppet name is required";
16 | public static final String REQUIRED_COMMAND ="command is required";
17 | public static final String COMMAND_HANDLER_ERROR ="CommandHandler must implements ICommandHandler and only have one interface";
18 | public static final String COMMAND_HANDLER_NOT_FOUND ="CommandHandler is not found";
19 | public static final String EXTENSION_NOT_FOUND ="sequence generator is not found";
20 | public static final String COMMANDHANDLERS_FILE_NOT_FOUND ="the file of commandhandlers is not found";
21 | public static final String COMMANDHANDLERS_FILE_CONFIG_ERROR="the file of commandhandlers is configured incorrect";
22 | public static final String ILLEGAL_STATUS ="illegal status";
23 | }
24 |
--------------------------------------------------------------------------------
/server/src/main/java/cn/yang/server/commandhandler/ScreenCommandHandler.java:
--------------------------------------------------------------------------------
1 | package cn.yang.server.commandhandler;
2 |
3 | import cn.yang.common.command.Commands;
4 | import cn.yang.common.dto.Request;
5 | import cn.yang.server.netty.ChannelPair;
6 | import io.netty.channel.Channel;
7 | import io.netty.channel.ChannelHandlerContext;
8 |
9 | import static cn.yang.common.constant.ExceptionMessageConstants.MASTER_CONNECTION_LOST;
10 | import static cn.yang.common.constant.ExceptionMessageConstants.WRONG_CONNECT_VALUE;
11 |
12 | /**
13 | * @author Cool-Coding
14 | * 2018/7/27
15 | */
16 | public class ScreenCommandHandler extends AbstractServerCommandHandler {
17 | @Override
18 | public void handle0(ChannelHandlerContext ctx, Request request) throws Exception {
19 | final String puppetName = request.getPuppetName();
20 |
21 | //检查请求的内容
22 | if(!(request.getValue() instanceof byte[])){
23 | final String should_be_bufferedImage = String.format("%s %s %s", WRONG_CONNECT_VALUE, request.getValue(), "should be BufferedImage");
24 | error(request,should_be_bufferedImage);
25 | sendError(request,ctx,should_be_bufferedImage);
26 | return;
27 | }
28 |
29 | //检查控制端连接是否正常
30 | final ChannelPair channelPair = CONNECTED_CHANNELPAIRS.get(puppetName);
31 | if (channelPair==null || channelPair.getMasterChannel()==null || !channelPair.getMasterChannel().isOpen()){
32 | error(request,MASTER_CONNECTION_LOST);
33 | sendError(request,ctx,MASTER_CONNECTION_LOST);
34 | return;
35 | }
36 |
37 | final Channel masterChannel = channelPair.getMasterChannel();
38 | masterChannel.writeAndFlush(buildResponse(request, Commands.SCREEN,request.getValue()));
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/master/src/main/java/cn/yang/master/client/commandhandler/ControlFireCommandHandler.java:
--------------------------------------------------------------------------------
1 | package cn.yang.master.client.commandhandler;
2 |
3 | import cn.yang.common.command.Commands;
4 | import cn.yang.common.dto.Request;
5 | import cn.yang.common.dto.Response;
6 | import cn.yang.common.exception.CommandHandlerException;
7 | import cn.yang.common.util.BeanUtil;
8 | import cn.yang.master.client.constant.ExceptionMessageConstants;
9 | import cn.yang.master.client.exception.ConnectionException;
10 | import cn.yang.master.client.exception.FireCommandHandlerException;
11 | import cn.yang.master.client.ui.IMasterDesktop;
12 | import io.netty.channel.ChannelHandlerContext;
13 |
14 | /**
15 | * @author Cool-Coding
16 | * 2018/7/27
17 | */
18 | public class ControlFireCommandHandler extends AbstractMasterFireCommandHandler {
19 |
20 | @Override
21 | protected void handle0(ChannelHandlerContext ctx, Response response) throws Exception {
22 | if(response.getValue() instanceof String) {
23 | //控制成功后,创建一个PuppetScreen对象,准备显示Puppet屏幕
24 | final IMasterDesktop desktop = BeanUtil.getBean(IMasterDesktop.class);
25 | desktop.lanuch((String) response.getValue());
26 | }else{
27 | throw new CommandHandlerException(ExceptionMessageConstants.CONTRL_COMMAND_RESULT_ERROR);
28 | }
29 | }
30 |
31 | @Override
32 | public void fire(String puppetName,Enum command,String puppetName2) throws FireCommandHandlerException {
33 | if (puppetName==null){
34 | throw new FireCommandHandlerException(ExceptionMessageConstants.PUPPET_NAME_EMPTY);
35 | }
36 |
37 | final Request request = buildRequest(Commands.CONTROL, puppetName, null);
38 | try {
39 | sendRequest(request);
40 | }catch (ConnectionException e){
41 | throw new FireCommandHandlerException(e);
42 | }
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/common/src/main/java/cn/yang/common/serialization/ProtobufDecoder.java:
--------------------------------------------------------------------------------
1 | package cn.yang.common.serialization;
2 |
3 | import cn.yang.common.dto.Request;
4 | import cn.yang.common.dto.Response;
5 | import cn.yang.common.util.SerializationUtil;
6 | import io.netty.buffer.ByteBuf;
7 | import io.netty.channel.ChannelHandlerContext;
8 | import io.netty.handler.codec.ByteToMessageDecoder;
9 | import org.slf4j.Logger;
10 | import org.slf4j.LoggerFactory;
11 |
12 | import java.util.List;
13 |
14 | /**
15 | * User:cool coding
16 | * Date:2018/1/7
17 | * Time:21:27
18 | * 解码
19 | */
20 | public class ProtobufDecoder extends ByteToMessageDecoder {
21 | private Class> genericClass;
22 |
23 | public ProtobufDecoder(Class> genericClass) {
24 | this.genericClass = genericClass;
25 | }
26 | private static final Logger LOGGER= LoggerFactory.getLogger(ProtobufDecoder.class);
27 |
28 | @Override
29 | protected void decode(ChannelHandlerContext ctx, ByteBuf in, List