Skip to content

Commit

Permalink
Started chat protocol implementation.
Browse files Browse the repository at this point in the history
  • Loading branch information
Sam Jakob Harker committed Jan 14, 2018
1 parent 1bb0617 commit cc49954
Show file tree
Hide file tree
Showing 8 changed files with 154 additions and 6 deletions.
12 changes: 11 additions & 1 deletion src/main/java/com/cloutteam/jarcraftinator/JARCraftinator.java
Expand Up @@ -27,6 +27,7 @@ public class JARCraftinator {
private ConfigManager configManager;
private Logger logger;
private String version;
private ConnectionHandler connectionHandler;
private TeleportManager teleportManager;
private PlayerManager playerManager;
private Timer timer;
Expand Down Expand Up @@ -76,7 +77,8 @@ private JARCraftinator() {
}

logger.log("Starting server...");
new ConnectionHandler(configManager.getPort()).start();
connectionHandler = new ConnectionHandler(configManager.getPort());
connectionHandler.start();

logger.log("Starting scheduler...");
timer = new Timer();
Expand Down Expand Up @@ -127,6 +129,10 @@ public static void main(String[] args) {
new JARCraftinator();
}

public static boolean isRunning(){
return instance.running;
}

public static ConfigManager getConfig() {
return instance.configManager;
}
Expand All @@ -151,4 +157,8 @@ public static Timer getTimer(){
return instance.timer;
}

public static ConnectionHandler getConnectionHandler(){
return instance.connectionHandler;
}

}
Expand Up @@ -2,7 +2,9 @@

import com.cloutteam.jarcraftinator.JARCraftinator;
import com.cloutteam.jarcraftinator.api.chat.ChatColor;
import com.cloutteam.jarcraftinator.api.json.JSONObject;
import com.cloutteam.jarcraftinator.exceptions.IOWriteException;
import com.cloutteam.jarcraftinator.handler.ConnectionHandler;
import com.cloutteam.jarcraftinator.logging.LogLevel;
import com.cloutteam.jarcraftinator.protocol.ConnectionState;
import com.cloutteam.jarcraftinator.protocol.MinecraftVersion;
Expand Down Expand Up @@ -161,6 +163,37 @@ public void run() {
ex.getMessage() + ")", LogLevel.DEBUG);
}
break;
case 0x02:
try {
PacketPlayInChat chatPacket = new PacketPlayInChat();
chatPacket.onReceive(packetLength, in);

if(!chatPacket.isValid()){
//TODO: Kick
JARCraftinator.getLogger().log(player.getName() + " sent a message of length greater than 256 characters. This is not normally possible.", LogLevel.WARNING);
socket.close();
}

if(chatPacket.getMessage().startsWith("/")){
return;
}

String message = getPlayer().getName() + " > " + chatPacket.getMessage();

JSONObject chatComponent = new JSONObject();
chatComponent.add("text", message);
System.out.println(chatComponent.toString());
PacketPlayOutChat chatOut = new PacketPlayOutChat(chatComponent.toString());

for(PlayerConnection connection :
JARCraftinator.getConnectionHandler().getAllPlayerConnections()){
chatOut.send(connection.getOut());
}
}catch(IOException ex){
JARCraftinator.getLogger().log("Error whilst receiving message (" +
ex.getMessage() + ")", LogLevel.DEBUG);
}
break;
case 0x04:
try {
PacketPlayInClientSettings clientSettings = new PacketPlayInClientSettings();
Expand All @@ -183,6 +216,10 @@ public void run() {
ex.getMessage() + ")", LogLevel.DEBUG);
}
break;
case 0x0B:
PacketPlayInKeepAlive packetPlayInKeepAlive = new PacketPlayInKeepAlive();
packetPlayInKeepAlive.onReceive(packetLength, in);
break;
case 0x0E:
try {
PacketPlayInPlayerPositionAndLook packetPlayInPlayerPositionAndLook = new PacketPlayInPlayerPositionAndLook();
Expand Down
Expand Up @@ -7,26 +7,36 @@
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;

public class ConnectionHandler extends Thread {

private final int port;
private List<PlayerConnection> connectionList;

public ConnectionHandler(int port){
this.port = port;
connectionList = new ArrayList<>();
}

@Override
public void run() {
try {
ServerSocket serverSocket = new ServerSocket(port);
while (true) {
while (JARCraftinator.isRunning()) {
Socket socket = serverSocket.accept();
new PlayerConnection(socket).start();
PlayerConnection connection = new PlayerConnection(socket);
connection.start();
connectionList.add(connection);
}
} catch (IOException ex) {
JARCraftinator.getLogger().log("An internal server error occurred.", LogLevel.CRITICAL);
System.exit(1);
}
}

public List<PlayerConnection> getAllPlayerConnections() {
return connectionList;
}
}
@@ -1,9 +1,10 @@
package com.cloutteam.jarcraftinator.protocol.packet;

import java.io.DataInputStream;
import java.io.IOException;

public abstract class PacketIn extends Packet {

public abstract void onReceive(int length, DataInputStream in) throws Exception;
public abstract void onReceive(int length, DataInputStream in) throws IOException;

}
@@ -0,0 +1,33 @@
package com.cloutteam.jarcraftinator.protocol.packet;

import com.cloutteam.jarcraftinator.utils.VarData;

import java.io.DataInputStream;
import java.io.IOException;

public class PacketPlayInChat extends PacketIn {

private boolean isValid;
private String message;

@Override
public void onReceive(int length, DataInputStream in) throws IOException {
int stringSize = VarData.readVarInt(in);

if(stringSize > 256){
isValid = false;
message = null;
}else {
isValid = true;
message = VarData.readVarString(in, stringSize);
}
}

public boolean isValid() {
return isValid;
}

public String getMessage() {
return message;
}
}
@@ -0,0 +1,15 @@
package com.cloutteam.jarcraftinator.protocol.packet;

import java.io.DataInputStream;
import java.io.IOException;

public class PacketPlayInKeepAlive extends PacketIn {

private long keepAliveId;

@Override
public void onReceive(int length, DataInputStream in) throws IOException {
keepAliveId = in.readLong();
}

}
@@ -0,0 +1,44 @@
package com.cloutteam.jarcraftinator.protocol.packet;

import com.cloutteam.jarcraftinator.utils.VarData;

import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.io.IOException;

public class PacketPlayOutChat extends PacketOut {

private String chatComponent;

public PacketPlayOutChat(String chatComponent){
this.chatComponent = chatComponent;
}

@Override
public void send(DataOutputStream out) throws IOException {
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
DataOutputStream dataOutputStream = new DataOutputStream(byteArrayOutputStream);

byte[] packetId = VarData.getVarInt(0x0F);

// Begin packet data
VarData.writeVarString(dataOutputStream, chatComponent);
dataOutputStream.writeByte(0x00); // 0 = chat box
// End packet data

// Flush packet data
dataOutputStream.flush();
dataOutputStream.close();
byteArrayOutputStream.flush();

// Send the entire packet to the client
VarData.writeVarInt(out, packetId.length + dataOutputStream.size());
out.write(packetId);
out.write(byteArrayOutputStream.toByteArray());
out.flush();

// Close our temporary streams
byteArrayOutputStream.close();
}

}
2 changes: 0 additions & 2 deletions src/main/java/com/cloutteam/jarcraftinator/utils/VarData.java
Expand Up @@ -52,8 +52,6 @@ public static String readVarString(DataInputStream in, int size) throws IOExcept
return result;
}

// Chunk data

public static void writeVarString(DataOutputStream out, String string) throws IOException {
writeVarInt(out, string.length());
out.writeUTF(string);
Expand Down

0 comments on commit cc49954

Please sign in to comment.