diff --git a/KLALB协议规范V2.1.docx b/KLALB协议规范V2.1.docx new file mode 100644 index 0000000..f252cdc Binary files /dev/null and b/KLALB协议规范V2.1.docx differ diff --git a/klalbclient.ini b/klalbclient.ini deleted file mode 100644 index b6ecda0..0000000 --- a/klalbclient.ini +++ /dev/null @@ -1,3 +0,0 @@ -#Tue Jul 25 19:03:09 CST 2023 -local=0.0.0.0\:35000 -server=127.0.0.1\:4569 diff --git a/klalbconfig.json b/klalbconfig.json new file mode 100644 index 0000000..eeca17c --- /dev/null +++ b/klalbconfig.json @@ -0,0 +1,29 @@ +[ + {"Type":"KLALBController" , + "TCPListen" : "0.0.0.0:4567", + "VirtualSocketName" : "KLALB_Stream", + "LineTable":["192.168.0.233:4569","192.168.1.233:4569"] + }, + {"Type":"SocketBridge" , + "Listen" : "0.0.0.0:4569", + "Connect" : { + "KLALB" : "127.0.0.1:4567", + "RDP":"127.0.0.1:3389", + "HTTP":"127.0.0.1:5212", + "HTTPS":"192.168.1.235:443", + "DEFAULT":"127.0.0.1:36554" + } + }, + {"Type":"MinecraftSocketBridge" , + "Listen" : "0.0.0.0:36554", + "Connect" : "127.0.0.1:36555" + }, + {"Type":"MinecraftSocketBridge" , + "Listen" : "{KLALB_Stream}[::0]:23332", + "Connect" : "127.0.0.1:36555" + }, + { "Type":"SocketBridge" , + "Listen" : "{KLALB_Stream}[::0]:23333", + "Connect" : "127.0.0.1:5212" + } +] \ No newline at end of file diff --git a/kserver - 副本.ini b/kserver - 副本.ini deleted file mode 100644 index 944768a..0000000 --- a/kserver - 副本.ini +++ /dev/null @@ -1,3 +0,0 @@ -virtualip=67c:72ce:765e:4db1:a02e:92fa:1959:29eb -bind=0.0.0.0:4569 -local=127.0.0.1:36555 diff --git a/lib/ini4j.jar b/lib/ini4j.jar new file mode 100644 index 0000000..c2fc538 Binary files /dev/null and b/lib/ini4j.jar differ diff --git a/src/org/kne/acclerate/FastLib.java b/src/org/kne/acclerate/FastLib.java new file mode 100644 index 0000000..eb09572 --- /dev/null +++ b/src/org/kne/acclerate/FastLib.java @@ -0,0 +1,46 @@ +package org.kne.acclerate; + +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.ThreadFactory; + +import org.kne.io.Task; + +public class FastLib { + private static int cores=Runtime.getRuntime().availableProcessors(); + private static ExecutorService exc=Executors.newFixedThreadPool(cores,new ThreadFactory() { + + @Override + public Thread newThread(Runnable r) { + Thread t=new Thread(r); + t.setDaemon(true); + t.setPriority(Thread.MAX_PRIORITY); + return t; + } + }); + public static void arraycopy(Object src, int srcPos, Object dest, int destPos, int length) { + if(length<2000) { + System.arraycopy(src, srcPos, dest, destPos, length); + }else { + int count=length/cores; + int mod=length%cores; + Task[]tsk=new Task[cores]; + for (int i = 0; i < cores; i++) { + int j=i; + Task t=new Task() { + + @Override + protected void runTask() { + System.arraycopy(src, srcPos+count*j, dest, destPos+count*j, count); + } + }; + exc.execute(t); + tsk[i]=t; + } + System.arraycopy(src, srcPos+count*cores, dest, destPos+count*cores, mod); + for (int i = 0; i < tsk.length; i++) { + tsk[i].waitfortask(); + } + } + } +} diff --git a/src/org/kne/cloud/network/DatagramServerSocket.java b/src/org/kne/cloud/network/DatagramServerSocket.java new file mode 100644 index 0000000..54a5ba7 --- /dev/null +++ b/src/org/kne/cloud/network/DatagramServerSocket.java @@ -0,0 +1,176 @@ +package org.kne.cloud.network; + +import java.io.IOException; +import java.io.InterruptedIOException; +import java.net.DatagramPacket; +import java.net.DatagramSocket; +import java.net.DatagramSocketImpl; +import java.net.InetAddress; +import java.net.InetSocketAddress; +import java.net.SocketAddress; +import java.net.SocketException; +import java.util.Collections; +import java.util.HashSet; +import java.util.Iterator; +import java.util.Map; +import java.util.Set; +import java.util.Vector; +import java.util.concurrent.ArrayBlockingQueue; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.Flow.Subscriber; + +public class DatagramServerSocket extends DatagramSocket { + private Map clients=new ConcurrentHashMap<>(); + public DatagramServerSocket() throws SocketException { + super((SocketAddress)null); + setReuseAddress(true); + } + + protected DatagramServerSocket(DatagramSocketImpl impl) throws SocketException { + super(impl); + setReuseAddress(true); + } + + public DatagramServerSocket(int port, InetAddress laddr) throws SocketException { + super((SocketAddress)null); + setReuseAddress(true); + bind(new InetSocketAddress(laddr, port)); + } + + public DatagramServerSocket(int port) throws SocketException { + super((SocketAddress)null); + setReuseAddress(true); + bind(new InetSocketAddress(port)); + } + + public DatagramServerSocket(SocketAddress bindaddr) throws SocketException { + super((SocketAddress)null); + setReuseAddress(true); + bind(bindaddr); + } + + public DatagramServerSocket(int port, int backlog) throws SocketException { + super((SocketAddress)null); + setReuseAddress(true); + bind(new InetSocketAddress(port)); + } + + @Override + public synchronized void send(DatagramPacket p) throws IOException { + // TODO 自动生成的方法存根 + super.send(p); + } + + @Override + public synchronized void receive(DatagramPacket p) throws IOException { + // TODO 自动生成的方法存根 + super.receive(p); + } + + public DatagramServerSocket(int port, int backlog, InetAddress laddr) throws SocketException { + super((SocketAddress)null); + setReuseAddress(true); + bind(new InetSocketAddress(laddr, port)); + } + public DatagramSocket accept()throws IOException{ + if (isClosed()) + throw new SocketException("Socket is closed"); + if (!isBound()) + throw new SocketException("Socket is not bound yet"); + DatagramPacket dp=new DatagramPacket(new byte[65535], 65535); + do { + receive(dp); + System.out.println(dp); + }while(clients.containsKey(dp.getSocketAddress())); + System.out.println("accept"); + SubDatagramSocket re=new SubDatagramSocket((SocketAddress)null); + re.dp=dp; + re.setReuseAddress(true); + re.bind(new InetSocketAddress(InetAddress.getByName("192.168.0.233"), getLocalPort())); + re.connect(dp.getSocketAddress()); + return re; + /* loop:while(true) { + receive(dp); + SocketAddress isa= dp.getSocketAddress() ; + synchronized (clients) { + for (Iterator iterator = clients.iterator(); iterator.hasNext();) { + SubDatagramSocket subDatagramSocket = (SubDatagramSocket) iterator.next(); + if(subDatagramSocket.getRemoteSocketAddress().equals(isa)) { + DatagramPacket dpx=dp; + dp=new DatagramPacket(new byte[65535], 65535); + subDatagramSocket.getFstq().offer(dpx); + continue loop; + } + } + DatagramPacket dpx=dp; + dp=new DatagramPacket(new byte[65535], 65535); + SubDatagramSocket sds=new SubDatagramSocket(isa); + sds.getFstq().add(dpx); + return sds; + + } + }*/ + } + private class SubDatagramSocket extends DatagramSocket{ + + DatagramPacket dp; + + public SubDatagramSocket() throws SocketException { + super(); + } + + protected SubDatagramSocket(DatagramSocketImpl impl) { + super(impl); + } + + public SubDatagramSocket(int port, InetAddress laddr) throws SocketException { + super(port, laddr); + } + + public SubDatagramSocket(int port) throws SocketException { + super(port); + } + + public SubDatagramSocket(SocketAddress bindaddr) throws SocketException { + super(bindaddr); + } + + @Override + public void connect(InetAddress address, int port) { + super.connect(address, port); + clients.put(new InetSocketAddress(address, port),this); + } + + @Override + public void connect(SocketAddress addr) throws SocketException { + super.connect(addr); + clients.put(addr,this); + } + + @Override + public void receive(DatagramPacket p) throws IOException { + if(dp!=null) { + p.setLength(dp.getLength()); + System.arraycopy(dp.getData(), dp.getOffset(), p.getData(), p.getOffset(), dp.getLength()); + dp=null; + }else { + super.receive(p); + } + } + + @Override + public void disconnect() { + super.disconnect(); + SocketAddress sa=getRemoteSocketAddress(); + if(sa!=null) + clients.remove(sa); + } + + public void close() { + super.close(); + SocketAddress sa=getRemoteSocketAddress(); + if(sa!=null) + clients.remove(sa); + } + } +} diff --git a/src/org/kne/cloud/network/DatagramServerSocketFactory.java b/src/org/kne/cloud/network/DatagramServerSocketFactory.java new file mode 100644 index 0000000..897173c --- /dev/null +++ b/src/org/kne/cloud/network/DatagramServerSocketFactory.java @@ -0,0 +1,18 @@ +package org.kne.cloud.network; + +import java.io.IOException; +import java.net.InetAddress; +import java.net.ServerSocket; +import java.net.SocketAddress; + +public abstract class DatagramServerSocketFactory { + public DatagramServerSocket createDatagramServerSocket() throws IOException { + return new DatagramServerSocket((SocketAddress)null); + } + + public abstract DatagramServerSocket createDatagramServerSocket(int port) throws IOException; + + public abstract DatagramServerSocket createDatagramServerSocket(int port, int backlog) throws IOException; + + public abstract DatagramServerSocket createDatagramServerSocket(int port, int backlog, InetAddress ifAddress) throws IOException; +} diff --git a/src/org/kne/cloud/network/DatagramSocketFactory.java b/src/org/kne/cloud/network/DatagramSocketFactory.java new file mode 100644 index 0000000..37afb3b --- /dev/null +++ b/src/org/kne/cloud/network/DatagramSocketFactory.java @@ -0,0 +1,27 @@ +package org.kne.cloud.network; + +import java.io.IOException; +import java.net.DatagramSocket; +import java.net.InetAddress; +import java.net.Socket; +import java.net.SocketAddress; +import java.net.SocketException; +import java.net.UnknownHostException; + +import javax.net.SocketFactory; + +public abstract class DatagramSocketFactory { + public DatagramSocket createSocket() throws IOException { + return new DatagramSocket((SocketAddress)null); + } + + public abstract DatagramSocket createSocket(String paramString, int paramInt) throws IOException, UnknownHostException; + + public abstract DatagramSocket createSocket(InetAddress paramInetAddress, int paramInt) throws IOException; + + public abstract DatagramSocket createSocket(String paramString, int paramInt1, InetAddress paramInetAddress, int paramInt2) + throws IOException, UnknownHostException; + + public abstract DatagramSocket createSocket(InetAddress paramInetAddress1, int paramInt1, InetAddress paramInetAddress2, + int paramInt2) throws IOException; +} diff --git a/src/org/kne/cloud/network/DatagramSocketListener.java b/src/org/kne/cloud/network/DatagramSocketListener.java new file mode 100644 index 0000000..de9beda --- /dev/null +++ b/src/org/kne/cloud/network/DatagramSocketListener.java @@ -0,0 +1,78 @@ +package org.kne.cloud.network; + +import java.io.Closeable; +import java.io.IOException; +import java.net.DatagramSocket; +import java.net.InetAddress; +import java.net.ServerSocket; +import java.net.Socket; +import java.net.SocketException; +import java.util.function.Consumer; + +import javax.net.ServerSocketFactory; + +public class DatagramSocketListener implements Closeable,AutoCloseable{ + private DatagramServerSocket serverSocket; + public DatagramServerSocket getDatagramServerSocket() { + return serverSocket; + } + + private volatile boolean flag=true; + + private Consumercon; + private Runnable r=new Runnable() { + @Override + public void run() { + while(flag){ + try { + DatagramSocket soce=serverSocket.accept(); + ThreadTool.makeVThreadIfSupport("端口监听处理线程",()->{ + con.accept(soce); + }).start(); + }catch(SocketException e) {e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + }; + private MultipurposeSocketAddress multipurposeSocketAddress; + + public DatagramSocketListener(MultipurposeSocketAddress multipurposeSocketAddress) throws IOException { + this.multipurposeSocketAddress=multipurposeSocketAddress; + open(); + } + public DatagramSocketListener(DatagramServerSocket tserverSocket) throws IOException { + this.serverSocket=tserverSocket; + open(); + } + + private void open() throws IOException { + if(serverSocket==null) + serverSocket=multipurposeSocketAddress.listenDatagramServerSocket(); + //new Thread(r).start(); + ThreadTool.makeVThreadIfSupport("端口监听线程",r).start(); + } + public void close() { + flag=false; + if(serverSocket!=null) { + serverSocket.close(); + serverSocket=null; + } + } + + + + public MultipurposeSocketAddress getMultipurposeSocketAddress() { + return multipurposeSocketAddress; + } + + public Consumer getCon() { + return con; + } + + public void setCon(Consumer con) { + this.con = con; + } + +} diff --git a/src/org/kne/cloud/network/DefaultDatagramServerSocketFactory.java b/src/org/kne/cloud/network/DefaultDatagramServerSocketFactory.java new file mode 100644 index 0000000..96327d4 --- /dev/null +++ b/src/org/kne/cloud/network/DefaultDatagramServerSocketFactory.java @@ -0,0 +1,28 @@ +package org.kne.cloud.network; + +import java.io.IOException; +import java.net.DatagramSocket; +import java.net.InetAddress; +import java.net.UnknownHostException; + +public class DefaultDatagramServerSocketFactory extends DatagramServerSocketFactory { + + @Override + public DatagramServerSocket createDatagramServerSocket(int port) throws IOException { + return new DatagramServerSocket(port); + } + + @Override + public DatagramServerSocket createDatagramServerSocket(int port, int backlog) throws IOException { + return new DatagramServerSocket(port,backlog); + } + + @Override + public DatagramServerSocket createDatagramServerSocket(int port, int backlog, InetAddress ifAddress) + throws IOException { + return new DatagramServerSocket(port,backlog, ifAddress); + } + + + +} diff --git a/src/org/kne/cloud/network/DefaultDatagramSocketFactory.java b/src/org/kne/cloud/network/DefaultDatagramSocketFactory.java new file mode 100644 index 0000000..9cf568b --- /dev/null +++ b/src/org/kne/cloud/network/DefaultDatagramSocketFactory.java @@ -0,0 +1,41 @@ +package org.kne.cloud.network; + +import java.io.IOException; +import java.net.DatagramSocket; +import java.net.InetAddress; +import java.net.InetSocketAddress; +import java.net.UnknownHostException; + +public class DefaultDatagramSocketFactory extends DatagramSocketFactory { + + @Override + public DatagramSocket createSocket(String paramString, int paramInt) throws IOException, UnknownHostException { + DatagramSocket dg=new DatagramSocket(); + dg.connect(new InetSocketAddress(paramString, paramInt)); + return dg; + } + + @Override + public DatagramSocket createSocket(InetAddress paramInetAddress, int paramInt) throws IOException { + DatagramSocket dg=new DatagramSocket(); + dg.connect(paramInetAddress, paramInt); + return dg; + } + + @Override + public DatagramSocket createSocket(String paramString, int paramInt1, InetAddress paramInetAddress, int paramInt2) + throws IOException, UnknownHostException { + DatagramSocket dg=new DatagramSocket(new InetSocketAddress(paramInetAddress, paramInt2)); + dg.connect(new InetSocketAddress(paramString, paramInt1)); + return dg; + } + + @Override + public DatagramSocket createSocket(InetAddress paramInetAddress1, int paramInt1, InetAddress paramInetAddress2, + int paramInt2) throws IOException { + DatagramSocket dg=new DatagramSocket(new InetSocketAddress(paramInetAddress2, paramInt2)); + dg.connect(paramInetAddress1, paramInt1); + return dg; + } + +} diff --git a/src/org/kne/cloud/network/KLALBProxyConfigJsonExecuter.java b/src/org/kne/cloud/network/KLALBProxyConfigJsonExecuter.java new file mode 100644 index 0000000..ad1a2e0 --- /dev/null +++ b/src/org/kne/cloud/network/KLALBProxyConfigJsonExecuter.java @@ -0,0 +1,172 @@ +package org.kne.cloud.network; + +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.UnknownHostException; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Hashtable; +import java.util.Iterator; +import java.util.Map.Entry; + +import org.kne.cloud.network.klalb.KLALBController; +import org.kne.cloud.network.klalb.KLALBController.KLALBSocketType; +import org.kne.cloud.network.klalb.KLALBRemoteLine; +import org.kne.cloud.network.klalb.StreamKLALBPacketLink; +import org.kne.cloud.network.minecraft.KLALBJsonMotdInserter; +import org.kne.cloud.network.minecraft.MinecraftSocketToSocketProxy; + +import java.util.Set; + +import com.google.gson.JsonArray; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import com.google.gson.JsonParser; + +public class KLALBProxyConfigJsonExecuter { + private Set proxys=new HashSet<>(); + private KLALBController klalbController; + public Set getProxys() { + return proxys; + } + public KLALBController getKlalbController() { + return klalbController; + } + public KLALBProxyConfigJsonExecuter(Reader json) { + loadConfigJson(json); + } + public KLALBProxyConfigJsonExecuter(String json) { + loadConfigJson(json); + } + + public KLALBProxyConfigJsonExecuter(JsonElement json) { + loadConfigJson(json); + } + public KLALBProxyConfigJsonExecuter(File jsonFile) throws IOException { + loadConfigJson(jsonFile); + } + public KLALBProxyConfigJsonExecuter() { + } + + + + 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()); + SocketListener tcpl = null; + try { + tcpl = new SocketListener(mpsa); + + tcpl.setCon((soc)->{ + + KLALBRemoteLine krs=null; + try { + krs = new KLALBRemoteLine(new StreamKLALBPacketLink(soc)); + klalbController.addRemoteLine(krs); + } catch (IOException e) { + e.printStackTrace(); + } + + }); + } catch (IOException e1) { + e1.printStackTrace(); + } + } + JsonElement linele=entry.get("LineTable"); + if(linele!=null) { + JsonArray jary=(JsonArray)linele; + StringBuilder sb=new StringBuilder(); + jary.forEach((aline)->{ + sb.append(aline.getAsString()); + sb.append('\n'); + }); + klalbController.setSelflineTableSupplier(()->{return sb.toString();}); + } + break; + case "SocketBridge": + HostPortMap mapp=new HostPortMap(); + + MultipurposeSocketAddress l=new MultipurposeSocketAddress(entry.get("Listen").getAsString()); + MultipurposeSocketAddress r=getDefault(entry.get("Connect"),mapp); + try { + proxys.add(new SocketToSocketProxy(l ,new MultipurposeSocketAddress("0.0.0.0:0"), r,mapp)); + } catch (IOException e) { + e.printStackTrace(); + } + break; + case "MinecraftSocketBridge": + + HostPortMap mapp2=new HostPortMap(); + MultipurposeSocketAddress l2=new MultipurposeSocketAddress(entry.get("Listen").getAsString()); + MultipurposeSocketAddress r2=getDefault(entry.get("Connect"),mapp2); + try { + MinecraftSocketToSocketProxy mcp=new MinecraftSocketToSocketProxy(l2 ,new MultipurposeSocketAddress("0.0.0.0:0"), r2,mapp2); + //if(MultipurposeSocketAddress.getSocketTypeRegister().get( l2.getType()) instanceof KLALBSocketType ) + mcp.getTransformersBA().add(new KLALBJsonMotdInserter(()->{return klalbController.getSelf();},()->{return 23332;})); + proxys.add(mcp); + } catch (IOException e) { + e.printStackTrace(); + } + break; + + default: + break; + } + } + private MultipurposeSocketAddress getDefault(JsonElement jsonElement, HostPortMap 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()); + } + } +} diff --git a/src/org/kne/cloud/network/ProxyProfileAnalyser.java b/src/org/kne/cloud/network/ProxyProfileAnalyser.java deleted file mode 100644 index ff55fb3..0000000 --- a/src/org/kne/cloud/network/ProxyProfileAnalyser.java +++ /dev/null @@ -1,63 +0,0 @@ -package org.kne.cloud.network.mport; - -import java.io.File; -import java.io.FileNotFoundException; -import java.io.InputStream; -import java.util.*; - -public class ProxyProfileAnalyser { - private Listentrys=new ArrayList(); - public List getEntrys() { - return entrys; - } - public ProxyProfileAnalyser(InputStream f) { - Scanner sr=new Scanner(f); - analyse(sr); - } - public ProxyProfileAnalyser(File f) throws FileNotFoundException { - Scanner sr=new Scanner(f); - analyse(sr); - } - public ProxyProfileAnalyser(String s) { - Scanner sr=new Scanner(s); - analyse(sr); - } - private void analyse(Scanner sr) { - int n=0; - while(sr.hasNext()) { - String sl=sr.nextLine().trim(); - int x=sl.indexOf("//"); - if(x!=-1) - sl=sl.substring(0, x); - n++; - if(sl.isEmpty()) { - continue; - } - String[] sp=sl.split("->"); - if(sp.length!=2) { - throw new IllegalArgumentException("Format error at line "+n); - } - String l=sp[0].trim(); - String r=sp[1].trim(); - //System.out.println(l+" "+r); - if(l.contains(":")) { - if(r.contains(":")){ - SocketToSocketProxyProfileEntry sts=new SocketToSocketProxyProfileEntry(l,r); - entrys.add(sts); - - }else { - SocketToServiceProxyProfileEntry sts=new SocketToServiceProxyProfileEntry(l,r); - entrys.add(sts); - } - }else { - if(r.contains(":")) { - ServiceToSocketProxyProfileEntry sts=new ServiceToSocketProxyProfileEntry(l,r); - entrys.add(sts); - }else { - - } - } - } - } - -} diff --git a/src/org/kne/cloud/network/ProxyProfileExecutor.java b/src/org/kne/cloud/network/ProxyProfileExecutor.java deleted file mode 100644 index 66d66c0..0000000 --- a/src/org/kne/cloud/network/ProxyProfileExecutor.java +++ /dev/null @@ -1,57 +0,0 @@ -package org.kne.cloud.network.mport; - -import java.io.File; -import java.io.FileNotFoundException; -import java.io.InputStream; -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; - -public class ProxyProfileExecutor { - private Listcurrent=new ArrayList<>(); - - public List getCurrent() { - return current; - } - public void applyNewProxyList(Listl) { - for (Iterator iterator = l.iterator(); iterator.hasNext();) { - ProxyProfileEntry proxyProfileEntry = (ProxyProfileEntry) iterator.next(); - if(!current.contains(proxyProfileEntry)) { - if(proxyProfileEntry instanceof SocketToSocketProxyProfileEntry) { - SocketToSocketProxyProfileEntry stsppe=(SocketToSocketProxyProfileEntry) proxyProfileEntry; - }else if(proxyProfileEntry instanceof SocketToServiceProxyProfileEntry){ - SocketToServiceProxyProfileEntry stsppe=(SocketToServiceProxyProfileEntry) proxyProfileEntry; - stsppe.getDes().listen(stsppe.getSrc()); - }else if(proxyProfileEntry instanceof ServiceToSocketProxyProfileEntry) { - ServiceToSocketProxyProfileEntry stsppe=(ServiceToSocketProxyProfileEntry) proxyProfileEntry; - stsppe.getSrc().connect(stsppe.getDes()); - } - } - } - for (Iterator iterator = current.iterator(); iterator.hasNext();) { - ProxyProfileEntry proxyProfileEntry = (ProxyProfileEntry) iterator.next(); - if(!l.contains(proxyProfileEntry)) { - if(proxyProfileEntry instanceof SocketToSocketProxyProfileEntry) { - SocketToSocketProxyProfileEntry stsppe=(SocketToSocketProxyProfileEntry) proxyProfileEntry; - }else if(proxyProfileEntry instanceof SocketToServiceProxyProfileEntry){ - SocketToServiceProxyProfileEntry stsppe=(SocketToServiceProxyProfileEntry) proxyProfileEntry; - stsppe.getDes().unlisten(stsppe.getSrc()); - }else if(proxyProfileEntry instanceof ServiceToSocketProxyProfileEntry) { - ServiceToSocketProxyProfileEntry stsppe=(ServiceToSocketProxyProfileEntry) proxyProfileEntry; - stsppe.getSrc().unconnect(stsppe.getDes()); - } - } - } - current.clear(); - current.addAll(l); - } - public void load(File f) throws FileNotFoundException { - applyNewProxyList(new ProxyProfileAnalyser(f).getEntrys()); - } - public void load(String s) { - applyNewProxyList(new ProxyProfileAnalyser(s).getEntrys()); - } - public void load(InputStream in) { - applyNewProxyList(new ProxyProfileAnalyser(in).getEntrys()); - } -} diff --git a/src/org/kne/cloud/network/SocketType.java b/src/org/kne/cloud/network/SocketType.java new file mode 100644 index 0000000..2cec2ce --- /dev/null +++ b/src/org/kne/cloud/network/SocketType.java @@ -0,0 +1,52 @@ +package org.kne.cloud.network; + +import java.net.DatagramSocket; + +import javax.net.ServerSocketFactory; +import javax.net.SocketFactory; + +public class SocketType { + private SocketFactory socketFactory; + private ServerSocketFactory serverSocketFactory; + private DatagramSocketFactory datagramSocketFactory; + private DatagramServerSocketFactory datagramServerSocketFactory; + private boolean stream; + + public SocketFactory getSocketFactory() { + return socketFactory; + } + + public ServerSocketFactory getServerSocketFactory() { + return serverSocketFactory; + } + + public DatagramSocketFactory getDatagramSocketFactory() { + return datagramSocketFactory; + } + + + public DatagramServerSocketFactory getDatagramServerSocketFactory() { + return datagramServerSocketFactory; + } + + public SocketType(SocketFactory socketFactory, ServerSocketFactory serverSocketFactory) { + super(); + this.socketFactory = socketFactory; + this.serverSocketFactory = serverSocketFactory; + this.stream=true; + } + + public SocketType(DatagramSocketFactory datagramSocketFactory, + DatagramServerSocketFactory datagramServerSocketFactory) { + super(); + this.datagramSocketFactory = datagramSocketFactory; + this.datagramServerSocketFactory = datagramServerSocketFactory; + this.stream=false; + } + + public boolean isStream() { + return stream; + } + + +} diff --git a/src/org/kne/cloud/network/frpc/FrpcIni.java b/src/org/kne/cloud/network/frpc/FrpcIni.java new file mode 100644 index 0000000..d47d0c4 --- /dev/null +++ b/src/org/kne/cloud/network/frpc/FrpcIni.java @@ -0,0 +1,233 @@ +package org.kne.cloud.network.frpc; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.io.Reader; +import java.io.StringReader; +import java.io.StringWriter; +import java.net.URL; + +import org.ini4j.Ini; +import org.ini4j.InvalidFileFormatException; + +public class FrpcIni extends Ini { + + public FrpcIni() { + super(); + } + + public FrpcIni(File input) throws IOException, InvalidFileFormatException { + super(input); + // TODO 自动生成的构造函数存根 + } + + public FrpcIni(InputStream input) throws IOException, InvalidFileFormatException { + super(input); + // TODO 自动生成的构造函数存根 + } + + public FrpcIni(Reader input) throws IOException, InvalidFileFormatException { + super(input); + // TODO 自动生成的构造函数存根 + } + + public FrpcIni(URL input) throws IOException, InvalidFileFormatException { + super(input); + // TODO 自动生成的构造函数存根 + } + + public FrpcIni(String str) throws InvalidFileFormatException { + this(); + loadFromString(str); + } + + public void setServerAddr(String addr) { + add("common", "server_addr", addr); + } + + public String getServerAddr() { + return get("common", "server_addr"); + } + + public void setToken(String addr) { + add("common", "token", addr); + } + + public String getToken() { + return get("common", "token"); + } + + public void setProtocol(String protocol) { + add("common", "protocol", protocol); + } + + public String getProtocol() { + return get("common", "protocol"); + } + + public void setServerPort(int port) { + add("common", "server_port", port); + } + + public int getServerPort() { + return get("common", "server_port", int.class); + } + + public void setDnsServer(String dns) { + add("common", "dns_server", dns); + } + + public String getDnsServer() { + return get("common", "dns_server"); + } + public void setConnectServerLocalIp(String connectserverlocalip) { + add("common", "connect_server_local_ip", connectserverlocalip); + } + + public String getConnectServerLocalIp() { + return get("common", "connect_server_local_ip"); + } + + public void setUser(String user) { + add("common", "user", user); + } + + public String getUser() { + return get("common", "user"); + } + + public void setTcpMux(boolean tcpmux) { + add("common", "tcp_mux", tcpmux); + } + + public boolean getTcpMux() { + return get("common", "tcp_mux",boolean.class); + } + + public void setTlsEnable(boolean tlsenable) { + add("common", "tls_enable", tlsenable); + } + + public boolean getTlsEnable() { + return get("common", "tls_enable",boolean.class); + } + + + + + + + + + + + + + public void setType(String tunnel,String type) { + add(tunnel, "type", type); + } + + public String getType(String tunnel) { + return get(tunnel, "type"); + } + public void setLocalIP (String tunnel,String localip) { + add(tunnel, "local_ip", localip); + } + + public String getLocalIP(String tunnel) { + return get(tunnel, "local_ip"); + } + public void setLocalPort (String tunnel,int localport) { + add(tunnel, "local_port", localport); + } + + public int getLocalPort(String tunnel) { + return get(tunnel, "local_port",int.class); + } + public void setRemotePort (String tunnel,int remoteport) { + add(tunnel, "remote_port", remoteport); + } + + public int getRemotePort(String tunnel) { + return get(tunnel, "remote_port",int.class); + } + public void setUseEncryption (String tunnel,boolean useencryption) { + add(tunnel, "use_encryption", useencryption); + } + + public boolean getUseEncryption(String tunnel) { + return get(tunnel, "use_encryption",boolean.class); + } + public void setUseCompression (String tunnel,boolean usecompression) { + add(tunnel, "use_compression", usecompression); + } + + public boolean getUseCompression(String tunnel) { + return get(tunnel, "use_compression",boolean.class); + } + public void setSk(String tunnel,String sk) { + add(tunnel, "sk", sk); + } + + public String getSk(String tunnel) { + return get(tunnel, "sk"); + } + public void setRole(String tunnel,String sk) { + add(tunnel, "role", sk); + } + + public String getRole(String tunnel) { + return get(tunnel, "role"); + } + public void setServerName(String tunnel,String servername) { + add(tunnel, "server_name", servername); + } + + public String getServerName(String tunnel) { + return get(tunnel, "server_name"); + } + + public void setBindAddr(String tunnel,String bindaddr) { + add(tunnel, "bind_addr", bindaddr); + } + + public String getBindAddr(String tunnel) { + return get(tunnel, "bind_addr"); + } + public void setBindPort (String tunnel,int bindport) { + add(tunnel, "bind_port", bindport); + } + + public int getBindPort(String tunnel) { + return get(tunnel, "bind_port",int.class); + } + public void setKeepTunnelOpen (String tunnel,boolean keeptunnelopen) { + add(tunnel, "keep_tunnel_open", keeptunnelopen); + } + + public boolean getKeepTunnelOpen(String tunnel) { + return get(tunnel, "keep_tunnel_open",boolean.class); + } + + + public String storeToString() { + StringWriter sw = new StringWriter(); + try { + store(sw); + } catch (IOException e) { + e.printStackTrace(); + } + return sw.toString(); + } + + public void loadFromString(String ini) throws InvalidFileFormatException { + try { + load(new StringReader(ini)); + } catch (InvalidFileFormatException e) { + throw e; + } catch (IOException e) { + e.printStackTrace(); + } + } +} diff --git a/src/org/kne/cloud/network/frpc/FrpcProcess.java b/src/org/kne/cloud/network/frpc/FrpcProcess.java new file mode 100644 index 0000000..f109bc5 --- /dev/null +++ b/src/org/kne/cloud/network/frpc/FrpcProcess.java @@ -0,0 +1,245 @@ +package org.kne.cloud.network.frpc; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.OutputStream; +import java.io.PrintStream; +import java.io.PrintWriter; +import java.lang.ProcessHandle.Info; +import java.net.BindException; +import java.net.ConnectException; +import java.net.SocketException; +import java.net.UnknownHostException; +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.atomic.AtomicReference; +import java.util.stream.Stream; + +public class FrpcProcess extends Process{ + private static File defaultBase=new File("frpc"); + + private volatile Thread hook; + + public static File getDefaultBase() { + return defaultBase; + } + public static void setDefaultBase(File defaultBase) { + FrpcProcess.defaultBase = defaultBase; + } + private File base; + private File exe; + private Process theProcess; + + public FrpcProcess(String ini) throws IOException { + this(defaultBase,ini); + + } + public FrpcProcess(File base,String ini) throws IOException { + this.base=base; + if(System.getProperty("os.name").toLowerCase().contains("windows")) { + exe=new File(base,"frpc_windows_amd64.exe"); + }else { + exe=new File(base,"frpc_linux_amd64"); + } + File f=new File(base,"frpc_conf.ini"); + f.createNewFile(); + PrintWriter ps=null; + try { + ps=new PrintWriter(f); + ps.println(ini); + }finally { + if(ps!=null) + ps.close(); + } + Listlstc=new ArrayList<>(); + lstc.add(exe.getAbsolutePath()); + lstc.add("-c"); + lstc.add(f.getName()); + ProcessBuilder psb=new ProcessBuilder(lstc); + psb.directory(base); + theProcess=psb.start(); + AtomicReferencearex=new AtomicReference(); + Thread t=Thread.currentThread(); + new Thread(()->{ + BufferedReader br=new BufferedReader(new InputStreamReader(theProcess.getInputStream())); + + try { + while(true) { + String s=br.readLine(); + if(s==null) { + break; + } + System.out.println (s); + if(s.contains("start proxy success")) { + t.interrupt(); + }else if(s.contains("port already used")){ + arex.set(new BindException("port on server already used")); + t.interrupt(); + }else if(s.contains("no such host")) { + arex.set(new UnknownHostException("no such host")); + t.interrupt(); + }else if(s.contains("connection write timeout")) { + arex.set(new ConnectException("connection write timeout")); + t.interrupt(); + }else if(s.contains("already exists")&&s.contains("proxy")) { + arex.set(new BindException("proxy already exists")); + t.interrupt(); + } + } + } catch (IOException e) { + e.printStackTrace(); + }finally { + try { + br.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + + }).start(); + try { + if(theProcess.waitFor(20000, TimeUnit.MILLISECONDS)) { + destroy(); + throw new SocketException("Frpc exit code:"+theProcess.exitValue()); + }else { + destroy(); + throw new SocketException("Frpc timed out"); + } + } catch (InterruptedException e) { + if(arex.get()!=null) { + destroy(); + arex.get().fillInStackTrace(); + throw arex.get(); + } + }finally { + Thread.interrupted(); + } + hook=new Thread(()->{ + try { + hook=null; + finalize(); + } catch (Throwable e) { + e.printStackTrace(); + } + }); + Runtime.getRuntime().addShutdownHook(hook); + } + public File getBase() { + return base; + } + @Override + public OutputStream getOutputStream() { + return theProcess.getOutputStream(); + } + @Override + public InputStream getInputStream() { + return theProcess.getInputStream(); + } + @Override + public InputStream getErrorStream() { + return theProcess.getErrorStream(); + } + @Override + public int waitFor() throws InterruptedException { + return theProcess.waitFor(); + } + @Override + public int exitValue() { + return theProcess.exitValue(); + } + @Override + public void destroy() { + theProcess.destroy(); + //System.out.println("frpc已关闭"); + if(hook!=null) { + Runtime.getRuntime().removeShutdownHook(hook); + } + } + @Override + public boolean waitFor(long timeout, TimeUnit unit) throws InterruptedException { + return theProcess.waitFor(timeout, unit); + } + @Override + public Process destroyForcibly() { + Process b= theProcess.destroyForcibly(); + //System.out.println("frpc已关闭"); + if(hook!=null) { + Runtime.getRuntime().removeShutdownHook(hook); + } + return b; + } + @Override + public boolean supportsNormalTermination() { + return theProcess.supportsNormalTermination(); + } + @Override + public boolean isAlive() { + return theProcess.isAlive(); + } + @Override + public long pid() { + return theProcess.pid(); + } + @Override + public CompletableFuture onExit() { + return theProcess.onExit(); + } + @Override + public ProcessHandle toHandle() { + return theProcess.toHandle(); + } + @Override + public Info info() { + return theProcess.info(); + } + @Override + public Stream children() { + return theProcess.children(); + } + @Override + public Stream descendants() { + return theProcess.descendants(); + } + public static void main(String[] args) throws IOException { + String str=""" + [common] +server_addr = us.afrps.cn +server_port = 7000 +token = afrps.cn +protocol=kcp +[test5] +type = tcp +local_ip = 127.0.0.1 +local_port = 7461 +remote_port = 49966 +use_encryption = true +use_compression = true + """; + FrpcIni fi=new FrpcIni(str); + + str=fi.storeToString(); + //System.out.println(fi.getServerPort()); + FrpcProcess fp=new FrpcProcess(str); + try { + Thread.sleep(10000); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + @Override + protected void finalize() throws Throwable { + + if(theProcess!=null) { + destroy(); + } + } +} diff --git a/src/org/kne/cloud/network/frpc/FrpcServerSocket.java b/src/org/kne/cloud/network/frpc/FrpcServerSocket.java new file mode 100644 index 0000000..70dddae --- /dev/null +++ b/src/org/kne/cloud/network/frpc/FrpcServerSocket.java @@ -0,0 +1,158 @@ +package org.kne.cloud.network.frpc; + +import java.io.IOException; +import java.net.InetAddress; +import java.net.InetSocketAddress; +import java.net.ServerSocket; +import java.net.Socket; +import java.net.SocketAddress; +import java.net.SocketImpl; +import java.net.UnknownHostException; +import java.util.Iterator; +import java.util.Map.Entry; + +import org.ini4j.Profile.Section; +import org.kne.cloud.network.MultipurposeSocketAddress; + +public class FrpcServerSocket extends ServerSocket { + private FrpcProcess frpc; + private FrpcIni frpcini; + private String tunnel; + public FrpcServerSocket() throws IOException { + super(); + } + + public FrpcServerSocket(FrpcIni fi, int port, int backlog, InetAddress bindAddr) throws IOException { + super(); + this.frpcini=fi; + if (port < 0 || port > 0xFFFF) + throw new IllegalArgumentException("Port value out of range: " + port); + if (backlog < 1) + backlog = 50; + + try { + bind(new InetSocketAddress(bindAddr, port), backlog); + } catch (IOException | SecurityException e) { + close(); + throw e; + } + } + + public FrpcServerSocket(FrpcIni fi,int port, int backlog) throws IOException { + this(fi,port, backlog, null); + } + + public FrpcServerSocket(FrpcIni fi,int port) throws IOException { + this(fi,port, 50, null); + } + public FrpcServerSocket(FrpcIni fi) throws IOException { + this(fi,0, 50, null); + } + protected FrpcServerSocket(SocketImpl impl) { + super(impl); + } + + @Override + public void bind(SocketAddress endpoint) throws IOException { + bind(endpoint, 50); + } + + + public String getTunnelHost() { + if (!isBound()) + return null; + return frpcini.getServerAddr(); + } + public InetAddress getTunnelInetAddress() throws UnknownHostException { + if (!isBound()) + return null; + return InetAddress.getByName( frpcini.getServerAddr()); + } + + public int getTunnelPort() { + if (!isBound()) + return -1; + return frpcini.getRemotePort(tunnel); + } + + public MultipurposeSocketAddress getTunnelSocketAddress() { + if (!isBound()) + return null; + return new MultipurposeSocketAddress(frpcini.getType(tunnel).toUpperCase(),getTunnelHost(), getTunnelPort()); + } + + @Override + public void bind(SocketAddress endpoint, int backlog) throws IOException { + if(frpcini!=null) { + if(tunnel==null) { + var e=frpcini.keySet(); + for (Iterator iterator = e.iterator(); iterator.hasNext();) { + String key = iterator.next(); + if(!key.equals("common")) { + tunnel=key; + break; + } + } + if(tunnel==null) { + throw new IllegalArgumentException("cant found avaliable tunnel!"); + } + } + super.bind(endpoint, backlog); + InetAddress iad=((InetSocketAddress) endpoint).getAddress(); + frpcini.setLocalIP(tunnel,iad.isAnyLocalAddress()?"127.0.0.1": iad.getHostAddress()); + frpcini.setLocalPort(tunnel, getLocalPort()); + frpcini.setConnectServerLocalIp(((InetSocketAddress)endpoint).getAddress().getHostAddress()); + frpc=new FrpcProcess(frpcini.storeToString()); + }else { + super.bind(endpoint, backlog); + } + } + + public FrpcIni getFrpcini() { + return frpcini; + } + + public void setFrpcini(FrpcIni frpcini) { + this.frpcini = frpcini; + } + + public String getTunnel() { + return tunnel; + } + + public void setTunnel(String tunnel) { + this.tunnel = tunnel; + } + + @Override + public void close() throws IOException { + if(frpc!=null) { + frpc.destroy(); + } + super.close(); + } + /*public MultipurposeSocketAddress getTunnelRemoteSocketAddress() { + return new MultipurposeSocketAddress(frpcini.getType(tunnel).toUpperCase(), frpcini.getServerAddr(), frpcini.getRemotePort(tunnel)); + }*/ + public static void main(String[] args) throws IOException { + + String str=""" + [common] +server_addr = us.afrps.cn +server_port = 7000 +token = afrps.cn +protocol=kcp +[test5] +type = tcp +local_ip = 127.0.0.1 +local_port = 7461 +remote_port = 49966 +use_encryption = true +use_compression = true + """; + FrpcIni fi=new FrpcIni(str); + FrpcServerSocket fss= new FrpcServerSocket(fi); + System.out.println(fss.getTunnelSocketAddress()); + System.out.println(fss.accept()); + } +} diff --git a/src/org/kne/cloud/network/klalb/BindableKLALBPacketConsumer.java b/src/org/kne/cloud/network/klalb/BindableKLALBPacketConsumer.java new file mode 100644 index 0000000..95b9a98 --- /dev/null +++ b/src/org/kne/cloud/network/klalb/BindableKLALBPacketConsumer.java @@ -0,0 +1,12 @@ +package org.kne.cloud.network.klalb; + +import java.net.InetAddress; +import java.net.ServerSocket; + +public interface BindableKLALBPacketConsumer extends KLALBPacketConsumer { + public InetAddress getRemoteInetAddress() ; + public InetAddress getLocalInetAddress() ; + public int getPort() ; + public int getLocalPort(); + public void setLocalPort(int i); +} diff --git a/src/org/kne/cloud/network/klalb/CONST.java b/src/org/kne/cloud/network/klalb/CONST.java new file mode 100644 index 0000000..396ed3b --- /dev/null +++ b/src/org/kne/cloud/network/klalb/CONST.java @@ -0,0 +1,6 @@ +package org.kne.cloud.network.klalb; + +public class CONST { + public static String klalb="KLALB"; + public static String klalbver="2.2"; +} diff --git a/src/org/kne/cloud/network/klalb/DatagramKLALBPacketLink.java b/src/org/kne/cloud/network/klalb/DatagramKLALBPacketLink.java new file mode 100644 index 0000000..a0b305d --- /dev/null +++ b/src/org/kne/cloud/network/klalb/DatagramKLALBPacketLink.java @@ -0,0 +1,68 @@ +package org.kne.cloud.network.klalb; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; +import java.net.DatagramPacket; +import java.net.DatagramSocket; +import java.net.SocketException; + +public class DatagramKLALBPacketLink implements KLALBPacketLink { + + @Override + public String toString() { + return "DatagramKLALBPacketLink [ds=" + ds + "]"; + } + + private DatagramSocket ds; + + public DatagramKLALBPacketLink(DatagramSocket connectDatagramSocket) throws IOException { + this.ds=connectDatagramSocket; + } + + private ByteArrayOutputStream bos=new ByteArrayOutputStream(65535); + private DataOutputStream dos=new DataOutputStream(bos); + @Override + public void writePacket(KLALBPacket kp) throws IOException { + //System.out.println(" TX:"+kp); + bos.reset(); + KLALBOutputStream.writeKLALBPacketToStream(dos, kp); + byte[]bt=bos.toByteArray(); + DatagramPacket dp=new DatagramPacket(bt,bt.length); + ds.send(dp); + } + + private byte[]bc=new byte[65535]; + @Override + public KLALBPacket readPacket() throws IOException { + DatagramPacket dp=new DatagramPacket(bc, bc.length); + ds.receive(dp); + DataInputStream dis=new DataInputStream(new ByteArrayInputStream(bc, 0, dp.getLength())); + KLALBPacket kp=KLALBInputStream.readKLALBPacketFromStream(dis); + dis.close(); + //System.out.println(" RX:"+kp); + return kp; + } + + @Override + public void close() throws IOException { + ds.close(); + } + + @Override + public boolean isClosed() { + return ds.isClosed(); + } + + @Override + public void setSoTimeout(int val) throws SocketException { + ds.setSoTimeout(val); + } + + @Override + public int getSoTimeout() throws SocketException { + return ds.getSoTimeout(); + } +} diff --git a/src/org/kne/cloud/network/klalb/KLALBPacketConsumer.java b/src/org/kne/cloud/network/klalb/KLALBPacketConsumer.java new file mode 100644 index 0000000..4021a84 --- /dev/null +++ b/src/org/kne/cloud/network/klalb/KLALBPacketConsumer.java @@ -0,0 +1,7 @@ +package org.kne.cloud.network.klalb; + +import java.util.function.BiConsumer; + +public interface KLALBPacketConsumer extends BiConsumer { + +} diff --git a/src/org/kne/cloud/network/klalb/KLALBPacketLink.java b/src/org/kne/cloud/network/klalb/KLALBPacketLink.java new file mode 100644 index 0000000..c47e8a0 --- /dev/null +++ b/src/org/kne/cloud/network/klalb/KLALBPacketLink.java @@ -0,0 +1,13 @@ +package org.kne.cloud.network.klalb; + +import java.io.IOException; +import java.net.SocketException; + +public interface KLALBPacketLink { + public void writePacket(KLALBPacket kp) throws IOException; + public KLALBPacket readPacket()throws IOException; + public void close() throws IOException; + public boolean isClosed(); + public void setSoTimeout(int val) throws SocketException; + public int getSoTimeout() throws SocketException; +} diff --git a/src/org/kne/cloud/network/klalb/KLALBProtocolDetectSocketListener.java b/src/org/kne/cloud/network/klalb/KLALBProtocolDetectSocketListener.java new file mode 100644 index 0000000..2b97d33 --- /dev/null +++ b/src/org/kne/cloud/network/klalb/KLALBProtocolDetectSocketListener.java @@ -0,0 +1,97 @@ +package org.kne.cloud.network.klalb; + +import java.io.IOException; +import java.net.ServerSocket; +import java.net.Socket; +import java.net.UnknownHostException; +import java.util.function.Consumer; + +import org.kne.cloud.network.KLALBDetectorItem; +import org.kne.cloud.network.MultipurposeSocketAddress; +import org.kne.cloud.network.ProtocolDetector; +import org.kne.cloud.network.ProtocolDetectorServerSocket; +import org.kne.cloud.network.ProtocolDetectorSocket; +import org.kne.cloud.network.SocketListener; + +public class KLALBProtocolDetectSocketListener extends SocketListener { + + private volatile Consumer conx; + private KLALBController klalbController; + + @Override + protected void open() throws UnknownHostException, IOException { + if(serverSocket==null) + serverSocket=getMultipurposeSocketAddress().listenServerSocket(); + if(!(serverSocket instanceof ProtocolDetectorServerSocket)) { + ProtocolDetector pd=new ProtocolDetector(); + pd.add(new KLALBDetectorItem()); + serverSocket=new ProtocolDetectorServerSocket(serverSocket,pd); + } + super.open(); + } + + public KLALBProtocolDetectSocketListener(MultipurposeSocketAddress multipurposeSocketAddress,KLALBController klalbc) throws IOException { + super(multipurposeSocketAddress); + this.klalbController=klalbc; + } + + public KLALBProtocolDetectSocketListener(ServerSocket tserverSocket,KLALBController klalbc) throws IOException { + super(tserverSocket); + this.klalbController=klalbc; + } + { + + super.setCon((soc)->{ + ProtocolDetectorSocket pds=(ProtocolDetectorSocket) soc; + if(!pds.getProtocolStack().isEmpty()&&pds.getProtocolStack().pop().getName().equals("KLALB")) { + KLALBRemoteLine krs=null; + try { + krs = new KLALBRemoteLine(new StreamKLALBPacketLink(pds)); + klalbController.addRemoteLine(krs); + } catch (Exception e) { + e.printStackTrace(); + try { + soc.close(); + } catch (IOException e1) { + e1.printStackTrace(); + } + + } + }else { + if(conx!=null) { + try { + conx.accept(soc); + } catch (Exception e) { + e.printStackTrace(); + try { + soc.close(); + } catch (IOException e1) { + e1.printStackTrace(); + } + + } + }else { + try { + soc.close(); + } catch (IOException e1) { + e1.printStackTrace(); + } + } + } + }); + } + @Override + public Consumer getCon() { + return conx; + } + + @Override + public void setCon(Consumer conx) { + this.conx=conx; + } + + public KLALBController getKlalbController() { + return klalbController; + } + +} diff --git a/src/org/kne/cloud/network/klalb/KLALBRemoteLine.java b/src/org/kne/cloud/network/klalb/KLALBRemoteLine.java new file mode 100644 index 0000000..e3abf54 --- /dev/null +++ b/src/org/kne/cloud/network/klalb/KLALBRemoteLine.java @@ -0,0 +1,502 @@ +package org.kne.cloud.network.klalb; + +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.PrintStream; +import java.io.PrintWriter; +import java.net.BindException; +import java.net.Inet6Address; +import java.net.InetAddress; +import java.net.InetSocketAddress; +import java.net.Socket; +import java.net.SocketTimeoutException; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.UUID; +import java.util.Vector; +import java.util.concurrent.ConcurrentLinkedQueue; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.atomic.AtomicLong; +import java.util.concurrent.atomic.AtomicReference; +import java.util.concurrent.locks.LockSupport; +import java.util.function.BiConsumer; +import java.util.function.Consumer; +import java.util.function.Supplier; + +import org.kne.cloud.network.MultipurposeSocketAddress; +import org.kne.cloud.network.ThreadTool; + +public class KLALBRemoteLine implements Comparable{ + + + private volatile boolean closed=false; + + private volatile Supplier localVaddrSupplier; + + public Supplier getLocalVaddrSupplier() { + return localVaddrSupplier; + } + + public void setLocalVaddrSupplier(Supplier localVaddrSupplier) { + this.localVaddrSupplier = localVaddrSupplier; + } + + + private volatile Inet6Address remoteVaddr; + public Inet6Address getRemoteVaddr() throws SocketTimeoutException { + return remoteVaddr; + } + + public void waitForRemoteVaddrAvaliable(long timeout) throws SocketTimeoutException { + long s=System.nanoTime(); + while(remoteVaddr==null) { + + try { + Thread.sleep(1); + } catch (InterruptedException e) { + e.printStackTrace(); + } + if(System.nanoTime()-s>timeout*1000000) + throw new SocketTimeoutException(); + } + } + + public Monitor getMonitor() { + return monitor; + } + public String toString() { + return remoteVaddr+"\t"+monitor.toString()+"\t"+sumNextPacketCount(); + } + + public String toString2() { + return remoteVaddr+"\t"+monitor.toString2(); + } + private Monitor monitor; + private volatile KLALBPacketLink kplink; + private MultipurposeSocketAddress bindAddress; + private MultipurposeSocketAddress socketAddress; + + private Thread lthd; + + + public void setKplink(KLALBPacketLink kplink) { + this.kplink = kplink; + } + + public KLALBPacketLink getKplink() { + return kplink; + } + + + public MultipurposeSocketAddress getSocketAddress() { + return socketAddress; + } + + + + public MultipurposeSocketAddress getBindAddress() { + return bindAddress; + } + + protected static KLALBPacketLink createLink(MultipurposeSocketAddress bindAddress,MultipurposeSocketAddress mpa) throws IOException { + if(mpa.isStream()) { + if(bindAddress!=null) { + return new StreamKLALBPacketLink(mpa.connectSocket(InetAddress.getByName( bindAddress.getHost()),bindAddress.getPort())); + }else { + return new StreamKLALBPacketLink(mpa.connectSocket()); + } + } + else { + if(bindAddress!=null) { + return new DatagramKLALBPacketLink(mpa.connectDatagramSocket(InetAddress.getByName( bindAddress.getHost()),bindAddress.getPort())); + }else { + return new DatagramKLALBPacketLink(mpa.connectDatagramSocket()); + } + } + } + public KLALBRemoteLine(MultipurposeSocketAddress mpa) { + this(mpa,new Monitor()); + } + public KLALBRemoteLine(MultipurposeSocketAddress mpa,Monitor monitor) { + this(mpa,null,monitor); + } + public KLALBRemoteLine(KLALBPacketLink kpl) { + this(kpl,new Monitor()); + } + public KLALBRemoteLine(KLALBPacketLink kpl,Monitor monitor) { + this.kplink=kpl; + this.monitor=monitor; + monitor.setName(kpl.toString()); + } + + public KLALBRemoteLine(MultipurposeSocketAddress mpa,MultipurposeSocketAddress bindaddr,Monitor monitor ) { + this.socketAddress=mpa; + this.bindAddress=bindaddr; + this.monitor=monitor; + monitor.setName(mpa.toString()); + } + + public KLALBRemoteLine(MultipurposeSocketAddress mpa, MultipurposeSocketAddress bindaddr) { + this(mpa,bindaddr,new Monitor()); + } + PrintStream pw; + private void startRecord() { + try { + pw=new PrintStream(UUID.randomUUID()+".csv"); + + pw.println("时间,状态,上传速度,下载速度,上传延迟,下载延迟,往返延迟,抖动"); + ThreadTool.makePDaemonThreadIfSupport("BigData Record", ()->{ + while(true) { + try { + Thread.sleep(1000); + } catch (InterruptedException e) { + e.printStackTrace(); + } + pw.println(System.currentTimeMillis()+","+monitor.getState()+","+monitor.getOutSpeedAvg()+","+monitor.getInSpeedAvg()+","+sndDelayFactor+","+rcvDelayFactor+","+monitor.getLatencyAvg()+","+monitor.getJitter()); + } + }).start(); + } catch (FileNotFoundException e) { + e.printStackTrace(); + } + } + + private void endRecord() { + if(pw!=null) + pw.close(); + } + + protected void startIO() { + ThreadTool.makePDaemonThreadIfSupport("远程接收线程", () -> { + //startRecord(); + while(true) { + try { + + monitor.setState(Monitor.CONNECTING); + if(socketAddress==null) { + if(kplink.isClosed()) { + monitor.setState(Monitor.OFFLINE); + closed=true; + break; + } + }else { + try { + kplink=createLink(bindAddress,socketAddress); + }catch(BindException be){ + //be.printStackTrace(); + close(); + throw be; + } + } + kplink.setSoTimeout(10000); + Thread t=ThreadTool.makePDaemonThreadIfSupport("远程发送线程", () -> { + try { + writePacketToKPL(new VADDRREQPacket()); + writePacketToKPL(new VADDRREQPacket()); + writePacketToKPL(new VADDRREQPacket()); + while ((!kplink.isClosed())&&(!closed)) { + if(checkPingTime()) { + writePacketToKPL(new PINGPacket(System.nanoTime())); + }else { + KLALBPacket kpp=getNextPacket(); + long lth=statLengthBefore(10); + if(lth>65536*2) { + monitor.updateOutSpeedMax(); + } + if(kpp!=null) { + pingInterval= 100000000L; + writePacketToKPL(kpp); + }else { + pingInterval=1000000000L; + tlock=Thread.currentThread(); + LockSupport.parkNanos(1000000); + } + } + Thread.yield(); + } + } catch (IOException e) { + e.printStackTrace(); + } finally { + try { + kplink.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + }); + t.start(); + boolean fst=true; + long stime=5000000000L; + while ((!kplink.isClosed())&&(!closed)) { + long readStart=System.nanoTime(); + KLALBPacket kpp = readPacketFromKPL(); + long readTime=System.nanoTime()-readStart; + if(readTime>stime) { + stime=readTime; + }else { + stime=(stime*99+readTime)/100; + } + if(stime<3000000000L) { + stime=3000000000L; + } + + //System.out.println(readTime); + kplink.setSoTimeout((int) (stime/1000000)); + if(kpp==null) + break; + switch (kpp.getType()) { + case KLALBPacket.PING: + sendPacket(new PONGPacket(((PINGPacket) kpp).getTime(),kpp.getRcvtime(),System.nanoTime()), -1); + break; + case KLALBPacket.PONG: + PONGPacket png=(PONGPacket) kpp; + long ul=png.getRcvtime()-( png.getTimepingsnd()+(png.getTimepongsnd()-png.getTimepingrcv())); + //System.out.println(toString()+"\t"+ul); + monitor.updateLatency (ul); + long DsndDelayFactor=png.getTimepingrcv()- png.getTimepingsnd(); + long DrcvDelayFactor=png.getRcvtime()- png.getTimepongsnd(); + //sndDelayFactor=DsndDelayFactor; + //rcvDelayFactor=DrcvDelayFactor; + if(sndDelayFactor==Long.MIN_VALUE) { + sndDelayFactor=DsndDelayFactor; + }else { + sndDelayFactor=(sndDelayFactor+ DsndDelayFactor)/2; + } + if(rcvDelayFactor==Long.MIN_VALUE) { + rcvDelayFactor=DrcvDelayFactor; + }else { + rcvDelayFactor=(rcvDelayFactor+ DrcvDelayFactor)/2; + } + LockSupport.unpark(tlock); + break; + case KLALBPacket.VADDRREQ: + sendPacket(new VADDRPacket(localVaddrSupplier.get()), -1); + break; + case KLALBPacket.VADDR: + remoteVaddr=((VADDRPacket) kpp).getVaddr(); + sendPacket(new VADDRACKPacket(), -1); + break; + case KLALBPacket.VADDRACK: + if(fst) { + monitor.resetCoolingTime(); + monitor.setState(Monitor.ONLINE); + fst=false; + } + break; + case KLALBPacket.TEST: + break; + default: + while(rec==null) { + Thread.sleep(1); + } + rec.accept(KLALBRemoteLine.this,kpp); + break; + } + Thread.yield(); + } + } catch (IOException e) { + e.printStackTrace(); + } catch (InterruptedException e) { + e.printStackTrace(); + } finally { + monitor.setState(Monitor.OFFLINE); + try { + if(kplink!=null) + kplink.close(); + } catch (IOException e) { + e.printStackTrace(); + } + + } + + if(closed) { + break; + } + //Thread.sleep(monitor.getCoolingTime()); + lthd=Thread.currentThread(); + LockSupport.parkNanos(monitor.getCoolingTime()*1000000L); + monitor.incCoolingTime(); + + } + endRecord(); + + }).start(); + + } + + + + + private KLALBPacket readPacketFromKPL() throws IOException { + KLALBPacket packet=kplink.readPacket(); + /*if(!(packet instanceof PINGPacket) ) + if(!(packet instanceof PONGPacket) ) + System.out.println("RX:" + packet);*/ + if(packet!=null) + monitor.getInTrafficAL().addAndGet(packet.getLength()); + return packet; + } + private void writePacketToKPL(KLALBPacket packet) throws IOException { + monitor.getOutTrafficAL().addAndGet(packet.getLength()); + kplink.writePacket(packet); + + /*if(!(packet instanceof PINGPacket) ) + if(!(packet instanceof PONGPacket) ) + System.err.println("TX:" + packet);*/ + } + + public void close() { + closed=true; + try { + if(kplink!=null) + kplink.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + public boolean isClosed() { + return closed; + } + + private volatile long time = System.nanoTime(); + private volatile long pingInterval=1000000000L; + + private boolean checkPingTime() { + long cu = System.nanoTime(); + if (cu - time > pingInterval) { + time = cu; + return true; + } else { + return false; + } + } + + + + private volatile BiConsumer rec; + + //private Object lock=new Object(); + private volatile Thread tlock; + private List> sendDequeList =new ArrayList>(); + { + for(int i=0;i<12;i++) { + sendDequeList.add(new SumQueue(new ConcurrentLinkedQueue<>())); + } + } + private KLALBPacket getNextPacket() { + for (Iterator> iterator = sendDequeList.iterator(); iterator.hasNext();) { + SumQueue queue = (SumQueue) iterator.next(); + KLALBPacket v=queue.poll(); + if(v!=null) + return v; + if(monitor.getLatencyCurr()>(monitor.getLatencyMin()<<3)) { + //System.out.println(monitor.getLatencyCurr()+" "+monitor.getLatencyMin()); + return null; + } + } + return null; + } + private long sumNextPacketSize() { + long i=0; + for (Iterator> iterator = sendDequeList.iterator(); iterator.hasNext();) { + SumQueue queue = (SumQueue) iterator.next(); + i+=queue.getSumValue(); + } + return i; + } + private long sumNextPacketCount() { + long i=0; + for (Iterator> iterator = sendDequeList.iterator(); iterator.hasNext();) { + SumQueue queue = (SumQueue) iterator.next(); + i+=queue.size(); + } + return i; + } + + public void sendPacket(KLALBPacket kp) { + sendPacket(kp, 5); + } + + public void sendPacket(KLALBPacket blk,int prio) { + sendDequeList.get(prio+1).add(blk); + LockSupport.unpark(tlock); + } + + public void setPacketReceiver(BiConsumer rec) { + this.rec = rec; + } + + + + public void remoeFromSendQueue(KLALBPacket klalbPacket) { + for (Iterator> iterator = sendDequeList.iterator(); iterator.hasNext();) { + SumQueue queue = iterator.next(); + queue.removeIf((x)->{ + return x.equals(klalbPacket); + }); + } + } + + public long statLengthBefore(int priority) { + AtomicLong al=new AtomicLong(); + int n=0; + for (Iterator> iterator = sendDequeList.iterator(); iterator.hasNext();n++) { + if(n>priority) { + break; + } + SumQueue queue = iterator.next(); + al.addAndGet(queue.getSumValue()); + + } + return al.get(); + } + + private long sndDelayFactor=Long.MIN_VALUE; + private long rcvDelayFactor=Long.MIN_VALUE; + + public long getSndDelayFactor() { + return sndDelayFactor; + } + public long getRcvDelayFactor() { + return rcvDelayFactor; + } + private volatile long predictTime; + public void runPredict(KLALBPacket curr,int priority) { + predictTime=sndDelayFactor; + //System.out.println(this+" "+sndDelayFactor); + long al=0; + al=statLengthBefore(priority); + long speed=getMonitor(). getOutSpeed(); + if(speed==0) { + if(al>0) { + predictTime=Long.MAX_VALUE; + } + }else { + predictTime+=al*1000000000L/speed; + } + } + @Override + public int compareTo(KLALBRemoteLine o2) { + long t1=this.predictTime; + long t2=o2.predictTime; + if(t1>t2) { + return 1; + }else if(t1 { - try { - - while (!isClosed()) { - KLALBPacket kpp = getInputStream().readPacket(); - if(kpp instanceof PINGPacket) { - sendPacket(new PONGPacket(((PINGPacket) kpp).getTime()), 65540); - }else if(kpp instanceof PONGPacket) { - PONGPacket png=(PONGPacket) kpp; - getMonitor().updateLatency (System.nanoTime()- png.getTime()); - try { - socket.setSoTimeout(600); - } catch (SocketException e1) { - // TODO 自动生成的 catch 块 - e1.printStackTrace(); - } - }else { - - System.out.println("RX:" + kpp); - if(kpp instanceof VADDRPacket) { - remoteVaddr=((VADDRPacket) kpp).getVaddr(); - } - while(rec==null) { - Thread.sleep(1); - } - rec.accept(kpp); - } - } - } catch (IOException e) { - //e.printStackTrace(); - } catch (InterruptedException e) { - e.printStackTrace(); - } finally { - try { - close(); - } catch (IOException e) { - e.printStackTrace(); - } - } - }).start(); - ThreadTool.makeVDaemonThreadIfSupport("远程发送线程", () -> { - try { - - while (!isClosed()) { - if(checkPingTime()) { - getOutputStream().writePacket(new PINGPacket(System.nanoTime())); - }else { - PQItem pqi=sendQueue.poll(); - if(pqi!=null) { - KLALBPacket kpp=pqi.getPacket(); - if(!(kpp instanceof PONGPacket)) - System.out.println("TX:" + kpp); - if(kpp instanceof PONGPacket) { - PONGPacket pp=(PONGPacket) kpp; - pp.redeltaTime(System.nanoTime()-pqi.getAddtime()); - } - getOutputStream().writePacket(kpp); - //System.out.println(sendQueue.size()); - }else { - synchronized (sendQueue) { - sendQueue.wait(10); - } - //Thread.sleep(1); - } - } - } - } catch (IOException e) { - // e.printStackTrace(); - } catch (InterruptedException e) { - } finally { - try { - close(); - } catch (IOException e) { - e.printStackTrace(); - } - } - }).start(); - } - - - private volatile long time = System.nanoTime(); - private volatile long pingInterval=500000000L; - - public long getPingInterval() { - return pingInterval; - } - - public void setPingInterval(long ns) { - this.pingInterval = ns; - } - - private boolean checkPingTime() { - long cu = System.nanoTime(); - if (cu - time > pingInterval) { - time = cu; - return true; - } else { - return false; - } - } - - - - - - private KLALBInputStream kis; - private KLALBOutputStream kos; - - @Override - public KLALBInputStream getInputStream() throws IOException { - if (kis == null) - kis = new KLALBInputStream(super.getInputStream()); - return kis; - } - - @Override - public KLALBOutputStream getOutputStream() throws IOException { - if (kos == null) - kos = new KLALBOutputStream(super.getOutputStream()); - return kos; - } - - - private volatile Consumer rec; - private Consumer clo; - private PriorityBlockingQueue sendQueue=new PriorityBlockingQueue(); - - protected PriorityBlockingQueue getSendQueue() { - return sendQueue; - } - - public void sendPacket(KLALBPacket kp) { - sendPacket(kp, 5); - } - - public void sendPacket(KLALBPacket kp,int priority) { - sendQueue.add(new PQItem(kp, priority)); - synchronized (sendQueue) { - sendQueue.notifyAll(); - } - } - - public void setPacketReceiver(Consumer rec) { - this.rec = rec; - } - public void setCloseListener(Consumer clo) { - this.clo = clo; - } - @Override - public synchronized void close() throws IOException { - if(!isClosed()&&clo!=null) - clo.accept(this); - cdl.countDown(); - super.close(); - sendQueue.forEach((x)->{ - try { - //System.out.println("断线重发"); - controller.sendPacketToAddress(remoteVaddr, x.getPacket(), x.getPriority()+1); - } catch (NoRouteToHostException e) { - } - }); - } - - @Override - public boolean isClosed() { - return cdl.getCount()<=0; - } - - private AtomicLong al=new AtomicLong(0); - protected class PQItem implements Comparable{ - private KLALBPacket packet; - private long index=al.getAndIncrement(); - private int priority=5; - private long addtime=System.nanoTime(); - public long getAddtime() { - return addtime; - } - public PQItem(KLALBPacket value, int priority) { - super(); - this.packet = value; - this.priority = priority; - } - public KLALBPacket getPacket() { - return packet; - } - public long getIndex() { - return index; - } - public int getPriority() { - return priority; - } - @Override - public int compareTo(PQItem o) { - if(priorityo.priority) { - return -1; - }else { - if(index>o.index) { - return 1; - }else if(index{ - return x.getPacket().equals(klalbPacket); - }); - } -} diff --git a/src/org/kne/cloud/network/klalb/KLALBStateGUI.java b/src/org/kne/cloud/network/klalb/KLALBStateGUI.java new file mode 100644 index 0000000..bae5f47 --- /dev/null +++ b/src/org/kne/cloud/network/klalb/KLALBStateGUI.java @@ -0,0 +1,201 @@ +package org.kne.cloud.network.klalb; + +import java.awt.AWTException; +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.Component; +import java.awt.Dimension; +import java.awt.MenuItem; +import java.awt.PopupMenu; +import java.awt.SystemTray; +import java.awt.TrayIcon; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.ComponentEvent; +import java.awt.event.ComponentListener; +import java.awt.event.ItemEvent; +import java.awt.event.ItemListener; +import java.awt.image.BufferedImage; +import java.io.File; +import java.io.IOException; +import java.net.ConnectException; +import java.net.UnknownHostException; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.util.Iterator; +import java.util.List; +import java.util.Map.Entry; +import java.util.Timer; +import java.util.TimerTask; + +import javax.imageio.ImageIO; +import javax.swing.JButton; +import javax.swing.JComboBox; +import javax.swing.JOptionPane; +import javax.swing.JPanel; + +import org.kne.cloud.network.MultipurposeSocketAddress; +import org.kne.cloud.network.SocketBridge; +import org.kne.cloud.network.SocketListener; +import org.kne.cloud.network.ThreadTool; +import org.kne.ui.XFrame; +import org.kne.ui.YScrollPane; +import javax.swing.JProgressBar; + +public class KLALBStateGUI extends XFrame { + private BufferedImage bi; + + private TimerTask tsk; + + private SystemTray st; + + private TrayIcon ti; + public KLALBStateGUI(KLALBController kc,String title) throws IOException { + setResizable(false); + try { + bi = ImageIO.read(KLALBStateGUI.class.getResourceAsStream("/assets/KNEL.png")); + } catch (IOException e) { + e.printStackTrace(); + } + if(bi!=null) + setIconImage(bi); + setTitleColor(new Color(0,0,0,80)); + getContentPane().setBackground(new Color(0,0,0,80)); + getTitlelabel().setForeground(Color.WHITE); + + + + YScrollPane ysp = new YScrollPane(660); + ysp.setOpaque(false); + getContentPane().add(ysp); + JPanel wv = ysp.getView(); + + /*JProgressBar progressBar = new JProgressBar(); + progressBar.setIndeterminate(true); + progressBar.setForeground(Color.YELLOW); + progressBar.setBorder(null); + progressBar.setPreferredSize(new Dimension(100, 4)); + ysp.add(progressBar, BorderLayout.NORTH);*/ + wv.addComponentListener(new ComponentListener() { + + @Override + public void componentShown(ComponentEvent e) { + // TODO 自动生成的方法存根 + + } + + @Override + public void componentResized(ComponentEvent e) { + // TODO 自动生成的方法存根 + + } + + @Override + public void componentMoved(ComponentEvent e) { + repaint(); + } + + @Override + public void componentHidden(ComponentEvent e) { + // TODO 自动生成的方法存根 + + } + }); + setTitle(title); + setSize(680, 430); + setLocationRelativeTo(null); + + //setVisible(true); + + if (SystemTray.isSupported()) { + st = SystemTray.getSystemTray(); + ti = new TrayIcon(bi); + ti.setImageAutoSize(true); + PopupMenu jpm = new PopupMenu(); + MenuItem mix = new MenuItem("open"); + mix.addActionListener(new ActionListener() { + + @Override + public void actionPerformed(ActionEvent e) { + setVisible(true); + } + }); + jpm.add(mix); + MenuItem mi = new MenuItem("exit"); + mi.addActionListener(new ActionListener() { + + @Override + public void actionPerformed(ActionEvent e) { + close(); + } + }); + jpm.add(mi); + ti.setPopupMenu(jpm); + try { + st.add(ti); + } catch (AWTException e1) { + e1.printStackTrace(); + } + ti.addActionListener((x) -> { + setVisible(true); + }); + } + + repaint(); + + /*progressBar.setIndeterminate(false); + progressBar.setValue(100); + progressBar.setForeground(Color.GREEN);*/ + Timer t= new Timer("状态刷新线程",true); + tsk=new TimerTask() { + + @Override + public void run() { + synchronized (kc.getLines()) { + loop:for (Iterator iterator = kc.getLines().iterator(); iterator.hasNext();) { + KLALBRemoteLine ent = iterator.next(); + Component[] count=ysp.getView().getComponents(); + for (int i = 0; i < count.length; i++) { + Component tp=count[i]; + if(tp instanceof TPanel) { + if(((TPanel) tp).getTunnel().equals(ent)) { + continue loop; + } + } + } + TPanel tp=new TPanel(ent); + ysp.getView().add(tp); + } + Component[] count=ysp.getView().getComponents(); + for (int i = 0; i < count.length; i++) { + Component tp=count[i]; + if(tp instanceof TPanel) { + if(kc.getLines().contains(((TPanel) tp).getTunnel())) { + ((TPanel) tp).updateTraffic(); + }else { + ysp.getView().remove(tp); + } + } + } + + } + repaint(); + } + }; + t.schedule(tsk, 500, 500); + } + + public void close() { + setVisible(false); + if(tsk!=null) { + tsk.cancel(); + } + st.remove(ti); + } + + public static void main(String[] args) throws IOException, InterruptedException {//,new MultipurposeSocketAddress("frp-mom.top:22226"),new MultipurposeSocketAddress("0.0.0.0:26468") + KLALBStateGUI kcg=new KLALBStateGUI(new KLALBController(),"KNE云网络负载均衡客户端 V2.0"); + Thread.sleep(10000); + kcg.close(); + } +} diff --git a/src/org/kne/cloud/network/klalb/LineManager.java b/src/org/kne/cloud/network/klalb/LineManager.java deleted file mode 100644 index 8e5e15a..0000000 --- a/src/org/kne/cloud/network/klalb/LineManager.java +++ /dev/null @@ -1,162 +0,0 @@ -package org.kne.cloud.network.klalb; - -import java.io.IOException; -import java.net.UnknownHostException; -import java.util.Iterator; -import java.util.List; -import java.util.Timer; -import java.util.TimerTask; -import java.util.TreeMap; -import java.util.TreeSet; -import java.util.Hashtable; - -import org.kne.cloud.network.klalb.LineManager.LineEntry; -import org.kne.cloud.network.mport.MultipurposeSocketAddress; -import org.kne.cloud.network.mport.ThreadTool; - -public class LineManager extends Hashtable{ - private Object lock=new Object(); - private KLALBController controller; - public LineManager(KLALBController controller) { - super(); - this.controller = controller; - } - /*public void applyList(HostPortList hpl) { - HostPortList lh=(HostPortList) hpl.clone(); - for (Iterator iterator = hm.iterator(); iterator.hasNext();) { - LineEntry hostPort = (LineEntry) iterator.next(); - lh.remove(hostPort.getHp()); - } - for (Iterator iterator = lh.iterator(); iterator.hasNext();) { - MultipurposeSocketAddress hostPort = (MultipurposeSocketAddress) iterator.next(); - LineEntry le=new LineEntry(hostPort); - hm.add(le); - ThreadTool.makeVDaemonThreadIfSupport("线路监视线程", le).start(); - } - - for (Iterator iterator = hm.iterator(); iterator.hasNext();) { - LineEntry hostPort = (LineEntry) iterator.next(); - if(!hpl.contains(hostPort.getHp())) { - hostPort.close(); - iterator.remove(); - } - } - - }*/ - public void retry() { - synchronized (lock) { - lock.notifyAll(); - } - } - public synchronized void addHostPort(MultipurposeSocketAddress v) { - LineEntry le=new LineEntry(v); - if(putIfAbsent(v,le)==null) - le.open(); - } - public synchronized void removeHostPort(MultipurposeSocketAddress v) { - for (Iterator> iterator = entrySet().iterator(); iterator.hasNext();) { - java.util.Map.Entry hostPort = iterator.next(); - if(hostPort.getValue().equals(v)) { - hostPort.getValue().close(); - iterator.remove(); - } - } - } - - - - public KLALBController getController() { - return controller; - } - - public class LineEntry implements Runnable{ - private MultipurposeSocketAddress hp; - private KLALBRemoteSocket krs; - private volatile boolean flag=true; - private Monitor monitor=new Monitor(); - - - public Monitor getMonitor() { - return monitor; - } - - public MultipurposeSocketAddress getHp() { - return hp; - } - - public LineEntry(MultipurposeSocketAddress hp) { - super(); - this.hp = hp; - } - public String toString() { - StringBuilder sb=new StringBuilder(); - sb.append(hp.toString()); - sb.append('\t'); - sb.append(monitor.toString()); - return sb.toString(); - } - - public String toString2() { - StringBuilder sb=new StringBuilder(); - - sb.append(hp.toString()); - sb.append('\n'); - sb.append(monitor.toString2()); - return sb.toString(); - } - - @Override - public void run() { - while(true){ - try { - monitor.setState(Monitor.CONNECTING); - krs=new KLALBRemoteSocket(hp.connectSocket(3000),monitor); - //System.out.println("open"); - controller.addRemoteSocket(krs); - monitor.resetCoolingTime(); - monitor.setState(Monitor.ONLINE); - krs.waitforlose(); - //System.out.println("close"); - } catch (UnknownHostException e) { - } catch (IOException e) { - //e.printStackTrace(); - }finally { - monitor.setState(Monitor.OFFLINE); - try { - if(krs!=null) - krs.close(); - } catch (IOException e) { - e.printStackTrace(); - } - } - if(!flag) { - break; - } - try { - synchronized (lock) { - lock.wait(monitor.getCoolingTime()); - } - monitor.incCoolingTime(); - } catch (InterruptedException e) { - e.printStackTrace(); - } - } - - } - public void open() { - - ThreadTool.makeVDaemonThreadIfSupport("线路监视线程", this).start(); - } - public void close() { - flag=false; - if(krs!=null) - try { - krs.close(); - } catch (IOException e) { - // TODO 自动生成的 catch 块 - e.printStackTrace(); - } - - } - } -} diff --git a/src/org/kne/cloud/network/klalb/NACKTPacket.java b/src/org/kne/cloud/network/klalb/NACKTPacket.java new file mode 100644 index 0000000..1162d18 --- /dev/null +++ b/src/org/kne/cloud/network/klalb/NACKTPacket.java @@ -0,0 +1,63 @@ +package org.kne.cloud.network.klalb; + +import java.io.DataInput; +import java.io.DataOutput; +import java.io.IOException; +import java.util.concurrent.atomic.AtomicInteger; + +public class NACKTPacket extends KLALBPacket implements PortPacket{ + private int sport,dport; + private long number; + + + public NACKTPacket(int sport,int dport,long number) { + super(NACKT); + this.sport=sport; + this.dport=dport; + this.number=number; + } + + public NACKTPacket() { + super(NACKT); + } + + @Override + public String toString() { + return "NACKT "+sport+"->"+dport+" "+number+"[]"; + } + + public int getSport() { + return sport; + } + + @Override + public long getLength() { + return super.getLength()+17; + } + + public int getDport() { + return dport; + } + + public long getNumber() { + return number; + } + + + @Override + protected void writeToStream(DataOutput dto) throws IOException { + super.writeToStream(dto); + dto.writeInt(sport); + dto.writeInt(dport); + dto.writeLong(number); + } + + @Override + protected void readFromStream(DataInput din) throws IOException { + super.readFromStream(din); + sport=din.readInt(); + dport=din.readInt(); + number=din.readLong(); + } + +} diff --git a/src/org/kne/cloud/network/klalb/PortBinder.java b/src/org/kne/cloud/network/klalb/PortBinder.java new file mode 100644 index 0000000..31d93b7 --- /dev/null +++ b/src/org/kne/cloud/network/klalb/PortBinder.java @@ -0,0 +1,243 @@ +package org.kne.cloud.network.klalb; + +import java.net.BindException; +import java.net.Inet6Address; +import java.net.InetAddress; +import java.net.InetSocketAddress; +import java.net.ServerSocket; +import java.net.Socket; +import java.net.SocketTimeoutException; +import java.net.UnknownHostException; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.locks.ReadWriteLock; +import java.util.concurrent.locks.ReentrantReadWriteLock; + +import com.google.gson.internal.Pair; + +public class PortBinder { + private static Inet6Address ANYLA; + static { + try { + ANYLA=(Inet6Address) Inet6Address.getByAddress(new byte[16]); + } catch (UnknownHostException e) { + } + } + private KLALBController controller; + public PortBinder(KLALBController controller) { + super(); + this.controller = controller; + } + private ReentrantReadWriteLock bindMaplock=new ReentrantReadWriteLock(); + private MapbindMap=new ConcurrentHashMap<>(); + private ReentrantReadWriteLock listenMaplock=new ReentrantReadWriteLock(); + private MaplistenMap=new ConcurrentHashMap<>(); + private ReentrantReadWriteLock connectMaplock=new ReentrantReadWriteLock(); + private Map,BindableKLALBPacketConsumer>connectMap=new ConcurrentHashMap<>(); + private volatile int portn=65535; + public void bind(BindableKLALBPacketConsumer ks) throws BindException { + bindMaplock.writeLock().lock(); + try { + int pold=ks.getLocalPort(); + if(pold==0) { + int portnod=portn+1; + if(portnod>65535) { + portnod=1; + } + int cnt=0; + while(true) { + portn++; + if(portn>65535) { + portn=1; + } + if(portn==portnod) { + cnt++; + if(cnt>1) { + throw new BindException("can't alloc port"); + } + } + boolean flag=true; + for (Iterator iterator = bindMap.keySet().iterator(); iterator.hasNext();) { + InetSocketAddress bindableKLALBPacketConsumer = (InetSocketAddress) iterator + .next(); + if(Objects.equals(ks.getLocalInetAddress(), bindableKLALBPacketConsumer.getAddress())&&portn==bindableKLALBPacketConsumer.getPort()) { + flag=false; + break; + } + } + if(flag) + break; + } + ks.setLocalPort(portn); + }else { + for (Iterator iterator = bindMap.keySet().iterator(); iterator.hasNext();) { + InetSocketAddress bindableKLALBPacketConsumer = (InetSocketAddress) iterator + .next(); + if(Objects.equals(ks.getLocalInetAddress(), bindableKLALBPacketConsumer.getAddress())&&pold==bindableKLALBPacketConsumer.getPort()) { + throw new BindException("port " + pold + " is already bind!"); + } + } + } + bindMap.put(new InetSocketAddress(ks.getLocalInetAddress(), ks.getLocalPort()),ks); + }finally { + bindMaplock.writeLock().unlock(); + } + } + + public void unbind(BindableKLALBPacketConsumer ks) { + bindMaplock.writeLock().lock(); + try { + removeAsValue(bindMap, ks); + }finally { + bindMaplock.writeLock().unlock(); + } + } + public void connect(BindableKLALBPacketConsumer ks) throws BindException { + connectMaplock.writeLock().lock(); + try { + connectMap.put(new Pair( new InetSocketAddress(ks.getLocalInetAddress(), ks.getLocalPort()), new InetSocketAddress(ks.getRemoteInetAddress(), ks.getPort())),ks); + }finally { + connectMaplock.writeLock().unlock(); + } + } + public void disconnect(BindableKLALBPacketConsumer ks) throws BindException { + connectMaplock.writeLock().lock(); + try { + removeAsValue(connectMap, ks); + }finally { + connectMaplock.writeLock().unlock(); + } + } + + public void listen(BindableKLALBPacketConsumer ks) throws BindException { + listenMaplock.writeLock().lock(); + try { + listenMap.put(new InetSocketAddress(ks.getLocalInetAddress(), ks.getLocalPort()),ks); + }finally { + listenMaplock.writeLock().unlock(); + } + } + public void unlisten(BindableKLALBPacketConsumer ks) throws BindException { + /*System.out.println(listenMap); + new RuntimeException("!").printStackTrace();*/ + listenMaplock.writeLock().lock(); + try { + removeAsValue(listenMap, ks); + }finally { + listenMaplock.writeLock().unlock(); + } + } + private static void removeAsValue(Map m,Object obj) { + Collection col= m.values(); + for (Iterator iterator = col.iterator(); iterator.hasNext();) { + Object object = (Object) iterator.next(); + if(object.equals(obj)) { + iterator.remove(); + } + } + } + /*private ReadWriteLock rwl=new ReentrantReadWriteLock(); + private List bindlist=new ArrayList<>(); + public void bind(BindableKLALBPacketConsumer ks) throws BindException { + rwl.writeLock().lock(); + try { + int pold=ks.getLocalPort(); + if(pold==0) { + int i=1; + while(true) { + if(i>65535) { + throw new BindException("can't alloc port"); + } + boolean flag=true; + for (Iterator iterator = bindlist.iterator(); iterator.hasNext();) { + BindableKLALBPacketConsumer bindableKLALBPacketConsumer = (BindableKLALBPacketConsumer) iterator + .next(); + if(Objects.equals(ks.getLocalInetAddress(), bindableKLALBPacketConsumer.getLocalInetAddress())&&i==bindableKLALBPacketConsumer.getLocalPort()&&Objects.equals( ks.getRemoteInetAddress(), bindableKLALBPacketConsumer.getRemoteInetAddress())&&(ks.getPort()==bindableKLALBPacketConsumer.getPort())) { + flag=false; + break; + } + } + if(flag) + break; + i++; + } + ks.setLocalPort(i); + }else { + for (Iterator iterator = bindlist.iterator(); iterator.hasNext();) { + BindableKLALBPacketConsumer bindableKLALBPacketConsumer = (BindableKLALBPacketConsumer) iterator + .next(); + if(Objects.equals(ks.getLocalInetAddress(), bindableKLALBPacketConsumer.getLocalInetAddress())&&pold==bindableKLALBPacketConsumer.getLocalPort()&&Objects.equals( ks.getRemoteInetAddress(), bindableKLALBPacketConsumer.getRemoteInetAddress())&&(ks.getPort()==bindableKLALBPacketConsumer.getPort())) { + throw new BindException("port " + pold + " is already bind!"); + } + } + } + bindlist.add(ks); + }finally { + rwl.writeLock().unlock(); + } + } + public boolean distributePacketToConsumer(KLALBRemoteLine krl,PortPacket packet) throws SocketTimeoutException { + rwl.readLock().lock(); + boolean b=false; + try { + for (Iterator iterator = bindlist.iterator(); iterator.hasNext();) { + BindableKLALBPacketConsumer bindableKLALBPacketConsumer = (BindableKLALBPacketConsumer) iterator.next(); + if(bindableKLALBPacketConsumer.getLocalPort()==packet.getDport()&&(controller.getSelf().equals(bindableKLALBPacketConsumer.getLocalInetAddress())||ANYLA.equals(bindableKLALBPacketConsumer.getLocalInetAddress()))) { + if(bindableKLALBPacketConsumer.getRemoteInetAddress()==null||bindableKLALBPacketConsumer.getRemoteInetAddress().equals(ANYLA)) { + bindableKLALBPacketConsumer.accept(krl, (KLALBPacket) packet); + b=true; + }else { + if(bindableKLALBPacketConsumer.getPort()==packet.getSport()&&bindableKLALBPacketConsumer.getRemoteInetAddress().equals(krl.getRemoteVaddr())) { + bindableKLALBPacketConsumer.accept(krl, (KLALBPacket) packet); + b=true; + } + } + } + } + }finally { + rwl.readLock().unlock(); + } + return b; + }*/ + public boolean distributePacketToConsumer(KLALBRemoteLine krl,PortPacket packet) throws SocketTimeoutException { + InetSocketAddress local=new InetSocketAddress(controller.getSelf(), packet.getDport()); + InetSocketAddress remote=new InetSocketAddress(krl.getRemoteVaddr(), packet.getSport()); + BindableKLALBPacketConsumer bkc=connectMap.get(new Pair(local, remote)); + if(bkc!=null) { + bkc.accept(krl, (KLALBPacket) packet); + return true; + } + InetSocketAddress localany=new InetSocketAddress(ANYLA, packet.getDport()); + bkc=connectMap.get(new Pair(localany, remote)); + if(bkc!=null) { + bkc.accept(krl, (KLALBPacket) packet); + return true; + } + + bkc=listenMap.get(local); + if(bkc!=null) { + bkc.accept(krl, (KLALBPacket) packet); + return true; + } + bkc=listenMap.get(localany); + if(bkc!=null) { + bkc.accept(krl, (KLALBPacket) packet); + return true; + } + + + return false; + } + public boolean checkIsBind(KLALBVirtualSocketImpl klalbVirtualSocketImpl) { + return bindMap.containsValue(klalbVirtualSocketImpl); + } + public boolean checkIsConnect(BindableKLALBPacketConsumer kservers,InetSocketAddress isaf) throws BindException { + return connectMap.containsKey(new Pair( new InetSocketAddress(kservers.getLocalInetAddress(), kservers.getLocalPort()),isaf)); + } + +} \ No newline at end of file diff --git a/src/org/kne/cloud/network/klalb/PortPacket.java b/src/org/kne/cloud/network/klalb/PortPacket.java new file mode 100644 index 0000000..aaf6e9d --- /dev/null +++ b/src/org/kne/cloud/network/klalb/PortPacket.java @@ -0,0 +1,8 @@ +package org.kne.cloud.network.klalb; + +public interface PortPacket { + + public int getSport(); + + public int getDport(); +} diff --git a/src/org/kne/cloud/network/klalb/StreamKLALBPacketLink.java b/src/org/kne/cloud/network/klalb/StreamKLALBPacketLink.java new file mode 100644 index 0000000..0ca035f --- /dev/null +++ b/src/org/kne/cloud/network/klalb/StreamKLALBPacketLink.java @@ -0,0 +1,59 @@ +package org.kne.cloud.network.klalb; + +import java.io.BufferedOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.net.Socket; +import java.net.SocketException; +import java.nio.Buffer; + +public class StreamKLALBPacketLink implements KLALBPacketLink { + + @Override + public String toString() { + return "StreamKLALBPacketLink [connectSocket=" + connectSocket + "]"; + } + + private Socket connectSocket; + private KLALBInputStream in; + private KLALBOutputStream out; + public StreamKLALBPacketLink(Socket connectSocket) throws IOException { + this.connectSocket=connectSocket; + connectSocket.setTcpNoDelay(true); + out=new KLALBOutputStream(connectSocket.getOutputStream()); + out.flush(); + in=new KLALBInputStream( connectSocket.getInputStream()); + //connectSocket.setSendBufferSize(1024*1024*1024); + } + + @Override + public void writePacket(KLALBPacket kp) throws IOException { + out.writePacket(kp); + } + + @Override + public KLALBPacket readPacket() throws IOException { + return in.readPacket(); + } + + @Override + public void close() throws IOException { + connectSocket.close(); + } + + @Override + public boolean isClosed() { + return connectSocket.isClosed(); + } + + @Override + public void setSoTimeout(int val) throws SocketException { + connectSocket.setSoTimeout(val); + } + + @Override + public int getSoTimeout() throws SocketException { + return connectSocket.getSoTimeout(); + } + +} diff --git a/src/org/kne/cloud/network/klalb/SumQueue.java b/src/org/kne/cloud/network/klalb/SumQueue.java new file mode 100644 index 0000000..ea8eac6 --- /dev/null +++ b/src/org/kne/cloud/network/klalb/SumQueue.java @@ -0,0 +1,216 @@ +package org.kne.cloud.network.klalb; + +import java.util.AbstractQueue; +import java.util.Collection; +import java.util.Iterator; +import java.util.Queue; +import java.util.Spliterator; +import java.util.concurrent.ConcurrentLinkedQueue; +import java.util.concurrent.atomic.AtomicLong; +import java.util.function.Consumer; +import java.util.function.IntFunction; +import java.util.function.Predicate; +import java.util.stream.Stream; + +public class SumQueue extends AbstractQueue implements Queue { + private AbstractQueue abq; + public SumQueue(AbstractQueue abq) { + this.abq=abq; + } + private AtomicLong sumed=new AtomicLong(); + public long getSumValue() { + return sumed.get(); + } + + private void resum() { + AtomicLong l=new AtomicLong(); + forEach((t)->{ + l.addAndGet(t.getValue()); + }); + sumed.set(l.get()); + } + + + + @Override + public boolean removeIf(Predicate filter) { + boolean removeIf = abq.removeIf(filter); + resum(); + return removeIf; + } + + + @Override + public boolean offer(T e) { + boolean offer = abq.offer(e); + if(offer) + sumed.addAndGet(e.getValue()); + return offer; + } + + @Override + public T poll() { + T poll = abq.poll(); + if(poll!=null) { + sumed.addAndGet(-poll.getValue()); + } + return poll; + } + + + + @Override + public boolean add(T e) { + boolean add = abq.add(e); + if(add) { + sumed.addAndGet(e.getValue()); + } + return add; + } + + @Override + public T remove() { + T remove = abq.remove(); + if(remove!=null) { + sumed.addAndGet(-remove.getValue()); + } + return remove; + } + + + @Override + public void clear() { + abq.clear(); + sumed.set(0); + } + + @Override + public boolean addAll(Collection c) { + boolean addAll = abq.addAll(c); + resum(); + return addAll; + } + + @Override + public Iterator iterator() { + return null; + } + + + + + + + + + + @Override + public boolean remove(Object o) { + boolean b = abq.remove(o); + if(b) + sumed.addAndGet(((Sumable)o).getValue()); + return b; + } + + + @Override + public boolean removeAll(Collection c) { + boolean removeAll = abq.removeAll(c); + resum(); + return removeAll; + } + + @Override + public boolean retainAll(Collection c) { + boolean retainAll = abq.retainAll(c); + resum(); + return retainAll; + } + + + + + + + + + + + + + + + @Override + public T element() { + return (T) abq.element(); + } + + @Override + public T peek() { + return (T) abq.peek(); + } + @Override + public int size() { + return abq.size(); + } + + @Override + public boolean isEmpty() { + return abq.isEmpty(); + } + + @Override + public boolean contains(Object o) { + return abq.contains(o); + } + + @Override + public Object[] toArray() { + return abq.toArray(); + } + + @Override + public Spliterator spliterator() { + return abq.spliterator(); + } + + @Override + public Stream stream() { + // TODO 自动生成的方法存根 + return abq.stream(); + } + + @Override + public Stream parallelStream() { + // TODO 自动生成的方法存根 + return abq.parallelStream(); + } + + @Override + public void forEach(Consumer action) { + // TODO 自动生成的方法存根 + abq.forEach(action); + } + + @Override + public boolean containsAll(Collection c) { + // TODO 自动生成的方法存根 + return abq.containsAll(c); + } + + @Override + public T[] toArray(IntFunction generator) { + return (T[]) abq.toArray(generator); + } +@Override + public T[] toArray(T[] a) { + // TODO 自动生成的方法存根 + return (T[]) abq.toArray(a); + } + @Override + public String toString() { + // TODO 自动生成的方法存根 + return abq.toString(); + } + +} \ No newline at end of file diff --git a/src/org/kne/cloud/network/klalb/Sumable.java b/src/org/kne/cloud/network/klalb/Sumable.java new file mode 100644 index 0000000..b6da654 --- /dev/null +++ b/src/org/kne/cloud/network/klalb/Sumable.java @@ -0,0 +1,5 @@ +package org.kne.cloud.network.klalb; + +public interface Sumable { + public long getValue(); +} \ No newline at end of file diff --git a/src/org/kne/cloud/network/klalb/TESTPacket.java b/src/org/kne/cloud/network/klalb/TESTPacket.java new file mode 100644 index 0000000..c56dfe7 --- /dev/null +++ b/src/org/kne/cloud/network/klalb/TESTPacket.java @@ -0,0 +1,37 @@ +package org.kne.cloud.network.klalb; + +import java.io.DataInput; +import java.io.DataOutput; +import java.io.IOException; + +public class TESTPacket extends KLALBPacket { + private static byte[]K=new byte[1024]; + @Override + public long getLength() { + return super.getLength()+1024; + } + + + public TESTPacket() { + super(TEST); + } + + + + @Override + public String toString() { + return "TEST"; + } + + @Override + protected void writeToStream(DataOutput dto) throws IOException { + super.writeToStream(dto); + dto.write(K); + } + + @Override + protected void readFromStream(DataInput din) throws IOException { + super.readFromStream(din); + din.readFully(K, 0, K.length); + } +} diff --git a/src/org/kne/cloud/network/klalb/TPanel.java b/src/org/kne/cloud/network/klalb/TPanel.java new file mode 100644 index 0000000..5224ea4 --- /dev/null +++ b/src/org/kne/cloud/network/klalb/TPanel.java @@ -0,0 +1,132 @@ +package org.kne.cloud.network.klalb; + +import javax.swing.JPanel; +import javax.swing.JLabel; +import java.awt.BorderLayout; +import java.awt.Color; + +import javax.swing.SwingConstants; +import javax.swing.border.LineBorder; + +import java.awt.Font; +import java.util.Objects; + +public class TPanel extends JPanel { + private JLabel tname; + private JLabel targ; + private KLALBRemoteLine tunnel; + + @Override + public int hashCode() { + return Objects.hash(tunnel); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + TPanel other = (TPanel) obj; + return Objects.equals(tunnel, other.tunnel); + } + + public JLabel getTname() { + return tname; + } + + public JLabel getTarg() { + return targ; + } + + /** + * @wbp.parser.constructor + */ + public TPanel(KLALBRemoteLine t) { + this.tunnel = t; + setOpaque(false); + setLayout(new BorderLayout(0, 0)); + + tname = new JLabel(); + if(t.getSocketAddress()!=null) { + tname.setText(t.getSocketAddress().toString()); + }else { + tname.setText(t.getKplink().toString()); + } + tname.setFont(new Font("宋体", Font.BOLD, 16)); + add(tname, BorderLayout.WEST); + + targ = new JLabel(); + targ.setFont(new Font("宋体", Font.PLAIN, 13)); + targ.setHorizontalAlignment(SwingConstants.TRAILING); + targ.setForeground(Color.YELLOW); + add(targ, BorderLayout.CENTER); + + setBorder(new LineBorder(Color.BLACK)); + setSize(650, 25); + setPreferredSize(getSize()); + } + + private volatile long up, down, ups, downs; + private volatile long delay=Long.MAX_VALUE; + + public long getDelay() { + return delay; + } + + private void updateText() { + String dl; + if (delay == Long.MIN_VALUE) + dl = "??"; + else + dl = Long.toString(delay / 1000000L); + targ.setText(bytesUnit(up) + "\u2191 " + bytesUnit(down) + "\u2193 " + bytesUnit(ups) + "/s\u2191 " + + bytesUnit(downs) + "/s\u2193 " + dl + "ms"); + } + + public KLALBRemoteLine getTunnel() { + return tunnel; + } + + private String bytesUnit(long v) { + if (v >= 1024L * 1024 * 1024 * 1024 * 1024) { + return String.format("%.1f", v / (1024.0 * 1024.0 * 1024.0 * 1024.0 * 1024.0)) + "PB"; + } else if (v >= 1024L * 1024 * 1024 * 1024) { + return String.format("%.1f", v / (1024.0 * 1024.0 * 1024.0 * 1024.0)) + "TB"; + } else if (v >= 1024L * 1024 * 1024) { + return String.format("%.1f", v / (1024.0 * 1024.0 * 1024.0)) + "GB"; + } else if (v >= 1024L * 1024) { + return String.format("%.1f", v / (1024.0 * 1024.0)) + "MB"; + } else if (v >= 1024L) { + return String.format("%.1f", v / (1024.0)) + "KB"; + } else { + return v + "B"; + } + } + + public void updateTraffic() { + switch (tunnel.getMonitor().getState()) { + case Monitor.OFFLINE: + tname.setForeground(Color.RED); + break; + case Monitor.CONNECTING: + tname.setForeground(Color.YELLOW); + break; + case Monitor.ONLINE: + tname.setForeground(Color.GREEN); + break; + default: + break; + } + up = tunnel.getMonitor().getOutTraffic(); + down = tunnel.getMonitor().getInTraffic(); + this.ups = tunnel.getMonitor().getOutSpeed(); + this.downs = tunnel.getMonitor().getInSpeed(); + this.delay = tunnel.getMonitor().getLatencyAvg(); + //System.out.println(delay); + updateText(); + } + +} diff --git a/src/org/kne/cloud/network/klalb/VADDRACKPacket.java b/src/org/kne/cloud/network/klalb/VADDRACKPacket.java new file mode 100644 index 0000000..1ad2de8 --- /dev/null +++ b/src/org/kne/cloud/network/klalb/VADDRACKPacket.java @@ -0,0 +1,14 @@ +package org.kne.cloud.network.klalb; + +public class VADDRACKPacket extends KLALBPacket { + + public VADDRACKPacket() { + super(VADDRACK); + } + + @Override + public String toString() { + return "VADDRACK"; + } + +} diff --git a/src/org/kne/cloud/network/klalb/VADDRREQPacket.java b/src/org/kne/cloud/network/klalb/VADDRREQPacket.java new file mode 100644 index 0000000..1859285 --- /dev/null +++ b/src/org/kne/cloud/network/klalb/VADDRREQPacket.java @@ -0,0 +1,14 @@ +package org.kne.cloud.network.klalb; + +public class VADDRREQPacket extends KLALBPacket { + + public VADDRREQPacket() { + super(VADDRREQ); + } + + @Override + public String toString() { + return "VADDRREQ"; + } + +} diff --git a/src/org/kne/cloud/network/minecraft/KLALBJsonMotdInserter.java b/src/org/kne/cloud/network/minecraft/KLALBJsonMotdInserter.java new file mode 100644 index 0000000..e8eef76 --- /dev/null +++ b/src/org/kne/cloud/network/minecraft/KLALBJsonMotdInserter.java @@ -0,0 +1,37 @@ +package org.kne.cloud.network.minecraft; + +import java.net.Inet6Address; +import java.util.function.Function; +import java.util.function.Supplier; + +import org.kne.cloud.network.klalb.CONST; + +import com.google.gson.JsonObject; +import com.google.gson.JsonParser; + +public class KLALBJsonMotdInserter implements Function { + private Supplier vaddrsup; + private Suppliervportsup; + @Override + public MinecraftPacket apply(MinecraftPacket t) { + if(t instanceof MinecraftMotdResponse) { + String src=((MinecraftMotdResponse) t).getJson(); + JsonObject jo=(JsonObject) new JsonParser().parse(src); + JsonObject jok=new JsonObject(); + jok.addProperty("version", CONST.klalbver); + jok.addProperty("vaddr", vaddrsup.get().getHostAddress()); + jok.addProperty("vport", vportsup.get()); + jo.add("KLALB", jok); + String des=jo.toString(); + //System.out.println(des); + return new MinecraftMotdResponse(des); + } + return t; + } + public KLALBJsonMotdInserter(Supplier vaddrsup, Supplier vportsup) { + super(); + this.vaddrsup = vaddrsup; + this.vportsup = vportsup; + } + +} diff --git a/src/org/kne/cloud/network/minecraft/MinecraftDefaultPacket.java b/src/org/kne/cloud/network/minecraft/MinecraftDefaultPacket.java new file mode 100644 index 0000000..0860a88 --- /dev/null +++ b/src/org/kne/cloud/network/minecraft/MinecraftDefaultPacket.java @@ -0,0 +1,35 @@ +package org.kne.cloud.network.minecraft; + +import java.io.IOException; + +import org.kne.io.VarDataInputStream; +import org.kne.io.VarDataOutputStream; + +public class MinecraftDefaultPacket extends MinecraftPacket { + private byte[]data; + + public byte[] getData() { + return data; + } + + public MinecraftDefaultPacket(int type) { + super(type ); + } + + @Override + protected void writeToStream(VarDataOutputStream dto) throws IOException { + super.writeToStream(dto); + dto.write(data); + } + + @Override + protected void readFromStream(VarDataInputStream din) throws IOException { + super.readFromStream(din); + data=din.readAllBytes(); + } + + public MinecraftDefaultPacket( int type, byte[] data) { + super(type); + this.data = data; + } +} diff --git a/src/org/kne/cloud/network/minecraft/MinecraftHandShakePacket.java b/src/org/kne/cloud/network/minecraft/MinecraftHandShakePacket.java new file mode 100644 index 0000000..7e79785 --- /dev/null +++ b/src/org/kne/cloud/network/minecraft/MinecraftHandShakePacket.java @@ -0,0 +1,57 @@ +package org.kne.cloud.network.minecraft; + +import java.io.IOException; + +import org.kne.io.VarDataInputStream; +import org.kne.io.VarDataOutputStream; + +public class MinecraftHandShakePacket extends MinecraftPacket { + int version; + String addr; + int port; + int nextstate; + public MinecraftHandShakePacket() { + super(HANDSHAKE_MOTD); + } + public MinecraftHandShakePacket( int version, String addr, int port, int nextstate) { + super(HANDSHAKE_MOTD); + this.version = version; + this.addr = addr; + this.port = port; + this.nextstate = nextstate; + } + public int getVersion() { + return version; + } + @Override + public String toString() { + return "MinecraftHandShakePacket [version=" + version + ", addr=" + addr + ", port=" + port + ", nextstate=" + + nextstate + "]"; + } + public String getAddr() { + return addr; + } + public int getPort() { + return port; + } + public int getNextstate() { + return nextstate; + } + @Override + protected void writeToStream(VarDataOutputStream dto) throws IOException { + super.writeToStream(dto); + dto.writeVarInt(version); + dto.writeVarUTF8(addr); + dto.writeShort(port); + dto.writeVarInt(nextstate); + } + @Override + protected void readFromStream(VarDataInputStream din) throws IOException { + super.readFromStream(din); + version=din.readVarInt(); + addr=din.readVarUTF8(); + port=din.readUnsignedShort(); + nextstate=din.readVarInt(); + } + +} diff --git a/src/org/kne/cloud/network/minecraft/MinecraftInputStream.java b/src/org/kne/cloud/network/minecraft/MinecraftInputStream.java new file mode 100644 index 0000000..9d6b1fc --- /dev/null +++ b/src/org/kne/cloud/network/minecraft/MinecraftInputStream.java @@ -0,0 +1,116 @@ +package org.kne.cloud.network.minecraft; +import static org.kne.cloud.network.minecraft.MinecraftPacket.*; + +import java.io.BufferedInputStream; +import java.io.ByteArrayInputStream; +import java.io.FilterInputStream; +import java.io.IOException; +import java.io.InputStream; + +import org.kne.cloud.network.klalb.PINGPacket; +import org.kne.io.VarDataInputStream; + +public class MinecraftInputStream extends VarDataInputStream { + private MinecraftProtocolContext context; + public MinecraftInputStream(InputStream in,MinecraftProtocolContext context) { + super(grin(in)); + this.context=context; + } + private static InputStream grin(InputStream in) { + InputStream rin; + if(in.markSupported()) { + rin=in; + }else { + rin=new BufferedInputStream(in,8192); + } + return rin; + } + public MinecraftProtocolContext getContext() { + return context; + } + public MinecraftPacket readPacket() throws IOException { + mark(1); + read(); + reset(); + if(context.getState()==2) { + MinecraftUnsolvedPacket mup=new MinecraftUnsolvedPacket(); + mup.readFromStream(this); + if(mup.getLenth()==-1) { + return null; + }else { + return mup; + } + } + byte[]b=readPacketVarBytes(); + if(b==null) + return null; + VarDataInputStream vdi=new VarDataInputStream(new ByteArrayInputStream(b)); + int type=vdi.readVarInt(); + MinecraftPacket mp; + if(context.isServer()) { + switch(context.getState()){ + case 0: + switch(type) { + case HANDSHAKE_MOTD: + mp=new MinecraftHandShakePacket(); + mp.readFromStream(vdi); + context.setState(((MinecraftHandShakePacket) mp).getNextstate()); + break; + + default : + mp=new MinecraftDefaultPacket(type); + mp.readFromStream(vdi); + break; + } + break; + case 1: + switch(type) { + case HANDSHAKE_MOTD: + mp=new MinecraftMotdRequest(); + mp.readFromStream(vdi); + break; + case PING_PONG: + mp=new MinecraftPingPacket(); + mp.readFromStream(vdi); + break; + default : + mp=new MinecraftDefaultPacket(type); + mp.readFromStream(vdi); + break; + } + break; + default: + mp=new MinecraftDefaultPacket(type); + mp.readFromStream(vdi); + break; + } + + }else { + switch(context.getState()) { + case 1: + switch(type) { + case HANDSHAKE_MOTD: + + mp=new MinecraftMotdResponse(); + mp.readFromStream(vdi); + break; + case PING_PONG: + mp=new MinecraftPongPacket(); + mp.readFromStream(vdi); + break; + default: + mp=new MinecraftDefaultPacket(type); + mp.readFromStream(vdi); + break; + } + break; + + default : + mp=new MinecraftDefaultPacket(type); + mp.readFromStream(vdi); + } + } + //System.out.println(mp); + return mp; + } +} diff --git a/src/org/kne/cloud/network/minecraft/MinecraftMotdRequest.java b/src/org/kne/cloud/network/minecraft/MinecraftMotdRequest.java new file mode 100644 index 0000000..972efbd --- /dev/null +++ b/src/org/kne/cloud/network/minecraft/MinecraftMotdRequest.java @@ -0,0 +1,14 @@ +package org.kne.cloud.network.minecraft; + +public class MinecraftMotdRequest extends MinecraftPacket { + + @Override + public String toString() { + return "MotdMinecraftRequest []"; + } + + public MinecraftMotdRequest() { + super(HANDSHAKE_MOTD); + } + +} diff --git a/src/org/kne/cloud/network/minecraft/MinecraftMotdResponse.java b/src/org/kne/cloud/network/minecraft/MinecraftMotdResponse.java new file mode 100644 index 0000000..7d8fbb9 --- /dev/null +++ b/src/org/kne/cloud/network/minecraft/MinecraftMotdResponse.java @@ -0,0 +1,38 @@ +package org.kne.cloud.network.minecraft; + +import java.io.IOException; + +import org.kne.io.VarDataInputStream; +import org.kne.io.VarDataOutputStream; + +public class MinecraftMotdResponse extends MinecraftPacket { + private String json; + + public String getJson() { + return json; + } + public MinecraftMotdResponse(String json) { + this(); + this.json=json; + } + @Override + public String toString() { + return "MotdMinecraftResponse [json=" + json + "]"; + } + public MinecraftMotdResponse() { + super(HANDSHAKE_MOTD); + } + + @Override + protected void writeToStream(VarDataOutputStream dto) throws IOException { + super.writeToStream(dto); + dto.writeVarUTF8(json); + } + + @Override + protected void readFromStream(VarDataInputStream din) throws IOException { + super.readFromStream(din); + json=din.readVarUTF8(); + } + +} diff --git a/src/org/kne/cloud/network/minecraft/MinecraftOutputStream.java b/src/org/kne/cloud/network/minecraft/MinecraftOutputStream.java new file mode 100644 index 0000000..64bea18 --- /dev/null +++ b/src/org/kne/cloud/network/minecraft/MinecraftOutputStream.java @@ -0,0 +1,38 @@ +package org.kne.cloud.network.minecraft; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.OutputStream; + +import javax.net.ssl.HandshakeCompletedEvent; + +import org.kne.io.VarDataOutputStream; + +public class MinecraftOutputStream extends VarDataOutputStream { + ByteArrayOutputStream bao=new ByteArrayOutputStream(); + private MinecraftProtocolContext context; + + public MinecraftOutputStream(OutputStream out,MinecraftProtocolContext context) { + super(out); + this.context=context; + } + public MinecraftProtocolContext getContext() { + return context; + } + public void writePacket(MinecraftPacket mp) throws IOException { + if (mp instanceof MinecraftUnsolvedPacket) { + mp.writeToStream(this); + }else { + VarDataOutputStream vdo=new VarDataOutputStream(bao); + vdo.writeVarInt(mp.getType()); + mp.writeToStream(vdo); + byte[]baob=bao.toByteArray(); + bao.reset(); + writeVarBytes(baob); + if(mp instanceof MinecraftHandShakePacket) { + MinecraftHandShakePacket hsmp=(MinecraftHandShakePacket) mp; + context.setState(hsmp.getNextstate()); + } + } + } +} diff --git a/src/org/kne/cloud/network/minecraft/MinecraftPacket.java b/src/org/kne/cloud/network/minecraft/MinecraftPacket.java new file mode 100644 index 0000000..c86f3b0 --- /dev/null +++ b/src/org/kne/cloud/network/minecraft/MinecraftPacket.java @@ -0,0 +1,45 @@ +package org.kne.cloud.network.minecraft; + +import java.io.DataInput; +import java.io.DataOutput; +import java.io.IOException; + +import org.kne.io.VarDataInputStream; +import org.kne.io.VarDataOutputStream; + +public abstract class MinecraftPacket { + public static final int HANDSHAKE_MOTD=0x00; + public static final int PING_PONG=0x01; + private int type; + private boolean solved; + public int getType() { + return type; + } + +public boolean isSolved() { + return solved; + } + +@Override + public String toString() { + return "MinecraftPacket [type=" + type + "]"; + } + +public MinecraftPacket(boolean solved) { + super(); + this.solved = solved; +} + +public MinecraftPacket(int type) { + super(); + this.type = type; + } + +protected void writeToStream(VarDataOutputStream dto) throws IOException { + + } + protected void readFromStream(VarDataInputStream din) throws IOException { + + } + +} diff --git a/src/org/kne/cloud/network/minecraft/MinecraftPingPacket.java b/src/org/kne/cloud/network/minecraft/MinecraftPingPacket.java new file mode 100644 index 0000000..54235ef --- /dev/null +++ b/src/org/kne/cloud/network/minecraft/MinecraftPingPacket.java @@ -0,0 +1,35 @@ +package org.kne.cloud.network.minecraft; + +import java.io.IOException; + +import org.kne.io.VarDataInputStream; +import org.kne.io.VarDataOutputStream; + +public class MinecraftPingPacket extends MinecraftPacket{ + private long time; + public long getTime() { + return time; + } + public MinecraftPingPacket() { + super(PING_PONG); + } + public MinecraftPingPacket( long time) { + super(PING_PONG); + this.time = time; + } + @Override + public String toString() { + return "MinecraftPingPacket [time=" + time + "]"; + } + @Override + protected void writeToStream(VarDataOutputStream dto) throws IOException { + super.writeToStream(dto); + dto.writeLong(time); + } + @Override + protected void readFromStream(VarDataInputStream din) throws IOException { + super.readFromStream(din); + time=din.readLong(); + } + +} diff --git a/src/org/kne/cloud/network/minecraft/MinecraftPongPacket.java b/src/org/kne/cloud/network/minecraft/MinecraftPongPacket.java new file mode 100644 index 0000000..0a69940 --- /dev/null +++ b/src/org/kne/cloud/network/minecraft/MinecraftPongPacket.java @@ -0,0 +1,34 @@ +package org.kne.cloud.network.minecraft; + +import java.io.IOException; + +import org.kne.io.VarDataInputStream; +import org.kne.io.VarDataOutputStream; + +public class MinecraftPongPacket extends MinecraftPacket{ + private long time; + public long getTime() { + return time; + } + public MinecraftPongPacket( long time) { + super(PING_PONG); + this.time = time; + } + @Override + public String toString() { + return "MinecraftPongPacket [time=" + time + "]"; + } + public MinecraftPongPacket() { + super(PING_PONG); + } + @Override + protected void writeToStream(VarDataOutputStream dto) throws IOException { + super.writeToStream(dto); + dto.writeLong(time); + } + @Override + protected void readFromStream(VarDataInputStream din) throws IOException { + super.readFromStream(din); + time=din.readLong(); + } +} diff --git a/src/org/kne/cloud/network/minecraft/MinecraftProtocolContext.java b/src/org/kne/cloud/network/minecraft/MinecraftProtocolContext.java new file mode 100644 index 0000000..a5d639a --- /dev/null +++ b/src/org/kne/cloud/network/minecraft/MinecraftProtocolContext.java @@ -0,0 +1,22 @@ +package org.kne.cloud.network.minecraft; + +public class MinecraftProtocolContext { + private boolean server; + private volatile int state=0; + public boolean isServer() { + return server; + } + public int getState() { + return state; + } + protected void setState(int state) { + this.state = state; + } + public MinecraftProtocolContext() { + this(false); + } + public MinecraftProtocolContext(boolean server) { + super(); + this.server = server; + } +} diff --git a/src/org/kne/cloud/network/minecraft/MinecraftServerAddress.java b/src/org/kne/cloud/network/minecraft/MinecraftServerAddress.java new file mode 100644 index 0000000..946a77b --- /dev/null +++ b/src/org/kne/cloud/network/minecraft/MinecraftServerAddress.java @@ -0,0 +1,119 @@ +package org.kne.cloud.network.minecraft; + +import java.net.IDN; +import java.util.Hashtable; +import javax.naming.directory.Attributes; +import javax.naming.directory.DirContext; +import javax.naming.directory.InitialDirContext; + +import org.kne.cloud.network.MultipurposeSocketAddress; + +public class MinecraftServerAddress extends MultipurposeSocketAddress +{ + + private String originAddr; + private int originPort; + private String originStr; + public int getOriginPort() { + return originPort; + } + public String getOriginAddr() { + return originAddr; + } + public String toOriginString() { + return originStr; + } + private MinecraftServerAddress(String ip, int port,String originaddr, int originPort, String addr) + { + super(IDN.toASCII(ip),port); + this.originAddr=originaddr; + this.originPort=originPort; + this.originStr=addr; + } + public static MinecraftServerAddress findAddress(String addr) + { + if (addr == null) + { + return null; + } + else + { + String[] astring = addr.split(":"); + + if (addr.startsWith("[")) + { + int i = addr.indexOf("]"); + + if (i > 0) + { + String s = addr.substring(1, i); + String s1 = addr.substring(i + 1).trim(); + + if (s1.startsWith(":") && s1.length() > 0) + { + s1 = s1.substring(1); + astring = new String[] {s, s1}; + } + else + { + astring = new String[] {s}; + } + } + } + + if (astring.length > 2) + { + astring = new String[] {addr}; + } + + String s2 = astring[0]; + String oaddr=s2; + int j = astring.length > 1 ? parseIntWithDefault(astring[1], 25565) : 25565; + int oport=j; + if (j == 25565) + { + String[] astring1 = getServerAddress(s2); + s2 = astring1[0]; + j = parseIntWithDefault(astring1[1], 25565); + } + + return new MinecraftServerAddress(s2, j,oaddr,oport,addr); + } + } + + /** + * Returns a server's address and port for the specified hostname, looking up the SRV record if possible + */ + private static String[] getServerAddress(String p_78863_0_) + { + try + { + String s = "com.sun.jndi.dns.DnsContextFactory"; + Class.forName("com.sun.jndi.dns.DnsContextFactory"); + Hashtable hashtable = new Hashtable(); + hashtable.put("java.naming.factory.initial", "com.sun.jndi.dns.DnsContextFactory"); + hashtable.put("java.naming.provider.url", "dns:"); + hashtable.put("com.sun.jndi.dns.timeout.retries", "1"); + DirContext dircontext = new InitialDirContext(hashtable); + Attributes attributes = dircontext.getAttributes("_minecraft._tcp." + p_78863_0_, new String[] {"SRV"}); + String[] astring = attributes.get("srv").get().toString().split(" ", 4); + return new String[] {astring[3], astring[2]}; + } + catch (Throwable var6) + { + return new String[] {p_78863_0_, Integer.toString(25565)}; + } + } + + private static int parseIntWithDefault(String str, int def) + { + try + { + return Integer.parseInt(str.trim()); + } + catch (Exception e) + { + return def; + } + } +} diff --git a/src/org/kne/cloud/network/minecraft/MinecraftServerPinger.java b/src/org/kne/cloud/network/minecraft/MinecraftServerPinger.java new file mode 100644 index 0000000..8748e92 --- /dev/null +++ b/src/org/kne/cloud/network/minecraft/MinecraftServerPinger.java @@ -0,0 +1,299 @@ +package org.kne.cloud.network.minecraft; + +import java.awt.image.BufferedImage; +import java.io.ByteArrayInputStream; +import java.io.EOFException; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.io.StringReader; +import java.net.Inet6Address; +import java.net.InetAddress; +import java.net.Socket; +import java.net.UnknownHostException; +import java.util.Base64; + +import javax.imageio.ImageIO; + +import org.kne.cloud.network.MultipurposeSocketAddress; + +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import com.google.gson.JsonParser; +import com.google.gson.stream.JsonReader; +import com.google.gson.stream.JsonToken; + +public class MinecraftServerPinger { + private Socket socket; + private MinecraftProtocolContext mpc=new MinecraftProtocolContext(); + private MultipurposeSocketAddress targetaddr; + + + + private long latency=-1; + private String json; + private BufferedImage icon; + private int max; + private int online; + private String description; + private boolean isOldDescription; + private String version; + private int protocol; + private String klalbversion; + private Inet6Address klalbvaddr; + private int klalbvport; + + public MinecraftServerPinger(MultipurposeSocketAddress target) throws UnknownHostException, IOException { + targetaddr=target; + socket=target.connectSocket(); + socket.setTcpNoDelay(true); + ping(); + analyseJson(); + } + + private void ping() throws IOException { + MinecraftInputStream in=null; + MinecraftOutputStream out=null; + try { + in=new MinecraftInputStream(socket.getInputStream(), mpc); + out=new MinecraftOutputStream(socket.getOutputStream(), mpc); + if(targetaddr instanceof MinecraftServerAddress) { + out.writePacket(new MinecraftHandShakePacket(763, ((MinecraftServerAddress) targetaddr).getOriginAddr(), ((MinecraftServerAddress) targetaddr).getOriginPort(), 1)); + }else { + out.writePacket(new MinecraftHandShakePacket(763, targetaddr.getHost(), targetaddr.getPort(), 1)); + } + out.writePacket(new MinecraftMotdRequest()); + out.flush(); + MinecraftMotdResponse resp=(MinecraftMotdResponse) in.readPacket(); + if(resp==null) + throw new EOFException(); + json=resp.getJson(); + long pst=System.nanoTime(); + out.writePacket(new MinecraftPingPacket(pst)); + out.flush(); + try { + MinecraftPongPacket repo=(MinecraftPongPacket) in.readPacket(); + latency=System.nanoTime()-repo.getTime(); + }catch(EOFException e) { + + } + + }finally { + try { + if(in!=null) + in.close(); + }catch(IOException e) {} + + try { + if(out!=null) + out.close(); + + }catch(IOException e) {} + try { + if(socket!=null) + socket.close(); + }catch(IOException e) {} + } + } + private void analyseJson() { + // System.out.println(json); + JsonObject jobj= (JsonObject) new JsonParser().parse(json); + + JsonObject versiont=(JsonObject) jobj.get("version"); + if(versiont!=null) { + version=versiont.get("name").getAsString(); + protocol=versiont.get("protocol").getAsInt(); + } + + JsonObject players=(JsonObject) jobj.get("players"); + if(players!=null) { + max=players.get("max").getAsInt(); + online=players.get("online").getAsInt(); + } + + JsonElement descriptionj =jobj.get("description"); + if(descriptionj!=null) { + isOldDescription=!(descriptionj instanceof JsonObject); + if(isOldDescription) { + description=descriptionj.getAsString(); + }else { + description=descriptionj.toString(); + } + } + + JsonElement klalb= jobj.get("KLALB"); + if(klalb!=null&&(klalb instanceof JsonObject)) { + JsonObject jobk=(JsonObject) klalb; + klalbversion=jobk.get("version").getAsString(); + try { + klalbvaddr=(Inet6Address) InetAddress.getByName( jobk.get("vaddr").getAsString()); + } catch (UnknownHostException e) { + e.printStackTrace(); + } + klalbvport=jobk.get("vport").getAsInt(); + } + + JsonElement favicon= jobj.get("favicon"); + if(favicon!=null) { + String s=favicon.getAsString(); + if(s.startsWith("data:image/png;base64,")){ + s=s.replace("\n", ""); + try { + icon=ImageIO.read(new ByteArrayInputStream(Base64.getDecoder().decode(s.substring("data:image/png;base64,".length())))); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + /*try { + JsonReader jr = new JsonReader(new StringReader(json)); + jr.setLenient(true); + jr.beginObject(); + while (jr.hasNext()) { + String n0 = jr.nextName(); + switch (n0) { + case "version": + jr.beginObject(); + while (jr.hasNext()) { + String n1 = jr.nextName(); + switch (n1) { + case "name": + version=jr.nextString(); + break; + + default: + jr.skipValue(); + break; + } + } + jr.endObject(); + break; + case "players": + jr.beginObject(); + while (jr.hasNext()) { + String n1 = jr.nextName(); + switch (n1) { + case "max": + max=jr.nextInt(); + break; + case "online": + online=jr.nextInt(); + break; + default: + jr.skipValue(); + break; + } + } + jr.endObject(); + break; + case "description": + JsonToken j=jr.peek(); + + if(j.equals(JsonToken.BEGIN_OBJECT)){ + jr.beginObject(); + while (jr.hasNext()) { + String n1 = jr.nextName(); + switch (n1) { + + case "text": + description=jr.nextString(); + break; + default: + jr.skipValue(); + break; + } + } + jr.endObject(); + }else{ + description=jr.nextString(); + } + break; + case "favicon": + String s=jr.nextString(); + if(s.startsWith("data:image/png;base64,")){ + s=s.replace("\n", ""); + icon=ImageIO.read(new ByteArrayInputStream(Base64.getDecoder().decode(s.substring("data:image/png;base64,".length())))); + } + break; + case "KLALB": + klalbversion=jr.nextString(); + break; + default: + jr.skipValue(); + break; + } + } + jr.endObject(); + jr.close(); + //System.out.println(time); + } catch (IOException e) { + e.printStackTrace(); + }*/ + } + + @Override + public String toString() { + return "MinecraftServerPinger [targetaddr=" + targetaddr + ", latency=" + latency + ", json=" + json + ", icon=" + + icon + ", max=" + max + ", online=" + online + ", description=" + description + ", isOldDescription=" + + isOldDescription + ", version=" + version + ", protocol=" + protocol + ", klalbversion=" + + klalbversion + ", klalbvaddr=" + klalbvaddr+ ", klalbvport=" + klalbvport+ "]"; + } + + public String getKlalbversion() { + return klalbversion; + } + + public Inet6Address getKlalbvaddr() { + return klalbvaddr; + } + + public int getKlalbvport() { + return klalbvport; + } + + public BufferedImage getIcon() { + return icon; + } + + public int getMax() { + return max; + } + + public int getOnline() { + return online; + } + + public String getDescription() { + return description; + } + + public String getVersion() { + return version; + } + + public int getProtocol() { + return protocol; + } + + + public boolean isOldDescription() { + return isOldDescription; + } + + public String getJson() { + return json; + } + + public MultipurposeSocketAddress getTargetaddr() { + return targetaddr; + } + + public long getLatency() { + return latency; + } + + public static void main(String[] args) throws UnknownHostException, IOException {//hypixel.net + MinecraftServerPinger sp=new MinecraftServerPinger(MinecraftServerAddress.findAddress("mc.hypixel.cn")); + System.out.println(sp); + } +} diff --git a/src/org/kne/cloud/network/minecraft/MinecraftSocketBridge.java b/src/org/kne/cloud/network/minecraft/MinecraftSocketBridge.java new file mode 100644 index 0000000..ba5a98c --- /dev/null +++ b/src/org/kne/cloud/network/minecraft/MinecraftSocketBridge.java @@ -0,0 +1,47 @@ +package org.kne.cloud.network.minecraft; + +import java.io.IOException; +import java.net.Socket; + +import org.kne.cloud.network.SocketBridge; +import org.kne.cloud.network.StreamBridge; + +public class MinecraftSocketBridge extends SocketBridge{ + private MinecraftProtocolContext mpca; + private MinecraftProtocolContext mpcb; + public MinecraftSocketBridge(Socket a, Socket b) throws IOException { + super(a, b); + } + + @Override + protected void createStreamBridge() throws IOException { + if(mpca==null) + mpca=new MinecraftProtocolContext(true); + if(mpcb==null) + mpcb=new MinecraftProtocolContext(false); + bridgeAB = new MinecraftStreamBridge(a.getInputStream(),mpca, b.getOutputStream(),mpcb,true); + bridgeBA = new MinecraftStreamBridge(b.getInputStream(),mpcb, a.getOutputStream(),mpca,false); + } + + public MinecraftProtocolContext getMpca() { + return mpca; + } + + public MinecraftProtocolContext getMpcb() { + return mpcb; + } + + @Override + public MinecraftStreamBridge getBridgeAB() { + // TODO 自动生成的方法存根 + return (MinecraftStreamBridge) super.getBridgeAB(); + } + + @Override + public MinecraftStreamBridge getBridgeBA() { + // TODO 自动生成的方法存根 + return (MinecraftStreamBridge) super.getBridgeBA(); + } + + +} diff --git a/src/org/kne/cloud/network/minecraft/MinecraftSocketToSocketProxy.java b/src/org/kne/cloud/network/minecraft/MinecraftSocketToSocketProxy.java new file mode 100644 index 0000000..0364865 --- /dev/null +++ b/src/org/kne/cloud/network/minecraft/MinecraftSocketToSocketProxy.java @@ -0,0 +1,55 @@ +package org.kne.cloud.network.minecraft; + +import java.io.IOException; +import java.net.Socket; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.function.Function; + +import org.kne.cloud.network.HostPortMap; +import org.kne.cloud.network.MultipurposeSocketAddress; +import org.kne.cloud.network.SocketToSocketProxy; + +public class MinecraftSocketToSocketProxy extends SocketToSocketProxy { + private List> transformersAB=new ArrayList>(); + private List> transformersBA=new ArrayList>(); + public List> getTransformersAB() { + return transformersAB; + } + + public List> getTransformersBA() { + return transformersBA; + } + + public MinecraftSocketToSocketProxy(MultipurposeSocketAddress listen, MultipurposeSocketAddress cbind, + MultipurposeSocketAddress defaultConnect, Map detectedConnect) + throws IOException { + super(listen, cbind, defaultConnect, detectedConnect); + } + + public MinecraftSocketToSocketProxy(MultipurposeSocketAddress listen, MultipurposeSocketAddress cbind, + MultipurposeSocketAddress defaultConnect) throws IOException { + super(listen, cbind, defaultConnect); + } + + public MinecraftSocketToSocketProxy(MultipurposeSocketAddress listen, MultipurposeSocketAddress connect) + throws IOException { + super(listen, connect); + } + + public MinecraftSocketToSocketProxy(String l, String r) throws IOException { + super(l, r); + } + + + + @Override + protected void runBridge(Socket sk, Socket sox) throws IOException {//new KLALBJsonMotdInserter(()->{return kc.getSelf();},()->{return 23333;}) + MinecraftSocketBridge dsb=new MinecraftSocketBridge(sk,sox); + dsb.getBridgeAB().getTransformers().addAll(transformersAB); + dsb.getBridgeBA().getTransformers().addAll(transformersBA); + dsb.run(); + } + +} diff --git a/src/org/kne/cloud/network/minecraft/MinecraftStreamBridge.java b/src/org/kne/cloud/network/minecraft/MinecraftStreamBridge.java new file mode 100644 index 0000000..300cec9 --- /dev/null +++ b/src/org/kne/cloud/network/minecraft/MinecraftStreamBridge.java @@ -0,0 +1,59 @@ +package org.kne.cloud.network.minecraft; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.function.Function; + +import org.kne.cloud.network.StreamBridge; + +public class MinecraftStreamBridge extends StreamBridge { + private List>transformers=new ArrayList>(); + public List> getTransformers() { + return transformers; + } + + @Override + public void runTask() { + MinecraftInputStream min=(MinecraftInputStream) in; + MinecraftOutputStream mout=(MinecraftOutputStream) out; + try { + MinecraftPacket mp=null; + while ((mp=min.readPacket())!=null) { + for (Iterator> iterator = transformers.iterator(); iterator.hasNext();) { + Function function = (Function) iterator + .next(); + mp=function.apply(mp); + } + mout.writePacket(mp); + mout.flush(); + //System.out.println(mp); + } + //super.runTask(); + } catch (IOException e) { + // TODO 自动生成的 catch 块 + e.printStackTrace(); + }finally { + try { + in.close(); + } catch (IOException e) { + // TODO 自动生成的 catch 块 + e.printStackTrace(); + } + try { + out.close(); + } catch (IOException e) { + // TODO 自动生成的 catch 块 + e.printStackTrace(); + } + } + } + + public MinecraftStreamBridge(InputStream in,MinecraftProtocolContext cin, OutputStream out,MinecraftProtocolContext cout, boolean server) { + super(new MinecraftInputStream( in,cin), new MinecraftOutputStream( out,cout)); + } + +} diff --git a/src/org/kne/cloud/network/minecraft/MinecraftUnsolvedPacket.java b/src/org/kne/cloud/network/minecraft/MinecraftUnsolvedPacket.java new file mode 100644 index 0000000..2d57a07 --- /dev/null +++ b/src/org/kne/cloud/network/minecraft/MinecraftUnsolvedPacket.java @@ -0,0 +1,39 @@ +package org.kne.cloud.network.minecraft; + +import java.io.IOException; + +import org.kne.io.VarDataInputStream; +import org.kne.io.VarDataOutputStream; + +public class MinecraftUnsolvedPacket extends MinecraftPacket{ + private byte[]data; + public byte[] getData() { + return data; + } + public int getLenth() { + return length; + } + public MinecraftUnsolvedPacket( ) { + super(false); + this.data = new byte[8192]; + this.length = data.length; + + } + public MinecraftUnsolvedPacket( byte[] data, int length) { + super(false); + this.data = data; + this.length = length; + } + private int length; + @Override + protected void writeToStream(VarDataOutputStream dto) throws IOException { + super.writeToStream(dto); + dto.write(data, 0, length); + } + @Override + protected void readFromStream(VarDataInputStream din) throws IOException { + super.readFromStream(din); + length=din.read(data); + } + +} diff --git a/src/org/kne/cloud/network/minecraft/SimpleKLALBMinecraftClient.java b/src/org/kne/cloud/network/minecraft/SimpleKLALBMinecraftClient.java new file mode 100644 index 0000000..8d06415 --- /dev/null +++ b/src/org/kne/cloud/network/minecraft/SimpleKLALBMinecraftClient.java @@ -0,0 +1,67 @@ +package org.kne.cloud.network.minecraft; + +import java.io.File; +import java.io.IOException; +import java.net.Inet6Address; +import java.net.InetSocketAddress; +import java.net.ServerSocket; +import java.net.UnknownHostException; +import java.util.Iterator; +import java.util.List; +import java.util.Properties; +import java.util.Scanner; + +import org.kne.cloud.network.MultipurposeSocketAddress; +import org.kne.cloud.network.SocketBridge; +import org.kne.cloud.network.SocketListener; +import org.kne.cloud.network.SocketToSocketProxy; +import org.kne.cloud.network.klalb.CONST; +import org.kne.cloud.network.klalb.KLALBController; +import org.kne.cloud.network.klalb.KLALBRemoteLine; +import org.kne.util.AutoProperties; + +public class SimpleKLALBMinecraftClient { +public static void main(String[] args) throws UnknownHostException, IOException { + + System.out.println(CONST.klalb+" V"+CONST.klalbver); + Scanner scn=new Scanner(System.in); + Properties def=new Properties(); + def.setProperty("server", ""); + def.setProperty("local", ""); + AutoProperties ap=new AutoProperties(new File("klalbclient.ini"),def); + KLALBController kc=new KLALBController(); + kc.registerToProxyTypeAs("KLALB"); + MinecraftServerAddress msa=MinecraftServerAddress.findAddress(ap.getProperty("server")); + MinecraftServerPinger msp=new MinecraftServerPinger(msa); + if(msp.getKlalbversion()==null) { + System.out.println("服务器不支持加速!!"); + try { + Thread.sleep(1000); + } catch (InterruptedException e) { + e.printStackTrace(); + } + System.exit(0); + } + Inet6Address vad= kc.getRemoteVaddrBySocketAddress(msa); + MultipurposeSocketAddress vmsa=new MultipurposeSocketAddress("KLALB_Stream",new InetSocketAddress(vad, msp.getKlalbvport())); + System.out.println("连接成功:"+ap.getProperty("server")); + new SocketToSocketProxy(new MultipurposeSocketAddress(ap.getProperty("local")), vmsa); + System.out.println("提示:输入state并回车可以查看当前线路状态"); + while(true) { + String s=scn.nextLine(); + switch(s) { + case "state": + System.out.println("状态\t上传流量\t下载流量\t上传速度\t下载速度\t延迟\t抖动\t下一次重试"); + for (Iterator iterator = kc.getLines().iterator(); iterator.hasNext();) { + KLALBRemoteLine hostPort = iterator.next(); + System.out.println(hostPort .toString2()); + //System.out.println(); + } + break; + default : + System.out.println("未知命令!"); + + } + } +} +} diff --git a/src/org/kne/cloud/network/minecraft/SimpleKLALBMinecraftServer.java b/src/org/kne/cloud/network/minecraft/SimpleKLALBMinecraftServer.java new file mode 100644 index 0000000..4ea5099 --- /dev/null +++ b/src/org/kne/cloud/network/minecraft/SimpleKLALBMinecraftServer.java @@ -0,0 +1,194 @@ +package org.kne.cloud.network.minecraft; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileReader; +import java.io.IOException; +import java.net.Socket; +import java.net.UnknownHostException; +import java.util.Iterator; +import java.util.Scanner; + +import org.kne.cloud.network.MultipurposeSocketAddress; +import org.kne.cloud.network.ProtocolDetectorServerSocketFactory; +import org.kne.cloud.network.ProtocolDetectorSocket; +import org.kne.cloud.network.SocketListener; +import org.kne.cloud.network.SocketType; +import org.kne.cloud.network.klalb.CONST; +import org.kne.cloud.network.klalb.KLALBController; +import org.kne.cloud.network.klalb.KLALBRemoteLine; +import org.kne.cloud.network.klalb.KLALBVirtualSocket; +import org.kne.cloud.network.klalb.ServerPropties; +import org.kne.cloud.network.klalb.StreamKLALBPacketLink; + +public class SimpleKLALBMinecraftServer { + public static SocketListener tcpl,tcpl2; + public static ServerPropties sp; + public static KLALBController kc; + static { + MultipurposeSocketAddress.getSocketTypeRegister().put("DETTCP",new SocketType(null, new ProtocolDetectorServerSocketFactory())); + } + public static void main(String[] args) throws IOException { + + System.out.println(CONST.klalb+"[Minecraft版] V"+CONST.klalbver); + sp=new ServerPropties(); + + System.out.println("虚拟地址:"+sp.getVirtualIP().getHostAddress()); + kc=new KLALBController(sp.getVirtualIP()); + kc.setSelflineTableSupplier(()->{ + return fileRead("linetable.txt"); + }); + kc.registerToProxyTypeAs("KLALB"); + + System.out.println("开放端口:"+sp.getBind()); + openPort(sp.getBind()); + System.out.println("本地服务:"+sp.getLocal()); + openLocalPort(sp.getLocal()); + + + + Scanner scn=new Scanner(System.in); + while(true) { + String s=scn.next(); + String[]sc=s.split(" "); + switch(sc[0]) { + case "help": + System.out.print("state:查看线路状态"); + System.out.println("reload:重新加载线路配置"); + break; + case "state": + System.out.println("状态\t上传流量\t下载流量\t上传速度\t下载速度\t延迟\t抖动\t下一次重试"); + for (Iterator iterator = kc.getLines().iterator(); iterator.hasNext();) { + KLALBRemoteLine hostPort = iterator.next(); + System.out.println(hostPort .toString2()); + //System.out.println(); + } + break; + default: + System.out.println("未知命令,请输入help以查询指令说明"); + } + } + } + private static void openPort(String bip) throws IOException { + if(tcpl!=null) + tcpl.close(); + MultipurposeSocketAddress mpsa=new MultipurposeSocketAddress(bip,"DETTCP"); + tcpl=new SocketListener(mpsa); + tcpl.setCon((soc)->{ + ProtocolDetectorSocket pds=(ProtocolDetectorSocket) soc; + if(!pds.getProtocolStack().isEmpty()&&pds.getProtocolStack().pop().getName().equals("KLALB")) { + KLALBRemoteLine krs=null; + try { + krs = new KLALBRemoteLine(new StreamKLALBPacketLink(pds)); + kc.addRemoteLine(krs); + } catch (IOException e) { + e.printStackTrace(); + } + }else { + MultipurposeSocketAddress mpsa2=new MultipurposeSocketAddress(sp.getLocal()); + Socket s=null; + try { + s=mpsa2.connectSocket(); + MinecraftSocketBridge dsb=new MinecraftSocketBridge(pds, s); + dsb.getBridgeBA().getTransformers().add(new KLALBJsonMotdInserter(()->{return kc.getSelf();},()->{return 23333;})); + dsb.run(); + } catch (UnknownHostException e) { + // TODO 自动生成的 catch 块 + e.printStackTrace(); + } catch (IOException e) { + // TODO 自动生成的 catch 块 + e.printStackTrace(); + }finally { + if(s!=null) + try { + s.close(); + } catch (IOException e1) { + // TODO 自动生成的 catch 块 + e1.printStackTrace(); + } + try { + soc.close(); + } catch (IOException e) { + // TODO 自动生成的 catch 块 + e.printStackTrace(); + } + } + } + }); + } + private static void openLocalPort(String bip) throws IOException { + if(tcpl2!=null) + tcpl2.close(); + MultipurposeSocketAddress mpsa=new MultipurposeSocketAddress(bip); + tcpl2=new SocketListener(new MultipurposeSocketAddress("KLALB_Stream", "::0", 23333)); + tcpl2.setCon((soc)->{ + Socket s=null; + try { + s=mpsa.connectSocket(); + s.setTcpNoDelay(true); + //soc.setTcpNoDelay(true); + //((KLALBVirtualSocket) soc).setCompress(1); + MinecraftSocketBridge dsb=new MinecraftSocketBridge(soc, s); + dsb.getBridgeBA().getTransformers().add(new KLALBJsonMotdInserter(()->{return kc.getSelf();},()->{return 23333;})); + //dsb.getSab().setDelay(1); + dsb.run(); + /*CompressedSocketBridge csb=new CompressedSocketBridge(s, soc); + csb.getSab().setDelay(1); + csb.run();*/ + } catch (UnknownHostException e) { + // TODO 自动生成的 catch 块 + e.printStackTrace(); + } catch (IOException e) { + // TODO 自动生成的 catch 块 + e.printStackTrace(); + }finally { + if(s!=null) + try { + s.close(); + } catch (IOException e1) { + // TODO 自动生成的 catch 块 + e1.printStackTrace(); + } + try { + soc.close(); + } catch (IOException e) { + // TODO 自动生成的 catch 块 + e.printStackTrace(); + } + } + + }); + } + private static String fileRead(String filePath){ + //1.定义一个BufferedReader对象,将文件内容读取到缓存 + BufferedReader bufferedReader =null; + String returnInfo=""; + try{ + // 2.定义一个file对象 + File file = new File(filePath);//定义一个file对象,用来初始化FileReader + // 3.定义一个fileReader对象 + FileReader reader = new FileReader(file); + // 4.定义一个BufferedReader对象,将文件内容读取到缓存 + bufferedReader = new BufferedReader(reader); + // 5.定义一个字符串缓存,将字符串存放缓存中 + StringBuilder stringBuilder = new StringBuilder(); + String str = ""; + while ((str =bufferedReader.readLine()) != null) {//逐行读取文件内容,不读取换行符和末尾的空格 + stringBuilder.append(str + "\n");//将读取的字符串添加换行符后累加存放在缓存中 + } + returnInfo = stringBuilder.toString(); + }catch (Exception e){ + e.printStackTrace(); + }finally { + try{ + if(bufferedReader!=null){ + bufferedReader.close(); + } + }catch (Exception e){ + e.printStackTrace(); + } + } + return returnInfo; + } + +} diff --git a/src/org/kne/cloud/network/nathole/ICMPNatholeTest.java b/src/org/kne/cloud/network/nathole/ICMPNatholeTest.java new file mode 100644 index 0000000..5a1b7f5 --- /dev/null +++ b/src/org/kne/cloud/network/nathole/ICMPNatholeTest.java @@ -0,0 +1,27 @@ +package org.kne.cloud.network.nathole; + +import java.io.IOException; +import java.net.InetAddress; +import java.util.Arrays; + +public class ICMPNatholeTest { + public static void main(String[] args) throws IllegalStateException, IOException { + + } + public static String toString(byte[] a) { + if (a == null) + return "null"; + int iMax = a.length - 1; + if (iMax == -1) + return "[]"; + + StringBuilder b = new StringBuilder(); + b.append('['); + for (int i = 0; ; i++) { + b.append( Integer.toString(a[i]&0xff,16)); + if (i == iMax) + return b.append(']').toString(); + b.append(", "); + } + } +} diff --git a/src/org/kne/cloud/network/nathole/UDPNatholeTest.java b/src/org/kne/cloud/network/nathole/UDPNatholeTest.java new file mode 100644 index 0000000..69d95ef --- /dev/null +++ b/src/org/kne/cloud/network/nathole/UDPNatholeTest.java @@ -0,0 +1,42 @@ +package org.kne.cloud.network.nathole; + +import java.io.IOException; +import java.net.BindException; +import java.net.DatagramPacket; +import java.net.DatagramSocket; +import java.net.InetAddress; +import java.net.InetSocketAddress; +import java.net.MulticastSocket; +import java.net.Socket; +import java.net.SocketAddress; +import java.net.SocketOption; +import java.net.SocketOptions; +import java.nio.channels.SocketChannel; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; + +public class UDPNatholeTest { + public static ExecutorService exc=Executors.newCachedThreadPool(); + public static void main(String[] args) throws IOException { + InetAddress addr=InetAddress.getByName("10.235.16.1"); + for (int i1 = 1024; i1 < 65536; i1++) { + MulticastSocket ms=new MulticastSocket(i1); + //ms.setReuseAddress(true); + ms.setSendBufferSize(65536); + DatagramPacket fp=new DatagramPacket(new byte[1], 1, addr, 13000); + ms.send(fp); + new Thread(()->{ + DatagramPacket rp=new DatagramPacket(new byte[10], 10); + try { + ms.receive(rp); + System.err.println(rp.getAddress()); + System.err.println(rp.getLength()); + System.exit(0); + } catch (IOException e) { + e.printStackTrace(); + } + }).start(); + System.out.println(i1); + } + } +} diff --git a/src/org/kne/debug/Debuger.java b/src/org/kne/debug/Debuger.java new file mode 100644 index 0000000..25e7668 --- /dev/null +++ b/src/org/kne/debug/Debuger.java @@ -0,0 +1,129 @@ +package org.kne.debug; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Comparator; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; + + +import java.util.Set; +final class Int implements Comparable,Cloneable { + public int value; + + public Int(int value) { + super(); + this.value = value; + } + + @Override + public int hashCode() { + return value; + } + + @Override + public Object clone() throws CloneNotSupportedException { + // TODO �Զ����ɵķ������ + return super.clone(); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + Int other = (Int) obj; + if (value != other.value) + return false; + return true; + } + + @Override + public String toString() { + return new Integer(value).toString(); + } + + @Override + public int compareTo(Int o) { + + return o.value-value; + } + + + +} + +public class Debuger extends Thread { + Map ,Object[]>md=new HashMap,Object[]>(); + @Override + public void run() { + while(true){ + for(int iz=0;iz<100;iz++){ + Map m=Thread.getAllStackTraces(); + Set> s=m.entrySet(); + Iterator> i=s.iterator(); + while(i.hasNext()){ + Entryelements =i.next(); + StackTraceElement[]value=elements.getValue(); + List l=new ArrayList(value.length); + for (int j = 0; j < value.length; j++) { + l.add(value[j]); + } + if(!l.isEmpty()) + if(md.containsKey(l)){ + ((Int)md.get(l)[0]).value++; + }else{ + md.put(l,new Object[]{new Int(1),elements.getKey()} ); + } + } + + } + ArrayList, Object[]>> tmp=new ArrayList(); + Set, Object[]>> sn=md.entrySet(); + Iterator, Object[]>> in=sn.iterator(); + while(in.hasNext()){ + Entry, Object[]>elements =in.next(); + + tmp.add(elements); + } + tmp.sort(new Comparator, Object[]>>() { + + @Override + public int compare(Entry, Object[]> o1, + Entry, Object[]> o2) { + + return ((Int)o2.getValue()[0]).value-((Int)o1.getValue()[0]).value; + } + }); + for(int d=0;d, Object[]>elements=tmp.get(d); + if(((Thread)(elements.getValue()[1])).getName().startsWith("SocketBridge A->B")){ + + }else{ + continue; + } + List k=elements.getKey(); + StringBuilder sb=new StringBuilder(); + for(int d2=0;d2 5) { + throw new RuntimeException("VarInt too big"); + } + + if ((b0 & 128) != 128) { + break; + } + } + + return i; + } + public long readVarLong() throws IOException { + long i = 0L; + int j = 0; + + while (true) { + byte b0 = this.readByte(); + i |= (long) (b0 & 127) << j++ * 7; + + if (j > 10) { + throw new RuntimeException("VarLong too big"); + } + + if ((b0 & 128) != 128) { + break; + } + } + + return i; + } +} diff --git a/src/org/kne/io/VarDataOutputStream.java b/src/org/kne/io/VarDataOutputStream.java new file mode 100644 index 0000000..f6512b6 --- /dev/null +++ b/src/org/kne/io/VarDataOutputStream.java @@ -0,0 +1,43 @@ +package org.kne.io; + +import java.io.DataOutputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.nio.charset.Charset; + +public class VarDataOutputStream extends DataOutputStream { + + public VarDataOutputStream(OutputStream out) { + super(out); + } + int cache=0; + public void writeVarInt_add(int input)throws IOException{ + writeVarInt (input-cache); + cache=input; + } + public void writeVarBytes(byte[]b) throws IOException { + writeVarInt(b.length); + write(b); + } + public void writeVarUTF8(String str) throws IOException { + writeVarBytes(str.getBytes(Charset.forName("UTF-8"))); + } + public void writeVarInt(int input) throws IOException { + while ((input & -128) != 0) { + this.out.write(input & 127 | 128); + input >>>= 7; + } + + this.out.write(input); + } + + + public void writeVarLong(long value) throws IOException { + while ((value & -128L) != 0L) { + this.writeByte((int) (value & 127L) | 128); + value >>>= 7; + } + + this.writeByte((int) value); + } +} diff --git a/src/org/kne/ui/KTabUI.java b/src/org/kne/ui/KTabUI.java deleted file mode 100644 index 9f4eb00..0000000 --- a/src/org/kne/ui/KTabUI.java +++ /dev/null @@ -1,34 +0,0 @@ -package org.kne.ui; - -import java.awt.Graphics; -import java.awt.Rectangle; - -import javax.swing.JComponent; -import javax.swing.plaf.metal.MetalTabbedPaneUI; - -public class KTabUI extends MetalTabbedPaneUI{ - - @Override - public void paint(Graphics g, JComponent c) { - - } - - @Override - protected void paintContentBorder(Graphics g, int tabPlacement, int selectedIndex) { - - } - - @Override - protected void paintTabBorder(Graphics g, int tabPlacement, int tabIndex, int x, int y, int w, int h, - boolean isSelected) { - } - - - - - - - - - -} diff --git a/src/org/kne/ui/XFrame.java b/src/org/kne/ui/XFrame.java deleted file mode 100644 index b2d5577..0000000 --- a/src/org/kne/ui/XFrame.java +++ /dev/null @@ -1,573 +0,0 @@ -package org.kne.ui; - -import java.awt.AWTEvent; -import java.awt.Color; -import java.awt.Container; -import java.awt.Cursor; -import java.awt.Point; -import java.awt.Toolkit; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; -import java.awt.event.MouseEvent; -import java.awt.event.MouseListener; -import java.awt.event.MouseMotionListener; -import java.awt.event.WindowEvent; -import java.awt.event.WindowListener; - -import javax.swing.JFrame; -import javax.swing.SpringLayout; -import javax.swing.JPanel; -import javax.swing.ImageIcon; -import javax.swing.JButton; -import javax.swing.JLabel; -import java.awt.Font; -import java.awt.Image; - -import javax.swing.SwingConstants; -import java.awt.BorderLayout; - -public class XFrame extends JFrame { - MouseListener lsr=new MouseListener() { - - @Override - public void mouseReleased(MouseEvent e) { - // TODO 自动生成的方法存根 - - } - - @Override - public void mousePressed(MouseEvent e) { - if(e.getButton()==MouseEvent.BUTTON1) { - delta.x = e.getXOnScreen()-XFrame.this.getX(); - delta.y = e.getYOnScreen()-XFrame.this.getY(); - delta0.x = e.getXOnScreen()-(XFrame.this.getX()+XFrame.this.getWidth()); - delta0.y = e.getYOnScreen()-(XFrame.this.getY()+XFrame.this.getHeight()); - total.x=XFrame.this.getWidth()+XFrame.this.getX(); - total.y=XFrame.this.getHeight()+XFrame.this.getY(); - xb=e.getY()<=8; - } - - } - - @Override - public void mouseExited(MouseEvent e) { - // TODO 自动生成的方法存根 - - } - - @Override - public void mouseEntered(MouseEvent e) { - // TODO 自动生成的方法存根 - - } - - @Override - public void mouseClicked(MouseEvent e) { - // TODO 自动生成的方法存根 - - } - }; - - @Override - public Container getContentPane() { - return content; - } - - private static final Color invisible=new Color(255,255,255, 1); - private JPanel titlepanel; - private Point delta = new Point(); - private Point delta0 = new Point(); - private Point total = new Point(); - private boolean xb; - private int state=0; - - private JPanel content; - private JLabel titlelabel; - private JLabel iconi; - - @Override - public void setIconImage(Image image) { - iconi.setIcon(new ImageIcon(image.getScaledInstance(27,27, Image.SCALE_SMOOTH))); - super.setIconImage(image); - repaint(); - } - public JPanel getTitlepanel() { - return titlepanel; - } - public JLabel getTitlelabel() { - return titlelabel; - } - public void setTitleColor(Color c) { - titlepanel.setBackground(c); - repaint(); - } - public Color getTitleColor() { - return titlepanel.getBackground(); - } - - @Override - public void setTitle(String title) { - titlelabel.setText(title); - super.setTitle(title); - repaint(); - } - @Override - public String getTitle() { - return super.getTitle(); - } - - public XFrame() { - setUndecorated(true); - - super.setBackground(new Color(255, 255, 255, 0)); - Container contentPane = super.getContentPane(); - contentPane.setBackground(new Color(255, 255, 255, 0)); - SpringLayout springLayout = new SpringLayout(); - contentPane.setLayout(springLayout); - - titlepanel = new JPanel(); - //titlepanel.setOpaque(false); - titlepanel.setBorder(null); - springLayout.putConstraint(SpringLayout.WEST, titlepanel, 8, SpringLayout.WEST, contentPane); - springLayout.putConstraint(SpringLayout.SOUTH, titlepanel, 31, SpringLayout.NORTH, contentPane); - springLayout.putConstraint(SpringLayout.EAST, titlepanel, -8, SpringLayout.EAST, contentPane); - springLayout.putConstraint(SpringLayout.NORTH, titlepanel, 0, SpringLayout.NORTH, contentPane); - contentPane.add(titlepanel); - titlepanel.addMouseListener(lsr); - titlepanel.addMouseMotionListener(new MouseMotionListener() { - - @Override - public void mouseMoved(MouseEvent e) { - if(e.getY()<=8) { - titlepanel.setCursor(Cursor.getPredefinedCursor(Cursor.N_RESIZE_CURSOR)); - }else { - titlepanel.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR)); - } - } - - @Override - public void mouseDragged(MouseEvent e) { - - Point p=e.getLocationOnScreen(); - if(xb) { - if (!isResizable()) - return; - XFrame.this.setLocation(XFrame.this.getX(),p.y-delta.y); - XFrame.this.setSize(XFrame.this.getWidth(), total.y-(p.y-delta.y)); - }else { - XFrame.this.setLocation(p.x-delta.x,p.y-delta.y); - } - } - }); - - JPanel lu = new JPanel(); - springLayout.putConstraint(SpringLayout.NORTH, lu, 0, SpringLayout.NORTH, contentPane); - springLayout.putConstraint(SpringLayout.WEST, lu, 0, SpringLayout.WEST, contentPane); - springLayout.putConstraint(SpringLayout.SOUTH, lu, 8, SpringLayout.NORTH, contentPane); - springLayout.putConstraint(SpringLayout.EAST, lu, 8, SpringLayout.WEST, contentPane); - lu.setBackground(invisible); - lu.addMouseListener(lsr); - lu.setCursor(Cursor.getPredefinedCursor(Cursor.NW_RESIZE_CURSOR)); - lu.addMouseMotionListener(new MouseMotionListener() { - - @Override - public void mouseMoved(MouseEvent e) { - // TODO 自动生成的方法存根 - - } - - @Override - public void mouseDragged(MouseEvent e) { - if (!isResizable()) - return; - Point p=e.getLocationOnScreen(); - XFrame.this.setLocation(p.x-delta.x,p.y-delta.y); - XFrame.this.setSize( total.x-(p.x-delta.x),total.y-(p.y-delta.y)); - - } - }); - contentPane.add(lu); - - JPanel ru = new JPanel(); - springLayout.putConstraint(SpringLayout.NORTH, ru, 0, SpringLayout.NORTH, contentPane); - springLayout.putConstraint(SpringLayout.WEST, ru, -8, SpringLayout.EAST, contentPane); - springLayout.putConstraint(SpringLayout.SOUTH, ru, 8, SpringLayout.NORTH,contentPane); - springLayout.putConstraint(SpringLayout.EAST, ru, 0, SpringLayout.EAST, contentPane); - ru.setBackground(invisible); - ru.addMouseListener(lsr); - ru.setCursor(Cursor.getPredefinedCursor(Cursor.NE_RESIZE_CURSOR)); - ru.addMouseMotionListener(new MouseMotionListener() { - - @Override - public void mouseMoved(MouseEvent e) { - // TODO 自动生成的方法存根 - - } - - @Override - public void mouseDragged(MouseEvent e) { - if (!isResizable()) - return; - Point p=e.getLocationOnScreen(); - XFrame.this.setLocation(XFrame.this.getX(),p.y-delta.y); - XFrame.this.setSize(p.x+delta0.x-XFrame.this.getX(), total.y-(p.y-delta.y)); - - } - }); - contentPane.add(ru); - - JPanel ld = new JPanel(); - springLayout.putConstraint(SpringLayout.NORTH, ld, -8, SpringLayout.SOUTH, contentPane); - springLayout.putConstraint(SpringLayout.WEST, ld, 0, SpringLayout.WEST, contentPane); - springLayout.putConstraint(SpringLayout.SOUTH, ld, 0, SpringLayout.SOUTH, contentPane); - springLayout.putConstraint(SpringLayout.EAST, ld, 8, SpringLayout.WEST, contentPane); - ld.setBackground(invisible); - ld.addMouseListener(lsr); - ld.setCursor(Cursor.getPredefinedCursor(Cursor.SW_RESIZE_CURSOR)); - ld.addMouseMotionListener(new MouseMotionListener() { - - @Override - public void mouseMoved(MouseEvent e) { - // TODO 自动生成的方法存根 - - } - - @Override - public void mouseDragged(MouseEvent e) { - if (!isResizable()) - return; - Point p=e.getLocationOnScreen(); - XFrame.this.setLocation(p.x-delta.x,XFrame.this.getY()); - XFrame.this.setSize( total.x-(p.x-delta.x),p.y+delta0.y-XFrame.this.getY()); - } - }); - contentPane.add(ld); - - JPanel rd = new JPanel(); - springLayout.putConstraint(SpringLayout.NORTH, rd, -8, SpringLayout.SOUTH, contentPane); - springLayout.putConstraint(SpringLayout.WEST, rd, -8, SpringLayout.EAST, contentPane); - springLayout.putConstraint(SpringLayout.SOUTH, rd, 0, SpringLayout.SOUTH, contentPane); - springLayout.putConstraint(SpringLayout.EAST, rd, 0, SpringLayout.EAST, contentPane); - rd.setBackground(invisible); - rd.addMouseListener(lsr); - rd.setCursor(Cursor.getPredefinedCursor(Cursor.SE_RESIZE_CURSOR)); - rd.addMouseMotionListener(new MouseMotionListener() { - - @Override - public void mouseMoved(MouseEvent e) { - // TODO 自动生成的方法存根 - - } - - @Override - public void mouseDragged(MouseEvent e) { - if (!isResizable()) - return; - Point p=e.getLocationOnScreen(); - XFrame.this.setSize(p.x+delta0.x-XFrame.this.getX(), p.y+delta0.y-XFrame.this.getY()); - - } - }); - contentPane.add(rd); - - JPanel l = new JPanel(); - springLayout.putConstraint(SpringLayout.NORTH, l, 0, SpringLayout.SOUTH, lu); - springLayout.putConstraint(SpringLayout.WEST, l, 0, SpringLayout.WEST, contentPane); - springLayout.putConstraint(SpringLayout.SOUTH, l, 0, SpringLayout.NORTH, ld); - springLayout.putConstraint(SpringLayout.EAST, l, 8, SpringLayout.WEST, contentPane); - l.setBackground(invisible); - l.addMouseListener(lsr); - l.setCursor(Cursor.getPredefinedCursor(Cursor.W_RESIZE_CURSOR)); - l.addMouseMotionListener(new MouseMotionListener() { - - @Override - public void mouseMoved(MouseEvent e) { - // TODO 自动生成的方法存根 - - } - - @Override - public void mouseDragged(MouseEvent e) { - if (!isResizable()) - return; - Point p=e.getLocationOnScreen(); - XFrame.this.setLocation(p.x-delta.x,XFrame.this.getY()); - XFrame.this.setSize( total.x-(p.x-delta.x),XFrame.this.getHeight()); - - } - }); - contentPane.add(l); - - JPanel r = new JPanel(); - springLayout.putConstraint(SpringLayout.NORTH, r, 0, SpringLayout.SOUTH, ru); - springLayout.putConstraint(SpringLayout.WEST, r, -8, SpringLayout.EAST,contentPane); - springLayout.putConstraint(SpringLayout.SOUTH, r, 0, SpringLayout.NORTH, rd); - springLayout.putConstraint(SpringLayout.EAST, r, 0, SpringLayout.EAST, contentPane); - r.setBackground(invisible); - r.addMouseListener(lsr); - r.setCursor(Cursor.getPredefinedCursor(Cursor.E_RESIZE_CURSOR)); - r.addMouseMotionListener(new MouseMotionListener() { - - @Override - public void mouseMoved(MouseEvent e) { - // TODO 自动生成的方法存根 - - } - - @Override - public void mouseDragged(MouseEvent e) { - if (!isResizable()) - return; - Point p=e.getLocationOnScreen(); - XFrame.this.setSize(p.x+delta0.x-XFrame.this.getX(), XFrame.this.getHeight()); - - } - }); - - contentPane.add(r); - - JPanel d = new JPanel(); - springLayout.putConstraint(SpringLayout.NORTH, d, -8, SpringLayout.SOUTH, contentPane); - springLayout.putConstraint(SpringLayout.WEST, d, 0, SpringLayout.EAST, ld); - springLayout.putConstraint(SpringLayout.SOUTH, d, 0, SpringLayout.SOUTH, contentPane); - springLayout.putConstraint(SpringLayout.EAST, d, 0, SpringLayout.WEST, rd); - d.setBackground(invisible); - d.addMouseListener(lsr); - d.setCursor(Cursor.getPredefinedCursor(Cursor.S_RESIZE_CURSOR)); - d.addMouseMotionListener(new MouseMotionListener() { - - @Override - public void mouseMoved(MouseEvent e) { - // TODO 自动生成的方法存根 - - } - - @Override - public void mouseDragged(MouseEvent e) { - if (!isResizable()) - return; - Point p=e.getLocationOnScreen(); - XFrame.this.setSize(XFrame.this.getWidth(), p.y+delta0.y-XFrame.this.getY()); - - } - }); - contentPane.add(d); - - content = new JPanel(); - content.setBorder(null); - springLayout.putConstraint(SpringLayout.NORTH, content, 0, SpringLayout.SOUTH, titlepanel); - SpringLayout sl_titlepanel = new SpringLayout(); - titlepanel.setLayout(sl_titlepanel); - - JLabel close = new JLabel(""); - close.setHorizontalAlignment(SwingConstants.CENTER); - close.setBackground(invisible); - close.setForeground(Color.WHITE); - close.setIcon(new ImageIcon(XFrame.class.getResource("/assets/close.png"))); - sl_titlepanel.putConstraint(SpringLayout.NORTH, close, 0, SpringLayout.NORTH, titlepanel); - sl_titlepanel.putConstraint(SpringLayout.WEST, close, -46, SpringLayout.EAST, titlepanel); - sl_titlepanel.putConstraint(SpringLayout.SOUTH, close, 0, SpringLayout.SOUTH, titlepanel); - sl_titlepanel.putConstraint(SpringLayout.EAST, close, 0, SpringLayout.EAST, titlepanel); - close.addMouseListener(new MouseListener() { - - @Override - public void mouseClicked(MouseEvent e) { - XFrame.super.processWindowEvent(new WindowEvent(XFrame.this, WindowEvent.WINDOW_CLOSING)); - - } - - @Override - public void mousePressed(MouseEvent e) { - // TODO 自动生成的方法存根 - - } - - @Override - public void mouseReleased(MouseEvent e) { - // TODO 自动生成的方法存根 - - } - - @Override - public void mouseEntered(MouseEvent e) { - // TODO 自动生成的方法存根 - - } - - @Override - public void mouseExited(MouseEvent e) { - // TODO 自动生成的方法存根 - - } - }); - titlepanel.add(close); - iconi = new JLabel(""); - iconi.setHorizontalAlignment(SwingConstants.CENTER); - sl_titlepanel.putConstraint(SpringLayout.NORTH, iconi, 0, SpringLayout.NORTH, titlepanel); - sl_titlepanel.putConstraint(SpringLayout.WEST, iconi, 0, SpringLayout.WEST, titlepanel); - sl_titlepanel.putConstraint(SpringLayout.SOUTH, iconi, 0, SpringLayout.SOUTH, titlepanel); - sl_titlepanel.putConstraint(SpringLayout.EAST, iconi, 31, SpringLayout.WEST, titlepanel); - iconi.setOpaque(false); - iconi.setBackground(invisible); - titlepanel.add(iconi); - JLabel maxium = new JLabel(""); - maxium.setHorizontalAlignment(SwingConstants.CENTER); - maxium.setForeground(Color.WHITE); - maxium.setBackground(Color.WHITE); - maxium.setIcon(new ImageIcon(XFrame.class.getResource("/assets/maxium.png"))); - sl_titlepanel.putConstraint(SpringLayout.NORTH, maxium, 0, SpringLayout.NORTH, close); - sl_titlepanel.putConstraint(SpringLayout.WEST, maxium, -46, SpringLayout.WEST, close); - sl_titlepanel.putConstraint(SpringLayout.SOUTH, maxium, 0, SpringLayout.SOUTH, titlepanel); - sl_titlepanel.putConstraint(SpringLayout.EAST, maxium, 0, SpringLayout.WEST, close); - //maxium.setBorderPainted(false); - maxium.setBackground(invisible); - maxium.addMouseListener(new MouseListener() { - - @Override - public void mouseClicked(MouseEvent e) { - if (!isResizable()) - return; - int s=XFrame.this.getExtendedState(); - if(s==JFrame.NORMAL) - XFrame.this.setExtendedState(JFrame.MAXIMIZED_BOTH); - if(s==JFrame.MAXIMIZED_BOTH) - XFrame.this.setExtendedState(JFrame.NORMAL); - } - - @Override - public void mousePressed(MouseEvent e) { - // TODO 自动生成的方法存根 - - } - - @Override - public void mouseReleased(MouseEvent e) { - // TODO 自动生成的方法存根 - - } - - @Override - public void mouseEntered(MouseEvent e) { - // TODO 自动生成的方法存根 - - } - - @Override - public void mouseExited(MouseEvent e) { - // TODO 自动生成的方法存根 - - } - }); - titlepanel.add(maxium); - - JLabel minium = new JLabel(""); - minium.setHorizontalAlignment(SwingConstants.CENTER); - minium.setForeground(Color.WHITE); - minium.setBackground(Color.WHITE); - minium.setIcon(new ImageIcon(XFrame.class.getResource("/assets/minium.png"))); - sl_titlepanel.putConstraint(SpringLayout.NORTH, minium, 0, SpringLayout.NORTH, close); - sl_titlepanel.putConstraint(SpringLayout.WEST, minium, -46, SpringLayout.WEST, maxium); - sl_titlepanel.putConstraint(SpringLayout.SOUTH, minium, 0, SpringLayout.SOUTH, close); - sl_titlepanel.putConstraint(SpringLayout.EAST, minium, 0, SpringLayout.WEST, maxium); - minium.setBackground(invisible); - minium.addMouseListener(new MouseListener() { - - @Override - public void mouseReleased(MouseEvent e) { - // TODO 自动生成的方法存根 - - } - - @Override - public void mousePressed(MouseEvent e) { - // TODO 自动生成的方法存根 - - } - - @Override - public void mouseExited(MouseEvent e) { - // TODO 自动生成的方法存根 - - } - - @Override - public void mouseEntered(MouseEvent e) { - // TODO 自动生成的方法存根 - - } - - @Override - public void mouseClicked(MouseEvent e) { - // TODO 自动生成的方法存根 - int s=XFrame.this.getExtendedState(); - if(s!=JFrame.ICONIFIED) { - state=s; - XFrame.this.setExtendedState(JFrame.ICONIFIED); - } else { - XFrame.this.setExtendedState(state); - } - } - }); - titlepanel.add(minium); - - titlelabel = new JLabel(); - sl_titlepanel.putConstraint(SpringLayout.WEST, titlelabel, 31, SpringLayout.WEST, titlepanel); - sl_titlepanel.putConstraint(SpringLayout.EAST, titlelabel, -31, SpringLayout.EAST, titlepanel); - titlelabel.setFont(new Font("宋体", Font.PLAIN, 16)); - sl_titlepanel.putConstraint(SpringLayout.NORTH, titlelabel, 0, SpringLayout.NORTH, titlepanel); - sl_titlepanel.putConstraint(SpringLayout.SOUTH, titlelabel, 0, SpringLayout.SOUTH, titlepanel); - titlelabel.setOpaque(false); - titlelabel.setBackground(invisible); - titlepanel.add(titlelabel); - springLayout.putConstraint(SpringLayout.WEST, content, 0, SpringLayout.EAST, l); - springLayout.putConstraint(SpringLayout.SOUTH, content, 0, SpringLayout.NORTH, d); - springLayout.putConstraint(SpringLayout.EAST, content, 0, SpringLayout.WEST, r); - contentPane.add(content); - content.setLayout(new BorderLayout(0, 0)); - addWindowListener(new WindowListener() { - - @Override - public void windowOpened(WindowEvent e) { - // TODO 自动生成的方法存根 - - } - - @Override - public void windowIconified(WindowEvent e) { - // TODO 自动生成的方法存根 - - } - - @Override - public void windowDeiconified(WindowEvent e) { - XFrame.this.setExtendedState(state); - - } - - @Override - public void windowDeactivated(WindowEvent e) { - // TODO 自动生成的方法存根 - - } - - @Override - public void windowClosing(WindowEvent e) { - // TODO 自动生成的方法存根 - - } - - @Override - public void windowClosed(WindowEvent e) { - // TODO 自动生成的方法存根 - - } - - @Override - public void windowActivated(WindowEvent e) { - // TODO 自动生成的方法存根 - - } - }); - - } -} diff --git a/src/org/kne/ui/YScrollPane.java b/src/org/kne/ui/YScrollPane.java deleted file mode 100644 index a325511..0000000 --- a/src/org/kne/ui/YScrollPane.java +++ /dev/null @@ -1,133 +0,0 @@ -package org.kne.ui; - -import javax.swing.JPanel; -import java.awt.BorderLayout; -import java.awt.Color; -import java.awt.Component; -import java.awt.Dimension; -import java.awt.FlowLayout; -import java.awt.event.AdjustmentEvent; -import java.awt.event.AdjustmentListener; -import java.awt.event.ComponentEvent; -import java.awt.event.ComponentListener; -import java.awt.event.ContainerEvent; -import java.awt.event.ContainerListener; -import java.awt.event.MouseWheelEvent; -import java.awt.event.MouseWheelListener; - -import javax.swing.JScrollBar; - -public class YScrollPane extends JPanel { - private JPanel settings; - private JScrollBar scrollBar; - public YScrollPane(int contentx){ - this(contentx,BorderLayout.EAST); - } - public YScrollPane(int contentx, String d) { - setLayout(new BorderLayout(0, 0)); - - setBackground(Color.WHITE); - scrollBar = new JScrollBar(); - add(scrollBar,d); - - JPanel panel = new JPanel(); - add(panel, BorderLayout.CENTER); - panel.setLayout(null); - panel.setOpaque(false); - - settings = new JPanel(); - settings.setOpaque(false); - settings.setMaximumSize(new Dimension(contentx, Integer.MAX_VALUE-10)); - settings.setPreferredSize(new Dimension(contentx, 0)); - settings.setSize(new Dimension(contentx, 0)); - FlowLayout flowLayout = (FlowLayout) settings.getLayout(); - flowLayout.setAlignment(FlowLayout.LEFT); - panel.add(settings); -settings.addContainerListener(new ContainerListener() { - - @Override - public void componentRemoved(ContainerEvent e) { - int maxv=0; - for (int i = 0; i - * Warning: - * Serialized objects of this class will not be compatible with - * future Swing releases. The current serialization support is - * appropriate for short term storage or RMI between applications running - * the same version of Swing. As of 1.4, support for long term storage - * of all JavaBeans™ - * has been added to the java.beans package. - * Please see {@link java.beans.XMLEncoder}. - * - * @author Michael C. Albers - */ -public class KNEProgressBarUI extends BasicProgressBarUI { - - // private Rectangle innards; - // private Rectangle box; - - public static ComponentUI createUI(JComponent c) { - return new KNEProgressBarUI(); - } - - /** - * Draws a bit of special highlighting on the progress bar. - * The core painting is deferred to the BasicProgressBar's - * paintDeterminate method. - * @since 1.4 - */ - public void paintDeterminate(Graphics g, JComponent c) { - super.paintDeterminate(g,c); - - - } - - /** - * Draws a bit of special highlighting on the progress bar - * and bouncing box. - * The core painting is deferred to the BasicProgressBar's - * paintIndeterminate method. - * @since 1.4 - */ - public void paintIndeterminate(Graphics g, JComponent c) { - super.paintIndeterminate(g, c); - } -} diff --git a/~$ALB协议规范V2.1.docx b/~$ALB协议规范V2.1.docx new file mode 100644 index 0000000..fcd42e3 Binary files /dev/null and b/~$ALB协议规范V2.1.docx differ