SubServers-2/SubServers.Bungee/src/net/ME1312/SubServers/Bungee/Network/Client.java
ME1312 75b9b688cc Rewrite SubData API for JSON dependancy changes
This commit removes the org.JSON library where alternatives are already provided (Bungee & Bukkit provide Gson). This change was made to improve compatability with BungeeCord plugins and reduce file sizes.

This means big changes to the SubData API, which heavily relied on org.JSON. Now we submit our data through YAMLSection to be converted and sent over the network.
2018-04-14 21:53:51 -04:00

217 lines
7.7 KiB
Java

package net.ME1312.SubServers.Bungee.Network;
import com.google.gson.JsonParseException;
import net.ME1312.SubServers.Bungee.Library.Config.YAMLSection;
import net.ME1312.SubServers.Bungee.Library.Exception.IllegalPacketException;
import net.ME1312.SubServers.Bungee.Library.Util;
import net.ME1312.SubServers.Bungee.Network.Packet.PacketAuthorization;
import org.yaml.snakeyaml.error.YAMLException;
import java.io.*;
import java.lang.reflect.InvocationTargetException;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.SocketException;
import java.util.*;
/**
* Network Client Class
*/
public class Client {
private Socket socket;
private InetSocketAddress address;
private ClientHandler handler;
private PrintWriter writer;
private Timer authorized;
private SubDataServer subdata;
boolean closed;
/**
* Network Client
*
* @param subdata SubData Direct Server
* @param client Socket to Bind
*/
public Client(SubDataServer subdata, Socket client) throws IOException {
if (Util.isNull(subdata, client)) throw new NullPointerException();
this.subdata = subdata;
closed = false;
socket = client;
writer = new PrintWriter(client.getOutputStream(), true);
address = new InetSocketAddress(client.getInetAddress(), client.getPort());
authorized = new Timer();
authorized.schedule(new TimerTask() {
@Override
public void run() {
if (!socket.isClosed()) try {
subdata.removeClient(Client.this);
} catch (IOException e) {
e.printStackTrace();
}
}
}, 15000);
loop();
}
/**
* Network Loop
*/
private void loop() {
new Thread(() -> {
try {
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
String input;
while ((input = in.readLine()) != null) {
try {
YAMLSection data = subdata.getCipher().decrypt(subdata.plugin.config.get().getSection("Settings").getSection("SubData").getRawString("Password"), Base64.getDecoder().decode(input));
for (PacketIn packet : SubDataServer.decodePacket(this, data)) {
boolean auth = authorized == null;
if (auth || packet instanceof PacketAuthorization) {
try {
if (data.contains("f")) {
if (data.getString("f").length() <= 0) {
List<Client> clients = new ArrayList<Client>();
clients.addAll(subdata.getClients());
for (Client client : clients) {
client.writer.println(input);
}
} else {
Client client = subdata.getClient(data.getString("f"));
if (client != null) {
client.writer.println(input);
} else {
throw new IllegalPacketException(getAddress().toString() + ": Unknown Forward Address: " + data.getString("f"));
}
}
} else {
packet.execute(Client.this, (data.contains("c"))?data.getSection("c"):null);
}
} catch (Throwable e) {
new InvocationTargetException(e, getAddress().toString() + ": Exception while executing PacketIn").printStackTrace();
}
} else {
sendPacket(new PacketAuthorization(-1, "Unauthorized"));
throw new IllegalPacketException(getAddress().toString() + ": Unauthorized call to packet type: " + data.getSection("h"));
}
}
} catch (JsonParseException | YAMLException e) {
new IllegalPacketException(getAddress().toString() + ": Unknown Packet Format: " + input).printStackTrace();
} catch (IllegalPacketException e) {
e.printStackTrace();
} catch (Exception e) {
new InvocationTargetException(e, getAddress().toString() + ": Exception while decoding packet").printStackTrace();
}
}
try {
subdata.removeClient(Client.this);
} catch (IOException e1) {
e1.printStackTrace();
}
} catch (Exception e) {
if (!(e instanceof SocketException)) e.printStackTrace();
try {
subdata.removeClient(Client.this);
} catch (IOException e1) {
e1.printStackTrace();
}
}
}).start();
}
/**
* Authorize Connection
*/
public void authorize() {
if (authorized != null) {
authorized.cancel();
System.out.println("SubData > " + socket.getRemoteSocketAddress().toString() + " logged in");
}
authorized = null;
}
/**
* Send Packet to Client
*
* @param packet Packet to send
*/
public void sendPacket(PacketOut packet) {
if (Util.isNull(packet)) throw new NullPointerException();
try {
writer.println(Base64.getEncoder().encodeToString(subdata.getCipher().encrypt(subdata.plugin.config.get().getSection("Settings").getSection("SubData").getRawString("Password"), SubDataServer.encodePacket(this, packet))));
} catch (Throwable e) {
e.printStackTrace();
}
}
/**
* Get Raw Connection
*
* @return Socket
*/
public Socket getConnection() {
return socket;
}
/**
* Get if the connection has been closed
*
* @return Closed Stauts
*/
public boolean isClosed() {
return closed && socket.isClosed();
}
/**
* Get Remote Address
*
* @return Address
*/
public InetSocketAddress getAddress() {
return address;
}
/**
* If the connection is authorized
*
* @return Authorization Status
*/
public boolean isAuthorized() {
return authorized == null;
}
/**
* Gets the Linked Handler
*
* @return Handler
*/
public ClientHandler getHandler() {
return handler;
}
/**
* Sets the Handler
*
* @param obj Handler
*/
public void setHandler(ClientHandler obj) {
if (handler != null && handler.getSubData() != null && equals(handler.getSubData())) handler.setSubData(null);
handler = obj;
if (handler != null && (handler.getSubData() == null || !equals(handler.getSubData()))) handler.setSubData(this);
}
/**
* Disconnects the Client
*
* @throws IOException
*/
public void disconnect() throws IOException {
if (!socket.isClosed()) getConnection().close();
if (handler != null) {
setHandler(null);
handler = null;
}
closed = true;
if (subdata.getClients().contains(this)) subdata.removeClient(this);
}
}