From 9447ca588747e5cabe053646cd1402358d2a25fb Mon Sep 17 00:00:00 2001 From: hexlocation pc Date: Sun, 21 Jul 2024 22:24:58 +0200 Subject: [PATCH] init commit w/ v0.1 release --- .gitignore | 2 + build.sh | 4 + pom.xml | 90 +++++++++ .../java/rip/iwakura/civilcore/CivilCore.java | 33 ++++ .../java/rip/iwakura/civilcore/Database.java | 177 ++++++++++++++++++ .../rip/iwakura/civilcore/PlayerHandler.java | 49 +++++ .../java/rip/iwakura/civilcore/Utils.java | 64 +++++++ .../civilcore/commands/TeamCommand.java | 111 +++++++++++ .../rip/iwakura/civilcore/types/DbPlayer.java | 17 ++ .../rip/iwakura/civilcore/types/Team.java | 19 ++ src/main/resources/config.yml | 0 src/main/resources/plugin.yml | 10 + 12 files changed, 576 insertions(+) create mode 100644 .gitignore create mode 100755 build.sh create mode 100644 pom.xml create mode 100644 src/main/java/rip/iwakura/civilcore/CivilCore.java create mode 100644 src/main/java/rip/iwakura/civilcore/Database.java create mode 100644 src/main/java/rip/iwakura/civilcore/PlayerHandler.java create mode 100644 src/main/java/rip/iwakura/civilcore/Utils.java create mode 100644 src/main/java/rip/iwakura/civilcore/commands/TeamCommand.java create mode 100644 src/main/java/rip/iwakura/civilcore/types/DbPlayer.java create mode 100644 src/main/java/rip/iwakura/civilcore/types/Team.java create mode 100644 src/main/resources/config.yml create mode 100644 src/main/resources/plugin.yml diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..aa0659f --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +target/ +test_server/ diff --git a/build.sh b/build.sh new file mode 100755 index 0000000..88d8a70 --- /dev/null +++ b/build.sh @@ -0,0 +1,4 @@ +mvn clean package dependency:copy -DskipTests -DmcVersion=1.21 -DoutputDirectory=test_server/plugins +cd test_server +java -jar server.jar -nogui +cd ../ diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..8fd1e50 --- /dev/null +++ b/pom.xml @@ -0,0 +1,90 @@ + + + 4.0.0 + + + UTF-8 + 21 + 21 + 1.21 + + + rip.iwakura + CivilCore + 0.1a + + + + spigot-repo + https://hub.spigotmc.org/nexus/content/repositories/snapshots/ + + + papermc + https://repo.papermc.io/repository/maven-public/ + + + + + + org.postgresql + postgresql + 42.7.3 + compile + + + + org.spigotmc + spigot-api + ${mcVersion}-R0.1-SNAPSHOT + + + + org.spigotmc + plugin-annotations + 1.2.3-SNAPSHOT + + + + + + + org.apache.maven.plugins + maven-shade-plugin + 3.1.0 + + + package + + shade + + + false + + + + + + org.apache.maven.plugins + maven-surefire-plugin + 2.22.1 + + + org.apache.maven.plugins + maven-dependency-plugin + 3.5.0 + + + + ${project.groupId} + ${project.artifactId} + ${project.version} + true + + + + + + + diff --git a/src/main/java/rip/iwakura/civilcore/CivilCore.java b/src/main/java/rip/iwakura/civilcore/CivilCore.java new file mode 100644 index 0000000..efa312e --- /dev/null +++ b/src/main/java/rip/iwakura/civilcore/CivilCore.java @@ -0,0 +1,33 @@ +package rip.iwakura.civilcore; + +import java.sql.SQLException; +import java.util.ArrayList; + +import org.bukkit.Bukkit; +import org.bukkit.plugin.java.JavaPlugin; + +import net.md_5.bungee.api.ChatColor; +import rip.iwakura.civilcore.commands.TeamCommand; + +public class CivilCore extends JavaPlugin { + public Database db = new Database(); + + @Override + public void onEnable() { + this.saveDefaultConfig(); + + try { + Class.forName("org.postgresql.Driver"); + } catch (ClassNotFoundException e) { + e.printStackTrace(); + } + + try { + db.connect(this.getConfig().getString("database.url")); + } catch (SQLException e) { + e.printStackTrace(); + } + getServer().getPluginManager().registerEvents(new PlayerHandler(this), this); + this.getCommand("team").setExecutor(new TeamCommand(this)); + } +} diff --git a/src/main/java/rip/iwakura/civilcore/Database.java b/src/main/java/rip/iwakura/civilcore/Database.java new file mode 100644 index 0000000..4fe2e86 --- /dev/null +++ b/src/main/java/rip/iwakura/civilcore/Database.java @@ -0,0 +1,177 @@ +package rip.iwakura.civilcore; + +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Statement; +import java.sql.Types; +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Collectors; + +import org.bukkit.Bukkit; + +import rip.iwakura.civilcore.types.DbPlayer; +import rip.iwakura.civilcore.types.Team; + +public class Database { + public ArrayList players = new ArrayList(); + public ArrayList teams = new ArrayList(); + + private Connection c = null; + + public boolean tableExists(String table) throws SQLException { + if (c.getMetaData().getTables(null, null, table, null).next()) { + return true; + } + return false; + } + + public DbPlayer getPlayerByName(String name) { + List filtered = players.stream().filter( + s -> s.name.equals(name)) + .collect(Collectors.toList()); + if (filtered.isEmpty()) return null; + return filtered.getFirst(); + } + + public Team getTeamByName(String name) { + List filtered = teams.stream().filter( + s -> s.name.equals(name)) + .collect(Collectors.toList()); + if (filtered.isEmpty()) return null; + return filtered.getFirst(); + } + + public void update(String sql) throws SQLException { + Statement stmt = c.createStatement(); + stmt.executeUpdate(sql); + stmt.close(); + } + + public void addPlayerToTeam(Team team, DbPlayer player) throws SQLException { + String sql = "UPDATE players SET TEAM_ID = ? WHERE name = ?; "; + PreparedStatement stmt = c.prepareStatement(sql); + + stmt.setInt(1, team.id); + stmt.setString(2, player.name); + + stmt.executeUpdate(); + + stmt.close(); + + refreshPlayers(); + } + + public void refreshTeams() throws SQLException { + teams.clear(); + Statement stmt = c.createStatement(); + ResultSet rs = stmt.executeQuery("SELECT * FROM teams;"); + + while (rs.next()) { + String name = rs.getString("name"); + String prefix = rs.getString("prefix"); + int id = rs.getInt("team_id"); + + Team team = new Team(name,prefix,id); + teams.add(team); + } + stmt.close(); + rs.close(); + } + + public void refreshPlayers() throws SQLException { + players.clear(); + String sql = "SELECT players.NAME AS player_name, teams.NAME AS team_name, teams.TEAM_ID as t_team_id, teams.PREFIX AS team_prefix " + + "FROM players LEFT JOIN teams ON players.TEAM_ID = teams.TEAM_ID"; + + Statement stmt = c.createStatement(); + ResultSet rs = stmt.executeQuery(sql); + + + while (rs.next()) { + String p_name = rs.getString("player_name"); + String t_name = rs.getString("team_name"); + int t_id = rs.getInt("t_team_id"); + String t_prefix = rs.getString("team_prefix"); + + Team team = new Team(t_name, t_prefix, t_id); + DbPlayer player = new DbPlayer(p_name, team); + players.add(player); + } + stmt.close(); + rs.close(); + } + + public void insertPlayer(DbPlayer player) throws SQLException { + String sql = "INSERT INTO players (NAME,TEAM_ID) " + + "VALUES(?, ?);"; + PreparedStatement stmt = c.prepareStatement(sql); + + stmt.setString(1, player.name); + if(player.team != null) { + stmt.setInt(2, player.team.id); + } else { + stmt.setNull(2, Types.NULL); + } + + stmt.executeUpdate(); + + stmt.close(); + + refreshPlayers(); + } + + public void insertTeam(Team team) throws SQLException { + String sql = "INSERT INTO teams (NAME,PREFIX) " + + "VALUES(?, ?);"; + PreparedStatement stmt = c.prepareStatement(sql); + + stmt.setString(1, team.name); + stmt.setString(2, team.prefix); + + stmt.executeUpdate(); + + stmt.close(); + + refreshTeams(); + } + + + + public void connect(String url) throws SQLException { + try { + Class.forName("org.postgresql.Driver"); + c = DriverManager.getConnection(url); + } catch (Exception e) { + e.printStackTrace(); + Bukkit.getLogger().info("Failed to connect to the database."); + Bukkit.getServer().getPluginManager().disablePlugin(new CivilCore()); + return; + } + Bukkit.getLogger().info("Connected to the database."); + if (!tableExists("teams")) { + String sql = "CREATE TABLE teams " + + "(TEAM_ID SERIAL PRIMARY KEY," + + " NAME TEXT NOT NULL," + + " PREFIX TEXT NOT NULL)"; + update(sql); + } + if (!tableExists("players")) { + String sql = "CREATE TABLE players " + + "(NAME TEXT PRIMARY KEY NOT NULL," + + " TEAM_ID INT, " + + " CONSTRAINT TEAM" + + " FOREIGN KEY(TEAM_ID)" + + " REFERENCES teams(TEAM_ID))"; + update(sql); + } + + refreshTeams(); + refreshPlayers(); + + Bukkit.getLogger().info("Database has been initialized."); + } +} diff --git a/src/main/java/rip/iwakura/civilcore/PlayerHandler.java b/src/main/java/rip/iwakura/civilcore/PlayerHandler.java new file mode 100644 index 0000000..15cc9ac --- /dev/null +++ b/src/main/java/rip/iwakura/civilcore/PlayerHandler.java @@ -0,0 +1,49 @@ +package rip.iwakura.civilcore; + +import java.sql.SQLException; + +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.player.AsyncPlayerChatEvent; +import org.bukkit.event.player.PlayerJoinEvent; + +import net.md_5.bungee.api.ChatColor; +import rip.iwakura.civilcore.types.DbPlayer; + +public class PlayerHandler implements Listener { + + private CivilCore civilCore = null; + + public PlayerHandler(CivilCore civilCore) { + this.civilCore = civilCore; + } + + @EventHandler + public void PlayerChat(AsyncPlayerChatEvent e) { + e.setCancelled(true); + + Player p = e.getPlayer(); + String player_name = p.getName(); + + DbPlayer dbPlayer = civilCore.db.getPlayerByName(player_name); + String prefix = dbPlayer.team.prefix == null ? "" : ChatColor.translateAlternateColorCodes('&', dbPlayer.team.prefix) + " "; + + Bukkit.broadcastMessage(String.format("%s%s: %s", prefix, player_name, e.getMessage())); + } + @EventHandler + public void PlayerJoinEvent(PlayerJoinEvent e) { + Player p = e.getPlayer(); + String player_name = p.getName(); + if(civilCore.db.getPlayerByName(player_name) == null) { + DbPlayer dbPlayer = new DbPlayer(p.getName(), null); + try { + civilCore.db.insertPlayer(dbPlayer); + } catch (SQLException e1) { + e1.printStackTrace(); + } + } + + } +} diff --git a/src/main/java/rip/iwakura/civilcore/Utils.java b/src/main/java/rip/iwakura/civilcore/Utils.java new file mode 100644 index 0000000..a12486d --- /dev/null +++ b/src/main/java/rip/iwakura/civilcore/Utils.java @@ -0,0 +1,64 @@ +package rip.iwakura.civilcore; + +import java.util.ArrayList; + +import org.bukkit.Bukkit; +import org.bukkit.command.CommandSender; + +import net.md_5.bungee.api.ChatColor; + +public class Utils { + private static String buffer = ""; + + private static void finishBuffer(ArrayList args) { + args.add(buffer); + buffer = ""; + } + + public static void exceptionHandler(Exception e, CommandSender sender) { + sender.sendMessage(ChatColor.RED + "Failed to execute command: " + e.getMessage()); + } + + public static ArrayList parser(String[] original_args) { + ArrayList args = new ArrayList(); + + String joined_args = String.join(" ", original_args); + + boolean inColon = false; + char lastCharacter = ' '; + + for (int i = 0; i < joined_args.length(); i++) { + char currentCharacter = joined_args.charAt(i); + + switch (currentCharacter) { + case '"': + if (!inColon) { + inColon = true; + } else { + inColon = false; + finishBuffer(args); + } + break; + + case ' ': + if (!inColon && lastCharacter != '"') { + finishBuffer(args); + break; + } + + if (lastCharacter != '"') buffer += " "; + break; + + default: + buffer+=currentCharacter; + if (i == joined_args.length() - 1) { + finishBuffer(args); + } + break; + } + lastCharacter = currentCharacter; + } + if (inColon) return null; + return args; + } +} diff --git a/src/main/java/rip/iwakura/civilcore/commands/TeamCommand.java b/src/main/java/rip/iwakura/civilcore/commands/TeamCommand.java new file mode 100644 index 0000000..0e1a282 --- /dev/null +++ b/src/main/java/rip/iwakura/civilcore/commands/TeamCommand.java @@ -0,0 +1,111 @@ +package rip.iwakura.civilcore.commands; + +import java.sql.SQLException; + +import org.bukkit.Bukkit; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; + +import net.md_5.bungee.api.ChatColor; +import rip.iwakura.civilcore.Utils; +import rip.iwakura.civilcore.CivilCore; +import rip.iwakura.civilcore.types.DbPlayer; +import rip.iwakura.civilcore.types.Team; + +public class TeamCommand implements CommandExecutor { + private CivilCore civilCore = null; + + public TeamCommand(CivilCore civilCore) { + this.civilCore = civilCore; + } + + @Override + public boolean onCommand(CommandSender sender, Command command, String label, String[] args) { + args = Utils.parser(args).toArray(new String[args.length]); + + if(args.length == 0) { + sender.sendMessage(ChatColor.RED + "Usage: /team [options]"); + return true; + }; + + switch (args[0]) { + case "list": + if (args.length < 2) { + sender.sendMessage(ChatColor.RED + "Usage: /team list "); + return true; + } + + switch (args[1]) { + case "players": + for (DbPlayer dbPlayer : civilCore.db.players) { + if (dbPlayer.team != null) sender.sendMessage(ChatColor.GREEN + String.format("%s belonging to team %s", dbPlayer.name, dbPlayer.team.name)); + if (dbPlayer.team == null) sender.sendMessage(ChatColor.GREEN + String.format("%s does not belong to any team.", dbPlayer.name)); + } + return true; + case "teams": + for (Team team : civilCore.db.teams) { + sender.sendMessage(ChatColor.GREEN + String.format("%s with prefix %s", team.name, ChatColor.translateAlternateColorCodes('&', "&r" + team.prefix))); + } + return true; + default: + sender.sendMessage(ChatColor.RED + "Usage: /team list "); + return true; + } + case "create": + if(args.length < 3) { + sender.sendMessage(ChatColor.RED + "Usage: /team create "); + return true; + }; + + Team team = new Team(args[1], args[2], null); + + try { + civilCore.db.insertTeam(team); + sender.sendMessage(ChatColor.GREEN + String.format("Successfully made team %s with prefix %s", args[1], ChatColor.translateAlternateColorCodes('&', "&r" + args[2]))); + } catch (Exception e) { + e.printStackTrace(); + Utils.exceptionHandler(e, sender); + } + + break; + case "add": + if(args.length < 3) { + sender.sendMessage(ChatColor.RED + "Usage: /team add "); + return true; + }; + + Team found_team = civilCore.db.getTeamByName(args[2]); + DbPlayer dbPlayer = civilCore.db.getPlayerByName(args[1]); + + if (found_team == null) { + sender.sendMessage(ChatColor.RED + "The team you are referencing does not exist."); + return true; + } + + String success_msg = ChatColor.GREEN + String.format("Successfully added %s to team %s.", args[1], args[2]); + + if(dbPlayer == null) { + dbPlayer = new DbPlayer(args[1], found_team); + try { + civilCore.db.insertPlayer(dbPlayer); + sender.sendMessage(success_msg); + } catch (Exception e) { + e.printStackTrace(); + Utils.exceptionHandler(e, sender); + } + return true; + } + + try { + civilCore.db.addPlayerToTeam(found_team, dbPlayer); + sender.sendMessage(success_msg); + } catch (Exception e) { + e.printStackTrace(); + Utils.exceptionHandler(e, sender); + } + break; + } + return true; + } +} diff --git a/src/main/java/rip/iwakura/civilcore/types/DbPlayer.java b/src/main/java/rip/iwakura/civilcore/types/DbPlayer.java new file mode 100644 index 0000000..5e1d6bd --- /dev/null +++ b/src/main/java/rip/iwakura/civilcore/types/DbPlayer.java @@ -0,0 +1,17 @@ +package rip.iwakura.civilcore.types; + +/* + * Player Type + * @String name + * @Team team + */ +public class DbPlayer { + + public Team team = null; + public String name = null; + + public DbPlayer(String name, Team team) { + this.name = name; + this.team = team; + } +} diff --git a/src/main/java/rip/iwakura/civilcore/types/Team.java b/src/main/java/rip/iwakura/civilcore/types/Team.java new file mode 100644 index 0000000..704bf3a --- /dev/null +++ b/src/main/java/rip/iwakura/civilcore/types/Team.java @@ -0,0 +1,19 @@ +package rip.iwakura.civilcore.types; + +/* + * Team Type + * @string name + * @string prefix + */ +public class Team { + + public String prefix = null; + public String name = null; + public Integer id = null; + + public Team(String name, String prefix, Integer id) { + this.prefix = prefix; + this.name = name; + this.id = id; + } +} diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml new file mode 100644 index 0000000..e69de29 diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml new file mode 100644 index 0000000..7152f6b --- /dev/null +++ b/src/main/resources/plugin.yml @@ -0,0 +1,10 @@ +main: rip.iwakura.civilcore.CivilCore +name: CivilCore +version: 0.1 +description: Core plugin for the CivilWars SMP +api-version: 1.21 +author: hex +commands: + team: + description: Team Manager + usage: /