2 Commits
Author SHA1 Message Date
crpmax 9865364919 update to MC 1.21 2025-02-21 18:12:04 +01:00
Lukas ʕ•́ᴥ•̀ʔ fb99076f88 Fix spelling mistake (#93) 2024-07-24 13:56:46 +02:00
4 changed files with 33 additions and 59 deletions

No files matched your search

+3 -3
View File
@@ -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
View File
@@ -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);
+24 -49
View File
@@ -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 } else {
int retryMax = 20; protocol = null;
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 {
throw e;
}
}
}
} }
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
); );