UPDATE 2.2

This commit is contained in:
Administrator
2024-01-30 16:54:57 +08:00
parent b4fccf3a03
commit e4f4c77c19
70 changed files with 4671 additions and 1520 deletions
Binary file not shown.
-3
View File
@@ -1,3 +0,0 @@
#Tue Jul 25 19:03:09 CST 2023
local=0.0.0.0\:35000
server=127.0.0.1\:4569
+29
View File
@@ -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"
}
]
-3
View File
@@ -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
BIN
View File
Binary file not shown.
+46
View File
@@ -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());
}
}
+52
View File
@@ -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;
}
}
+233
View File
@@ -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);
}
}
+132
View File
@@ -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);
}
}
}
+129
View File
@@ -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();
}
}
}
}
+80
View File
@@ -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;
}
}
+43
View File
@@ -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);
}
}
-34
View File
@@ -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) {
}
}
-573
View File
@@ -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 自动生成的方法存根
}
});
}
}
-133
View File
@@ -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;
}
}
-64
View File
@@ -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;
}
}
-83
View File
@@ -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&trade;
* 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.