Initial Commit
This commit is contained in:
commit
7aa4e0dd00
4
.gitignore
vendored
Normal file
4
.gitignore
vendored
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
.settings/
|
||||||
|
/bin
|
||||||
|
.classpath
|
||||||
|
.project
|
185
src/be/jeffcheasey88/Client.java
Normal file
185
src/be/jeffcheasey88/Client.java
Normal file
@ -0,0 +1,185 @@
|
|||||||
|
package be.jeffcheasey88;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
import java.io.UnsupportedEncodingException;
|
||||||
|
import java.net.Socket;
|
||||||
|
import java.security.MessageDigest;
|
||||||
|
import java.security.NoSuchAlgorithmException;
|
||||||
|
import java.util.LinkedList;
|
||||||
|
import java.util.Queue;
|
||||||
|
import java.util.Scanner;
|
||||||
|
import java.util.concurrent.LinkedBlockingQueue;
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
import javax.xml.bind.DatatypeConverter;
|
||||||
|
|
||||||
|
public class Client extends Thread{
|
||||||
|
|
||||||
|
private Socket clientSocket;
|
||||||
|
private InputStream inputStream;
|
||||||
|
private OutputStream outputStream;
|
||||||
|
private Queue<String> messages;
|
||||||
|
|
||||||
|
public Client(Socket socket) throws Exception {
|
||||||
|
this.clientSocket = socket;
|
||||||
|
this.inputStream = clientSocket.getInputStream();
|
||||||
|
this.outputStream = clientSocket.getOutputStream();
|
||||||
|
this.messages = new LinkedList<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run(){
|
||||||
|
try {
|
||||||
|
doHandShakeToInitializeWebSocketConnection();
|
||||||
|
|
||||||
|
int buffLenth = 1024;
|
||||||
|
int len = 0;
|
||||||
|
byte[] b = new byte[buffLenth];
|
||||||
|
//rawIn is a Socket.getInputStream();
|
||||||
|
while(true){
|
||||||
|
len = inputStream.read(b);
|
||||||
|
if(len!=-1){
|
||||||
|
|
||||||
|
byte rLength = 0;
|
||||||
|
int rMaskIndex = 2;
|
||||||
|
int rDataStart = 0;
|
||||||
|
//b[0] is always text in my case so no need to check;
|
||||||
|
byte data = b[1];
|
||||||
|
byte op = (byte) 127;
|
||||||
|
rLength = (byte) (data & op);
|
||||||
|
|
||||||
|
if(rLength==(byte)126) rMaskIndex=4;
|
||||||
|
if(rLength==(byte)127) rMaskIndex=10;
|
||||||
|
|
||||||
|
byte[] masks = new byte[4];
|
||||||
|
|
||||||
|
int j=0;
|
||||||
|
int i=0;
|
||||||
|
for(i=rMaskIndex;i<(rMaskIndex+4);i++){
|
||||||
|
masks[j] = b[i];
|
||||||
|
j++;
|
||||||
|
}
|
||||||
|
|
||||||
|
rDataStart = rMaskIndex + 4;
|
||||||
|
|
||||||
|
int messLen = len - rDataStart;
|
||||||
|
|
||||||
|
byte[] message = new byte[messLen];
|
||||||
|
|
||||||
|
for(i=rDataStart, j=0; i<len; i++, j++){
|
||||||
|
message[j] = (byte) (b[i] ^ masks[j % 4]);
|
||||||
|
}
|
||||||
|
this.messages.add(new String(message));
|
||||||
|
synchronized(this.messages) {
|
||||||
|
this.messages.notify();
|
||||||
|
}
|
||||||
|
|
||||||
|
b = new byte[buffLenth];
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}catch(Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void sendMessage(String message) throws Exception {
|
||||||
|
outputStream.write(encode(message));
|
||||||
|
outputStream.flush();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void doHandShakeToInitializeWebSocketConnection() throws UnsupportedEncodingException {
|
||||||
|
String data = new Scanner(inputStream,"UTF-8").useDelimiter("\\r\\n\\r\\n").next();
|
||||||
|
|
||||||
|
Matcher get = Pattern.compile("^GET").matcher(data);
|
||||||
|
|
||||||
|
if (get.find()) {
|
||||||
|
Matcher match = Pattern.compile("Sec-WebSocket-Key: (.*)").matcher(data);
|
||||||
|
match.find();
|
||||||
|
|
||||||
|
byte[] response = null;
|
||||||
|
try {
|
||||||
|
response = ("HTTP/1.1 101 Switching Protocols\r\n"
|
||||||
|
+ "Connection: Upgrade\r\n"
|
||||||
|
+ "Upgrade: websocket\r\n"
|
||||||
|
+ "Sec-WebSocket-Accept: "
|
||||||
|
+ DatatypeConverter.printBase64Binary(
|
||||||
|
MessageDigest
|
||||||
|
.getInstance("SHA-1")
|
||||||
|
.digest((match.group(1) + "258EAFA5-E914-47DA-95CA-C5AB0DC85B11")
|
||||||
|
.getBytes("UTF-8")))
|
||||||
|
+ "\r\n\r\n")
|
||||||
|
.getBytes("UTF-8");
|
||||||
|
} catch (NoSuchAlgorithmException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
outputStream.write(response, 0, response.length);
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public String read() throws Exception{
|
||||||
|
synchronized(this.messages){
|
||||||
|
this.messages.wait();
|
||||||
|
}
|
||||||
|
return this.messages.poll();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private byte[] encode(String mess) throws IOException{
|
||||||
|
byte[] rawData = mess.getBytes();
|
||||||
|
|
||||||
|
int frameCount = 0;
|
||||||
|
byte[] frame = new byte[10];
|
||||||
|
|
||||||
|
frame[0] = (byte) 129;
|
||||||
|
|
||||||
|
if(rawData.length <= 125){
|
||||||
|
frame[1] = (byte) rawData.length;
|
||||||
|
frameCount = 2;
|
||||||
|
}else if(rawData.length >= 126 && rawData.length <= 65535){
|
||||||
|
frame[1] = (byte) 126;
|
||||||
|
int len = rawData.length;
|
||||||
|
frame[2] = (byte)((len >> 8 ) & (byte)255);
|
||||||
|
frame[3] = (byte)(len & (byte)255);
|
||||||
|
frameCount = 4;
|
||||||
|
}else{
|
||||||
|
frame[1] = (byte) 127;
|
||||||
|
int len = rawData.length;
|
||||||
|
frame[2] = (byte)((len >> 56 ) & (byte)255);
|
||||||
|
frame[3] = (byte)((len >> 48 ) & (byte)255);
|
||||||
|
frame[4] = (byte)((len >> 40 ) & (byte)255);
|
||||||
|
frame[5] = (byte)((len >> 32 ) & (byte)255);
|
||||||
|
frame[6] = (byte)((len >> 24 ) & (byte)255);
|
||||||
|
frame[7] = (byte)((len >> 16 ) & (byte)255);
|
||||||
|
frame[8] = (byte)((len >> 8 ) & (byte)255);
|
||||||
|
frame[9] = (byte)(len & (byte)255);
|
||||||
|
frameCount = 10;
|
||||||
|
}
|
||||||
|
|
||||||
|
int bLength = frameCount + rawData.length;
|
||||||
|
|
||||||
|
byte[] reply = new byte[bLength];
|
||||||
|
|
||||||
|
int bLim = 0;
|
||||||
|
for(int i=0; i<frameCount;i++){
|
||||||
|
reply[bLim] = frame[i];
|
||||||
|
bLim++;
|
||||||
|
}
|
||||||
|
for(int i=0; i<rawData.length;i++){
|
||||||
|
reply[bLim] = rawData[i];
|
||||||
|
bLim++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return reply;
|
||||||
|
}
|
||||||
|
}
|
59
src/be/jeffcheasey88/Main.java
Normal file
59
src/be/jeffcheasey88/Main.java
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
package be.jeffcheasey88;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
import java.io.UnsupportedEncodingException;
|
||||||
|
import java.net.ServerSocket;
|
||||||
|
import java.net.Socket;
|
||||||
|
import java.security.MessageDigest;
|
||||||
|
import java.security.NoSuchAlgorithmException;
|
||||||
|
import java.util.Scanner;
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
import javax.xml.bind.DatatypeConverter;
|
||||||
|
|
||||||
|
import be.jeffcheasey88.commands.CommandManager;
|
||||||
|
import be.jeffcheasey88.commands.NameCommand;
|
||||||
|
|
||||||
|
public class Main {
|
||||||
|
|
||||||
|
public static void main(String[] args){
|
||||||
|
|
||||||
|
System.out.println("Start");
|
||||||
|
|
||||||
|
int portNumber = 233;
|
||||||
|
|
||||||
|
ServerSocket server;
|
||||||
|
try {
|
||||||
|
server = new ServerSocket(portNumber);
|
||||||
|
} catch (IOException exception) {
|
||||||
|
throw new IllegalStateException("Could not create web server", exception);
|
||||||
|
}
|
||||||
|
|
||||||
|
CommandManager manager = new CommandManager(new PlayerRepository());
|
||||||
|
manager.register(new NameCommand());
|
||||||
|
|
||||||
|
while(true){
|
||||||
|
try {
|
||||||
|
Player player = new Player(server.accept()); //waits until a client connects
|
||||||
|
System.out.println("co");
|
||||||
|
player.start();
|
||||||
|
System.out.println("Go");
|
||||||
|
Pipeline pipe = new Pipeline(player);
|
||||||
|
manager.readPipeline(player, pipe);
|
||||||
|
} catch (Exception waitException) {
|
||||||
|
throw new IllegalStateException("Could not wait for client connection", waitException);
|
||||||
|
}
|
||||||
|
|
||||||
|
System.out.println("Connected");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//Source for encoding and decoding:
|
||||||
|
//https://stackoverflow.com/questions/8125507/how-can-i-send-and-receive-websocket-messages-on-the-server-side
|
||||||
|
|
||||||
|
}
|
16
src/be/jeffcheasey88/Pipeline.java
Normal file
16
src/be/jeffcheasey88/Pipeline.java
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
package be.jeffcheasey88;
|
||||||
|
|
||||||
|
public class Pipeline {
|
||||||
|
|
||||||
|
private Client client;
|
||||||
|
|
||||||
|
public Pipeline(Client client){
|
||||||
|
this.client = client;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String read() throws Exception{
|
||||||
|
return this.client.read();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
14
src/be/jeffcheasey88/Player.java
Normal file
14
src/be/jeffcheasey88/Player.java
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
package be.jeffcheasey88;
|
||||||
|
|
||||||
|
import java.net.Socket;
|
||||||
|
|
||||||
|
public class Player extends Client{
|
||||||
|
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
public Player(Socket socket) throws Exception {
|
||||||
|
super(socket);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
24
src/be/jeffcheasey88/PlayerRepository.java
Normal file
24
src/be/jeffcheasey88/PlayerRepository.java
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
package be.jeffcheasey88;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public class PlayerRepository {
|
||||||
|
|
||||||
|
private Map<String, Player> players;
|
||||||
|
|
||||||
|
public PlayerRepository(){
|
||||||
|
this.players = new HashMap<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void update(Player player, String lastname, String newName){
|
||||||
|
this.players.remove(lastname);
|
||||||
|
player.setName(newName);
|
||||||
|
this.players.put(newName, player);
|
||||||
|
System.out.println("Hello "+newName);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Player getPlayer(String name){
|
||||||
|
return this.players.get(name);
|
||||||
|
}
|
||||||
|
}
|
21
src/be/jeffcheasey88/commands/Command.java
Normal file
21
src/be/jeffcheasey88/commands/Command.java
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
package be.jeffcheasey88.commands;
|
||||||
|
|
||||||
|
import org.json.simple.JSONObject;
|
||||||
|
|
||||||
|
import be.jeffcheasey88.Player;
|
||||||
|
import be.jeffcheasey88.PlayerRepository;
|
||||||
|
|
||||||
|
public abstract class Command {
|
||||||
|
|
||||||
|
private String type;
|
||||||
|
|
||||||
|
public Command(String type){
|
||||||
|
this.type = type;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getType(){
|
||||||
|
return this.type;
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract void execute(PlayerRepository repo, Player player, JSONObject json);
|
||||||
|
}
|
41
src/be/jeffcheasey88/commands/CommandManager.java
Normal file
41
src/be/jeffcheasey88/commands/CommandManager.java
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
package be.jeffcheasey88.commands;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.json.simple.JSONObject;
|
||||||
|
import org.json.simple.parser.JSONParser;
|
||||||
|
|
||||||
|
import be.jeffcheasey88.Pipeline;
|
||||||
|
import be.jeffcheasey88.Player;
|
||||||
|
import be.jeffcheasey88.PlayerRepository;
|
||||||
|
|
||||||
|
public class CommandManager{
|
||||||
|
|
||||||
|
private Map<String, Command> commands;
|
||||||
|
private PlayerRepository repo;
|
||||||
|
|
||||||
|
public CommandManager(PlayerRepository repo){
|
||||||
|
this.commands = new HashMap<>();
|
||||||
|
this.repo = repo;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void register(Command command){
|
||||||
|
this.commands.put(command.getType(), command);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void readPipeline(Player player, Pipeline pipe){
|
||||||
|
try {
|
||||||
|
while(true){
|
||||||
|
String value = pipe.read();
|
||||||
|
System.out.println(value);
|
||||||
|
JSONObject json = (JSONObject) new JSONParser().parse(value);
|
||||||
|
String type = (String) json.get("type");
|
||||||
|
Command command = this.commands.get(type);
|
||||||
|
command.execute(repo,player, json);
|
||||||
|
}
|
||||||
|
}catch(Exception e){
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
18
src/be/jeffcheasey88/commands/NameCommand.java
Normal file
18
src/be/jeffcheasey88/commands/NameCommand.java
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
package be.jeffcheasey88.commands;
|
||||||
|
|
||||||
|
import org.json.simple.JSONObject;
|
||||||
|
|
||||||
|
import be.jeffcheasey88.Player;
|
||||||
|
import be.jeffcheasey88.PlayerRepository;
|
||||||
|
|
||||||
|
public class NameCommand extends Command{
|
||||||
|
|
||||||
|
public NameCommand(){
|
||||||
|
super("name");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void execute(PlayerRepository repo, Player player, JSONObject json){
|
||||||
|
repo.update(player, player.getName(), (String) json.get("value"));
|
||||||
|
}
|
||||||
|
}
|
26
src/be/jeffcheasey88/commands/OtherCommand.java
Normal file
26
src/be/jeffcheasey88/commands/OtherCommand.java
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
package be.jeffcheasey88.commands;
|
||||||
|
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
import org.json.simple.JSONObject;
|
||||||
|
|
||||||
|
import be.jeffcheasey88.Player;
|
||||||
|
import be.jeffcheasey88.PlayerRepository;
|
||||||
|
|
||||||
|
public class OtherCommand extends Command{
|
||||||
|
|
||||||
|
public static void main(String[] args){
|
||||||
|
String regex = "^\\d$";
|
||||||
|
System.out.println(Pattern.matches(regex,"2"));
|
||||||
|
System.out.println(Pattern.matches("2-210208-1-4", regex));
|
||||||
|
}
|
||||||
|
|
||||||
|
public OtherCommand(){
|
||||||
|
super("other");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void execute(PlayerRepository repo, Player player, JSONObject json){
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user