forked from KNEMC/KLALB
UPDATE 2.2
This commit is contained in:
Binary file not shown.
@@ -1,3 +0,0 @@
|
||||
#Tue Jul 25 19:03:09 CST 2023
|
||||
local=0.0.0.0\:35000
|
||||
server=127.0.0.1\:4569
|
||||
@@ -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"
|
||||
}
|
||||
]
|
||||
@@ -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
|
||||
Binary file not shown.
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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<SocketAddress,SubDatagramSocket> 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<SubDatagramSocket> 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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 Consumer<DatagramSocket>con;
|
||||
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<DatagramSocket> getCon() {
|
||||
return con;
|
||||
}
|
||||
|
||||
public void setCon(Consumer<DatagramSocket> con) {
|
||||
this.con = con;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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<Proxy> proxys=new HashSet<>();
|
||||
private KLALBController klalbController;
|
||||
public Set<Proxy> 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());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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 List<ProxyProfileEntry>entrys=new ArrayList<ProxyProfileEntry>();
|
||||
public List<ProxyProfileEntry> 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 {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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 List<ProxyProfileEntry>current=new ArrayList<>();
|
||||
|
||||
public List<ProxyProfileEntry> getCurrent() {
|
||||
return current;
|
||||
}
|
||||
public void applyNewProxyList(List<ProxyProfileEntry>l) {
|
||||
for (Iterator<ProxyProfileEntry> 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<ProxyProfileEntry> 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());
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
List<String>lstc=new ArrayList<>();
|
||||
lstc.add(exe.getAbsolutePath());
|
||||
lstc.add("-c");
|
||||
lstc.add(f.getName());
|
||||
ProcessBuilder psb=new ProcessBuilder(lstc);
|
||||
psb.directory(base);
|
||||
theProcess=psb.start();
|
||||
AtomicReference<IOException >arex=new AtomicReference<IOException >();
|
||||
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<Process> onExit() {
|
||||
return theProcess.onExit();
|
||||
}
|
||||
@Override
|
||||
public ProcessHandle toHandle() {
|
||||
return theProcess.toHandle();
|
||||
}
|
||||
@Override
|
||||
public Info info() {
|
||||
return theProcess.info();
|
||||
}
|
||||
@Override
|
||||
public Stream<ProcessHandle> children() {
|
||||
return theProcess.children();
|
||||
}
|
||||
@Override
|
||||
public Stream<ProcessHandle> 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();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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<String> 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());
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
package org.kne.cloud.network.klalb;
|
||||
|
||||
public class CONST {
|
||||
public static String klalb="KLALB";
|
||||
public static String klalbver="2.2";
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
package org.kne.cloud.network.klalb;
|
||||
|
||||
import java.util.function.BiConsumer;
|
||||
|
||||
public interface KLALBPacketConsumer extends BiConsumer<KLALBRemoteLine, KLALBPacket> {
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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<Socket> 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<Socket> getCon() {
|
||||
return conx;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCon(Consumer<Socket> conx) {
|
||||
this.conx=conx;
|
||||
}
|
||||
|
||||
public KLALBController getKlalbController() {
|
||||
return klalbController;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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<KLALBRemoteLine>{
|
||||
|
||||
|
||||
private volatile boolean closed=false;
|
||||
|
||||
private volatile Supplier<Inet6Address> localVaddrSupplier;
|
||||
|
||||
public Supplier<Inet6Address> getLocalVaddrSupplier() {
|
||||
return localVaddrSupplier;
|
||||
}
|
||||
|
||||
public void setLocalVaddrSupplier(Supplier<Inet6Address> 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<KLALBRemoteLine, KLALBPacket> rec;
|
||||
|
||||
//private Object lock=new Object();
|
||||
private volatile Thread tlock;
|
||||
private List<SumQueue<KLALBPacket>> sendDequeList =new ArrayList<SumQueue<KLALBPacket>>();
|
||||
{
|
||||
for(int i=0;i<12;i++) {
|
||||
sendDequeList.add(new SumQueue<KLALBPacket>(new ConcurrentLinkedQueue<>()));
|
||||
}
|
||||
}
|
||||
private KLALBPacket getNextPacket() {
|
||||
for (Iterator<SumQueue<KLALBPacket>> iterator = sendDequeList.iterator(); iterator.hasNext();) {
|
||||
SumQueue<KLALBPacket> queue = (SumQueue<KLALBPacket>) 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<SumQueue<KLALBPacket>> iterator = sendDequeList.iterator(); iterator.hasNext();) {
|
||||
SumQueue<KLALBPacket> queue = (SumQueue<KLALBPacket>) iterator.next();
|
||||
i+=queue.getSumValue();
|
||||
}
|
||||
return i;
|
||||
}
|
||||
private long sumNextPacketCount() {
|
||||
long i=0;
|
||||
for (Iterator<SumQueue<KLALBPacket>> iterator = sendDequeList.iterator(); iterator.hasNext();) {
|
||||
SumQueue<KLALBPacket> queue = (SumQueue<KLALBPacket>) 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<KLALBRemoteLine,KLALBPacket> rec) {
|
||||
this.rec = rec;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public void remoeFromSendQueue(KLALBPacket klalbPacket) {
|
||||
for (Iterator<SumQueue<KLALBPacket>> iterator = sendDequeList.iterator(); iterator.hasNext();) {
|
||||
SumQueue<KLALBPacket> queue = iterator.next();
|
||||
queue.removeIf((x)->{
|
||||
return x.equals(klalbPacket);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public long statLengthBefore(int priority) {
|
||||
AtomicLong al=new AtomicLong();
|
||||
int n=0;
|
||||
for (Iterator<SumQueue<KLALBPacket>> iterator = sendDequeList.iterator(); iterator.hasNext();n++) {
|
||||
if(n>priority) {
|
||||
break;
|
||||
}
|
||||
SumQueue<KLALBPacket> 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<t2){
|
||||
return -1;
|
||||
}else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
public void reconnectImmediately() {
|
||||
if(lthd!=null) {
|
||||
LockSupport.unpark(lthd);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -1,267 +0,0 @@
|
||||
package org.kne.cloud.network.klalb;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.Inet6Address;
|
||||
import java.net.NoRouteToHostException;
|
||||
import java.net.Socket;
|
||||
import java.net.SocketException;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.PriorityBlockingQueue;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import org.kne.cloud.network.mport.ThreadTool;
|
||||
|
||||
public class KLALBRemoteSocket extends MonitoredSocket {
|
||||
private Inet6Address remoteVaddr;
|
||||
|
||||
private KLALBController controller;
|
||||
|
||||
public KLALBController getController() {
|
||||
return controller;
|
||||
}
|
||||
protected void setController(KLALBController controller) {
|
||||
this.controller = controller;
|
||||
}
|
||||
public Inet6Address getRemoteVaddr() {
|
||||
return remoteVaddr;
|
||||
}
|
||||
public String toString() {
|
||||
return super.toString()+ getMonitor().toString();
|
||||
}
|
||||
public KLALBRemoteSocket(Socket socket) {
|
||||
this(socket,new Monitor());
|
||||
}
|
||||
public KLALBRemoteSocket(Socket socket,Monitor m) {
|
||||
super(socket,m);
|
||||
try {
|
||||
//socket.setSendBufferSize(32768);
|
||||
//socket.setReceiveBufferSize(65535);
|
||||
//System.out.println(socket.getSendBufferSize()+" "+socket.getReceiveBufferSize());
|
||||
socket.setTcpNoDelay(true);
|
||||
socket.setSoTimeout(10000);
|
||||
} catch (SocketException e1) {
|
||||
e1.printStackTrace();
|
||||
}
|
||||
ThreadTool.makeVDaemonThreadIfSupport("远程接收线程", () -> {
|
||||
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<KLALBPacket> rec;
|
||||
private Consumer<KLALBRemoteSocket> clo;
|
||||
private PriorityBlockingQueue<PQItem> sendQueue=new PriorityBlockingQueue<PQItem>();
|
||||
|
||||
protected PriorityBlockingQueue<PQItem> 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<KLALBPacket> rec) {
|
||||
this.rec = rec;
|
||||
}
|
||||
public void setCloseListener(Consumer<KLALBRemoteSocket> 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<PQItem>{
|
||||
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(priority<o.priority) {
|
||||
return 1;
|
||||
}else if(priority>o.priority) {
|
||||
return -1;
|
||||
}else {
|
||||
if(index>o.index) {
|
||||
return 1;
|
||||
}else if(index<o.index){
|
||||
return -1;
|
||||
}else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
private CountDownLatch cdl=new CountDownLatch(1);
|
||||
public void waitforlose() {
|
||||
try {
|
||||
cdl.await();
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
public void remoeFromSendQueue(KLALBPacket klalbPacket) {
|
||||
sendQueue.removeIf((x)->{
|
||||
return x.getPacket().equals(klalbPacket);
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -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<KLALBRemoteLine> 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();
|
||||
}
|
||||
}
|
||||
@@ -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<MultipurposeSocketAddress,LineEntry>{
|
||||
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<LineEntry> 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<LineEntry> 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<java.util.Map.Entry<MultipurposeSocketAddress, LineEntry>> iterator = entrySet().iterator(); iterator.hasNext();) {
|
||||
java.util.Map.Entry<MultipurposeSocketAddress, LineEntry> 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();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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 Map<InetSocketAddress,BindableKLALBPacketConsumer>bindMap=new ConcurrentHashMap<>();
|
||||
private ReentrantReadWriteLock listenMaplock=new ReentrantReadWriteLock();
|
||||
private Map<InetSocketAddress,BindableKLALBPacketConsumer>listenMap=new ConcurrentHashMap<>();
|
||||
private ReentrantReadWriteLock connectMaplock=new ReentrantReadWriteLock();
|
||||
private Map<Pair<InetSocketAddress,InetSocketAddress>,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<InetSocketAddress> 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<InetSocketAddress> 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<InetSocketAddress, InetSocketAddress>( 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<BindableKLALBPacketConsumer> 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<BindableKLALBPacketConsumer> 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<BindableKLALBPacketConsumer> 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<BindableKLALBPacketConsumer> 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<InetSocketAddress, InetSocketAddress>(local, remote));
|
||||
if(bkc!=null) {
|
||||
bkc.accept(krl, (KLALBPacket) packet);
|
||||
return true;
|
||||
}
|
||||
InetSocketAddress localany=new InetSocketAddress(ANYLA, packet.getDport());
|
||||
bkc=connectMap.get(new Pair<InetSocketAddress, InetSocketAddress>(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<InetSocketAddress, InetSocketAddress>( new InetSocketAddress(kservers.getLocalInetAddress(), kservers.getLocalPort()),isaf));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
package org.kne.cloud.network.klalb;
|
||||
|
||||
public interface PortPacket {
|
||||
|
||||
public int getSport();
|
||||
|
||||
public int getDport();
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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<T extends Sumable> extends AbstractQueue<T> implements Queue<T> {
|
||||
private AbstractQueue<T> abq;
|
||||
public SumQueue(AbstractQueue<T> 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<? super T> 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<? extends T> c) {
|
||||
boolean addAll = abq.addAll(c);
|
||||
resum();
|
||||
return addAll;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterator<T> 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<T> spliterator() {
|
||||
return abq.spliterator();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Stream<T> stream() {
|
||||
// TODO 自动生成的方法存根
|
||||
return abq.stream();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Stream<T> parallelStream() {
|
||||
// TODO 自动生成的方法存根
|
||||
return abq.parallelStream();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void forEach(Consumer<? super T> action) {
|
||||
// TODO 自动生成的方法存根
|
||||
abq.forEach(action);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean containsAll(Collection<?> c) {
|
||||
// TODO 自动生成的方法存根
|
||||
return abq.containsAll(c);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> T[] toArray(IntFunction<T[]> generator) {
|
||||
return (T[]) abq.toArray(generator);
|
||||
}
|
||||
@Override
|
||||
public <T> T[] toArray(T[] a) {
|
||||
// TODO 自动生成的方法存根
|
||||
return (T[]) abq.toArray(a);
|
||||
}
|
||||
@Override
|
||||
public String toString() {
|
||||
// TODO 自动生成的方法存根
|
||||
return abq.toString();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
package org.kne.cloud.network.klalb;
|
||||
|
||||
public interface Sumable {
|
||||
public long getValue();
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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";
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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";
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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<MinecraftPacket, MinecraftPacket> {
|
||||
private Supplier<Inet6Address> vaddrsup;
|
||||
private Supplier<Integer>vportsup;
|
||||
@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<Inet6Address> vaddrsup, Supplier<Integer> vportsup) {
|
||||
super();
|
||||
this.vaddrsup = vaddrsup;
|
||||
this.vportsup = vportsup;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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 {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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<String, String> 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -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<Function<MinecraftPacket,MinecraftPacket>> transformersAB=new ArrayList<Function<MinecraftPacket,MinecraftPacket>>();
|
||||
private List<Function<MinecraftPacket,MinecraftPacket>> transformersBA=new ArrayList<Function<MinecraftPacket,MinecraftPacket>>();
|
||||
public List<Function<MinecraftPacket, MinecraftPacket>> getTransformersAB() {
|
||||
return transformersAB;
|
||||
}
|
||||
|
||||
public List<Function<MinecraftPacket, MinecraftPacket>> getTransformersBA() {
|
||||
return transformersBA;
|
||||
}
|
||||
|
||||
public MinecraftSocketToSocketProxy(MultipurposeSocketAddress listen, MultipurposeSocketAddress cbind,
|
||||
MultipurposeSocketAddress defaultConnect, Map<String, MultipurposeSocketAddress> 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();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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<Function<MinecraftPacket,MinecraftPacket>>transformers=new ArrayList<Function<MinecraftPacket,MinecraftPacket>>();
|
||||
public List<Function<MinecraftPacket, MinecraftPacket>> 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<Function<MinecraftPacket, MinecraftPacket>> iterator = transformers.iterator(); iterator.hasNext();) {
|
||||
Function<MinecraftPacket, MinecraftPacket> function = (Function<MinecraftPacket, MinecraftPacket>) 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));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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<KLALBRemoteLine> iterator = kc.getLines().iterator(); iterator.hasNext();) {
|
||||
KLALBRemoteLine hostPort = iterator.next();
|
||||
System.out.println(hostPort .toString2());
|
||||
//System.out.println();
|
||||
}
|
||||
break;
|
||||
default :
|
||||
System.out.println("未知命令!");
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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<KLALBRemoteLine> 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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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(", ");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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<Int>,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 <List<StackTraceElement>,Object[]>md=new HashMap<List<StackTraceElement>,Object[]>();
|
||||
@Override
|
||||
public void run() {
|
||||
while(true){
|
||||
for(int iz=0;iz<100;iz++){
|
||||
Map<Thread, StackTraceElement[]> m=Thread.getAllStackTraces();
|
||||
Set<Entry<Thread, StackTraceElement[]>> s=m.entrySet();
|
||||
Iterator<Entry<Thread, StackTraceElement[]>> i=s.iterator();
|
||||
while(i.hasNext()){
|
||||
Entry<Thread, StackTraceElement[]>elements =i.next();
|
||||
StackTraceElement[]value=elements.getValue();
|
||||
List<StackTraceElement> l=new ArrayList<StackTraceElement>(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<Entry<List<StackTraceElement>, Object[]>> tmp=new ArrayList();
|
||||
Set<Entry<List<StackTraceElement>, Object[]>> sn=md.entrySet();
|
||||
Iterator<Entry<List<StackTraceElement>, Object[]>> in=sn.iterator();
|
||||
while(in.hasNext()){
|
||||
Entry<List<StackTraceElement>, Object[]>elements =in.next();
|
||||
|
||||
tmp.add(elements);
|
||||
}
|
||||
tmp.sort(new Comparator<Entry<List<StackTraceElement>, Object[]>>() {
|
||||
|
||||
@Override
|
||||
public int compare(Entry<List<StackTraceElement>, Object[]> o1,
|
||||
Entry<List<StackTraceElement>, Object[]> o2) {
|
||||
|
||||
return ((Int)o2.getValue()[0]).value-((Int)o1.getValue()[0]).value;
|
||||
}
|
||||
});
|
||||
for(int d=0;d<tmp.size();d++){
|
||||
|
||||
Entry<List<StackTraceElement>, Object[]>elements=tmp.get(d);
|
||||
if(((Thread)(elements.getValue()[1])).getName().startsWith("SocketBridge A->B")){
|
||||
|
||||
}else{
|
||||
continue;
|
||||
}
|
||||
List<StackTraceElement> k=elements.getKey();
|
||||
StringBuilder sb=new StringBuilder();
|
||||
for(int d2=0;d2<k.size();d2++){
|
||||
sb.append(' ');sb.append(k.get(d2));
|
||||
}
|
||||
System.err.println(elements.getValue()[0]+":"+elements.getValue()[1]+"="+sb);
|
||||
}
|
||||
System.err.println("--------------------------------------------------------------------------------------------------------------------");
|
||||
try {
|
||||
Thread.sleep(1000);
|
||||
} catch (InterruptedException e) {
|
||||
// TODO �Զ����ɵ� catch ��
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
package org.kne.io;
|
||||
|
||||
import java.io.DataInputStream;
|
||||
import java.io.EOFException;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.nio.charset.Charset;
|
||||
|
||||
public class VarDataInputStream extends DataInputStream {
|
||||
|
||||
public VarDataInputStream(InputStream in) {
|
||||
super(in);
|
||||
|
||||
}
|
||||
public byte[] readPacketVarBytes() throws IOException {
|
||||
|
||||
int i;
|
||||
try {
|
||||
i=readVarInt();
|
||||
}catch(Exception e) {
|
||||
return null;
|
||||
}
|
||||
byte[]b=new byte[i];
|
||||
readFully(b);
|
||||
return b;
|
||||
}
|
||||
public byte[] readVarBytes() throws IOException {
|
||||
|
||||
int i=readVarInt();
|
||||
byte[]b=new byte[i];
|
||||
readFully(b);
|
||||
return b;
|
||||
}
|
||||
public String readVarUTF8() throws IOException {
|
||||
return new String(readVarBytes(), Charset.forName("UTF-8"));
|
||||
}
|
||||
int cache=0;
|
||||
public int readVarInt_addd()throws IOException {
|
||||
cache+=readVarInt();
|
||||
return cache;
|
||||
}
|
||||
public int readVarInt() throws IOException {
|
||||
int i = 0;
|
||||
int j = 0;
|
||||
|
||||
while (true) {
|
||||
byte b0 = this.readByte();
|
||||
i |= (b0 & 127) << j++ * 7;
|
||||
|
||||
if (j > 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;
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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) {
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -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 自动生成的方法存根
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
}
|
||||
@@ -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<settings.getComponentCount(); i++) {
|
||||
Component comp=settings.getComponent(i);
|
||||
int tmp=comp.getY()+comp.getHeight();
|
||||
maxv+=tmp+flowLayout.getVgap();
|
||||
}
|
||||
settings.setSize(settings.getWidth(), maxv);
|
||||
flowLayout.layoutContainer(settings);
|
||||
scrollBar.setMaximum(settings.getHeight());
|
||||
scrollBar.setMinimum(0);
|
||||
scrollBar.setVisibleAmount(panel.getHeight());
|
||||
updateUI();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void componentAdded(ContainerEvent e) {
|
||||
int maxv=0;
|
||||
for (int i = 0; i<settings.getComponentCount(); i++) {
|
||||
Component comp=settings.getComponent(i);
|
||||
int tmp=comp.getHeight();
|
||||
maxv+=tmp+flowLayout.getVgap();
|
||||
}
|
||||
settings.setSize(settings.getWidth(), maxv);
|
||||
flowLayout.layoutContainer(settings);
|
||||
scrollBar.setMaximum(settings.getHeight());
|
||||
scrollBar.setMinimum(0);
|
||||
scrollBar.setVisibleAmount(panel.getHeight());
|
||||
updateUI();
|
||||
}
|
||||
});
|
||||
scrollBar.addAdjustmentListener(new AdjustmentListener() {
|
||||
|
||||
@Override
|
||||
public void adjustmentValueChanged(AdjustmentEvent e) {
|
||||
settings.setLocation(settings.getX(), -scrollBar.getValue());
|
||||
}
|
||||
});
|
||||
panel.addComponentListener(new ComponentListener() {
|
||||
|
||||
@Override
|
||||
public void componentShown(ComponentEvent e) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void componentResized(ComponentEvent e) {
|
||||
settings.setLocation(panel.getWidth()/2-settings.getWidth()/2, settings.getY());
|
||||
|
||||
flowLayout.layoutContainer(settings);
|
||||
scrollBar.setMaximum(settings.getHeight());
|
||||
scrollBar.setMinimum(0);
|
||||
scrollBar.setVisibleAmount(panel.getHeight());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void componentMoved(ComponentEvent e) {
|
||||
// TODO 自动生成的方法存根
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void componentHidden(ComponentEvent e) {
|
||||
// TODO 自动生成的方法存根
|
||||
|
||||
}
|
||||
});
|
||||
settings.addMouseWheelListener(new MouseWheelListener() {
|
||||
|
||||
@Override
|
||||
public void mouseWheelMoved(MouseWheelEvent e) {
|
||||
int x=e.getWheelRotation()*20;
|
||||
scrollBar.setValue(scrollBar.getValue()+x);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public JPanel getView() {
|
||||
return settings;
|
||||
}
|
||||
public JScrollBar getScrollBar() {
|
||||
return scrollBar;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,64 +0,0 @@
|
||||
package org.knemcl.ui;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Dialog.ModalExclusionType;
|
||||
import java.awt.Font;
|
||||
import java.awt.HeadlessException;
|
||||
import java.awt.Toolkit;
|
||||
import javax.swing.JFrame;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JProgressBar;
|
||||
import javax.swing.UIManager;
|
||||
import javax.swing.WindowConstants;
|
||||
import javax.swing.SwingConstants;
|
||||
import javax.swing.plaf.ProgressBarUI;
|
||||
import org.knemcl.uitool.KNEProgressBarUI;
|
||||
|
||||
public class ProcessingFrame extends JFrame{
|
||||
|
||||
private JLabel j;
|
||||
private JProgressBar bar;
|
||||
static{
|
||||
UIManager.put("ProgressBar.selectionBackground",Color.BLACK);
|
||||
UIManager.put("ProgressBar.selectionForeground",Color.BLACK);
|
||||
}
|
||||
public ProcessingFrame(String text) throws HeadlessException {
|
||||
this("",text);
|
||||
}
|
||||
public void setText(String s){
|
||||
j.setText(s);
|
||||
}
|
||||
/**
|
||||
* @wbp.parser.constructor
|
||||
*/
|
||||
public ProcessingFrame(String title,String text) throws HeadlessException {
|
||||
super(title);
|
||||
getContentPane().setBackground(Color.WHITE);
|
||||
setModalExclusionType(ModalExclusionType.APPLICATION_EXCLUDE);
|
||||
getContentPane().setLayout(null);
|
||||
setIconImage(UIEnv.getIcon());
|
||||
//setUndecorated(true);
|
||||
setSize(400, 200);
|
||||
setBackground(new Color(255, 255,255 , 255));
|
||||
setLocationRelativeTo(null);
|
||||
j = new JLabel(text);
|
||||
j.setBackground(Color.WHITE);
|
||||
j.setBounds(0, 110, 394, 30);
|
||||
j.setHorizontalAlignment(SwingConstants.CENTER);
|
||||
j.setForeground(Color.GRAY);
|
||||
//j.setFont(UIEnv.getFont().deriveFont(20f));
|
||||
getContentPane().add(j);
|
||||
bar = new JProgressBar();
|
||||
bar.setUI(new KNEProgressBarUI());
|
||||
bar.setForeground(UIEnv.getDefaultcolor());//new Color(129,209,243)
|
||||
bar.setStringPainted(true);
|
||||
bar.setBorder(null);
|
||||
bar.setBounds(6,145,380,20);
|
||||
bar.setString("");
|
||||
getContentPane().add(bar);
|
||||
setResizable(false);
|
||||
}
|
||||
public JProgressBar getProgressBar(){
|
||||
return bar;
|
||||
}
|
||||
}
|
||||
@@ -1,83 +0,0 @@
|
||||
package org.knemcl.ui;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Cursor;
|
||||
import java.awt.Font;
|
||||
import java.awt.FontFormatException;
|
||||
import java.awt.Image;
|
||||
import java.awt.Point;
|
||||
import java.awt.Toolkit;
|
||||
import java.io.IOException;
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.UIManager;
|
||||
public class UIEnv {
|
||||
private static Font font;
|
||||
private static Image icon ;
|
||||
private static Cursor cur;
|
||||
private static Color defaultcolor=new Color(207,218,223);
|
||||
private static Color selectedcolor=new Color(207/2,218/2,223/2);
|
||||
public static Color getDefaultcolor() {
|
||||
return defaultcolor;
|
||||
}
|
||||
public static void setDefaultColor(Color defaultcolor) {
|
||||
UIEnv.defaultcolor = defaultcolor;
|
||||
}
|
||||
public static Color getDefaultTitleColor() {
|
||||
Color c=new Color(32, 32,32, 128);
|
||||
return c;
|
||||
}
|
||||
public static void inituie(){
|
||||
try {
|
||||
font = Font.createFont(Font.PLAIN, UIEnv.class.getResourceAsStream("/assets/SourceHanSansCN-Light.otf")).deriveFont(12f);
|
||||
} catch (FontFormatException e1) {
|
||||
e1.printStackTrace();
|
||||
} catch (IOException e1) {
|
||||
// TODO 自动生成的 catch 块
|
||||
e1.printStackTrace();
|
||||
}
|
||||
|
||||
java.util.Enumeration keys = UIManager.getDefaults().keys();
|
||||
while (keys.hasMoreElements()) {
|
||||
Object key = keys.nextElement();
|
||||
Object value = UIManager.get(key);
|
||||
if (value instanceof javax.swing.plaf.FontUIResource) {
|
||||
UIManager.put(key, font);
|
||||
}
|
||||
}
|
||||
icon=Toolkit.getDefaultToolkit().getImage(
|
||||
UIEnv.class.getResource("/assets/logo3.png"));
|
||||
cur=Toolkit.getDefaultToolkit().createCustomCursor(Toolkit.getDefaultToolkit().getImage(UIEnv.class.getResource("/assets/diamond_sword.png")),new Point(0,0), "");
|
||||
}
|
||||
public static void defbut(JButton start) {
|
||||
if(font==null)
|
||||
inituie();
|
||||
start.setBorderPainted(false);
|
||||
start.setForeground(Color.WHITE);
|
||||
start.setFont(font.deriveFont(Font.BOLD, 20));
|
||||
start.setBackground(defaultcolor);
|
||||
}
|
||||
public static void defbut(JButton start,int fontsize) {
|
||||
if(font==null)
|
||||
inituie();
|
||||
start.setBorderPainted(false);
|
||||
start.setForeground(Color.WHITE);
|
||||
start.setFont(font.deriveFont(Font.BOLD, fontsize));
|
||||
start.setBackground(defaultcolor);
|
||||
}
|
||||
public static Font getFont(){
|
||||
return font;
|
||||
}
|
||||
public static Image getIcon(){
|
||||
return icon;
|
||||
}
|
||||
public static Cursor getCursor(){
|
||||
return cur;
|
||||
}
|
||||
|
||||
public static Color getSelectedcolor() {
|
||||
return selectedcolor;
|
||||
}
|
||||
public static void setSelectedcolor(Color selectedcolor) {
|
||||
UIEnv.selectedcolor = selectedcolor;
|
||||
}
|
||||
}
|
||||
@@ -1,78 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
package org.knemcl.uitool;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.plaf.*;
|
||||
import javax.swing.plaf.basic.*;
|
||||
import java.awt.*;
|
||||
|
||||
/**
|
||||
* The Metal implementation of ProgressBarUI.
|
||||
* <p>
|
||||
* <strong>Warning:</strong>
|
||||
* 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 <code>java.beans</code> 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
|
||||
* <code>paintDeterminate</code> 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
|
||||
* <code>paintIndeterminate</code> method.
|
||||
* @since 1.4
|
||||
*/
|
||||
public void paintIndeterminate(Graphics g, JComponent c) {
|
||||
super.paintIndeterminate(g, c);
|
||||
}
|
||||
}
|
||||
Binary file not shown.
Reference in New Issue
Block a user