package org.kne.cloud.network.klalb; import java.io.File; import java.io.FileReader; import java.io.IOException; import java.io.Reader; import java.net.Inet6Address; import java.net.InetAddress; import java.net.Socket; import java.net.SocketException; import java.net.SocketTimeoutException; import java.net.UnknownHostException; import java.util.HashMap; import java.util.HashSet; import java.util.Hashtable; import java.util.Iterator; import java.util.LinkedHashMap; import java.util.Map; import java.util.Map.Entry; import org.kne.cloud.network.*; import org.kne.cloud.network.minecraft.MinecraftSocketBridge; import java.util.Set; import com.google.gson.JsonArray; import com.google.gson.JsonElement; import com.google.gson.JsonObject; import com.google.gson.JsonParser; import com.google.gson.JsonPrimitive; public class KLALBProxySystem { private Set proxys=new HashSet<>(); private KLALBController klalbController; private KLALBRemoteManagement krm; public Set getProxys() { return proxys; } public KLALBController getKlalbController() { return klalbController; } public KLALBProxySystem(Reader json) { loadConfigJson(json); } public KLALBProxySystem(String json) { loadConfigJson(json); } public KLALBProxySystem(JsonElement json) { loadConfigJson(json); } public KLALBProxySystem(File jsonFile) throws IOException { loadConfigJson(jsonFile); } public KLALBProxySystem() { } public void enableRemoteManagement() throws IOException { if(krm==null) { krm=new KLALBRemoteManagement(this); }else { throw new IllegalStateException("Remote Management already enabled!"); } } public void enableRemoteManagement(MultipurposeSocketAddress bind) throws IOException { if(krm==null) { krm=new KLALBRemoteManagement(this,bind); }else { throw new IllegalStateException("Remote Management already enabled!"); } } public boolean isRemoteManagementEnabled() { return krm!=null; } public void disableRemoteManagement() { if(krm!=null) { krm.close(); krm=null; } } public void loadConfigJson(File jsonFile) throws IOException { FileReader fr = null; try { fr=new FileReader(jsonFile); loadConfigJson(fr); }finally { if(fr!=null) fr.close(); } } public void loadConfigJson(String json) { loadConfigJson(new JsonParser().parse(json)); } public void loadConfigJson(Reader json) { loadConfigJson(new JsonParser().parse(json)); } public void loadConfigJson(JsonElement json) { JsonArray jobj=(JsonArray) json; jobj.forEach((val)->{ solveEntry((JsonObject) val); }); } protected void solveEntry(JsonObject entry){ switch (entry.get("Type").getAsString()) { case "KLALBController": JsonElement vase= entry.get("VirtualAddress"); if(vase!=null) { try { klalbController=new KLALBController((Inet6Address) InetAddress.getByName(vase.getAsString())); } catch (UnknownHostException e) { e.printStackTrace(); } }else { klalbController=new KLALBController(); } JsonElement vsne=entry.get("VirtualSocketName"); //if(vsne!=null) { MultipurposeSocketAddress.getSocketTypeRegister().put(vsne.getAsString(), klalbController.getSocketType()); //} JsonElement tcple=entry.get("TCPListen"); if(tcple!=null) { MultipurposeSocketAddress mpsa=new MultipurposeSocketAddress(tcple.getAsString()); SocketChannelListener tcpl = null; try { tcpl = new SocketChannelListener(mpsa); tcpl.setCon((soc)->{ KLALBRemoteLine krs=null; try { krs = new KLALBRemoteLine(new StreamChannelKLALBPacketLink(soc)); klalbController.addRemoteLine(krs); } catch (IOException e) { e.printStackTrace(); } }); klalbController.getListenSocketAddress().add(mpsa); } catch (IOException e1) { e1.printStackTrace(); } } JsonElement udple=entry.get("UDPListen"); if(udple!=null) { MultipurposeSocketAddress mpsa=new MultipurposeSocketAddress(udple.getAsString()); DatagramSocketListener udpl = null; try { udpl = new DatagramSocketListener(mpsa); udpl.setCon((soc)->{ KLALBRemoteLine krs=null; try { krs = new KLALBRemoteLine(new SplitedDatagramKLALBPacketLink(soc)); klalbController.addRemoteLine(krs); } catch (IOException e) { e.printStackTrace(); } }); //klalbController.getListenSocketAddress().add(mpsa); } catch (IOException e1) { e1.printStackTrace(); } } JsonElement linele=entry.get("LineTable"); if(linele!=null) { JsonArray jary=(JsonArray)linele; jary.forEach((aline)->{ klalbController.getSelflineTable().add(new MultipurposeSocketAddress(aline.getAsString())); }); } JsonElement linetoc=entry.get("ConnectLineTable"); if(linetoc!=null) { JsonArray jary=(JsonArray)linetoc; jary.forEach((aline)->{ try { klalbController.addRemoteLines(new MultipurposeSocketAddress(aline.getAsString())); } catch (SocketTimeoutException e) { e.printStackTrace(); } catch (SocketException e) { e.printStackTrace(); } }); } break; case "SocketBridge": try { proxys.add(createProxyByJson(entry)); } catch (IOException e) { e.printStackTrace(); } break; default: break; } } public Proxy createProxyByJson(JsonObject entry) throws IOException { HostPortMap mapp=new HostPortMap(); LinkedHashMapmapb=new LinkedHashMap<>(); MultipurposeSocketAddress l=new MultipurposeSocketAddress(entry.get("Listen").getAsString()); SocketBridgeFactory bdg=getDefaultBridgeFactory(entry.get("Bridge"),mapb); MultipurposeSocketAddress r=getDefaultConnect(entry.get("Connect"),mapp); return new SocketToSocketProxy(l ,new MultipurposeSocketAddress("0.0.0.0:0"), r,mapp,bdg,mapb); } public JsonObject createJsonObjectByProxy(Proxy p) { if(p instanceof SocketToSocketProxy) { SocketToSocketProxy stsp=(SocketToSocketProxy) p; JsonObject jobj=new JsonObject(); jobj.addProperty("Listen", stsp.getListen().toString()); jobj.add("Bridge", getJsonElementByBridges(stsp)); jobj.add("Connect", getJsonElementByConnects(stsp)); return jobj; }else { throw new UnsupportedOperationException(); } } private JsonElement getJsonElementByConnects(SocketToSocketProxy stsp) { if(stsp.getDetectedConnect()==null||stsp.getDetectedConnect().isEmpty()) { return new JsonPrimitive(stsp.getDefaultConnect().toString()); }else { JsonObject jo=new JsonObject(); for (Iterator> iterator = stsp.getDetectedConnect().entrySet().iterator(); iterator.hasNext();) { Entry proxy = (Entry) iterator.next(); if(!proxy.getKey().equals("DEFAULT")) { jo.addProperty(proxy.getKey(), proxy.getValue().toString()); } } jo.addProperty("DEFAULT", stsp.getDefaultConnect().toString()); return jo; } } private JsonElement getJsonElementByBridges(SocketToSocketProxy stsp) { if(stsp.getDetectedFactory()==null||stsp.getDetectedFactory().isEmpty()) { return new JsonPrimitive(getJobjByFActory(stsp.getDefaultFactory())); }else { JsonObject jo=new JsonObject(); for (Iterator> iterator = stsp.getDetectedFactory().entrySet().iterator(); iterator.hasNext();) { Entry proxy = (Entry) iterator.next(); if(!proxy.getKey().equals("DEFAULT")) { jo.addProperty(proxy.getKey(), getJobjByFActory(proxy.getValue())); } } jo.addProperty("DEFAULT",getJobjByFActory( stsp.getDefaultFactory())); return jo; } } private MultipurposeSocketAddress getDefaultConnect(JsonElement jsonElement, LinkedHashMap mapp) { if(jsonElement instanceof JsonObject) { JsonObject jobj=(JsonObject) jsonElement; jobj.entrySet().forEach((en)->{ mapp.put(en.getKey(), new MultipurposeSocketAddress( en.getValue().getAsString())); }); return mapp.get("DEFAULT"); }else { return new MultipurposeSocketAddress(jsonElement.getAsString()); } } private SocketBridgeFactory getDefaultBridgeFactory(JsonElement jsonElement, LinkedHashMap mapp) { if(jsonElement instanceof JsonObject) { JsonObject jobj=(JsonObject) jsonElement; jobj.entrySet().forEach((en)->{ mapp.put(en.getKey(), getFactoryByJobj(en.getValue().getAsString())); }); return mapp.get("DEFAULT"); }else { return getFactoryByJobj(jsonElement.getAsString()); } } private SocketBridgeFactory getFactoryByJobj(String string) { if(string.startsWith("SocketBridge")) { return new DefaultSocketBridgeFactory(); }else if(string.startsWith("MinecraftSocketBridge")) { return new DefaultMinecraftSocketBridgeFactory(klalbController.getSelf(), Integer.parseInt(string.substring(21))); } throw new IllegalArgumentException("unknown SocketBridge type:"+string); } private String getJobjByFActory(SocketBridgeFactory sbf) { if(sbf instanceof DefaultSocketBridgeFactory) { return "SocketBridge"; }else if(sbf instanceof DefaultMinecraftSocketBridgeFactory) { return "MinecraftSocketBridge"+((DefaultMinecraftSocketBridgeFactory)sbf).getVport(); }else { throw new UnsupportedOperationException(); } } private KLALBStateGUI2 kgui; public KLALBStateGUI2 getKLALBGUI() { if(kgui==null) kgui=new KLALBStateGUI2(klalbController); return kgui; } }