Added some message, fixed problem with packet reading

This commit is contained in:
LOOHP 2020-08-04 23:44:58 +08:00
parent b01cbad932
commit 4600303f96
11 changed files with 330 additions and 16 deletions

View File

@ -0,0 +1,32 @@
package com.loohp.limbo;
import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import com.loohp.limbo.Server.Packets.PacketPlayOutDeclareCommands;
import com.loohp.limbo.Utils.DataTypeIO;
public class DeclareCommands {
public static PacketPlayOutDeclareCommands getDeclareCommandPacket() throws IOException {
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
DataOutputStream output = new DataOutputStream(buffer);
DataTypeIO.writeVarInt(output, 2);
output.writeByte(0);
DataTypeIO.writeVarInt(output, 1);
DataTypeIO.writeVarInt(output, 1);
output.writeByte(1 | 0x04);
DataTypeIO.writeVarInt(output, 0);
DataTypeIO.writeString(output, "spawn", StandardCharsets.UTF_8);
DataTypeIO.writeVarInt(output, 0);
return new PacketPlayOutDeclareCommands(buffer.toByteArray());
}
}

View File

@ -27,6 +27,7 @@ import com.loohp.limbo.Server.Packets.Packet;
import com.loohp.limbo.Server.Packets.PacketIn; import com.loohp.limbo.Server.Packets.PacketIn;
import com.loohp.limbo.Server.Packets.PacketOut; import com.loohp.limbo.Server.Packets.PacketOut;
import com.loohp.limbo.Utils.ImageUtils; import com.loohp.limbo.Utils.ImageUtils;
import com.loohp.limbo.Utils.NetworkUtils;
import com.loohp.limbo.World.Schematic; import com.loohp.limbo.World.Schematic;
import com.loohp.limbo.World.World; import com.loohp.limbo.World.World;
@ -74,6 +75,12 @@ public class Limbo {
} }
} }
properties = new ServerProperties(sp); properties = new ServerProperties(sp);
if (!properties.isBungeecord()) {
console.sendMessage("If you are using bungeecord, consider turning that on in the settings!");
} else {
console.sendMessage("Starting Limbo server in bungeecord mode!");
}
String mappingName = "mapping.json"; String mappingName = "mapping.json";
File mappingFile = new File(mappingName); File mappingFile = new File(mappingName);
@ -85,9 +92,12 @@ public class Limbo {
} }
} }
console.sendMessage("Loading packet id mappings from mapping.json ...");
JSONObject json = (JSONObject) new JSONParser().parse(new FileReader(mappingFile)); JSONObject json = (JSONObject) new JSONParser().parse(new FileReader(mappingFile));
String classPrefix = Packet.class.getName().substring(0, Packet.class.getName().lastIndexOf(".") + 1); String classPrefix = Packet.class.getName().substring(0, Packet.class.getName().lastIndexOf(".") + 1);
int mappingsCount = 0;
Map<Integer, Class<? extends PacketIn>> HandshakeIn = new HashMap<>(); Map<Integer, Class<? extends PacketIn>> HandshakeIn = new HashMap<>();
for (Object key : ((JSONObject) json.get("HandshakeIn")).keySet()) { for (Object key : ((JSONObject) json.get("HandshakeIn")).keySet()) {
@ -95,6 +105,7 @@ public class Limbo {
HandshakeIn.put(packetId, (Class<? extends PacketIn>) Class.forName(classPrefix + (String) ((JSONObject) json.get("HandshakeIn")).get(key))); HandshakeIn.put(packetId, (Class<? extends PacketIn>) Class.forName(classPrefix + (String) ((JSONObject) json.get("HandshakeIn")).get(key)));
} }
Packet.setHandshakeIn(HandshakeIn); Packet.setHandshakeIn(HandshakeIn);
mappingsCount += HandshakeIn.size();
Map<Integer, Class<? extends PacketIn>> StatusIn = new HashMap<>(); Map<Integer, Class<? extends PacketIn>> StatusIn = new HashMap<>();
for (Object key : ((JSONObject) json.get("StatusIn")).keySet()) { for (Object key : ((JSONObject) json.get("StatusIn")).keySet()) {
@ -102,6 +113,7 @@ public class Limbo {
StatusIn.put(packetId, (Class<? extends PacketIn>) Class.forName(classPrefix + (String) ((JSONObject) json.get("StatusIn")).get(key))); StatusIn.put(packetId, (Class<? extends PacketIn>) Class.forName(classPrefix + (String) ((JSONObject) json.get("StatusIn")).get(key)));
} }
Packet.setStatusIn(StatusIn); Packet.setStatusIn(StatusIn);
mappingsCount += StatusIn.size();
Map<Class<? extends PacketOut>, Integer> StatusOut = new HashMap<>(); Map<Class<? extends PacketOut>, Integer> StatusOut = new HashMap<>();
for (Object key : ((JSONObject) json.get("StatusOut")).keySet()) { for (Object key : ((JSONObject) json.get("StatusOut")).keySet()) {
@ -109,6 +121,7 @@ public class Limbo {
StatusOut.put(packetClass, Integer.decode((String) ((JSONObject) json.get("StatusOut")).get(key))); StatusOut.put(packetClass, Integer.decode((String) ((JSONObject) json.get("StatusOut")).get(key)));
} }
Packet.setStatusOut(StatusOut); Packet.setStatusOut(StatusOut);
mappingsCount += StatusOut.size();
Map<Integer, Class<? extends PacketIn>> LoginIn = new HashMap<>(); Map<Integer, Class<? extends PacketIn>> LoginIn = new HashMap<>();
for (Object key : ((JSONObject) json.get("LoginIn")).keySet()) { for (Object key : ((JSONObject) json.get("LoginIn")).keySet()) {
@ -116,6 +129,7 @@ public class Limbo {
LoginIn.put(packetId, (Class<? extends PacketIn>) Class.forName(classPrefix + (String) ((JSONObject) json.get("LoginIn")).get(key))); LoginIn.put(packetId, (Class<? extends PacketIn>) Class.forName(classPrefix + (String) ((JSONObject) json.get("LoginIn")).get(key)));
} }
Packet.setLoginIn(LoginIn); Packet.setLoginIn(LoginIn);
mappingsCount += LoginIn.size();
Map<Class<? extends PacketOut>, Integer> LoginOut = new HashMap<>(); Map<Class<? extends PacketOut>, Integer> LoginOut = new HashMap<>();
for (Object key : ((JSONObject) json.get("LoginOut")).keySet()) { for (Object key : ((JSONObject) json.get("LoginOut")).keySet()) {
@ -123,6 +137,7 @@ public class Limbo {
LoginOut.put(packetClass, Integer.decode((String) ((JSONObject) json.get("LoginOut")).get(key))); LoginOut.put(packetClass, Integer.decode((String) ((JSONObject) json.get("LoginOut")).get(key)));
} }
Packet.setLoginOut(LoginOut); Packet.setLoginOut(LoginOut);
mappingsCount += LoginOut.size();
Map<Integer, Class<? extends PacketIn>> PlayIn = new HashMap<>(); Map<Integer, Class<? extends PacketIn>> PlayIn = new HashMap<>();
for (Object key : ((JSONObject) json.get("PlayIn")).keySet()) { for (Object key : ((JSONObject) json.get("PlayIn")).keySet()) {
@ -130,6 +145,7 @@ public class Limbo {
PlayIn.put(packetId, (Class<? extends PacketIn>) Class.forName(classPrefix + (String) ((JSONObject) json.get("PlayIn")).get(key))); PlayIn.put(packetId, (Class<? extends PacketIn>) Class.forName(classPrefix + (String) ((JSONObject) json.get("PlayIn")).get(key)));
} }
Packet.setPlayIn(PlayIn); Packet.setPlayIn(PlayIn);
mappingsCount += PlayIn.size();
Map<Class<? extends PacketOut>, Integer> PlayOut = new HashMap<>(); Map<Class<? extends PacketOut>, Integer> PlayOut = new HashMap<>();
for (Object key : ((JSONObject) json.get("PlayOut")).keySet()) { for (Object key : ((JSONObject) json.get("PlayOut")).keySet()) {
@ -137,27 +153,43 @@ public class Limbo {
PlayOut.put(packetClass, Integer.decode((String) ((JSONObject) json.get("PlayOut")).get(key))); PlayOut.put(packetClass, Integer.decode((String) ((JSONObject) json.get("PlayOut")).get(key)));
} }
Packet.setPlayOut(PlayOut); Packet.setPlayOut(PlayOut);
mappingsCount += PlayOut.size();
console.sendMessage("Loaded all " + mappingsCount + " packet id mappings!");
worlds.add(loadDefaultWorld()); worlds.add(loadDefaultWorld());
Location spawn = properties.getWorldSpawn(); Location spawn = properties.getWorldSpawn();
properties.setWorldSpawn(new Location(getWorld(properties.getLevelName().getKey()), spawn.getX(), spawn.getY(), spawn.getZ(), spawn.getYaw(), spawn.getPitch())); properties.setWorldSpawn(new Location(getWorld(properties.getLevelName().getKey()), spawn.getX(), spawn.getY(), spawn.getZ(), spawn.getYaw(), spawn.getPitch()));
if (!NetworkUtils.available(properties.getServerPort())) {
console.sendMessage("");
console.sendMessage("*****FAILED TO BIND PORT [" + properties.getServerPort() + "]*****");
console.sendMessage("*****PORT ALREADY IN USE*****");
console.sendMessage("*****PERHAPS ANOTHER INSTANCE OF THE SERVER IS ALREADY RUNNING?*****");
console.sendMessage("");
System.exit(2);
}
server = new ServerConnection(properties.getServerIp(), properties.getServerPort()); server = new ServerConnection(properties.getServerIp(), properties.getServerPort());
console.run(); console.run();
} }
private World loadDefaultWorld() throws IOException { private World loadDefaultWorld() throws IOException {
console.sendMessage("Loading world " + properties.getLevelName() + " with the schematic file " + properties.getSchemFileName() + " ...");
File schem = new File(properties.getSchemFileName()); File schem = new File(properties.getSchemFileName());
if (!schem.exists()) { if (!schem.exists()) {
System.out.println("Schemetic file " + properties.getSchemFileName() + " for world " + properties.getLevelName() + " not found!"); console.sendMessage("Schemetic file " + properties.getSchemFileName() + " for world " + properties.getLevelName() + " not found!");
console.sendMessage("Server will exit!");
System.exit(1);
return null; return null;
} }
World world = Schematic.toWorld(properties.getLevelName().getKey(), (CompoundTag) NBTUtil.read(schem).getTag()); World world = Schematic.toWorld(properties.getLevelName().getKey(), (CompoundTag) NBTUtil.read(schem).getTag());
System.out.println("Loaded world " + properties.getLevelName() + " with the schematic file " + properties.getSchemFileName()); console.sendMessage("Loaded world " + properties.getLevelName() + "!");
return world; return world;
} }

View File

@ -6,10 +6,13 @@ import java.io.IOException;
import java.net.InetAddress; import java.net.InetAddress;
import java.net.Socket; import java.net.Socket;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional; import java.util.Optional;
import java.util.UUID; import java.util.UUID;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import com.loohp.limbo.DeclareCommands;
import com.loohp.limbo.Limbo; import com.loohp.limbo.Limbo;
import com.loohp.limbo.File.ServerProperties; import com.loohp.limbo.File.ServerProperties;
import com.loohp.limbo.Location.Location; import com.loohp.limbo.Location.Location;
@ -25,6 +28,8 @@ import com.loohp.limbo.Server.Packets.PacketPlayInKeepAlive;
import com.loohp.limbo.Server.Packets.PacketPlayInPosition; import com.loohp.limbo.Server.Packets.PacketPlayInPosition;
import com.loohp.limbo.Server.Packets.PacketPlayInPositionAndLook; import com.loohp.limbo.Server.Packets.PacketPlayInPositionAndLook;
import com.loohp.limbo.Server.Packets.PacketPlayInRotation; import com.loohp.limbo.Server.Packets.PacketPlayInRotation;
import com.loohp.limbo.Server.Packets.PacketPlayInTabComplete;
import com.loohp.limbo.Server.Packets.PacketPlayOutDeclareCommands;
import com.loohp.limbo.Server.Packets.PacketPlayOutDisconnect; import com.loohp.limbo.Server.Packets.PacketPlayOutDisconnect;
import com.loohp.limbo.Server.Packets.PacketPlayOutLogin; import com.loohp.limbo.Server.Packets.PacketPlayOutLogin;
import com.loohp.limbo.Server.Packets.PacketPlayOutMapChunk; import com.loohp.limbo.Server.Packets.PacketPlayOutMapChunk;
@ -37,6 +42,8 @@ import com.loohp.limbo.Server.Packets.PacketPlayOutPlayerInfo.PlayerInfoData.Pla
import com.loohp.limbo.Server.Packets.PacketPlayOutPositionAndLook; import com.loohp.limbo.Server.Packets.PacketPlayOutPositionAndLook;
import com.loohp.limbo.Server.Packets.PacketPlayOutShowPlayerSkins; import com.loohp.limbo.Server.Packets.PacketPlayOutShowPlayerSkins;
import com.loohp.limbo.Server.Packets.PacketPlayOutSpawnPosition; import com.loohp.limbo.Server.Packets.PacketPlayOutSpawnPosition;
import com.loohp.limbo.Server.Packets.PacketPlayOutTabComplete;
import com.loohp.limbo.Server.Packets.PacketPlayOutTabComplete.TabCompleteMatches;
import com.loohp.limbo.Server.Packets.PacketPlayOutUpdateViewPosition; import com.loohp.limbo.Server.Packets.PacketPlayOutUpdateViewPosition;
import com.loohp.limbo.Server.Packets.PacketStatusInPing; import com.loohp.limbo.Server.Packets.PacketStatusInPing;
import com.loohp.limbo.Server.Packets.PacketStatusInRequest; import com.loohp.limbo.Server.Packets.PacketStatusInRequest;
@ -73,7 +80,8 @@ public class ClientConnection extends Thread {
private Player player; private Player player;
private long lastKeepAlivePayLoad; private long lastKeepAlivePayLoad;
private DataOutputStream output; protected DataOutputStream output;
protected DataInputStream input;
private InetAddress iNetAddress; private InetAddress iNetAddress;
@ -156,7 +164,7 @@ public class ClientConnection extends Thread {
state = ClientState.HANDSHAKE; state = ClientState.HANDSHAKE;
try { try {
client_socket.setKeepAlive(true); client_socket.setKeepAlive(true);
DataInputStream input = new DataInputStream(client_socket.getInputStream()); input = new DataInputStream(client_socket.getInputStream());
output = new DataOutputStream(client_socket.getOutputStream()); output = new DataOutputStream(client_socket.getOutputStream());
DataTypeIO.readVarInt(input); DataTypeIO.readVarInt(input);
@ -236,6 +244,8 @@ public class ClientConnection extends Thread {
Limbo.getInstance().addPlayer(player); Limbo.getInstance().addPlayer(player);
break; break;
} else {
input.skipBytes(size - DataTypeIO.getVarIntLength(packetId));
} }
} }
break; break;
@ -299,13 +309,15 @@ public class ClientConnection extends Thread {
String str = client_socket.getInetAddress().getHostName() + ":" + client_socket.getPort() + "|" + player.getName(); String str = client_socket.getInetAddress().getHostName() + ":" + client_socket.getPort() + "|" + player.getName();
Limbo.getInstance().getConsole().sendMessage("[/" + str + "] <-> Player had connected to the Limbo server!"); Limbo.getInstance().getConsole().sendMessage("[/" + str + "] <-> Player had connected to the Limbo server!");
PacketPlayOutDeclareCommands declare = DeclareCommands.getDeclareCommandPacket();
sendPacket(declare);
while (client_socket.isConnected()) { while (client_socket.isConnected()) {
try { try {
int size = DataTypeIO.readVarInt(input); int size = DataTypeIO.readVarInt(input);
int packetId = DataTypeIO.readVarInt(input); int packetId = DataTypeIO.readVarInt(input);
Class<? extends Packet> packetType = Packet.getPlayIn().get(packetId); Class<? extends Packet> packetType = Packet.getPlayIn().get(packetId);
//System.out.println(packetId); //System.out.println(packetType);
if (packetType == null) { if (packetType == null) {
input.skipBytes(size - DataTypeIO.getVarIntLength(packetId)); input.skipBytes(size - DataTypeIO.getVarIntLength(packetId));
} else if (packetType.equals(PacketPlayInPositionAndLook.class)) { } else if (packetType.equals(PacketPlayInPositionAndLook.class)) {
@ -332,6 +344,30 @@ public class ClientConnection extends Thread {
Limbo.getInstance().getConsole().sendMessage("Incorrect Payload recieved in KeepAlive packet for player " + player.getName()); Limbo.getInstance().getConsole().sendMessage("Incorrect Payload recieved in KeepAlive packet for player " + player.getName());
break; break;
} }
} else if (packetType.equals(PacketPlayInTabComplete.class)) {
PacketPlayInTabComplete request = new PacketPlayInTabComplete(input);
String[] command = CustomStringUtils.splitStringToArgs(request.getText());
System.out.println(request.getText());
List<TabCompleteMatches> matches = new ArrayList<TabCompleteMatches>();
TabCompleteMatches spawn = new TabCompleteMatches("spawn", new TextComponent(ChatColor.GOLD + "Teleports you back to the Limbo spawn!"));
switch (command.length) {
case 0:
matches.add(spawn);
break;
case 1:
if ("spawn".startsWith(command[0])) {
matches.add(spawn);
}
break;
}
int start = CustomStringUtils.getIndexOfArg(request.getText(), command.length - 1);
int length = command[command.length - 1].length();
PacketPlayOutTabComplete response = new PacketPlayOutTabComplete(request.getId(), start, length, matches.toArray(new TabCompleteMatches[matches.size()]));
sendPacket(response);
} else if (packetType.equals(PacketPlayInChat.class)) { } else if (packetType.equals(PacketPlayInChat.class)) {
PacketPlayInChat chat = new PacketPlayInChat(input); PacketPlayInChat chat = new PacketPlayInChat(input);
if (chat.getMessage().startsWith("/")) { if (chat.getMessage().startsWith("/")) {
@ -349,6 +385,8 @@ public class ClientConnection extends Thread {
each.sendMessage(message); each.sendMessage(message);
} }
} }
} else {
input.skipBytes(size - DataTypeIO.getVarIntLength(packetId));
} }
} catch (Exception e) { } catch (Exception e) {

View File

@ -1,6 +1,5 @@
package com.loohp.limbo.Server; package com.loohp.limbo.Server;
import java.io.DataOutputStream;
import java.io.IOException; import java.io.IOException;
import java.util.Random; import java.util.Random;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
@ -12,9 +11,10 @@ import com.loohp.limbo.Utils.DataTypeIO;
public class KeepAliveSender extends Thread { public class KeepAliveSender extends Thread {
private Random random = new Random(); private Random random;
public KeepAliveSender() { public KeepAliveSender() {
random = new Random();
start(); start();
} }
@ -25,11 +25,10 @@ public class KeepAliveSender extends Thread {
for (ClientConnection client : Limbo.getInstance().getServerConnection().getClients()) { for (ClientConnection client : Limbo.getInstance().getServerConnection().getClients()) {
if (client.getClientState().equals(ClientState.PLAY)) { if (client.getClientState().equals(ClientState.PLAY)) {
try { try {
DataOutputStream output = new DataOutputStream(client.getSocket().getOutputStream());
PacketPlayOutKeepAlive packet = new PacketPlayOutKeepAlive(random.nextLong()); PacketPlayOutKeepAlive packet = new PacketPlayOutKeepAlive(random.nextLong());
byte[] packetByte = packet.serializePacket(); byte[] packetByte = packet.serializePacket();
DataTypeIO.writeVarInt(output, packetByte.length); DataTypeIO.writeVarInt(client.output, packetByte.length);
output.write(packetByte); client.output.write(packetByte);
client.setLastKeepAlivePayLoad(packet.getPayload()); client.setLastKeepAlivePayLoad(packet.getPayload());
} catch (IOException ignore) {} } catch (IOException ignore) {}
} }

View File

@ -0,0 +1,30 @@
package com.loohp.limbo.Server.Packets;
import java.io.DataInputStream;
import java.io.IOException;
import com.loohp.limbo.Utils.DataTypeIO;
public class PacketPlayInTabComplete extends PacketIn {
private int id;
private String text;
public PacketPlayInTabComplete(int id, String text) {
this.id = id;
this.text = text;
}
public PacketPlayInTabComplete(DataInputStream in) throws IOException {
this(DataTypeIO.readVarInt(in), DataTypeIO.readString(in));
}
public int getId() {
return id;
}
public String getText() {
return text;
}
}

View File

@ -0,0 +1,30 @@
package com.loohp.limbo.Server.Packets;
import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.io.IOException;
public class PacketPlayOutDeclareCommands extends PacketOut {
private byte[] data;
public PacketPlayOutDeclareCommands(byte[] data) {
this.data = data;
}
public byte[] getData() {
return data;
}
@Override
public byte[] serializePacket() throws IOException {
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
DataOutputStream output = new DataOutputStream(buffer);
output.writeByte(Packet.getPlayOut().get(getClass()));
output.write(data);
return buffer.toByteArray();
}
}

View File

@ -0,0 +1,87 @@
package com.loohp.limbo.Server.Packets;
import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.Optional;
import com.loohp.limbo.Utils.DataTypeIO;
import net.md_5.bungee.api.chat.BaseComponent;
import net.md_5.bungee.chat.ComponentSerializer;
public class PacketPlayOutTabComplete extends PacketOut {
private int id;
private int start;
private int length;
private TabCompleteMatches[] matches;
public PacketPlayOutTabComplete(int id, int start, int length, TabCompleteMatches... matches) {
this.id = id;
this.start = start;
this.length = length;
}
public int getId() {
return id;
}
public int getStart() {
return start;
}
public int getLength() {
return length;
}
public TabCompleteMatches[] getMatches() {
return matches;
}
@Override
public byte[] serializePacket() throws IOException {
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
DataOutputStream output = new DataOutputStream(buffer);
output.writeByte(Packet.getPlayOut().get(getClass()));
DataTypeIO.writeVarInt(output, id);
DataTypeIO.writeVarInt(output, start);
DataTypeIO.writeVarInt(output, length);
DataTypeIO.writeVarInt(output, matches.length);
for (TabCompleteMatches match : matches) {
DataTypeIO.writeString(output, match.getMatch(), StandardCharsets.UTF_8);
if (match.getTooltip().isPresent()) {
output.writeBoolean(true);
DataTypeIO.writeString(output, ComponentSerializer.toString(match.getTooltip().get()), StandardCharsets.UTF_8);
} else {
output.writeBoolean(false);
}
}
return buffer.toByteArray();
}
public static class TabCompleteMatches {
private String match;
private Optional<BaseComponent[]> tooltip;
public TabCompleteMatches(String match, BaseComponent... tooltip) {
this.match = match;
this.tooltip = tooltip.length > 0 ? Optional.of(tooltip) : Optional.empty();
}
public String getMatch() {
return match;
}
public Optional<BaseComponent[]> getTooltip() {
return tooltip;
}
}
}

View File

@ -27,7 +27,7 @@ public class ServerConnection extends Thread {
public void run() { public void run() {
try { try {
serverSocket = new ServerSocket(port, 50, InetAddress.getByName(ip)); serverSocket = new ServerSocket(port, 50, InetAddress.getByName(ip));
System.out.println("Server listening on [" + serverSocket.getInetAddress().getHostName() + ":" + serverSocket.getLocalPort() + "]"); System.out.println("Limbo server listening on /" + serverSocket.getInetAddress().getHostName() + ":" + serverSocket.getLocalPort());
while (true) { while (true) {
Socket connection = serverSocket.accept(); Socket connection = serverSocket.accept();
//String str = connection.getInetAddress().getHostName() + ":" + connection.getPort(); //String str = connection.getInetAddress().getHostName() + ":" + connection.getPort();

View File

@ -37,4 +37,31 @@ public class CustomStringUtils {
return tokens.toArray(new String[tokens.size()]); return tokens.toArray(new String[tokens.size()]);
} }
public static int getIndexOfArg(String str, int ordinal) {
StringBuilder sb = new StringBuilder();
boolean insideQuote = false;
int pos = 0;
int found = 0;
for (char c : str.toCharArray()) {
if (c == '"') {
insideQuote = !insideQuote;
} else if (c == ' ' && !insideQuote) {
if (sb.length() > 0) {
found++;
}
sb.delete(0, sb.length());
} else {
sb.append(c);
}
if (found == ordinal) {
return pos;
}
pos++;
}
return -1;
}
} }

View File

@ -0,0 +1,36 @@
package com.loohp.limbo.Utils;
import java.io.IOException;
import java.net.DatagramSocket;
import java.net.ServerSocket;
public class NetworkUtils {
public static boolean available(int port) {
ServerSocket ss = null;
DatagramSocket ds = null;
try {
ss = new ServerSocket(port);
ss.setReuseAddress(true);
ds = new DatagramSocket(port);
ds.setReuseAddress(true);
return true;
} catch (IOException e) {
e.printStackTrace();
} finally {
if (ds != null) {
ds.close();
}
if (ss != null) {
try {
ss.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return false;
}
}

View File

@ -17,7 +17,8 @@
"0x13": "PacketPlayInPositionAndLook", "0x13": "PacketPlayInPositionAndLook",
"0x12": "PacketPlayInPosition", "0x12": "PacketPlayInPosition",
"0x14": "PacketPlayInRotation", "0x14": "PacketPlayInRotation",
"0x0B": "PacketPlayInPluginMessaging" "0x0B": "PacketPlayInPluginMessaging",
"0x06": "PacketPlayInTabComplete"
}, },
"PlayOut": { "PlayOut": {
"PacketPlayOutLogin": "0x25", "PacketPlayOutLogin": "0x25",
@ -31,7 +32,9 @@
"PacketPlayOutUpdateViewPosition": "0x40", "PacketPlayOutUpdateViewPosition": "0x40",
"PacketPlayOutShowPlayerSkins": "0x44", "PacketPlayOutShowPlayerSkins": "0x44",
"PacketPlayOutDisconnect": "0x1A", "PacketPlayOutDisconnect": "0x1A",
"PacketPlayOutPluginMessaging": "0x17" "PacketPlayOutPluginMessaging": "0x17",
"PacketPlayOutTabComplete": "0x10",
"PacketPlayOutDeclareCommands": "0x11"
}, },
"StatusIn": { "StatusIn": {
"0x01": "PacketStatusInPing", "0x01": "PacketStatusInPing",