diff --git a/.classpath b/.classpath
new file mode 100644
index 0000000..720c4f0
--- /dev/null
+++ b/.classpath
@@ -0,0 +1,24 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/.gitignore b/.gitignore
index aa0659f..b161ed0 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,2 +1,7 @@
target/
test_server/
+.gradle
+build/
+server/
+bin/
+bin/*
diff --git a/.project b/.project
new file mode 100644
index 0000000..28c5951
--- /dev/null
+++ b/.project
@@ -0,0 +1,34 @@
+
+
+ CivilCore
+ Project civilcore created by Buildship.
+
+
+
+
+ org.eclipse.jdt.core.javabuilder
+
+
+
+
+ org.eclipse.buildship.core.gradleprojectbuilder
+
+
+
+
+
+ org.eclipse.jdt.core.javanature
+ org.eclipse.buildship.core.gradleprojectnature
+
+
+
+ 1745013535336
+
+ 30
+
+ org.eclipse.core.resources.regexFilterMatcher
+ node_modules|\.git|__CREATED_BY_JAVA_LANGUAGE_SERVER__
+
+
+
+
diff --git a/.settings/org.eclipse.buildship.core.prefs b/.settings/org.eclipse.buildship.core.prefs
new file mode 100644
index 0000000..8fc1399
--- /dev/null
+++ b/.settings/org.eclipse.buildship.core.prefs
@@ -0,0 +1,13 @@
+arguments=--init-script /home/hex/.cache/jdtls/config/org.eclipse.osgi/248/0/.cp/gradle/init/init.gradle
+auto.sync=false
+build.scans.enabled=false
+connection.gradle.distribution=GRADLE_DISTRIBUTION(WRAPPER)
+connection.project.dir=
+eclipse.preferences.version=1
+gradle.user.home=
+java.home=/opt/openjdk-bin-21.0.6_p7
+jvm.arguments=
+offline.mode=false
+override.workspace.settings=true
+show.console.view=true
+show.executions.view=true
diff --git a/CivilCore.iml b/CivilCore.iml
deleted file mode 100644
index 9cb719e..0000000
--- a/CivilCore.iml
+++ /dev/null
@@ -1,13 +0,0 @@
-
-
-
-
-
-
- BUKKIT
-
- 1
-
-
-
-
\ No newline at end of file
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..15ec143
--- /dev/null
+++ b/README.md
@@ -0,0 +1,3 @@
+# CivilCore (v2)
+
+PaperMC plugin written in Kotlin for civil.iwakura.rip.
diff --git a/build.gradle.kts b/build.gradle.kts
new file mode 100644
index 0000000..79c11f9
--- /dev/null
+++ b/build.gradle.kts
@@ -0,0 +1,45 @@
+group = "rip.iwakura"
+version = "2.1.1"
+
+plugins {
+ java
+ id("com.gradleup.shadow") version "8.3.6"
+ id("de.eldoria.plugin-yml.paper") version "0.7.1"
+}
+
+repositories {
+ mavenCentral()
+ maven {
+ name = "papermc"
+ url = uri("https://repo.papermc.io/repository/maven-public/")
+ }
+}
+
+paper {
+ main = "rip.iwakura.civil.Core"
+ authors = listOf("hex", "grng")
+ apiVersion = "1.21"
+}
+
+tasks {
+ register("copyToServer") {
+ from(shadowJar)
+ destinationDir = File("server/plugins")
+ }
+ build {
+ dependsOn(shadowJar)
+ }
+}
+
+dependencies {
+ compileOnly("io.papermc.paper:paper-api:1.21.4-R0.1-SNAPSHOT")
+ implementation("club.minnced:discord-webhooks:0.8.4")
+ implementation("net.dv8tion:JDA:5.3.2")
+ implementation("com.j256.ormlite", "ormlite-jdbc", "6.1")
+ implementation("org.postgresql", "postgresql", "42.7.5")
+ library("com.google.code.gson", "gson", "2.10.1") // All platform plugins
+}
+
+java {
+ toolchain.languageVersion.set(JavaLanguageVersion.of(21))
+}
diff --git a/build.sh b/build.sh
old mode 100755
new mode 100644
index 88d8a70..1404b4f
--- a/build.sh
+++ b/build.sh
@@ -1,4 +1,10 @@
-mvn clean package dependency:copy -DskipTests -DmcVersion=1.21 -DoutputDirectory=test_server/plugins
-cd test_server
-java -jar server.jar -nogui
-cd ../
+#!/bin/bash
+
+catch () {
+ echo "An error occured: see above."
+ exit 1
+}
+
+./gradlew clean build copyToServer || catch
+
+cd server && java -jar server.jar -nogui && cd ..
diff --git a/db.ps1 b/db.ps1
deleted file mode 100644
index 01fddb1..0000000
--- a/db.ps1
+++ /dev/null
@@ -1,2 +0,0 @@
-docker-compose up
-docker ps
\ No newline at end of file
diff --git a/docker-compose.yml b/docker-compose.yml
index 5765784..93ceec2 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -3,6 +3,6 @@ services:
civil_test_db:
environment:
- POSTGRES_PASSWORD=TEST123
- image: postgres:16.3
+ image: docker.io/postgres:16.3
ports:
- - 5432:5432
\ No newline at end of file
+ - 127.0.0.1:5432:5432
diff --git a/gradle.properties b/gradle.properties
new file mode 100644
index 0000000..377538c
--- /dev/null
+++ b/gradle.properties
@@ -0,0 +1,5 @@
+# This file was generated by the Gradle 'init' task.
+# https://docs.gradle.org/current/userguide/build_environment.html#sec:gradle_configuration_properties
+
+org.gradle.configuration-cache=true
+
diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml
new file mode 100644
index 0000000..ca02e23
--- /dev/null
+++ b/gradle/libs.versions.toml
@@ -0,0 +1,8 @@
+# This file was generated by the Gradle 'init' task.
+# https://docs.gradle.org/current/userguide/platforms.html#sub::toml-dependencies-format
+
+[versions]
+kotlin-gradle-plugin = "2.0.20"
+
+[libraries]
+kotlin-gradle-plugin = { module = "org.jetbrains.kotlin:kotlin-gradle-plugin", version.ref = "kotlin-gradle-plugin" }
diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar
new file mode 100644
index 0000000..a4b76b9
Binary files /dev/null and b/gradle/wrapper/gradle-wrapper.jar differ
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 0000000..e2847c8
--- /dev/null
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,7 @@
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-8.11.1-bin.zip
+networkTimeout=10000
+validateDistributionUrl=true
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
diff --git a/gradlew b/gradlew
new file mode 100644
index 0000000..f5feea6
--- /dev/null
+++ b/gradlew
@@ -0,0 +1,252 @@
+#!/bin/sh
+
+#
+# Copyright © 2015-2021 the original authors.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# SPDX-License-Identifier: Apache-2.0
+#
+
+##############################################################################
+#
+# Gradle start up script for POSIX generated by Gradle.
+#
+# Important for running:
+#
+# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is
+# noncompliant, but you have some other compliant shell such as ksh or
+# bash, then to run this script, type that shell name before the whole
+# command line, like:
+#
+# ksh Gradle
+#
+# Busybox and similar reduced shells will NOT work, because this script
+# requires all of these POSIX shell features:
+# * functions;
+# * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,
+# «${var#prefix}», «${var%suffix}», and «$( cmd )»;
+# * compound commands having a testable exit status, especially «case»;
+# * various built-in commands including «command», «set», and «ulimit».
+#
+# Important for patching:
+#
+# (2) This script targets any POSIX shell, so it avoids extensions provided
+# by Bash, Ksh, etc; in particular arrays are avoided.
+#
+# The "traditional" practice of packing multiple parameters into a
+# space-separated string is a well documented source of bugs and security
+# problems, so this is (mostly) avoided, by progressively accumulating
+# options in "$@", and eventually passing that to Java.
+#
+# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,
+# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;
+# see the in-line comments for details.
+#
+# There are tweaks for specific operating systems such as AIX, CygWin,
+# Darwin, MinGW, and NonStop.
+#
+# (3) This script is generated from the Groovy template
+# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
+# within the Gradle project.
+#
+# You can find Gradle at https://github.com/gradle/gradle/.
+#
+##############################################################################
+
+# Attempt to set APP_HOME
+
+# Resolve links: $0 may be a link
+app_path=$0
+
+# Need this for daisy-chained symlinks.
+while
+ APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path
+ [ -h "$app_path" ]
+do
+ ls=$( ls -ld "$app_path" )
+ link=${ls#*' -> '}
+ case $link in #(
+ /*) app_path=$link ;; #(
+ *) app_path=$APP_HOME$link ;;
+ esac
+done
+
+# This is normally unused
+# shellcheck disable=SC2034
+APP_BASE_NAME=${0##*/}
+# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)
+APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s
+' "$PWD" ) || exit
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD=maximum
+
+warn () {
+ echo "$*"
+} >&2
+
+die () {
+ echo
+ echo "$*"
+ echo
+ exit 1
+} >&2
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+nonstop=false
+case "$( uname )" in #(
+ CYGWIN* ) cygwin=true ;; #(
+ Darwin* ) darwin=true ;; #(
+ MSYS* | MINGW* ) msys=true ;; #(
+ NONSTOP* ) nonstop=true ;;
+esac
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+ if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+ # IBM's JDK on AIX uses strange locations for the executables
+ JAVACMD=$JAVA_HOME/jre/sh/java
+ else
+ JAVACMD=$JAVA_HOME/bin/java
+ fi
+ if [ ! -x "$JAVACMD" ] ; then
+ die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+ fi
+else
+ JAVACMD=java
+ if ! command -v java >/dev/null 2>&1
+ then
+ die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+ fi
+fi
+
+# Increase the maximum file descriptors if we can.
+if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
+ case $MAX_FD in #(
+ max*)
+ # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.
+ # shellcheck disable=SC2039,SC3045
+ MAX_FD=$( ulimit -H -n ) ||
+ warn "Could not query maximum file descriptor limit"
+ esac
+ case $MAX_FD in #(
+ '' | soft) :;; #(
+ *)
+ # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.
+ # shellcheck disable=SC2039,SC3045
+ ulimit -n "$MAX_FD" ||
+ warn "Could not set maximum file descriptor limit to $MAX_FD"
+ esac
+fi
+
+# Collect all arguments for the java command, stacking in reverse order:
+# * args from the command line
+# * the main class name
+# * -classpath
+# * -D...appname settings
+# * --module-path (only if needed)
+# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.
+
+# For Cygwin or MSYS, switch paths to Windows format before running java
+if "$cygwin" || "$msys" ; then
+ APP_HOME=$( cygpath --path --mixed "$APP_HOME" )
+ CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" )
+
+ JAVACMD=$( cygpath --unix "$JAVACMD" )
+
+ # Now convert the arguments - kludge to limit ourselves to /bin/sh
+ for arg do
+ if
+ case $arg in #(
+ -*) false ;; # don't mess with options #(
+ /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath
+ [ -e "$t" ] ;; #(
+ *) false ;;
+ esac
+ then
+ arg=$( cygpath --path --ignore --mixed "$arg" )
+ fi
+ # Roll the args list around exactly as many times as the number of
+ # args, so each arg winds up back in the position where it started, but
+ # possibly modified.
+ #
+ # NB: a `for` loop captures its iteration list before it begins, so
+ # changing the positional parameters here affects neither the number of
+ # iterations, nor the values presented in `arg`.
+ shift # remove old arg
+ set -- "$@" "$arg" # push replacement arg
+ done
+fi
+
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
+
+# Collect all arguments for the java command:
+# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,
+# and any embedded shellness will be escaped.
+# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be
+# treated as '${Hostname}' itself on the command line.
+
+set -- \
+ "-Dorg.gradle.appname=$APP_BASE_NAME" \
+ -classpath "$CLASSPATH" \
+ org.gradle.wrapper.GradleWrapperMain \
+ "$@"
+
+# Stop when "xargs" is not available.
+if ! command -v xargs >/dev/null 2>&1
+then
+ die "xargs is not available"
+fi
+
+# Use "xargs" to parse quoted args.
+#
+# With -n1 it outputs one arg per line, with the quotes and backslashes removed.
+#
+# In Bash we could simply go:
+#
+# readarray ARGS < <( xargs -n1 <<<"$var" ) &&
+# set -- "${ARGS[@]}" "$@"
+#
+# but POSIX shell has neither arrays nor command substitution, so instead we
+# post-process each arg (as a line of input to sed) to backslash-escape any
+# character that might be a shell metacharacter, then use eval to reverse
+# that process (while maintaining the separation between arguments), and wrap
+# the whole thing up as a single "set" statement.
+#
+# This will of course break if any of these variables contains a newline or
+# an unmatched quote.
+#
+
+eval "set -- $(
+ printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" |
+ xargs -n1 |
+ sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' |
+ tr '\n' ' '
+ )" '"$@"'
+
+exec "$JAVACMD" "$@"
diff --git a/gradlew.bat b/gradlew.bat
new file mode 100644
index 0000000..9b42019
--- /dev/null
+++ b/gradlew.bat
@@ -0,0 +1,94 @@
+@rem
+@rem Copyright 2015 the original author or authors.
+@rem
+@rem Licensed under the Apache License, Version 2.0 (the "License");
+@rem you may not use this file except in compliance with the License.
+@rem You may obtain a copy of the License at
+@rem
+@rem https://www.apache.org/licenses/LICENSE-2.0
+@rem
+@rem Unless required by applicable law or agreed to in writing, software
+@rem distributed under the License is distributed on an "AS IS" BASIS,
+@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+@rem See the License for the specific language governing permissions and
+@rem limitations under the License.
+@rem
+@rem SPDX-License-Identifier: Apache-2.0
+@rem
+
+@if "%DEBUG%"=="" @echo off
+@rem ##########################################################################
+@rem
+@rem Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+set DIRNAME=%~dp0
+if "%DIRNAME%"=="" set DIRNAME=.
+@rem This is normally unused
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Resolve any "." and ".." in APP_HOME to make it shorter.
+for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if %ERRORLEVEL% equ 0 goto execute
+
+echo. 1>&2
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2
+echo. 1>&2
+echo Please set the JAVA_HOME variable in your environment to match the 1>&2
+echo location of your Java installation. 1>&2
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto execute
+
+echo. 1>&2
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2
+echo. 1>&2
+echo Please set the JAVA_HOME variable in your environment to match the 1>&2
+echo location of your Java installation. 1>&2
+
+goto fail
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
+
+:end
+@rem End local scope for the variables with windows NT shell
+if %ERRORLEVEL% equ 0 goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+set EXIT_CODE=%ERRORLEVEL%
+if %EXIT_CODE% equ 0 set EXIT_CODE=1
+if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
+exit /b %EXIT_CODE%
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega
diff --git a/kls_database.db b/kls_database.db
new file mode 100644
index 0000000..4fd9015
Binary files /dev/null and b/kls_database.db differ
diff --git a/pom.xml b/pom.xml
deleted file mode 100644
index 976bac2..0000000
--- a/pom.xml
+++ /dev/null
@@ -1,106 +0,0 @@
-
-
- 4.0.0
-
-
- UTF-8
- 21
- 21
- 1.21
-
-
- rip.iwakura
- CivilCore
- 0.1c
-
-
-
- spigot-repo
- https://hub.spigotmc.org/nexus/content/repositories/snapshots/
-
-
- papermc
- https://repo.papermc.io/repository/maven-public/
-
-
- jitpack.io
- https://jitpack.io
-
-
-
-
-
- net.dv8tion
- JDA
- 5.0.1
- compile
-
-
- club.minnced
- discord-webhooks
- 0.1.6
- compile
-
-
- 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/run.ps1 b/run.ps1
deleted file mode 100644
index 3260453..0000000
--- a/run.ps1
+++ /dev/null
@@ -1,9 +0,0 @@
-if (-not (Test-Path -Path test_server)) {
- New-Item -ItemType Directory -Path test_server
-}
-
-# mvn clean package dependency:copy -DskipTests -DoutputDirectory=test_server/plugins
-
-Set-Location -Path test_server
-java -jar server.jar -nogui
-Set-Location -Path ..
\ No newline at end of file
diff --git a/settings.gradle.kts b/settings.gradle.kts
new file mode 100644
index 0000000..82d9ae2
--- /dev/null
+++ b/settings.gradle.kts
@@ -0,0 +1,13 @@
+/*
+ * This file was generated by the Gradle 'init' task.
+ *
+ * The settings file is used to specify which projects to include in your build.
+ * For more detailed information on multi-project builds, please refer to https://docs.gradle.org/8.11.1/userguide/multi_project_builds.html in the Gradle documentation.
+ */
+
+plugins {
+ // Apply the foojay-resolver plugin to allow automatic download of JDKs
+ id("org.gradle.toolchains.foojay-resolver-convention") version "0.8.0"
+}
+
+rootProject.name = "CivilCore"
diff --git a/src/main/java/rip/iwakura/civil/Core.java b/src/main/java/rip/iwakura/civil/Core.java
new file mode 100644
index 0000000..04c8cae
--- /dev/null
+++ b/src/main/java/rip/iwakura/civil/Core.java
@@ -0,0 +1,115 @@
+package rip.iwakura.civil;
+
+import java.sql.SQLException;
+import java.util.ArrayList;
+import java.util.logging.Level;
+
+import org.bukkit.Bukkit;
+import org.bukkit.Location;
+import org.bukkit.entity.Player;
+import org.bukkit.plugin.java.JavaPlugin;
+
+import io.papermc.paper.plugin.lifecycle.event.types.LifecycleEvents;
+import net.dv8tion.jda.api.JDA;
+import net.dv8tion.jda.api.JDABuilder;
+import net.dv8tion.jda.api.entities.User;
+import net.dv8tion.jda.api.entities.channel.concrete.TextChannel;
+import net.dv8tion.jda.api.utils.messages.MessageCreateBuilder;
+import net.dv8tion.jda.api.utils.messages.MessageCreateData;
+import net.kyori.adventure.text.Component;
+import net.kyori.adventure.text.format.NamedTextColor;
+import net.kyori.adventure.text.format.TextDecoration;
+import net.kyori.adventure.text.serializer.plain.PlainTextComponentSerializer;
+import rip.iwakura.civil.events.ChatHandler;
+import rip.iwakura.civil.events.TeamChatHandler;
+import rip.iwakura.civil.commands.Spawn;
+import rip.iwakura.civil.commands.Team;
+import rip.iwakura.civil.events.JoinHandler;
+import rip.iwakura.civil.events.RespawnHandler;
+import rip.iwakura.civil.types.CivilPlayer;
+
+public class Core extends JavaPlugin {
+ public Database database;
+ public Discord discord;
+
+ public java.util.List teamChatToggled;
+
+ public Component renderTeamChat(CivilPlayer p, Component message) {
+ return Component.text("TEAM")
+ .color(NamedTextColor.BLUE)
+ .decoration(TextDecoration.BOLD, true)
+ .appendSpace()
+ .append(Component.text(p.getName())
+ .append(Component.text(": "))
+ .append(message)
+ .color(NamedTextColor.WHITE).decoration(TextDecoration.BOLD, false));
+ }
+
+ public Component renderTeamChat(User author, String message) {
+ return Component.text("TEAM")
+ .color(NamedTextColor.BLUE)
+ .decoration(TextDecoration.BOLD, true)
+ .append(Component.text(" Discord", NamedTextColor.BLUE).decoration(TextDecoration.BOLD, false)
+ .appendSpace()
+ .append(Component.text(author.getName())
+ .append(Component.text(": "))
+ .append(Component.text(message))
+ .color(NamedTextColor.WHITE).decoration(TextDecoration.BOLD, false)));
+ }
+
+ public void sendTeamMessage(CivilPlayer author, Component message) throws SQLException {
+ Component deserializedMessage = renderTeamChat(author, message);
+ discord.sendMessage(author, PlainTextComponentSerializer.plainText().serialize(message));
+ for (CivilPlayer member : database.getAllPlayers(author.getTeam())) {
+ try {
+ Player player = Bukkit.getPlayer(member.getName());
+
+ if (player == null || !player.isOnline())
+ continue;
+
+ player.sendMessage(deserializedMessage);
+ } catch (Exception e) {
+ continue;
+ }
+ }
+ }
+
+ public Location getSpawn() {
+ return new Location(Bukkit.getWorld(getConfig().getString("spawn.world")),
+ getConfig().getDouble("spawn.x"), getConfig().getDouble("spawn.y"),
+ getConfig().getDouble("spawn.z"), (float) getConfig().getDouble("spawn.yaw"),
+ (float) getConfig().getDouble("spawn.pitch"));
+ };
+
+ @Override
+ public void onEnable() {
+ getLogger().info("Hello world! We are booting up...");
+
+ saveDefaultConfig();
+
+ teamChatToggled = new ArrayList<>();
+
+ try {
+ this.database = new Database(getConfig().getString("database.url"), this);
+ } catch (SQLException e) {
+ getLogger().log(Level.SEVERE, e.getMessage());
+ Bukkit.getPluginManager().disablePlugin(this);
+ }
+
+ this.discord = new Discord(this);
+ discord.connect(getConfig().getString("discord.token"));
+
+ Team teamCommand = new Team(this);
+ Spawn spawnCommand = new Spawn(this);
+
+ this.getLifecycleManager().registerEventHandler(LifecycleEvents.COMMANDS, commands -> {
+ commands.registrar().register(teamCommand.getCommand());
+ commands.registrar().register(spawnCommand.getCommand());
+ });
+
+ getServer().getPluginManager().registerEvents(new JoinHandler(database), this);
+ getServer().getPluginManager().registerEvents(new ChatHandler(this), this);
+ getServer().getPluginManager().registerEvents(new TeamChatHandler(this), this);
+ getServer().getPluginManager().registerEvents(new RespawnHandler(this), this);
+ }
+}
diff --git a/src/main/java/rip/iwakura/civil/Database.java b/src/main/java/rip/iwakura/civil/Database.java
new file mode 100644
index 0000000..1669d2f
--- /dev/null
+++ b/src/main/java/rip/iwakura/civil/Database.java
@@ -0,0 +1,102 @@
+package rip.iwakura.civil;
+
+import java.sql.SQLException;
+import java.util.List;
+import java.util.UUID;
+
+import org.bukkit.Location;
+import org.bukkit.entity.Player;
+
+import com.j256.ormlite.dao.Dao;
+import com.j256.ormlite.dao.DaoManager;
+import com.j256.ormlite.jdbc.JdbcConnectionSource;
+import com.j256.ormlite.support.ConnectionSource;
+import com.j256.ormlite.table.TableUtils;
+
+import net.dv8tion.jda.api.entities.channel.concrete.TextChannel;
+import rip.iwakura.civil.exceptions.InvalidChannelException;
+import rip.iwakura.civil.types.CivilPlayer;
+import rip.iwakura.civil.types.CivilTeam;
+
+public class Database {
+ private final Dao playerDao;
+ private final Dao teamDao;
+ private ConnectionSource connectionSource;
+ private Core core;
+
+ public Database(String uri, Core core) throws SQLException {
+ connectionSource = new JdbcConnectionSource(uri);
+
+ TableUtils.createTableIfNotExists(connectionSource, CivilPlayer.class);
+ TableUtils.createTableIfNotExists(connectionSource, CivilTeam.class);
+
+ playerDao = DaoManager.createDao(connectionSource, CivilPlayer.class);
+ teamDao = DaoManager.createDao(connectionSource, CivilTeam.class);
+ this.core = core;
+ }
+
+ public void createPlayer(Player p) throws SQLException {
+ playerDao.create(
+ new CivilPlayer(p.getUniqueId(), p.getName()));
+ }
+
+ public void createTeam(String name, String prefix) throws SQLException {
+ teamDao.create(
+ new CivilTeam(name, prefix));
+ }
+
+ public void joinTeam(Player p, CivilTeam team) throws SQLException {
+ CivilPlayer civilPlayer = playerDao.queryForId(p.getUniqueId());
+ civilPlayer.setTeam(team);
+ playerDao.update(civilPlayer);
+ }
+
+ public void joinTeam(CivilPlayer p, CivilTeam team) throws SQLException {
+ p.setTeam(team);
+ playerDao.update(p);
+ }
+
+ public CivilTeam getTeam(String team) throws SQLException {
+ return teamDao.queryForId(team);
+ }
+
+ public List getAllTeams() throws SQLException {
+ return teamDao.queryForAll();
+ }
+
+ public List getAllTeams(Long channel) throws SQLException {
+ return teamDao.queryBuilder().where().eq("channel", channel).query();
+ }
+
+ public CivilPlayer getPlayer(String name) throws SQLException {
+ return playerDao.queryBuilder().where().eq("name", name).queryForFirst();
+ }
+
+ public CivilPlayer getPlayer(UUID uuid) throws SQLException {
+ return playerDao.queryForId(uuid);
+ }
+
+ public CivilPlayer getPlayer(Player p) throws SQLException {
+ return playerDao.queryForId(p.getUniqueId());
+ }
+
+ public List getAllPlayers() throws SQLException {
+ return playerDao.queryForAll();
+ }
+
+ public List getAllPlayers(CivilTeam team) throws SQLException {
+ return playerDao.queryBuilder().where().eq("team_id", team.getName()).query();
+ }
+
+ public void setHome(CivilTeam team, Location location) throws SQLException {
+ team.setHome(location);
+ teamDao.update(team);
+ }
+
+ public void linkChannel(CivilTeam team, TextChannel channel) throws SQLException {
+ team.setChannel(channel.getIdLong());
+
+ team.setWebhook(channel.createWebhook("CivilCore").complete().getUrl());
+ teamDao.update(team);
+ }
+}
diff --git a/src/main/java/rip/iwakura/civil/Discord.java b/src/main/java/rip/iwakura/civil/Discord.java
new file mode 100644
index 0000000..a344563
--- /dev/null
+++ b/src/main/java/rip/iwakura/civil/Discord.java
@@ -0,0 +1,104 @@
+package rip.iwakura.civil;
+
+import java.sql.SQLException;
+import java.util.List;
+
+import org.bukkit.Bukkit;
+import org.bukkit.entity.Player;
+
+import com.mojang.brigadier.arguments.StringArgumentType;
+
+import club.minnced.discord.webhook.WebhookClient;
+import club.minnced.discord.webhook.WebhookClientBuilder;
+import club.minnced.discord.webhook.send.WebhookMessageBuilder;
+import net.dv8tion.jda.api.JDA;
+import net.dv8tion.jda.api.JDABuilder;
+import net.dv8tion.jda.api.Permission;
+import net.dv8tion.jda.api.entities.Guild;
+import net.dv8tion.jda.api.entities.Webhook;
+import net.dv8tion.jda.api.entities.channel.concrete.TextChannel;
+import net.dv8tion.jda.api.events.message.MessageReceivedEvent;
+import net.dv8tion.jda.api.hooks.ListenerAdapter;
+import net.dv8tion.jda.api.interactions.commands.DefaultMemberPermissions;
+import net.dv8tion.jda.api.interactions.commands.OptionType;
+import net.dv8tion.jda.api.interactions.commands.build.Commands;
+import net.dv8tion.jda.api.requests.GatewayIntent;
+import net.dv8tion.jda.api.utils.messages.MessageCreateBuilder;
+import rip.iwakura.civil.discord.LinkCommand;
+import rip.iwakura.civil.types.CivilPlayer;
+import rip.iwakura.civil.types.CivilTeam;
+
+/**
+ * Discord
+ */
+public class Discord extends ListenerAdapter {
+ private Core core;
+ public JDA jda;
+
+ public Discord(Core core) {
+ this.core = core;
+ }
+
+ public void sendMessage(CivilPlayer p, String message) {
+ String webhook = p.getTeam().getWebhook();
+ if (webhook != null) {
+ WebhookClient client = WebhookClient.withUrl(webhook);
+ client.send(new WebhookMessageBuilder().setUsername(p.getName())
+ .setAvatarUrl("https://www.mc-heads.net/avatar/" + p.getName()).setContent(message).build());
+ }
+ }
+
+ public void connect(String token) {
+ jda = JDABuilder.createDefault(token)
+ .enableIntents(GatewayIntent.MESSAGE_CONTENT, GatewayIntent.GUILD_MESSAGES, GatewayIntent.GUILD_MEMBERS)
+ .addEventListeners(this)
+ .addEventListeners(new LinkCommand(core))
+ .build();
+
+ try {
+ jda.awaitReady();
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+
+ registerCommands(core.getConfig().getLong("discord.guild"));
+ }
+
+ public void registerCommands(Long guildId) {
+ Guild guild = jda.getGuildById(guildId);
+
+ if (guild == null) {
+ core.getLogger().info("Guild ID not found.");
+ return;
+ }
+
+ guild.updateCommands().addCommands(Commands.slash("link", "Link in-game team chat to a discord channel.")
+ .setDefaultPermissions(DefaultMemberPermissions.enabledFor(Permission.MANAGE_CHANNEL))
+ .addOption(OptionType.STRING, "team", "Name of the team you want to link to the current channel.", true,
+ true))
+ .queue();
+ }
+
+ @Override
+ public void onMessageReceived(MessageReceivedEvent event) {
+ if (event.getAuthor().isBot()) return;
+
+ try {
+ List linked_teams = core.database.getAllTeams(event.getChannel().getIdLong());
+
+ for (CivilTeam team : linked_teams) {
+ List members = core.database.getAllPlayers(team);
+
+ for (CivilPlayer member : members) {
+ Player player = Bukkit.getPlayerExact(member.getName());
+
+ if (player == null || !player.isOnline()) continue;
+
+ player.sendMessage(core.renderTeamChat(event.getAuthor(),event.getMessage().getContentDisplay()));
+ }
+ }
+ } catch (SQLException e) {
+ e.printStackTrace();
+ }
+ }
+}
diff --git a/src/main/java/rip/iwakura/civil/commands/PlayerArgument.java b/src/main/java/rip/iwakura/civil/commands/PlayerArgument.java
new file mode 100644
index 0000000..0979be7
--- /dev/null
+++ b/src/main/java/rip/iwakura/civil/commands/PlayerArgument.java
@@ -0,0 +1,77 @@
+package rip.iwakura.civil.commands;
+
+import java.sql.SQLException;
+import java.util.List;
+import java.util.concurrent.CompletableFuture;
+
+import org.bukkit.entity.Player;
+
+import com.mojang.brigadier.Message;
+import com.mojang.brigadier.arguments.ArgumentType;
+import com.mojang.brigadier.arguments.StringArgumentType;
+import com.mojang.brigadier.context.CommandContext;
+import com.mojang.brigadier.exceptions.CommandSyntaxException;
+import com.mojang.brigadier.exceptions.SimpleCommandExceptionType;
+import com.mojang.brigadier.suggestion.Suggestions;
+import com.mojang.brigadier.suggestion.SuggestionsBuilder;
+
+import io.papermc.paper.command.brigadier.MessageComponentSerializer;
+import io.papermc.paper.command.brigadier.argument.CustomArgumentType;
+import net.kyori.adventure.text.Component;
+import net.kyori.adventure.text.format.NamedTextColor;
+import rip.iwakura.civil.types.CivilPlayer;
+import rip.iwakura.civil.Database;
+
+/**
+ * PlayerArgument
+ */
+public class PlayerArgument implements CustomArgumentType.Converted {
+ private Database database;
+
+ public PlayerArgument(Database database) {
+ this.database = database;
+ }
+
+ @Override
+ public CivilPlayer convert(String playerName) throws CommandSyntaxException {
+ try {
+ CivilPlayer civilPlayer = database.getPlayer(playerName);
+
+ if (civilPlayer == null) {
+ final Message message = MessageComponentSerializer.message()
+ .serialize(Component.text(playerName + " doesn't exist!", NamedTextColor.RED));
+ throw new CommandSyntaxException(new SimpleCommandExceptionType(message), message);
+ }
+
+ return civilPlayer;
+
+ } catch (SQLException e) {
+ final Message message = MessageComponentSerializer.message()
+ .serialize(Component.text("Uh oh, an error occured!", NamedTextColor.RED));
+ throw new CommandSyntaxException(new SimpleCommandExceptionType(message), message);
+ }
+ }
+
+ @Override
+ public CompletableFuture listSuggestions(CommandContext ctx, SuggestionsBuilder builder) {
+ try {
+ List players = database.getAllPlayers();
+
+ for (CivilPlayer player : players) {
+ String name = player.getName();
+
+ if (name.toLowerCase().startsWith(builder.getRemainingLowerCase())) {
+ builder.suggest(name);
+ }
+ }
+ } catch (SQLException e) {
+ }
+
+ return builder.buildFuture();
+ }
+
+ @Override
+ public ArgumentType getNativeType() {
+ return StringArgumentType.word();
+ }
+}
diff --git a/src/main/java/rip/iwakura/civil/commands/Spawn.java b/src/main/java/rip/iwakura/civil/commands/Spawn.java
new file mode 100644
index 0000000..af683cf
--- /dev/null
+++ b/src/main/java/rip/iwakura/civil/commands/Spawn.java
@@ -0,0 +1,76 @@
+package rip.iwakura.civil.commands;
+
+import java.sql.SQLException;
+import java.text.Format;
+
+import org.bukkit.Bukkit;
+import org.bukkit.Location;
+import org.bukkit.command.CommandSender;
+import org.bukkit.entity.Player;
+import org.checkerframework.common.reflection.qual.GetConstructor;
+
+import com.mojang.brigadier.Command;
+import com.mojang.brigadier.arguments.LongArgumentType;
+import com.mojang.brigadier.arguments.StringArgumentType;
+import com.mojang.brigadier.builder.LiteralArgumentBuilder;
+import com.mojang.brigadier.tree.LiteralCommandNode;
+
+import io.papermc.paper.command.brigadier.CommandSourceStack;
+import io.papermc.paper.command.brigadier.Commands;
+import net.kyori.adventure.text.Component;
+import net.kyori.adventure.text.format.NamedTextColor;
+import net.kyori.adventure.text.format.TextDecoration;
+import net.kyori.adventure.text.minimessage.MiniMessage;
+import net.kyori.adventure.text.minimessage.translation.MiniMessageTranslator;
+import rip.iwakura.civil.Core;
+import rip.iwakura.civil.Database;
+import rip.iwakura.civil.exceptions.InvalidChannelException;
+import rip.iwakura.civil.types.*;
+
+public class Spawn {
+ private Core core;
+
+ public Spawn(Core core) {
+ this.core = core;
+ }
+
+ public LiteralCommandNode getCommand() {
+ return Commands.literal("spawn")
+ .requires(ctx -> ctx.getSender() instanceof Player)
+ .executes(ctx -> {
+ Player p = (Player) ctx.getSource().getSender();
+
+ if (!core.getConfig().contains("spawn")) {
+ p.sendMessage(MiniMessage.miniMessage().deserialize("The spawn has not been set yet."));
+ return 0;
+ }
+
+ p.teleport(core.getSpawn());
+
+ return Command.SINGLE_SUCCESS;
+ })
+ .then(Commands.literal("set").requires(
+ ctx -> ctx.getSender() instanceof Player && ctx.getSender().hasPermission("civil.spawn.set"))
+ .executes(ctx -> {
+ Player p = (Player) ctx.getSource().getSender();
+ Location loc = p.getLocation();
+
+ core.getConfig().set("spawn.world", loc.getWorld().getName());
+ core.getConfig().set("spawn.x", loc.x());
+ core.getConfig().set("spawn.y", loc.y());
+ core.getConfig().set("spawn.z", loc.z());
+ core.getConfig().set("spawn.yaw", loc.getYaw());
+ core.getConfig().set("spawn.pitch", loc.getPitch());
+
+ core.getServer().getWorld("world").setSpawnLocation(loc);
+
+ core.saveConfig();
+
+ p.sendMessage(MiniMessage.miniMessage().deserialize("Set the server spawn to your current position."));
+
+ return Command.SINGLE_SUCCESS;
+ }))
+ .build();
+ }
+
+}
diff --git a/src/main/java/rip/iwakura/civil/commands/Team.java b/src/main/java/rip/iwakura/civil/commands/Team.java
new file mode 100644
index 0000000..7242f20
--- /dev/null
+++ b/src/main/java/rip/iwakura/civil/commands/Team.java
@@ -0,0 +1,231 @@
+package rip.iwakura.civil.commands;
+
+import java.util.List;
+import java.sql.SQLException;
+import java.text.Format;
+
+import org.bukkit.Location;
+import org.bukkit.command.CommandSender;
+import org.bukkit.entity.Player;
+
+import com.mojang.brigadier.Command;
+import com.mojang.brigadier.arguments.LongArgumentType;
+import com.mojang.brigadier.arguments.StringArgumentType;
+import com.mojang.brigadier.builder.LiteralArgumentBuilder;
+import com.mojang.brigadier.tree.LiteralCommandNode;
+
+import io.papermc.paper.command.brigadier.CommandSourceStack;
+import io.papermc.paper.command.brigadier.Commands;
+import net.kyori.adventure.text.Component;
+import net.kyori.adventure.text.format.NamedTextColor;
+import net.kyori.adventure.text.format.TextDecoration;
+import net.kyori.adventure.text.minimessage.MiniMessage;
+import rip.iwakura.civil.Core;
+import rip.iwakura.civil.Database;
+import rip.iwakura.civil.exceptions.InvalidChannelException;
+import rip.iwakura.civil.types.*;
+
+public class Team {
+ private Database database;
+ private Core core;
+
+ public Team(Core core) {
+ this.core = core;
+ this.database = core.database;
+ }
+
+ private LiteralArgumentBuilder createTeam() {
+ return Commands.literal("create")
+ .requires(source -> source.getSender().hasPermission("civil.team.create"))
+ .then(
+ Commands.argument("name", StringArgumentType.string())
+ .then(
+ Commands.argument("prefix", StringArgumentType.string())
+ .executes(ctx -> {
+ String name = StringArgumentType.getString(ctx, "name");
+ String prefix = StringArgumentType.getString(ctx, "prefix");
+ CommandSender sender = ctx.getSource().getSender();
+
+ try {
+ database.createTeam(name, prefix);
+ sender.sendMessage(
+ Component
+ .text("Successfully created team ",
+ NamedTextColor.GREEN)
+ .append(Component
+ .text(name, NamedTextColor.GOLD))
+ .append(Component.text(" with prefix: \""))
+ .append(MiniMessage.miniMessage()
+ .deserialize(prefix))
+ .append(Component.text("\"")));
+
+ return Command.SINGLE_SUCCESS;
+ } catch (SQLException e) {
+ ctx.getSource().getSender().sendMessage(
+ Component.text(e.getMessage(), NamedTextColor.RED));
+ e.printStackTrace();
+ return 0;
+ }
+ })));
+ }
+
+ // Send team chat message
+ private LiteralArgumentBuilder homeCommand() {
+ return Commands.literal("home")
+ .requires(sender -> sender.getSender() instanceof Player)
+ .executes(ctx -> {
+ Player p = (Player) ctx.getSource().getSender();
+
+ try {
+ CivilPlayer cPlayer = core.database.getPlayer(p);
+ p.teleport(cPlayer.getTeam().getHome(core));
+ p.sendRichMessage("You have been teleported to your team's home.");
+ return Command.SINGLE_SUCCESS;
+ } catch (SQLException e) {
+ e.printStackTrace();
+ }
+
+ return 0;
+ }).then(Commands.literal("set")
+ .requires(sender -> sender.getSender() instanceof Player)
+ .executes(ctx -> {
+ Player p = (Player) ctx.getSource().getSender();
+
+ try {
+ CivilPlayer cPlayer = database.getPlayer(p);
+
+ Location location = p.getLocation();
+
+ database.setHome(cPlayer.getTeam(), location);
+
+ p.sendRichMessage("Your team's home location has been set to: "
+ + String.format("%d %d %d", Math.round(location.x()),
+ Math.round(location.y()), Math.round(location.z())));
+ return Command.SINGLE_SUCCESS;
+
+ } catch (SQLException e) {
+ e.printStackTrace();
+ }
+
+ return 1;
+ }));
+
+ }
+
+ // Send team chat message
+ private LiteralArgumentBuilder teamChat() {
+ return Commands.literal("chat")
+ .requires(sender -> sender.getSender() instanceof Player)
+ .executes(ctx -> {
+ Player p = (Player) ctx.getSource().getSender();
+
+ if (core.teamChatToggled.contains(p)) {
+ core.teamChatToggled.remove(p);
+ p.sendRichMessage("Team chat disabled.");
+ } else {
+ core.teamChatToggled.add(p);
+ p.sendRichMessage("Team chat enabled.");
+ }
+
+ return Command.SINGLE_SUCCESS;
+ }).then(Commands.argument("message", StringArgumentType.greedyString())
+ .requires(sender -> sender.getSender() instanceof Player)
+ .executes(ctx -> {
+ CommandSender sender = ctx.getSource().getSender();
+ String message = StringArgumentType.getString(ctx, "message");
+
+ try {
+ CivilPlayer p = database.getPlayer((Player) sender);
+
+ core.sendTeamMessage(p, MiniMessage.miniMessage().deserialize(message));
+
+ return Command.SINGLE_SUCCESS;
+
+ } catch (SQLException e) {
+ sender.sendRichMessage("Uh oh, something went wrong!");
+ e.printStackTrace();
+ }
+
+ return 1;
+ }));
+
+ }
+
+ // Add a player to a team.
+ private LiteralArgumentBuilder joinTeam() {
+ return Commands.literal("add")
+ .requires(source -> source.getSender().hasPermission("civil.team.add"))
+ .then(
+ Commands.argument("player", new PlayerArgument(database))
+ .then(
+ Commands.argument("team", new TeamArgument(database))
+ .executes(ctx -> {
+ CivilTeam civilTeam = ctx.getArgument("team", CivilTeam.class);
+ CivilPlayer civilPlayer = ctx.getArgument("player",
+ CivilPlayer.class);
+ CommandSender sender = ctx.getSource().getSender();
+
+ try {
+ database.joinTeam(civilPlayer, civilTeam);
+
+ sender.sendMessage(
+ Component
+ .text("Successfully added ",
+ NamedTextColor.GREEN)
+ .append(Component
+ .text(civilPlayer.getName(),
+ NamedTextColor.GOLD))
+ .append(Component.text(" to team "))
+ .append(Component
+ .text(civilTeam.getName(),
+ NamedTextColor.AQUA)));
+ return Command.SINGLE_SUCCESS;
+ } catch (SQLException e) {
+ ctx.getSource().getSender().sendMessage(
+ Component.text(e.getMessage(), NamedTextColor.RED));
+ e.printStackTrace();
+ return 0;
+ }
+ })));
+ };
+
+ // List team info.
+ private LiteralArgumentBuilder getTeamInfo() {
+ return Commands.literal("info")
+ .then(
+ Commands.argument("team", new TeamArgument(database))
+ .executes(ctx -> {
+ try {
+ CivilTeam civilTeam = ctx.getArgument("team", CivilTeam.class);
+ CommandSender sender = ctx.getSource().getSender();
+
+ String finalMessage = String.format(
+ "Team: %s\nPrefix: %s\nPlayers:",
+ civilTeam.getName(), civilTeam.getPrefix());
+
+ List members = database.getAllPlayers(civilTeam);
+
+ for (CivilPlayer member : members)
+ finalMessage += " " + member.getName();
+
+ sender.sendMessage(MiniMessage.miniMessage().deserialize(finalMessage));
+
+ return Command.SINGLE_SUCCESS;
+ } catch (SQLException e) {
+ e.printStackTrace();
+ return -1;
+ }
+ }));
+ };
+
+ public LiteralCommandNode getCommand() {
+ return Commands.literal("team")
+ .then(createTeam())
+ .then(joinTeam())
+ .then(teamChat())
+ .then(homeCommand())
+ .then(getTeamInfo())
+ .build();
+ }
+
+}
diff --git a/src/main/java/rip/iwakura/civil/commands/TeamArgument.java b/src/main/java/rip/iwakura/civil/commands/TeamArgument.java
new file mode 100644
index 0000000..3a9988a
--- /dev/null
+++ b/src/main/java/rip/iwakura/civil/commands/TeamArgument.java
@@ -0,0 +1,75 @@
+package rip.iwakura.civil.commands;
+
+import java.sql.SQLException;
+import java.util.List;
+import java.util.concurrent.CompletableFuture;
+
+import com.mojang.brigadier.Message;
+import com.mojang.brigadier.arguments.ArgumentType;
+import com.mojang.brigadier.arguments.StringArgumentType;
+import com.mojang.brigadier.context.CommandContext;
+import com.mojang.brigadier.exceptions.CommandSyntaxException;
+import com.mojang.brigadier.exceptions.SimpleCommandExceptionType;
+import com.mojang.brigadier.suggestion.Suggestions;
+import com.mojang.brigadier.suggestion.SuggestionsBuilder;
+
+import io.papermc.paper.command.brigadier.MessageComponentSerializer;
+import io.papermc.paper.command.brigadier.argument.CustomArgumentType;
+import net.kyori.adventure.text.Component;
+import net.kyori.adventure.text.format.NamedTextColor;
+import rip.iwakura.civil.types.CivilTeam;
+import rip.iwakura.civil.Database;
+
+/**
+ * TeamArgument
+ */
+public class TeamArgument implements CustomArgumentType.Converted {
+ private Database database;
+
+ public TeamArgument(Database database) {
+ this.database = database;
+ }
+
+ @Override
+ public CivilTeam convert(String teamName) throws CommandSyntaxException {
+ try {
+ CivilTeam civilTeam = database.getTeam(teamName);
+
+ if (civilTeam == null) {
+ final Message message = MessageComponentSerializer.message()
+ .serialize(Component.text(teamName + " doesn't exist!", NamedTextColor.RED));
+ throw new CommandSyntaxException(new SimpleCommandExceptionType(message), message);
+ }
+
+ return civilTeam;
+
+ } catch (SQLException e) {
+ final Message message = MessageComponentSerializer.message()
+ .serialize(Component.text("Uh oh, an error occured!", NamedTextColor.RED));
+ throw new CommandSyntaxException(new SimpleCommandExceptionType(message), message);
+ }
+ }
+
+ @Override
+ public CompletableFuture listSuggestions(CommandContext ctx, SuggestionsBuilder builder) {
+ try {
+ List teams = database.getAllTeams();
+
+ for (CivilTeam team : teams) {
+ String name = team.getName();
+
+ if (name.toLowerCase().startsWith(builder.getRemainingLowerCase())) {
+ builder.suggest(name);
+ }
+ }
+ } catch (SQLException e) {
+ }
+
+ return builder.buildFuture();
+ }
+
+ @Override
+ public ArgumentType getNativeType() {
+ return StringArgumentType.string();
+ }
+}
diff --git a/src/main/java/rip/iwakura/civil/discord/LinkCommand.java b/src/main/java/rip/iwakura/civil/discord/LinkCommand.java
new file mode 100644
index 0000000..c5db068
--- /dev/null
+++ b/src/main/java/rip/iwakura/civil/discord/LinkCommand.java
@@ -0,0 +1,56 @@
+package rip.iwakura.civil.discord;
+
+import java.sql.SQLException;
+import java.util.List;
+import java.util.logging.StreamHandler;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+import net.dv8tion.jda.api.events.interaction.command.CommandAutoCompleteInteractionEvent;
+import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent;
+import net.dv8tion.jda.api.hooks.ListenerAdapter;
+import net.dv8tion.jda.api.interactions.commands.Command;
+import net.dv8tion.jda.api.interactions.commands.SlashCommandInteraction;
+import rip.iwakura.civil.Core;
+import rip.iwakura.civil.types.CivilTeam;
+
+/**
+ * LinkCommand
+ */
+public class LinkCommand extends ListenerAdapter {
+ private Core core;
+
+ public LinkCommand(Core core) {
+ this.core = core;
+ }
+
+ @Override
+ public void onSlashCommandInteraction(SlashCommandInteractionEvent event) {
+ try {
+ if (event.getName().equals("link")) {
+ core.database.linkChannel(core.database.getTeam(event.getOption("team").getAsString()),event.getChannel().asTextChannel());
+ event.reply("Successfully linked channel to team chat.").queue();
+ }
+ } catch (SQLException e) {
+ e.printStackTrace();
+ }
+ }
+
+ @Override
+ public void onCommandAutoCompleteInteraction(CommandAutoCompleteInteractionEvent event) {
+ try {
+ if (event.getName().equals("link") && event.getFocusedOption().getName().equals("team")) {
+ List teamNames = core.database.getAllTeams().stream().map(CivilTeam::getName).collect(
+ Collectors.toList());
+
+ List options = teamNames.stream()
+ .filter(name -> name.startsWith(event.getFocusedOption().getValue()))
+ .map(name -> new Command.Choice(name, name)).collect(Collectors.toList());
+
+ event.replyChoices(options).queue();
+ }
+ } catch (SQLException e) {
+ e.printStackTrace();
+ }
+ }
+}
diff --git a/src/main/java/rip/iwakura/civil/events/ChatHandler.java b/src/main/java/rip/iwakura/civil/events/ChatHandler.java
new file mode 100644
index 0000000..2a6bda1
--- /dev/null
+++ b/src/main/java/rip/iwakura/civil/events/ChatHandler.java
@@ -0,0 +1,51 @@
+package rip.iwakura.civil.events;
+
+import java.sql.SQLException;
+import java.util.logging.Level;
+
+import org.bukkit.entity.Player;
+import org.bukkit.event.EventHandler;
+import org.bukkit.event.Listener;
+
+import io.papermc.paper.chat.ChatRenderer;
+import io.papermc.paper.event.player.AsyncChatEvent;
+import net.kyori.adventure.audience.Audience;
+import net.kyori.adventure.text.Component;
+import net.kyori.adventure.text.minimessage.MiniMessage;
+import rip.iwakura.civil.Core;
+import rip.iwakura.civil.Database;
+
+public class ChatHandler implements Listener, ChatRenderer {
+ private Core core;
+ private Database database;
+
+ public ChatHandler(Core core) {
+ this.core = core;
+ this.database = core.database;
+ }
+
+ @EventHandler
+ public void chatHandler(AsyncChatEvent event) {
+ event.renderer(this);
+ }
+
+ @Override
+ public Component render(Player source, Component sourceDisplayName, Component message, Audience viewer) {
+ String prefix = null;
+
+ try {
+ prefix = database.getPlayer(source).getTeam().getPrefix();
+ } catch (SQLException e) {
+ core.getLogger().log(Level.WARNING, e.getMessage());;
+ } catch (NullPointerException e) {
+ }
+
+ if (prefix == null) prefix = "";
+
+ return MiniMessage.miniMessage()
+ .deserialize(prefix)
+ .append(sourceDisplayName)
+ .append(Component.text(": "))
+ .append(message);
+ }
+}
diff --git a/src/main/java/rip/iwakura/civil/events/JoinHandler.java b/src/main/java/rip/iwakura/civil/events/JoinHandler.java
new file mode 100644
index 0000000..770a8d4
--- /dev/null
+++ b/src/main/java/rip/iwakura/civil/events/JoinHandler.java
@@ -0,0 +1,30 @@
+package rip.iwakura.civil.events;
+
+import java.sql.SQLException;
+
+import org.bukkit.entity.Player;
+import org.bukkit.event.EventHandler;
+import org.bukkit.event.Listener;
+import org.bukkit.event.player.PlayerJoinEvent;
+
+import net.kyori.adventure.text.minimessage.MiniMessage;
+import rip.iwakura.civil.Database;
+
+public class JoinHandler implements Listener {
+ private Database database;
+
+ public JoinHandler(Database database) {
+ this.database = database;
+ }
+
+ @EventHandler
+ public void joinHandler(PlayerJoinEvent event) throws SQLException {
+ Player p = event.getPlayer();
+
+ event.joinMessage(MiniMessage.miniMessage()
+ .deserialize("[+] " + p.getName() + ""));
+
+ if (database.getPlayer(p) == null)
+ database.createPlayer(p);
+ }
+}
diff --git a/src/main/java/rip/iwakura/civil/events/LeaveHandler.java b/src/main/java/rip/iwakura/civil/events/LeaveHandler.java
new file mode 100644
index 0000000..18ce883
--- /dev/null
+++ b/src/main/java/rip/iwakura/civil/events/LeaveHandler.java
@@ -0,0 +1,21 @@
+package rip.iwakura.civil.events;
+
+import java.sql.SQLException;
+
+import org.bukkit.entity.Player;
+import org.bukkit.event.EventHandler;
+import org.bukkit.event.Listener;
+import org.bukkit.event.player.PlayerQuitEvent;
+
+import net.kyori.adventure.text.minimessage.MiniMessage;
+
+public class LeaveHandler implements Listener {
+
+ @EventHandler
+ public void leaveHandler(PlayerQuitEvent event) throws SQLException {
+ Player p = event.getPlayer();
+
+ event.quitMessage(MiniMessage.miniMessage()
+ .deserialize("[-] " + p.getName() + ""));
+ }
+}
diff --git a/src/main/java/rip/iwakura/civil/events/RespawnHandler.java b/src/main/java/rip/iwakura/civil/events/RespawnHandler.java
new file mode 100644
index 0000000..45c2202
--- /dev/null
+++ b/src/main/java/rip/iwakura/civil/events/RespawnHandler.java
@@ -0,0 +1,23 @@
+package rip.iwakura.civil.events;
+import org.bukkit.Bukkit;
+import org.bukkit.event.EventHandler;
+import org.bukkit.event.Listener;
+import org.bukkit.event.entity.PlayerDeathEvent;
+import org.bukkit.event.player.PlayerRespawnEvent;
+
+import rip.iwakura.civil.Core;
+
+public class RespawnHandler implements Listener {
+ private Core core;
+
+ public RespawnHandler(Core core) {
+ this.core = core;
+ }
+
+ @EventHandler
+ public void respawnEvent(PlayerRespawnEvent ev) {
+ if (ev.isBedSpawn()) return;
+
+ ev.setRespawnLocation(core.getSpawn());
+ }
+}
diff --git a/src/main/java/rip/iwakura/civil/events/TeamChatHandler.java b/src/main/java/rip/iwakura/civil/events/TeamChatHandler.java
new file mode 100644
index 0000000..d097852
--- /dev/null
+++ b/src/main/java/rip/iwakura/civil/events/TeamChatHandler.java
@@ -0,0 +1,39 @@
+package rip.iwakura.civil.events;
+
+import java.sql.SQLException;
+
+import org.bukkit.entity.Player;
+import org.bukkit.event.EventHandler;
+import org.bukkit.event.EventPriority;
+import org.bukkit.event.Listener;
+
+import io.papermc.paper.chat.ChatRenderer;
+import io.papermc.paper.event.player.AsyncChatEvent;
+import net.kyori.adventure.audience.Audience;
+import net.kyori.adventure.text.Component;
+import net.kyori.adventure.text.minimessage.MiniMessage;
+import net.kyori.adventure.text.serializer.plain.PlainTextComponentSerializer;
+import rip.iwakura.civil.Core;
+import rip.iwakura.civil.Database;
+import rip.iwakura.civil.types.CivilPlayer;
+
+public class TeamChatHandler implements Listener {
+ private Core core;
+ private Database database;
+
+ public TeamChatHandler(Core core) {
+ this.core = core;
+ this.database = core.database;
+ }
+
+ @EventHandler(priority = EventPriority.HIGHEST)
+ public void chatHandler(AsyncChatEvent event) throws SQLException {
+ if (core.teamChatToggled.contains(event.getPlayer())) {
+ CivilPlayer p = database.getPlayer(event.getPlayer());
+
+ core.sendTeamMessage(p, MiniMessage.miniMessage()
+ .deserialize(PlainTextComponentSerializer.plainText().serialize(event.message())));
+ event.setCancelled(true);
+ }
+ }
+}
diff --git a/src/main/java/rip/iwakura/civil/exceptions/InvalidChannelException.java b/src/main/java/rip/iwakura/civil/exceptions/InvalidChannelException.java
new file mode 100644
index 0000000..14d56ec
--- /dev/null
+++ b/src/main/java/rip/iwakura/civil/exceptions/InvalidChannelException.java
@@ -0,0 +1,12 @@
+package rip.iwakura.civil.exceptions;
+
+import net.dv8tion.jda.api.entities.channel.concrete.TextChannel;
+
+/**
+ * InvalidChannelException
+ */
+public class InvalidChannelException extends Exception {
+ public InvalidChannelException(Long channelId) {
+ super("Channel with ID: " + channelId.toString() + " could not be found.");
+ }
+}
diff --git a/src/main/java/rip/iwakura/civil/types/CivilPlayer.java b/src/main/java/rip/iwakura/civil/types/CivilPlayer.java
new file mode 100644
index 0000000..2ca4014
--- /dev/null
+++ b/src/main/java/rip/iwakura/civil/types/CivilPlayer.java
@@ -0,0 +1,38 @@
+package rip.iwakura.civil.types;
+
+import java.util.UUID;
+
+import com.j256.ormlite.field.DatabaseField;
+import com.j256.ormlite.table.DatabaseTable;
+
+@DatabaseTable(tableName = "players")
+public class CivilPlayer {
+ @DatabaseField(id = true, canBeNull = false, generatedId = false, columnName = "uuid")
+ private UUID uuid;
+
+ @DatabaseField(canBeNull = false, columnName = "name")
+ private String name;
+
+ @DatabaseField(canBeNull = true, foreign = true, foreignAutoRefresh = true)
+ private CivilTeam team;
+
+ public CivilPlayer() {
+ }
+
+ public CivilPlayer(UUID uuid, String name) {
+ this.uuid = uuid;
+ this.name = name;
+ }
+
+ public void setTeam(CivilTeam team) {
+ this.team = team;
+ }
+
+ public CivilTeam getTeam() {
+ return team;
+ }
+
+ public String getName() {
+ return name;
+ }
+}
diff --git a/src/main/java/rip/iwakura/civil/types/CivilTeam.java b/src/main/java/rip/iwakura/civil/types/CivilTeam.java
new file mode 100644
index 0000000..b6ebf97
--- /dev/null
+++ b/src/main/java/rip/iwakura/civil/types/CivilTeam.java
@@ -0,0 +1,78 @@
+package rip.iwakura.civil.types;
+
+import org.bukkit.Location;
+
+import com.j256.ormlite.field.DatabaseField;
+import com.j256.ormlite.table.DatabaseTable;
+
+import rip.iwakura.civil.Core;
+
+@DatabaseTable(tableName = "teams")
+public class CivilTeam {
+ @DatabaseField(id = true)
+ private String name;
+
+ @DatabaseField(canBeNull = false)
+ private String prefix;
+
+ @DatabaseField(canBeNull = true)
+ private Long channel;
+
+ @DatabaseField(canBeNull = true)
+ private String webhook;
+
+ @DatabaseField(canBeNull = true)
+ private double home_x;
+
+ @DatabaseField(canBeNull = true)
+ private double home_y;
+
+ @DatabaseField(canBeNull = true)
+ private double home_z;
+
+ @DatabaseField(canBeNull = true)
+ private String home_world;
+
+ public CivilTeam() {
+ }
+
+ public CivilTeam(String name, String prefix) {
+ this.name = name;
+ this.prefix = prefix;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public String getPrefix() {
+ return prefix;
+ }
+
+ public void setHome(Location home) {
+ this.home_x = home.x();
+ this.home_y = home.y();
+ this.home_z = home.z();
+ this.home_world = home.getWorld().getName();
+ }
+
+ public Location getHome(Core core) {
+ return new Location(core.getServer().getWorld(home_world), home_x, home_y, home_z);
+ }
+
+ public void setChannel(Long channel) {
+ this.channel = channel;
+ }
+
+ public Long getChannel() {
+ return channel;
+ }
+
+ public void setWebhook(String webhook) {
+ this.webhook = webhook;
+ }
+
+ public String getWebhook() {
+ return webhook;
+ }
+}
diff --git a/src/main/java/rip/iwakura/civilcore/CivilCore.java b/src/main/java/rip/iwakura/civilcore/CivilCore.java
deleted file mode 100644
index 137e0e1..0000000
--- a/src/main/java/rip/iwakura/civilcore/CivilCore.java
+++ /dev/null
@@ -1,50 +0,0 @@
-package rip.iwakura.civilcore;
-
-import java.sql.SQLException;
-import java.util.ArrayList;
-import java.util.HashMap;
-
-import org.bukkit.Bukkit;
-import org.bukkit.WorldCreator;
-import org.bukkit.entity.Player;
-import org.bukkit.plugin.java.JavaPlugin;
-
-import net.md_5.bungee.api.ChatColor;
-import rip.iwakura.civilcore.commands.TeamChatCommand;
-import rip.iwakura.civilcore.commands.TeamCommand;
-import rip.iwakura.civilcore.discord.Discord;
-
-public class CivilCore extends JavaPlugin {
- public Database db = new Database();
- public Discord bot;
- public ArrayList teamChatRegister = new ArrayList<>();
-
- @Override
- public void onEnable() {
- this.saveDefaultConfig();
-
- this.bot = new Discord(getConfig().getString("discord.token"), getConfig().getString("discord.channel"), this);
- this.bot.initialize();
-
- if (Bukkit.getWorld("court") == null) {
- new WorldCreator("court").createWorld();
- }
-
- 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);
- getServer().getPluginManager().registerEvents(new Court(), this);
- this.getCommand("team").setExecutor(new TeamCommand(this));
- this.getCommand("court").setExecutor(new Court());
- this.getCommand("tc").setExecutor(new TeamChatCommand(this));
- }
-}
diff --git a/src/main/java/rip/iwakura/civilcore/Court.java b/src/main/java/rip/iwakura/civilcore/Court.java
deleted file mode 100644
index b0e723a..0000000
--- a/src/main/java/rip/iwakura/civilcore/Court.java
+++ /dev/null
@@ -1,89 +0,0 @@
-package rip.iwakura.civilcore;
-
-import org.bukkit.Bukkit;
-import org.bukkit.Location;
-import org.bukkit.World;
-import org.bukkit.command.Command;
-import org.bukkit.command.CommandExecutor;
-import org.bukkit.command.CommandSender;
-import org.bukkit.entity.Player;
-import org.bukkit.event.EventHandler;
-import org.bukkit.event.Listener;
-import org.bukkit.event.block.BlockBreakEvent;
-import org.bukkit.event.block.BlockBurnEvent;
-import org.bukkit.event.block.BlockPlaceEvent;
-import org.bukkit.event.block.BlockSpreadEvent;
-import org.bukkit.event.entity.EntityDamageEvent;
-import org.bukkit.event.entity.EntityDamageEvent.DamageCause;
-import org.bukkit.event.player.PlayerBucketEmptyEvent;
-
-public class Court implements Listener,CommandExecutor{
- private World court_world = Bukkit.getWorld("court");
-
- private Location court_location = new Location(court_world, 4.5, 70.0, 0.5, -90f, 1.0f);
-
- @EventHandler
- public void PlayerPlaceWater(PlayerBucketEmptyEvent e) {
- Player p = (Player) e.getPlayer();
- if (!p.getLocation().getWorld().getName().equals("court")) return;
- e.setCancelled(true);
- }
-
- @EventHandler
- public void PlayerHurt(EntityDamageEvent e) {
- if (!(e.getEntity() instanceof Player)) return;
- Player p = (Player) e.getEntity();
-
- if (!p.getLocation().getWorld().getName().equals("court")) return;
-
- e.setCancelled(true);
-
- if (e.getCause() == DamageCause.VOID) {
- p.teleport(court_location);
- return;
- }
- }
-
- @EventHandler
- public void PlayerBreak(BlockBreakEvent e) {
- if (e.getPlayer().isOp()) return;
- if (e.getBlock().getWorld().getName().equals(court_world.getName())) e.setCancelled(true);
- }
- @EventHandler
- public void PlayerPlace(BlockPlaceEvent e) {
- if (e.getPlayer().isOp()) return;
- if (e.getBlock().getWorld().getName().equals(court_world.getName())) e.setCancelled(true);
- }
- @EventHandler
- public void PlayerBurn(BlockBurnEvent e) {
- if (e.getBlock().getWorld().getName().equals(court_world.getName())) e.setCancelled(true);
- }
- @EventHandler
- public void FireSpread(BlockSpreadEvent e) {
- if (e.getBlock().getWorld().getName().equals(court_world.getName())) e.setCancelled(true);
- }
- @Override
- public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args) {
- if (!(sender instanceof Player)) {
- sender.sendMessage("Non-player type.");
- return true;
- }
-
- Player p = (Player) sender;
-
- switch (args[0]) {
- case "enter":
- p.teleport(court_location);
- break;
- case "leave":
- Location loc = p.getBedSpawnLocation();
- if (loc == null) {
- loc = Bukkit.getWorld("world").getSpawnLocation();
- }
- p.teleport(loc);
- break;
- }
- return true;
- }
-
-}
diff --git a/src/main/java/rip/iwakura/civilcore/Database.java b/src/main/java/rip/iwakura/civilcore/Database.java
deleted file mode 100644
index 044fc05..0000000
--- a/src/main/java/rip/iwakura/civilcore/Database.java
+++ /dev/null
@@ -1,188 +0,0 @@
-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 List getPlayersInTeam(String team_name) {
- List filtered = players.stream().filter(
- s -> {
- if (s.team.name == null) return false;
- return s.team.name.equals(team_name);
- })
- .collect(Collectors.toList());
- if(filtered.isEmpty()) return null;
- return filtered;
- }
-
- 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
deleted file mode 100644
index e2eebb2..0000000
--- a/src/main/java/rip/iwakura/civilcore/PlayerHandler.java
+++ /dev/null
@@ -1,72 +0,0 @@
-package rip.iwakura.civilcore;
-
-import java.sql.SQLException;
-import java.util.List;
-
-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 final CivilCore civilCore;
-
- 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();
- boolean inTeamChat = civilCore.teamChatRegister.contains(p);
-
- DbPlayer dbPlayer = civilCore.db.getPlayerByName(player_name);
- String prefix = (inTeamChat ? ChatColor.DARK_GREEN + "TEAM >" + ChatColor.RESET : "")
- + (dbPlayer.team.prefix == null ?
- "" :
- ChatColor.translateAlternateColorCodes('&', inTeamChat ? "" : "[" + dbPlayer.team.prefix + "]"));
- String message = String.format("%s %s: %s", prefix, player_name, e.getMessage());
-
- if (!inTeamChat) {
- Bukkit.broadcastMessage(message);
- civilCore.bot.sendMessage(e);
- } else {
- List players = civilCore.db.getPlayersInTeam(dbPlayer.team.name);
-
- if (players == null) return;
-
- for (DbPlayer team_dbp : players) {
- Player team_p = Bukkit.getPlayer(team_dbp.name);
-
- if (team_p == null) continue;
-
- team_p.sendMessage(message);
- }
- }
-
- }
-
- @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
deleted file mode 100644
index a12486d..0000000
--- a/src/main/java/rip/iwakura/civilcore/Utils.java
+++ /dev/null
@@ -1,64 +0,0 @@
-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/TeamChatCommand.java b/src/main/java/rip/iwakura/civilcore/commands/TeamChatCommand.java
deleted file mode 100644
index 33b66e1..0000000
--- a/src/main/java/rip/iwakura/civilcore/commands/TeamChatCommand.java
+++ /dev/null
@@ -1,83 +0,0 @@
-package rip.iwakura.civilcore.commands;
-
-import org.bukkit.Bukkit;
-import org.bukkit.command.Command;
-import org.bukkit.command.CommandExecutor;
-import org.bukkit.command.CommandSender;
-import org.bukkit.entity.Player;
-
-import net.md_5.bungee.api.ChatColor;
-import org.jetbrains.annotations.NotNull;
-import rip.iwakura.civilcore.Utils;
-import rip.iwakura.civilcore.CivilCore;
-import rip.iwakura.civilcore.types.DbPlayer;
-
-import java.util.List;
-import java.util.Objects;
-
-public class TeamChatCommand implements CommandExecutor {
- private final CivilCore civilCore;
-
- public TeamChatCommand(CivilCore civilCore) {
- this.civilCore = civilCore;
- }
-
- private String getPrefix(String name, boolean inTeamChat) {
- DbPlayer dbPlayer = civilCore.db.getPlayerByName(name);
- return (inTeamChat ? ChatColor.DARK_GREEN + "TEAM >" + ChatColor.RESET : "")
- + (dbPlayer.team.prefix == null ?
- "" :
- ChatColor.translateAlternateColorCodes('&', inTeamChat ? "" : "[" + dbPlayer.team.prefix + "]"));
- }
-
- @Override
- public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, String[] args) {
- args = Objects.requireNonNull(Utils.parser(args)).toArray(new String[0]);
-
- if (!(sender instanceof Player p)) return true;
- if (args.length == 0) {
- if (civilCore.teamChatRegister.contains(p)) {
- civilCore.teamChatRegister.remove(p);
- p.sendMessage(ChatColor.GREEN + "You are now in the " + ChatColor.GOLD + "GLOBAL" + ChatColor.GREEN + " channel");
- } else {
- civilCore.teamChatRegister.add(p);
- p.sendMessage(ChatColor.GREEN + "You are now in the " + ChatColor.GOLD + "TEAM" + ChatColor.GREEN + " channel");
- }
- return true;
- }
-
- String message = String.join(" ", args);
-
- String player_name = p.getName();
- boolean inTeamChat = civilCore.teamChatRegister.contains(p);
-
- DbPlayer dbPlayer = civilCore.db.getPlayerByName(player_name);
-
- if (inTeamChat) {
- // Send message to global chat
- civilCore.teamChatRegister.remove(p);
- String formatted = String.format("%s%s: %s", getPrefix(player_name, false) + " ", player_name, message);
- Bukkit.broadcastMessage(formatted);
- civilCore.bot.sendMessage(p, message);
- civilCore.teamChatRegister.add(p);
- } else {
- // Send message to team chat
- civilCore.teamChatRegister.add(p);
- String formatted = String.format("%s%s: %s", getPrefix(player_name, true) + " ", player_name, message);
- List players = civilCore.db.getPlayersInTeam(dbPlayer.team.name);
-
- if (players == null) return true;
-
- for (DbPlayer team_dbp : players) {
- Player team_p = Bukkit.getPlayer(team_dbp.name);
-
- if (team_p == null) continue;
-
- team_p.sendMessage(formatted);
- }
- civilCore.teamChatRegister.remove(p);
- }
-
- return true;
- }
-}
\ No newline at end of file
diff --git a/src/main/java/rip/iwakura/civilcore/commands/TeamCommand.java b/src/main/java/rip/iwakura/civilcore/commands/TeamCommand.java
deleted file mode 100644
index 66040dd..0000000
--- a/src/main/java/rip/iwakura/civilcore/commands/TeamCommand.java
+++ /dev/null
@@ -1,111 +0,0 @@
-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[0]);
-
- 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/discord/Discord.java b/src/main/java/rip/iwakura/civilcore/discord/Discord.java
deleted file mode 100644
index be440ee..0000000
--- a/src/main/java/rip/iwakura/civilcore/discord/Discord.java
+++ /dev/null
@@ -1,108 +0,0 @@
-package rip.iwakura.civilcore.discord;
-
-import java.util.EnumSet;
-
-import org.bukkit.Bukkit;
-import org.bukkit.entity.Player;
-import org.bukkit.event.player.AsyncPlayerChatEvent;
-import org.checkerframework.common.reflection.qual.GetConstructor;
-
-import club.minnced.discord.webhook.WebhookClient;
-import club.minnced.discord.webhook.WebhookClientBuilder;
-import club.minnced.discord.webhook.send.WebhookMessage;
-import club.minnced.discord.webhook.send.WebhookMessageBuilder;
-import net.dv8tion.jda.api.JDA;
-import net.dv8tion.jda.api.JDABuilder;
-import net.dv8tion.jda.api.entities.channel.concrete.TextChannel;
-import net.dv8tion.jda.api.hooks.ListenerAdapter;
-import net.dv8tion.jda.api.requests.GatewayIntent;
-import rip.iwakura.civilcore.CivilCore;
-import net.dv8tion.jda.api.events.session.ReadyEvent;
-import rip.iwakura.civilcore.types.DbPlayer;
-
-public class Discord extends ListenerAdapter {
- private String token;
- private CivilCore civilCore;
-
- public String channelId;
-
- private TextChannel channel;
- private WebhookClient webhook;
-
- public JDA bot;
-
- private EnumSet intents = EnumSet.of(GatewayIntent.GUILD_MESSAGES, GatewayIntent.MESSAGE_CONTENT, GatewayIntent.GUILD_WEBHOOKS);
-
- public Discord(String token, String channelId, CivilCore civilCore){
- this.civilCore = civilCore;
- this.channelId = channelId;
- this.token = token;
- }
-
- public void initialize() {
- this.bot = JDABuilder.createLight(token, intents)
- .addEventListeners(new MessageReceive(civilCore))
- .addEventListeners(this)
- .build();
- }
-
- public void sendMessage(AsyncPlayerChatEvent e) {
- DbPlayer dbPlayer = civilCore.db.getPlayerByName(e.getPlayer().getName());
- String prefix = (dbPlayer.team.prefix == null ?
- "" :
- "[" + dbPlayer.team.prefix + "]");
-
- String player_name = e.getPlayer().getName();
- WebhookMessageBuilder builder = new WebhookMessageBuilder()
- .setUsername(prefix + " " + player_name)
- .setAvatarUrl(String.format("https://mc-heads.net/avatar/%s", player_name))
- .setContent(e.getMessage());
- webhook.send(builder.build());
- //channel.sendMessage(String.format("%s: %s", e.getPlayer().getName(), e.getMessage())).complete();
- }
-
- public void sendMessage(Player p, String message) {
- DbPlayer dbPlayer = civilCore.db.getPlayerByName(p.getName());
- String prefix = (dbPlayer.team.prefix == null ?
- "" :
- "[" + dbPlayer.team.prefix + "]");
-
- WebhookMessageBuilder builder = new WebhookMessageBuilder()
- .setUsername(prefix + " " + p.getName())
- .setAvatarUrl(String.format("https://mc-heads.net/avatar/%s", p.getName()))
- .setContent(message);
- webhook.send(builder.build());
- //channel.sendMessage(String.format("%s: %s", p.getName(), message)).complete();
- }
-
- public void sendMessage(String message, String name) {
- DbPlayer dbPlayer = civilCore.db.getPlayerByName(name);
- String prefix = (dbPlayer.team.prefix == null ?
- "" :
- "[" + dbPlayer.team.prefix + "]");
-
- WebhookMessageBuilder builder = new WebhookMessageBuilder()
- .setUsername(prefix + " " + name)
- .setAvatarUrl(String.format("https://mc-heads.net/avatar/%s", name))
- .setContent(message);
- webhook.send(builder.build());
- //channel.sendMessage(String.format("%s: %s", name, message)).complete();
- }
-
- @Override
- public void onReady(ReadyEvent e) {
- this.channel = bot.getTextChannelById(channelId);
- String webhook_token = civilCore.getConfig().getString("discord.webhook.token");
- if (webhook_token != null) {
- Long webhook_id = Long.parseLong(civilCore.getConfig().getString("discord.webhook.id"));
- this.webhook = new WebhookClientBuilder(webhook_id, webhook_token).build();
- } else {
- channel.createWebhook("CivilBot").queue((hook) -> {
- civilCore.getConfig().set("discord.webhook.id", hook.getId());
- civilCore.getConfig().set("discord.webhook.token", hook.getToken());
- civilCore.saveConfig();
- this.webhook = new WebhookClientBuilder(Long.parseLong(hook.getId()), hook.getToken()).build();
- });
- }
- }
-}
diff --git a/src/main/java/rip/iwakura/civilcore/discord/MessageReceive.java b/src/main/java/rip/iwakura/civilcore/discord/MessageReceive.java
deleted file mode 100644
index a2a5617..0000000
--- a/src/main/java/rip/iwakura/civilcore/discord/MessageReceive.java
+++ /dev/null
@@ -1,22 +0,0 @@
-package rip.iwakura.civilcore.discord;
-
-import org.bukkit.Bukkit;
-
-import net.dv8tion.jda.api.events.message.MessageReceivedEvent;
-import net.dv8tion.jda.api.hooks.ListenerAdapter;
-import net.md_5.bungee.api.ChatColor;
-import rip.iwakura.civilcore.CivilCore;
-
-public class MessageReceive extends ListenerAdapter {
- private CivilCore civilCore;
-
- public MessageReceive (CivilCore civilCore) {
- this.civilCore = civilCore;
- }
-
- @Override
- public void onMessageReceived(MessageReceivedEvent e) {
- if (e.getAuthor().isBot()) return;
- if(e.getChannel().getId().equals(civilCore.bot.channelId)) Bukkit.broadcastMessage(String.format("%sDiscord%s %s: %s", ChatColor.BLUE, ChatColor.RESET, e.getAuthor().getName(), e.getMessage()));
- }
-}
diff --git a/src/main/java/rip/iwakura/civilcore/types/CoreCommand.java b/src/main/java/rip/iwakura/civilcore/types/CoreCommand.java
deleted file mode 100644
index 9f24454..0000000
--- a/src/main/java/rip/iwakura/civilcore/types/CoreCommand.java
+++ /dev/null
@@ -1,7 +0,0 @@
-package rip.iwakura.civilcore.types;
-
-import org.bukkit.command.CommandSender;
-
-public interface CoreCommand {
- public boolean run(CommandSender sender);
-}
diff --git a/src/main/java/rip/iwakura/civilcore/types/DbPlayer.java b/src/main/java/rip/iwakura/civilcore/types/DbPlayer.java
deleted file mode 100644
index 5e1d6bd..0000000
--- a/src/main/java/rip/iwakura/civilcore/types/DbPlayer.java
+++ /dev/null
@@ -1,17 +0,0 @@
-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
deleted file mode 100644
index 704bf3a..0000000
--- a/src/main/java/rip/iwakura/civilcore/types/Team.java
+++ /dev/null
@@ -1,19 +0,0 @@
-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
index e69de29..40ac02b 100644
--- a/src/main/resources/config.yml
+++ b/src/main/resources/config.yml
@@ -0,0 +1,2 @@
+database:
+ url: ""
diff --git a/src/main/resources/log4j.properties b/src/main/resources/log4j.properties
new file mode 100644
index 0000000..ccf1f99
--- /dev/null
+++ b/src/main/resources/log4j.properties
@@ -0,0 +1,16 @@
+log4j.rootLogger=INFO, stdout
+
+log4j.appender.stdout=org.apache.log4j.ConsoleAppender
+log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
+
+# print the date in ISO 8601 format
+log4j.appender.stdout.layout.ConversionPattern=%d{ISO8601} [%p] %c{1} %m%n
+
+# be more verbose with our code
+log4j.logger.com.j256.ormlite=DEBUG
+
+# to enable logging of arguments to all of the SQL calls
+# uncomment the following lines
+log4j.logger.com.j256.ormlite.stmt.mapped.BaseMappedStatement=TRACE
+log4j.logger.com.j256.ormlite.stmt.mapped.MappedCreate=TRACE
+log4j.logger.com.j256.ormlite.stmt.StatementExecutor=TRACE
diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml
deleted file mode 100644
index 529c1fa..0000000
--- a/src/main/resources/plugin.yml
+++ /dev/null
@@ -1,17 +0,0 @@
-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: /
- permission: "civil.teams"
- court:
- description: Court Manager
- usage: /
- tc:
- description: Team Chat
- usage: /