diff --git a/pom.xml b/pom.xml index 414e057..8d36c2a 100644 --- a/pom.xml +++ b/pom.xml @@ -35,6 +35,7 @@ 1.1.12 1.1.6 1.0.2 + 1.0.1 @@ -130,6 +131,11 @@ poi-ooxml ${poi.version} + + top.focess + focess-socket + ${socket.version} + diff --git a/src/main/java/top/focess/qq/FocessQQ.java b/src/main/java/top/focess/qq/FocessQQ.java index f3c3c3c..51ddc40 100755 --- a/src/main/java/top/focess/qq/FocessQQ.java +++ b/src/main/java/top/focess/qq/FocessQQ.java @@ -6,6 +6,15 @@ import org.checkerframework.checker.nullness.qual.Nullable; import org.jetbrains.annotations.UnmodifiableView; import top.focess.command.CommandResult; +import top.focess.net.IllegalPortException; +import top.focess.net.receiver.FocessClientReceiver; +import top.focess.net.receiver.FocessReceiver; +import top.focess.net.receiver.FocessUDPMultiReceiver; +import top.focess.net.receiver.FocessUDPReceiver; +import top.focess.net.socket.FocessSidedClientSocket; +import top.focess.net.socket.FocessSidedSocket; +import top.focess.net.socket.FocessSocket; +import top.focess.net.socket.FocessUDPSocket; import top.focess.qq.api.bot.Bot; import top.focess.qq.api.bot.BotLoginException; import top.focess.qq.api.bot.BotManager; @@ -29,10 +38,13 @@ import top.focess.qq.api.event.chat.ConsoleChatEvent; import top.focess.qq.api.event.server.ServerStartEvent; import top.focess.qq.api.event.server.ServerStopEvent; -import top.focess.qq.api.net.*; +import top.focess.qq.api.net.ClientReceiver; +import top.focess.qq.api.net.ServerMultiReceiver; +import top.focess.qq.api.net.ServerReceiver; +import top.focess.qq.api.net.Socket; import top.focess.qq.api.plugin.Plugin; import top.focess.qq.api.plugin.PluginLoadException; -import top.focess.qq.api.schedule.Schedulers; +import top.focess.qq.api.scheduler.Schedulers; import top.focess.qq.api.util.IOHandler; import top.focess.qq.api.util.config.LangConfig; import top.focess.qq.api.util.logger.FocessLogger; @@ -42,7 +54,6 @@ import top.focess.qq.core.listeners.ChatListener; import top.focess.qq.core.listeners.ConsoleListener; import top.focess.qq.core.listeners.PluginListener; -import top.focess.qq.core.net.*; import top.focess.qq.core.permission.Permission; import top.focess.qq.core.permission.PermissionEnv; import top.focess.qq.core.plugin.PluginClassLoader; @@ -169,33 +180,28 @@ private static boolean hasNextLine() { /** * The default socket */ - @Nullable - private static Socket socket; + private static @Nullable Socket socket; /** * The default udp socket */ - @Nullable - private static Socket udpSocket; + private static @Nullable Socket udpSocket; /** * The default udp server receiver */ - @Nullable - private static ServerReceiver udpServerReceiver; + private static @Nullable ServerReceiver udpServerReceiver; /** * The default server receiver */ - @Nullable - private static ServerReceiver serverReceiver; + + private static @Nullable ServerReceiver serverReceiver; /** * The default client receiver */ - @Nullable - private static ClientReceiver clientReceiver; + private static @Nullable ClientReceiver clientReceiver; /** * The default server multi receiver */ - @Nullable - private static ServerMultiReceiver udpServerMultiReceiver; + private static @Nullable ServerMultiReceiver udpServerMultiReceiver; /** * The Mirai Bot user or we call it QQ number */ @@ -278,33 +284,27 @@ public static BotManager getBotManager() { return botManager; } - @Nullable - public static Socket getSocket() { + public static @Nullable Socket getSocket() { return socket; } - @Nullable - public static ServerReceiver getServerReceiver() { + public static @Nullable ServerReceiver getServerReceiver() { return serverReceiver; } - @Nullable - public static ClientReceiver getClientReceiver() { + public static @Nullable ClientReceiver getClientReceiver() { return clientReceiver; } - @Nullable - public static Socket getUdpSocket() { + public static @Nullable Socket getUdpSocket() { return udpSocket; } - @Nullable - public static ServerReceiver getUdpServerReceiver() { + public static @Nullable ServerReceiver getUdpServerReceiver() { return udpServerReceiver; } - @Nullable - public static ServerMultiReceiver getUdpServerMultiReceiver() { + public static @Nullable ServerMultiReceiver getUdpServerMultiReceiver() { return udpServerMultiReceiver; } @@ -462,8 +462,10 @@ public static void main(final String[] args) { if (sidedOption == null) try { final FocessSocket focessSocket = new FocessSocket(option.get(IntegerOptionType.INTEGER_OPTION_TYPE)); - focessSocket.registerReceiver(serverReceiver = new FocessReceiver(focessSocket)); - socket = focessSocket; + FocessReceiver receiver = new FocessReceiver(focessSocket); + focessSocket.registerReceiver(receiver); + serverReceiver = new ServerReceiver(receiver); + socket = new Socket(focessSocket); getLogger().infoLang("create-focess-socket-server"); } catch (final Exception e) { getLogger().thrLang("exception-create-focess-socket-server", e); @@ -471,8 +473,8 @@ public static void main(final String[] args) { else { try { final FocessSidedSocket focessSidedSocket = new FocessSidedSocket(option.get(IntegerOptionType.INTEGER_OPTION_TYPE)); - focessSidedSocket.registerReceiver(serverReceiver = new FocessSidedReceiver()); - socket = focessSidedSocket; + serverReceiver = new ServerReceiver(focessSidedSocket.getReceiver()); + socket = new Socket(focessSidedSocket); getLogger().infoLang("create-focess-sided-socket-server"); } catch (final Exception e) { getLogger().thrLang("exception-create-focess-sided-socket-server", e); @@ -488,8 +490,10 @@ public static void main(final String[] args) { final String host = option.get(OptionType.DEFAULT_OPTION_TYPE); final int port = option.get(IntegerOptionType.INTEGER_OPTION_TYPE); final String name = option.get(OptionType.DEFAULT_OPTION_TYPE); - focessSocket.registerReceiver(clientReceiver = new FocessClientReceiver(focessSocket, localhost, host, port, name)); - socket = focessSocket; + FocessClientReceiver receiver = new FocessClientReceiver(focessSocket, localhost, host, port, name); + focessSocket.registerReceiver(receiver); + clientReceiver = new ClientReceiver(receiver); + socket = new Socket(focessSocket); getLogger().infoLang("create-focess-socket-client"); } catch (final Exception e) { getLogger().thrLang("exception-create-focess-socket-client", e); @@ -499,9 +503,9 @@ public static void main(final String[] args) { final String host = option.get(OptionType.DEFAULT_OPTION_TYPE); final int port = option.get(IntegerOptionType.INTEGER_OPTION_TYPE); final String name = option.get(OptionType.DEFAULT_OPTION_TYPE); - final FocessSidedClientSocket focessSidedClientSocket = new FocessSidedClientSocket(host, port); - focessSidedClientSocket.registerReceiver(clientReceiver = new FocessSidedClientReceiver(focessSidedClientSocket, name)); - socket = focessSidedClientSocket; + final FocessSidedClientSocket focessSidedClientSocket = new FocessSidedClientSocket(host, port, name); + clientReceiver = new ClientReceiver(focessSidedClientSocket.getReceiver()); + socket = new Socket(focessSidedClientSocket); getLogger().infoLang("create-focess-sided-socket-client"); } catch (final Exception e) { getLogger().thrLang("exception-create-focess-sided-socket-client", e); @@ -512,11 +516,17 @@ public static void main(final String[] args) { if (option != null) { try { final FocessUDPSocket focessUDPSocket = new FocessUDPSocket(option.get(IntegerOptionType.INTEGER_OPTION_TYPE)); - if (multiOption == null) - focessUDPSocket.registerReceiver(udpServerReceiver = new FocessUDPReceiver(focessUDPSocket)); - else - focessUDPSocket.registerReceiver(udpServerMultiReceiver = new FocessUDPMultiReceiver(focessUDPSocket)); - udpSocket = focessUDPSocket; + if (multiOption == null) { + FocessUDPReceiver receiver = new FocessUDPReceiver(focessUDPSocket); + focessUDPSocket.registerReceiver(receiver); + udpServerReceiver = new ServerReceiver(receiver); + } + else { + FocessUDPMultiReceiver receiver = new FocessUDPMultiReceiver(focessUDPSocket); + focessUDPSocket.registerReceiver(receiver); + udpServerMultiReceiver = new ServerMultiReceiver(receiver); + } + udpSocket = new Socket(focessUDPSocket); getLogger().infoLang("create-focess-udp-socket-client"); } catch (final IllegalPortException e) { getLogger().thrLang("exception-create-focess-udp-socket-client", e); @@ -573,6 +583,7 @@ public static void exit() { Thread.sleep(5000); } catch (InterruptedException e) { } + System.err.println("Force Shutdown"); System.exit(0); }).start(); } @@ -652,6 +663,7 @@ public void enable() { this.registerCommand(new ExecCommand()); this.registerCommand(new PauseCommand()); this.registerCommand(new TestCommand()); + this.registerCommand(new PermissionCommand()); getLogger().debugLang("register-default-commands"); this.registerSpecialArgumentComplexHandler("previous", new PreviousArgumentHandler()); this.registerSpecialArgumentComplexHandler("next", new NextArgumentHandler()); diff --git a/src/main/java/top/focess/qq/api/command/CommandLine.java b/src/main/java/top/focess/qq/api/command/CommandLine.java index 17ca232..52985e5 100644 --- a/src/main/java/top/focess/qq/api/command/CommandLine.java +++ b/src/main/java/top/focess/qq/api/command/CommandLine.java @@ -7,7 +7,7 @@ import top.focess.command.CommandResult; import top.focess.qq.FocessQQ; import top.focess.qq.api.plugin.Plugin; -import top.focess.qq.api.schedule.Schedulers; +import top.focess.qq.api.scheduler.Schedulers; import top.focess.qq.api.util.IOHandler; import top.focess.qq.core.permission.Permission; import top.focess.qq.core.permission.PermissionEnv; diff --git a/src/main/java/top/focess/qq/api/event/EventManager.java b/src/main/java/top/focess/qq/api/event/EventManager.java index 1befabb..d14f48a 100644 --- a/src/main/java/top/focess/qq/api/event/EventManager.java +++ b/src/main/java/top/focess/qq/api/event/EventManager.java @@ -3,7 +3,7 @@ import com.google.common.collect.Maps; import org.jetbrains.annotations.NotNull; import top.focess.qq.FocessQQ; -import top.focess.qq.api.schedule.Schedulers; +import top.focess.qq.api.scheduler.Schedulers; import top.focess.qq.core.debug.Section; import top.focess.qq.core.permission.Permission; import top.focess.qq.core.permission.PermissionEnv; diff --git a/src/main/java/top/focess/qq/api/net/Client.java b/src/main/java/top/focess/qq/api/net/Client.java deleted file mode 100644 index c0b4d61..0000000 --- a/src/main/java/top/focess/qq/api/net/Client.java +++ /dev/null @@ -1,22 +0,0 @@ -package top.focess.qq.api.net; - -/** - * Represents a Client connected to a server. - */ -public interface Client { - - - /** - * Get the client name - * - * @return the client name - */ - String getName(); - - /** - * Get the client id - * - * @return the client id - */ - int getId(); -} diff --git a/src/main/java/top/focess/qq/api/net/ClientReceiver.java b/src/main/java/top/focess/qq/api/net/ClientReceiver.java index 4acb207..afb62d6 100644 --- a/src/main/java/top/focess/qq/api/net/ClientReceiver.java +++ b/src/main/java/top/focess/qq/api/net/ClientReceiver.java @@ -1,70 +1,85 @@ package top.focess.qq.api.net; -import top.focess.qq.api.net.packet.Packet; +import com.google.common.collect.Lists; +import com.google.common.collect.Maps; +import top.focess.net.PackHandler; +import top.focess.net.packet.Packet; import top.focess.qq.api.plugin.Plugin; +import top.focess.qq.core.permission.Permission; +import top.focess.qq.core.permission.PermissionEnv; -/** - * The socket receiver for client. - */ -public interface ClientReceiver extends Receiver { - - /** - * Send the packet to the server - * - * @param packet the packet - */ - void sendPacket(Packet packet); - - /** - * Register packet handler for server - * - * @param c the packet class - * @param packHandler the packet handler - * @param plugin the plugin - * @param the packet type - */ - void register(Plugin plugin, Class c, PackHandler packHandler); - - - /** - * Get the name of the client - * - * @return the name of the client - */ - String getName(); - - /** - * Get the target host of the client - * - * @return the target host of the client - */ - String getHost(); - - /** - * Get the target port of the client - * - * @return the target port of the client - */ - int getPort(); - - /** - * Indicate this client has connected to a server - * - * @return true if the client has connected to a server, false otherwise - */ - boolean isConnected(); - - /** - * Get the client id - * - * @return the client id - */ - int getClientId(); - - /** - * Get the client token - * - * @return the client token - */ - String getClientToken(); +import java.util.List; +import java.util.Map; + +@PermissionEnv(values = {Permission.SEND_PACKET, Permission.RECEIVE_PACKET}) +public class ClientReceiver { + + private final Map, List>> handlers = Maps.newConcurrentMap(); + + private final top.focess.net.receiver.ClientReceiver receiver; + + public ClientReceiver(top.focess.net.receiver.ClientReceiver receiver) { + this.receiver = receiver; + } + + public void close() { + receiver.close(); + this.handlers.clear(); + } + + public void unregisterAll() { + receiver.unregisterAll(); + this.handlers.clear(); + } + + public void unregister(Plugin plugin) { + Map, List> handlers = this.handlers.getOrDefault(plugin, Maps.newConcurrentMap()); + handlers.values().forEach(v->v.forEach(receiver::unregister)); + this.handlers.remove(plugin); + } + + public void sendPacket(Packet packet) { + Permission.checkPermission(Permission.SEND_PACKET); + receiver.sendPacket(packet); + } + + public void register(Plugin plugin, Class packet, PackHandler packHandler) { + Permission.checkPermission(Permission.RECEIVE_PACKET); + handlers.compute(plugin, (k,v)->{ + if (v == null) + v = Maps.newConcurrentMap(); + v.compute(packet, (k1,v1)->{ + if (v1 == null) + v1 = Lists.newArrayList(); + v1.add(packHandler); + return v1; + }); + return v; + }); + receiver.register(packet,packHandler); + } + + public String getName() { + return receiver.getName(); + } + + public String getHost() { + return receiver.getHost(); + } + + public int getPort() { + return receiver.getPort(); + } + + public boolean isConnected() { + return receiver.isConnected(); + } + + public int getClientId() { + return receiver.getClientId(); + } + + public String getClientToken() { + return receiver.getClientToken(); + } } diff --git a/src/main/java/top/focess/qq/api/net/IllegalPortException.java b/src/main/java/top/focess/qq/api/net/IllegalPortException.java deleted file mode 100644 index 31afc6d..0000000 --- a/src/main/java/top/focess/qq/api/net/IllegalPortException.java +++ /dev/null @@ -1,17 +0,0 @@ -package top.focess.qq.api.net; - -import java.io.IOException; - -/** - * Thrown to indicate this port is not available - */ -public class IllegalPortException extends IOException { - /** - * Constructs a IllegalPortException - * - * @param port the unavailable port - */ - public IllegalPortException(final int port) { - super("The " + port + " is not available."); - } -} diff --git a/src/main/java/top/focess/qq/api/net/PackHandler.java b/src/main/java/top/focess/qq/api/net/PackHandler.java deleted file mode 100644 index a4dafbe..0000000 --- a/src/main/java/top/focess/qq/api/net/PackHandler.java +++ /dev/null @@ -1,19 +0,0 @@ -package top.focess.qq.api.net; - -import top.focess.qq.api.net.packet.Packet; - -/** - * Represents a packet handler to define how to handle packet. - * - * @param the packet type - * This is a functional interface whose functional method is {@link PackHandler#handle(Packet)} - */ -public interface PackHandler { - - /** - * Used to handle the packet - * - * @param packet the packet - */ - void handle(T packet); -} diff --git a/src/main/java/top/focess/qq/api/net/PacketPreCodec.java b/src/main/java/top/focess/qq/api/net/PacketPreCodec.java deleted file mode 100644 index 3d60900..0000000 --- a/src/main/java/top/focess/qq/api/net/PacketPreCodec.java +++ /dev/null @@ -1,272 +0,0 @@ -package top.focess.qq.api.net; - -import com.google.common.collect.Lists; -import com.google.common.collect.Maps; -import com.google.common.primitives.Bytes; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; -import top.focess.qq.FocessQQ; -import top.focess.qq.api.net.packet.*; - -import java.nio.charset.StandardCharsets; -import java.util.List; -import java.util.Map; - -/** - * This class is used to prehandle the packet. - */ -public class PacketPreCodec { - - private static final Map> PACKET_CODECS = Maps.newHashMap(); - - static { - register(MessagePacket.PACKET_ID, new MessagePacketCodec()); - register(HeartPacket.PACKET_ID, new HeartPacketCodec()); - register(ConnectPacket.PACKET_ID, new ConnectPacketCodec()); - register(ConnectedPacket.PACKET_ID, new ConnectedPacketCodec()); - register(DisconnectPacket.PACKET_ID, new DisconnectPacketCodec()); - register(DisconnectedPacket.PACKET_ID, new DisconnectedPacketCodec()); - register(ClientPackPacket.PACKET_ID, new ClientPackPacketCodec()); - register(ServerPackPacket.PACKET_ID, new ServerPackPacketCodec()); - register(SidedConnectPacket.PACKET_ID, new SidedConnectPacketCodec()); - register(WaitPacket.PACKET_ID, new WaitPacketCodec()); - } - - private final List data = Lists.newArrayList(); - - private int pointer; - - /** - * Register the packet codec for the special packet id - * - * @param packetId the packet id - * @param packetCodec the packet codec - * @param the packet type - */ - public static void register(final int packetId, final PacketCodec packetCodec) { - PACKET_CODECS.put(packetId, packetCodec); - } - - /** - * Read a integer - * - * @return the integer read from precodec - */ - public int readInt() { - int r = 0; - for (int i = 0; i < 4; i++) - r += Byte.toUnsignedInt(this.data.get(this.pointer++)) << (i * 8); - return r; - } - - /** - * Read a long - * - * @return the long read from precodec - */ - public long readLong() { - long r = 0L; - for (int i = 0; i < 8; i++) - r += Byte.toUnsignedLong(this.data.get(this.pointer++)) << (i * 8L); - return r; - } - - /** - * Write a integer - * - * @param v the integer - */ - public void writeInt(int v) { - for (int i = 0; i < 4; i++) { - this.data.add((byte) (v & 0xFF)); - v >>>= 8; - } - } - - /** - * Write a long - * - * @param v the long - */ - public void writeLong(long v) { - for (int i = 0; i < 8; i++) { - this.data.add((byte) (v & 0xFFL)); - v >>>= 8; - } - } - - /** - * Write a string - * - * @param v the string - */ - public void writeString(@NotNull final String v) { - final byte[] bytes = v.getBytes(StandardCharsets.UTF_8); - this.writeInt(bytes.length); - this.data.addAll(Bytes.asList(bytes)); - } - - /** - * Read a string - * - * @return the string read from precodec - */ - public String readString() { - final int length = this.readInt(); - final byte[] bytes = new byte[length]; - for (int i = 0; i < length; i++) - bytes[i] = this.data.get(this.pointer++); - return new String(bytes, StandardCharsets.UTF_8); - } - - /** - * Write a float - * - * @param v the float - */ - public void writeFloat(final float v) { - this.writeInt(Float.floatToIntBits(v)); - } - - /** - * Read a float - * - * @return the float read from precodec - */ - public float readFloat() { - return Float.intBitsToFloat(this.readInt()); - } - - /** - * Write a double - * - * @param v the double - */ - public void writeDouble(final double v) { - this.writeLong(Double.doubleToLongBits(v)); - } - - /** - * Read a double - * - * @return the double read from precodec - */ - public double readDouble() { - return Double.longBitsToDouble(this.readLong()); - } - - /** - * Read a byte - * - * @return the byte read from precodec - */ - public byte readByte() { - return this.data.get(this.pointer++); - } - - /** - * Write a byte - * - * @param b the byte - */ - public void writeByte(final byte b) { - this.data.add(b); - } - - /** - * Read a short - * - * @return the short read from precodec - */ - public short readShort() { - short r = 0; - for (int i = 0; i < 2; i++) - // still the right side is short even if not cast to short - // because two bytes are used to represent a short - r += (short)((short) Byte.toUnsignedInt(this.data.get(this.pointer++)) << (i * 8)); - return r; - } - - /** - * Write a short - * - * @param v the short - */ - public void writeShort(short v) { - for (int i = 0; i < 2; i++) { - this.data.add((byte) (v & 0xFF)); - v >>>= 8; - } - } - - /** - * Get all bytes of the packet - * - * @return all bytes of the packet - */ - public byte[] getBytes() { - return Bytes.toArray(this.data); - } - - /** - * Read a packet - * - * @return the packet read from precodec - */ - @Nullable - public Packet readPacket() { - final int packetId; - try { - packetId = this.readInt(); - } catch (final Exception e) { - return null; - } - final PacketCodec packetCodec = PACKET_CODECS.get(packetId); - if (packetCodec != null) - return packetCodec.readPacket(this); - FocessQQ.getLogger().debugLang("unknown-packet", packetId); - return null; - } - - /** - * Write a packet - * - * @param packet the packet - * @param the packet type - * @return true if the packet has been written successfully, false otherwise - */ - public boolean writePacket(@NotNull final T packet) { - final int packetId = packet.getId(); - final PacketCodec packetCodec = (PacketCodec) PACKET_CODECS.get(packetId); - if (packetCodec != null) { - this.writeInt(packetId); - packetCodec.writePacket(packet, this); - return true; - } else FocessQQ.getLogger().debugLang("unknown-packet", packetId); - return false; - } - - /** - * Push the data to the precodec - * - * @param buffer the data - * @param offset the offset of the data - * @param length the length of the data - * @see #push(byte[], int) - */ - public void push(final byte[] buffer, final int offset, final int length) { - for (int i = offset; i < length; i++) - this.data.add(buffer[i]); - } - - /** - * Push the data to the precodec - * - * @param buffer the data - * @param length the length of the data - * @see #push(byte[], int, int) - */ - public void push(final byte[] buffer, final int length) { - this.push(buffer, 0, length); - } -} diff --git a/src/main/java/top/focess/qq/api/net/Receiver.java b/src/main/java/top/focess/qq/api/net/Receiver.java deleted file mode 100644 index 299b6d7..0000000 --- a/src/main/java/top/focess/qq/api/net/Receiver.java +++ /dev/null @@ -1,30 +0,0 @@ -package top.focess.qq.api.net; - -import top.focess.qq.api.plugin.Plugin; - -/** - * The class is used to handle packet. - */ -public interface Receiver { - - /** - * Close the receiver. - * - * @return true if there is some resources not closed before, false otherwise - */ - boolean close(); - - /** - * Unregister the packet handlers of the plugin - * - * @param plugin the plugin - */ - void unregister(Plugin plugin); - - /** - * Unregister all the packet handlers - * - * @return true if there are some packet-handlers not belonging to MainPlugin not been unregistered, false otherwise - */ - boolean unregisterAll(); -} diff --git a/src/main/java/top/focess/qq/api/net/ServerMultiReceiver.java b/src/main/java/top/focess/qq/api/net/ServerMultiReceiver.java index c50f5e4..fc9c3bf 100644 --- a/src/main/java/top/focess/qq/api/net/ServerMultiReceiver.java +++ b/src/main/java/top/focess/qq/api/net/ServerMultiReceiver.java @@ -1,29 +1,28 @@ package top.focess.qq.api.net; import org.jetbrains.annotations.UnmodifiableView; -import top.focess.qq.api.net.packet.Packet; +import top.focess.net.Client; +import top.focess.net.packet.Packet; +import top.focess.qq.core.permission.Permission; +import top.focess.qq.core.permission.PermissionEnv; import java.util.List; -/** - * The socket multi receiver for server. - */ -public interface ServerMultiReceiver extends ServerReceiver { - - /** - * Send packet to the special client - * - * @param id the client id - * @param packet the packet - */ - void sendPacket(int id, Packet packet); - - /** - * Get the list of the clients with given name - * - * @param name the client name - * @return the list of the clients with given name - */ - @UnmodifiableView - List getClients(String name); +@PermissionEnv(values = {Permission.SEND_PACKET}) +public class ServerMultiReceiver extends ServerReceiver { + + + public ServerMultiReceiver(top.focess.net.receiver.ServerMultiReceiver receiver) { + super(receiver); + } + + public void sendPacket(int i, Packet packet) { + Permission.checkPermission(Permission.SEND_PACKET); + ((top.focess.net.receiver.ServerMultiReceiver)receiver).sendPacket(i,packet); + } + + public @UnmodifiableView List getClients(String s) { + return ((top.focess.net.receiver.ServerMultiReceiver)receiver).getClients(s); + } + } diff --git a/src/main/java/top/focess/qq/api/net/ServerReceiver.java b/src/main/java/top/focess/qq/api/net/ServerReceiver.java index e974cc2..75d868b 100644 --- a/src/main/java/top/focess/qq/api/net/ServerReceiver.java +++ b/src/main/java/top/focess/qq/api/net/ServerReceiver.java @@ -1,49 +1,76 @@ package top.focess.qq.api.net; +import com.google.common.collect.Lists; +import com.google.common.collect.Maps; import org.jetbrains.annotations.Nullable; -import top.focess.qq.api.net.packet.Packet; +import top.focess.net.Client; +import top.focess.net.PackHandler; +import top.focess.net.packet.Packet; import top.focess.qq.api.plugin.Plugin; +import top.focess.qq.core.permission.Permission; +import top.focess.qq.core.permission.PermissionEnv; -/** - * The socket receiver for server. - */ -public interface ServerReceiver extends Receiver { - - /** - * Send packet to the special client - * - * @param client the client name - * @param packet the packet - */ - void sendPacket(String client, Packet packet); - - /** - * Register packet handler for special client - * - * @param client the client name - * @param c the packet class - * @param packHandler the packet handler - * @param plugin the plugin - * @param the packet type - */ - void register(Plugin plugin, String client, Class c, PackHandler packHandler); - - - /** - * Indicate the client is connected to server - * - * @param client the client name - * @return true if the client is connected to server, false otherwise - */ - boolean isConnected(String client); - - /** - * Get the client by given name - * - * @param name the client name - * @return the client - */ - @Nullable - Client getClient(String name); +import java.util.List; +import java.util.Map; +@PermissionEnv(values = {Permission.SEND_PACKET, Permission.RECEIVE_PACKET}) +public class ServerReceiver { + + protected final top.focess.net.receiver.ServerReceiver receiver; + + private final Map, List>>> handlers = Maps.newConcurrentMap(); + + public ServerReceiver(top.focess.net.receiver.ServerReceiver receiver) { + this.receiver = receiver; + } + + public void sendPacket(String s, Packet packet) { + Permission.checkPermission(Permission.SEND_PACKET); + receiver.sendPacket(s,packet); + } + + public void unregister(Plugin plugin) { + Map, List>> handlers = this.handlers.getOrDefault(plugin, Maps.newConcurrentMap()); + handlers.values().forEach(v->v.values().forEach(v1->v1.forEach(receiver::unregister))); + this.handlers.remove(plugin); + } + + public void register(Plugin plugin, String client, Class packet, PackHandler packHandler) { + Permission.checkPermission(Permission.RECEIVE_PACKET); + handlers.compute(plugin, (k,v)->{ + if (v == null) + v = Maps.newConcurrentMap(); + v.compute(client, (k1,v1)->{ + if (v1 == null) + v1 = Maps.newConcurrentMap(); + v1.compute(packet, (k2,v2)->{ + if (v2 == null) + v2 = Lists.newArrayList(); + v2.add(packHandler); + return v2; + }); + return v1; + }); + return v; + }); + receiver.register(client,packet,packHandler); + } + + public boolean isConnected(String client) { + return receiver.isConnected(client); + } + + public @Nullable Client getClient(String client) { + return receiver.getClient(client); + } + + public void close() { + receiver.close(); + this.handlers.clear(); + } + + public void unregisterAll() { + receiver.unregisterAll(); + this.handlers.clear(); + } } diff --git a/src/main/java/top/focess/qq/api/net/Socket.java b/src/main/java/top/focess/qq/api/net/Socket.java index f7150b4..facdbb2 100644 --- a/src/main/java/top/focess/qq/api/net/Socket.java +++ b/src/main/java/top/focess/qq/api/net/Socket.java @@ -1,44 +1,54 @@ package top.focess.qq.api.net; +import com.google.common.collect.Lists; +import com.google.common.collect.Maps; +import top.focess.net.receiver.Receiver; import top.focess.qq.api.plugin.Plugin; -/** - * Represents a FocessSocket. This class is used to handle socket. - */ -public interface Socket { - - /** - * Register packet receiver for this socket - * - * @param receiver the packet receiver for this socket - */ - void registerReceiver(Receiver receiver); - - /** - * Indicate this socket contains server side receiver - * - * @return true if it contains server side receiver, false otherwise - */ - boolean containsServerSide(); - - /** - * Indicate this socket contains client side receiver - * - * @return true if it contains client side receiver, false otherwise - */ - boolean containsClientSide(); - - /** - * Close the socket - * - * @return true if there is some resources not closed before, false otherwise - */ - boolean close(); - - /** - * Unregister the packet-handlers of the plugin - * - * @param plugin the plugin - */ - void unregister(Plugin plugin); +import java.util.List; +import java.util.Map; + +public class Socket { + + private final top.focess.net.socket.Socket socket; + + private final Map> receivers = Maps.newConcurrentMap(); + + public Socket(top.focess.net.socket.Socket socket) { + this.socket = socket; + } + + public void registerReceiver(Plugin plugin, Receiver receiver) { + receivers.compute(plugin, (k,v)->{ + if (v == null) + v = Lists.newCopyOnWriteArrayList(); + v.add(receiver); + return v; + }); + this.socket.registerReceiver(receiver); + } + + public boolean containsServerSide() { + return this.socket.containsServerSide(); + } + + public boolean containsClientSide() { + return this.socket.containsClientSide(); + } + + public void close() { + this.socket.close(); + this.receivers.clear(); + } + + public void unregister(Plugin plugin) { + List receivers = this.receivers.getOrDefault(plugin,Lists.newArrayList()); + receivers.forEach(this.socket::unregister); + this.receivers.remove(plugin); + } + + public void unregisterAll() { + this.socket.unregisterAll(); + this.receivers.clear(); + } } diff --git a/src/main/java/top/focess/qq/api/net/packet/ClientPackPacket.java b/src/main/java/top/focess/qq/api/net/packet/ClientPackPacket.java deleted file mode 100644 index 825b772..0000000 --- a/src/main/java/top/focess/qq/api/net/packet/ClientPackPacket.java +++ /dev/null @@ -1,34 +0,0 @@ -package top.focess.qq.api.net.packet; - -/** - * Used to pack package sent by client. - */ -public class ClientPackPacket extends ClientPacket { - - public static final int PACKET_ID = 7; - /** - * The packet sent by client - */ - private final Packet packet; - - /** - * Constructs a ClientPackPacket - * - * @param clientId the client id - * @param token the client token - * @param packet the packet sent by client - */ - public ClientPackPacket(final int clientId, final String token, final Packet packet) { - super(clientId, token); - this.packet = packet; - } - - @Override - public int getId() { - return PACKET_ID; - } - - public Packet getPacket() { - return this.packet; - } -} diff --git a/src/main/java/top/focess/qq/api/net/packet/ClientPackPacketCodec.java b/src/main/java/top/focess/qq/api/net/packet/ClientPackPacketCodec.java deleted file mode 100644 index 73d4193..0000000 --- a/src/main/java/top/focess/qq/api/net/packet/ClientPackPacketCodec.java +++ /dev/null @@ -1,28 +0,0 @@ -package top.focess.qq.api.net.packet; - -import org.jetbrains.annotations.Nullable; -import top.focess.qq.api.net.PacketPreCodec; - -/** - * Codec for ClientPackPacket. - */ -public class ClientPackPacketCodec extends PacketCodec { - - @Nullable - @Override - public ClientPackPacket readPacket(final PacketPreCodec packetPreCodec) { - final int clientId = packetPreCodec.readInt(); - final String token = packetPreCodec.readString(); - final Packet packet = packetPreCodec.readPacket(); - if (packet == null) - return null; - return new ClientPackPacket(clientId, token, packet); - } - - @Override - public void writePacket(final ClientPackPacket packet, final PacketPreCodec packetPreCodec) { - packetPreCodec.writeInt(packet.getClientId()); - packetPreCodec.writeString(packet.getToken()); - packetPreCodec.writePacket(packet.getPacket()); - } -} diff --git a/src/main/java/top/focess/qq/api/net/packet/ClientPacket.java b/src/main/java/top/focess/qq/api/net/packet/ClientPacket.java deleted file mode 100644 index af9dc49..0000000 --- a/src/main/java/top/focess/qq/api/net/packet/ClientPacket.java +++ /dev/null @@ -1,36 +0,0 @@ -package top.focess.qq.api.net.packet; - -/** - * The class indicates that this packet is for client side. - */ -public abstract class ClientPacket extends Packet { - - /** - * The client id - */ - private final int clientId; - - /** - * The client token - */ - private final String token; - - /** - * Constructs a ClientPacket - * - * @param clientId the client id - * @param token the client token - */ - public ClientPacket(final int clientId, final String token) { - this.clientId = clientId; - this.token = token; - } - - public int getClientId() { - return this.clientId; - } - - public String getToken() { - return this.token; - } -} diff --git a/src/main/java/top/focess/qq/api/net/packet/ConnectPacket.java b/src/main/java/top/focess/qq/api/net/packet/ConnectPacket.java deleted file mode 100644 index 967d615..0000000 --- a/src/main/java/top/focess/qq/api/net/packet/ConnectPacket.java +++ /dev/null @@ -1,51 +0,0 @@ -package top.focess.qq.api.net.packet; - -/** - * Used to connect to the server. - */ -public class ConnectPacket extends Packet { - - public static final int PACKET_ID = 3; - /** - * The client host - */ - private final String host; - /** - * The client port - */ - private final int port; - /** - * The client name - */ - private final String name; - - /** - * Constructs a ConnectPacket - * - * @param host the client host - * @param port the client port - * @param name the client name - */ - public ConnectPacket(final String host, final int port, final String name) { - this.host = host; - this.port = port; - this.name = name; - } - - @Override - public int getId() { - return PACKET_ID; - } - - public String getHost() { - return this.host; - } - - public int getPort() { - return this.port; - } - - public String getName() { - return this.name; - } -} diff --git a/src/main/java/top/focess/qq/api/net/packet/ConnectPacketCodec.java b/src/main/java/top/focess/qq/api/net/packet/ConnectPacketCodec.java deleted file mode 100644 index 2d40a68..0000000 --- a/src/main/java/top/focess/qq/api/net/packet/ConnectPacketCodec.java +++ /dev/null @@ -1,23 +0,0 @@ -package top.focess.qq.api.net.packet; - -import top.focess.qq.api.net.PacketPreCodec; - -/** - * Codec for ConnectPacket. - */ -public class ConnectPacketCodec extends PacketCodec { - @Override - public ConnectPacket readPacket(final PacketPreCodec packetPreCodec) { - final String host = packetPreCodec.readString(); - final int port = packetPreCodec.readInt(); - final String name = packetPreCodec.readString(); - return new ConnectPacket(host, port, name); - } - - @Override - public void writePacket(final ConnectPacket packet, final PacketPreCodec packetPreCodec) { - packetPreCodec.writeString(packet.getHost()); - packetPreCodec.writeInt(packet.getPort()); - packetPreCodec.writeString(packet.getName()); - } -} diff --git a/src/main/java/top/focess/qq/api/net/packet/ConnectedPacket.java b/src/main/java/top/focess/qq/api/net/packet/ConnectedPacket.java deleted file mode 100644 index 8cf8201..0000000 --- a/src/main/java/top/focess/qq/api/net/packet/ConnectedPacket.java +++ /dev/null @@ -1,41 +0,0 @@ -package top.focess.qq.api.net.packet; - -/** - * Used to tell client the id and the token - */ -public class ConnectedPacket extends ServerPacket { - - public static final int PACKET_ID = 4; - /** - * The client id - */ - private final int clientId; - /** - * The token - */ - private final String token; - - /** - * Constructs a ConnectedPacket - * - * @param clientId the client id - * @param token the token - */ - public ConnectedPacket(final int clientId, final String token) { - this.clientId = clientId; - this.token = token; - } - - @Override - public int getId() { - return PACKET_ID; - } - - public int getClientId() { - return this.clientId; - } - - public String getToken() { - return this.token; - } -} diff --git a/src/main/java/top/focess/qq/api/net/packet/ConnectedPacketCodec.java b/src/main/java/top/focess/qq/api/net/packet/ConnectedPacketCodec.java deleted file mode 100644 index 23ecab3..0000000 --- a/src/main/java/top/focess/qq/api/net/packet/ConnectedPacketCodec.java +++ /dev/null @@ -1,21 +0,0 @@ -package top.focess.qq.api.net.packet; - -import top.focess.qq.api.net.PacketPreCodec; - -/** - * Codec for ConnectedPacket. - */ -public class ConnectedPacketCodec extends PacketCodec { - @Override - public ConnectedPacket readPacket(final PacketPreCodec packetPreCodec) { - final int clientId = packetPreCodec.readInt(); - final String token = packetPreCodec.readString(); - return new ConnectedPacket(clientId, token); - } - - @Override - public void writePacket(final ConnectedPacket packet, final PacketPreCodec packetPreCodec) { - packetPreCodec.writeInt(packet.getClientId()); - packetPreCodec.writeString(packet.getToken()); - } -} diff --git a/src/main/java/top/focess/qq/api/net/packet/DisconnectPacket.java b/src/main/java/top/focess/qq/api/net/packet/DisconnectPacket.java deleted file mode 100644 index 0f9c6c8..0000000 --- a/src/main/java/top/focess/qq/api/net/packet/DisconnectPacket.java +++ /dev/null @@ -1,24 +0,0 @@ -package top.focess.qq.api.net.packet; - -/** - * Used to tell server the connection has lost. - */ -public class DisconnectPacket extends ClientPacket { - - public static final int PACKET_ID = 5; - - /** - * Constructs a DisconnectedPacket - * - * @param clientId the client id - * @param token the client token - */ - public DisconnectPacket(final int clientId, final String token) { - super(clientId, token); - } - - @Override - public int getId() { - return PACKET_ID; - } -} diff --git a/src/main/java/top/focess/qq/api/net/packet/DisconnectPacketCodec.java b/src/main/java/top/focess/qq/api/net/packet/DisconnectPacketCodec.java deleted file mode 100644 index cec945f..0000000 --- a/src/main/java/top/focess/qq/api/net/packet/DisconnectPacketCodec.java +++ /dev/null @@ -1,21 +0,0 @@ -package top.focess.qq.api.net.packet; - -import top.focess.qq.api.net.PacketPreCodec; - -/** - * Codec for DisconnectPacket. - */ -public class DisconnectPacketCodec extends PacketCodec { - @Override - public DisconnectPacket readPacket(final PacketPreCodec packetPreCodec) { - final int clientId = packetPreCodec.readInt(); - final String token = packetPreCodec.readString(); - return new DisconnectPacket(clientId, token); - } - - @Override - public void writePacket(final DisconnectPacket packet, final PacketPreCodec packetPreCodec) { - packetPreCodec.writeInt(packet.getClientId()); - packetPreCodec.writeString(packet.getToken()); - } -} diff --git a/src/main/java/top/focess/qq/api/net/packet/DisconnectedPacket.java b/src/main/java/top/focess/qq/api/net/packet/DisconnectedPacket.java deleted file mode 100644 index ff9a4e7..0000000 --- a/src/main/java/top/focess/qq/api/net/packet/DisconnectedPacket.java +++ /dev/null @@ -1,21 +0,0 @@ -package top.focess.qq.api.net.packet; - -/** - * Used to tell client the connection has lost. - */ -public class DisconnectedPacket extends ServerPacket { - - public static final int PACKET_ID = 6; - - /** - * Constructs a DisconnectedPacket - */ - public DisconnectedPacket() { - - } - - @Override - public int getId() { - return PACKET_ID; - } -} diff --git a/src/main/java/top/focess/qq/api/net/packet/DisconnectedPacketCodec.java b/src/main/java/top/focess/qq/api/net/packet/DisconnectedPacketCodec.java deleted file mode 100644 index ac06704..0000000 --- a/src/main/java/top/focess/qq/api/net/packet/DisconnectedPacketCodec.java +++ /dev/null @@ -1,17 +0,0 @@ -package top.focess.qq.api.net.packet; - -import top.focess.qq.api.net.PacketPreCodec; - -/** - * Codec for DisconnectedPacket. - */ -public class DisconnectedPacketCodec extends PacketCodec { - @Override - public DisconnectedPacket readPacket(final PacketPreCodec packetPreCodec) { - return new DisconnectedPacket(); - } - - @Override - public void writePacket(final DisconnectedPacket packet, final PacketPreCodec packetPreCodec) { - } -} diff --git a/src/main/java/top/focess/qq/api/net/packet/HeartPacket.java b/src/main/java/top/focess/qq/api/net/packet/HeartPacket.java deleted file mode 100644 index b9ebcf8..0000000 --- a/src/main/java/top/focess/qq/api/net/packet/HeartPacket.java +++ /dev/null @@ -1,31 +0,0 @@ -package top.focess.qq.api.net.packet; - -/** - * Used to tell server the connection is not lost. - */ -public class HeartPacket extends ClientPacket { - - public static final int PACKET_ID = 2; - private final long time; - - /** - * Constructs a HeartPacket - * - * @param clientId the client id - * @param token the client token - * @param time the client time - */ - public HeartPacket(final int clientId, final String token, final long time) { - super(clientId, token); - this.time = time; - } - - @Override - public int getId() { - return PACKET_ID; - } - - public long getTime() { - return this.time; - } -} diff --git a/src/main/java/top/focess/qq/api/net/packet/HeartPacketCodec.java b/src/main/java/top/focess/qq/api/net/packet/HeartPacketCodec.java deleted file mode 100644 index 10770ab..0000000 --- a/src/main/java/top/focess/qq/api/net/packet/HeartPacketCodec.java +++ /dev/null @@ -1,24 +0,0 @@ -package top.focess.qq.api.net.packet; - -import top.focess.qq.api.net.PacketPreCodec; - -/** - * Codec for HeartPacket. - */ -public class HeartPacketCodec extends PacketCodec { - - @Override - public HeartPacket readPacket(final PacketPreCodec packetPreCodec) { - final int clientId = packetPreCodec.readInt(); - final String token = packetPreCodec.readString(); - final long time = packetPreCodec.readLong(); - return new HeartPacket(clientId, token, time); - } - - @Override - public void writePacket(final HeartPacket packet, final PacketPreCodec packetPreCodec) { - packetPreCodec.writeInt(packet.getClientId()); - packetPreCodec.writeString(packet.getToken()); - packetPreCodec.writeLong(packet.getTime()); - } -} diff --git a/src/main/java/top/focess/qq/api/net/packet/MessagePacket.java b/src/main/java/top/focess/qq/api/net/packet/MessagePacket.java deleted file mode 100644 index 63348aa..0000000 --- a/src/main/java/top/focess/qq/api/net/packet/MessagePacket.java +++ /dev/null @@ -1,32 +0,0 @@ -package top.focess.qq.api.net.packet; - -/** - * Used to send String message. - */ -public class MessagePacket extends Packet { - - - public static final int PACKET_ID = 1; - /** - * The message - */ - private final String message; - - /** - * Constructs a MessagePacket - * - * @param message the message - */ - public MessagePacket(final String message) { - this.message = message; - } - - @Override - public int getId() { - return PACKET_ID; - } - - public String getMessage() { - return this.message; - } -} diff --git a/src/main/java/top/focess/qq/api/net/packet/MessagePacketCodec.java b/src/main/java/top/focess/qq/api/net/packet/MessagePacketCodec.java deleted file mode 100644 index 91435a7..0000000 --- a/src/main/java/top/focess/qq/api/net/packet/MessagePacketCodec.java +++ /dev/null @@ -1,19 +0,0 @@ -package top.focess.qq.api.net.packet; - -import top.focess.qq.api.net.PacketPreCodec; - -/** - * Codec for MessagePacket. - */ -public class MessagePacketCodec extends PacketCodec { - - @Override - public MessagePacket readPacket(final PacketPreCodec packetPreCodec) { - return new MessagePacket(packetPreCodec.readString()); - } - - @Override - public void writePacket(final MessagePacket packet, final PacketPreCodec packetPreCodec) { - packetPreCodec.writeString(packet.getMessage()); - } -} diff --git a/src/main/java/top/focess/qq/api/net/packet/Packet.java b/src/main/java/top/focess/qq/api/net/packet/Packet.java deleted file mode 100644 index 7859ca0..0000000 --- a/src/main/java/top/focess/qq/api/net/packet/Packet.java +++ /dev/null @@ -1,16 +0,0 @@ -package top.focess.qq.api.net.packet; - -import top.focess.util.serialize.FocessSerializable; - -/** - * This is the base class of all packets. - */ -public abstract class Packet implements FocessSerializable { - - /** - * Get the packet id - * - * @return the packet id - */ - public abstract int getId(); -} diff --git a/src/main/java/top/focess/qq/api/net/packet/PacketCodec.java b/src/main/java/top/focess/qq/api/net/packet/PacketCodec.java deleted file mode 100644 index 215a04c..0000000 --- a/src/main/java/top/focess/qq/api/net/packet/PacketCodec.java +++ /dev/null @@ -1,29 +0,0 @@ -package top.focess.qq.api.net.packet; - -import org.checkerframework.checker.nullness.qual.Nullable; -import top.focess.qq.api.net.PacketPreCodec; - -/** - * The codec for special packet type. - * - * @param the packet type - */ -public abstract class PacketCodec { - - /** - * Read the special packet from precodec - * - * @param packetPreCodec the precodec - * @return the packet - */ - @Nullable - public abstract T readPacket(PacketPreCodec packetPreCodec); - - /** - * Write the packet to the precodec - * - * @param packet the packet - * @param packetPreCodec the precodec - */ - public abstract void writePacket(T packet, PacketPreCodec packetPreCodec); -} diff --git a/src/main/java/top/focess/qq/api/net/packet/ServerPackPacket.java b/src/main/java/top/focess/qq/api/net/packet/ServerPackPacket.java deleted file mode 100644 index 4075439..0000000 --- a/src/main/java/top/focess/qq/api/net/packet/ServerPackPacket.java +++ /dev/null @@ -1,31 +0,0 @@ -package top.focess.qq.api.net.packet; - -/** - * Used to pack package sent by server. - */ -public class ServerPackPacket extends ServerPacket { - - public static final int PACKET_ID = 8; - /** - * The packet sent by server - */ - private final Packet packet; - - /** - * Constructs a ServerPackPacket - * - * @param packet the packet sent by server - */ - public ServerPackPacket(final Packet packet) { - this.packet = packet; - } - - @Override - public int getId() { - return PACKET_ID; - } - - public Packet getPacket() { - return this.packet; - } -} diff --git a/src/main/java/top/focess/qq/api/net/packet/ServerPackPacketCodec.java b/src/main/java/top/focess/qq/api/net/packet/ServerPackPacketCodec.java deleted file mode 100644 index 34fa5a5..0000000 --- a/src/main/java/top/focess/qq/api/net/packet/ServerPackPacketCodec.java +++ /dev/null @@ -1,23 +0,0 @@ -package top.focess.qq.api.net.packet; - -import org.jetbrains.annotations.Nullable; -import top.focess.qq.api.net.PacketPreCodec; - -/** - * Codec for ServerPackPacket. - */ -public class ServerPackPacketCodec extends PacketCodec { - @Nullable - @Override - public ServerPackPacket readPacket(final PacketPreCodec packetPreCodec) { - final Packet packet = packetPreCodec.readPacket(); - if (packet == null) - return null; - return new ServerPackPacket(packet); - } - - @Override - public void writePacket(final ServerPackPacket packet, final PacketPreCodec packetPreCodec) { - packetPreCodec.writePacket(packet.getPacket()); - } -} diff --git a/src/main/java/top/focess/qq/api/net/packet/ServerPacket.java b/src/main/java/top/focess/qq/api/net/packet/ServerPacket.java deleted file mode 100644 index 9a99f7e..0000000 --- a/src/main/java/top/focess/qq/api/net/packet/ServerPacket.java +++ /dev/null @@ -1,7 +0,0 @@ -package top.focess.qq.api.net.packet; - -/** - * The class indicates that this packet is for server side. - */ -public abstract class ServerPacket extends Packet { -} diff --git a/src/main/java/top/focess/qq/api/net/packet/SidedConnectPacket.java b/src/main/java/top/focess/qq/api/net/packet/SidedConnectPacket.java deleted file mode 100644 index 94291ac..0000000 --- a/src/main/java/top/focess/qq/api/net/packet/SidedConnectPacket.java +++ /dev/null @@ -1,31 +0,0 @@ -package top.focess.qq.api.net.packet; - -/** - * Used to connect to the server. - */ -public class SidedConnectPacket extends Packet { - - public static final int PACKET_ID = 9; - /** - * The client name - */ - private final String name; - - /** - * Constructs a SidedConnectPacket - * - * @param name the client name - */ - public SidedConnectPacket(final String name) { - this.name = name; - } - - public String getName() { - return this.name; - } - - @Override - public int getId() { - return PACKET_ID; - } -} diff --git a/src/main/java/top/focess/qq/api/net/packet/SidedConnectPacketCodec.java b/src/main/java/top/focess/qq/api/net/packet/SidedConnectPacketCodec.java deleted file mode 100644 index 1e611d1..0000000 --- a/src/main/java/top/focess/qq/api/net/packet/SidedConnectPacketCodec.java +++ /dev/null @@ -1,19 +0,0 @@ -package top.focess.qq.api.net.packet; - -import top.focess.qq.api.net.PacketPreCodec; - -/** - * Codec for SidedConnectPacket. - */ -public class SidedConnectPacketCodec extends PacketCodec { - - @Override - public SidedConnectPacket readPacket(final PacketPreCodec packetPreCodec) { - return new SidedConnectPacket(packetPreCodec.readString()); - } - - @Override - public void writePacket(final SidedConnectPacket packet, final PacketPreCodec packetPreCodec) { - packetPreCodec.writeString(packet.getName()); - } -} diff --git a/src/main/java/top/focess/qq/api/net/packet/WaitPacket.java b/src/main/java/top/focess/qq/api/net/packet/WaitPacket.java deleted file mode 100644 index b0e7665..0000000 --- a/src/main/java/top/focess/qq/api/net/packet/WaitPacket.java +++ /dev/null @@ -1,24 +0,0 @@ -package top.focess.qq.api.net.packet; - -/** - * Used to create receive-packet time for client and send-packet time for server. - */ -public class WaitPacket extends ClientPacket { - - public static final int PACKET_ID = 10; - - /** - * Constructs a WaitPacket - * - * @param clientId the client id - * @param token the client token - */ - public WaitPacket(final int clientId, final String token) { - super(clientId, token); - } - - @Override - public int getId() { - return PACKET_ID; - } -} diff --git a/src/main/java/top/focess/qq/api/net/packet/WaitPacketCodec.java b/src/main/java/top/focess/qq/api/net/packet/WaitPacketCodec.java deleted file mode 100644 index 7b20c8b..0000000 --- a/src/main/java/top/focess/qq/api/net/packet/WaitPacketCodec.java +++ /dev/null @@ -1,22 +0,0 @@ -package top.focess.qq.api.net.packet; - -import top.focess.qq.api.net.PacketPreCodec; - -/** - * Codec for WaitPacket. - */ -public class WaitPacketCodec extends PacketCodec { - - @Override - public WaitPacket readPacket(final PacketPreCodec packetPreCodec) { - final int clientId = packetPreCodec.readInt(); - final String token = packetPreCodec.readString(); - return new WaitPacket(clientId, token); - } - - @Override - public void writePacket(final WaitPacket packet, final PacketPreCodec packetPreCodec) { - packetPreCodec.writeInt(packet.getClientId()); - packetPreCodec.writeString(packet.getToken()); - } -} diff --git a/src/main/java/top/focess/qq/api/plugin/PluginDescription.java b/src/main/java/top/focess/qq/api/plugin/PluginDescription.java index a8b474b..e8b4d2a 100644 --- a/src/main/java/top/focess/qq/api/plugin/PluginDescription.java +++ b/src/main/java/top/focess/qq/api/plugin/PluginDescription.java @@ -212,4 +212,17 @@ public boolean hasPermission(Permission permission) { return true; return false; } + + public boolean addPermission(Permission permission) { + this.permissions.put(permission, true); + YamlConfiguration permissionsStatus = permissionsConfig.getSection(this.name); + List yeses = permissionsStatus.getListOrEmpty("yes"); + List nos = permissionsStatus.getListOrEmpty("no"); + if (yeses.contains(permission.getName())) + return false; + nos.remove(permission.getName()); + yeses.add(permission.getName()); + permissionsConfig.save(new File("plugins/Main", "permissions.yml")); + return true; + } } diff --git a/src/main/java/top/focess/qq/api/schedule/Schedulers.java b/src/main/java/top/focess/qq/api/scheduler/Schedulers.java similarity index 99% rename from src/main/java/top/focess/qq/api/schedule/Schedulers.java rename to src/main/java/top/focess/qq/api/scheduler/Schedulers.java index 405f4cc..81e589e 100644 --- a/src/main/java/top/focess/qq/api/schedule/Schedulers.java +++ b/src/main/java/top/focess/qq/api/scheduler/Schedulers.java @@ -1,4 +1,4 @@ -package top.focess.qq.api.schedule; +package top.focess.qq.api.scheduler; import org.jetbrains.annotations.Contract; import org.jetbrains.annotations.NotNull; diff --git a/src/main/java/top/focess/qq/api/util/IOHandler.java b/src/main/java/top/focess/qq/api/util/IOHandler.java index 9d194de..adc7134 100755 --- a/src/main/java/top/focess/qq/api/util/IOHandler.java +++ b/src/main/java/top/focess/qq/api/util/IOHandler.java @@ -7,7 +7,7 @@ import top.focess.command.InputTimeoutException; import top.focess.qq.FocessQQ; import top.focess.qq.api.bot.message.Message; -import top.focess.qq.api.schedule.Schedulers; +import top.focess.qq.api.scheduler.Schedulers; import top.focess.qq.core.listeners.ConsoleListener; import top.focess.qq.core.plugin.PluginCoreClassLoader; import top.focess.qq.core.util.MethodCaller; diff --git a/src/main/java/top/focess/qq/core/bot/mirai/MiraiBotManager.java b/src/main/java/top/focess/qq/core/bot/mirai/MiraiBotManager.java index b82e43d..15e30ed 100644 --- a/src/main/java/top/focess/qq/core/bot/mirai/MiraiBotManager.java +++ b/src/main/java/top/focess/qq/core/bot/mirai/MiraiBotManager.java @@ -35,7 +35,7 @@ import top.focess.qq.api.event.request.FriendRequestEvent; import top.focess.qq.api.event.request.GroupRequestEvent; import top.focess.qq.api.plugin.Plugin; -import top.focess.qq.api.schedule.Schedulers; +import top.focess.qq.api.scheduler.Schedulers; import top.focess.qq.api.util.IOHandler; import top.focess.qq.core.bot.mirai.message.MiraiMessage; import top.focess.qq.core.bot.mirai.message.MiraiMessageChain; diff --git a/src/main/java/top/focess/qq/core/commands/PermissionCommand.java b/src/main/java/top/focess/qq/core/commands/PermissionCommand.java new file mode 100644 index 0000000..8dadfec --- /dev/null +++ b/src/main/java/top/focess/qq/core/commands/PermissionCommand.java @@ -0,0 +1,51 @@ +package top.focess.qq.core.commands; + +import com.google.common.collect.Lists; +import org.jetbrains.annotations.NotNull; +import top.focess.command.CommandArgument; +import top.focess.command.CommandResult; +import top.focess.qq.api.command.Command; +import top.focess.qq.api.command.CommandSender; +import top.focess.qq.api.command.converter.PermissionDataConverter; +import top.focess.qq.api.command.converter.PluginDataConverter; +import top.focess.qq.api.plugin.Plugin; +import top.focess.qq.core.permission.Permission; + +import java.util.List; + +public class PermissionCommand extends Command { + + public PermissionCommand() { + super("permission"); + } + + @Override + public void init() { + this.setExecutorPermission(i -> i.isAdministrator() || i.isConsole()); + this.addExecutor((sender,data,ioHandler)->{ + Plugin plugin = data.get(Plugin.class); + if (plugin.getPluginDescription().getPermissions().size() == 0) + ioHandler.outputLang("permission-command-no-permission",plugin.getName()); + else { + StringBuilder stringBuilder = new StringBuilder(); + for (Permission permission : plugin.getPluginDescription().getPermissions().keySet()) + stringBuilder.append(' ').append(permission); + ioHandler.outputLang("permission-command-list", plugin.getName(), stringBuilder.toString()); + } + return CommandResult.ALLOW; + }, CommandArgument.of("get"), CommandArgument.of(PluginDataConverter.PLUGIN_DATA_CONVERTER)); + this.addExecutor((sender,data,ioHandler)->{ + Plugin plugin = data.get(Plugin.class); + Permission permission = data.get(Permission.class); + if (plugin.getPluginDescription().addPermission(permission)) + ioHandler.outputLang("permission-command-set-success",plugin.getName(), permission.getName()); + else ioHandler.outputLang("permission-command-set-failed",plugin.getName(),permission.getName()); + return CommandResult.ALLOW; + }, CommandArgument.of("set"), CommandArgument.of(PluginDataConverter.PLUGIN_DATA_CONVERTER), CommandArgument.of(PermissionDataConverter.PERMISSION_DATA_CONVERTER)); + } + + @Override + public @NotNull List usage(CommandSender sender) { + return Lists.newArrayList("Use: permission set ","Use: permission get "); + } +} diff --git a/src/main/java/top/focess/qq/core/debug/Section.java b/src/main/java/top/focess/qq/core/debug/Section.java index 428aee1..9282831 100644 --- a/src/main/java/top/focess/qq/core/debug/Section.java +++ b/src/main/java/top/focess/qq/core/debug/Section.java @@ -2,7 +2,7 @@ import org.jetbrains.annotations.NotNull; import top.focess.qq.FocessQQ; -import top.focess.qq.api.schedule.Schedulers; +import top.focess.qq.api.scheduler.Schedulers; import top.focess.scheduler.Scheduler; import top.focess.scheduler.Task; diff --git a/src/main/java/top/focess/qq/core/listeners/ChatListener.java b/src/main/java/top/focess/qq/core/listeners/ChatListener.java index 2494c04..6305f1b 100644 --- a/src/main/java/top/focess/qq/core/listeners/ChatListener.java +++ b/src/main/java/top/focess/qq/core/listeners/ChatListener.java @@ -18,7 +18,7 @@ import top.focess.qq.api.event.message.FriendMessageEvent; import top.focess.qq.api.event.message.GroupMessageEvent; import top.focess.qq.api.event.message.StrangerMessageEvent; -import top.focess.qq.api.schedule.Schedulers; +import top.focess.qq.api.scheduler.Schedulers; import top.focess.qq.api.util.IOHandler; import top.focess.qq.core.debug.Section; import top.focess.scheduler.Scheduler; diff --git a/src/main/java/top/focess/qq/core/listeners/ConsoleListener.java b/src/main/java/top/focess/qq/core/listeners/ConsoleListener.java index dc31ad0..d5844fb 100644 --- a/src/main/java/top/focess/qq/core/listeners/ConsoleListener.java +++ b/src/main/java/top/focess/qq/core/listeners/ConsoleListener.java @@ -12,7 +12,7 @@ import top.focess.qq.api.event.Listener; import top.focess.qq.api.event.chat.ConsoleChatEvent; import top.focess.qq.api.event.message.ConsoleMessageEvent; -import top.focess.qq.api.schedule.Schedulers; +import top.focess.qq.api.scheduler.Schedulers; import top.focess.qq.api.util.IOHandler; import top.focess.qq.core.debug.Section; import top.focess.scheduler.Scheduler; diff --git a/src/main/java/top/focess/qq/core/net/AClientReceiver.java b/src/main/java/top/focess/qq/core/net/AClientReceiver.java deleted file mode 100644 index 63e0628..0000000 --- a/src/main/java/top/focess/qq/core/net/AClientReceiver.java +++ /dev/null @@ -1,88 +0,0 @@ -package top.focess.qq.core.net; - -import com.google.common.collect.Lists; -import com.google.common.collect.Maps; -import top.focess.qq.FocessQQ; -import top.focess.qq.api.net.ClientReceiver; -import top.focess.qq.api.net.PackHandler; -import top.focess.qq.api.net.packet.Packet; -import top.focess.qq.api.plugin.Plugin; - -import java.util.List; -import java.util.Map; - -public abstract class AClientReceiver implements ClientReceiver { - - protected final String host; - protected final int port; - protected final String name; - protected final Map, List>> packHandlers = Maps.newConcurrentMap(); - protected String token; - protected int id; - protected volatile boolean connected; - - public AClientReceiver(final String host, final int port, final String name) { - this.host = host; - this.port = port; - this.name = name; - } - - @Override - public void register(final Plugin plugin, final Class c, final PackHandler packHandler) { - this.packHandlers.compute(plugin, (k, v) -> { - if (v == null) - v = Maps.newHashMap(); - v.compute(c, (k1, v1) -> { - if (v1 == null) - v1 = Lists.newArrayList(); - v1.add(packHandler); - return v1; - }); - return v; - }); - } - - @Override - public void unregister(final Plugin plugin) { - this.packHandlers.remove(plugin); - } - - @Override - public boolean unregisterAll() { - boolean ret = false; - for (final Plugin plugin : this.packHandlers.keySet()) { - if (plugin != FocessQQ.getMainPlugin()) - ret = true; - this.unregister(plugin); - } - return ret; - } - - public String getHost() { - return this.host; - } - - public int getPort() { - return this.port; - } - - @Override - public boolean isConnected() { - return this.connected; - } - - @Override - public int getClientId() { - return this.id; - } - - @Override - public String getClientToken() { - return this.token; - } - - public String getName() { - return this.name; - } - -} diff --git a/src/main/java/top/focess/qq/core/net/AServerReceiver.java b/src/main/java/top/focess/qq/core/net/AServerReceiver.java deleted file mode 100644 index ebf8147..0000000 --- a/src/main/java/top/focess/qq/core/net/AServerReceiver.java +++ /dev/null @@ -1,93 +0,0 @@ -package top.focess.qq.core.net; - -import com.google.common.collect.Lists; -import com.google.common.collect.Maps; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; -import top.focess.qq.FocessQQ; -import top.focess.qq.api.net.Client; -import top.focess.qq.api.net.PackHandler; -import top.focess.qq.api.net.ServerReceiver; -import top.focess.qq.api.net.packet.Packet; -import top.focess.qq.api.plugin.Plugin; - -import java.util.List; -import java.util.Map; -import java.util.Random; - -public abstract class AServerReceiver implements ServerReceiver { - - - protected final Map lastHeart = Maps.newConcurrentMap(); - protected final Map clientInfos = Maps.newConcurrentMap(); - protected final Map, List>>> packHandlers = Maps.newConcurrentMap(); - protected int defaultClientId; - - @NotNull - protected static String generateToken() { - final StringBuilder stringBuilder = new StringBuilder(); - final Random random = new Random(System.currentTimeMillis()); - for (int i = 0; i < 64; i++) { - switch (random.nextInt(3)) { - case 0: - stringBuilder.append((char) ('0' + random.nextInt(10))); - break; - case 1: - stringBuilder.append((char) ('a' + random.nextInt(26))); - break; - case 2: - stringBuilder.append((char) ('A' + random.nextInt(26))); - break; - } - } - return stringBuilder.toString(); - } - - @Override - public boolean isConnected(final String client) { - return this.clientInfos.values().stream().anyMatch(simpleClient -> simpleClient.getName().equals(client)); - } - - @Override - @Nullable - public Client getClient(final String name) { - return this.clientInfos.values().stream().filter(simpleClient -> simpleClient.getName().equals(name)).findFirst().orElse(null); - } - - @Override - public boolean unregisterAll() { - boolean ret = false; - for (final Plugin plugin : this.packHandlers.keySet()) { - if (plugin != FocessQQ.getMainPlugin()) - ret = true; - this.unregister(plugin); - } - return ret; - } - - @Override - public void unregister(final Plugin plugin) { - this.packHandlers.remove(plugin); - } - - @Override - public void register(final Plugin plugin, final String name, final Class c, final PackHandler packHandler) { - this.packHandlers.compute(plugin, (k, v) -> { - if (v == null) - v = Maps.newHashMap(); - v.compute(name, (k1, v1) -> { - if (v1 == null) - v1 = Maps.newHashMap(); - v1.compute(c, (k2, v2) -> { - if (v2 == null) - v2 = Lists.newArrayList(); - v2.add(packHandler); - return v2; - }); - return v1; - }); - return v; - }); - } - -} diff --git a/src/main/java/top/focess/qq/core/net/ASocket.java b/src/main/java/top/focess/qq/core/net/ASocket.java deleted file mode 100644 index 52f2014..0000000 --- a/src/main/java/top/focess/qq/core/net/ASocket.java +++ /dev/null @@ -1,48 +0,0 @@ -package top.focess.qq.core.net; - -import com.google.common.collect.Lists; -import com.google.common.collect.Maps; -import top.focess.qq.api.net.Receiver; -import top.focess.qq.api.net.Socket; -import top.focess.qq.api.net.packet.Packet; -import top.focess.qq.api.plugin.Plugin; -import top.focess.util.Pair; - -import java.lang.reflect.Method; -import java.lang.reflect.Modifier; -import java.util.List; -import java.util.Map; - -public abstract class ASocket implements Socket { - - - protected final Map, List>> packetMethods = Maps.newHashMap(); - protected final List receivers = Lists.newArrayList(); - - @Override - public void registerReceiver(final Receiver receiver) { - this.receivers.add(receiver); - for (final Method method : receiver.getClass().getDeclaredMethods()) - if (method.getAnnotation(PacketHandler.class) != null) - if (method.getParameterTypes().length == 1 && (method.getReturnType().equals(Void.TYPE) || Packet.class.isAssignableFrom(method.getReturnType()))) { - final Class packetClass = method.getParameterTypes()[0]; - if (Packet.class.isAssignableFrom(packetClass) && !Modifier.isAbstract(packetClass.getModifiers())) { - try { - this.packetMethods.compute((Class) packetClass, (k, v) -> { - if (v == null) - v = Lists.newArrayList(); - v.add(Pair.of(receiver, method)); - return v; - }); - } catch (final Exception ignored) { - } - } - } - } - - @Override - public void unregister(final Plugin plugin) { - for (final Receiver receiver : this.receivers) - receiver.unregister(plugin); - } -} diff --git a/src/main/java/top/focess/qq/core/net/FocessClientReceiver.java b/src/main/java/top/focess/qq/core/net/FocessClientReceiver.java deleted file mode 100644 index 5a1b966..0000000 --- a/src/main/java/top/focess/qq/core/net/FocessClientReceiver.java +++ /dev/null @@ -1,64 +0,0 @@ -package top.focess.qq.core.net; - -import com.google.common.collect.Lists; -import top.focess.qq.FocessQQ; -import top.focess.qq.api.net.PackHandler; -import top.focess.qq.api.net.packet.*; -import top.focess.qq.api.plugin.Plugin; -import top.focess.qq.api.schedule.Schedulers; -import top.focess.scheduler.Scheduler; - -import java.time.Duration; - -public class FocessClientReceiver extends AClientReceiver { - - private final String localhost; - private final FocessSocket focessSocket; - private final Scheduler scheduler = Schedulers.newFocessScheduler(FocessQQ.getMainPlugin(), "FocessClientReceiver"); - private volatile boolean connected; - - public FocessClientReceiver(final FocessSocket focessSocket, final String localhost, final String host, final int port, final String name) { - super(host, port, name); - this.localhost = localhost; - this.focessSocket = focessSocket; - this.scheduler.runTimer(() -> { - if (this.connected) - focessSocket.sendPacket(host, port, new HeartPacket(this.id, this.token, System.currentTimeMillis())); - else - focessSocket.sendPacket(this.host, this.port, new ConnectPacket(localhost, focessSocket.getLocalPort(), name)); - }, Duration.ZERO, Duration.ofSeconds(2)); - } - - @PacketHandler - public void onConnected(final ConnectedPacket packet) { - if (this.connected) - return; - this.token = packet.getToken(); - this.id = packet.getClientId(); - this.connected = true; - } - - @PacketHandler - public void onDisconnected(final DisconnectedPacket packet) { - this.connected = false; - this.focessSocket.sendPacket(this.host, this.port, new ConnectPacket(this.localhost, this.focessSocket.getLocalPort(), this.name)); - } - - @PacketHandler - public void onServerPacket(final ServerPackPacket packet) { - for (final Plugin plugin : this.packHandlers.keySet()) - for (final PackHandler packHandler : this.packHandlers.get(plugin).getOrDefault(packet.getPacket().getClass(), Lists.newArrayList())) - packHandler.handle(packet.getPacket()); - } - - @Override - public void sendPacket(final Packet packet) { - this.focessSocket.sendPacket(this.host, this.port, new ClientPackPacket(this.id, this.token, packet)); - } - - @Override - public boolean close() { - this.scheduler.close(); - return this.unregisterAll(); - } -} diff --git a/src/main/java/top/focess/qq/core/net/FocessReceiver.java b/src/main/java/top/focess/qq/core/net/FocessReceiver.java deleted file mode 100644 index 18ba5fd..0000000 --- a/src/main/java/top/focess/qq/core/net/FocessReceiver.java +++ /dev/null @@ -1,92 +0,0 @@ -package top.focess.qq.core.net; - -import com.google.common.collect.Lists; -import com.google.common.collect.Maps; -import org.jetbrains.annotations.NotNull; -import top.focess.qq.FocessQQ; -import top.focess.qq.api.net.PackHandler; -import top.focess.qq.api.net.packet.*; -import top.focess.qq.api.plugin.Plugin; -import top.focess.qq.api.schedule.Schedulers; -import top.focess.scheduler.Scheduler; - -import java.time.Duration; -import java.util.Objects; - -public class FocessReceiver extends AServerReceiver { - - private final FocessSocket focessSocket; - private final Scheduler scheduler = Schedulers.newFocessScheduler(FocessQQ.getMainPlugin(), "FocessReceiver"); - - public FocessReceiver(final FocessSocket focessSocket) { - this.focessSocket = focessSocket; - this.scheduler.runTimer(() -> { - for (final SimpleClient simpleClient : this.clientInfos.values()) { - final long time = this.lastHeart.getOrDefault(simpleClient.getId(), 0L); - if (System.currentTimeMillis() - time > 10 * 1000) - this.clientInfos.remove(simpleClient.getId()); - } - }, Duration.ZERO, Duration.ofSeconds(1)); - } - - @PacketHandler - public void onConnect(final ConnectPacket packet) { - for (final SimpleClient simpleClient : this.clientInfos.values()) - if (simpleClient.getName().equals(packet.getName())) - return; - final SimpleClient simpleClient = new SimpleClient(packet.getHost(), packet.getPort(), this.defaultClientId++, packet.getName(), generateToken()); - this.lastHeart.put(simpleClient.getId(), System.currentTimeMillis()); - this.clientInfos.put(simpleClient.getId(), simpleClient); - this.focessSocket.sendPacket(packet.getHost(), packet.getPort(), new ConnectedPacket(simpleClient.getId(), simpleClient.getToken())); - } - - @PacketHandler - public void onDisconnect(@NotNull final DisconnectPacket packet) { - if (this.clientInfos.get(packet.getClientId()) != null) { - final SimpleClient simpleClient = this.clientInfos.get(packet.getClientId()); - if (simpleClient.getToken().equals(packet.getToken())) - this.disconnect(packet.getClientId()); - } - } - - @PacketHandler - public void onHeart(@NotNull final HeartPacket packet) { - if (this.clientInfos.get(packet.getClientId()) != null) { - final SimpleClient simpleClient = this.clientInfos.get(packet.getClientId()); - if (simpleClient.getToken().equals(packet.getToken()) && System.currentTimeMillis() + 5 * 1000 > packet.getTime()) - this.lastHeart.put(simpleClient.getId(), packet.getTime()); - } - } - - @PacketHandler - public void onClientPacket(@NotNull final ClientPackPacket packet) { - if (this.clientInfos.get(packet.getClientId()) != null) { - final SimpleClient simpleClient = this.clientInfos.get(packet.getClientId()); - if (simpleClient.getToken().equals(packet.getToken())) - for (final Plugin plugin : this.packHandlers.keySet()) - for (final PackHandler packHandler : this.packHandlers.get(plugin).getOrDefault(simpleClient.getName(), Maps.newHashMap()).getOrDefault(packet.getPacket().getClass(), Lists.newArrayList())) - packHandler.handle(packet.getPacket()); - } - } - - private void disconnect(final int clientId) { - final SimpleClient simpleClient = this.clientInfos.remove(clientId); - if (simpleClient != null) - this.focessSocket.sendPacket(Objects.requireNonNull(simpleClient.getHost()), simpleClient.getPort(), new DisconnectedPacket()); - } - - @Override - public void sendPacket(final String client, final Packet packet) { - for (final SimpleClient simpleClient : this.clientInfos.values()) - if (simpleClient.getName().equals(client)) - this.focessSocket.sendPacket(Objects.requireNonNull(simpleClient.getHost()), simpleClient.getPort(), new ServerPackPacket(packet)); - } - - @Override - public boolean close() { - this.scheduler.close(); - for (final Integer id : this.clientInfos.keySet()) - this.disconnect(id); - return this.unregisterAll(); - } -} diff --git a/src/main/java/top/focess/qq/core/net/FocessSidedClientReceiver.java b/src/main/java/top/focess/qq/core/net/FocessSidedClientReceiver.java deleted file mode 100644 index d716e37..0000000 --- a/src/main/java/top/focess/qq/core/net/FocessSidedClientReceiver.java +++ /dev/null @@ -1,73 +0,0 @@ -package top.focess.qq.core.net; - -import com.google.common.collect.Lists; -import com.google.common.collect.Queues; -import org.jetbrains.annotations.NotNull; -import top.focess.qq.FocessQQ; -import top.focess.qq.api.net.PackHandler; -import top.focess.qq.api.net.packet.*; -import top.focess.qq.api.plugin.Plugin; -import top.focess.qq.api.schedule.Schedulers; -import top.focess.scheduler.Scheduler; - -import java.time.Duration; -import java.util.Queue; - -public class FocessSidedClientReceiver extends AClientReceiver { - - private final FocessSidedClientSocket focessSidedClientSocket; - private final Scheduler scheduler = Schedulers.newFocessScheduler(FocessQQ.getMainPlugin(), "FocessSidedClientReceiver"); - private final Queue packets = Queues.newConcurrentLinkedQueue(); - - public FocessSidedClientReceiver(@NotNull final FocessSidedClientSocket focessSidedClientSocket, final String name) { - super(focessSidedClientSocket.getHost(), focessSidedClientSocket.getPort(), name); - this.focessSidedClientSocket = focessSidedClientSocket; - this.scheduler.runTimer(() -> { - if (this.connected) - this.packets.offer(new HeartPacket(this.id, this.token, System.currentTimeMillis())); - else - focessSidedClientSocket.sendPacket(new SidedConnectPacket(name)); - }, Duration.ZERO, Duration.ofSeconds(2)); - this.scheduler.runTimer(() -> { - if (this.connected) { - Packet packet = this.packets.poll(); - if (packet == null) - packet = new WaitPacket(this.id, this.token); - focessSidedClientSocket.sendPacket(packet); - } - }, Duration.ZERO, Duration.ofMillis(100)); - } - - @Override - public void sendPacket(final Packet packet) { - this.packets.add(new ClientPackPacket(this.id, this.token, packet)); - } - - @PacketHandler - public void onConnected(final ConnectedPacket packet) { - if (this.connected) - return; - this.token = packet.getToken(); - this.id = packet.getClientId(); - this.connected = true; - } - - @PacketHandler - public void onDisconnected(final DisconnectedPacket packet) { - this.connected = false; - this.focessSidedClientSocket.sendPacket(new SidedConnectPacket(this.name)); - } - - @PacketHandler - public void onServerPacket(final ServerPackPacket packet) { - for (final Plugin plugin : this.packHandlers.keySet()) - for (final PackHandler packHandler : this.packHandlers.get(plugin).getOrDefault(packet.getPacket().getClass(), Lists.newArrayList())) - packHandler.handle(packet.getPacket()); - } - - @Override - public boolean close() { - this.scheduler.close(); - return this.unregisterAll(); - } -} diff --git a/src/main/java/top/focess/qq/core/net/FocessSidedClientSocket.java b/src/main/java/top/focess/qq/core/net/FocessSidedClientSocket.java deleted file mode 100644 index 1d2c05c..0000000 --- a/src/main/java/top/focess/qq/core/net/FocessSidedClientSocket.java +++ /dev/null @@ -1,90 +0,0 @@ -package top.focess.qq.core.net; - -import com.google.common.collect.Lists; -import top.focess.qq.FocessQQ; -import top.focess.qq.api.net.ClientReceiver; -import top.focess.qq.api.net.PacketPreCodec; -import top.focess.qq.api.net.Receiver; -import top.focess.qq.api.net.packet.Packet; -import top.focess.util.Pair; - -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.lang.reflect.Method; - -public class FocessSidedClientSocket extends ASocket { - - private final String host; - private final int port; - - public FocessSidedClientSocket(final String host, final int port) { - this.host = host; - this.port = port; - } - - public String getHost() { - return this.host; - } - - public int getPort() { - return this.port; - } - - public boolean sendPacket(final T packet) { - final PacketPreCodec packetPreCodec = new PacketPreCodec(); - if (packetPreCodec.writePacket(packet)) - try { - final java.net.Socket socket = new java.net.Socket(this.host, this.port); - final OutputStream outputStream = socket.getOutputStream(); - outputStream.write(packetPreCodec.getBytes()); - outputStream.flush(); - socket.shutdownOutput(); - final InputStream inputStream = socket.getInputStream(); - final byte[] buffer = new byte[1024]; - int length; - final PacketPreCodec codec = new PacketPreCodec(); - while ((length = inputStream.read(buffer)) != -1) - codec.push(buffer, length); - final Packet p = codec.readPacket(); - if (p != null) - for (final Pair pair : this.packetMethods.getOrDefault(p.getClass(), Lists.newArrayList())) { - final Method method = pair.getValue(); - try { - method.setAccessible(true); - method.invoke(pair.getKey(), p); - } catch (final Exception e) { - FocessQQ.getLogger().thrLang("exception-handle-packet", e); - } - } - return true; - } catch (final IOException e) { - return false; - } - return false; - } - - public void registerReceiver(final Receiver receiver) { - if (!(receiver instanceof ClientReceiver)) - throw new UnsupportedOperationException(); - super.registerReceiver(receiver); - } - - @Override - public boolean containsServerSide() { - return false; - } - - @Override - public boolean containsClientSide() { - return true; - } - - @Override - public boolean close() { - boolean ret = false; - for (final Receiver receiver : this.receivers) - ret = ret || receiver.close(); - return ret; - } -} diff --git a/src/main/java/top/focess/qq/core/net/FocessSidedReceiver.java b/src/main/java/top/focess/qq/core/net/FocessSidedReceiver.java deleted file mode 100644 index 3cccd0b..0000000 --- a/src/main/java/top/focess/qq/core/net/FocessSidedReceiver.java +++ /dev/null @@ -1,120 +0,0 @@ -package top.focess.qq.core.net; - -import com.google.common.collect.Lists; -import com.google.common.collect.Maps; -import com.google.common.collect.Queues; -import org.jetbrains.annotations.Contract; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; -import top.focess.qq.FocessQQ; -import top.focess.qq.api.net.PackHandler; -import top.focess.qq.api.net.packet.*; -import top.focess.qq.api.plugin.Plugin; -import top.focess.qq.api.schedule.Schedulers; -import top.focess.scheduler.Scheduler; - -import java.time.Duration; -import java.util.Map; -import java.util.Queue; - -public class FocessSidedReceiver extends AServerReceiver { - - private final Map> packets = Maps.newConcurrentMap(); - private final Scheduler scheduler = Schedulers.newFocessScheduler(FocessQQ.getMainPlugin(), "FocessSidedReceiver"); - - public FocessSidedReceiver() { - this.scheduler.runTimer(() -> { - for (final SimpleClient simpleClient : this.clientInfos.values()) { - final long time = this.lastHeart.getOrDefault(simpleClient.getId(), 0L); - if (System.currentTimeMillis() - time > 10 * 1000) - this.clientInfos.remove(simpleClient.getId()); - } - }, Duration.ZERO, Duration.ofSeconds(1)); - } - - @Nullable - @PacketHandler - public ConnectedPacket onConnect(final SidedConnectPacket packet) { - for (final SimpleClient simpleClient : this.clientInfos.values()) - if (simpleClient.getName().equals(packet.getName())) - return null; - final SimpleClient simpleClient = new SimpleClient(this.defaultClientId++, packet.getName(), generateToken()); - this.lastHeart.put(simpleClient.getId(), System.currentTimeMillis()); - this.clientInfos.put(simpleClient.getId(), simpleClient); - return new ConnectedPacket(simpleClient.getId(), simpleClient.getToken()); - } - - @Nullable - @PacketHandler - public DisconnectedPacket onDisconnect(@NotNull final DisconnectPacket packet) { - if (this.clientInfos.get(packet.getClientId()) != null) { - final SimpleClient simpleClient = this.clientInfos.get(packet.getClientId()); - if (simpleClient.getToken().equals(packet.getToken())) - return this.disconnect(packet.getClientId()); - } - return null; - } - - @Nullable - @PacketHandler - public Packet onHeart(@NotNull final HeartPacket packet) { - if (this.clientInfos.get(packet.getClientId()) != null) { - final SimpleClient simpleClient = this.clientInfos.get(packet.getClientId()); - if (simpleClient.getToken().equals(packet.getToken()) && System.currentTimeMillis() + 5 * 1000 > packet.getTime()) { - this.lastHeart.put(simpleClient.getId(), packet.getTime()); - return this.packets.getOrDefault(simpleClient.getName(), Queues.newConcurrentLinkedQueue()).poll(); - } - } - return null; - } - - @Nullable - @PacketHandler - public Packet onClientPacket(@NotNull final ClientPackPacket packet) { - if (this.clientInfos.get(packet.getClientId()) != null) { - final SimpleClient simpleClient = this.clientInfos.get(packet.getClientId()); - if (simpleClient.getToken().equals(packet.getToken())) { - for (final Plugin plugin : this.packHandlers.keySet()) - for (final PackHandler packHandler : this.packHandlers.get(plugin).getOrDefault(simpleClient.getName(), Maps.newHashMap()).getOrDefault(packet.getPacket().getClass(), Lists.newArrayList())) - packHandler.handle(packet.getPacket()); - return this.packets.getOrDefault(simpleClient.getName(), Queues.newConcurrentLinkedQueue()).poll(); - } - } - return null; - } - - @Nullable - @PacketHandler - public Packet onWait(@NotNull final WaitPacket packet) { - if (this.clientInfos.get(packet.getClientId()) != null) { - final SimpleClient simpleClient = this.clientInfos.get(packet.getClientId()); - if (simpleClient.getToken().equals(packet.getToken())) - return this.packets.getOrDefault(simpleClient.getName(), Queues.newConcurrentLinkedQueue()).poll(); - } - return null; - } - - public void sendPacket(final String client, final Packet packet) { - this.packets.compute(client, (k, v) -> { - if (v == null) - v = Queues.newConcurrentLinkedQueue(); - v.offer(new ServerPackPacket(packet)); - return v; - }); - } - - @NotNull - @Contract("_ -> new") - private DisconnectedPacket disconnect(final int clientId) { - this.clientInfos.remove(clientId); - return new DisconnectedPacket(); - } - - @Override - public boolean close() { - this.scheduler.close(); - for (final Integer id : this.clientInfos.keySet()) - this.disconnect(id); - return this.unregisterAll(); - } -} diff --git a/src/main/java/top/focess/qq/core/net/FocessSidedSocket.java b/src/main/java/top/focess/qq/core/net/FocessSidedSocket.java deleted file mode 100644 index 91f695d..0000000 --- a/src/main/java/top/focess/qq/core/net/FocessSidedSocket.java +++ /dev/null @@ -1,101 +0,0 @@ -package top.focess.qq.core.net; - -import com.google.common.collect.Lists; -import top.focess.qq.FocessQQ; -import top.focess.qq.api.net.IllegalPortException; -import top.focess.qq.api.net.PacketPreCodec; -import top.focess.qq.api.net.Receiver; -import top.focess.qq.api.net.ServerReceiver; -import top.focess.qq.api.net.packet.Packet; -import top.focess.util.Pair; - -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.lang.reflect.Method; -import java.net.ServerSocket; - -public class FocessSidedSocket extends ASocket { - - private final int localPort; - private final ServerSocket server; - - public FocessSidedSocket(final int localPort) throws IllegalPortException { - this.localPort = localPort; - try { - this.server = new ServerSocket(localPort); - } catch (final IOException e) { - throw new IllegalPortException(localPort); - } - final Thread thread = new Thread(() -> { - FocessQQ.getLogger().debugLang("start-focess-sided-socket", localPort); - while (!this.server.isClosed()) - try { - final java.net.Socket socket = this.server.accept(); - final InputStream inputStream = socket.getInputStream(); - final byte[] buffer = new byte[1024]; - final PacketPreCodec packetPreCodec = new PacketPreCodec(); - int length; - while ((length = inputStream.read(buffer)) != -1) - packetPreCodec.push(buffer, length); - final Packet packet = packetPreCodec.readPacket(); - final OutputStream outputStream = socket.getOutputStream(); - if (packet != null) - for (final Pair pair : this.packetMethods.getOrDefault(packet.getClass(), Lists.newArrayList())) { - final Method method = pair.getValue(); - try { - method.setAccessible(true); - final Object o = method.invoke(pair.getKey(), packet); - if (o != null) { - final PacketPreCodec handler = new PacketPreCodec(); - handler.writePacket((Packet) o); - outputStream.write(handler.getBytes()); - outputStream.flush(); - } - } catch (final Exception e) { - FocessQQ.getLogger().thrLang("exception-handle-packet", e); - } - } - socket.shutdownOutput(); - } catch (final IOException e) { - FocessQQ.getLogger().thrLang("exception-focess-sided-socket", e); - if (this.server.isClosed()) - return; - } - }); - thread.start(); - } - - @Override - public boolean close() { - boolean ret = false; - for (final Receiver receiver : this.receivers) - ret = ret || receiver.close(); - try { - this.server.close(); - } catch (final IOException ignored) { - } - return ret; - } - - @Override - public void registerReceiver(final Receiver receiver) { - if (!(receiver instanceof ServerReceiver)) - throw new UnsupportedOperationException(); - super.registerReceiver(receiver); - } - - @Override - public boolean containsServerSide() { - return true; - } - - @Override - public boolean containsClientSide() { - return false; - } - - public int getLocalPort() { - return this.localPort; - } -} diff --git a/src/main/java/top/focess/qq/core/net/FocessSocket.java b/src/main/java/top/focess/qq/core/net/FocessSocket.java deleted file mode 100644 index 36271dd..0000000 --- a/src/main/java/top/focess/qq/core/net/FocessSocket.java +++ /dev/null @@ -1,111 +0,0 @@ -package top.focess.qq.core.net; - -import com.google.common.collect.Lists; -import top.focess.qq.FocessQQ; -import top.focess.qq.api.net.*; -import top.focess.qq.api.net.packet.Packet; -import top.focess.util.Pair; - -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.lang.reflect.Method; -import java.net.ServerSocket; - -public class FocessSocket extends ASocket { - - private final ServerSocket server; - private final int localPort; - private boolean serverSide; - private boolean clientSide; - public FocessSocket(final int localPort) throws IllegalPortException { - this.localPort = localPort; - try { - this.server = new ServerSocket(localPort); - } catch (final IOException e) { - throw new IllegalPortException(localPort); - } - final Thread thread = new Thread(() -> { - FocessQQ.getLogger().debugLang("start-focess-socket", localPort); - while (!this.server.isClosed()) - try { - final java.net.Socket socket = this.server.accept(); - final InputStream inputStream = socket.getInputStream(); - final byte[] buffer = new byte[1024]; - final PacketPreCodec packetPreCodec = new PacketPreCodec(); - int length; - while ((length = inputStream.read(buffer)) != -1) - packetPreCodec.push(buffer, length); - inputStream.close(); - final Packet packet = packetPreCodec.readPacket(); - if (packet != null) - for (final Pair pair : this.packetMethods.getOrDefault(packet.getClass(), Lists.newArrayList())) { - final Method method = pair.getValue(); - try { - method.setAccessible(true); - method.invoke(pair.getKey(), packet); - } catch (final Exception e) { - FocessQQ.getLogger().thrLang("exception-handle-packet", e); - } - } - } catch (final IOException e) { - FocessQQ.getLogger().thrLang("exception-focess-socket", e); - if (this.server.isClosed()) - return; - } - }); - thread.start(); - } - - public void registerReceiver(final Receiver receiver) { - if (receiver instanceof ServerReceiver) - this.serverSide = true; - if (receiver instanceof ClientReceiver) - this.clientSide = true; - super.registerReceiver(receiver); - } - - @Override - public boolean containsServerSide() { - return this.serverSide; - } - - @Override - public boolean containsClientSide() { - return this.clientSide; - } - - public boolean sendPacket(final String targetHost, final int targetPort, final T packet) { - final PacketPreCodec packetPreCodec = new PacketPreCodec(); - if (packetPreCodec.writePacket(packet)) - try { - final java.net.Socket socket = new java.net.Socket(targetHost, targetPort); - final OutputStream outputStream = socket.getOutputStream(); - outputStream.write(packetPreCodec.getBytes()); - outputStream.flush(); - outputStream.close(); - return true; - } catch (final IOException e) { - FocessQQ.getLogger().thrLang("exception-send-packet", e); - return false; - } - return false; - } - - @Override - public boolean close() { - boolean ret = false; - for (final Receiver receiver : this.receivers) - ret = ret || receiver.close(); - try { - this.server.close(); - } catch (final IOException ignored) { - } - return ret; - } - - public int getLocalPort() { - return this.localPort; - } - -} diff --git a/src/main/java/top/focess/qq/core/net/FocessUDPMultiReceiver.java b/src/main/java/top/focess/qq/core/net/FocessUDPMultiReceiver.java deleted file mode 100644 index b408fc3..0000000 --- a/src/main/java/top/focess/qq/core/net/FocessUDPMultiReceiver.java +++ /dev/null @@ -1,113 +0,0 @@ -package top.focess.qq.core.net; - -import com.google.common.collect.Lists; -import com.google.common.collect.Maps; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.UnmodifiableView; -import top.focess.qq.FocessQQ; -import top.focess.qq.api.net.Client; -import top.focess.qq.api.net.PackHandler; -import top.focess.qq.api.net.ServerMultiReceiver; -import top.focess.qq.api.net.packet.*; -import top.focess.qq.api.plugin.Plugin; -import top.focess.qq.api.schedule.Schedulers; -import top.focess.scheduler.Scheduler; - -import java.time.Duration; -import java.util.Collections; -import java.util.List; -import java.util.Objects; - -public class FocessUDPMultiReceiver extends AServerReceiver implements ServerMultiReceiver { - - private final FocessUDPSocket focessUDPSocket; - private final Scheduler scheduler = Schedulers.newFocessScheduler(FocessQQ.getMainPlugin(), "FocessUDPMultiReceiver"); - - public FocessUDPMultiReceiver(final FocessUDPSocket focessUDPSocket) { - this.focessUDPSocket = focessUDPSocket; - this.scheduler.runTimer(() -> { - for (final SimpleClient simpleClient : this.clientInfos.values()) { - final long time = this.lastHeart.getOrDefault(simpleClient.getId(), 0L); - if (System.currentTimeMillis() - time > 10 * 1000) - this.clientInfos.remove(simpleClient.getId()); - } - }, Duration.ZERO, Duration.ofSeconds(1)); - } - - private void disconnect(final int clientId) { - final SimpleClient simpleClient = this.clientInfos.remove(clientId); - if (simpleClient != null) - this.focessUDPSocket.sendPacket(Objects.requireNonNull(simpleClient.getHost()), simpleClient.getPort(), new DisconnectedPacket()); - } - - @Override - public boolean close() { - this.scheduler.close(); - for (final Integer id : this.clientInfos.keySet()) - this.disconnect(id); - return this.unregisterAll(); - } - - @PacketHandler - public void onConnect(@NotNull final ConnectPacket packet) { - final SimpleClient simpleClient = new SimpleClient(packet.getHost(), packet.getPort(), this.defaultClientId++, packet.getName(), generateToken()); - this.lastHeart.put(simpleClient.getId(), System.currentTimeMillis()); - this.clientInfos.put(simpleClient.getId(), simpleClient); - this.focessUDPSocket.sendPacket(packet.getHost(), packet.getPort(), new ConnectedPacket(simpleClient.getId(), simpleClient.getToken())); - } - - @PacketHandler - public void onDisconnect(@NotNull final DisconnectPacket packet) { - if (this.clientInfos.get(packet.getClientId()) != null) { - final SimpleClient simpleClient = this.clientInfos.get(packet.getClientId()); - if (simpleClient.getToken().equals(packet.getToken())) - this.disconnect(packet.getClientId()); - } - } - - @PacketHandler - public void onHeart(@NotNull final HeartPacket packet) { - if (this.clientInfos.get(packet.getClientId()) != null) { - final SimpleClient simpleClient = this.clientInfos.get(packet.getClientId()); - if (simpleClient.getToken().equals(packet.getToken())) - this.lastHeart.put(simpleClient.getId(), System.currentTimeMillis()); - } - } - - @PacketHandler - public void onClientPacket(@NotNull final ClientPackPacket packet) { - if (this.clientInfos.get(packet.getClientId()) != null) { - final SimpleClient simpleClient = this.clientInfos.get(packet.getClientId()); - if (simpleClient.getToken().equals(packet.getToken())) - for (final Plugin plugin : this.packHandlers.keySet()) - for (final PackHandler packHandler : this.packHandlers.get(plugin).getOrDefault(simpleClient.getName(), Maps.newHashMap()).getOrDefault(packet.getPacket().getClass(), Lists.newArrayList())) - packHandler.handle(packet.getPacket()); - } - } - - @Override - public void sendPacket(final String client, final Packet packet) { - for (final SimpleClient simpleClient : this.clientInfos.values()) - if (simpleClient.getName().equals(client)) - this.focessUDPSocket.sendPacket(Objects.requireNonNull(simpleClient.getHost()), simpleClient.getPort(), new ServerPackPacket(packet)); - } - - @Override - public void sendPacket(final int id, final Packet packet) { - final SimpleClient simpleClient = this.clientInfos.get(id); - if (simpleClient != null) - this.focessUDPSocket.sendPacket(Objects.requireNonNull(simpleClient.getHost()), simpleClient.getPort(), packet); - } - - @Override - @UnmodifiableView - public List getClients(final String name) { - final List ret = Lists.newArrayList(); - for (final SimpleClient client : this.clientInfos.values()) - if (client.getName().equals(name)) - ret.add(client); - return Collections.unmodifiableList(ret); - } - - -} diff --git a/src/main/java/top/focess/qq/core/net/FocessUDPReceiver.java b/src/main/java/top/focess/qq/core/net/FocessUDPReceiver.java deleted file mode 100644 index d8a2715..0000000 --- a/src/main/java/top/focess/qq/core/net/FocessUDPReceiver.java +++ /dev/null @@ -1,93 +0,0 @@ -package top.focess.qq.core.net; - -import com.google.common.collect.Lists; -import com.google.common.collect.Maps; -import org.jetbrains.annotations.NotNull; -import top.focess.qq.FocessQQ; -import top.focess.qq.api.net.PackHandler; -import top.focess.qq.api.net.packet.*; -import top.focess.qq.api.plugin.Plugin; -import top.focess.qq.api.schedule.Schedulers; -import top.focess.scheduler.Scheduler; - -import java.time.Duration; -import java.util.Objects; - -public class FocessUDPReceiver extends AServerReceiver { - - private final FocessUDPSocket focessUDPSocket; - private final Scheduler scheduler = Schedulers.newFocessScheduler(FocessQQ.getMainPlugin(), "FocessUDPReceiver"); - - public FocessUDPReceiver(final FocessUDPSocket focessUDPSocket) { - this.focessUDPSocket = focessUDPSocket; - this.scheduler.runTimer(() -> { - for (final SimpleClient simpleClient : this.clientInfos.values()) { - final long time = this.lastHeart.getOrDefault(simpleClient.getId(), 0L); - if (System.currentTimeMillis() - time > 10 * 1000) - this.clientInfos.remove(simpleClient.getId()); - } - }, Duration.ZERO, Duration.ofSeconds(1)); - } - - private void disconnect(final int clientId) { - final SimpleClient simpleClient = this.clientInfos.remove(clientId); - if (simpleClient != null) - this.focessUDPSocket.sendPacket(Objects.requireNonNull(simpleClient.getHost()), simpleClient.getPort(), new DisconnectedPacket()); - } - - @Override - public boolean close() { - this.scheduler.close(); - for (final Integer id : this.clientInfos.keySet()) - this.disconnect(id); - return this.unregisterAll(); - } - - @PacketHandler - public void onConnect(final ConnectPacket packet) { - for (final SimpleClient simpleClient : this.clientInfos.values()) - if (simpleClient.getName().equals(packet.getName())) - return; - final SimpleClient simpleClient = new SimpleClient(packet.getHost(), packet.getPort(), this.defaultClientId++, packet.getName(), generateToken()); - this.lastHeart.put(simpleClient.getId(), System.currentTimeMillis()); - this.clientInfos.put(simpleClient.getId(), simpleClient); - this.focessUDPSocket.sendPacket(packet.getHost(), packet.getPort(), new ConnectedPacket(simpleClient.getId(), simpleClient.getToken())); - } - - @PacketHandler - public void onDisconnect(@NotNull final DisconnectPacket packet) { - if (this.clientInfos.get(packet.getClientId()) != null) { - final SimpleClient simpleClient = this.clientInfos.get(packet.getClientId()); - if (simpleClient.getToken().equals(packet.getToken())) - this.disconnect(packet.getClientId()); - } - } - - @PacketHandler - public void onHeart(@NotNull final HeartPacket packet) { - if (this.clientInfos.get(packet.getClientId()) != null) { - final SimpleClient simpleClient = this.clientInfos.get(packet.getClientId()); - if (simpleClient.getToken().equals(packet.getToken())) - this.lastHeart.put(simpleClient.getId(), System.currentTimeMillis()); - } - } - - @PacketHandler - public void onClientPacket(@NotNull final ClientPackPacket packet) { - if (this.clientInfos.get(packet.getClientId()) != null) { - final SimpleClient simpleClient = this.clientInfos.get(packet.getClientId()); - if (simpleClient.getToken().equals(packet.getToken())) - for (final Plugin plugin : this.packHandlers.keySet()) - for (final PackHandler packHandler : this.packHandlers.get(plugin).getOrDefault(simpleClient.getName(), Maps.newHashMap()).getOrDefault(packet.getPacket().getClass(), Lists.newArrayList())) - packHandler.handle(packet.getPacket()); - } - } - - @Override - public void sendPacket(final String client, final Packet packet) { - for (final SimpleClient simpleClient : this.clientInfos.values()) - if (simpleClient.getName().equals(client)) - this.focessUDPSocket.sendPacket(Objects.requireNonNull(simpleClient.getHost()), simpleClient.getPort(), new ServerPackPacket(packet)); - } - -} diff --git a/src/main/java/top/focess/qq/core/net/FocessUDPSocket.java b/src/main/java/top/focess/qq/core/net/FocessUDPSocket.java deleted file mode 100644 index 5fd1711..0000000 --- a/src/main/java/top/focess/qq/core/net/FocessUDPSocket.java +++ /dev/null @@ -1,106 +0,0 @@ -package top.focess.qq.core.net; - -import com.google.common.collect.Lists; -import top.focess.qq.FocessQQ; -import top.focess.qq.api.net.IllegalPortException; -import top.focess.qq.api.net.PacketPreCodec; -import top.focess.qq.api.net.Receiver; -import top.focess.qq.api.net.ServerReceiver; -import top.focess.qq.api.net.packet.ConnectPacket; -import top.focess.qq.api.net.packet.Packet; -import top.focess.qq.api.net.packet.SidedConnectPacket; -import top.focess.util.Pair; - -import java.io.IOException; -import java.lang.reflect.Method; -import java.net.DatagramPacket; -import java.net.DatagramSocket; -import java.net.InetSocketAddress; -import java.net.SocketException; - -public class FocessUDPSocket extends ASocket { - - private final DatagramSocket socket; - private final DatagramPacket packet; - - public FocessUDPSocket(final int port) throws IllegalPortException { - try { - this.socket = new DatagramSocket(port); - } catch (final SocketException e) { - throw new IllegalPortException(port); - } - this.packet = new DatagramPacket(new byte[1024 * 1024], 1024 * 1024); - final Thread thread = new Thread(() -> { - FocessQQ.getLogger().debugLang("start-focess-udp-socket", port); - while (!this.socket.isClosed()) { - try { - this.socket.receive(this.packet); - final PacketPreCodec packetPreCodec = new PacketPreCodec(); - packetPreCodec.push(this.packet.getData(), this.packet.getOffset(), this.packet.getLength()); - Packet packet = packetPreCodec.readPacket(); - if (packet != null) { - if (packet instanceof SidedConnectPacket) { - final String name = ((SidedConnectPacket) packet).getName(); - packet = new ConnectPacket(this.packet.getAddress().getHostName(), this.packet.getPort(), name); - } - for (final Pair pair : this.packetMethods.getOrDefault(packet.getClass(), Lists.newArrayList())) { - final Method method = pair.getValue(); - try { - method.setAccessible(true); - final Object o = method.invoke(pair.getKey(), packet); - if (o != null) { - final PacketPreCodec handler = new PacketPreCodec(); - handler.writePacket((Packet) o); - final DatagramPacket sendPacket = new DatagramPacket(handler.getBytes(), handler.getBytes().length, this.packet.getSocketAddress()); - this.socket.send(sendPacket); - } - } catch (final Exception e) { - FocessQQ.getLogger().thrLang("exception-handle-packet", e); - } - } - } - } catch (final IOException e) { - FocessQQ.getLogger().thrLang("exception-focess-udp-socket", e); - } - } - }); - thread.start(); - } - - @Override - public void registerReceiver(final Receiver receiver) { - if (!(receiver instanceof ServerReceiver)) - throw new UnsupportedOperationException(); - super.registerReceiver(receiver); - } - - @Override - public boolean containsServerSide() { - return true; - } - - @Override - public boolean containsClientSide() { - return false; - } - - @Override - public boolean close() { - boolean ret = false; - for (final Receiver receiver : this.receivers) - ret = ret || receiver.close(); - this.socket.close(); - return ret; - } - - public void sendPacket(final String host, final int port, final Packet packet) { - final PacketPreCodec handler = new PacketPreCodec(); - handler.writePacket(packet); - final DatagramPacket sendPacket = new DatagramPacket(handler.getBytes(), handler.getBytes().length, new InetSocketAddress(host, port)); - try { - this.socket.send(sendPacket); - } catch (final IOException e) { - FocessQQ.getLogger().thrLang("exception-send-packet", e); - } - } -} diff --git a/src/main/java/top/focess/qq/core/net/PacketHandler.java b/src/main/java/top/focess/qq/core/net/PacketHandler.java deleted file mode 100644 index afb7371..0000000 --- a/src/main/java/top/focess/qq/core/net/PacketHandler.java +++ /dev/null @@ -1,14 +0,0 @@ -package top.focess.qq.core.net; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** - * Represent a packet receiver method. It means this method mush own one argument whose class is an implemented Packet. - */ -@Target(ElementType.METHOD) -@Retention(RetentionPolicy.RUNTIME) -public @interface PacketHandler { -} diff --git a/src/main/java/top/focess/qq/core/net/SimpleClient.java b/src/main/java/top/focess/qq/core/net/SimpleClient.java deleted file mode 100644 index 1c79414..0000000 --- a/src/main/java/top/focess/qq/core/net/SimpleClient.java +++ /dev/null @@ -1,50 +0,0 @@ -package top.focess.qq.core.net; - -import org.jetbrains.annotations.Nullable; -import top.focess.qq.api.net.Client; - -public class SimpleClient implements Client { - - private final String host; - private final int port; - private final int id; - private final String name; - private final String token; - - public SimpleClient(final String host, final int port, final int id, final String name, final String token) { - this.host = host; - this.port = port; - this.id = id; - this.name = name; - this.token = token; - } - - public SimpleClient(final int id, final String name, final String token) { - this.host = null; - this.port = -1; - this.id = id; - this.name = name; - this.token = token; - } - - @Nullable - public String getHost() { - return this.host; - } - - public int getPort() { - return this.port; - } - - public int getId() { - return this.id; - } - - public String getToken() { - return this.token; - } - - public String getName() { - return this.name; - } -} diff --git a/src/main/java/top/focess/qq/core/permission/Permission.java b/src/main/java/top/focess/qq/core/permission/Permission.java index fd35d53..a2cc7e2 100644 --- a/src/main/java/top/focess/qq/core/permission/Permission.java +++ b/src/main/java/top/focess/qq/core/permission/Permission.java @@ -47,6 +47,11 @@ public enum Permission { BOT("BOT", 3, BOT_LOGIN, QUIT_GROUP, DELETE_FRIEND, BOT_LOGOUT, BOT_RELOGIN, FRIEND_REQUEST_ACCEPT, FRIEND_REQUEST_REFUSE, GROUP_REQUEST_ACCEPT, GROUP_REQUEST_IGNORE), + SEND_PACKET("SEND_PACKET", 2), + RECEIVE_PACKET("RECEIVE_PACKET", 2), + + PACKET("PACKET", 3, SEND_PACKET, RECEIVE_PACKET), + NETWORK("NETWORK", 2), SCHEDULER("SCHEDULER", 2), diff --git a/src/main/java/top/focess/qq/core/plugin/PluginClassLoader.java b/src/main/java/top/focess/qq/core/plugin/PluginClassLoader.java index 27a6a6e..9806c57 100644 --- a/src/main/java/top/focess/qq/core/plugin/PluginClassLoader.java +++ b/src/main/java/top/focess/qq/core/plugin/PluginClassLoader.java @@ -18,7 +18,7 @@ import top.focess.qq.api.event.plugin.PluginLoadEvent; import top.focess.qq.api.event.plugin.PluginUnloadEvent; import top.focess.qq.api.plugin.*; -import top.focess.qq.api.schedule.Schedulers; +import top.focess.qq.api.scheduler.Schedulers; import top.focess.qq.core.bot.BotManagerFactory; import top.focess.qq.core.debug.Section; import top.focess.qq.core.permission.Permission; @@ -332,6 +332,14 @@ public static File disablePlugin0(@NotNull final Plugin plugin) { FocessQQ.getSocket().unregister(plugin); if (FocessQQ.getUdpSocket() != null) FocessQQ.getUdpSocket().unregister(plugin); + if (FocessQQ.getClientReceiver() != null) + FocessQQ.getClientReceiver().unregister(plugin); + if (FocessQQ.getUdpServerMultiReceiver() != null) + FocessQQ.getUdpServerMultiReceiver().unregister(plugin); + if (FocessQQ.getServerReceiver() != null) + FocessQQ.getServerReceiver().unregister(plugin); + if (FocessQQ.getUdpServerReceiver() != null) + FocessQQ.getUdpServerReceiver().unregister(plugin); } CommandSender.clear(plugin); FocessQQ.getLogger().debugLang("clear-command-sender-session", plugin.getName()); @@ -478,6 +486,14 @@ public boolean load() { FocessQQ.getSocket().unregister(this.plugin); if (FocessQQ.getUdpSocket() != null) FocessQQ.getUdpSocket().unregister(this.plugin); + if (FocessQQ.getClientReceiver() != null) + FocessQQ.getClientReceiver().unregister(this.plugin); + if (FocessQQ.getUdpServerMultiReceiver() != null) + FocessQQ.getUdpServerMultiReceiver().unregister(this.plugin); + if (FocessQQ.getServerReceiver() != null) + FocessQQ.getServerReceiver().unregister(this.plugin); + if (FocessQQ.getUdpServerReceiver() != null) + FocessQQ.getUdpServerReceiver().unregister(this.plugin); } else if (e instanceof PluginLoadException) // this plugin is null and PluginLoadException means there is something wrong in the new instance of the plugin FocessQQ.getLogger().thrLang("exception-load-plugin-file", e); diff --git a/src/main/resources/lang.yml b/src/main/resources/lang.yml index e4c057b..d2c24e0 100644 --- a/src/main/resources/lang.yml +++ b/src/main/resources/lang.yml @@ -84,9 +84,6 @@ start-load-plugin: Start loading file %s start-reload-plugin: Start reloading plugin %s start-enable-main-plugin: Start enabling main plugin start-disable-main-plugin: Start disabling main plugin -start-focess-sided-socket: Start focess sided socket server on port %d -start-focess-socket: Start focess socket server on port %d -start-focess-udp-socket: Start focess udp socket server on port %d save-log: Save log save-default-properties: Save default properties use-given-account: Use given account as default bot account @@ -214,5 +211,9 @@ permission-timeout: "Input timeout, ignore the permission." debug-submit-event: "Submit event: %s to %s" debug-prevent-event: "Prevent event: %s to %s" debug-cancel-event: "Cancel event: %s to %s" +permission-command-no-permission: "The plugin %s does not have permissions" +permission-command-list: "The plugin %s has the following permissions:%s" +permission-command-set-success: "The plugin %s set the permission %s successfully" +permission-command-set-failed: "The plugin %s set the permission %s failed, it may already have the permission" diff --git a/src/test/java/top/focess/qq/test/environment/TestBotManager.java b/src/test/java/top/focess/qq/test/environment/TestBotManager.java index 8d93835..2d60a0c 100644 --- a/src/test/java/top/focess/qq/test/environment/TestBotManager.java +++ b/src/test/java/top/focess/qq/test/environment/TestBotManager.java @@ -11,7 +11,7 @@ import top.focess.qq.api.bot.BotManager; import top.focess.qq.api.bot.BotProtocol; import top.focess.qq.api.plugin.Plugin; -import top.focess.qq.api.schedule.Schedulers; +import top.focess.qq.api.scheduler.Schedulers; import top.focess.qq.core.bot.BotManagerFactory; import top.focess.scheduler.Scheduler;