From 9c736848fb7aa82d295b3aa2946e6cd132ee998f Mon Sep 17 00:00:00 2001 From: modmuss50 Date: Wed, 14 Sep 2022 13:12:55 +0100 Subject: Add checkstyle (#460) --- enigma-server/build.gradle | 6 +- enigma-server/docs/protocol.md | 50 +++++-- .../cuchaz/enigma/network/ClientPacketHandler.java | 18 +-- .../enigma/network/DedicatedEnigmaServer.java | 74 ++++------ .../java/cuchaz/enigma/network/EnigmaClient.java | 25 ++-- .../java/cuchaz/enigma/network/EnigmaServer.java | 47 ++++++- .../enigma/network/IntegratedEnigmaServer.java | 4 +- .../main/java/cuchaz/enigma/network/Message.java | 155 +++++++++++++-------- .../java/cuchaz/enigma/network/ServerAddress.java | 44 ++++-- .../cuchaz/enigma/network/ServerPacketHandler.java | 1 - .../network/packet/ConfirmChangeC2SPacket.java | 4 +- .../network/packet/EntryChangeC2SPacket.java | 2 - .../network/packet/EntryChangeS2CPacket.java | 2 - .../enigma/network/packet/KickS2CPacket.java | 4 +- .../enigma/network/packet/LoginC2SPacket.java | 13 +- .../enigma/network/packet/MessageC2SPacket.java | 5 +- .../enigma/network/packet/MessageS2CPacket.java | 2 - .../java/cuchaz/enigma/network/packet/Packet.java | 2 - .../cuchaz/enigma/network/packet/PacketHelper.java | 109 ++++++++------- .../enigma/network/packet/PacketRegistry.java | 2 - .../network/packet/SyncMappingsS2CPacket.java | 9 +- .../enigma/network/packet/UserListS2CPacket.java | 8 +- .../cuchaz/enigma/network/ServerAddressTest.java | 6 +- 23 files changed, 358 insertions(+), 234 deletions(-) (limited to 'enigma-server') diff --git a/enigma-server/build.gradle b/enigma-server/build.gradle index 2764558..873adb9 100644 --- a/enigma-server/build.gradle +++ b/enigma-server/build.gradle @@ -1,10 +1,10 @@ plugins { - id 'application' + id 'application' } dependencies { - implementation project(':enigma') - implementation 'net.sf.jopt-simple:jopt-simple:6.0-alpha-3' + implementation project(':enigma') + implementation 'net.sf.jopt-simple:jopt-simple:6.0-alpha-3' } mainClassName = 'cuchaz.enigma.network.DedicatedEnigmaServer' diff --git a/enigma-server/docs/protocol.md b/enigma-server/docs/protocol.md index 83ef4c0..f642e13 100644 --- a/enigma-server/docs/protocol.md +++ b/enigma-server/docs/protocol.md @@ -1,4 +1,5 @@ # Enigma protocol + Enigma uses TCP sockets for communication. Data is sent in each direction as a continuous stream, with packets being concatenated one after the other. @@ -10,6 +11,7 @@ use the same modified UTF format as in `DataOutputStream`, I repeat, the normal Strings, see below. ## Login protocol + ``` Client Server | | @@ -22,6 +24,7 @@ Client Server | ConfirmChange | | >>>>>>>>>>>>> | ``` + 1. On connect, the client sends a login packet to the server. This allows the server to test the validity of the client, as well as allowing the client to declare metadata about itself, such as the username. 1. After validating the login packet, the server sends all its mappings to the client, and the client will apply them. @@ -29,15 +32,18 @@ Client Server has received the mappings and is in sync with the server. Once the server receives this packet, the client will be allowed to modify mappings. -The server will not accept any other packets from the client until this entire exchange has been completed. +The server will not accept any other packets from the client until this entire exchange has been completed. ## Kicking clients + When the server kicks a client, it may optionally send a `Kick` packet immediately before closing the connection, which contains the reason why the client was kicked (so the client can display it to the user). This is not required though - the server may simply terminate the connection. ## Changing mappings + This section uses the example of renaming, but the same pattern applies to all mapping changes. + ``` Client A Server Client B | | | @@ -66,19 +72,23 @@ Client A Server Client B server will unlock that mapping for that client and allow them to make changes again. ## Packets + ```c struct Packet { unsigned short packet_id; data[]; // depends on packet_id } ``` + The IDs for client-to-server packets are as follows: + - 0: `Login` - 1: `ConfirmChange` - 6: `Message` - 7: `EntryChange` The IDs for server-to-client packets are as follows: + - 0: `Kick` - 1: `SyncMappings` - 6: `Message` @@ -86,17 +96,20 @@ The IDs for server-to-client packets are as follows: - 8: `EntryChange` ### The utf struct + ```c struct utf { unsigned short length; byte data[length]; } ``` + - `length`: The number of bytes in the UTF-8 encoding of the string. Note, this may not be the same as the number of - Unicode characters in the string. -- `data`: A standard UTF-8 encoded byte array representing the string. + Unicode characters in the string. +- `data`: A standard UTF-8 encoded byte array representing the string. ### The Entry struct + ```c enum EntryType { ENTRY_CLASS = 0, ENTRY_FIELD = 1, ENTRY_METHOD = 2, ENTRY_LOCAL_VAR = 3; @@ -121,9 +134,10 @@ struct Entry { } } ``` + - `type`: The type of entry this is. One of `ENTRY_CLASS`, `ENTRY_FIELD`, `ENTRY_METHOD` or `ENTRY_LOCAL_VAR`. - `parent`: The parent entry. Only class entries may have no parent. fields, methods and inner classes must have their - containing class as their parent. Local variables have a method as a parent. + containing class as their parent. Local variables have a method as a parent. - `name`: The class/field/method/variable name. - `javadoc`: The javadoc of an entry, if present. - `descriptor`: The field/method descriptor. @@ -131,6 +145,7 @@ struct Entry { - `parameter`: Whether the local variable is a parameter. ### The Message struct + ```c enum MessageType { MESSAGE_CHAT = 0, @@ -176,8 +191,9 @@ struct Message { } data; }; ``` + - `type`: The type of message this is. One of `MESSAGE_CHAT`, `MESSAGE_CONNECT`, `MESSAGE_DISCONNECT`, - `MESSAGE_EDIT_DOCS`, `MESSAGE_MARK_DEOBF`, `MESSAGE_REMOVE_MAPPING`, `MESSAGE_RENAME`. + `MESSAGE_EDIT_DOCS`, `MESSAGE_MARK_DEOBF`, `MESSAGE_REMOVE_MAPPING`, `MESSAGE_RENAME`. - `chat`: Chat message. Use in case `type` is `MESSAGE_CHAT` - `connect`: Sent when a user connects. Use in case `type` is `MESSAGE_CONNECT` - `disconnect`: Sent when a user disconnects. Use in case `type` is `MESSAGE_DISCONNECT` @@ -191,6 +207,7 @@ struct Message { - `new_name`: The new name for the entry. ### The entry_change struct + ```c typedef enum tristate_change { TRISTATE_CHANGE_UNCHANGED = 0, @@ -224,6 +241,7 @@ struct entry_change { } } ``` + - `entry`: The entry this change gets applied to. - `flags`: See definition of `entry_change_flags`. - `deobf_name`: The new deobfuscated name, if deobf_name_change == TRISTATE_CHANGE_SET @@ -231,6 +249,7 @@ struct entry_change { - `access_modifiers`: The new access modifier, if access_change == TRISTATE_CHANGE_SET (otherwise 0) ### Login (client-to-server) + ```c struct LoginC2SPacket { unsigned short protocol_version; @@ -240,47 +259,57 @@ struct LoginC2SPacket { utf username; } ``` + - `protocol_version`: the version of the protocol. If the version does not match on the server, then the client will be - kicked immediately. Currently always equal to 0. + kicked immediately. Currently always equal to 0. - `checksum`: the SHA-1 hash of the JAR file the client has open. If this does not match the SHA-1 hash of the JAR file - the server has open, the client will be kicked. + the server has open, the client will be kicked. - `password`: the password needed to log into the server. Note that each `char` is 2 bytes, as per the Java data type. - If this password is incorrect, the client will be kicked. + If this password is incorrect, the client will be kicked. - `username`: the username of the user logging in. If the username is not unique, the client will be kicked. ### ConfirmChange (client-to-server) + ```c struct ConfirmChangeC2SPacket { unsigned short sync_id; } ``` + - `sync_id`: the sync ID to confirm. ### Message (client-to-server) + ```c struct MessageC2SPacket { utf message; } ``` + - `message`: The text message the user sent. ### EntryChange (client-to-server) + ```c struct EntryChangeC2SPacket { entry_change change; } ``` + - `change`: The change to apply. ### Kick (server-to-client) + ```c struct KickS2CPacket { utf reason; } ``` + - `reason`: the reason for the kick, may or may not be a translation key for the client to display to the user. ### SyncMappings (server-to-client) + ```c struct SyncMappingsS2CPacket { int num_roots; @@ -296,6 +325,7 @@ struct MappingNode { } typedef { Entry but without the has_parent or parent fields } NoParentEntry; ``` + - `roots`: The root mapping nodes, containing all the entries without parents. - `obf_entry`: The value of a node, containing the obfuscated name and descriptor of the entry. - `name`: The deobfuscated name of the entry, if it exists, otherwise the empty string. @@ -303,6 +333,7 @@ typedef { Entry but without the has_parent or parent fields } NoParentEntry; - `children`: The children of this node ### Message (server-to-client) + ```c struct MessageS2CPacket { Message message; @@ -310,6 +341,7 @@ struct MessageS2CPacket { ``` ### UserList (server-to-client) + ```c struct UserListS2CPacket { unsigned short len; @@ -318,11 +350,13 @@ struct UserListS2CPacket { ``` ### EntryChange (server-to-client) + ```c struct EntryChangeS2CPacket { uint16_t sync_id; entry_change change; } ``` + - `sync_id`: The sync ID of the change for locking purposes. - `change`: The change to apply. \ No newline at end of file diff --git a/enigma-server/src/main/java/cuchaz/enigma/network/ClientPacketHandler.java b/enigma-server/src/main/java/cuchaz/enigma/network/ClientPacketHandler.java index a651fe8..8fcd437 100644 --- a/enigma-server/src/main/java/cuchaz/enigma/network/ClientPacketHandler.java +++ b/enigma-server/src/main/java/cuchaz/enigma/network/ClientPacketHandler.java @@ -1,22 +1,22 @@ package cuchaz.enigma.network; +import java.util.List; + +import cuchaz.enigma.network.packet.Packet; import cuchaz.enigma.translation.mapping.EntryChange; import cuchaz.enigma.translation.mapping.EntryMapping; import cuchaz.enigma.translation.mapping.tree.EntryTree; -import cuchaz.enigma.network.packet.Packet; - -import java.util.List; public interface ClientPacketHandler { - void openMappings(EntryTree mappings); + void openMappings(EntryTree mappings); - boolean applyChangeFromServer(EntryChange change); + boolean applyChangeFromServer(EntryChange change); - void disconnectIfConnected(String reason); + void disconnectIfConnected(String reason); - void sendPacket(Packet packet); + void sendPacket(Packet packet); - void addMessage(Message message); + void addMessage(Message message); - void updateUserList(List users); + void updateUserList(List users); } diff --git a/enigma-server/src/main/java/cuchaz/enigma/network/DedicatedEnigmaServer.java b/enigma-server/src/main/java/cuchaz/enigma/network/DedicatedEnigmaServer.java index 41f0834..eb22a50 100644 --- a/enigma-server/src/main/java/cuchaz/enigma/network/DedicatedEnigmaServer.java +++ b/enigma-server/src/main/java/cuchaz/enigma/network/DedicatedEnigmaServer.java @@ -1,17 +1,5 @@ package cuchaz.enigma.network; -import com.google.common.io.MoreFiles; -import cuchaz.enigma.*; -import cuchaz.enigma.classprovider.ClasspathClassProvider; -import cuchaz.enigma.translation.mapping.serde.MappingParseException; -import cuchaz.enigma.translation.mapping.EntryRemapper; -import cuchaz.enigma.translation.mapping.serde.MappingFormat; -import cuchaz.enigma.utils.Utils; -import joptsimple.OptionParser; -import joptsimple.OptionSet; -import joptsimple.OptionSpec; -import joptsimple.ValueConverter; - import java.io.IOException; import java.io.PrintWriter; import java.nio.file.Files; @@ -22,24 +10,30 @@ import java.util.concurrent.Executors; import java.util.concurrent.LinkedBlockingDeque; import java.util.concurrent.TimeUnit; -public class DedicatedEnigmaServer extends EnigmaServer { +import com.google.common.io.MoreFiles; +import joptsimple.OptionParser; +import joptsimple.OptionSet; +import joptsimple.OptionSpec; +import joptsimple.ValueConverter; + +import cuchaz.enigma.Enigma; +import cuchaz.enigma.EnigmaProfile; +import cuchaz.enigma.EnigmaProject; +import cuchaz.enigma.ProgressListener; +import cuchaz.enigma.classprovider.ClasspathClassProvider; +import cuchaz.enigma.translation.mapping.EntryRemapper; +import cuchaz.enigma.translation.mapping.serde.MappingFormat; +import cuchaz.enigma.translation.mapping.serde.MappingParseException; +import cuchaz.enigma.utils.Utils; +public class DedicatedEnigmaServer extends EnigmaServer { private final EnigmaProfile profile; private final MappingFormat mappingFormat; private final Path mappingsFile; private final PrintWriter log; private BlockingQueue tasks = new LinkedBlockingDeque<>(); - public DedicatedEnigmaServer( - byte[] jarChecksum, - char[] password, - EnigmaProfile profile, - MappingFormat mappingFormat, - Path mappingsFile, - PrintWriter log, - EntryRemapper mappings, - int port - ) { + public DedicatedEnigmaServer(byte[] jarChecksum, char[] password, EnigmaProfile profile, MappingFormat mappingFormat, Path mappingsFile, PrintWriter log, EntryRemapper mappings, int port) { super(jarChecksum, password, mappings, port); this.profile = profile; this.mappingFormat = mappingFormat; @@ -61,33 +55,17 @@ public class DedicatedEnigmaServer extends EnigmaServer { public static void main(String[] args) { OptionParser parser = new OptionParser(); - OptionSpec jarOpt = parser.accepts("jar", "Jar file to open at startup") - .withRequiredArg() - .required() - .withValuesConvertedBy(PathConverter.INSTANCE); + OptionSpec jarOpt = parser.accepts("jar", "Jar file to open at startup").withRequiredArg().required().withValuesConvertedBy(PathConverter.INSTANCE); - OptionSpec mappingsOpt = parser.accepts("mappings", "Mappings file to open at startup") - .withRequiredArg() - .required() - .withValuesConvertedBy(PathConverter.INSTANCE); + OptionSpec mappingsOpt = parser.accepts("mappings", "Mappings file to open at startup").withRequiredArg().required().withValuesConvertedBy(PathConverter.INSTANCE); - OptionSpec profileOpt = parser.accepts("profile", "Profile json to apply at startup") - .withRequiredArg() - .withValuesConvertedBy(PathConverter.INSTANCE); + OptionSpec profileOpt = parser.accepts("profile", "Profile json to apply at startup").withRequiredArg().withValuesConvertedBy(PathConverter.INSTANCE); - OptionSpec portOpt = parser.accepts("port", "Port to run the server on") - .withOptionalArg() - .ofType(Integer.class) - .defaultsTo(EnigmaServer.DEFAULT_PORT); + OptionSpec portOpt = parser.accepts("port", "Port to run the server on").withOptionalArg().ofType(Integer.class).defaultsTo(EnigmaServer.DEFAULT_PORT); - OptionSpec passwordOpt = parser.accepts("password", "The password to join the server") - .withRequiredArg() - .defaultsTo(""); + OptionSpec passwordOpt = parser.accepts("password", "The password to join the server").withRequiredArg().defaultsTo(""); - OptionSpec logFileOpt = parser.accepts("log", "The log file to write to") - .withRequiredArg() - .withValuesConvertedBy(PathConverter.INSTANCE) - .defaultsTo(Paths.get("log.txt")); + OptionSpec logFileOpt = parser.accepts("log", "The log file to write to").withRequiredArg().withValuesConvertedBy(PathConverter.INSTANCE).defaultsTo(Paths.get("log.txt")); OptionSet parsedArgs = parser.parse(args); Path jar = parsedArgs.valueOf(jarOpt); @@ -95,14 +73,17 @@ public class DedicatedEnigmaServer extends EnigmaServer { Path profileFile = parsedArgs.valueOf(profileOpt); int port = parsedArgs.valueOf(portOpt); char[] password = parsedArgs.valueOf(passwordOpt).toCharArray(); + if (password.length > EnigmaServer.MAX_PASSWORD_LENGTH) { System.err.println("Password too long, must be at most " + EnigmaServer.MAX_PASSWORD_LENGTH + " characters"); System.exit(1); } + Path logFile = parsedArgs.valueOf(logFileOpt); System.out.println("Starting Enigma server"); DedicatedEnigmaServer server; + try { byte[] checksum = Utils.zipSha1(parsedArgs.valueOf(jarOpt)); @@ -113,10 +94,12 @@ public class DedicatedEnigmaServer extends EnigmaServer { MappingFormat mappingFormat = MappingFormat.ENIGMA_DIRECTORY; EntryRemapper mappings; + if (!Files.exists(mappingsFile)) { mappings = EntryRemapper.empty(project.getJarIndex()); } else { System.out.println("Reading mappings..."); + if (Files.isDirectory(mappingsFile)) { mappingFormat = MappingFormat.ENIGMA_DIRECTORY; } else if ("zip".equalsIgnoreCase(MoreFiles.getFileExtension(mappingsFile))) { @@ -124,6 +107,7 @@ public class DedicatedEnigmaServer extends EnigmaServer { } else { mappingFormat = MappingFormat.ENIGMA_FILE; } + mappings = EntryRemapper.mapped(project.getJarIndex(), mappingFormat.read(mappingsFile, ProgressListener.none(), profile.getMappingSaveParameters())); } diff --git a/enigma-server/src/main/java/cuchaz/enigma/network/EnigmaClient.java b/enigma-server/src/main/java/cuchaz/enigma/network/EnigmaClient.java index 71bd011..69e4f5e 100644 --- a/enigma-server/src/main/java/cuchaz/enigma/network/EnigmaClient.java +++ b/enigma-server/src/main/java/cuchaz/enigma/network/EnigmaClient.java @@ -1,15 +1,20 @@ package cuchaz.enigma.network; -import cuchaz.enigma.network.packet.Packet; -import cuchaz.enigma.network.packet.PacketRegistry; - -import javax.swing.*; -import java.io.*; +import java.io.DataInput; +import java.io.DataInputStream; +import java.io.DataOutput; +import java.io.DataOutputStream; +import java.io.EOFException; +import java.io.IOException; import java.net.Socket; import java.net.SocketException; -public class EnigmaClient { +import javax.swing.SwingUtilities; +import cuchaz.enigma.network.packet.Packet; +import cuchaz.enigma.network.packet.PacketRegistry; + +public class EnigmaClient { private final ClientPacketHandler controller; private final String ip; @@ -29,17 +34,22 @@ public class EnigmaClient { Thread thread = new Thread(() -> { try { DataInput input = new DataInputStream(socket.getInputStream()); + while (true) { int packetId; + try { packetId = input.readUnsignedByte(); } catch (EOFException | SocketException e) { break; } + Packet packet = PacketRegistry.createS2CPacket(packetId); + if (packet == null) { throw new IOException("Received invalid packet id " + packetId); } + packet.read(input); SwingUtilities.invokeLater(() -> packet.handle(controller)); } @@ -47,6 +57,7 @@ public class EnigmaClient { controller.disconnectIfConnected(e.toString()); return; } + controller.disconnectIfConnected("Disconnected"); }); thread.setName("Client I/O thread"); @@ -65,7 +76,6 @@ public class EnigmaClient { } } - public void sendPacket(Packet packet) { try { output.writeByte(PacketRegistry.getC2SId(packet)); @@ -74,5 +84,4 @@ public class EnigmaClient { controller.disconnectIfConnected(e.toString()); } } - } diff --git a/enigma-server/src/main/java/cuchaz/enigma/network/EnigmaServer.java b/enigma-server/src/main/java/cuchaz/enigma/network/EnigmaServer.java index 1ce359b..8872735 100644 --- a/enigma-server/src/main/java/cuchaz/enigma/network/EnigmaServer.java +++ b/enigma-server/src/main/java/cuchaz/enigma/network/EnigmaServer.java @@ -1,20 +1,35 @@ package cuchaz.enigma.network; -import java.io.*; +import java.io.DataInput; +import java.io.DataInputStream; +import java.io.DataOutput; +import java.io.DataOutputStream; +import java.io.EOFException; +import java.io.IOException; import java.net.ServerSocket; import java.net.Socket; import java.net.SocketException; -import java.util.*; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; import java.util.concurrent.CopyOnWriteArrayList; -import cuchaz.enigma.network.packet.*; +import cuchaz.enigma.network.packet.EntryChangeS2CPacket; +import cuchaz.enigma.network.packet.KickS2CPacket; +import cuchaz.enigma.network.packet.MessageS2CPacket; +import cuchaz.enigma.network.packet.Packet; +import cuchaz.enigma.network.packet.PacketRegistry; +import cuchaz.enigma.network.packet.UserListS2CPacket; import cuchaz.enigma.translation.mapping.EntryChange; import cuchaz.enigma.translation.mapping.EntryMapping; import cuchaz.enigma.translation.mapping.EntryRemapper; import cuchaz.enigma.translation.representation.entry.Entry; public abstract class EnigmaServer { - // https://discordapp.com/channels/507304429255393322/566418023372816394/700292322918793347 public static final int DEFAULT_PORT = 34712; public static final int PROTOCOL_VERSION = 1; @@ -71,17 +86,22 @@ public abstract class EnigmaServer { Thread thread = new Thread(() -> { try { DataInput input = new DataInputStream(client.getInputStream()); + while (true) { int packetId; + try { packetId = input.readUnsignedByte(); } catch (EOFException | SocketException e) { break; } + Packet packet = PacketRegistry.createC2SPacket(packetId); + if (packet == null) { throw new IOException("Received invalid packet id " + packetId); } + packet.read(input); runOnThread(() -> packet.handle(new ServerPacketHandler(client, this))); } @@ -90,6 +110,7 @@ public abstract class EnigmaServer { e.printStackTrace(); return; } + kick(client, "disconnect.disconnected"); }); thread.setName("Server I/O thread #" + (nextIoId++)); @@ -103,6 +124,7 @@ public abstract class EnigmaServer { for (Socket client : clients) { kick(client, "disconnect.server_closed"); } + try { socket.close(); } catch (IOException e) { @@ -114,7 +136,9 @@ public abstract class EnigmaServer { } public void kick(Socket client, String reason) { - if (!clients.remove(client)) return; + if (!clients.remove(client)) { + return; + } sendPacket(client, new KickS2CPacket(reason)); @@ -123,6 +147,7 @@ public abstract class EnigmaServer { return list.isEmpty(); }); String username = usernames.remove(client); + try { client.close(); } catch (IOException e) { @@ -134,6 +159,7 @@ public abstract class EnigmaServer { System.out.println("Kicked " + username + " because " + reason); sendMessage(Message.disconnect(username)); } + sendUsernamePacket(); } @@ -159,6 +185,7 @@ public abstract class EnigmaServer { public void sendPacket(Socket client, Packet packet) { if (!client.isClosed()) { int packetId = PacketRegistry.getS2CId(packet); + try { DataOutput output = new DataOutputStream(client.getOutputStream()); output.writeByte(packetId); @@ -192,9 +219,11 @@ public abstract class EnigmaServer { } Integer syncId = syncIds.get(entry); + if (syncId == null) { return true; } + Set clients = clientsNeedingConfirmation.get(syncId); return clients == null || !clients.contains(client); } @@ -202,14 +231,18 @@ public abstract class EnigmaServer { public int lockEntry(Socket exception, Entry entry) { int syncId = nextSyncId; nextSyncId++; + // sync id is sent as an unsigned short, can't have more than 65536 if (nextSyncId == 65536) { nextSyncId = DUMMY_SYNC_ID + 1; } + Integer oldSyncId = syncIds.get(entry); + if (oldSyncId != null) { clientsNeedingConfirmation.remove(oldSyncId); } + syncIds.put(entry, syncId); inverseSyncIds.put(syncId, entry); Set clients = new HashSet<>(this.clients); @@ -224,8 +257,10 @@ public abstract class EnigmaServer { } Set clients = clientsNeedingConfirmation.get(syncId); + if (clients != null) { clients.remove(client); + if (clients.isEmpty()) { clientsNeedingConfirmation.remove(syncId); syncIds.remove(inverseSyncIds.remove(syncId)); @@ -236,6 +271,7 @@ public abstract class EnigmaServer { public void sendCorrectMapping(Socket client, Entry entry, boolean refreshClassTree) { EntryMapping oldMapping = mappings.getDeobfMapping(entry); String oldName = oldMapping.targetName(); + if (oldName == null) { sendPacket(client, new EntryChangeS2CPacket(DUMMY_SYNC_ID, EntryChange.modify(entry).clearDeobfName())); } else { @@ -269,5 +305,4 @@ public abstract class EnigmaServer { log(String.format("[MSG] %s", message.translate())); sendToAll(new MessageS2CPacket(message)); } - } diff --git a/enigma-server/src/main/java/cuchaz/enigma/network/IntegratedEnigmaServer.java b/enigma-server/src/main/java/cuchaz/enigma/network/IntegratedEnigmaServer.java index 21c6825..99e4e99 100644 --- a/enigma-server/src/main/java/cuchaz/enigma/network/IntegratedEnigmaServer.java +++ b/enigma-server/src/main/java/cuchaz/enigma/network/IntegratedEnigmaServer.java @@ -1,8 +1,8 @@ package cuchaz.enigma.network; -import cuchaz.enigma.translation.mapping.EntryRemapper; +import javax.swing.SwingUtilities; -import javax.swing.*; +import cuchaz.enigma.translation.mapping.EntryRemapper; public class IntegratedEnigmaServer extends EnigmaServer { public IntegratedEnigmaServer(byte[] jarChecksum, char[] password, EntryRemapper mappings, int port) { diff --git a/enigma-server/src/main/java/cuchaz/enigma/network/Message.java b/enigma-server/src/main/java/cuchaz/enigma/network/Message.java index c157838..d49e60c 100644 --- a/enigma-server/src/main/java/cuchaz/enigma/network/Message.java +++ b/enigma-server/src/main/java/cuchaz/enigma/network/Message.java @@ -10,9 +10,8 @@ import cuchaz.enigma.translation.representation.entry.Entry; import cuchaz.enigma.utils.I18n; public abstract class Message { - public final String user; - + public static Chat chat(String user, String message) { return new Chat(user, message); } @@ -47,34 +46,37 @@ public abstract class Message { public static Message read(DataInput input) throws IOException { byte typeId = input.readByte(); + if (typeId < 0 || typeId >= Type.values().length) { throw new IOException(String.format("Invalid message type ID %d", typeId)); } + Type type = Type.values()[typeId]; String user = input.readUTF(); + switch (type) { - case CHAT: - String message = input.readUTF(); - return chat(user, message); - case CONNECT: - return connect(user); - case DISCONNECT: - return disconnect(user); - case EDIT_DOCS: - Entry entry = PacketHelper.readEntry(input); - return editDocs(user, entry); - case MARK_DEOBF: - entry = PacketHelper.readEntry(input); - return markDeobf(user, entry); - case REMOVE_MAPPING: - entry = PacketHelper.readEntry(input); - return removeMapping(user, entry); - case RENAME: - entry = PacketHelper.readEntry(input); - String newName = input.readUTF(); - return rename(user, entry, newName); - default: - throw new IllegalStateException("unreachable"); + case CHAT: + String message = input.readUTF(); + return chat(user, message); + case CONNECT: + return connect(user); + case DISCONNECT: + return disconnect(user); + case EDIT_DOCS: + Entry entry = PacketHelper.readEntry(input); + return editDocs(user, entry); + case MARK_DEOBF: + entry = PacketHelper.readEntry(input); + return markDeobf(user, entry); + case REMOVE_MAPPING: + entry = PacketHelper.readEntry(input); + return removeMapping(user, entry); + case RENAME: + entry = PacketHelper.readEntry(input); + String newName = input.readUTF(); + return rename(user, entry, newName); + default: + throw new IllegalStateException("unreachable"); } } @@ -89,8 +91,14 @@ public abstract class Message { @Override public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; + if (this == o) { + return true; + } + + if (o == null || getClass() != o.getClass()) { + return false; + } + Message message = (Message) o; return Objects.equals(user, message.user); } @@ -111,7 +119,6 @@ public abstract class Message { } public static final class Chat extends Message { - public final String message; private Chat(String user, String message) { @@ -137,9 +144,18 @@ public abstract class Message { @Override public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - if (!super.equals(o)) return false; + if (this == o) { + return true; + } + + if (o == null || getClass() != o.getClass()) { + return false; + } + + if (!super.equals(o)) { + return false; + } + Chat chat = (Chat) o; return Objects.equals(message, chat.message); } @@ -153,11 +169,9 @@ public abstract class Message { public String toString() { return String.format("Message.Chat { user: '%s', message: '%s' }", user, message); } - } public static final class Connect extends Message { - private Connect(String user) { super(user); } @@ -176,11 +190,9 @@ public abstract class Message { public String toString() { return String.format("Message.Connect { user: '%s' }", user); } - } public static final class Disconnect extends Message { - private Disconnect(String user) { super(user); } @@ -199,11 +211,9 @@ public abstract class Message { public String toString() { return String.format("Message.Disconnect { user: '%s' }", user); } - } - public static final class EditDocs extends Message { - + public static final class EditDocs extends Message { public final Entry entry; private EditDocs(String user, Entry entry) { @@ -229,9 +239,18 @@ public abstract class Message { @Override public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - if (!super.equals(o)) return false; + if (this == o) { + return true; + } + + if (o == null || getClass() != o.getClass()) { + return false; + } + + if (!super.equals(o)) { + return false; + } + EditDocs editDocs = (EditDocs) o; return Objects.equals(entry, editDocs.entry); } @@ -245,11 +264,9 @@ public abstract class Message { public String toString() { return String.format("Message.EditDocs { user: '%s', entry: %s }", user, entry); } - } public static final class MarkDeobf extends Message { - public final Entry entry; private MarkDeobf(String user, Entry entry) { @@ -275,9 +292,18 @@ public abstract class Message { @Override public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - if (!super.equals(o)) return false; + if (this == o) { + return true; + } + + if (o == null || getClass() != o.getClass()) { + return false; + } + + if (!super.equals(o)) { + return false; + } + MarkDeobf markDeobf = (MarkDeobf) o; return Objects.equals(entry, markDeobf.entry); } @@ -291,11 +317,9 @@ public abstract class Message { public String toString() { return String.format("Message.MarkDeobf { user: '%s', entry: %s }", user, entry); } - } public static final class RemoveMapping extends Message { - public final Entry entry; private RemoveMapping(String user, Entry entry) { @@ -321,9 +345,18 @@ public abstract class Message { @Override public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - if (!super.equals(o)) return false; + if (this == o) { + return true; + } + + if (o == null || getClass() != o.getClass()) { + return false; + } + + if (!super.equals(o)) { + return false; + } + RemoveMapping that = (RemoveMapping) o; return Objects.equals(entry, that.entry); } @@ -337,11 +370,9 @@ public abstract class Message { public String toString() { return String.format("Message.RemoveMapping { user: '%s', entry: %s }", user, entry); } - } public static final class Rename extends Message { - public final Entry entry; public final String newName; @@ -370,12 +401,20 @@ public abstract class Message { @Override public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - if (!super.equals(o)) return false; + if (this == o) { + return true; + } + + if (o == null || getClass() != o.getClass()) { + return false; + } + + if (!super.equals(o)) { + return false; + } + Rename rename = (Rename) o; - return Objects.equals(entry, rename.entry) && - Objects.equals(newName, rename.newName); + return Objects.equals(entry, rename.entry) && Objects.equals(newName, rename.newName); } @Override @@ -387,7 +426,5 @@ public abstract class Message { public String toString() { return String.format("Message.Rename { user: '%s', entry: %s, newName: '%s' }", user, entry, newName); } - } - } diff --git a/enigma-server/src/main/java/cuchaz/enigma/network/ServerAddress.java b/enigma-server/src/main/java/cuchaz/enigma/network/ServerAddress.java index 45e0750..a8a1029 100644 --- a/enigma-server/src/main/java/cuchaz/enigma/network/ServerAddress.java +++ b/enigma-server/src/main/java/cuchaz/enigma/network/ServerAddress.java @@ -5,7 +5,6 @@ import java.util.Objects; import javax.annotation.Nullable; public class ServerAddress { - public final String address; public final int port; @@ -16,11 +15,26 @@ public class ServerAddress { @Nullable public static ServerAddress of(String address, int port) { - if (port < 0 || port > 65535) return null; - if (address == null) return null; - if (address.equals("")) return null; - if (!address.matches("[a-zA-Z0-9.:-]+")) return null; - if (address.startsWith("-") || address.endsWith("-")) return null; + if (port < 0 || port > 65535) { + return null; + } + + if (address == null) { + return null; + } + + if (address.equals("")) { + return null; + } + + if (!address.matches("[a-zA-Z0-9.:-]+")) { + return null; + } + + if (address.startsWith("-") || address.endsWith("-")) { + return null; + } + return new ServerAddress(address, port); } @@ -28,6 +42,7 @@ public class ServerAddress { public static ServerAddress from(String s, int defaultPort) { String address; int idx = s.indexOf(']'); + if (s.startsWith("[") && idx != -1) { address = s.substring(1, idx); s = s.substring(idx + 1); @@ -41,10 +56,12 @@ public class ServerAddress { } int port; + if (s.isEmpty()) { port = defaultPort; } else if (s.startsWith(":")) { s = s.substring(1); + try { port = Integer.parseInt(s); } catch (NumberFormatException e) { @@ -53,16 +70,22 @@ public class ServerAddress { } else { return null; } + return ServerAddress.of(address, port); } @Override public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; + if (this == o) { + return true; + } + + if (o == null || getClass() != o.getClass()) { + return false; + } + ServerAddress that = (ServerAddress) o; - return port == that.port && - Objects.equals(address, that.address); + return port == that.port && Objects.equals(address, that.address); } @Override @@ -74,5 +97,4 @@ public class ServerAddress { public String toString() { return String.format("ServerAddress { address: '%s', port: %d }", address, port); } - } diff --git a/enigma-server/src/main/java/cuchaz/enigma/network/ServerPacketHandler.java b/enigma-server/src/main/java/cuchaz/enigma/network/ServerPacketHandler.java index 8618553..5b5b0e6 100644 --- a/enigma-server/src/main/java/cuchaz/enigma/network/ServerPacketHandler.java +++ b/enigma-server/src/main/java/cuchaz/enigma/network/ServerPacketHandler.java @@ -3,7 +3,6 @@ package cuchaz.enigma.network; import java.net.Socket; public class ServerPacketHandler { - private final Socket client; private final EnigmaServer server; diff --git a/enigma-server/src/main/java/cuchaz/enigma/network/packet/ConfirmChangeC2SPacket.java b/enigma-server/src/main/java/cuchaz/enigma/network/packet/ConfirmChangeC2SPacket.java index 78ef964..ab4f5a1 100644 --- a/enigma-server/src/main/java/cuchaz/enigma/network/packet/ConfirmChangeC2SPacket.java +++ b/enigma-server/src/main/java/cuchaz/enigma/network/packet/ConfirmChangeC2SPacket.java @@ -1,11 +1,11 @@ package cuchaz.enigma.network.packet; -import cuchaz.enigma.network.ServerPacketHandler; - import java.io.DataInput; import java.io.DataOutput; import java.io.IOException; +import cuchaz.enigma.network.ServerPacketHandler; + public class ConfirmChangeC2SPacket implements Packet { private int syncId; diff --git a/enigma-server/src/main/java/cuchaz/enigma/network/packet/EntryChangeC2SPacket.java b/enigma-server/src/main/java/cuchaz/enigma/network/packet/EntryChangeC2SPacket.java index b97877c..6a7ffe9 100644 --- a/enigma-server/src/main/java/cuchaz/enigma/network/packet/EntryChangeC2SPacket.java +++ b/enigma-server/src/main/java/cuchaz/enigma/network/packet/EntryChangeC2SPacket.java @@ -12,7 +12,6 @@ import cuchaz.enigma.utils.validation.PrintValidatable; import cuchaz.enigma.utils.validation.ValidationContext; public class EntryChangeC2SPacket implements Packet { - private EntryChange change; EntryChangeC2SPacket() { @@ -62,5 +61,4 @@ public class EntryChangeC2SPacket implements Packet { handler.getServer().sendMessage(Message.editDocs(handler.getServer().getUsername(handler.getClient()), this.change.getTarget())); } } - } diff --git a/enigma-server/src/main/java/cuchaz/enigma/network/packet/EntryChangeS2CPacket.java b/enigma-server/src/main/java/cuchaz/enigma/network/packet/EntryChangeS2CPacket.java index a237b91..8e4688e 100644 --- a/enigma-server/src/main/java/cuchaz/enigma/network/packet/EntryChangeS2CPacket.java +++ b/enigma-server/src/main/java/cuchaz/enigma/network/packet/EntryChangeS2CPacket.java @@ -8,7 +8,6 @@ import cuchaz.enigma.network.ClientPacketHandler; import cuchaz.enigma.translation.mapping.EntryChange; public class EntryChangeS2CPacket implements Packet { - private int syncId; private EntryChange change; @@ -38,5 +37,4 @@ public class EntryChangeS2CPacket implements Packet { handler.sendPacket(new ConfirmChangeC2SPacket(this.syncId)); } } - } diff --git a/enigma-server/src/main/java/cuchaz/enigma/network/packet/KickS2CPacket.java b/enigma-server/src/main/java/cuchaz/enigma/network/packet/KickS2CPacket.java index 9a112a8..bd238dc 100644 --- a/enigma-server/src/main/java/cuchaz/enigma/network/packet/KickS2CPacket.java +++ b/enigma-server/src/main/java/cuchaz/enigma/network/packet/KickS2CPacket.java @@ -1,11 +1,11 @@ package cuchaz.enigma.network.packet; -import cuchaz.enigma.network.ClientPacketHandler; - import java.io.DataInput; import java.io.DataOutput; import java.io.IOException; +import cuchaz.enigma.network.ClientPacketHandler; + public class KickS2CPacket implements Packet { private String reason; diff --git a/enigma-server/src/main/java/cuchaz/enigma/network/packet/LoginC2SPacket.java b/enigma-server/src/main/java/cuchaz/enigma/network/packet/LoginC2SPacket.java index da0f44a..e93c1d4 100644 --- a/enigma-server/src/main/java/cuchaz/enigma/network/packet/LoginC2SPacket.java +++ b/enigma-server/src/main/java/cuchaz/enigma/network/packet/LoginC2SPacket.java @@ -1,14 +1,14 @@ package cuchaz.enigma.network.packet; -import cuchaz.enigma.network.EnigmaServer; -import cuchaz.enigma.network.ServerPacketHandler; -import cuchaz.enigma.network.Message; - import java.io.DataInput; import java.io.DataOutput; import java.io.IOException; import java.util.Arrays; +import cuchaz.enigma.network.EnigmaServer; +import cuchaz.enigma.network.Message; +import cuchaz.enigma.network.ServerPacketHandler; + public class LoginC2SPacket implements Packet { private byte[] jarChecksum; private char[] password; @@ -28,12 +28,15 @@ public class LoginC2SPacket implements Packet { if (input.readUnsignedShort() != EnigmaServer.PROTOCOL_VERSION) { throw new IOException("Mismatching protocol"); } + this.jarChecksum = new byte[EnigmaServer.CHECKSUM_SIZE]; input.readFully(jarChecksum); this.password = new char[input.readUnsignedByte()]; + for (int i = 0; i < password.length; i++) { password[i] = input.readChar(); } + this.username = PacketHelper.readString(input); } @@ -42,9 +45,11 @@ public class LoginC2SPacket implements Packet { output.writeShort(EnigmaServer.PROTOCOL_VERSION); output.write(jarChecksum); output.writeByte(password.length); + for (char c : password) { output.writeChar(c); } + PacketHelper.writeString(output, username); } diff --git a/enigma-server/src/main/java/cuchaz/enigma/network/packet/MessageC2SPacket.java b/enigma-server/src/main/java/cuchaz/enigma/network/packet/MessageC2SPacket.java index 3bc09e7..b0610b0 100644 --- a/enigma-server/src/main/java/cuchaz/enigma/network/packet/MessageC2SPacket.java +++ b/enigma-server/src/main/java/cuchaz/enigma/network/packet/MessageC2SPacket.java @@ -4,11 +4,10 @@ import java.io.DataInput; import java.io.DataOutput; import java.io.IOException; -import cuchaz.enigma.network.ServerPacketHandler; import cuchaz.enigma.network.Message; +import cuchaz.enigma.network.ServerPacketHandler; public class MessageC2SPacket implements Packet { - private String message; MessageC2SPacket() { @@ -31,9 +30,9 @@ public class MessageC2SPacket implements Packet { @Override public void handle(ServerPacketHandler handler) { String message = this.message.trim(); + if (!message.isEmpty()) { handler.getServer().sendMessage(Message.chat(handler.getServer().getUsername(handler.getClient()), message)); } } - } diff --git a/enigma-server/src/main/java/cuchaz/enigma/network/packet/MessageS2CPacket.java b/enigma-server/src/main/java/cuchaz/enigma/network/packet/MessageS2CPacket.java index 2b07968..9833eeb 100644 --- a/enigma-server/src/main/java/cuchaz/enigma/network/packet/MessageS2CPacket.java +++ b/enigma-server/src/main/java/cuchaz/enigma/network/packet/MessageS2CPacket.java @@ -8,7 +8,6 @@ import cuchaz.enigma.network.ClientPacketHandler; import cuchaz.enigma.network.Message; public class MessageS2CPacket implements Packet { - private Message message; MessageS2CPacket() { @@ -32,5 +31,4 @@ public class MessageS2CPacket implements Packet { public void handle(ClientPacketHandler handler) { handler.addMessage(message); } - } diff --git a/enigma-server/src/main/java/cuchaz/enigma/network/packet/Packet.java b/enigma-server/src/main/java/cuchaz/enigma/network/packet/Packet.java index 2f16dfb..15054e7 100644 --- a/enigma-server/src/main/java/cuchaz/enigma/network/packet/Packet.java +++ b/enigma-server/src/main/java/cuchaz/enigma/network/packet/Packet.java @@ -5,11 +5,9 @@ import java.io.DataOutput; import java.io.IOException; public interface Packet { - void read(DataInput input) throws IOException; void write(DataOutput output) throws IOException; void handle(H handler); - } diff --git a/enigma-server/src/main/java/cuchaz/enigma/network/packet/PacketHelper.java b/enigma-server/src/main/java/cuchaz/enigma/network/packet/PacketHelper.java index 2649cdc..ce767c3 100644 --- a/enigma-server/src/main/java/cuchaz/enigma/network/packet/PacketHelper.java +++ b/enigma-server/src/main/java/cuchaz/enigma/network/packet/PacketHelper.java @@ -9,11 +9,14 @@ import cuchaz.enigma.translation.mapping.AccessModifier; import cuchaz.enigma.translation.mapping.EntryChange; import cuchaz.enigma.translation.representation.MethodDescriptor; import cuchaz.enigma.translation.representation.TypeDescriptor; -import cuchaz.enigma.translation.representation.entry.*; +import cuchaz.enigma.translation.representation.entry.ClassEntry; +import cuchaz.enigma.translation.representation.entry.Entry; +import cuchaz.enigma.translation.representation.entry.FieldEntry; +import cuchaz.enigma.translation.representation.entry.LocalVariableEntry; +import cuchaz.enigma.translation.representation.entry.MethodEntry; import cuchaz.enigma.utils.TristateChange; public class PacketHelper { - private static final int ENTRY_CLASS = 0, ENTRY_FIELD = 1, ENTRY_METHOD = 2, ENTRY_LOCAL_VAR = 3; private static final int MAX_STRING_LENGTH = 65535; @@ -31,45 +34,46 @@ public class PacketHelper { String name = readString(input); String javadocs = null; + if (input.readBoolean()) { javadocs = readString(input); } switch (type) { - case ENTRY_CLASS: { - if (parent != null && !(parent instanceof ClassEntry)) { - throw new IOException("Class requires class parent"); - } - - return new ClassEntry((ClassEntry) parent, name, javadocs); + case ENTRY_CLASS: { + if (parent != null && !(parent instanceof ClassEntry)) { + throw new IOException("Class requires class parent"); } - case ENTRY_FIELD: { - if (!(parent instanceof ClassEntry parentClass)) { - throw new IOException("Field requires class parent"); - } - TypeDescriptor desc = new TypeDescriptor(readString(input)); - return new FieldEntry(parentClass, name, desc, javadocs); + return new ClassEntry((ClassEntry) parent, name, javadocs); + } + case ENTRY_FIELD: { + if (!(parent instanceof ClassEntry parentClass)) { + throw new IOException("Field requires class parent"); } - case ENTRY_METHOD: { - if (!(parent instanceof ClassEntry parentClass)) { - throw new IOException("Method requires class parent"); - } - MethodDescriptor desc = new MethodDescriptor(readString(input)); - return new MethodEntry(parentClass, name, desc, javadocs); + TypeDescriptor desc = new TypeDescriptor(readString(input)); + return new FieldEntry(parentClass, name, desc, javadocs); + } + case ENTRY_METHOD: { + if (!(parent instanceof ClassEntry parentClass)) { + throw new IOException("Method requires class parent"); } - case ENTRY_LOCAL_VAR: { - if (!(parent instanceof MethodEntry parentMethod)) { - throw new IOException("Local variable requires method parent"); - } - - int index = input.readUnsignedShort(); - boolean parameter = input.readBoolean(); - return new LocalVariableEntry(parentMethod, index, name, parameter, javadocs); + + MethodDescriptor desc = new MethodDescriptor(readString(input)); + return new MethodEntry(parentClass, name, desc, javadocs); + } + case ENTRY_LOCAL_VAR: { + if (!(parent instanceof MethodEntry parentMethod)) { + throw new IOException("Local variable requires method parent"); } - default: - throw new IOException("Received unknown entry type " + type); + + int index = input.readUnsignedShort(); + boolean parameter = input.readBoolean(); + return new LocalVariableEntry(parentMethod, index, name, parameter, javadocs); + } + default: + throw new IOException("Received unknown entry type " + type); } } @@ -94,6 +98,7 @@ public class PacketHelper { // parent if (includeParent) { output.writeBoolean(entry.getParent() != null); + if (entry.getParent() != null) { writeEntry(output, entry.getParent(), true); } @@ -104,6 +109,7 @@ public class PacketHelper { // javadocs output.writeBoolean(entry.getJavadocs() != null); + if (entry.getJavadocs() != null) { writeString(output, entry.getJavadocs()); } @@ -129,9 +135,11 @@ public class PacketHelper { public static void writeString(DataOutput output, String str) throws IOException { byte[] bytes = str.getBytes(StandardCharsets.UTF_8); + if (bytes.length > MAX_STRING_LENGTH) { throw new IOException("String too long, was " + bytes.length + " bytes, max " + MAX_STRING_LENGTH + " allowed"); } + output.writeShort(bytes.length); output.write(bytes); } @@ -146,30 +154,30 @@ public class PacketHelper { TristateChange.Type javadocT = TristateChange.Type.values()[flags >> 4 & 0x3]; switch (deobfNameT) { - case RESET: - change = change.clearDeobfName(); - break; - case SET: - change = change.withDeobfName(readString(input)); - break; + case RESET: + change = change.clearDeobfName(); + break; + case SET: + change = change.withDeobfName(readString(input)); + break; } switch (accessT) { - case RESET: - change = change.clearAccess(); - break; - case SET: - change = change.withAccess(AccessModifier.values()[flags >> 6 & 0x3]); - break; + case RESET: + change = change.clearAccess(); + break; + case SET: + change = change.withAccess(AccessModifier.values()[flags >> 6 & 0x3]); + break; } switch (javadocT) { - case RESET: - change = change.clearJavadoc(); - break; - case SET: - change = change.withJavadoc(readString(input)); - break; + case RESET: + change = change.clearJavadoc(); + break; + case SET: + change = change.withJavadoc(readString(input)); + break; } return change; @@ -177,9 +185,7 @@ public class PacketHelper { public static void writeEntryChange(DataOutput output, EntryChange change) throws IOException { writeEntry(output, change.getTarget()); - int flags = change.getDeobfName().getType().ordinal() | - change.getAccess().getType().ordinal() << 2 | - change.getJavadoc().getType().ordinal() << 4; + int flags = change.getDeobfName().getType().ordinal() | change.getAccess().getType().ordinal() << 2 | change.getJavadoc().getType().ordinal() << 4; if (change.getAccess().isSet()) { flags |= change.getAccess().getNewValue().ordinal() << 6; @@ -195,5 +201,4 @@ public class PacketHelper { writeString(output, change.getJavadoc().getNewValue()); } } - } diff --git a/enigma-server/src/main/java/cuchaz/enigma/network/packet/PacketRegistry.java b/enigma-server/src/main/java/cuchaz/enigma/network/packet/PacketRegistry.java index 59999cc..49d56fd 100644 --- a/enigma-server/src/main/java/cuchaz/enigma/network/packet/PacketRegistry.java +++ b/enigma-server/src/main/java/cuchaz/enigma/network/packet/PacketRegistry.java @@ -8,7 +8,6 @@ import cuchaz.enigma.network.ClientPacketHandler; import cuchaz.enigma.network.ServerPacketHandler; public class PacketRegistry { - private static final Map>, Integer> c2sPacketIds = new HashMap<>(); private static final Map>> c2sPacketCreators = new HashMap<>(); private static final Map>, Integer> s2cPacketIds = new HashMap<>(); @@ -54,5 +53,4 @@ public class PacketRegistry { Supplier> creator = s2cPacketCreators.get(id); return creator == null ? null : creator.get(); } - } diff --git a/enigma-server/src/main/java/cuchaz/enigma/network/packet/SyncMappingsS2CPacket.java b/enigma-server/src/main/java/cuchaz/enigma/network/packet/SyncMappingsS2CPacket.java index 6d9c0bc..7e50938 100644 --- a/enigma-server/src/main/java/cuchaz/enigma/network/packet/SyncMappingsS2CPacket.java +++ b/enigma-server/src/main/java/cuchaz/enigma/network/packet/SyncMappingsS2CPacket.java @@ -28,6 +28,7 @@ public class SyncMappingsS2CPacket implements Packet { public void read(DataInput input) throws IOException { mappings = new HashEntryTree<>(); int size = input.readInt(); + for (int i = 0; i < size; i++) { readEntryTreeNode(input, null); } @@ -40,6 +41,7 @@ public class SyncMappingsS2CPacket implements Packet { EntryMapping mapping = new EntryMapping(!name.isEmpty() ? name : null, !javadoc.isEmpty() ? javadoc : null); mappings.insert(entry, mapping); int size = input.readUnsignedShort(); + for (int i = 0; i < size; i++) { readEntryTreeNode(input, entry); } @@ -49,6 +51,7 @@ public class SyncMappingsS2CPacket implements Packet { public void write(DataOutput output) throws IOException { List> roots = mappings.getRootNodes().toList(); output.writeInt(roots.size()); + for (EntryTreeNode node : roots) { writeEntryTreeNode(output, node); } @@ -57,12 +60,16 @@ public class SyncMappingsS2CPacket implements Packet { private static void writeEntryTreeNode(DataOutput output, EntryTreeNode node) throws IOException { PacketHelper.writeEntry(output, node.getEntry(), false); EntryMapping value = node.getValue(); - if (value == null) value = EntryMapping.DEFAULT; + + if (value == null) { + value = EntryMapping.DEFAULT; + } PacketHelper.writeString(output, value.targetName() != null ? value.targetName() : ""); PacketHelper.writeString(output, value.javadoc() != null ? value.javadoc() : ""); Collection> children = node.getChildNodes(); output.writeShort(children.size()); + for (EntryTreeNode child : children) { writeEntryTreeNode(output, child); } diff --git a/enigma-server/src/main/java/cuchaz/enigma/network/packet/UserListS2CPacket.java b/enigma-server/src/main/java/cuchaz/enigma/network/packet/UserListS2CPacket.java index b4a277a..baac2b3 100644 --- a/enigma-server/src/main/java/cuchaz/enigma/network/packet/UserListS2CPacket.java +++ b/enigma-server/src/main/java/cuchaz/enigma/network/packet/UserListS2CPacket.java @@ -1,15 +1,14 @@ package cuchaz.enigma.network.packet; -import cuchaz.enigma.network.ClientPacketHandler; - import java.io.DataInput; import java.io.DataOutput; import java.io.IOException; import java.util.ArrayList; import java.util.List; -public class UserListS2CPacket implements Packet { +import cuchaz.enigma.network.ClientPacketHandler; +public class UserListS2CPacket implements Packet { private List users; UserListS2CPacket() { @@ -23,6 +22,7 @@ public class UserListS2CPacket implements Packet { public void read(DataInput input) throws IOException { int len = input.readUnsignedShort(); users = new ArrayList<>(len); + for (int i = 0; i < len; i++) { users.add(input.readUTF()); } @@ -31,6 +31,7 @@ public class UserListS2CPacket implements Packet { @Override public void write(DataOutput output) throws IOException { output.writeShort(users.size()); + for (String user : users) { PacketHelper.writeString(output, user); } @@ -40,5 +41,4 @@ public class UserListS2CPacket implements Packet { public void handle(ClientPacketHandler handler) { handler.updateUserList(users); } - } diff --git a/enigma-server/src/test/java/cuchaz/enigma/network/ServerAddressTest.java b/enigma-server/src/test/java/cuchaz/enigma/network/ServerAddressTest.java index 3765f7a..c2920e0 100644 --- a/enigma-server/src/test/java/cuchaz/enigma/network/ServerAddressTest.java +++ b/enigma-server/src/test/java/cuchaz/enigma/network/ServerAddressTest.java @@ -1,12 +1,11 @@ package cuchaz.enigma.network; -import org.junit.Test; - import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNull; -public class ServerAddressTest { +import org.junit.Test; +public class ServerAddressTest { @Test public void validAddresses() { assertEquals(ServerAddress.of("127.0.0.1", 22), ServerAddress.from("127.0.0.1", 22)); @@ -24,5 +23,4 @@ public class ServerAddressTest { assertNull(ServerAddress.from("127.0.0.1:100000000", 22)); assertNull(ServerAddress.from("127.0.0.1:lmao", 22)); } - } -- cgit v1.2.3