This commit is contained in:
Him188moe 2019-08-16 00:23:58 +08:00
parent 20a322a0a0
commit 14ffda6ae2
6 changed files with 101 additions and 232 deletions

View File

@ -5,9 +5,7 @@ import lombok.extern.log4j.Log4j2;
import net.mamoe.mirai.event.MiraiEventManager;
import net.mamoe.mirai.event.events.server.ServerDisableEvent;
import net.mamoe.mirai.event.events.server.ServerEnableEvent;
import net.mamoe.mirai.network.MiraiNetwork;
import net.mamoe.mirai.network.MiraiUDPClient;
import net.mamoe.mirai.network.MiraiUDPServer;
import net.mamoe.mirai.network.Robot;
import net.mamoe.mirai.task.MiraiTaskManager;
import net.mamoe.mirai.utils.LoggerTextFormat;
import net.mamoe.mirai.utils.config.MiraiConfig;
@ -16,9 +14,6 @@ import org.apache.logging.log4j.Logger;
import java.io.File;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.InetAddress;
import java.nio.charset.StandardCharsets;
import java.util.Scanner;
@Log4j2
@ -99,8 +94,12 @@ public class MiraiServer {
});
*/
new Robot(1994701021L);
/*
System.out.println("network test");
try {
MiraiUDPServer server = new MiraiUDPServer();
MiraiUDPClient client = new MiraiUDPClient(InetAddress.getLocalHost(),9999,MiraiNetwork.getAvailablePort());
this.getTaskManager().repeatingTask(() -> {
@ -113,7 +112,7 @@ public class MiraiServer {
},300);
} catch (IOException e) {
e.printStackTrace();
}
}*/
}
public void initSetting(File setting){

View File

@ -1,67 +0,0 @@
package net.mamoe.mirai.network
import io.netty.channel.ChannelHandlerContext
import io.netty.channel.SimpleChannelInboundHandler
import lombok.extern.log4j.Log4j2
import net.mamoe.mirai.MiraiServer
import net.mamoe.mirai.network.packet.server.ServerPacket
/**
* @author Him188moe @ Mirai Project
*/
@Log4j2
class ClientHandler(val robot: Robot) : SimpleChannelInboundHandler<ByteArray>() {
private object Reader {
private var length: Int? = null
private lateinit var bytes: ByteArray
fun init(bytes: ByteArray) {
this.length = bytes.size
this.bytes = bytes
}
/**
* Reads bytes, combining them to create a packet, returning remaining bytes.
*/
fun read(bytes: ByteArray): ByteArray? {
checkNotNull(this.length)
val needSize = length!! - this.bytes.size;//How many bytes we need
if (needSize == bytes.size || needSize > bytes.size) {
this.bytes += bytes
return null;
}
//We got more than we need
this.bytes += bytes.copyOfRange(0, needSize)
return bytes.copyOfRange(needSize, bytes.size - needSize)//We got remaining bytes, that is of another packet
}
fun isPacketAvailable() = this.length == this.bytes.size
fun toServerPacket(): ServerPacket {
return ServerPacket.ofByteArray(this.bytes)
}
}
override fun channelRead0(ctx: ChannelHandlerContext?, bytes: ByteArray) {
try {
/*val remaining = Reader.read(bytes);
if (Reader.isPacketAvailable()) {
robot.onPacketReceived(Reader.toServerPacket())
Reader.init()
remaining
}*/
robot.onPacketReceived(ServerPacket.ofByteArray(bytes))
} catch (e: Exception) {
MiraiServer.getLogger().catching(e)
}
}
override fun channelActive(ctx: ChannelHandlerContext) {
println("Successfully connected to server")
}
override fun exceptionCaught(ctx: ChannelHandlerContext, cause: Throwable) {
MiraiServer.getLogger().catching(cause)
}
}

View File

@ -1,52 +0,0 @@
package net.mamoe.mirai.network;
import io.netty.bootstrap.Bootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.codec.bytes.ByteArrayDecoder;
import io.netty.handler.codec.bytes.ByteArrayEncoder;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
public class MiraiNetwork {
public static void connect(String host, int port) throws InterruptedException {
EventLoopGroup group = new NioEventLoopGroup();
try {
Bootstrap b = new Bootstrap();
b.group(group)
.channel(NioSocketChannel.class)
.remoteAddress(new InetSocketAddress(host, port))
.handler(new ChannelInitializer<SocketChannel>() {
@Override
protected void initChannel(SocketChannel ch) throws Exception {
System.out.println("connected server...");
ch.pipeline().addLast(new ByteArrayEncoder());
ch.pipeline().addLast(new ByteArrayDecoder());
ch.pipeline().addLast(new ClientHandler());
}
});
ChannelFuture cf = b.connect().sync();
cf.channel().closeFuture().sync();
} finally {
group.shutdownGracefully().sync();
}
}
public static int getAvailablePort() throws IOException {
ServerSocket serverSocket = new ServerSocket(0); //读取空闲的可用端口
int port = serverSocket.getLocalPort();
serverSocket.close();
return port;
}
}

View File

@ -1,55 +0,0 @@
package net.mamoe.mirai.network;
import lombok.extern.log4j.Log4j2;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.nio.charset.StandardCharsets;
@Log4j2
public class MiraiUDPClient {
private DatagramSocket localUDPSocket;
private Thread thread;
public MiraiUDPClient(InetAddress target, int targetPort, int localPort) {
log.info("creating client");
try{
this.localUDPSocket = new DatagramSocket(localPort);
this.localUDPSocket.connect(target,targetPort);
this.localUDPSocket.setReuseAddress(true);
this.thread = new Thread(() -> {
try {
while (true) {
byte[] data = new byte[1024];
// 接收数据报的包
DatagramPacket packet = new DatagramPacket(data, data.length);
DatagramSocket localUDPSocket = MiraiUDPClient.this.localUDPSocket;
if ((localUDPSocket == null) || (localUDPSocket.isClosed())) continue;
// 阻塞直到收到数据
localUDPSocket.receive(packet);
// 解析服务端发过来的数据
MiraiUDPClient.this.onReceive(packet);
}
} catch (Exception e) {
e.printStackTrace();
}
});
this.thread.start();
} catch (SocketException e) {
e.printStackTrace();
}
log.info("created client");
}
public void onReceive(DatagramPacket packet){
System.out.println(new String(packet.getData(), 0 , packet.getLength(), StandardCharsets.UTF_8));
}
public void send(DatagramPacket packet) throws IOException {
this.localUDPSocket.send(packet);
}
}

View File

@ -1,51 +0,0 @@
package net.mamoe.mirai.network;
import io.netty.bootstrap.Bootstrap;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.DatagramPacket;
import io.netty.channel.socket.nio.NioDatagramChannel;
import io.netty.util.CharsetUtil;
import lombok.extern.log4j.Log4j2;
@Log4j2
public class MiraiUDPServer {
public MiraiUDPServer() {
log.info("creating server");
new Thread(() -> {
Bootstrap b = new Bootstrap();
EventLoopGroup group = new NioEventLoopGroup();
b.group(group)
.channel(NioDatagramChannel.class)
.handler(new SimpleChannelInboundHandler<DatagramPacket>() {
protected void channelRead0(ChannelHandlerContext ctx, DatagramPacket packet)
throws Exception {
// 读取收到的数据
ByteBuf buf = packet.copy().content();
byte[] req = new byte[buf.readableBytes()];
buf.readBytes(req);
String body = new String(req, CharsetUtil.UTF_8);
System.out.println("【NOTE】>>>>>> 收到客户端的数据:" + body);
// 回复一条信息给客户端
ctx.writeAndFlush(new DatagramPacket(
Unpooled.copiedBuffer("Hello我是Server我的时间戳是" + System.currentTimeMillis()
, CharsetUtil.UTF_8)
, packet.sender())).sync();
}
});
// 服务端监听在9999端口
try {
b.bind(9999).sync().channel().closeFuture().await();
} catch (InterruptedException e) {
e.printStackTrace();
}
}).start();
log.info("created server");
}
}

View File

@ -1,9 +1,21 @@
package net.mamoe.mirai.network
import io.netty.bootstrap.Bootstrap
import io.netty.channel.ChannelHandlerContext
import io.netty.channel.ChannelInitializer
import io.netty.channel.SimpleChannelInboundHandler
import io.netty.channel.nio.NioEventLoopGroup
import io.netty.channel.socket.SocketChannel
import io.netty.channel.socket.nio.NioSocketChannel
import io.netty.handler.codec.bytes.ByteArrayDecoder
import io.netty.handler.codec.bytes.ByteArrayEncoder
import lombok.extern.log4j.Log4j2
import net.mamoe.mirai.MiraiServer
import net.mamoe.mirai.network.packet.Packet
import net.mamoe.mirai.network.packet.client.Client0825ResponsePacket
import net.mamoe.mirai.network.packet.server.Server0825Packet
import net.mamoe.mirai.network.packet.server.ServerPacket
import java.net.InetSocketAddress
/**
* [number] is a QQ number.
@ -26,4 +38,87 @@ class Robot(val number: Long) {
private fun sendPacket(packet: Packet) {
TODO()
}
@Throws(InterruptedException::class)
fun connect(host: String, port: Int) {
val group = NioEventLoopGroup()
try {
val b = Bootstrap()
b.group(group)
.channel(NioSocketChannel::class.java)
.remoteAddress(InetSocketAddress(host, port))
.handler(object : ChannelInitializer<SocketChannel>() {
@Throws(Exception::class)
override fun initChannel(ch: SocketChannel) {
println("connected server...")
ch.pipeline().addLast(ByteArrayEncoder())
ch.pipeline().addLast(ByteArrayDecoder())
ch.pipeline().addLast(ClientHandler(this@Robot))
}
})
val cf = b.connect().sync()
cf.channel().closeFuture().sync()
} finally {
group.shutdownGracefully().sync()
}
}
@Log4j2
private class ClientHandler(val robot: Robot) : SimpleChannelInboundHandler<ByteArray>() {
private object Reader {
private var length: Int? = null
private lateinit var bytes: ByteArray
fun init(bytes: ByteArray) {
this.length = bytes.size
this.bytes = bytes
}
/**
* Reads bytes, combining them to create a packet, returning remaining bytes.
*/
fun read(bytes: ByteArray): ByteArray? {
checkNotNull(this.length)
val needSize = length!! - this.bytes.size;//How many bytes we need
if (needSize == bytes.size || needSize > bytes.size) {
this.bytes += bytes
return null;
}
//We got more than we need
this.bytes += bytes.copyOfRange(0, needSize)
return bytes.copyOfRange(needSize, bytes.size - needSize)//We got remaining bytes, that is of another packet
}
fun isPacketAvailable() = this.length == this.bytes.size
fun toServerPacket(): ServerPacket {
return ServerPacket.ofByteArray(this.bytes)
}
}
override fun channelRead0(ctx: ChannelHandlerContext?, bytes: ByteArray) {
try {
/*val remaining = Reader.read(bytes);
if (Reader.isPacketAvailable()) {
robot.onPacketReceived(Reader.toServerPacket())
Reader.init()
remaining
}*/
robot.onPacketReceived(ServerPacket.ofByteArray(bytes))
} catch (e: Exception) {
MiraiServer.getLogger().catching(e)
}
}
override fun channelActive(ctx: ChannelHandlerContext) {
println("Successfully connected to server")
}
override fun exceptionCaught(ctx: ChannelHandlerContext, cause: Throwable) {
MiraiServer.getLogger().catching(cause)
}
}
}