Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9865364919 | ||
|
|
fb99076f88 |
No files matched your search
@@ -1,7 +1,7 @@
|
|||||||
# Minecraft bot stress tester
|
# Minecraft bot stress tester
|
||||||
🤖 A simple open source app written in Java used for stress testing Minecraft servers with bots (fake players).
|
🤖 A simple open source app written in Java used for stress testing Minecraft servers with bots (fake players).
|
||||||
💥 It can be also used to test plugins or minigames.
|
💥 It can be also used to test plugins or minigames.
|
||||||
✔️ The MC version of the bots is 1.20.6
|
✔️ The MC version of the bots is 1.21
|
||||||
For older MC versions please look in the [releases](https://github.com/crpmax/mc-bots/releases " releases").
|
For older MC versions please look in the [releases](https://github.com/crpmax/mc-bots/releases " releases").
|
||||||
|
|
||||||
## 🆒 Features
|
## 🆒 Features
|
||||||
@@ -11,7 +11,7 @@ For older MC versions please look in the [releases](https://github.com/crpmax/mc
|
|||||||
- ✅ Set connection delay
|
- ✅ Set connection delay
|
||||||
- ✅ Set messages or commands on join
|
- ✅ Set messages or commands on join
|
||||||
- ✅ Generate random or real looking nicknames or load from file
|
- ✅ Generate random or real looking nicknames or load from file
|
||||||
- ✅ Online (premium) account support with login using Microsoft OAuth - only for migrated accounts
|
- ✅ Online (premium) account support with login using Microsoft
|
||||||
- ✅ Control all or selected bots
|
- ✅ Control all or selected bots
|
||||||
|
|
||||||
## 📖 Usage
|
## 📖 Usage
|
||||||
@@ -21,7 +21,7 @@ Use of pre-compiled jar from [releases](https://github.com/crpmax/mc-bots/releas
|
|||||||
When running, you can write a chat message to the terminal to send it by all bots.
|
When running, you can write a chat message to the terminal to send it by all bots.
|
||||||
|
|
||||||
## 🧪 Example
|
## 🧪 Example
|
||||||
`java -jar mc-bots-1.2.11.jar -s 192.168.0.189:25565 -p BOT_ -d 4000 5000 -c 30 -r`
|
`java -jar mc-bots-1.2.12.jar -s 192.168.0.189:25565 -p BOT_ -d 4000 5000 -c 30 -r`
|
||||||
This will connect 30 bots to server at 192.168.0.189:25565 with delay 4000-5000 ms and will use real-looking nicknames prefixed with BOT_
|
This will connect 30 bots to server at 192.168.0.189:25565 with delay 4000-5000 ms and will use real-looking nicknames prefixed with BOT_
|
||||||
|
|
||||||
<img src="https://imgur.com/XWcckas.png" title="Connected bots" width="350px"/>
|
<img src="https://imgur.com/XWcckas.png" title="Connected bots" width="350px"/>
|
||||||
|
|||||||
+2
-2
@@ -3,7 +3,7 @@ plugins {
|
|||||||
}
|
}
|
||||||
|
|
||||||
group 'me.creepermaxcz.mc-bots'
|
group 'me.creepermaxcz.mc-bots'
|
||||||
version '1.2.11'
|
version '1.2.12'
|
||||||
|
|
||||||
sourceCompatibility = 1.17
|
sourceCompatibility = 1.17
|
||||||
targetCompatibility = 1.17
|
targetCompatibility = 1.17
|
||||||
@@ -16,7 +16,7 @@ repositories {
|
|||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
implementation 'org.geysermc.mcprotocollib:protocol:1.20.6-2-SNAPSHOT'
|
implementation 'org.geysermc.mcprotocollib:protocol:1.21-SNAPSHOT'
|
||||||
implementation 'net.kyori:adventure-text-serializer-gson:4.16.0'
|
implementation 'net.kyori:adventure-text-serializer-gson:4.16.0'
|
||||||
implementation 'commons-cli:commons-cli:1.5.0'
|
implementation 'commons-cli:commons-cli:1.5.0'
|
||||||
implementation 'com.diogonunes:JColor:5.2.0'
|
implementation 'com.diogonunes:JColor:5.2.0'
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
package me.creepermaxcz.mcbots;
|
package me.creepermaxcz.mcbots;
|
||||||
|
|
||||||
import com.github.steveice10.mc.auth.service.AuthenticationService;
|
import org.geysermc.mcprotocollib.auth.GameProfile;
|
||||||
import com.github.steveice10.mc.auth.service.SessionService;
|
import org.geysermc.mcprotocollib.auth.SessionService;
|
||||||
import org.geysermc.mcprotocollib.network.ProxyInfo;
|
import org.geysermc.mcprotocollib.network.ProxyInfo;
|
||||||
import org.geysermc.mcprotocollib.network.Session;
|
import org.geysermc.mcprotocollib.network.Session;
|
||||||
import org.geysermc.mcprotocollib.network.event.session.DisconnectedEvent;
|
import org.geysermc.mcprotocollib.network.event.session.DisconnectedEvent;
|
||||||
@@ -53,13 +53,12 @@ public class Bot extends Thread {
|
|||||||
client = new TcpClientSession(address.getHostString(), address.getPort(), protocol, proxy);
|
client = new TcpClientSession(address.getHostString(), address.getPort(), protocol, proxy);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Bot(AuthenticationService authService, InetSocketAddress address, ProxyInfo proxy) {
|
public Bot(MinecraftProtocol protocol, InetSocketAddress address, ProxyInfo proxy) {
|
||||||
this.nickname = authService.getUsername();
|
this.nickname = protocol.getProfile().getName();
|
||||||
this.address = address;
|
this.address = address;
|
||||||
this.proxy = proxy;
|
this.proxy = proxy;
|
||||||
|
|
||||||
Log.info("Creating bot", nickname);
|
Log.info("Creating bot", nickname);
|
||||||
protocol = new MinecraftProtocol(authService.getSelectedProfile(), authService.getAccessToken());
|
|
||||||
|
|
||||||
client = new TcpClientSession(address.getHostString(), address.getPort(), protocol, proxy);
|
client = new TcpClientSession(address.getHostString(), address.getPort(), protocol, proxy);
|
||||||
|
|
||||||
|
|||||||
@@ -1,10 +1,12 @@
|
|||||||
package me.creepermaxcz.mcbots;
|
package me.creepermaxcz.mcbots;
|
||||||
|
|
||||||
import com.github.steveice10.mc.auth.exception.request.AuthPendingException;
|
import net.lenni0451.commons.httpclient.HttpClient;
|
||||||
import com.github.steveice10.mc.auth.service.AuthenticationService;
|
import net.raphimc.minecraftauth.MinecraftAuth;
|
||||||
import com.github.steveice10.mc.auth.service.MsaAuthenticationService;
|
import net.raphimc.minecraftauth.step.java.session.StepFullJavaSession;
|
||||||
import com.github.steveice10.mc.auth.util.HTTP;
|
import net.raphimc.minecraftauth.step.msa.StepMsaDeviceCode;
|
||||||
|
import org.geysermc.mcprotocollib.auth.GameProfile;
|
||||||
import org.geysermc.mcprotocollib.network.ProxyInfo;
|
import org.geysermc.mcprotocollib.network.ProxyInfo;
|
||||||
|
import org.geysermc.mcprotocollib.protocol.MinecraftProtocol;
|
||||||
import org.geysermc.mcprotocollib.protocol.data.status.ServerStatusInfo;
|
import org.geysermc.mcprotocollib.protocol.data.status.ServerStatusInfo;
|
||||||
import org.apache.commons.cli.*;
|
import org.apache.commons.cli.*;
|
||||||
import org.jline.reader.LineReader;
|
import org.jline.reader.LineReader;
|
||||||
@@ -105,7 +107,7 @@ public class Main {
|
|||||||
try {
|
try {
|
||||||
proxyType = ProxyInfo.Type.valueOf(typeStr);
|
proxyType = ProxyInfo.Type.valueOf(typeStr);
|
||||||
} catch (IllegalArgumentException e) {
|
} catch (IllegalArgumentException e) {
|
||||||
Log.error("Inavlid proxy type, use SOCKS4 or SOCKS5.");
|
Log.error("Invalid proxy type, use SOCKS4 or SOCKS5.");
|
||||||
System.exit(1);
|
System.exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -269,55 +271,28 @@ public class Main {
|
|||||||
Log.warn("There was an error retrieving server status information. The server may be offline or running on a different version.");
|
Log.warn("There was an error retrieving server status information. The server may be offline or running on a different version.");
|
||||||
}
|
}
|
||||||
|
|
||||||
AuthenticationService authService = null;
|
MinecraftProtocol protocol;
|
||||||
if (cmd.hasOption("o")) {
|
if (cmd.hasOption("o")) {
|
||||||
Log.warn("Online mode enabled. The bot count will be set to 1.");
|
Log.warn("Online mode enabled. The bot count will be set to 1.");
|
||||||
botCount = 1;
|
botCount = 1;
|
||||||
|
|
||||||
// Create request parameters map
|
HttpClient httpClient = MinecraftAuth.createHttpClient();
|
||||||
Map<String, String> params = new HashMap<>();
|
StepFullJavaSession.FullJavaSession javaSession =
|
||||||
params.put("client_id", CLIENT_ID);
|
MinecraftAuth.JAVA_DEVICE_CODE_LOGIN.getFromInput(
|
||||||
params.put("scope", "XboxLive.signin");
|
httpClient, new StepMsaDeviceCode.MsaDeviceCodeCallback(
|
||||||
|
msaDeviceCode -> {
|
||||||
|
Log.info("Authorize your Microsoft account on " + msaDeviceCode.getDirectVerificationUri());
|
||||||
|
Log.info("Waiting for authorization.");
|
||||||
|
}));
|
||||||
|
|
||||||
// Send request to Microsoft OAuth api
|
Log.info("Logged in with username: " + javaSession.getMcProfile().getName());
|
||||||
// https://learn.microsoft.com/en-us/azure/active-directory/develop/v2-oauth2-device-code
|
|
||||||
URI endpointURI = URI.create("https://login.microsoftonline.com/consumers/oauth2/v2.0/devicecode");
|
|
||||||
MsaAuthenticationService.MsCodeResponse response = HTTP.makeRequestForm(
|
|
||||||
Proxy.NO_PROXY, endpointURI, params, MsaAuthenticationService.MsCodeResponse.class
|
|
||||||
);
|
|
||||||
try {
|
|
||||||
Log.info("Please go to " + response.verification_uri.toURL() + " to authenticate your account - Code: " + response.user_code);
|
|
||||||
} catch (MalformedURLException e) {
|
|
||||||
Log.error("Error while trying to get the url of the authentication page");
|
|
||||||
}
|
|
||||||
|
|
||||||
authService = new MsaAuthenticationService(CLIENT_ID, response.device_code);
|
GameProfile gameProfile = new GameProfile(javaSession.getMcProfile().getId(), javaSession.getMcProfile().getName());
|
||||||
|
protocol = new MinecraftProtocol(gameProfile, javaSession.getMcProfile().getMcToken().getAccessToken());
|
||||||
// Wait for user to login on microsoft page
|
|
||||||
int retryMax = 20;
|
|
||||||
while (true) {
|
|
||||||
try {
|
|
||||||
authService.login();
|
|
||||||
break;
|
|
||||||
} catch (Exception e) {
|
|
||||||
if (e instanceof AuthPendingException) {
|
|
||||||
Log.info("Authentication is pending, waiting for user to authenticate...");
|
|
||||||
try {
|
|
||||||
Thread.sleep(5000);
|
|
||||||
} catch (InterruptedException ignored) {
|
|
||||||
}
|
|
||||||
if (retryMax == 0)
|
|
||||||
throw e;
|
|
||||||
retryMax--;
|
|
||||||
} else {
|
} else {
|
||||||
throw e;
|
protocol = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
AuthenticationService finalAuthService = authService;
|
|
||||||
new Thread(() -> {
|
new Thread(() -> {
|
||||||
for (int i = 0; i < botCount; i++) {
|
for (int i = 0; i < botCount; i++) {
|
||||||
try {
|
try {
|
||||||
@@ -347,15 +322,15 @@ public class Main {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Bot bot = null;
|
Bot bot = null;
|
||||||
if (finalAuthService != null) {
|
if (protocol != null) {
|
||||||
bot = new Bot(
|
bot = new Bot(
|
||||||
finalAuthService,
|
protocol,
|
||||||
inetAddr,
|
inetAddr,
|
||||||
proxyInfo
|
proxyInfo
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
bot = new Bot(
|
bot = new Bot(
|
||||||
nickGen.nextNick(),
|
new MinecraftProtocol(nickGen.nextNick()),
|
||||||
inetAddr,
|
inetAddr,
|
||||||
proxyInfo
|
proxyInfo
|
||||||
);
|
);
|
||||||
|
|||||||
Reference in new issue
Block a user