diff --git a/mirai-core/src/main/java/net/mamoe/mirai/MiraiServer.java b/mirai-core/src/main/java/net/mamoe/mirai/MiraiServer.java index d23136e22..8378e2cc1 100644 --- a/mirai-core/src/main/java/net/mamoe/mirai/MiraiServer.java +++ b/mirai-core/src/main/java/net/mamoe/mirai/MiraiServer.java @@ -84,16 +84,17 @@ public class MiraiServer { this.setting = new MiraiConfig(setting); } - int port = this.setting.getMapSection("network").getInt("port"); - MiraiNetwork.start(port); - Thread.yield(); - if(MiraiNetwork.getLastError()!=null){ - this.getLogger().log(LoggerTextFormat.RED + "an error occurred when staring network layer"); - this.shutdown(); - } - - this.getLogger().log(LoggerTextFormat.SKY_BLUE + "Listening on port " + port); + MiraiMapSection qqs = this.setting.getMapSection("qq"); + qqs.forEach((a,p) -> { + this.getLogger().log(LoggerTextFormat.SKY_BLUE + "Finding available ports between " + "1-65536"); + try { + int port = MiraiNetwork.getAvailablePort(); + this.getLogger().log(LoggerTextFormat.SKY_BLUE + "Listening on port " + port); + } catch (IOException e) { + e.printStackTrace(); + } + }); } public void initSetting(File setting){ @@ -108,7 +109,7 @@ public class MiraiServer { } this.setting = new MiraiConfig(setting); MiraiMapSection network = this.setting.getMapSection("network"); - network.put("port",19139); + MiraiMapSection qqs = this.setting.getMapSection("qq"); Scanner scanner = new Scanner(System.in); this.getLogger().log(LoggerTextFormat.SKY_BLUE + "input one " + LoggerTextFormat.RED + " QQ number " + LoggerTextFormat.SKY_BLUE +"for default robot"); diff --git a/mirai-core/src/main/java/net/mamoe/mirai/network/MiraiNetwork.java b/mirai-core/src/main/java/net/mamoe/mirai/network/MiraiNetwork.java index f71b1b475..75d8ba2d9 100644 --- a/mirai-core/src/main/java/net/mamoe/mirai/network/MiraiNetwork.java +++ b/mirai-core/src/main/java/net/mamoe/mirai/network/MiraiNetwork.java @@ -1,67 +1,20 @@ package net.mamoe.mirai.network; import io.netty.bootstrap.ServerBootstrap; -import io.netty.channel.ChannelInitializer; -import io.netty.channel.ChannelPipeline; -import io.netty.channel.EventLoopGroup; -import io.netty.channel.nio.NioEventLoopGroup; -import io.netty.channel.socket.SocketChannel; -import io.netty.channel.socket.nio.NioServerSocketChannel; -import io.netty.handler.codec.bytes.ByteArrayDecoder; -import io.netty.handler.codec.bytes.ByteArrayEncoder; import lombok.Getter; -import net.mamoe.mirai.MiraiServer; -import net.mamoe.mirai.event.events.server.ServerDisableEvent; + import java.io.IOException; import java.net.ServerSocket; public class MiraiNetwork { - private static ServerBootstrap server; - private static Thread thread; @Getter private static volatile Throwable lastError = null; public static void start(int port){ - thread = new Thread(() -> { - if (server != null) { - throw new RuntimeException("there is already a ServerBootstrap instance"); - } - EventLoopGroup bossGroup = new NioEventLoopGroup(); - EventLoopGroup workerGroup = new NioEventLoopGroup(); - try { - server = new ServerBootstrap(); - server.group(bossGroup, workerGroup); - server.channel(NioServerSocketChannel.class); - //b.option(ChannelOption.SO_BACKLOG, 100); - //b.handler(new LoggingHandler(LogLevel.INFO)); - server.childHandler(new ChannelInitializer<SocketChannel>() { - @Override - protected void initChannel(SocketChannel ch) throws Exception { - ChannelPipeline pipeline = ch.pipeline(); - pipeline.addLast("bytesDecoder", new ByteArrayDecoder()); - pipeline.addLast("bytesEncoder", new ByteArrayEncoder()); - pipeline.addLast("handler", new NetworkPacketHandler()); - } - }); - - - server.bind(port).sync().channel().closeFuture().sync(); - } catch (InterruptedException e) { - e.printStackTrace(); - lastError = e; - } finally { - bossGroup.shutdownGracefully(); - workerGroup.shutdownGracefully(); - } - }); - thread.start(); - MiraiServer.getInstance().getEventManager().onEvent(ServerDisableEvent.class).setHandler(a -> { - thread.interrupt(); - }); } diff --git a/mirai-core/src/main/java/net/mamoe/mirai/network/MiraiUDPClient.java b/mirai-core/src/main/java/net/mamoe/mirai/network/MiraiUDPClient.java new file mode 100644 index 000000000..64f16e5f3 --- /dev/null +++ b/mirai-core/src/main/java/net/mamoe/mirai/network/MiraiUDPClient.java @@ -0,0 +1,47 @@ +package net.mamoe.mirai.network; + +import java.io.IOException; +import java.io.UnsupportedEncodingException; +import java.net.*; +import java.nio.charset.StandardCharsets; + +public class MiraiUDPClient { + private DatagramSocket localUDPSocket; + private Thread thread; + public MiraiUDPClient(InetAddress target, int targetPort, int localPort) { + 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(); + } + } + 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); + } +} +