diff options
author | Florian Rinke <develop@torui.de> | 2021-10-14 17:05:42 +0200 |
---|---|---|
committer | Florian Rinke <develop@torui.de> | 2021-10-14 17:05:42 +0200 |
commit | fd39e0b0f1318d5dfa0c2617e10d825710b7dd01 (patch) | |
tree | f9b3dbbd20fb05eed3f217acc099ebddeabc7a6e /src/main/java/de/torui/coflsky/network | |
parent | 7eacb4b62638c1ef5d5d23d7c2a8d8b0045e6bbc (diff) | |
download | COFL-fd39e0b0f1318d5dfa0c2617e10d825710b7dd01.tar.gz COFL-fd39e0b0f1318d5dfa0c2617e10d825710b7dd01.tar.bz2 COFL-fd39e0b0f1318d5dfa0c2617e10d825710b7dd01.zip |
refactor websocket package to network package
Diffstat (limited to 'src/main/java/de/torui/coflsky/network')
4 files changed, 516 insertions, 0 deletions
diff --git a/src/main/java/de/torui/coflsky/network/NaiveSSLContext.java b/src/main/java/de/torui/coflsky/network/NaiveSSLContext.java new file mode 100644 index 0000000..e5f7a95 --- /dev/null +++ b/src/main/java/de/torui/coflsky/network/NaiveSSLContext.java @@ -0,0 +1,125 @@ +package de.torui.coflsky.network; +/* + * Copyright (C) 2015 Neo Visionaries Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific + * language governing permissions and limitations under the + * License. + */ +import java.security.KeyManagementException; +import java.security.NoSuchAlgorithmException; +import java.security.NoSuchProviderException; +import java.security.Provider; +import java.security.cert.X509Certificate; +import javax.net.ssl.SSLContext; +import javax.net.ssl.TrustManager; +import javax.net.ssl.X509TrustManager; + + +/** + * A factory class which creates an {@link SSLContext} that + * naively accepts all certificates without verification. + * + * <pre> + * // Create an SSL context that naively accepts all certificates. + * SSLContext context = NaiveSSLContext.getInstance("TLS"); + * + * // Create a socket factory from the SSL context. + * SSLSocketFactory factory = context.getSocketFactory(); + * + * // Create a socket from the socket factory. + * SSLSocket socket = factory.createSocket("www.example.com", 443); + * </pre> + * + * @author Takahiko Kawasaki + */ +public class NaiveSSLContext +{ + private NaiveSSLContext() + { + } + + + /** + * Get an SSLContext that implements the specified secure + * socket protocol and naively accepts all certificates + * without verification. + */ + public static SSLContext getInstance(String protocol) throws NoSuchAlgorithmException + { + return init(SSLContext.getInstance(protocol)); + } + + + /** + * Get an SSLContext that implements the specified secure + * socket protocol and naively accepts all certificates + * without verification. + */ + public static SSLContext getInstance(String protocol, Provider provider) throws NoSuchAlgorithmException + { + return init(SSLContext.getInstance(protocol, provider)); + } + + + /** + * Get an SSLContext that implements the specified secure + * socket protocol and naively accepts all certificates + * without verification. + */ + public static SSLContext getInstance(String protocol, String provider) throws NoSuchAlgorithmException, NoSuchProviderException + { + return init(SSLContext.getInstance(protocol, provider)); + } + + + /** + * Set NaiveTrustManager to the given context. + */ + private static SSLContext init(SSLContext context) + { + try + { + // Set NaiveTrustManager. + context.init(null, new TrustManager[] { new NaiveTrustManager() }, null); + } + catch (KeyManagementException e) + { + throw new RuntimeException("Failed to initialize an SSLContext.", e); + } + + return context; + } + + + /** + * A {@link TrustManager} which trusts all certificates naively. + */ + private static class NaiveTrustManager implements X509TrustManager + { + @Override + public X509Certificate[] getAcceptedIssuers() + { + return null; + } + + + public void checkClientTrusted(X509Certificate[] certs, String authType) + { + } + + + public void checkServerTrusted(X509Certificate[] certs, String authType) + { + } + } +}
\ No newline at end of file diff --git a/src/main/java/de/torui/coflsky/network/QueryServerCommands.java b/src/main/java/de/torui/coflsky/network/QueryServerCommands.java new file mode 100644 index 0000000..0bf54a3 --- /dev/null +++ b/src/main/java/de/torui/coflsky/network/QueryServerCommands.java @@ -0,0 +1,105 @@ +package de.torui.coflsky.network; + +import java.io.BufferedInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.net.HttpURLConnection; +import java.net.URL; +import java.util.Arrays; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; + +import de.torui.coflsky.CoflSky; + +public class QueryServerCommands { + + private static Gson gson = new GsonBuilder().create(); + + public static String QueryCommands() { + + String queryResult = GetRequest(CoflSky.CommandUri); + + if(queryResult != null) { + CommandInfo[] commands = gson.fromJson(queryResult, CommandInfo[].class); + + System.out.println(">>> "+Arrays.toString(commands)); + + StringBuilder sb = new StringBuilder(); + + if(commands.length>0) { + for(CommandInfo cm : commands) { + sb.append(cm + "\n"); + } + } + return sb.toString().trim(); + + } + + return "§4ERROR: Could not connect to command server!"; + } + + private static class CommandInfo { + + public String subCommand; + public String description; + + public CommandInfo() {} + + public CommandInfo(String subCommand, String description) { + super(); + this.subCommand = subCommand; + this.description = description; + } + + @Override + public String toString() { + return subCommand + ": " + description; + } + + + + } + private static String GetRequest(String uri) { + + try { + System.out.println("Get request"); + URL url = new URL(uri); + HttpURLConnection con; + con = (HttpURLConnection) url.openConnection(); + con.setRequestMethod("GET"); + + //con.setRequestProperty("Content-Type", "application/json; charset=UTF-8"); + con.setRequestProperty("Accept", "application/json"); + con.setRequestProperty("User-Agent", "CoflMod"); + //con.setDoInput(true); + con.setDoInput(true); + + // ... + + /*OutputStream os = con.getOutputStream(); + byte[] bytes = ("[\"" + getUsername() + "\"]").getBytes("UTF-8"); + os.write(bytes); + os.close(); + */ + System.out.println("InputStream"); + InputStream in = new BufferedInputStream(con.getInputStream()); + ByteArrayOutputStream result = new ByteArrayOutputStream(); + byte[] buffer = new byte[1024]; + for (int length; (length = in.read(buffer)) != -1; ) { + result.write(buffer, 0, length); + } + // StandardCharsets.UTF_8.name() > JDK 7 + String resString = result.toString("UTF-8"); + + System.out.println("Result= " + resString); + return resString; + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + + return null; + } +} diff --git a/src/main/java/de/torui/coflsky/network/WSClient.java b/src/main/java/de/torui/coflsky/network/WSClient.java new file mode 100644 index 0000000..529056b --- /dev/null +++ b/src/main/java/de/torui/coflsky/network/WSClient.java @@ -0,0 +1,134 @@ +package de.torui.coflsky.network; + +import java.io.IOException; +import java.net.URI; +import java.security.NoSuchAlgorithmException; + +import javax.net.ssl.SSLContext; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.neovisionaries.ws.client.WebSocket; +import com.neovisionaries.ws.client.WebSocketAdapter; +import com.neovisionaries.ws.client.WebSocketException; +import com.neovisionaries.ws.client.WebSocketFactory; +import com.neovisionaries.ws.client.WebSocketState; +import net.minecraft.client.Minecraft; +import de.torui.coflsky.CoflSky; +import de.torui.coflsky.WSCommandHandler; +import de.torui.coflsky.core.Command; +import de.torui.coflsky.core.StringCommand; + +public class WSClient extends WebSocketAdapter { + + + public static Gson gson; + + + static { + gson = new GsonBuilder()/*.setFieldNamingStrategy(new FieldNamingStrategy() { + @Override + public String translateName(Field f) { + + String name = f.getName(); + char firstChar = name.charAt(0); + return Character.toLowerCase(firstChar) + name.substring(1); + } + })*/.create(); + } + public URI uri; + public WebSocket socket; + public boolean shouldRun = false; + public WebSocketState currentState = WebSocketState.CLOSED; + + public WSClient(URI uri) { + this.uri = uri; + + } + + public void start() throws IOException, WebSocketException, NoSuchAlgorithmException { + WebSocketFactory factory = new WebSocketFactory(); + + /*// Create a custom SSL context. + SSLContext context = NaiveSSLContext.getInstance("TLS"); + + // Set the custom SSL context. + factory.setSSLContext(context); + + // Disable manual hostname verification for NaiveSSLContext. + // + // Manual hostname verification has been enabled since the + // version 2.1. Because the verification is executed manually + // after Socket.connect(SocketAddress, int) succeeds, the + // hostname verification is always executed even if you has + // passed an SSLContext which naively accepts any server + // certificate. However, this behavior is not desirable in + // some cases and you may want to disable the hostname + // verification. You can disable the hostname verification + // by calling WebSocketFactory.setVerifyHostname(false). + factory.setVerifyHostname(false); + factory.*/ + factory.setConnectionTimeout(10*1000); + this.socket = factory.createSocket(uri); + this.socket.addListener(this); + this.socket.connect(); + } + + public void stop() { + System.out.println("Closing Socket"); + // socket.sendClose(); + socket.clearListeners(); + + socket.disconnect(); + /*try { + socket.getConnectedSocket().close(); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (WebSocketException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + }*/ + System.out.println("Socket closed"); + + } + + @Override + public void onStateChanged(WebSocket websocket, WebSocketState newState) throws Exception { + System.out.println("WebSocket Changed state to: " + newState); + currentState = newState; + + if(newState == WebSocketState.CLOSED && shouldRun) { + CoflSky.Wrapper.restartWebsocketConnection(); + } + + super.onStateChanged(websocket, newState); + } + + + + @Override + public void onTextMessage(WebSocket websocket, String text) throws Exception{ + + //super.onTextMessage(websocket, text); + System.out.println("Received: "+ text); + Command cmd = gson.fromJson(text, Command.class); + //System.out.println(cmd); + WSCommandHandler.HandleCommand(cmd, Minecraft.getMinecraft().thePlayer); + + } + + public void SendCommand(Command cmd) { + String json = gson.toJson(cmd); + this.socket.sendText(json); + } + + public void SendCommand(StringCommand sc) { + String json = gson.toJson(sc); + this.socket.sendText(json); + } + + + + +}
\ No newline at end of file diff --git a/src/main/java/de/torui/coflsky/network/WSClientWrapper.java b/src/main/java/de/torui/coflsky/network/WSClientWrapper.java new file mode 100644 index 0000000..f30d0f9 --- /dev/null +++ b/src/main/java/de/torui/coflsky/network/WSClientWrapper.java @@ -0,0 +1,152 @@ +package de.torui.coflsky.network; + +import java.io.IOException; +import java.net.URI; +import java.net.URISyntaxException; +import java.security.NoSuchAlgorithmException; +import java.util.UUID; + +import com.neovisionaries.ws.client.WebSocketException; + +import de.torui.coflsky.CoflSky; +import de.torui.coflsky.core.Command; +import de.torui.coflsky.core.StringCommand; +import de.torui.coflsky.minecraft_integration.PlayerDataProvider; +import net.minecraft.client.Minecraft; +import net.minecraft.util.ChatComponentText; +import de.torui.coflsky.minecraft_integration.CoflSessionManager; + + +public class WSClientWrapper { + public WSClient socket; + // public Thread thread; + public boolean isRunning; + + private String[] uris; + + + public WSClientWrapper(String[] uris) { + this.uris = uris; + } + + public void restartWebsocketConnection() { + socket.socket.clearListeners(); + socket.stop(); + + System.out.println("Sleeping..."); + Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText("Lost connection to Coflnet, trying to reestablish the connection in 2 Seconds...")); + + try { + Thread.sleep(2000); + } catch (InterruptedException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + + socket = new WSClient(socket.uri); + isRunning = false; + start(); + } + + + public boolean startConnection() { + + if(isRunning) + return false; + + for(String s : uris) { + + System.out.println("Trying connection with uri=" + s); + + if(initializeNewSocket(s)) { + return true; + } + } + + throw new Error("Could not connect to any websocket remote!"); + } + + + + private boolean initializeNewSocket(String uriPrefix) { + + + String uri = uriPrefix; + uri += "?version=" + CoflSky.VERSION; + + String username = PlayerDataProvider.getUsername(); + uri += "&player=" + username; + + //Generate a CoflSession + + try { + CoflSessionManager.UpdateCoflSessions(); + String coflSessionID = CoflSessionManager.GetCoflSession(username).SessionUUID; + + uri += "&SId=" + coflSessionID; + + socket = new WSClient(URI.create(uri)); + + boolean successfull = start(); + if(successfull) { + socket.shouldRun = true; + } + return successfull; + } catch(IOException e) { + e.printStackTrace(); + } + + return false; + + } + + private synchronized boolean start() { + if(!isRunning) { + try { + + socket.start(); + isRunning = true; + + return true; + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (WebSocketException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (NoSuchAlgorithmException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + return false; + } + return false; + } + + public synchronized void stop() { + if(isRunning) { + socket.shouldRun = false; + socket.stop(); + isRunning = false; + socket = null; + } + } + + public synchronized void SendMessage(Command cmd){ + if(this.isRunning) { + this.socket.SendCommand(cmd); + } else { + Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText("tried sending a callback to coflnet but failed. the connection must be closed.")); + } + + } + + public void SendMessage(StringCommand sc) { + this.socket.SendCommand(sc); + } + + public String GetStatus() { + return "" + isRunning + " " + + (this.socket!=null ? this.socket.currentState.toString() : "NOT_INITIALIZED"); + } +} |