commit 5d75c12b7dab6831e87017d4064dd48da865204e Author: Defend Date: Fri Feb 17 15:17:49 2017 +0300 Release 12 diff --git a/.idea/compiler.xml b/.idea/compiler.xml new file mode 100644 index 0000000..96cc43e --- /dev/null +++ b/.idea/compiler.xml @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/copyright/profiles_settings.xml b/.idea/copyright/profiles_settings.xml new file mode 100644 index 0000000..e7bedf3 --- /dev/null +++ b/.idea/copyright/profiles_settings.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..4b23316 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,82 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..a6d8063 --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/sqldialects.xml b/.idea/sqldialects.xml new file mode 100644 index 0000000..af0e43a --- /dev/null +++ b/.idea/sqldialects.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/.idea/workspace.xml b/.idea/workspace.xml new file mode 100644 index 0000000..aff860f --- /dev/null +++ b/.idea/workspace.xml @@ -0,0 +1,915 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + true + DEFINITION_ORDER + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + project + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1470646840402 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + file://$PROJECT_DIR$/src/console.java + 48 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1.8 + + + + + + + + \ No newline at end of file diff --git a/ctServer.iml b/ctServer.iml new file mode 100644 index 0000000..c90834f --- /dev/null +++ b/ctServer.iml @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/ctserver.properties b/ctserver.properties new file mode 100644 index 0000000..81b0032 --- /dev/null +++ b/ctserver.properties @@ -0,0 +1,4 @@ +path.variable.kotlin_bundled=E\:\\ProfessionalPrograms\\IntelliJ IDEA 2016.2.1\\plugins\\Kotlin\\kotlinc +path.variable.maven_repository=C\:\\Users\\itsmy\\.m2\\repository +jdk.home.1.8=E\:/ProfessionalPrograms/JDK8 +javac2.instrumentation.includeJavaRuntime=false \ No newline at end of file diff --git a/out/production/ctServer/client.class b/out/production/ctServer/client.class new file mode 100644 index 0000000..220a390 Binary files /dev/null and b/out/production/ctServer/client.class differ diff --git a/out/production/ctServer/console.class b/out/production/ctServer/console.class new file mode 100644 index 0000000..59e3a3e Binary files /dev/null and b/out/production/ctServer/console.class differ diff --git a/out/production/ctServer/ctServer$ClientInfo.class b/out/production/ctServer/ctServer$ClientInfo.class new file mode 100644 index 0000000..c15da56 Binary files /dev/null and b/out/production/ctServer/ctServer$ClientInfo.class differ diff --git a/out/production/ctServer/ctServer.class b/out/production/ctServer/ctServer.class new file mode 100644 index 0000000..a3e3c59 Binary files /dev/null and b/out/production/ctServer/ctServer.class differ diff --git a/src/client.java b/src/client.java new file mode 100644 index 0000000..36251e7 --- /dev/null +++ b/src/client.java @@ -0,0 +1,303 @@ +import jdk.nashorn.internal.parser.JSONParser; + +import javax.xml.bind.DatatypeConverter; +import java.io.*; +import java.net.*; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; +import java.util.NoSuchElementException; +import java.util.Scanner; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * Created by itsmy on 08.08.2016. + */ +public class client extends Thread { + private Socket socket; + private BufferedReader reader; + private OutputStreamWriter writer; + private OutputStream out; + private InputStream in; + public Boolean httpAuthed = false; + public Boolean socketAuthed = false; + public int socketID; + + public void openSocket(Socket s) throws IOException { + socket = s; + out = socket.getOutputStream(); + in = socket.getInputStream(); + start(); + } + + + public void run() { + socketID = ctServer.socketID; + ctServer.sockets.add(socketID, this); + console.socket(socketID,"New connection"); + wsControl(); + } + + public void close(){ + try{ + if(socket.isClosed()){ + return; + } + socket.close(); + } + catch(IOException e){ + } + if(socketAuthed){ + ctServer.clientInfoList.remove(socketID); + } + ctServer.sessions[socketID] = false; + httpAuthed = false; + socketAuthed = false; + console.socket(socketID,"Disconnected"); + this.interrupt(); + } + + public void wsControl(){ + try{ + handshake(); + while (httpAuthed) { + String msg = readSocket(); + sendSocket(msg); + //TODO: сделать проверку протокола + } + } finally { + close(); + } + + + } + + private String bytesToStringUTFCustom(int[] ints) { + char[] buffer = new char[ints.length]; + for(int i = 0; i < buffer.length; i++) { + char c = (char) ints[i]; + buffer[i] = c; + } + return new String(buffer); + } + + private void handshake(){ + try{ + if(!httpAuthed) { + socket.setSoTimeout(2000); + String data = new Scanner(in, "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(); + try { + byte[] 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"); + out.write(response, 0, response.length); + } catch (IOException e) { + console.out("Server Error:", e.toString()); + } catch (NoSuchAlgorithmException e) { + console.out("Server Error:", e.toString()); + } + socket.setSoTimeout(0); + httpAuthed = true; + console.socket(socketID,"Handshake accepted!"); + } + } + }catch (SocketException e){ + console.debug("исключение 22"); + //TODO: написать исключение если сокет закрыт + }catch (NoSuchElementException e){ + console.socket(socketID,"Handshake Timeout (2000ms)"); + httpAuthed = false; + } + } + + public Boolean sendSocket(String message){ + byte[] response; + byte[] r; + try{ + response = message.getBytes("UTF-8"); + }catch (UnsupportedEncodingException e){ + console.socket(socketID, "Unsupported encoding!"); + return false; + } + catch (NullPointerException e){ + return false; + } + if (message.length() < 126) { + r = new byte[response.length+2]; + System.arraycopy(response,0,r,2,response.length); + r[0] = (byte) 129; + r[1] = (byte) (response.length); + } + else{ + if (message.length() < 65535) { + r = new byte[response.length+4]; + System.arraycopy(response,0,r,4,response.length); + r[0] = (byte) 129; + r[1] = (byte) 126; + r[2] = (byte) (response.length >>> 8); + r[3] = (byte) (response.length); + } + else{ + if(response.length > Long.MAX_VALUE){ + console.out("Socket Exception", "Too long message for sending! (>64bit)"); + return false; + } + r = new byte[response.length+8]; + System.arraycopy(response,0,r,8,response.length); + r[0] = (byte) 129; + r[1] = (byte) 127; + r[2] = (byte) (response.length >>> 56); + r[3] = (byte) (response.length >>> 48); + r[4] = (byte) (response.length >>> 40); + r[5] = (byte) (response.length >>> 32); + r[6] = (byte) (response.length >>> 24); + r[7] = (byte) (response.length >>> 16); + r[8] = (byte) (response.length >>> 8); + r[9] = (byte) (response.length); + } + } + try{ + out.write(r, 0, r.length); + return true; + }catch(IOException e){ + console.out("Socket Exeption", "Client socket is closed?! Closing socket connection!"); + close(); + return false; + } + } + + public String readSocket(){ + String out = ""; + try + { + int[] MSG = new int[0]; + int OPCOUNT = 1; + int LENGTH; + int KEYFRAME = 0; + int[] KEY = new int[4]; + int OPCODE = in.read(); //читаем OPCODE byte + switch(OPCODE){ + case -1: close(); //закрываем чтение потока при -1 + return null; + case 136: close(); + return null; + case 129: + LENGTH = in.read(); //читаем второй бит с данными о размере сообщения + //TODO: which и switch OPCOUNT - необходимо убрать + while(OPCOUNT < 4) { + switch (OPCOUNT){ + case 1: switch (LENGTH){ //узнаем длину сообщения + default: KEYFRAME = 2; + break; + case 254: KEYFRAME = 4; //126-65535 + break; + case 255: KEYFRAME = 10; //65535-... + break; + } + break; + case 2: + switch (KEYFRAME) { + case 2: + MSG = new int[LENGTH - 128]; + break; + case 4: + LENGTH = (in.read() << 8) + (in.read()); + MSG = new int[LENGTH]; + break; + case 10: + LENGTH = (in.read() << 56) + + (in.read() << 48) + + (in.read() << 40) + + (in.read() << 32) + + (in.read() << 24) + + (in.read() << 16) + + (in.read() << 8) + + (in.read()); + MSG = new int[LENGTH]; + break; + } + for (int i = 0; i < 4; i++) { + KEY[i] = in.read(); + } + for (int j = 0; j < (MSG.length); j++) { + int enc = in.read(); + MSG[j] = (byte) (enc ^ KEY[j & 0x3]); + } + break; + case 3: + if(MSG.length>0){ + out = bytesToStringUTFCustom(MSG); + } + else{ + return null; + } + } + OPCOUNT++; + } + } + }catch(IOException e){ + console.out("Socket Exception", "Client socket is closed?! Closing socket connection!"); + close(); + } + console.socket(socketID, "Message: "+out); + return out; + } +// +// public Socket getSocketbyId(socketID){ +// if(socket.closed) +// return this.socket; +// } + + + +// public void sControl(){ +// try{ +// while (true) { +// String input = reader.readLine(); +// if(input == null){break;} +// Pattern main = Pattern.compile(";"); +// if(!httpAuthed) { +// if (!ctServer.checkClient(this, main.split(input))) { +// writer.println("CONNECT_DENIED"); +// break; +// } +// } +// switch (input) { +// case "EXIT": +// socket.close(); +// break; +// default: +// writer.println("Client info - " + socket.getRemoteSocketAddress().toString()); +// console.out("Socket "+socketID+" Message",input); +// } +// } +// } catch (IOException e) { +// console.out("Server Error:", e.toString()); +// } finally { +// close(); +// try { +// socket.close(); +// console.out("Server", "Socket "+socketID+" disconnected!"); +// } catch (IOException e) { +// console.out("Server","System socket closing error!"); +// }catch (NullPointerException e){ +// +// } +// +// } +// } + +} diff --git a/src/console.java b/src/console.java new file mode 100644 index 0000000..8233b49 --- /dev/null +++ b/src/console.java @@ -0,0 +1,89 @@ +import javafx.application.Application; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.time.Clock; +import java.time.Instant; +import java.util.ArrayList; +import java.util.regex.Pattern; + +/** + * Created by itsmy on 08.08.2016. + */ +public class console extends Thread{ + + private BufferedReader in; + private String line; + + public void consoleListner() throws IOException{ + in = new BufferedReader(new InputStreamReader(System.in)); + line = ""; + start(); + } + + public static void out(String parent, String msg){ + Instant instant2 = Clock.systemUTC().instant(); + String time = instant2.toString(); + System.out.println("["+time+"|"+parent+"]: "+msg); + } + + public static void socket(Integer socketId, String msg){ + Instant instant2 = Clock.systemUTC().instant(); + String time = instant2.toString(); + System.out.println("["+time+"|"+"Socket "+socketId+"]: "+msg); + } + + public static void debug(String msg){ + Instant instant2 = Clock.systemUTC().instant(); + String time = instant2.toString(); + System.out.println("["+time+"|DEBUG]: "+msg); + } + + public void run() { + while (line.equalsIgnoreCase("quit") == false) { + try{ + line = in.readLine(); + Pattern main = Pattern.compile(" "); + String[] sx = main.split(line); + switch (sx[0]){ + case "/list": + ArrayList cil = ctServer.clientInfoList; + console.out("Server","/list"); + for(int i = 0; ctServer.sessions[i]; i++){ + if(ctServer.sockets.get(Integer.valueOf(i)).socketAuthed) { + ctServer.ClientInfo ci = cil.get(i); + console.out("Socket " + i, "VKID " + ci.VKID + " and PROTOCOL " + ci.PROTOCOL); + }else{ + console.out("Socket "+ i,"Not authed!"); + } + } + break; + case "/kick": + if(sx.length < 2) { + console.out("Server","/kick - Укажите имя сокета"); + } + break; + case "/help": + console.out("Server","/kick [socketid] для отключения сокета от сервера"); + console.out("Server","/list для отображения всех клиентов"); + console.out("Server","/info [socketid] для отображения полной информации о данном клиенте"); + console.out("Server","/send [socketid] [msg] отладочная команда"); + console.out("Server","ctServer Proto Defend Development 2016"); + break; + case "/send": + if(ctServer.sessions[Integer.valueOf(sx[1])]) { + if ((ctServer.sockets.size() >= Integer.valueOf(sx[1])) && (Integer.valueOf(sx[1]) >= 0)) { + ctServer.sockets.get(Integer.valueOf(sx[1])).sendSocket(sx[2]); + } + } + break; + default: console.out("Server","Введите /help для помощи"); + } + + }catch (IOException e){ + + } + } + } +} diff --git a/src/ctServer.java b/src/ctServer.java new file mode 100644 index 0000000..f0800a5 --- /dev/null +++ b/src/ctServer.java @@ -0,0 +1,102 @@ +import java.net.*; +import java.io.*; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.regex.Pattern; + +public class ctServer { + public static Boolean[] sessions; + public static List sockets; + public static int socketID; + public static ArrayList clientInfoList; + + public static class ClientInfo{ + public static String VKID, ROLE, PROTOCOL, EVENT, TRACKID; + public static int TIME; + public static Boolean notEmpty = false; + public static void destroy(){ + VKID = null; + ROLE = null; + PROTOCOL = null; + EVENT = null; + TRACKID = null; + TIME = 0; + notEmpty = false; + } + } + + public static boolean checkClient(client c, String[] args){ + ClientInfo ci = new ClientInfo(); + ci.destroy(); + try { + for (String name : args) { + Pattern main = Pattern.compile(":"); + String[] sx = main.split(name); + switch (sx[0]) { + case "PROTOCOL": + ci.PROTOCOL = sx[1]; + break; + case "VKID": + ci.VKID = sx[1]; + break; + } + } + if (!ci.VKID.equals("")) { + if (!ci.PROTOCOL.equals("")) { + clientInfoList.add(c.socketID, ci); + c.httpAuthed = true; + console.debug("Авторизация произошла!"); + return true; + } + } + } catch (NullPointerException e){ + return false; + } + return false; + } + + public static void main(String[] args) throws IOException{ + sessions = new Boolean[1000]; + for (int i = 0; i < sessions.length; i++) { + sessions[i] = false; + } + clientInfoList = new ArrayList<>(); + sockets = new ArrayList<>(); + try{ + new console().consoleListner(); + } + catch (IOException e){ + + } + int port = 80; + console.out("Socket Port", port+""); + ServerSocket ss = new ServerSocket(port); + try { + console.out("Server", "Waiting for a client"); + while(true) { + Socket socket = ss.accept(); + try { + for(int i = 0; ctServer.sessions.length > i; i++){ + if(ctServer.sessions[i] == null){ + ctServer.socketID = i; + ctServer.sessions[i] = true; + break; + } + if(ctServer.sessions[i] == false){ + ctServer.socketID = i; + ctServer.sessions[i] = true; + break; + } + } + new client().openSocket(socket); + } catch (IOException e) { + socket.close(); + } + } + } finally { + ss.close(); + } + } + +} \ No newline at end of file