diff --git a/Plugins/Mineplex.Core.Common/src/mineplex/core/common/api/ApiHost.java b/Plugins/Mineplex.Core.Common/src/mineplex/core/common/api/ApiHost.java index a6dd1cbae..b1593c552 100644 --- a/Plugins/Mineplex.Core.Common/src/mineplex/core/common/api/ApiHost.java +++ b/Plugins/Mineplex.Core.Common/src/mineplex/core/common/api/ApiHost.java @@ -71,6 +71,11 @@ public class ApiHost return getAPIHost("ENDERCHEST"); } + public static ApiHost getBanner() + { + return getAPIHost("BANNER"); + } + private String _host; private int _port; diff --git a/Plugins/Mineplex.Core.Common/src/mineplex/core/common/util/UtilPlayer.java b/Plugins/Mineplex.Core.Common/src/mineplex/core/common/util/UtilPlayer.java index bfc5e4ec8..19b7b6059 100644 --- a/Plugins/Mineplex.Core.Common/src/mineplex/core/common/util/UtilPlayer.java +++ b/Plugins/Mineplex.Core.Common/src/mineplex/core/common/util/UtilPlayer.java @@ -1,5 +1,6 @@ package mineplex.core.common.util; +import java.net.InetAddress; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; @@ -1145,6 +1146,11 @@ public class UtilPlayer return entityPlayer.activeContainer != entityPlayer.defaultContainer; } + public static String getIp(Player player) + { + return player.getAddress().getAddress().getHostAddress(); + } + /* * Returns whether the UUID belongs to a slim skin */ diff --git a/Plugins/Mineplex.Core/src/mineplex/core/antihack/AntiHack.java b/Plugins/Mineplex.Core/src/mineplex/core/antihack/AntiHack.java index b59982c6f..ffb40fc5d 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/antihack/AntiHack.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/antihack/AntiHack.java @@ -68,6 +68,7 @@ import mineplex.core.antihack.commands.AnticheatOnCommand; import mineplex.core.antihack.commands.DetailedMessagesCommand; import mineplex.core.antihack.commands.GetVlsCommand; import mineplex.core.antihack.commands.TestBanCommand; +import mineplex.core.antihack.compedaccount.CompromisedAccountManager; import mineplex.core.antihack.gep.GwenExtremePrejudice; import mineplex.core.antihack.guardians.GuardianManager; import mineplex.core.antihack.logging.AntihackLogger; @@ -147,6 +148,8 @@ public class AntiHack extends MiniPlugin private BanWaveManager _banWaveManager; + private final CompromisedAccountManager _compromisedAccountManager; + private AntiHack() { super("AntiHack"); @@ -155,6 +158,7 @@ public class AntiHack extends MiniPlugin require(GuardianManager.class); _banWaveManager = require(BanWaveManager.class); + _compromisedAccountManager = require(CompromisedAccountManager.class); Bukkit.getServicesManager().register(MineplexLink.class, new MineplexLinkImpl(), this._plugin, ServicePriority.Normal); @@ -225,6 +229,8 @@ public class AntiHack extends MiniPlugin new GwenBanNotification(_thisServer, player.getName(), player.getUniqueId().toString(), coreClient.GetRank().name(), CheckManager.getCheckSimpleName(cause), id, gep).publish(); }); + _compromisedAccountManager.submitImmediateBan(player); + _punish.AddPunishment(coreClient.getName(), Category.Hacking, finalMessage, AntiHack.NAME, 3, true, -1, true, after); }; diff --git a/Plugins/Mineplex.Core/src/mineplex/core/antihack/banwave/BanWaveManager.java b/Plugins/Mineplex.Core/src/mineplex/core/antihack/banwave/BanWaveManager.java index 668c60db2..a4a5476e5 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/antihack/banwave/BanWaveManager.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/antihack/banwave/BanWaveManager.java @@ -5,6 +5,7 @@ import mineplex.core.ReflectivelyCreateMiniPlugin; import mineplex.core.account.CoreClient; import mineplex.core.account.CoreClientManager; import mineplex.core.antihack.AntiHack; +import mineplex.core.antihack.compedaccount.CompromisedAccountManager; import mineplex.core.antihack.logging.AntihackLogger; import mineplex.core.antihack.redisnotifications.GwenBanwaveNotification; import mineplex.core.common.util.UtilServer; @@ -74,6 +75,7 @@ public class BanWaveManager extends MiniPlugin JsonObject custom = new JsonObject(); custom.addProperty("is-banwave", true); + require(CompromisedAccountManager.class).submitPendingDelayedBan(player); require(AntihackLogger.class).saveMetadata(player, id, after, custom); } }); diff --git a/Plugins/Mineplex.Core/src/mineplex/core/antihack/compedaccount/CompromisedAccountManager.java b/Plugins/Mineplex.Core/src/mineplex/core/antihack/compedaccount/CompromisedAccountManager.java new file mode 100644 index 000000000..cebea5a50 --- /dev/null +++ b/Plugins/Mineplex.Core/src/mineplex/core/antihack/compedaccount/CompromisedAccountManager.java @@ -0,0 +1,76 @@ +package mineplex.core.antihack.compedaccount; + +import java.util.logging.Level; + +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.player.PlayerJoinEvent; + +import com.google.gson.JsonObject; + +import mineplex.core.MiniPlugin; +import mineplex.core.ReflectivelyCreateMiniPlugin; +import mineplex.core.account.CoreClient; +import mineplex.core.account.CoreClientManager; +import mineplex.core.common.api.ApiHost; +import mineplex.core.common.api.ApiWebCall; +import mineplex.core.common.util.UtilPlayer; + +@ReflectivelyCreateMiniPlugin +public class CompromisedAccountManager extends MiniPlugin +{ + private final CompromisedAccountRepository _repository = new CompromisedAccountRepository(); + + private final CoreClientManager _clientManager = require(CoreClientManager.class); + + private final ApiWebCall _apiCall; + + private CompromisedAccountManager() + { + super("CompedAccount"); + + String url = "http://" + ApiHost.getBanner().getHost() + ":" + ApiHost.getBanner().getPort() + "/"; + _apiCall = new ApiWebCall(url); + } + + public void submitImmediateBan(Player player) + { + _repository.insertPunishment(_clientManager.getAccountId(player), UtilPlayer.getIp(player), "immediate").whenComplete((res, err) -> + { + if (err != null) + { + getPlugin().getLogger().log(Level.SEVERE, "An unexpected error occurred while submitting immediate ban of " + player.getName(), err); + } + }); + } + + public void submitPendingDelayedBan(Player player) + { + _repository.insertPunishment(_clientManager.getAccountId(player), UtilPlayer.getIp(player), "predelayed").whenComplete((res, err) -> + { + if (err != null) + { + getPlugin().getLogger().log(Level.SEVERE, "An unexpected error occurred while submitting delayed ban of " + player.getName(), err); + } + }); + } + + @EventHandler + public void onJoin(PlayerJoinEvent event) + { + CoreClient coreClient = _clientManager.Get(event.getPlayer()); + PlayerInfo playerInfo = new PlayerInfo( + event.getPlayer().getName(), + coreClient.getName(), + event.getPlayer().getUniqueId(), + coreClient.getAccountId(), + UtilPlayer.getIp(event.getPlayer()) + ); + + JsonObject response = _apiCall.post("api/server/login/" + event.getPlayer().getName(), JsonObject.class, playerInfo); + if (response != null && response.get("error") != null) + { + getPlugin().getLogger().log(Level.SEVERE, "Response from Banner: " + response); + } + } +} diff --git a/Plugins/Mineplex.Core/src/mineplex/core/antihack/compedaccount/CompromisedAccountRepository.java b/Plugins/Mineplex.Core/src/mineplex/core/antihack/compedaccount/CompromisedAccountRepository.java new file mode 100644 index 000000000..c9af4fa35 --- /dev/null +++ b/Plugins/Mineplex.Core/src/mineplex/core/antihack/compedaccount/CompromisedAccountRepository.java @@ -0,0 +1,46 @@ +package mineplex.core.antihack.compedaccount; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.SQLException; +import java.util.concurrent.CompletableFuture; + +import mineplex.core.common.util.UtilServer; +import mineplex.serverdata.database.DBPool; +import mineplex.serverdata.database.RepositoryBase; + +public class CompromisedAccountRepository extends RepositoryBase +{ + private static final String INSERT_BAN = "INSERT INTO gwenPunishments (accountId, ip, type) VALUES (?, ?, ?)"; + + public CompromisedAccountRepository() + { + super(DBPool.getAccount()); + } + + public CompletableFuture insertPunishment(int accountId, String ip, String type) + { + CompletableFuture future = new CompletableFuture<>(); + + CompletableFuture.runAsync(() -> { + try (Connection connection = getConnection()) + { + try (PreparedStatement preparedStatement = connection.prepareStatement(INSERT_BAN)) + { + preparedStatement.setInt(1, accountId); + preparedStatement.setString(2, ip); + preparedStatement.setString(3, type); + preparedStatement.executeUpdate(); + } + } + catch (SQLException ex) + { + future.completeExceptionally(ex); + return; + } + future.complete(null); + }); + + return future; + } +} diff --git a/Plugins/Mineplex.Core/src/mineplex/core/antihack/compedaccount/PlayerInfo.java b/Plugins/Mineplex.Core/src/mineplex/core/antihack/compedaccount/PlayerInfo.java new file mode 100644 index 000000000..d80ccf5b9 --- /dev/null +++ b/Plugins/Mineplex.Core/src/mineplex/core/antihack/compedaccount/PlayerInfo.java @@ -0,0 +1,62 @@ +package mineplex.core.antihack.compedaccount; + +import java.util.Objects; +import java.util.UUID; + +public class PlayerInfo +{ + private final String _name; + private final String _realName; + private final UUID _uuid; + private final int _accountId; + private final String _ip; + + public PlayerInfo(String name, String realName, UUID uuid, int accountId, String ip) + { + _name = name; + _realName = realName; + _uuid = uuid; + _accountId = accountId; + _ip = ip; + } + + public String getName() + { + return _name; + } + + public String getRealName() + { + return _realName; + } + + public UUID getUuid() + { + return _uuid; + } + + public int getAccountId() + { + return _accountId; + } + + public String getIp() + { + return _ip; + } + + @Override + public boolean equals(Object o) + { + if (this == o) return true; + if (!(o instanceof PlayerInfo)) return false; + PlayerInfo that = (PlayerInfo) o; + return _accountId == that._accountId; + } + + @Override + public int hashCode() + { + return Objects.hash(_accountId); + } +}