refactor: rewrite AuthPlugin to be based on IP

This commit is contained in:
ChomeNS
2025-01-07 17:03:45 +07:00
parent 6164483e11
commit ae8be94be3
5 changed files with 38 additions and 116 deletions

View File

@@ -1,141 +1,60 @@
package me.chayapak1.chomens_bot.plugins;
import com.google.common.hash.Hashing;
import me.chayapak1.chomens_bot.Bot;
import me.chayapak1.chomens_bot.data.PlayerEntry;
import me.chayapak1.chomens_bot.util.UUIDUtilities;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.TextComponent;
import net.kyori.adventure.text.format.NamedTextColor;
import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;
public class AuthPlugin extends PlayersPlugin.Listener {
public final String id = "chomens_bot_verify"; // should this be static
private final Bot bot;
private String key = null;
private long timeJoined;
private boolean hasCorrectHash;
private PlayerEntry targetPlayer;
private boolean started = false;
private final String ownerIpForServer;
public AuthPlugin (Bot bot) {
this.bot = bot;
if (!bot.config.ownerAuthentication.enabled) return;
this.ownerIpForServer = bot.config.ownerAuthentication.ips.get(bot.host + ":" + bot.port);
this.key = bot.config.ownerAuthentication.key;
if (!bot.config.ownerAuthentication.enabled || ownerIpForServer == null) return;
bot.players.addListener(this);
bot.chat.addListener(new ChatPlugin.Listener() {
@Override
public boolean systemMessageReceived(Component component, String string, String ansi) {
return AuthPlugin.this.systemMessageReceived(component);
}
});
bot.executor.scheduleAtFixedRate(this::check, 1, 3, TimeUnit.SECONDS);
}
private String getSanitizedOwnerName() {
return bot.config.ownerName.replaceAll("§[a-f0-9rlonmk]", "");
}
@Override
public void playerJoined(PlayerEntry target) {
if (!target.profile.getName().equals(getSanitizedOwnerName()) || !bot.options.useCore) return;
if (!target.profile.getName().equals(bot.config.ownerName) || !bot.options.useCore) return;
targetPlayer = target;
final CompletableFuture<String> future = bot.players.getPlayerIP(target, true);
bot.executor.schedule(() -> sendVerificationMessage(target, true), 2, TimeUnit.SECONDS);
}
future.completeOnTimeout("", 10, TimeUnit.SECONDS);
public void sendVerificationMessage (PlayerEntry entry, boolean setTimeJoined) {
started = true;
future.thenApplyAsync(ip -> {
bot.logger.custom(
Component
.text("Auth")
.color(NamedTextColor.RED),
Component.translatable(
"Authenticating with user IP %s and configured owner IP %s",
Component.text(ip),
Component.text(ownerIpForServer)
)
);
final long currentTime = System.currentTimeMillis();
if (ip.equals(ownerIpForServer)) {
bot.chat.tellraw(
Component
.text("You have been verified")
.color(NamedTextColor.GREEN),
target.profile.getId()
);
} else {
bot.filter.doAll(target, bot.config.ownerAuthentication.muteReason);
}
if (setTimeJoined) timeJoined = currentTime;
final long time = currentTime / 10_000;
final String hash = Hashing.sha256()
.hashString(key + time, StandardCharsets.UTF_8)
.toString()
.substring(0, 8);
bot.chat.tellraw(
Component
.text(id)
.append(Component.text(hash))
.append(Component.text(UUIDUtilities.selector(bot.profile.getId()))), // convenient reason
entry.profile.getId()
);
}
@Override
public void playerLeft(PlayerEntry target) {
if (!target.profile.getName().equals(getSanitizedOwnerName())) return;
hasCorrectHash = false;
started = false;
}
private boolean systemMessageReceived (Component component) {
try {
if (!(component instanceof TextComponent idComponent)) return true;
if (!idComponent.content().equals(id)) return true;
final List<Component> children = component.children();
if (children.size() != 1) return true;
if (!(children.getFirst() instanceof TextComponent)) return true;
final String inputHash = ((TextComponent) children.getFirst()).content();
final long time = System.currentTimeMillis() / 10_000;
final String hash = Hashing.sha256()
// very pro hash input
.hashString(key + key + time + time, StandardCharsets.UTF_8)
.toString()
.substring(0, 8);
bot.logger.custom(Component.text("Auth").color(NamedTextColor.RED), Component.text("Authenticating with real hash " + hash + " and user hash " + inputHash));
hasCorrectHash = inputHash.equals(hash);
if (hasCorrectHash && targetPlayer != null) bot.chat.tellraw(Component.text("You have been verified").color(NamedTextColor.GREEN), targetPlayer.profile.getId());
return false;
} catch (Exception ignored) {}
return true;
}
private void check() {
if (!started || !bot.config.ownerAuthentication.enabled) return;
final PlayerEntry entry = bot.players.getEntry(getSanitizedOwnerName());
if (entry == null) return;
final long timeSinceJoined = System.currentTimeMillis() - timeJoined;
if (!hasCorrectHash) sendVerificationMessage(entry, false);
if (timeSinceJoined > bot.config.ownerAuthentication.timeout && !hasCorrectHash) {
bot.filter.mute(entry, "Not verified");
bot.filter.deOp(entry);
}
return ip;
});
}
}