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
@@ -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;
}
}