Sketch of connection refusing system

This commit is contained in:
Tomasz Kuraczyk 2026-02-22 00:30:11 +01:00
parent 49e5051aaf
commit 053bc0a83b
12 changed files with 663 additions and 93 deletions

View file

@ -0,0 +1,61 @@
package net.kuraczyk.banhammer;
import net.kuraczyk.banhammer.events.PlayerPreLogin;
import org.bukkit.ChatColor;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.plugin.java.JavaPlugin;
import net.kuraczyk.banhammer.utils.*;
public final class BanHammer extends JavaPlugin {
public FileConfiguration config;
public DBManager db;
@Override
public void onEnable() {
saveDefaultConfig();
config = getConfig();
try {
Class.forName("net.kuraczyk.libs.postgresql.Driver");
} catch (ClassNotFoundException e) {
throw new RuntimeException(e);
}
db = new DBManager(
config.getString("database.host"),
config.getInt("database.port"),
config.getString("database.user"),
config.getString("database.pass"),
config.getString("database.database"),
this.getClassLoader()
);
String error = db.connect();
if(error != null){
getLogger().severe(
"Failed to connect to DB!!!!\n"
+error
);
getServer().getPluginManager().disablePlugin(this);
}
getLogger().info(ChatColor.translateAlternateColorCodes('&', "&a&b+&r&8 | &aBan&7Hammer"));
getServer().getPluginManager().registerEvents(new PlayerPreLogin(this), this);
}
@Override
public void onDisable() {
if(db != null){
String error = db.disconnect();
if(error != null) {
getLogger().severe(
"Error occured while disconnecting from from DB!!!!\n"
+error
);
}
}
getLogger().info(ChatColor.translateAlternateColorCodes('&', "&c&b-&r&8 | &aBan&7Hammer"));
}
}

View file

@ -0,0 +1,126 @@
package net.kuraczyk.banhammer.events;
import net.kuraczyk.banhammer.BanHammer;
import net.kyori.adventure.text.Component;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.player.AsyncPlayerPreLoginEvent;
import java.net.InetAddress;
import java.sql.*;
import java.util.UUID;
import java.util.concurrent.TimeUnit;
import net.kuraczyk.banhammer.utils.TextUtils;
public class PlayerPreLogin implements Listener {
BanHammer plugin;
Component kickMessage = Component.text("If this message is displayed something went terribly wrong...\nModule: BanHammer");
public PlayerPreLogin(BanHammer m) {
plugin = m;
m.getClass();
}
@EventHandler
public void onPlayerPreLogin(AsyncPlayerPreLoginEvent e) {
if(checkPlayerBanStatus(e.getPlayerProfile().getName(), e.getUniqueId(), e.getAddress()))
e.disallow(AsyncPlayerPreLoginEvent.Result.KICK_BANNED, kickMessage);
}
private boolean checkPlayerBanStatus(String nickname, UUID uuid, InetAddress ip) {
try {
Connection conn = plugin.db.getConnection();
if(conn!=null){
PreparedStatement ps = conn.prepareStatement("SELECT * from player_bans WHERE (player_name = ? OR player_uuid = ?::uuid) AND (scope = ? OR scope = '*')");
ps.setString(1, nickname);
ps.setObject(2, uuid);
ps.setString(3, plugin.getConfig().getString("serverID"));
ResultSet rs = ps.executeQuery();
while(rs.next()){
String reason = rs.getString("reason");
String parsedDate;
if(rs.getObject("end_time")!=null){
long timeLeft = ((Timestamp)rs.getObject("end_time")).getTime() - new Timestamp(System.currentTimeMillis()).getTime();
if(timeLeft <= 0) {
PreparedStatement archiveBan = conn.prepareStatement("DELETE FROM player_bans WHERE id = ?::uuid");
archiveBan.setString(1, rs.getObject("id").toString());
archiveBan.executeUpdate();
continue;
}
long timeLeftDays = TimeUnit.MILLISECONDS.toDays(timeLeft);
timeLeft-=TimeUnit.DAYS.toMillis(timeLeftDays);
long timeLeftHours = TimeUnit.MILLISECONDS.toHours(timeLeft);
timeLeft-=TimeUnit.HOURS.toMillis(timeLeftHours);
long timeLeftMinutes = TimeUnit.MILLISECONDS.toMinutes(timeLeft);
timeLeft-=TimeUnit.MINUTES.toMillis(timeLeftMinutes);
long timeLeftSeconds = TimeUnit.MILLISECONDS.toSeconds(timeLeft);
timeLeft-=TimeUnit.SECONDS.toMillis(timeLeftSeconds);
parsedDate = TextUtils.parsePolishDate(timeLeftDays, timeLeftHours, timeLeftMinutes, timeLeftSeconds);
kickMessage = TextUtils.colorString(TextUtils.resolvePlaceholders(String.format("Zostałeś zbanowany na %s.\nPowód: %s", parsedDate, reason)));
return true;
}
else {
kickMessage = TextUtils.colorString(TextUtils.resolvePlaceholders(String.format("Zostałeś permanentnie zbanowany.\nPowód: %s", reason)));
return true;
}
}
PreparedStatement ps2 = conn.prepareStatement("SELECT * from ip_bans WHERE (ip_address = ?::inet) AND (scope = ? OR scope = '*')");
ps2.setObject(1, ip.getHostAddress());
ps2.setString(2, plugin.getConfig().getString("serverID"));
ResultSet rs2 = ps2.executeQuery();
while(rs2.next()) {
String reason = rs2.getString("reason");
String parsedDate;
if(rs2.getObject("end_time")!=null){
long timeLeft = ((Timestamp)rs2.getObject("end_time")).getTime() - new Timestamp(System.currentTimeMillis()).getTime();
if(timeLeft <= 0) {
PreparedStatement archiveBan = conn.prepareStatement("DELETE FROM ip_bans WHERE id = ?::uuid");
archiveBan.setString(1, rs2.getObject("id").toString());
archiveBan.executeUpdate();
continue;
}
long timeLeftDays = TimeUnit.MILLISECONDS.toDays(timeLeft);
timeLeft-=TimeUnit.DAYS.toMillis(timeLeftDays);
long timeLeftHours = TimeUnit.MILLISECONDS.toHours(timeLeft);
timeLeft-=TimeUnit.HOURS.toMillis(timeLeftHours);
long timeLeftMinutes = TimeUnit.MILLISECONDS.toMinutes(timeLeft);
timeLeft-=TimeUnit.MINUTES.toMillis(timeLeftMinutes);
long timeLeftSeconds = TimeUnit.MILLISECONDS.toSeconds(timeLeft);
timeLeft-=TimeUnit.SECONDS.toMillis(timeLeftSeconds);
parsedDate = TextUtils.parsePolishDate(timeLeftDays, timeLeftHours, timeLeftMinutes, timeLeftSeconds);
kickMessage = TextUtils.colorString(TextUtils.resolvePlaceholders(String.format("Zostałeś IPzbanowany na %s.\nPowód: %s", parsedDate, reason)));
return true;
}
else {
kickMessage = TextUtils.colorString(TextUtils.resolvePlaceholders(String.format("Zostałeś permanentnie IPzbanowany.\nPowód: %s", reason)));
return true;
}
}
return false;
}
} catch (SQLException e) {
plugin.getLogger().severe(e.toString());
}
return true;
}
}

View file

@ -0,0 +1,92 @@
package net.kuraczyk.banhammer.utils;
import org.apache.commons.lang3.tuple.Pair;
import org.flywaydb.core.Flyway;
import org.flywaydb.core.api.output.MigrateResult;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Struct;
public class DBManager {
private String host, user, pass, database;
private int port;
private Connection connection;
private ClassLoader classLoader;
public DBManager(String host, int port, String user, String pass, String database, ClassLoader classLoader) {
this.host = host;
this.port = port;
this.user = user;
this.pass = pass;
this.database = database;
this.classLoader = classLoader;
}
public String connect() {
try {
if(connection != null && !connection.isClosed()){
return null;
}
connection = DriverManager.getConnection(String.format("jdbc:postgresql://%s:%d/%s", host, port, database), user, pass);
String migrationSuccess = performMigration();
if(migrationSuccess != null){
return migrationSuccess;
}
return null;
} catch (SQLException e) {
return e.toString();
}
}
public String disconnect() {
try {
if(connection != null && !connection.isClosed()){
connection.close();
return null;
}
return "Error";
} catch (SQLException e) {
return e.toString();
}
}
public Connection getConnection() throws SQLException {
if(connection == null || connection.isClosed()){
return null;
}
return connection;
}
private String performMigration() {
try {
Flyway flyway = Flyway.configure(classLoader)
.driver("net.kuraczyk.libs.postgresql.Driver")
.dataSource(String.format("jdbc:postgresql://%s:%d/%s", host, port, database), user, pass)
.locations("classpath:db/migration")
.baselineOnMigrate(true)
.validateOnMigrate(true)
.cleanDisabled(true)
.table("flyway_schema_history")
.load();
MigrateResult result = flyway.migrate();
if (result.success) {
return null;
} else {
return result.warnings.toString();
}
} catch (Exception e) {
return e.toString();
}
}
}

View file

@ -0,0 +1,121 @@
package net.kuraczyk.banhammer.utils;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.minimessage.MiniMessage;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.entity.Player;
import java.util.Arrays;
public class TextUtils {
public static Component colorString(String s){
return colorMarkupFormattedString(
colorLegacyFormattedString(s)
);
}
private static Component colorMarkupFormattedString(String s){
return MiniMessage.miniMessage().deserialize(s);
}
private static String colorLegacyFormattedString(String s){
return ChatColor.translateAlternateColorCodes('&', s);
}
public static String resolvePlaceholders(String s){
return s.replace("{onlinePlayerCount}", String.valueOf(
Bukkit.getOnlinePlayers().size()+Arrays.stream(Bukkit.getOfflinePlayers()).count()
));
}
public static String resolvePlaceholders(String s, Player p){
return resolvePlaceholders(s)
.replace("{playerName}", p.getName())
.replace("{ping}", String.valueOf(p.getPing()));
}
public static String parsePolishDate(long days, long hours, long minutes, long seconds){
String parsedDays, parsedHours, parsedMinutes, parsedSeconds;
// Parse days string block
if(days >= 2){
parsedDays="dni";
}
else if (days==1){
parsedDays="dzień";
}
else{
parsedDays="";
}
if(parsedDays!="") parsedDays=Long.toString(days)+' '+parsedDays+", ";
// Parse hours string block
if(hours >= 20 || (hours < 10 && hours > 1)){
if(hours%10 >=2 && hours%10 <=4){
parsedHours="godziny";
}
else{
parsedHours="godzin";
}
}
else if(hours < 20 && hours >= 10){
parsedHours="godzin";
}
else if (hours==1){
parsedHours="godzina";
}
else{
parsedHours="";
}
if(parsedHours!="") parsedHours=Long.toString(hours)+' '+parsedHours+", ";
// Parse minutes string block
if(minutes >= 20 || (minutes < 10 && minutes > 1)){
if(minutes%10 >=2 && minutes%10 <=4){
parsedMinutes="minuty";
}
else{
parsedMinutes="minut";
}
}
else if(minutes < 20 && minutes >= 10){
parsedMinutes="minut";
}
else if (minutes==1){
parsedMinutes="minuta";
}
else{
parsedMinutes="";
}
if(parsedMinutes!="") parsedMinutes=Long.toString(minutes)+' '+parsedMinutes+", ";
// Parse seconds string block
if(seconds >= 20 || (seconds < 10 && seconds > 1)){
if(seconds%10 >=2 && seconds%10 <=4){
parsedSeconds="sekundy";
}
else{
parsedSeconds="sekund";
}
}
else if(seconds < 20 && seconds >= 10){
parsedSeconds="sekund";
}
else if (seconds==1){
parsedSeconds="sekunda";
}
else{
parsedSeconds="";
}
if(parsedSeconds!="") parsedSeconds=Long.toString(seconds)+' '+parsedSeconds+", ";
// Create final gramatically correct string
String result = String.format("%s%s%s%s", parsedDays, parsedHours, parsedMinutes, parsedSeconds);
if(result.length()>=2) result = result.substring(0, result.length() - 2);
return result;
}
}