init commit w/ v0.1 release

This commit is contained in:
hexlocation pc 2024-07-21 22:24:58 +02:00
commit 9447ca5887
12 changed files with 576 additions and 0 deletions

2
.gitignore vendored Normal file
View file

@ -0,0 +1,2 @@
target/
test_server/

4
build.sh Executable file
View file

@ -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 ../

90
pom.xml Normal file
View file

@ -0,0 +1,90 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>21</maven.compiler.source>
<maven.compiler.target>21</maven.compiler.target>
<mcVersion>1.21</mcVersion> <!-- default mc version -->
</properties>
<groupId>rip.iwakura</groupId>
<artifactId>CivilCore</artifactId>
<version>0.1a</version>
<repositories>
<repository>
<id>spigot-repo</id>
<url>https://hub.spigotmc.org/nexus/content/repositories/snapshots/</url>
</repository>
<repository>
<id>papermc</id>
<url>https://repo.papermc.io/repository/maven-public/</url>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>42.7.3</version>
<scope>compile</scope>
</dependency>
<!-- spigot api -->
<dependency>
<groupId>org.spigotmc</groupId>
<artifactId>spigot-api</artifactId>
<version>${mcVersion}-R0.1-SNAPSHOT</version>
</dependency>
<!-- plugin annotations -->
<dependency>
<groupId>org.spigotmc</groupId>
<artifactId>plugin-annotations</artifactId>
<version>1.2.3-SNAPSHOT</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.1.0</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<createDependencyReducedPom>false</createDependencyReducedPom>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.22.1</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>3.5.0</version>
<configuration>
<artifactItems>
<artifactItem>
<groupId>${project.groupId}</groupId>
<artifactId>${project.artifactId}</artifactId>
<version>${project.version}</version>
<overWrite>true</overWrite>
</artifactItem>
</artifactItems>
</configuration>
</plugin>
</plugins>
</build>
</project>

View file

@ -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));
}
}

View file

@ -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<DbPlayer> players = new ArrayList<DbPlayer>();
public ArrayList<Team> teams = new ArrayList<Team>();
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<DbPlayer> 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<Team> 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.");
}
}

View file

@ -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();
}
}
}
}

View file

@ -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<String> 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<String> parser(String[] original_args) {
ArrayList<String> args = new ArrayList<String>();
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;
}
}

View file

@ -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 <create | destroy | add | remove | list> [options]");
return true;
};
switch (args[0]) {
case "list":
if (args.length < 2) {
sender.sendMessage(ChatColor.RED + "Usage: /team list <teams | players>");
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 <teams | players>");
return true;
}
case "create":
if(args.length < 3) {
sender.sendMessage(ChatColor.RED + "Usage: /team create <name> <prefix>");
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 <player> <team name>");
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;
}
}

View file

@ -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;
}
}

View file

@ -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;
}
}

View file

View file

@ -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: /<command> <create|destroy|add|remove>