Leaderboard dynamic & Lock System & Refractor WebSocket + Headers
This commit is contained in:
parent
14e37b9e38
commit
9ba9ab12c7
14 changed files with 297 additions and 141 deletions
|
@ -5,6 +5,8 @@ import static be.jeffcheasey88.peeratcode.framework.RequestType.OPTIONS;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.net.ServerSocket;
|
import java.net.ServerSocket;
|
||||||
import java.net.Socket;
|
import java.net.Socket;
|
||||||
|
import java.util.Timer;
|
||||||
|
import java.util.TimerTask;
|
||||||
import java.util.regex.Matcher;
|
import java.util.regex.Matcher;
|
||||||
|
|
||||||
import javax.net.ssl.SSLServerSocket;
|
import javax.net.ssl.SSLServerSocket;
|
||||||
|
@ -18,10 +20,12 @@ import be.jeffcheasey88.peeratcode.framework.Response;
|
||||||
import be.jeffcheasey88.peeratcode.framework.Route;
|
import be.jeffcheasey88.peeratcode.framework.Route;
|
||||||
import be.jeffcheasey88.peeratcode.framework.Router;
|
import be.jeffcheasey88.peeratcode.framework.Router;
|
||||||
import be.jeffcheasey88.peeratcode.framework.User;
|
import be.jeffcheasey88.peeratcode.framework.User;
|
||||||
|
import be.jeffcheasey88.peeratcode.model.Completion;
|
||||||
import be.jeffcheasey88.peeratcode.repository.DatabaseRepository;
|
import be.jeffcheasey88.peeratcode.repository.DatabaseRepository;
|
||||||
import be.jeffcheasey88.peeratcode.routes.BadgeDetails;
|
import be.jeffcheasey88.peeratcode.routes.BadgeDetails;
|
||||||
import be.jeffcheasey88.peeratcode.routes.ChapterElement;
|
import be.jeffcheasey88.peeratcode.routes.ChapterElement;
|
||||||
import be.jeffcheasey88.peeratcode.routes.ChapterList;
|
import be.jeffcheasey88.peeratcode.routes.ChapterList;
|
||||||
|
import be.jeffcheasey88.peeratcode.routes.DynamicLeaderboard;
|
||||||
import be.jeffcheasey88.peeratcode.routes.Leaderboard;
|
import be.jeffcheasey88.peeratcode.routes.Leaderboard;
|
||||||
import be.jeffcheasey88.peeratcode.routes.Login;
|
import be.jeffcheasey88.peeratcode.routes.Login;
|
||||||
import be.jeffcheasey88.peeratcode.routes.PlayerDetails;
|
import be.jeffcheasey88.peeratcode.routes.PlayerDetails;
|
||||||
|
@ -29,7 +33,7 @@ import be.jeffcheasey88.peeratcode.routes.PuzzleElement;
|
||||||
import be.jeffcheasey88.peeratcode.routes.PuzzleResponse;
|
import be.jeffcheasey88.peeratcode.routes.PuzzleResponse;
|
||||||
import be.jeffcheasey88.peeratcode.routes.Register;
|
import be.jeffcheasey88.peeratcode.routes.Register;
|
||||||
import be.jeffcheasey88.peeratcode.routes.Result;
|
import be.jeffcheasey88.peeratcode.routes.Result;
|
||||||
import be.jeffcheasey88.peeratcode.routes.groups.CreateGroup;
|
import be.jeffcheasey88.peeratcode.routes.groups.GroupCreate;
|
||||||
import be.jeffcheasey88.peeratcode.routes.groups.GroupJoin;
|
import be.jeffcheasey88.peeratcode.routes.groups.GroupJoin;
|
||||||
import be.jeffcheasey88.peeratcode.routes.groups.GroupList;
|
import be.jeffcheasey88.peeratcode.routes.groups.GroupList;
|
||||||
import be.jeffcheasey88.peeratcode.routes.groups.GroupQuit;
|
import be.jeffcheasey88.peeratcode.routes.groups.GroupQuit;
|
||||||
|
@ -75,15 +79,19 @@ public class Main{
|
||||||
router.register(new Register(router.getDataBase(), router, config.getUsersFiles()));
|
router.register(new Register(router.getDataBase(), router, config.getUsersFiles()));
|
||||||
router.register(new Login(router.getDataBase(), router));
|
router.register(new Login(router.getDataBase(), router));
|
||||||
router.register(new Result(router.getDataBase()));
|
router.register(new Result(router.getDataBase()));
|
||||||
router.register(new PuzzleResponse(router.getDataBase(), config.getUsersFiles()));
|
|
||||||
router.register(new Leaderboard(router.getDataBase()));
|
router.register(new Leaderboard(router.getDataBase()));
|
||||||
router.register(new PlayerDetails(router.getDataBase()));
|
router.register(new PlayerDetails(router.getDataBase()));
|
||||||
router.register(new BadgeDetails(router.getDataBase()));
|
router.register(new BadgeDetails(router.getDataBase()));
|
||||||
|
|
||||||
router.register(new GroupList(router.getDataBase()));
|
router.register(new GroupList(router.getDataBase()));
|
||||||
router.register(new CreateGroup(router.getDataBase()));
|
router.register(new GroupCreate(router.getDataBase()));
|
||||||
router.register(new GroupJoin(router.getDataBase()));
|
router.register(new GroupJoin(router.getDataBase()));
|
||||||
router.register(new GroupQuit(router.getDataBase()));
|
router.register(new GroupQuit(router.getDataBase()));
|
||||||
|
|
||||||
|
DynamicLeaderboard dlb = new DynamicLeaderboard(router.getDataBase());
|
||||||
|
router.register(dlb);
|
||||||
|
|
||||||
|
router.register(new PuzzleResponse(router.getDataBase(), config.getUsersFiles(), dlb.getLocker()));
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void startWebServer(Configuration config, Router router) throws IOException {
|
private static void startWebServer(Configuration config, Router router) throws IOException {
|
||||||
|
|
|
@ -27,6 +27,7 @@ public class Client extends Thread{
|
||||||
try {
|
try {
|
||||||
String[] headers = reader.readLine().split("\\s");
|
String[] headers = reader.readLine().split("\\s");
|
||||||
System.out.println(Arrays.toString(headers));
|
System.out.println(Arrays.toString(headers));
|
||||||
|
reader.readHeaders();
|
||||||
|
|
||||||
router.exec(RequestType.valueOf(headers[0]), headers[1], isLogin(reader), reader, writer);
|
router.exec(RequestType.valueOf(headers[0]), headers[1], isLogin(reader), reader, writer);
|
||||||
writer.flush();
|
writer.flush();
|
||||||
|
@ -37,8 +38,9 @@ public class Client extends Thread{
|
||||||
}
|
}
|
||||||
|
|
||||||
private User isLogin(HttpReader reader) throws Exception{
|
private User isLogin(HttpReader reader) throws Exception{
|
||||||
String auth = HttpUtil.readAuthorization(reader);
|
String auth = reader.getHeader("Authorization");
|
||||||
if(auth == null) return null;
|
if(auth == null) return null;
|
||||||
|
auth = auth.substring(7);
|
||||||
try{
|
try{
|
||||||
JwtConsumer jwtConsumer = new JwtConsumerBuilder()
|
JwtConsumer jwtConsumer = new JwtConsumerBuilder()
|
||||||
.setRequireExpirationTime()
|
.setRequireExpirationTime()
|
||||||
|
|
|
@ -5,23 +5,51 @@ import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.InputStreamReader;
|
import java.io.InputStreamReader;
|
||||||
import java.net.Socket;
|
import java.net.Socket;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
public class HttpReader {
|
public class HttpReader {
|
||||||
|
|
||||||
|
private static Pattern HEADER_PATTERN = Pattern.compile("^([^:]*):\\s+(.*)$");
|
||||||
|
|
||||||
private Socket socket;
|
private Socket socket;
|
||||||
private InputStream in;
|
private InputStream in;
|
||||||
private BufferedReader reader;
|
private BufferedReader reader;
|
||||||
|
|
||||||
|
private Map<String, String> headers;
|
||||||
|
|
||||||
public HttpReader(Socket socket) throws Exception {
|
public HttpReader(Socket socket) throws Exception{
|
||||||
this.socket = socket;
|
this.socket = socket;
|
||||||
this.in = socket.getInputStream();
|
this.in = socket.getInputStream();
|
||||||
this.reader = new BufferedReader(new InputStreamReader(in));
|
this.reader = new BufferedReader(new InputStreamReader(in));
|
||||||
|
this.headers = new HashMap<>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public HttpReader(HttpReader origin) throws Exception{
|
||||||
|
this.socket = origin.socket;
|
||||||
|
this.in = origin.in;
|
||||||
|
this.reader = origin.reader;
|
||||||
|
}
|
||||||
|
|
||||||
public boolean isClosed() {
|
public boolean isClosed() {
|
||||||
return this.socket.isClosed();
|
return this.socket.isClosed();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void readHeaders() throws Exception{
|
||||||
|
String line;
|
||||||
|
while(((line = reader.readLine()) != null) && (line.length() > 0)){
|
||||||
|
Matcher matcher = HEADER_PATTERN.matcher(line);
|
||||||
|
matcher.matches();
|
||||||
|
this.headers.put(matcher.group(1), matcher.group(2));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getHeader(String key){
|
||||||
|
return this.headers.get(key);
|
||||||
|
}
|
||||||
|
|
||||||
public int read(byte[] buffer) throws IOException {
|
public int read(byte[] buffer) throws IOException {
|
||||||
return this.in.read(buffer);
|
return this.in.read(buffer);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
package be.jeffcheasey88.peeratcode.framework;
|
package be.jeffcheasey88.peeratcode.framework;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
import java.security.MessageDigest;
|
import java.security.MessageDigest;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
@ -45,7 +46,7 @@ public class HttpUtil{
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void switchToWebSocket(HttpReader reader, HttpWriter writer) throws Exception{
|
public static void switchToWebSocket(HttpReader reader, HttpWriter writer) throws Exception{
|
||||||
String key = readWebSocketKey(reader);
|
String key = reader.getHeader("Sec-WebSocket-Key");
|
||||||
if (key == null) throw new IllegalArgumentException();
|
if (key == null) throw new IllegalArgumentException();
|
||||||
|
|
||||||
writer.write("HTTP/1.1 101 Switching Protocols\n");
|
writer.write("HTTP/1.1 101 Switching Protocols\n");
|
||||||
|
@ -57,34 +58,6 @@ public class HttpUtil{
|
||||||
writer.flush();
|
writer.flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Pattern WEBSOCKET_KEY = Pattern.compile("Sec-WebSocket-Key: (.*)");
|
|
||||||
|
|
||||||
public static String readWebSocketKey(HttpReader reader) throws Exception{
|
|
||||||
String line;
|
|
||||||
String key = null;
|
|
||||||
while(((line = reader.readLine()) != null) && (line.length() > 0)){
|
|
||||||
if(key != null) continue;
|
|
||||||
Matcher matcher = WEBSOCKET_KEY.matcher(line);
|
|
||||||
if(matcher.matches()) key = matcher.group(1);
|
|
||||||
}
|
|
||||||
return key;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Pattern AUTORIZATION = Pattern.compile("Authorization: Bearer (.*)");
|
|
||||||
|
|
||||||
public static String readAuthorization(HttpReader reader) throws Exception{
|
|
||||||
String line;
|
|
||||||
String key = null;
|
|
||||||
while (((line = reader.readLine()) != null) && (line.length() > 0)){
|
|
||||||
Matcher matcher = AUTORIZATION.matcher(line);
|
|
||||||
if(matcher.matches()){
|
|
||||||
key = matcher.group(1);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return key;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Object readJson(HttpReader reader) throws Exception{
|
public static Object readJson(HttpReader reader) throws Exception{
|
||||||
String line = "";
|
String line = "";
|
||||||
while (reader.ready()){
|
while (reader.ready()){
|
||||||
|
@ -103,104 +76,6 @@ public class HttpUtil{
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
// I found this code on StackOverFlow !!!!! (and the write too)
|
|
||||||
public static String readWebSocket(HttpReader reader) throws Exception{
|
|
||||||
int buffLenth = 1024;
|
|
||||||
int len = 0;
|
|
||||||
byte[] b = new byte[buffLenth];
|
|
||||||
// rawIn is a Socket.getInputStream();
|
|
||||||
while (true){
|
|
||||||
len = reader.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]);
|
|
||||||
}
|
|
||||||
|
|
||||||
return new String(message);
|
|
||||||
|
|
||||||
} else
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void sendWebSocket(HttpWriter writer, String message) throws Exception{
|
|
||||||
byte[] rawData = message.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++;
|
|
||||||
}
|
|
||||||
|
|
||||||
writer.write(reply);
|
|
||||||
writer.flush();
|
|
||||||
}
|
|
||||||
|
|
||||||
private static String codeMessage(int paramInt){
|
private static String codeMessage(int paramInt){
|
||||||
switch (paramInt){
|
switch (paramInt){
|
||||||
case 200:
|
case 200:
|
||||||
|
|
|
@ -16,6 +16,11 @@ public class HttpWriter{
|
||||||
this.out = socket.getOutputStream();
|
this.out = socket.getOutputStream();
|
||||||
this.writer = new BufferedWriter(new OutputStreamWriter(out, StandardCharsets.UTF_8));
|
this.writer = new BufferedWriter(new OutputStreamWriter(out, StandardCharsets.UTF_8));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public HttpWriter(HttpWriter origin) throws Exception{
|
||||||
|
this.out = origin.out;
|
||||||
|
this.writer = origin.writer;
|
||||||
|
}
|
||||||
|
|
||||||
public void write(byte[] buffer) throws IOException{
|
public void write(byte[] buffer) throws IOException{
|
||||||
this.out.write(buffer);
|
this.out.write(buffer);
|
||||||
|
|
59
src/be/jeffcheasey88/peeratcode/framework/Locker.java
Normal file
59
src/be/jeffcheasey88/peeratcode/framework/Locker.java
Normal file
|
@ -0,0 +1,59 @@
|
||||||
|
package be.jeffcheasey88.peeratcode.framework;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Map.Entry;
|
||||||
|
import java.util.concurrent.BlockingQueue;
|
||||||
|
import java.util.concurrent.LinkedBlockingQueue;
|
||||||
|
|
||||||
|
public class Locker<V>{
|
||||||
|
|
||||||
|
private Map<Key, BlockingQueue<V>> map;
|
||||||
|
|
||||||
|
public Locker(){
|
||||||
|
this.map = new HashMap<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void init(Key key){
|
||||||
|
this.map.put(key, new LinkedBlockingQueue<>());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void remove(Key key){
|
||||||
|
this.map.remove(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
private BlockingQueue<V> get(Key key){
|
||||||
|
return this.map.get(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setValue(V value){
|
||||||
|
for(Entry<Key, BlockingQueue<V>> entry : this.map.entrySet()){
|
||||||
|
entry.getValue().add(value);
|
||||||
|
this.unlock(entry.getKey());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public V getValue(Key key){
|
||||||
|
BlockingQueue<V> queue = get(key);
|
||||||
|
if(queue.isEmpty()) return null;
|
||||||
|
return queue.poll();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void lock(Key key) throws InterruptedException{
|
||||||
|
BlockingQueue<V> queue = get(key);
|
||||||
|
if(queue.isEmpty()){
|
||||||
|
synchronized(queue){
|
||||||
|
queue.wait();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void unlock(Key key){
|
||||||
|
BlockingQueue<V> queue = get(key);
|
||||||
|
synchronized(queue){
|
||||||
|
queue.notify();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class Key{ public Key(){} }
|
||||||
|
}
|
|
@ -15,4 +15,5 @@ public @interface Route{
|
||||||
|
|
||||||
boolean needLogin() default false;
|
boolean needLogin() default false;
|
||||||
|
|
||||||
|
boolean websocket() default false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -63,6 +63,11 @@ public class Router{
|
||||||
Matcher matcher = this.patterns.get(routes.getKey()).matcher(path);
|
Matcher matcher = this.patterns.get(routes.getKey()).matcher(path);
|
||||||
if(matcher.matches()){
|
if(matcher.matches()){
|
||||||
if(user == null && routes.getValue().needLogin()) return;
|
if(user == null && routes.getValue().needLogin()) return;
|
||||||
|
if(routes.getValue().websocket()){
|
||||||
|
HttpUtil.switchToWebSocket(reader, writer);
|
||||||
|
reader = new WebSocketReader(reader);
|
||||||
|
writer = new WebSocketWriter(writer);
|
||||||
|
}
|
||||||
routes.getKey().exec(matcher, user, reader, writer);
|
routes.getKey().exec(matcher, user, reader, writer);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,62 @@
|
||||||
|
package be.jeffcheasey88.peeratcode.framework;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
public class WebSocketReader extends HttpReader{
|
||||||
|
|
||||||
|
public WebSocketReader(HttpReader origin) throws Exception {
|
||||||
|
super(origin);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String readLine() throws IOException{
|
||||||
|
//read websocket found on StackOverFlow
|
||||||
|
int buffLenth = 1024;
|
||||||
|
int len = 0;
|
||||||
|
byte[] b = new byte[buffLenth];
|
||||||
|
// rawIn is a Socket.getInputStream();
|
||||||
|
while (true){
|
||||||
|
len = 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]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return new String(message);
|
||||||
|
|
||||||
|
} else
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,61 @@
|
||||||
|
package be.jeffcheasey88.peeratcode.framework;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
public class WebSocketWriter extends HttpWriter{
|
||||||
|
|
||||||
|
public WebSocketWriter(HttpWriter origin) throws Exception {
|
||||||
|
super(origin);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void write(String message) throws IOException{
|
||||||
|
//write websocket found on StackOverFlow
|
||||||
|
byte[] rawData = message.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++;
|
||||||
|
}
|
||||||
|
|
||||||
|
write(reply);
|
||||||
|
flush();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,43 @@
|
||||||
|
package be.jeffcheasey88.peeratcode.routes;
|
||||||
|
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
|
||||||
|
import be.jeffcheasey88.peeratcode.framework.HttpReader;
|
||||||
|
import be.jeffcheasey88.peeratcode.framework.HttpWriter;
|
||||||
|
import be.jeffcheasey88.peeratcode.framework.Locker;
|
||||||
|
import be.jeffcheasey88.peeratcode.framework.Locker.Key;
|
||||||
|
import be.jeffcheasey88.peeratcode.framework.Route;
|
||||||
|
import be.jeffcheasey88.peeratcode.framework.User;
|
||||||
|
import be.jeffcheasey88.peeratcode.model.Completion;
|
||||||
|
import be.jeffcheasey88.peeratcode.repository.DatabaseRepository;
|
||||||
|
|
||||||
|
public class DynamicLeaderboard extends Leaderboard{
|
||||||
|
|
||||||
|
private Locker<Completion> locker;
|
||||||
|
|
||||||
|
public DynamicLeaderboard(DatabaseRepository databaseRepo){
|
||||||
|
super(databaseRepo);
|
||||||
|
this.locker = new Locker<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Locker<Completion> getLocker(){
|
||||||
|
return this.locker;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Route(path = "^\\/rleaderboard\\/?(\\d+)?$", websocket = true)
|
||||||
|
public void exec(Matcher matcher, User user, HttpReader reader, HttpWriter writer) throws Exception{
|
||||||
|
Key key = new Key();
|
||||||
|
|
||||||
|
locker.init(key);
|
||||||
|
while(!reader.isClosed()){
|
||||||
|
locker.getValue(key);
|
||||||
|
if(matcher.group(1) != null){
|
||||||
|
groupsLeaderboard(Integer.parseInt(matcher.group(1)), writer);
|
||||||
|
}else{
|
||||||
|
playersLeaderboard(writer);
|
||||||
|
}
|
||||||
|
locker.lock(key);
|
||||||
|
}
|
||||||
|
locker.remove(key);
|
||||||
|
}
|
||||||
|
}
|
|
@ -37,7 +37,7 @@ public class Leaderboard implements Response {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void groupsLeaderboard(int chapterId, HttpWriter writer) throws IOException {
|
public final void groupsLeaderboard(int chapterId, HttpWriter writer) throws IOException {
|
||||||
Chapter chInfo = databaseRepo.getChapter(chapterId);
|
Chapter chInfo = databaseRepo.getChapter(chapterId);
|
||||||
|
|
||||||
SortedSet<Group> allGroupsForChapter = databaseRepo.getAllGroupForChapterLeaderboard(chapterId);
|
SortedSet<Group> allGroupsForChapter = databaseRepo.getAllGroupForChapterLeaderboard(chapterId);
|
||||||
|
@ -68,7 +68,7 @@ public class Leaderboard implements Response {
|
||||||
writer.write(leaderboardJSON.toJSONString().replace("\\", ""));
|
writer.write(leaderboardJSON.toJSONString().replace("\\", ""));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void playersLeaderboard(HttpWriter writer) throws IOException {
|
public final void playersLeaderboard(HttpWriter writer) throws IOException {
|
||||||
SortedSet<Player> allPlayers = databaseRepo.getAllPlayerForLeaderboard();
|
SortedSet<Player> allPlayers = databaseRepo.getAllPlayerForLeaderboard();
|
||||||
JSONArray playersJSON = new JSONArray();
|
JSONArray playersJSON = new JSONArray();
|
||||||
if (allPlayers != null) {
|
if (allPlayers != null) {
|
||||||
|
@ -77,8 +77,8 @@ public class Leaderboard implements Response {
|
||||||
playerJSON.put("pseudo", player.getPseudo());
|
playerJSON.put("pseudo", player.getPseudo());
|
||||||
if (player.getGroups() != null)
|
if (player.getGroups() != null)
|
||||||
playerJSON.put("groups", player.getJsonGroups());
|
playerJSON.put("groups", player.getJsonGroups());
|
||||||
if (player.getAvatar() != null)
|
// if (player.getAvatar() != null)
|
||||||
playerJSON.put("avatar", Base64.getEncoder().encodeToString(player.getAvatar()));
|
// playerJSON.put("avatar", Base64.getEncoder().encodeToString(player.getAvatar()));
|
||||||
playerJSON.put("rank", player.getRank());
|
playerJSON.put("rank", player.getRank());
|
||||||
playerJSON.put("score", player.getTotalScore());
|
playerJSON.put("score", player.getTotalScore());
|
||||||
playerJSON.put("completions", player.getTotalCompletion());
|
playerJSON.put("completions", player.getTotalCompletion());
|
||||||
|
|
|
@ -14,6 +14,7 @@ import org.json.simple.JSONObject;
|
||||||
import be.jeffcheasey88.peeratcode.framework.HttpReader;
|
import be.jeffcheasey88.peeratcode.framework.HttpReader;
|
||||||
import be.jeffcheasey88.peeratcode.framework.HttpUtil;
|
import be.jeffcheasey88.peeratcode.framework.HttpUtil;
|
||||||
import be.jeffcheasey88.peeratcode.framework.HttpWriter;
|
import be.jeffcheasey88.peeratcode.framework.HttpWriter;
|
||||||
|
import be.jeffcheasey88.peeratcode.framework.Locker;
|
||||||
import be.jeffcheasey88.peeratcode.framework.Response;
|
import be.jeffcheasey88.peeratcode.framework.Response;
|
||||||
import be.jeffcheasey88.peeratcode.framework.Route;
|
import be.jeffcheasey88.peeratcode.framework.Route;
|
||||||
import be.jeffcheasey88.peeratcode.framework.User;
|
import be.jeffcheasey88.peeratcode.framework.User;
|
||||||
|
@ -25,10 +26,13 @@ import be.jeffcheasey88.peeratcode.repository.DatabaseRepository;
|
||||||
public class PuzzleResponse implements Response {
|
public class PuzzleResponse implements Response {
|
||||||
private final DatabaseRepository databaseRepo;
|
private final DatabaseRepository databaseRepo;
|
||||||
private final String usersFilesPath;
|
private final String usersFilesPath;
|
||||||
|
|
||||||
public PuzzleResponse(DatabaseRepository databaseRepo, String initUsersFilesPath) {
|
private final Locker<Completion> leaderboard;
|
||||||
|
|
||||||
|
public PuzzleResponse(DatabaseRepository databaseRepo, String initUsersFilesPath, Locker<Completion> locker){
|
||||||
this.databaseRepo = databaseRepo;
|
this.databaseRepo = databaseRepo;
|
||||||
usersFilesPath = initUsersFilesPath;
|
usersFilesPath = initUsersFilesPath;
|
||||||
|
this.leaderboard = locker;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Route(path = "^\\/puzzleResponse\\/([0-9]+)$", type = POST, needLogin = true)
|
@Route(path = "^\\/puzzleResponse\\/([0-9]+)$", type = POST, needLogin = true)
|
||||||
|
@ -54,6 +58,9 @@ public class PuzzleResponse implements Response {
|
||||||
responseJSON.put("tries", completion.getTries());
|
responseJSON.put("tries", completion.getTries());
|
||||||
}
|
}
|
||||||
writer.write(responseJSON.toJSONString());
|
writer.write(responseJSON.toJSONString());
|
||||||
|
writer.flush();
|
||||||
|
|
||||||
|
leaderboard.setValue(completion);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void saveSourceCode(ReceivedResponse received, Player player){
|
private void saveSourceCode(ReceivedResponse received, Player player){
|
||||||
|
|
|
@ -15,11 +15,11 @@ import be.jeffcheasey88.peeratcode.framework.User;
|
||||||
import be.jeffcheasey88.peeratcode.model.Group;
|
import be.jeffcheasey88.peeratcode.model.Group;
|
||||||
import be.jeffcheasey88.peeratcode.repository.DatabaseRepository;
|
import be.jeffcheasey88.peeratcode.repository.DatabaseRepository;
|
||||||
|
|
||||||
public class CreateGroup implements Response {
|
public class GroupCreate implements Response {
|
||||||
|
|
||||||
private DatabaseRepository repo;
|
private DatabaseRepository repo;
|
||||||
|
|
||||||
public CreateGroup(DatabaseRepository repo) {
|
public GroupCreate(DatabaseRepository repo) {
|
||||||
this.repo = repo;
|
this.repo = repo;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue