init commit w/ v0.1 release
This commit is contained in:
commit
9447ca5887
12 changed files with 576 additions and 0 deletions
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
|
@ -0,0 +1,2 @@
|
|||
target/
|
||||
test_server/
|
4
build.sh
Executable file
4
build.sh
Executable 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
90
pom.xml
Normal 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>
|
33
src/main/java/rip/iwakura/civilcore/CivilCore.java
Normal file
33
src/main/java/rip/iwakura/civilcore/CivilCore.java
Normal 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));
|
||||
}
|
||||
}
|
177
src/main/java/rip/iwakura/civilcore/Database.java
Normal file
177
src/main/java/rip/iwakura/civilcore/Database.java
Normal 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.");
|
||||
}
|
||||
}
|
49
src/main/java/rip/iwakura/civilcore/PlayerHandler.java
Normal file
49
src/main/java/rip/iwakura/civilcore/PlayerHandler.java
Normal 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();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
64
src/main/java/rip/iwakura/civilcore/Utils.java
Normal file
64
src/main/java/rip/iwakura/civilcore/Utils.java
Normal 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;
|
||||
}
|
||||
}
|
111
src/main/java/rip/iwakura/civilcore/commands/TeamCommand.java
Normal file
111
src/main/java/rip/iwakura/civilcore/commands/TeamCommand.java
Normal 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;
|
||||
}
|
||||
}
|
17
src/main/java/rip/iwakura/civilcore/types/DbPlayer.java
Normal file
17
src/main/java/rip/iwakura/civilcore/types/DbPlayer.java
Normal 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;
|
||||
}
|
||||
}
|
19
src/main/java/rip/iwakura/civilcore/types/Team.java
Normal file
19
src/main/java/rip/iwakura/civilcore/types/Team.java
Normal 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;
|
||||
}
|
||||
}
|
0
src/main/resources/config.yml
Normal file
0
src/main/resources/config.yml
Normal file
10
src/main/resources/plugin.yml
Normal file
10
src/main/resources/plugin.yml
Normal 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>
|
Loading…
Reference in a new issue