From 6c6fc0ca500ef4cbfcb1296d4c885f9688f2380e Mon Sep 17 00:00:00 2001 From: iceBear67 Date: Tue, 16 Jul 2024 01:30:51 +0800 Subject: [PATCH] add: listgeo to inspect alts --- .../io/ib67/sfcraft/geoip/GeoIPService.java | 6 +++ .../sfcraft/geoip/MaxMindGeoIPService.java | 16 +++++++- .../module/command/ManagementModule.java | 38 +++++++++++++++++++ .../java/io/ib67/sfcraft/util/Helper.java | 11 ++++++ .../java/io/ib67/sfcraft/util/SFConsts.java | 2 + 5 files changed, 72 insertions(+), 1 deletion(-) diff --git a/src/main/java/io/ib67/sfcraft/geoip/GeoIPService.java b/src/main/java/io/ib67/sfcraft/geoip/GeoIPService.java index 6b3e726..1a17734 100644 --- a/src/main/java/io/ib67/sfcraft/geoip/GeoIPService.java +++ b/src/main/java/io/ib67/sfcraft/geoip/GeoIPService.java @@ -1,6 +1,8 @@ package io.ib67.sfcraft.geoip; import com.maxmind.geoip2.exception.GeoIp2Exception; +import com.maxmind.geoip2.record.City; +import com.maxmind.geoip2.record.Country; import lombok.SneakyThrows; import java.io.Closeable; @@ -9,4 +11,8 @@ import java.time.Clock; public interface GeoIPService extends Closeable { Clock clockOf(InetAddress address) throws GeoIp2Exception; + + City cityOf(InetAddress address) throws GeoIp2Exception; + + Country countryOf(InetAddress address) throws GeoIp2Exception; } diff --git a/src/main/java/io/ib67/sfcraft/geoip/MaxMindGeoIPService.java b/src/main/java/io/ib67/sfcraft/geoip/MaxMindGeoIPService.java index 7a31eb4..5a5f134 100644 --- a/src/main/java/io/ib67/sfcraft/geoip/MaxMindGeoIPService.java +++ b/src/main/java/io/ib67/sfcraft/geoip/MaxMindGeoIPService.java @@ -7,7 +7,8 @@ import com.google.inject.Singleton; import com.maxmind.db.CHMCache; import com.maxmind.geoip2.DatabaseReader; import com.maxmind.geoip2.exception.GeoIp2Exception; -import io.ib67.sfcraft.SFCraft; +import com.maxmind.geoip2.record.City; +import com.maxmind.geoip2.record.Country; import io.ib67.sfcraft.inject.ConfigRoot; import lombok.SneakyThrows; import lombok.extern.log4j.Log4j2; @@ -42,6 +43,19 @@ public class MaxMindGeoIPService implements Module, GeoIPService { return Clock.system(TimeZone.getTimeZone(databaseReader.city(address).getLocation().getTimeZone()).toZoneId()); } + @Override + @SneakyThrows + public City cityOf(InetAddress address) throws GeoIp2Exception { + return databaseReader.city(address).getCity(); + } + + @Override + @SneakyThrows + public Country countryOf(InetAddress address) throws GeoIp2Exception { + return databaseReader.country(address).getCountry(); + } + + @SneakyThrows private DatabaseReader loadData() throws InterruptedException { try { return new DatabaseReader.Builder(mmdbPath.toFile()).withCache(new CHMCache()).build(); diff --git a/src/main/java/io/ib67/sfcraft/module/command/ManagementModule.java b/src/main/java/io/ib67/sfcraft/module/command/ManagementModule.java index 957e1a5..2dd231f 100644 --- a/src/main/java/io/ib67/sfcraft/module/command/ManagementModule.java +++ b/src/main/java/io/ib67/sfcraft/module/command/ManagementModule.java @@ -1,8 +1,12 @@ package io.ib67.sfcraft.module.command; +import com.google.inject.Inject; +import com.maxmind.geoip2.exception.GeoIp2Exception; import com.mojang.brigadier.CommandDispatcher; import com.mojang.brigadier.builder.LiteralArgumentBuilder; import com.mojang.brigadier.context.CommandContext; +import io.ib67.sfcraft.geoip.GeoIPService; +import io.ib67.sfcraft.util.Helper; import io.ib67.sfcraft.util.Permission; import io.ib67.sfcraft.util.SFConsts; import io.ib67.sfcraft.ServerModule; @@ -14,12 +18,20 @@ import net.minecraft.server.MinecraftServer; import net.minecraft.server.command.CommandManager; import net.minecraft.server.command.ServerCommandSource; import net.minecraft.server.network.ServerPlayNetworkHandler; +import net.minecraft.server.network.ServerPlayerEntity; import net.minecraft.text.Text; import net.minecraft.util.Colors; import java.lang.reflect.Field; +import java.net.Inet4Address; +import java.net.InetAddress; +import java.net.InetSocketAddress; +import java.net.UnknownHostException; public class ManagementModule extends ServerModule { + @Inject + private GeoIPService geoIPService; + @Override public void onInitialize() { CommandRegistrationCallback.EVENT.register(this::registerCommands); @@ -44,6 +56,32 @@ public class ManagementModule extends ServerModule { .requires(it -> it.hasPermissionLevel(2) || SFConsts.COMMAND_LISTPERM.hasPermission(it.getPlayer())) .executes(this::listPerms) ); + dispatcher.register(LiteralArgumentBuilder.literal("listgeo") + .requires(it -> this.isEnabled()) + .requires(it -> it.hasPermissionLevel(2) || SFConsts.COMMAND_LISTGEO.hasPermission(it.getPlayer())) + .executes(this::listGeo) + ); + } + + private int listGeo(CommandContext ctx) { + var src = ctx.getSource(); + var server = src.getServer(); + src.sendMessage(Text.of("List of player with cities:")); + for (ServerPlayerEntity serverPlayerEntity : server.getPlayerManager().getPlayerList()) { + try { + var addr = InetAddress.getByName(serverPlayerEntity.getIp()); + var city = geoIPService.cityOf(addr); + src.sendMessage( + Text.literal(" - ") + .append(Text.literal("[" + city.getName() + "] ").withColor(Colors.BLUE)) + .append(Text.literal(serverPlayerEntity.getName().getLiteralString())) + .append(Text.literal(" (" + Helper.hideIp(addr) + ")").withColor(Colors.LIGHT_GRAY)) + ); + } catch (GeoIp2Exception | UnknownHostException e) { + src.sendMessage(Text.literal(" - [FAILED TO FETCH] " + serverPlayerEntity.getName().getLiteralString()).withColor(Colors.LIGHT_RED)); + } + } + return 0; } public int enterSudoMode(CommandContext ctx) { diff --git a/src/main/java/io/ib67/sfcraft/util/Helper.java b/src/main/java/io/ib67/sfcraft/util/Helper.java index 8950135..b8cfdf2 100644 --- a/src/main/java/io/ib67/sfcraft/util/Helper.java +++ b/src/main/java/io/ib67/sfcraft/util/Helper.java @@ -20,6 +20,7 @@ import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.Direction; import net.minecraft.world.World; +import java.net.InetAddress; import java.net.InetSocketAddress; import java.nio.file.Files; import java.nio.file.Path; @@ -102,4 +103,14 @@ public class Helper { return block instanceof SaplingBlock || block instanceof CropBlock; } + + public static String hideIp(InetAddress addr) { + var _addr = addr.getHostAddress(); + var q = _addr.split("\\."); + if (q.length == 0) { + // ipv6 is not supported + return _addr; + } + return q[0] + "." + q[1] + ".*.*"; + } } diff --git a/src/main/java/io/ib67/sfcraft/util/SFConsts.java b/src/main/java/io/ib67/sfcraft/util/SFConsts.java index c5b794d..e6dd210 100644 --- a/src/main/java/io/ib67/sfcraft/util/SFConsts.java +++ b/src/main/java/io/ib67/sfcraft/util/SFConsts.java @@ -4,6 +4,7 @@ import io.ib67.sfcraft.util.Permission; import lombok.experimental.UtilityClass; import net.fabricmc.loader.api.FabricLoader; import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.server.network.ServerPlayerEntity; @UtilityClass public class SFConsts { @@ -18,6 +19,7 @@ public class SFConsts { public static final Permission COMMAND_UNBLOCKSERVER = ofSFCPermission("command.unblockserver", false); public static final Permission COMMAND_LISTOFFLINE = ofSFCPermission("command.listoffline", false); public static final Permission COMMAND_LISTPERM = ofSFCPermission("command.listperm", false); + public static final Permission COMMAND_LISTGEO = ofSFCPermission("command.listgeo", false); public static Permission ofSFCPermission(String key, boolean byDefault) { return new Permission<>("sfcraft." + key, byDefault);