17 Commits

Author SHA1 Message Date
912dff0ec9 attempt to add discordsrv 2024-01-25 17:44:47 -06:00
aab5083f78 Add BroadcastEvent 2024-01-25 17:00:59 -06:00
adb0d070a4 Update Jetty 2024-01-25 15:56:45 -06:00
e22f079062 Tab completion improvements to ban command 2024-01-23 19:58:15 -06:00
8f713fd30c uncomment prism support 2024-01-23 19:52:03 -06:00
72467de5ce Tab completer improvements (#80)
* Attempt to improve the tab completion for Plex

* i give up for the night

* steven is a god

* Fix permission node
2024-01-20 11:32:24 -06:00
c9d954d1c0 reformat 2024-01-19 22:30:26 -06:00
b168029df1 Fixed /mp and it now has the ability to purge one or all mobs + tab completion. (#79)
* Added a tab completion to /mp because our genius Plex devs forgot to. Its shitty but works lmao

* Rewrote /mp to actually work with or without args so now specific or all mobs can be purged, instead of just all mobs being purged. Why the REAL plex developers didn't include this (yet they did for /rd) defies any sort of logic.

* Tweaked the command a bit. It works as it should now.

* Tweaked the command a bit. It works as it should now.
2024-01-19 22:29:00 -06:00
f34df4f296 Add IP Banning by getting every IP punishment through SQL and checking if it's the same IP, if it's a ban / tempban, and if it's active
Make the ban command add the most recent IP used by a PlexPlayer if the player being banned is not online, else use online player's IP
2024-01-16 22:23:31 -08:00
79206d9354 (broken) ip bans 2024-01-16 21:03:50 -06:00
7bca348587 Show the same treatment for tempbans 2024-01-15 15:45:00 -08:00
b35bf63ba4 Add coreprotect support, start on prism but commented out until they figure out a maven repository for their API 2024-01-15 15:39:57 -08:00
8c5c058292 Allow Prism to work with Plex 2024-01-15 13:18:24 -06:00
3d70100119 Yes, there is 2023-12-02 01:17:27 -06:00
6a8228947b Switch to indra git 2023-12-01 23:52:07 -06:00
187226ff45 Add build number back for local builds
I couldn't find a more efficient way to do this
2023-12-01 23:43:27 -06:00
6d80d5f4e3 Revamp the build system 2023-12-01 21:46:20 -06:00
67 changed files with 977 additions and 445 deletions

View File

@ -1,72 +0,0 @@
plugins {
id "java"
id "maven-publish"
id "com.github.johnrengelman.shadow" version "8.1.1"
}
group = "dev.plex"
version = "1.4-SNAPSHOT"
description = "Plex"
subprojects {
apply plugin: "java"
apply plugin: "maven-publish"
apply plugin: "com.github.johnrengelman.shadow"
repositories {
maven {
url = uri("https://repo.papermc.io/repository/maven-public/")
}
maven {
url = uri("https://repository.apache.org/content/repositories/snapshots/")
}
maven {
url = uri("https://repo.maven.apache.org/maven2/")
}
maven {
url = uri("https://jitpack.io")
content {
includeGroup("com.github.MilkBowl")
}
}
mavenCentral()
}
java {
toolchain.languageVersion.set(JavaLanguageVersion.of(17))
}
tasks.withType(JavaCompile) {
options.encoding = "UTF-8"
}
publishing {
repositories {
maven {
def releasesRepoUrl = uri("https://nexus.telesphoreo.me/repository/plex-releases/")
def snapshotsRepoUrl = uri("https://nexus.telesphoreo.me/repository/plex-snapshots/")
url = rootProject.version.endsWith('SNAPSHOT') ? snapshotsRepoUrl : releasesRepoUrl
credentials {
username = System.getenv("plexUser")
password = System.getenv("plexPassword")
}
}
}
}
}
clean {
dependsOn(":server:clean")
dependsOn(":proxy:clean")
}
task copyJars(type: Copy, dependsOn: subprojects.jar) {
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
from(subprojects.jar)
from(subprojects.shadowJar)
into project.file('build/libs')
}

90
build.gradle.kts Normal file
View File

@ -0,0 +1,90 @@
plugins {
id("java")
id("maven-publish")
id("org.jetbrains.gradle.plugin.idea-ext") version "1.1.7"
id("net.kyori.blossom") version "2.1.0"
id("com.github.johnrengelman.shadow") version "8.1.1"
}
group = "dev.plex"
version = "1.4-SNAPSHOT"
description = "Plex"
subprojects {
apply(plugin = "java")
apply(plugin = "maven-publish")
apply(plugin = "org.jetbrains.gradle.plugin.idea-ext")
apply(plugin = "net.kyori.blossom")
apply(plugin = "com.github.johnrengelman.shadow")
repositories {
maven {
url = uri("https://repo.papermc.io/repository/maven-public/")
}
maven {
url = uri("https://repository.apache.org/content/repositories/snapshots/")
}
maven {
url = uri("https://repo.maven.apache.org/maven2/")
}
maven {
url = uri("https://jitpack.io")
content {
includeGroup("com.github.MilkBowl")
}
}
mavenCentral()
}
java {
toolchain.languageVersion.set(JavaLanguageVersion.of(17))
}
tasks {
compileJava {
options.encoding = Charsets.UTF_8.name()
}
javadoc {
options.encoding = Charsets.UTF_8.name()
}
processResources {
filteringCharset = Charsets.UTF_8.name()
}
}
publishing {
repositories {
maven {
val releasesRepoUrl = uri("https://nexus.telesphoreo.me/repository/plex-releases/")
val snapshotsRepoUrl = uri("https://nexus.telesphoreo.me/repository/plex-snapshots/")
url = if (rootProject.version.toString().endsWith("SNAPSHOT")) snapshotsRepoUrl else releasesRepoUrl
credentials {
username = System.getenv("plexUser")
password = System.getenv("plexPassword")
}
}
}
}
}
tasks.clean {
dependsOn(subprojects.map {
it.project.tasks.clean
})
}
tasks.create<Copy>("copyJars") {
dependsOn(tasks.jar)
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
from(subprojects.map {
it.project.tasks.shadowJar
})
from(subprojects.map {
it.project.tasks.jar
})
into(file("build/libs"))
}

View File

@ -1,6 +1,6 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.4-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-8.5-bin.zip
networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME

View File

@ -1,8 +1,3 @@
plugins {
id("org.jetbrains.gradle.plugin.idea-ext") version "1.1.7"
id("net.kyori.blossom") version "2.1.0"
}
group = rootProject.group
version = rootProject.version
description = "Plex-Velocity"
@ -47,7 +42,6 @@ dependencies {
compileOnly("org.projectlombok:lombok:1.18.30")
annotationProcessor("org.projectlombok:lombok:1.18.30")
compileOnly("org.json:json:20231013")
implementation("net.kyori:adventure-text-minimessage:4.14.0")
compileOnly("com.velocitypowered:velocity-api:4.0.0-SNAPSHOT")
annotationProcessor("com.velocitypowered:velocity-api:4.0.0-SNAPSHOT")
compileOnly("com.velocitypowered:velocity-api:3.2.0-SNAPSHOT")
annotationProcessor("com.velocitypowered:velocity-api:3.2.0-SNAPSHOT")
}

View File

@ -2,7 +2,7 @@ package dev.plex;
import com.google.inject.Inject;
import com.velocitypowered.api.event.Subscribe;
import com.velocitypowered.api.event.lifecycle.ProxyInitializeEvent;
import com.velocitypowered.api.event.proxy.ProxyInitializeEvent;
import com.velocitypowered.api.plugin.Plugin;
import com.velocitypowered.api.plugin.annotation.DataDirectory;
import com.velocitypowered.api.proxy.ProxyServer;
@ -28,7 +28,7 @@ import java.util.logging.Logger;
@Plugin(
name = "Plex",
id = "plex",
version = "{{ version }}",
version = BuildParameters.VERSION,
url = "https://plex.us.org",
description = "Plex provides a new experience for freedom servers.",
authors = {"Telesphoreo", "Taah"}

View File

@ -2,9 +2,9 @@ package dev.plex.command;
import com.velocitypowered.api.command.CommandMeta;
import com.velocitypowered.api.command.CommandSource;
import com.velocitypowered.api.command.ConsoleCommandSource;
import com.velocitypowered.api.command.SimpleCommand;
import com.velocitypowered.api.proxy.connection.Player;
import com.velocitypowered.api.proxy.ConsoleCommandSource;
import com.velocitypowered.api.proxy.Player;
import dev.plex.Plex;
import dev.plex.command.annotation.CommandParameters;
import dev.plex.command.annotation.CommandPermissions;
@ -43,9 +43,10 @@ public abstract class PlexCommand implements SimpleCommand
this.perms = getClass().getAnnotation(CommandPermissions.class);
this.commandSource = this.perms.source();
CommandMeta.Builder meta = plugin.getServer().commandManager().createMetaBuilder(this.params.name());
CommandMeta.Builder meta = plugin.getServer().getCommandManager().metaBuilder(this.params.name());
meta.aliases(this.params.aliases());
plugin.getServer().commandManager().register(meta.build(), this);
meta.plugin(Plex.get());
plugin.getServer().getCommandManager().register(meta.build(), this);
}
protected abstract Component execute(@NotNull CommandSource source, @Nullable Player player, @NotNull String[] args);

View File

@ -8,6 +8,6 @@ public class PlexListener
public PlexListener()
{
Plex.get().getServer().eventManager().register(Plex.get(), this);
Plex.get().getServer().getEventManager().register(Plex.get(), this);
}
}

View File

@ -2,7 +2,7 @@ package dev.plex.listener.impl;
import com.velocitypowered.api.event.PostOrder;
import com.velocitypowered.api.event.Subscribe;
import com.velocitypowered.api.event.player.DisconnectEvent;
import com.velocitypowered.api.event.connection.DisconnectEvent;
import com.velocitypowered.api.event.player.ServerConnectedEvent;
import dev.plex.Plex;
import dev.plex.listener.PlexListener;
@ -14,27 +14,27 @@ public class ConnectionListener extends PlexListener
@Subscribe(order = PostOrder.FIRST)
public void onPlayerJoin(ServerConnectedEvent event)
{
if (event.previousServer() != null)
if (event.getPreviousServer().isPresent())
{
Plex.get().server.sendMessage(miniMessage("<dark_gray>[<#ffbf00>o<dark_gray>] <yellow>"
+ event.player().username() + " switched from " + event.previousServer().serverInfo().name()
+ " to " + event.target().serverInfo().name()));
+ event.getPlayer().getUsername() + " switched from " + event.getPreviousServer().get().getServerInfo().getName()
+ " to " + event.getServer().getServerInfo().getName()));
}
else
{
Plex.get().server.sendMessage(miniMessage("<dark_gray>[<green>+<dark_gray>] <yellow>"
+ event.player().username() + " joined server " + event.target().serverInfo().name()));
+ event.getPlayer().getUsername() + " joined server " + event.getServer().getServerInfo().getName()));
}
}
@Subscribe(order = PostOrder.FIRST)
public void onPlayerLeave(DisconnectEvent event)
{
if (event.player().connectedServer() != null)
if (event.getPlayer().getCurrentServer().isPresent())
{
Plex.get().server.sendMessage(miniMessage("<dark_gray>[<red>-<dark_gray>] <yellow>"
+ event.player().username() + " left server " +
event.player().connectedServer().serverInfo().name()));
+ event.getPlayer().getUsername() + " left server " +
event.getPlayer().getCurrentServer().get().getServerInfo().getName()));
}
}

View File

@ -2,7 +2,7 @@ package dev.plex.listener.impl;
import com.velocitypowered.api.event.PostOrder;
import com.velocitypowered.api.event.Subscribe;
import com.velocitypowered.api.event.connection.ProxyPingEvent;
import com.velocitypowered.api.event.proxy.ProxyPingEvent;
import com.velocitypowered.api.proxy.server.ServerPing;
import dev.plex.listener.PlexListener;
import dev.plex.settings.ServerSettings;
@ -24,10 +24,10 @@ public class ServerListener extends PlexListener
String baseMotd = plugin.getConfig().as(ServerSettings.class).getServer().getMotd().get(ThreadLocalRandom.current().nextInt(plugin.getConfig().as(ServerSettings.class).getServer().getMotd().size()));
baseMotd = baseMotd.replace("\\n", "\n");
baseMotd = baseMotd.replace("%servername%", plugin.getConfig().as(ServerSettings.class).getServer().getName());
baseMotd = baseMotd.replace("%mcversion%", plugin.getServer().version().version().split(" ")[0]);
baseMotd = baseMotd.replace("%mcversion%", plugin.getServer().getVersion().getVersion().split(" ")[0]);
baseMotd = baseMotd.replace("%randomgradient%", "<gradient:" + RandomUtil.getRandomColor().toString() + ":" + RandomUtil.getRandomColor().toString() + ">");
ServerPing.Builder builder = event.ping().asBuilder();
ServerPing.Builder builder = event.getPing().asBuilder();
if (plugin.getConfig().as(ServerSettings.class).getServer().isColorizeMotd())
{
@ -45,7 +45,7 @@ public class ServerListener extends PlexListener
}
builder.samplePlayers(plugin.getConfig().as(ServerSettings.class).getServer().getSample().stream().map(s -> new ServerPing.SamplePlayer(convertColorCodes(s), UUID.randomUUID())).toArray(ServerPing.SamplePlayer[]::new));
builder.onlinePlayers(plugin.getServer().countConnectedPlayers() + plugin.getConfig().as(ServerSettings.class).getServer().getAddPlayerCount());
builder.onlinePlayers(plugin.getServer().getPlayerCount() + plugin.getConfig().as(ServerSettings.class).getServer().getAddPlayerCount());
if (plugin.getConfig().as(ServerSettings.class).getServer().isPlusOneMaxPlayer())
{
builder.maximumPlayers(builder.getOnlinePlayers() + 1);

View File

@ -17,12 +17,12 @@ public class PlexLog
message = message.replace("{" + i + "}", strings[i].toString());
}
}
Plex.get().getServer().consoleCommandSource().sendMessage(MiniMessage.miniMessage().deserialize("<yellow>[Plex] <gray>" + message));
Plex.get().getServer().getConsoleCommandSource().sendMessage(MiniMessage.miniMessage().deserialize("<yellow>[Plex] <gray>" + message));
}
public static void log(Component component)
{
Plex.get().getServer().consoleCommandSource().sendMessage(Component.text("[Plex] ").color(NamedTextColor.YELLOW).append(component).colorIfAbsent(NamedTextColor.GRAY));
Plex.get().getServer().getConsoleCommandSource().sendMessage(Component.text("[Plex] ").color(NamedTextColor.YELLOW).append(component).colorIfAbsent(NamedTextColor.GRAY));
}
public static void error(String message, Object... strings)
@ -34,7 +34,7 @@ public class PlexLog
message = message.replace("{" + i + "}", strings[i].toString());
}
}
Plex.get().getServer().consoleCommandSource().sendMessage(MiniMessage.miniMessage().deserialize("<red>[Plex Error] <gold>" + message));
Plex.get().getServer().getConsoleCommandSource().sendMessage(MiniMessage.miniMessage().deserialize("<red>[Plex Error] <gold>" + message));
}
public static void warn(String message, Object... strings)
@ -46,7 +46,7 @@ public class PlexLog
message = message.replace("{" + i + "}", strings[i].toString());
}
}
Plex.get().getServer().consoleCommandSource().sendMessage(MiniMessage.miniMessage().deserialize("<#eb7c0e>[Plex Warning] <gold>" + message));
Plex.get().getServer().getConsoleCommandSource().sendMessage(MiniMessage.miniMessage().deserialize("<#eb7c0e>[Plex Warning] <gold>" + message));
}
public static void debug(String message, Object... strings)
@ -60,7 +60,7 @@ public class PlexLog
}
if (Plex.get().getConfig().as(ServerSettings.class).getServer().isDebug())
{
Plex.get().getServer().consoleCommandSource().sendMessage(MiniMessage.miniMessage().deserialize("<dark_purple>[Plex Debug] <gold>" + message));
Plex.get().getServer().getConsoleCommandSource().sendMessage(MiniMessage.miniMessage().deserialize("<dark_purple>[Plex Debug] <gold>" + message));
}
}
}

View File

@ -1,154 +0,0 @@
plugins {
id "net.minecrell.plugin-yml.paper" version "0.6.0"
}
dependencies {
library "org.projectlombok:lombok:1.18.30"
annotationProcessor "org.projectlombok:lombok:1.18.30"
library "org.json:json:20231013"
library "commons-io:commons-io:2.15.0"
library "redis.clients:jedis:5.0.2"
library "org.mariadb.jdbc:mariadb-java-client:3.2.0"
library "com.zaxxer:HikariCP:5.0.1"
library "org.apache.maven.resolver:maven-resolver-transport-http:1.9.16"
library "org.jetbrains:annotations:24.0.1"
compileOnly "dev.folia:folia-api:1.20.1-R0.1-SNAPSHOT"
compileOnly("com.github.MilkBowl:VaultAPI:1.7.1") {
exclude group: "org.bukkit", module: "bukkit"
}
implementation "org.bstats:bstats-base:3.0.2"
implementation "org.bstats:bstats-bukkit:3.0.2"
}
group = rootProject.group
version = rootProject.version
description = "Plex-Server"
shadowJar {
archiveBaseName.set("Plex")
archiveClassifier.set("")
relocate "org.bstats", "dev.plex"
}
paper {
name = "Plex"
version = project.version
description = "Plex provides a new experience for freedom servers."
main = "dev.plex.Plex"
loader = "dev.plex.PlexLibraryManager"
website = "https://plex.us.org"
authors = ["Telesphoreo", "taahanis", "supernt"]
apiVersion = "1.19"
foliaSupported = true
generateLibrariesJson = true
// Load BukkitTelnet and LibsDisguises before Plex so the modules register properly
serverDependencies {
'BukkitTelnet' {
required = false
load = 'BEFORE'
}
'LibsDisguises' {
required = false
load = 'BEFORE'
}
'Vault' {
required = false
load = 'BEFORE'
}
'Essentials' {
required = false
load = 'BEFORE'
}
'SlimeWorldManager' {
required = false
load = 'AFTER'
}
}
}
String getGitHash() {
def stdout = new ByteArrayOutputStream()
try {
exec {
commandLine "git", "rev-parse", "--short", "HEAD"
standardOutput = stdout
ignoreExitValue = true
}
} catch (GradleException e) {
logger.error("Couldn't determine Git head because Git is not installed. " + e.getMessage())
}
return stdout.size() > 0 ? stdout.toString().trim() : "unknown"
}
String getBuildNumber() {
def stdout = new ByteArrayOutputStream()
try {
exec {
commandLine "git", "rev-list", "HEAD", "--count"
standardOutput = stdout
ignoreExitValue = true
}
} catch (GradleException e) {
logger.error("Couldn't determine build number because Git is not installed. " + e.getMessage())
}
return stdout.size() ? stdout.toString().trim() + " (local)" : "unknown"
}
static def getDate() {
return new Date().format("MM/dd/yyyy '<light_purple>at<gold>' hh:mm:ss a z")
}
task buildProperties {
ant.propertyfile(file: "$project.projectDir/src/main/resources/build.properties") {
entry(key: "buildAuthor", default: System.getenv("JENKINS_URL") != null ? "jenkins" : "unknown")
entry(key: "buildNumber", value: System.getenv("JENKINS_URL") != null ? System.getenv("BUILD_NUMBER") + " (Jenkins)" : getBuildNumber())
entry(key: "buildDate", value: getDate())
entry(key: "buildHead", value: getGitHash())
}
}
tasks {
build {
dependsOn(shadowJar)
finalizedBy(buildProperties)
}
jar {
enabled = false
}
shadowJar {
finalizedBy(rootProject.tasks.copyJars)
}
javadoc {
options.memberLevel = JavadocMemberLevel.PRIVATE
}
}
publishing {
publications {
maven(MavenPublication) {
pom.withXml {
def dependenciesNode = asNode().appendNode("dependencies")
configurations.getByName("library").getAllDependencies().each { dependency ->
dependenciesNode.appendNode("dependency").with {
it.appendNode("groupId", dependency.group)
it.appendNode("artifactId", dependency.name)
it.appendNode("version", dependency.version)
it.appendNode("scope", "provided")
}
}
configurations.getByName("implementation").getAllDependencies().each { dependency ->
dependenciesNode.appendNode("dependency").with {
it.appendNode("groupId", dependency.group)
it.appendNode("artifactId", dependency.name)
it.appendNode("version", dependency.version)
it.appendNode("scope", "runtime")
}
}
}
artifacts = [shadowJar]
}
}
}

162
server/build.gradle.kts Normal file
View File

@ -0,0 +1,162 @@
import net.minecrell.pluginyml.paper.PaperPluginDescription
import java.io.ByteArrayOutputStream
import java.text.SimpleDateFormat
import java.util.*
plugins {
id("net.kyori.indra.git") version "3.1.3"
id("net.minecrell.plugin-yml.paper") version "0.6.0"
}
repositories {
maven(url = uri("https://maven.playpro.com"))
maven(url = uri("https://nexus.telesphoreo.me/repository/plex-modules/"))
}
dependencies {
library("org.projectlombok:lombok:1.18.30")
library("org.json:json:20231013")
library("commons-io:commons-io:2.15.1")
library("redis.clients:jedis:5.1.0")
library("org.mariadb.jdbc:mariadb-java-client:3.3.1")
library("com.zaxxer:HikariCP:5.1.0")
library("org.apache.maven.resolver:maven-resolver-transport-http:1.9.18")
library("org.jetbrains:annotations:24.1.0")
compileOnly("dev.folia:folia-api:1.20.2-R0.1-SNAPSHOT")
compileOnly("com.github.MilkBowl:VaultAPI:1.7.1") {
exclude("org.bukkit", "bukkit")
}
compileOnly("net.coreprotect:coreprotect:22.2")
compileOnly("network.darkhelmet.prism:Prism-Api:1.0.0")
implementation("org.bstats:bstats-base:3.0.2")
implementation("org.bstats:bstats-bukkit:3.0.2")
annotationProcessor("org.projectlombok:lombok:1.18.30")
}
group = rootProject.group
version = rootProject.version
description = "Plex-Server"
paper {
name = "Plex"
version = rootProject.version.toString()
description = "Plex provides a new experience for freedom servers."
main = "dev.plex.Plex"
loader = "dev.plex.PlexLibraryManager"
website = "https://plex.us.org"
authors = listOf("Telesphoreo", "taahanis", "supernt")
apiVersion = "1.19"
foliaSupported = true
generateLibrariesJson = true
// Load BukkitTelnet and LibsDisguises before Plex so the modules register properly
serverDependencies {
register("BukkitTelnet") {
required = false
load = PaperPluginDescription.RelativeLoadOrder.BEFORE
}
register("DiscordSRV") {
required = false
load = PaperPluginDescription.RelativeLoadOrder.AFTER
}
register("Essentials") {
required = false
load = PaperPluginDescription.RelativeLoadOrder.BEFORE
}
register("LibsDisguises") {
required = false
load = PaperPluginDescription.RelativeLoadOrder.BEFORE
}
register("Prism") {
required = false
load = PaperPluginDescription.RelativeLoadOrder.BEFORE
}
register("CoreProtect") {
required = false
load = PaperPluginDescription.RelativeLoadOrder.BEFORE
}
register("SlimeWorldManager") {
required = false
load = PaperPluginDescription.RelativeLoadOrder.AFTER
}
register("Vault") {
required = false
load = PaperPluginDescription.RelativeLoadOrder.BEFORE
}
}
}
fun getBuildNumber(): String {
val stdout = ByteArrayOutputStream()
try {
exec {
commandLine("git", "rev-list", "HEAD", "--count")
standardOutput = stdout
isIgnoreExitValue = true
}
} catch (e: GradleException) {
logger.error("Couldn't determine build number because Git is not installed. " + e.message)
}
return if (stdout.size() > 0) stdout.toString().trim() else "unknown"
}
tasks {
build {
dependsOn(shadowJar)
}
jar {
enabled = false
}
sourceSets {
main {
blossom {
resources {
property("author", if (System.getenv("JENKINS_URL") != null) "jenkins" else System.getProperty("user.name"))
property("buildNumber", if (System.getenv("BUILD_NUMBER") != null) System.getenv("BUILD_NUMBER") else getBuildNumber())
property("date", SimpleDateFormat("MM/dd/yyyy '<light_purple>at<gold>' hh:mm:ss a z").format(Date()))
property("gitCommit", indraGit.commit()?.name?.take(7))
}
}
}
}
shadowJar {
archiveBaseName.set("Plex")
archiveClassifier.set("")
relocate("org.bstats", "dev.plex")
finalizedBy(rootProject.tasks["copyJars"])
}
javadoc {
options.memberLevel = JavadocMemberLevel.PRIVATE
}
}
publishing {
publications {
create<MavenPublication>("maven") {
pom.withXml {
val dependenciesNode = asNode().appendNode("dependencies")
configurations.getByName("library").allDependencies.configureEach {
dependenciesNode.appendNode("dependency")
.appendNode("groupId", group).parent()
.appendNode("artifactId", name).parent()
.appendNode("version", version).parent()
.appendNode("scope", "provided").parent()
}
configurations.getByName("implementation").allDependencies.configureEach {
dependenciesNode.appendNode("dependency")
.appendNode("groupId", group).parent()
.appendNode("artifactId", name).parent()
.appendNode("version", version).parent()
.appendNode("scope", "provided").parent()
}
}
artifacts.artifact(tasks.shadowJar)
}
}
}

View File

@ -1,11 +1,12 @@
package dev.plex;
import com.google.common.collect.Lists;
import dev.plex.cache.DataUtils;
import dev.plex.cache.PlayerCache;
import dev.plex.config.Config;
import dev.plex.handlers.CommandHandler;
import dev.plex.handlers.ListenerHandler;
import dev.plex.hook.CoreProtectHook;
import dev.plex.hook.PrismHook;
import dev.plex.module.ModuleManager;
import dev.plex.player.PlexPlayer;
import dev.plex.punishment.PunishmentManager;
@ -16,22 +17,23 @@ import dev.plex.storage.StorageType;
import dev.plex.storage.player.SQLPlayerData;
import dev.plex.storage.punishment.SQLNotes;
import dev.plex.storage.punishment.SQLPunishment;
import dev.plex.util.*;
import dev.plex.util.BuildInfo;
import dev.plex.util.BungeeUtil;
import dev.plex.util.PlexLog;
import dev.plex.util.PlexUtils;
import dev.plex.util.UpdateChecker;
import dev.plex.util.redis.MessageUtil;
import dev.plex.util.sql.SQLUtil;
import dev.plex.world.CustomWorld;
import java.io.File;
import lombok.Getter;
import lombok.Setter;
import net.milkbowl.vault.chat.Chat;
import net.milkbowl.vault.permission.Permission;
import org.apache.commons.lang3.StringUtils;
import org.bstats.bukkit.Metrics;
import org.bukkit.Bukkit;
import org.bukkit.plugin.RegisteredServiceProvider;
import org.bukkit.plugin.java.JavaPlugin;
import java.io.File;
@Getter
@Setter
public class Plex extends JavaPlugin
@ -46,7 +48,6 @@ public class Plex extends JavaPlugin
public File modulesFolder;
private StorageType storageType = StorageType.SQLITE;
private SQLConnection sqlConnection;
// private MongoConnection mongoConnection;
private RedisConnection redisConnection;
private PlayerCache playerCache;
@ -63,6 +64,9 @@ public class Plex extends JavaPlugin
private Permission permissions;
private Chat chat;
private CoreProtectHook coreProtectHook;
private PrismHook prismHook;
public static Plex get()
{
return plugin;
@ -124,12 +128,31 @@ public class Plex extends JavaPlugin
if (!getServer().getPluginManager().isPluginEnabled("Vault"))
{
throw new RuntimeException("Vault is required to run on the server if you use permissions alongside a permissions plugin, we recommend LuckPerms!");
throw new RuntimeException("Vault is required to run on the server alongside a permissions plugin, we recommend LuckPerms!");
}
permissions = setupPermissions();
chat = setupChat();
if (plugin.getServer().getPluginManager().isPluginEnabled("CoreProtect"))
{
PlexLog.log("Hooked into CoreProtect!");
coreProtectHook = new CoreProtectHook(this);
}
else
{
PlexLog.debug("Not hooking into CoreProtect");
}
if (plugin.getServer().getPluginManager().isPluginEnabled("Prism"))
{
PlexLog.log("Hooked into Prism!");
prismHook = new PrismHook(this);
}
else
{
PlexLog.debug("Not hooking into Prism");
}
updateChecker = new UpdateChecker();
PlexLog.log("Update checking enabled");

View File

@ -29,9 +29,14 @@ public class PlexLibraryManager implements PluginLoader
// The plugin is null, a hacky way to check whether to load Jetty or not
if (new File("plugins/Plex/modules/Module-HTTPD.jar").isFile())
{
resolver.addDependency(new Dependency(new DefaultArtifact("org.eclipse.jetty:jetty-server:11.0.18"), null));
resolver.addDependency(new Dependency(new DefaultArtifact("org.eclipse.jetty:jetty-servlet:11.0.18"), null));
resolver.addDependency(new Dependency(new DefaultArtifact("org.eclipse.jetty:jetty-proxy:11.0.18"), null));
resolver.addDependency(new Dependency(new DefaultArtifact("org.eclipse.jetty:jetty-server:11.0.19"), null));
resolver.addDependency(new Dependency(new DefaultArtifact("org.eclipse.jetty:jetty-servlet:11.0.19"), null));
resolver.addDependency(new Dependency(new DefaultArtifact("org.eclipse.jetty:jetty-proxy:11.0.19"), null));
}
if (new File("plugins/Plex/modules/Module-DiscordSRV.jar").isFile())
{
resolver.addRepository(new RemoteRepository.Builder("discordsrv", "default", "https://nexus.scarsz.me/content/groups/public/").build());
resolver.addDependency(new Dependency(new DefaultArtifact("com.discordsrv:discordsrv:1.27.0"), null));
}
classpathBuilder.addLibrary(resolver);
}

View File

@ -1,5 +1,6 @@
package dev.plex.command;
import com.google.common.collect.Lists;
import dev.plex.Plex;
import dev.plex.cache.DataUtils;
import dev.plex.command.annotation.CommandParameters;
@ -14,14 +15,15 @@ import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.format.NamedTextColor;
import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.World;
import org.bukkit.command.*;
import org.bukkit.entity.Player;
import org.bukkit.util.StringUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Arrays;
import java.util.List;
import java.util.UUID;
/**
@ -61,6 +63,7 @@ public abstract class PlexCommand extends Command implements PluginIdentifiableC
setName(this.params.name());
setLabel(this.params.name());
setDescription(params.description());
setPermission(this.perms.permission());
setUsage(params.usage().replace("<command>", this.params.name()));
if (params.aliases().split(",").length > 0)
{
@ -74,7 +77,8 @@ public abstract class PlexCommand extends Command implements PluginIdentifiableC
{
getMap().getKnownCommands().remove(this.getName().toLowerCase());
}
this.getAliases().forEach(s -> {
this.getAliases().forEach(s ->
{
if (getMap().getKnownCommands().containsKey(s.toLowerCase()))
{
getMap().getKnownCommands().remove(s.toLowerCase());
@ -166,6 +170,17 @@ public abstract class PlexCommand extends Command implements PluginIdentifiableC
return true;
}
@NotNull
public abstract List<String> smartTabComplete(@NotNull CommandSender sender, @NotNull String alias, @NotNull String[] args) throws IllegalArgumentException;
@NotNull
@Override
public List<String> tabComplete(@NotNull CommandSender sender, @NotNull String alias, @NotNull String[] args) throws IllegalArgumentException
{
List<String> list = smartTabComplete(sender, alias, args);
return StringUtil.copyPartialMatches(args[args.length - 1], list, Lists.newArrayList());
}
/**
* Checks if the String given is a matching command
*
@ -283,47 +298,6 @@ public abstract class PlexCommand extends Command implements PluginIdentifiableC
return !permission.isEmpty() && player.hasPermission(permission);
}
/* *//**
* Checks whether a sender has enough permissions or is high enough a rank
*
* @param sender The player object
* @param rank The rank to check (if the server is using ranks)
* @param permission The permission to check (if the server is using permissions)
* @return true if the sender has enough permissions
* @see Rank
*//*
protected boolean silentCheckPermission(CommandSender sender, Rank rank, String permission)
{
if (!isConsole(sender))
{
return silentCheckPermission((Player) sender, rank, permission);
}
return true;
}
*//**
* Checks whether a player has enough permissions or is high enough a rank
*
* @param player The player object
* @param rank The rank to check (if the server is using ranks)
* @param permission The permission to check (if the server is using permissions)
* @return true if the sender has enough permissions
* @see Rank
*//*
protected boolean silentCheckPermission(Player player, Rank rank, String permission)
{
PlexPlayer plexPlayer = getPlexPlayer(player);
if (plugin.getSystem().equalsIgnoreCase("ranks"))
{
return rank.isAtLeast(Rank.ADMIN) ? plexPlayer.isAdminActive() && plexPlayer.getRankFromString().isAtLeast(rank) : plexPlayer.getRankFromString().isAtLeast(rank);
}
else if (plugin.getSystem().equalsIgnoreCase("permissions"))
{
return !permission.isEmpty() && player.hasPermission(permission);
}
return true;
}*/
/**
* Gets the UUID of the sender
*

View File

@ -1,6 +1,5 @@
package dev.plex.command.impl;
import dev.plex.cache.DataUtils;
import dev.plex.command.PlexCommand;
import dev.plex.command.annotation.CommandParameters;
import dev.plex.command.annotation.CommandPermissions;
@ -12,8 +11,6 @@ import dev.plex.util.PlexUtils;
import dev.plex.util.minimessage.SafeMiniMessage;
import dev.plex.util.redis.MessageUtil;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.TextComponent;
import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
import org.apache.commons.lang3.BooleanUtils;
import org.apache.commons.lang3.StringUtils;
import org.bukkit.command.CommandSender;
@ -21,6 +18,8 @@ import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Collections;
import java.util.List;
import java.util.UUID;
@CommandPermissions(permission = "plex.adminchat", source = RequiredCommandSource.ANY)
@ -58,4 +57,10 @@ public class AdminChatCMD extends PlexCommand
MessageUtil.sendStaffChat(sender, SafeMiniMessage.mmDeserialize(message), PlexUtils.adminChat(sender.getName(), prefix, message).toArray(UUID[]::new));
return null;
}
@Override
public @NotNull List<String> smartTabComplete(@NotNull CommandSender sender, @NotNull String alias, @NotNull String[] args) throws IllegalArgumentException
{
return Collections.emptyList();
}
}

View File

@ -12,6 +12,9 @@ import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Collections;
import java.util.List;
@CommandPermissions(permission = "plex.adminworld", source = RequiredCommandSource.IN_GAME)
@CommandParameters(name = "adminworld", aliases = "aw", description = "Teleport to the adminworld")
public class AdminworldCMD extends PlexCommand
@ -29,4 +32,10 @@ public class AdminworldCMD extends PlexCommand
}
return null;
}
@Override
public @NotNull List<String> smartTabComplete(@NotNull CommandSender sender, @NotNull String alias, @NotNull String[] args) throws IllegalArgumentException
{
return Collections.emptyList();
}
}

View File

@ -53,7 +53,7 @@ public class AdventureCMD extends PlexCommand
}
@Override
public @NotNull List<String> tabComplete(@NotNull CommandSender sender, @NotNull String alias, @NotNull String[] args) throws IllegalArgumentException
public @NotNull List<String> smartTabComplete(@NotNull CommandSender sender, @NotNull String alias, @NotNull String[] args) throws IllegalArgumentException
{
if (silentCheckPermission(sender, "plex.gamemode.adventure.others"))
{

View File

@ -1,6 +1,5 @@
package dev.plex.command.impl;
import com.google.common.collect.ImmutableList;
import dev.plex.Plex;
import dev.plex.cache.DataUtils;
import dev.plex.command.PlexCommand;
@ -11,8 +10,21 @@ import dev.plex.command.source.RequiredCommandSource;
import dev.plex.player.PlexPlayer;
import dev.plex.punishment.Punishment;
import dev.plex.punishment.PunishmentType;
import dev.plex.util.*;
import dev.plex.util.BungeeUtil;
import dev.plex.util.PlexLog;
import dev.plex.util.PlexUtils;
import dev.plex.util.TimeUtils;
import java.time.Instant;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import net.kyori.adventure.text.Component;
import network.darkhelmet.prism.api.PrismParameters;
import network.darkhelmet.prism.api.Result;
import network.darkhelmet.prism.api.actions.PrismProcessType;
import org.apache.commons.lang3.StringUtils;
import org.bukkit.Bukkit;
import org.bukkit.command.CommandSender;
@ -20,11 +32,7 @@ import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.util.List;
@CommandParameters(name = "ban", usage = "/<command> <player> [reason]", aliases = "offlineban,gtfo", description = "Bans a player, offline or online")
@CommandParameters(name = "ban", usage = "/<command> <player> [-nrb] [reason] [-nrb]", aliases = "offlineban,gtfo", description = "Bans a player, offline or online")
@CommandPermissions(permission = "plex.ban", source = RequiredCommandSource.ANY)
public class BanCMD extends PlexCommand
@ -56,10 +64,13 @@ public class BanCMD extends PlexCommand
String reason;
Punishment punishment = new Punishment(plexPlayer.getUuid(), getUUID(sender));
punishment.setType(PunishmentType.BAN);
boolean rollBack = true;
if (args.length > 1)
{
reason = StringUtils.join(args, " ", 1, args.length);
punishment.setReason(reason);
String newReason = StringUtils.normalizeSpace(reason.replace("-nrb", ""));
punishment.setReason(newReason.trim().isEmpty() ? "No reason provided." : newReason);
rollBack = !reason.startsWith("-nrb") && !reason.endsWith("-nrb");
}
else
{
@ -70,10 +81,7 @@ public class BanCMD extends PlexCommand
punishment.setEndDate(date.plusDays(1));
punishment.setCustomTime(false);
punishment.setActive(true);
if (player != null)
{
punishment.setIp(player.getAddress().getAddress().getHostAddress().trim());
}
punishment.setIp(player != null ? player.getAddress().getAddress().getHostAddress().trim() : plexPlayer.getIps().get(plexPlayer.getIps().size() - 1));
plugin.getPunishmentManager().punish(plexPlayer, punishment);
PlexUtils.broadcast(messageComponent("banningPlayer", sender.getName(), plexPlayer.getName()));
Bukkit.getScheduler().runTask(Plex.get(), () ->
@ -84,14 +92,59 @@ public class BanCMD extends PlexCommand
}
});
PlexLog.debug("(From /ban command) PunishedPlayer UUID: " + plexPlayer.getUuid());
if (rollBack)
{
if (plugin.getPrismHook().hasPrism())
{
PrismParameters parameters = plugin.getPrismHook().prismApi().createParameters();
parameters.addActionType("block-place");
parameters.addActionType("block-break");
parameters.addActionType("block-burn");
parameters.addActionType("entity-spawn");
parameters.addActionType("entity-kill");
parameters.addActionType("entity-explode");
parameters.addPlayerName(plexPlayer.getName());
parameters.setBeforeTime(Instant.now().toEpochMilli());
parameters.setProcessType(PrismProcessType.ROLLBACK);
final Future<Result> result = plugin.getPrismHook().prismApi().performLookup(parameters, sender);
Bukkit.getAsyncScheduler().runNow(plugin, scheduledTask ->
{
try
{
final Result done = result.get();
}
catch (InterruptedException | ExecutionException e)
{
throw new RuntimeException(e);
}
});
}
else if (plugin.getCoreProtectHook().hasCoreProtect())
{
PlexLog.debug("Testing coreprotect");
Bukkit.getAsyncScheduler().runNow(plugin, scheduledTask ->
{
plugin.getCoreProtectHook().coreProtectAPI().performRollback(86400, Collections.singletonList(plexPlayer.getName()), null, null, null, null, 0, null);
});
}
}
});
return null;
}
@Override
public @NotNull List<String> tabComplete(@NotNull CommandSender sender, @NotNull String alias, @NotNull String[] args) throws IllegalArgumentException
public @NotNull List<String> smartTabComplete(@NotNull CommandSender sender, @NotNull String alias, @NotNull String[] args) throws IllegalArgumentException
{
return args.length == 1 && silentCheckPermission(sender, "plex.ban") ? PlexUtils.getPlayerNameList() : ImmutableList.of();
if (args.length == 1 && silentCheckPermission(sender, this.getPermission()))
{
return PlexUtils.getPlayerNameList();
}
if (args.length != 1 && silentCheckPermission(sender, this.getPermission()))
{
return Collections.singletonList("-nrb");
}
return Collections.emptyList();
}
}

View File

@ -12,6 +12,11 @@ import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
@CommandPermissions(permission = "plex.blockedit")
@CommandParameters(name = "blockedit", usage = "/<command> [list | purge | all | <player>]", aliases = "bedit", description = "Prevent players from modifying blocks")
public class BlockEditCMD extends PlexCommand
@ -94,4 +99,20 @@ public class BlockEditCMD extends PlexCommand
}
return null;
}
@Override
public @NotNull List<String> smartTabComplete(@NotNull CommandSender sender, @NotNull String alias, @NotNull String[] args) throws IllegalArgumentException
{
if (silentCheckPermission(sender, this.getPermission()))
{
List<String> options = new ArrayList<>();
if (args.length == 1)
{
options.addAll(Arrays.asList("list", "purge", "all"));
options.addAll(PlexUtils.getPlayerNameList());
return options;
}
}
return Collections.emptyList();
}
}

View File

@ -12,6 +12,9 @@ import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Collections;
import java.util.List;
@CommandPermissions(permission = "plex.commandspy", source = RequiredCommandSource.IN_GAME)
@CommandParameters(name = "commandspy", aliases = "cmdspy", description = "Spy on other player's commands")
public class CommandSpyCMD extends PlexCommand
@ -30,4 +33,10 @@ public class CommandSpyCMD extends PlexCommand
}
return null;
}
@Override
public @NotNull List<String> smartTabComplete(@NotNull CommandSender sender, @NotNull String alias, @NotNull String[] args) throws IllegalArgumentException
{
return Collections.emptyList();
}
}

View File

@ -12,6 +12,9 @@ import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Collections;
import java.util.List;
@CommandPermissions(permission = "plex.consolesay", source = RequiredCommandSource.CONSOLE)
@CommandParameters(name = "consolesay", usage = "/<command> <message>", description = "Displays a message to everyone", aliases = "csay")
public class ConsoleSayCMD extends PlexCommand
@ -27,4 +30,10 @@ public class ConsoleSayCMD extends PlexCommand
PlexUtils.broadcast(PlexUtils.messageComponent("consoleSayMessage", sender.getName(), PlexUtils.mmStripColor(StringUtils.join(args, " "))));
return null;
}
@Override
public @NotNull List<String> smartTabComplete(@NotNull CommandSender sender, @NotNull String alias, @NotNull String[] args) throws IllegalArgumentException
{
return Collections.emptyList();
}
}

View File

@ -56,7 +56,7 @@ public class CreativeCMD extends PlexCommand
}
@Override
public @NotNull List<String> tabComplete(@NotNull CommandSender sender, @NotNull String alias, @NotNull String[] args) throws IllegalArgumentException
public @NotNull List<String> smartTabComplete(@NotNull CommandSender sender, @NotNull String alias, @NotNull String[] args) throws IllegalArgumentException
{
if (silentCheckPermission(sender, "plex.gamemode.creative.others"))
{

View File

@ -21,7 +21,6 @@ import org.jetbrains.annotations.Nullable;
import java.util.Arrays;
import java.util.List;
import java.util.Locale;
import java.util.concurrent.CompletableFuture;
@CommandParameters(name = "pdebug", description = "Plex's debug command", usage = "/<command> <aliases <command> | redis-reset <player> | gamerules>")
@CommandPermissions(permission = "plex.debug")
@ -91,8 +90,8 @@ public class DebugCMD extends PlexCommand
}
@Override
public @NotNull List<String> tabComplete(@NotNull CommandSender sender, @NotNull String alias, @NotNull String[] args) throws IllegalArgumentException
public @NotNull List<String> smartTabComplete(@NotNull CommandSender sender, @NotNull String alias, @NotNull String[] args) throws IllegalArgumentException
{
return args.length == 1 ? PlexUtils.getPlayerNameList() : ImmutableList.of();
return args.length == 1 && silentCheckPermission(sender, this.getPermission()) ? PlexUtils.getPlayerNameList() : ImmutableList.of();
}
}

View File

@ -106,20 +106,24 @@ public class EntityWipeCMD extends PlexCommand
return null;
}
public @NotNull List<String> tabComplete(@NotNull CommandSender sender, @NotNull String alias, @NotNull String[] args) throws IllegalArgumentException
public @NotNull List<String> smartTabComplete(@NotNull CommandSender sender, @NotNull String alias, @NotNull String[] args) throws IllegalArgumentException
{
List<String> entities = new ArrayList<>();
for (World world : Bukkit.getWorlds())
if (silentCheckPermission(sender, this.getPermission()))
{
for (Entity entity : world.getEntities())
List<String> entities = new ArrayList<>();
for (World world : Bukkit.getWorlds())
{
if (entity.getType() != EntityType.PLAYER)
for (Entity entity : world.getEntities())
{
entities.add(entity.getType().name());
if (entity.getType() != EntityType.PLAYER)
{
entities.add(entity.getType().name());
}
}
}
return entities.stream().toList();
}
return entities.stream().toList();
return Collections.emptyList();
}
private Integer parseInt(CommandSender sender, String string)

View File

@ -4,7 +4,6 @@ import dev.plex.command.PlexCommand;
import dev.plex.command.annotation.CommandParameters;
import dev.plex.command.annotation.CommandPermissions;
import dev.plex.command.source.RequiredCommandSource;
import net.kyori.adventure.text.Component;
import org.bukkit.Bukkit;
import org.bukkit.Location;
@ -13,6 +12,9 @@ import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Collections;
import java.util.List;
@CommandPermissions(permission = "plex.flatlands", source = RequiredCommandSource.IN_GAME)
@CommandParameters(name = "flatlands", description = "Teleport to the flatlands")
public class FlatlandsCMD extends PlexCommand
@ -29,4 +31,10 @@ public class FlatlandsCMD extends PlexCommand
}
return null;
}
@Override
public @NotNull List<String> smartTabComplete(@NotNull CommandSender sender, @NotNull String alias, @NotNull String[] args) throws IllegalArgumentException
{
return Collections.emptyList();
}
}

View File

@ -7,7 +7,6 @@ import dev.plex.command.annotation.CommandPermissions;
import dev.plex.player.PlexPlayer;
import dev.plex.punishment.Punishment;
import dev.plex.punishment.PunishmentType;
import dev.plex.util.PlexUtils;
import dev.plex.util.TimeUtils;
import net.kyori.adventure.text.Component;
@ -54,8 +53,8 @@ public class FreezeCMD extends PlexCommand
}
@Override
public @NotNull List<String> tabComplete(@NotNull CommandSender sender, @NotNull String alias, @NotNull String[] args) throws IllegalArgumentException
public @NotNull List<String> smartTabComplete(@NotNull CommandSender sender, @NotNull String alias, @NotNull String[] args) throws IllegalArgumentException
{
return args.length == 1 && silentCheckPermission(sender, "plex.freeze") ? PlexUtils.getPlayerNameList() : ImmutableList.of();
return args.length == 1 && silentCheckPermission(sender, this.getPermission()) ? PlexUtils.getPlayerNameList() : ImmutableList.of();
}
}

View File

@ -88,7 +88,7 @@ public class GamemodeCMD extends PlexCommand
}
@Override
public @NotNull List<String> tabComplete(@NotNull CommandSender sender, @NotNull String alias, @NotNull String[] args) throws IllegalArgumentException
public @NotNull List<String> smartTabComplete(@NotNull CommandSender sender, @NotNull String alias, @NotNull String[] args) throws IllegalArgumentException
{
if (args.length == 1)
{
@ -96,7 +96,10 @@ public class GamemodeCMD extends PlexCommand
}
if (args.length == 2)
{
return PlexUtils.getPlayerNameList();
if (silentCheckPermission(sender, "plex.gamemode.others"))
{
return PlexUtils.getPlayerNameList();
}
}
return Collections.emptyList();
}

View File

@ -1,5 +1,6 @@
package dev.plex.command.impl;
import com.google.common.collect.ImmutableList;
import dev.plex.cache.DataUtils;
import dev.plex.command.PlexCommand;
import dev.plex.command.annotation.CommandParameters;
@ -9,7 +10,6 @@ import dev.plex.command.source.RequiredCommandSource;
import dev.plex.player.PlexPlayer;
import dev.plex.punishment.Punishment;
import dev.plex.punishment.PunishmentType;
import dev.plex.util.BungeeUtil;
import dev.plex.util.PlexUtils;
import dev.plex.util.TimeUtils;
@ -23,6 +23,7 @@ import org.jetbrains.annotations.Nullable;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.util.List;
@CommandParameters(name = "kick", description = "Kicks a player", usage = "/<command> <player>")
@CommandPermissions(permission = "plex.kick", source = RequiredCommandSource.ANY)
@ -67,4 +68,10 @@ public class KickCMD extends PlexCommand
BungeeUtil.kickPlayer(player, Punishment.generateKickMessage(punishment));
return null;
}
@Override
public @NotNull List<String> smartTabComplete(@NotNull CommandSender sender, @NotNull String alias, @NotNull String[] args) throws IllegalArgumentException
{
return args.length == 1 && silentCheckPermission(sender, this.getPermission()) ? PlexUtils.getPlayerNameList() : ImmutableList.of();
}
}

View File

@ -65,9 +65,9 @@ public class ListCMD extends PlexCommand
return list;
}
public @NotNull List<String> tabComplete(@NotNull CommandSender sender, @NotNull String alias, @NotNull String[] args) throws IllegalArgumentException
public @NotNull List<String> smartTabComplete(@NotNull CommandSender sender, @NotNull String alias, @NotNull String[] args) throws IllegalArgumentException
{
if (args.length == 1)
if (args.length == 1 && silentCheckPermission(sender, this.getPermission()))
{
return Collections.singletonList("-d");
}

View File

@ -11,6 +11,9 @@ import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Collections;
import java.util.List;
@CommandParameters(name = "localspawn", description = "Teleport to the spawnpoint of the world you are in")
@CommandPermissions(permission = "plex.localspawn", source = RequiredCommandSource.IN_GAME)
public class LocalSpawnCMD extends PlexCommand
@ -22,4 +25,10 @@ public class LocalSpawnCMD extends PlexCommand
playerSender.teleportAsync(playerSender.getWorld().getSpawnLocation());
return messageComponent("teleportedToWorldSpawn");
}
@Override
public @NotNull List<String> smartTabComplete(@NotNull CommandSender sender, @NotNull String alias, @NotNull String[] args) throws IllegalArgumentException
{
return Collections.emptyList();
}
}

View File

@ -5,7 +5,6 @@ import dev.plex.command.PlexCommand;
import dev.plex.command.annotation.CommandParameters;
import dev.plex.command.annotation.CommandPermissions;
import dev.plex.player.PlexPlayer;
import dev.plex.util.PlexUtils;
import net.kyori.adventure.text.Component;
import org.bukkit.command.CommandSender;
@ -39,8 +38,8 @@ public class LockupCMD extends PlexCommand
}
@Override
public @NotNull List<String> tabComplete(@NotNull CommandSender sender, @NotNull String alias, @NotNull String[] args) throws IllegalArgumentException
public @NotNull List<String> smartTabComplete(@NotNull CommandSender sender, @NotNull String alias, @NotNull String[] args) throws IllegalArgumentException
{
return args.length == 1 && silentCheckPermission(sender, "plex.lockup") ? PlexUtils.getPlayerNameList() : ImmutableList.of();
return args.length == 1 && silentCheckPermission(sender, this.getPermission()) ? PlexUtils.getPlayerNameList() : ImmutableList.of();
}
}

View File

@ -13,6 +13,9 @@ import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Collections;
import java.util.List;
@CommandPermissions(permission = "plex.masterbuilderworld", source = RequiredCommandSource.IN_GAME)
@CommandParameters(name = "masterbuilderworld", aliases = "mbw", description = "Teleport to the Master Builder world")
public class MasterbuilderworldCMD extends PlexCommand
@ -30,4 +33,10 @@ public class MasterbuilderworldCMD extends PlexCommand
}
return null;
}
@Override
public @NotNull List<String> smartTabComplete(@NotNull CommandSender sender, @NotNull String alias, @NotNull String[] args) throws IllegalArgumentException
{
return Collections.emptyList();
}
}

View File

@ -4,50 +4,119 @@ import dev.plex.command.PlexCommand;
import dev.plex.command.annotation.CommandParameters;
import dev.plex.command.annotation.CommandPermissions;
import dev.plex.command.source.RequiredCommandSource;
import dev.plex.util.PlexLog;
import dev.plex.util.PlexUtils;
import net.kyori.adventure.text.Component;
import org.apache.commons.lang3.text.WordUtils;
import org.bukkit.Bukkit;
import org.bukkit.World;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Mob;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.HashMap;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
@CommandPermissions(permission = "plex.mobpurge", source = RequiredCommandSource.ANY)
@CommandParameters(name = "mobpurge", description = "Purge all mobs.", usage = "/<command>", aliases = "mp")
@CommandParameters(name = "mobpurge", description = "Purge all mobs.", usage = "/<command> [mob]", aliases = "mp")
public class MobPurgeCMD extends PlexCommand
{
private final List<EntityType> MOB_TYPES = new ArrayList<>();
@Override
protected Component execute(@NotNull CommandSender sender, @Nullable Player playerSender, @NotNull String[] args)
{
HashMap<String, Integer> entityCounts = new HashMap<>();
EntityType type = null;
String mobName = null;
if (args.length > 0)
{
try
{
type = EntityType.valueOf(args[0].toUpperCase());
}
catch (Exception e)
{
PlexLog.debug("A genius tried and failed removing the following invalid mob: " + args[0].toUpperCase());
send(sender, messageComponent("notAValidMob"));
return null;
}
if (!MOB_TYPES.contains(type))
{
PlexLog.debug(Arrays.deepToString(MOB_TYPES.toArray()));
PlexLog.debug("A genius tried to remove a mob that doesn't exist: " + args[0].toUpperCase());
sender.sendMessage(messageComponent("notAValidMobButValidEntity"));
return null;
}
}
if (type != null)
{
mobName = WordUtils.capitalizeFully(type.name().replace("_", " "));
PlexLog.debug("The args aren't null so the mob is: " + mobName);
}
int count = purgeMobs(type);
if (type != null)
{
PlexUtils.broadcast(messageComponent("removedEntitiesOfTypes", sender.getName(), count, mobName));
PlexLog.debug("All " + count + " of " + mobName + " were removed");
}
else
{
PlexUtils.broadcast(messageComponent("removedMobs", sender.getName(), count));
PlexLog.debug("All " + count + " valid mobs were removed");
}
sender.sendMessage(messageComponent("amountOfMobsRemoved", count, (type != null ? mobName : "mob") + multipleS(count)));
return null;
}
private String multipleS(int count)
{
return (count == 1 ? "" : "s");
}
private int purgeMobs(EntityType type)
{
int removed = 0;
for (World world : Bukkit.getWorlds())
{
for (Entity entity : world.getEntities())
for (Entity entity : world.getLivingEntities())
{
if (entity instanceof Mob)
if (entity instanceof LivingEntity && !(entity instanceof Player))
{
String type = entity.getType().name();
if (type != null && !entity.getType().equals(type))
{
continue;
}
entity.remove();
entityCounts.put(type, entityCounts.getOrDefault(type, 0) + 1);
removed++;
}
}
}
return removed;
}
int entityCount = entityCounts.values().stream().mapToInt(a -> a).sum();
private List<String> getAllMobs()
{
List<String> mobs = new ArrayList<>();
Arrays.stream(EntityType.values()).filter(EntityType::isAlive).filter(EntityType::isSpawnable).forEach(MOB_TYPES::add);
for (EntityType entityType : MOB_TYPES)
{
mobs.add(entityType.name());
}
return mobs;
}
PlexUtils.broadcast(messageComponent("removedMobs", sender.getName(), entityCount));
/*entityCounts.forEach((entityName, numRemoved) -> {
sender.sendMessage(messageComponent("removedEntitiesOfType", sender.getName(), numRemoved, entityName));
});*/
return null;
public @NotNull List<String> smartTabComplete(@NotNull CommandSender sender, @NotNull String alias, @NotNull String[] args) throws IllegalArgumentException
{
if (args.length == 1 && silentCheckPermission(sender, this.getPermission()))
{
return getAllMobs();
}
return Collections.emptyList();
}
}

View File

@ -7,7 +7,6 @@ import dev.plex.command.annotation.CommandPermissions;
import dev.plex.player.PlexPlayer;
import dev.plex.punishment.Punishment;
import dev.plex.punishment.PunishmentType;
import dev.plex.util.PlexUtils;
import dev.plex.util.TimeUtils;
import net.kyori.adventure.text.Component;
@ -39,7 +38,7 @@ public class MuteCMD extends PlexCommand
return messageComponent("playerMuted");
}
if (silentCheckPermission(player,"plex.mute"))
if (silentCheckPermission(player, "plex.mute"))
{
send(sender, messageComponent("higherRankThanYou"));
return null;
@ -60,8 +59,8 @@ public class MuteCMD extends PlexCommand
}
@Override
public @NotNull List<String> tabComplete(@NotNull CommandSender sender, @NotNull String alias, @NotNull String[] args) throws IllegalArgumentException
public @NotNull List<String> smartTabComplete(@NotNull CommandSender sender, @NotNull String alias, @NotNull String[] args) throws IllegalArgumentException
{
return args.length == 1 && silentCheckPermission(sender,"plex.mute") ? PlexUtils.getPlayerNameList() : ImmutableList.of();
return args.length == 1 && silentCheckPermission(sender, this.getPermission()) ? PlexUtils.getPlayerNameList() : ImmutableList.of();
}
}

View File

@ -6,7 +6,6 @@ import dev.plex.command.annotation.CommandParameters;
import dev.plex.command.annotation.CommandPermissions;
import dev.plex.player.PlexPlayer;
import dev.plex.punishment.extra.Note;
import dev.plex.util.PlexUtils;
import dev.plex.util.TimeUtils;
import net.kyori.adventure.text.Component;
@ -137,15 +136,19 @@ public class NotesCMD extends PlexCommand
}
@Override
public @NotNull List<String> tabComplete(@NotNull CommandSender sender, @NotNull String alias, @NotNull String[] args) throws IllegalArgumentException
public @NotNull List<String> smartTabComplete(@NotNull CommandSender sender, @NotNull String alias, @NotNull String[] args) throws IllegalArgumentException
{
if (args.length == 1)
if (silentCheckPermission(sender, this.getPermission()))
{
return PlexUtils.getPlayerNameList();
}
if (args.length == 2)
{
return Arrays.asList("list", "add", "remove", "clear");
if (args.length == 1)
{
return PlexUtils.getPlayerNameList();
}
if (args.length == 2)
{
return Arrays.asList("list", "add", "remove", "clear");
}
return Collections.emptyList();
}
return Collections.emptyList();
}

View File

@ -35,7 +35,7 @@ public class PlexCMD extends PlexCommand
if (args.length == 0)
{
send(sender, mmString("<light_purple>Plex - A new freedom plugin."));
send(sender, mmString("<light_purple>Plugin version: <gold>" + plugin.getDescription().getVersion() + " #" + BuildInfo.getNumber() + " <light_purple>Git: <gold>" + BuildInfo.getHead()));
send(sender, mmString("<light_purple>Plugin version: <gold>" + plugin.getDescription().getVersion() + " #" + BuildInfo.getNumber() + " <light_purple>Git: <gold>" + BuildInfo.getCommit()));
send(sender, mmString("<light_purple>Authors: <gold>Telesphoreo, Taahh"));
send(sender, mmString("<light_purple>Built by: <gold>" + BuildInfo.getAuthor() + " <light_purple>on <gold>" + BuildInfo.getDate()));
send(sender, mmString("<light_purple>Run <gold>/plex modules <light_purple>to see a list of modules."));
@ -126,7 +126,7 @@ public class PlexCMD extends PlexCommand
}
@Override
public @NotNull List<String> tabComplete(@NotNull CommandSender sender, @NotNull String alias, @NotNull String[] args) throws IllegalArgumentException
public @NotNull List<String> smartTabComplete(@NotNull CommandSender sender, @NotNull String alias, @NotNull String[] args) throws IllegalArgumentException
{
if (args.length == 1)
{

View File

@ -7,7 +7,6 @@ import dev.plex.command.annotation.CommandParameters;
import dev.plex.command.annotation.CommandPermissions;
import dev.plex.command.exception.PlayerNotFoundException;
import dev.plex.command.source.RequiredCommandSource;
import dev.plex.menu.impl.PunishedPlayerMenu;
import dev.plex.menu.impl.PunishmentMenu;
import dev.plex.player.PlexPlayer;
@ -50,8 +49,8 @@ public class PunishmentsCMD extends PlexCommand
}
@Override
public @NotNull List<String> tabComplete(@NotNull CommandSender sender, @NotNull String alias, @NotNull String[] args) throws IllegalArgumentException
public @NotNull List<String> smartTabComplete(@NotNull CommandSender sender, @NotNull String alias, @NotNull String[] args) throws IllegalArgumentException
{
return args.length == 1 ? PlexUtils.getPlayerNameList() : ImmutableList.of();
return args.length == 1 && silentCheckPermission(sender, this.getPermission()) ? PlexUtils.getPlayerNameList() : ImmutableList.of();
}
}

View File

@ -13,6 +13,9 @@ import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Collections;
import java.util.List;
@CommandPermissions(permission = "plex.rawsay", source = RequiredCommandSource.ANY)
@CommandParameters(name = "rawsay", usage = "/<command> <message>", description = "Displays a raw message to everyone")
public class RawSayCMD extends PlexCommand
@ -28,4 +31,10 @@ public class RawSayCMD extends PlexCommand
PlexUtils.broadcast(StringUtils.join(args, " "));
return null;
}
@Override
public @NotNull List<String> smartTabComplete(@NotNull CommandSender sender, @NotNull String alias, @NotNull String[] args) throws IllegalArgumentException
{
return Collections.emptyList();
}
}

View File

@ -1,17 +1,21 @@
package dev.plex.command.impl;
import com.google.common.collect.ImmutableList;
import dev.plex.cache.DataUtils;
import dev.plex.command.PlexCommand;
import dev.plex.command.annotation.CommandParameters;
import dev.plex.command.annotation.CommandPermissions;
import dev.plex.command.source.RequiredCommandSource;
import dev.plex.player.PlexPlayer;
import dev.plex.util.PlexUtils;
import net.kyori.adventure.text.Component;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.List;
@CommandPermissions(permission = "plex.removeloginmessage", source = RequiredCommandSource.ANY)
@CommandParameters(name = "removeloginmessage", usage = "/<command> [-o <player>]", description = "Remove your own (or someone else's) login message", aliases = "rlm,removeloginmsg")
public class RemoveLoginMessageCMD extends PlexCommand
@ -51,4 +55,17 @@ public class RemoveLoginMessageCMD extends PlexCommand
}
return null;
}
@Override
public @NotNull List<String> smartTabComplete(@NotNull CommandSender sender, @NotNull String alias, @NotNull String[] args) throws IllegalArgumentException
{
if (args.length == 1)
{
if (silentCheckPermission(sender, "plex.removeloginmessage.others"))
{
return List.of("-o");
}
}
return args.length == 2 && silentCheckPermission(sender, "plex.removeloginmessage.others") ? PlexUtils.getPlayerNameList() : ImmutableList.of();
}
}

View File

@ -4,7 +4,6 @@ import dev.plex.command.PlexCommand;
import dev.plex.command.annotation.CommandParameters;
import dev.plex.command.annotation.CommandPermissions;
import dev.plex.command.source.RequiredCommandSource;
import dev.plex.util.PlexUtils;
import net.kyori.adventure.text.Component;
import org.apache.commons.lang3.StringUtils;
@ -13,6 +12,9 @@ import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Collections;
import java.util.List;
@CommandPermissions(permission = "plex.say", source = RequiredCommandSource.ANY)
@CommandParameters(name = "say", usage = "/<command> <message>", description = "Displays a message to everyone")
public class SayCMD extends PlexCommand
@ -28,4 +30,10 @@ public class SayCMD extends PlexCommand
PlexUtils.broadcast(PlexUtils.messageComponent("sayMessage", sender.getName(), PlexUtils.mmStripColor(StringUtils.join(args, " "))));
return null;
}
@Override
public @NotNull List<String> smartTabComplete(@NotNull CommandSender sender, @NotNull String alias, @NotNull String[] args) throws IllegalArgumentException
{
return Collections.emptyList();
}
}

View File

@ -1,5 +1,6 @@
package dev.plex.command.impl;
import com.google.common.collect.ImmutableList;
import dev.plex.cache.DataUtils;
import dev.plex.command.PlexCommand;
import dev.plex.command.annotation.CommandParameters;
@ -16,6 +17,8 @@ import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.List;
@CommandPermissions(permission = "plex.setloginmessage", source = RequiredCommandSource.ANY)
@CommandParameters(name = "setloginmessage", usage = "/<command> [-o <player>] <message>", description = "Sets your (or someone else's) login message", aliases = "slm,setloginmsg")
public class SetLoginMessageCMD extends PlexCommand
@ -79,4 +82,17 @@ public class SetLoginMessageCMD extends PlexCommand
throw new CommandFailException(messageString("nameRequired"));
}
}
@Override
public @NotNull List<String> smartTabComplete(@NotNull CommandSender sender, @NotNull String alias, @NotNull String[] args) throws IllegalArgumentException
{
if (args.length == 1)
{
if (silentCheckPermission(sender, "plex.setloginmessage"))
{
return List.of("-o");
}
}
return args.length == 2 && args[0].equalsIgnoreCase("-o") && silentCheckPermission(sender, "plex.setloginmessage") ? PlexUtils.getPlayerNameList() : ImmutableList.of();
}
}

View File

@ -7,7 +7,6 @@ import dev.plex.command.source.RequiredCommandSource;
import dev.plex.player.PlexPlayer;
import dev.plex.punishment.Punishment;
import dev.plex.punishment.PunishmentType;
import dev.plex.util.PlexUtils;
import dev.plex.util.TimeUtils;
import net.kyori.adventure.text.Component;
@ -136,9 +135,9 @@ public class SmiteCMD extends PlexCommand
}
@Override
public @NotNull List<String> tabComplete(@NotNull CommandSender sender, @NotNull String alias, @NotNull String[] args) throws IllegalArgumentException
public @NotNull List<String> smartTabComplete(@NotNull CommandSender sender, @NotNull String alias, @NotNull String[] args) throws IllegalArgumentException
{
if (silentCheckPermission(sender,"plex.smite") && args.length == 1)
if (silentCheckPermission(sender, this.getPermission()) && args.length == 1)
{
return PlexUtils.getPlayerNameList();
}

View File

@ -56,7 +56,7 @@ public class SpectatorCMD extends PlexCommand
}
@Override
public @NotNull List<String> tabComplete(@NotNull CommandSender sender, @NotNull String alias, @NotNull String[] args) throws IllegalArgumentException
public @NotNull List<String> smartTabComplete(@NotNull CommandSender sender, @NotNull String alias, @NotNull String[] args) throws IllegalArgumentException
{
if (silentCheckPermission(sender,"plex.gamemode.spectator.others"))
{

View File

@ -57,7 +57,7 @@ public class SurvivalCMD extends PlexCommand
}
@Override
public @NotNull List<String> tabComplete(@NotNull CommandSender sender, @NotNull String alias, @NotNull String[] args) throws IllegalArgumentException
public @NotNull List<String> smartTabComplete(@NotNull CommandSender sender, @NotNull String alias, @NotNull String[] args) throws IllegalArgumentException
{
if (silentCheckPermission(sender,"plex.gamemode.survival.others"))
{

View File

@ -6,7 +6,6 @@ import dev.plex.command.annotation.CommandParameters;
import dev.plex.command.annotation.CommandPermissions;
import dev.plex.command.source.RequiredCommandSource;
import dev.plex.player.PlexPlayer;
import dev.plex.util.PlexUtils;
import dev.plex.util.minimessage.SafeMiniMessage;
import net.kyori.adventure.text.Component;
@ -19,6 +18,10 @@ import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
@CommandPermissions(permission = "plex.tag", source = RequiredCommandSource.ANY)
@CommandParameters(name = "tag", aliases = "prefix", description = "Set or clear your prefix", usage = "/<command> <set <prefix> | clear <player>>")
public class TagCMD extends PlexCommand
@ -80,7 +83,7 @@ public class TagCMD extends PlexCommand
DataUtils.update(player);
return messageComponent("prefixCleared");
}
checkPermission(sender,"plex.tag.clear.others");
checkPermission(sender, "plex.tag.clear.others");
Player target = getNonNullPlayer(args[1]);
PlexPlayer plexTarget = DataUtils.getPlayer(target.getUniqueId());
plexTarget.setPrefix(null);
@ -89,6 +92,26 @@ public class TagCMD extends PlexCommand
}
return usage();
}
@Override
public @NotNull List<String> smartTabComplete(@NotNull CommandSender sender, @NotNull String alias, @NotNull String[] args) throws IllegalArgumentException
{
if (args.length == 1)
{
return Arrays.asList("set", "clear");
}
if (args.length == 2)
{
if (args[0].equalsIgnoreCase("clear"))
{
if (silentCheckPermission(sender, "plex.tag.clear.others"))
{
return PlexUtils.getPlayerNameList();
}
}
}
return Collections.emptyList();
}
}

View File

@ -10,8 +10,8 @@ import dev.plex.command.source.RequiredCommandSource;
import dev.plex.player.PlexPlayer;
import dev.plex.punishment.Punishment;
import dev.plex.punishment.PunishmentType;
import dev.plex.util.BungeeUtil;
import dev.plex.util.PlexLog;
import dev.plex.util.PlexUtils;
import dev.plex.util.TimeUtils;
import net.kyori.adventure.text.Component;
@ -22,6 +22,7 @@ import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Collections;
import java.util.List;
@CommandParameters(name = "tempban", usage = "/<command> <player> <time> [reason]", description = "Temporarily ban a player")
@ -52,10 +53,13 @@ public class TempbanCMD extends PlexCommand
}
Punishment punishment = new Punishment(target.getUuid(), getUUID(sender));
punishment.setType(PunishmentType.TEMPBAN);
boolean rollBack = true;
if (args.length > 2)
{
reason = StringUtils.join(args, " ", 2, args.length);
punishment.setReason(reason);
String newReason = StringUtils.normalizeSpace(reason.replace("-nrb", ""));
punishment.setReason(newReason.trim().isEmpty() ? "No reason provided." : newReason);
rollBack = !reason.startsWith("-nrb") && !reason.endsWith("-nrb");
}
else
{
@ -75,12 +79,46 @@ public class TempbanCMD extends PlexCommand
{
BungeeUtil.kickPlayer(player, Punishment.generateBanMessage(punishment));
}
if (rollBack)
{
/*if (plugin.getPrismHook().hasPrism()) {
PrismParameters parameters = plugin.getPrismHook().prismApi().createParameters();
parameters.addActionType("block-place");
parameters.addActionType("block-break");
parameters.addActionType("block-burn");
parameters.addActionType("entity-spawn");
parameters.addActionType("entity-kill");
parameters.addActionType("entity-explode");
parameters.addPlayerName(plexPlayer.getName());
parameters.setBeforeTime(Instant.now().toEpochMilli());
parameters.setProcessType(PrismProcessType.ROLLBACK);
final Future<Result> result = plugin.getPrismHook().prismApi().performLookup(parameters, sender);
Bukkit.getAsyncScheduler().runNow(plugin, scheduledTask -> {
try
{
final Result done = result.get();
} catch (InterruptedException | ExecutionException e)
{
throw new RuntimeException(e);
}
});
}
else */
if (plugin.getCoreProtectHook().hasCoreProtect())
{
PlexLog.debug("Testing coreprotect");
Bukkit.getAsyncScheduler().runNow(plugin, scheduledTask ->
{
plugin.getCoreProtectHook().coreProtectAPI().performRollback(86400, Collections.singletonList(target.getName()), null, null, null, null, 0, null);
});
}
}
return null;
}
@Override
public @NotNull List<String> tabComplete(@NotNull CommandSender sender, @NotNull String alias, @NotNull String[] args) throws IllegalArgumentException
public @NotNull List<String> smartTabComplete(@NotNull CommandSender sender, @NotNull String alias, @NotNull String[] args) throws IllegalArgumentException
{
return args.length == 1 && silentCheckPermission(sender,"plex.tempban") ? PlexUtils.getPlayerNameList() : ImmutableList.of();
return args.length == 1 && silentCheckPermission(sender, this.getPermission()) ? PlexUtils.getPlayerNameList() : ImmutableList.of();
}
}

View File

@ -6,7 +6,6 @@ import dev.plex.command.annotation.CommandParameters;
import dev.plex.command.annotation.CommandPermissions;
import dev.plex.command.source.RequiredCommandSource;
import dev.plex.menu.impl.ToggleMenu;
import dev.plex.util.PlexUtils;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.format.NamedTextColor;
@ -64,9 +63,9 @@ public class ToggleCMD extends PlexCommand
}
@Override
public @NotNull List<String> tabComplete(@NotNull CommandSender sender, @NotNull String alias, @NotNull String[] args) throws IllegalArgumentException
public @NotNull List<String> smartTabComplete(@NotNull CommandSender sender, @NotNull String alias, @NotNull String[] args) throws IllegalArgumentException
{
return args.length == 1 ? PlexUtils.getPlayerNameList() : ImmutableList.of();
return args.length == 1 && silentCheckPermission(sender, this.getPermission()) ? PlexUtils.getPlayerNameList() : ImmutableList.of();
}
private String status(String toggle)

View File

@ -9,7 +9,6 @@ import dev.plex.command.exception.PlayerNotBannedException;
import dev.plex.command.exception.PlayerNotFoundException;
import dev.plex.command.source.RequiredCommandSource;
import dev.plex.player.PlexPlayer;
import dev.plex.util.PlexUtils;
import net.kyori.adventure.text.Component;
import org.bukkit.command.CommandSender;
@ -56,8 +55,8 @@ public class UnbanCMD extends PlexCommand
}
@Override
public @NotNull List<String> tabComplete(@NotNull CommandSender sender, @NotNull String alias, @NotNull String[] args) throws IllegalArgumentException
public @NotNull List<String> smartTabComplete(@NotNull CommandSender sender, @NotNull String alias, @NotNull String[] args) throws IllegalArgumentException
{
return args.length == 1 && silentCheckPermission(sender,"plex.unban") ? PlexUtils.getPlayerNameList() : ImmutableList.of();
return args.length == 1 && silentCheckPermission(sender, this.getPermission()) ? PlexUtils.getPlayerNameList() : ImmutableList.of();
}
}

View File

@ -6,7 +6,6 @@ import dev.plex.command.annotation.CommandParameters;
import dev.plex.command.annotation.CommandPermissions;
import dev.plex.command.exception.CommandFailException;
import dev.plex.player.PlexPlayer;
import dev.plex.util.PlexUtils;
import net.kyori.adventure.text.Component;
import org.bukkit.command.CommandSender;
@ -39,8 +38,8 @@ public class UnfreezeCMD extends PlexCommand
}
@Override
public @NotNull List<String> tabComplete(@NotNull CommandSender sender, @NotNull String alias, @NotNull String[] args) throws IllegalArgumentException
public @NotNull List<String> smartTabComplete(@NotNull CommandSender sender, @NotNull String alias, @NotNull String[] args) throws IllegalArgumentException
{
return args.length == 1 && silentCheckPermission(sender,"plex.unfreeze") ? PlexUtils.getPlayerNameList() : ImmutableList.of();
return args.length == 1 && silentCheckPermission(sender, this.getPermission()) ? PlexUtils.getPlayerNameList() : ImmutableList.of();
}
}

View File

@ -6,7 +6,6 @@ import dev.plex.command.annotation.CommandParameters;
import dev.plex.command.annotation.CommandPermissions;
import dev.plex.command.exception.CommandFailException;
import dev.plex.player.PlexPlayer;
import dev.plex.util.PlexUtils;
import net.kyori.adventure.text.Component;
import org.bukkit.command.CommandSender;
@ -39,8 +38,8 @@ public class UnmuteCMD extends PlexCommand
}
@Override
public @NotNull List<String> tabComplete(@NotNull CommandSender sender, @NotNull String alias, @NotNull String[] args) throws IllegalArgumentException
public @NotNull List<String> smartTabComplete(@NotNull CommandSender sender, @NotNull String alias, @NotNull String[] args) throws IllegalArgumentException
{
return args.length == 1 && silentCheckPermission(sender,"plex.unfreeze") ? PlexUtils.getPlayerNameList() : ImmutableList.of();
return args.length == 1 && silentCheckPermission(sender, this.getPermission()) ? PlexUtils.getPlayerNameList() : ImmutableList.of();
}
}

View File

@ -45,8 +45,8 @@ public class WhoHasCMD extends PlexCommand
}
@Override
public @NotNull List<String> tabComplete(@NotNull CommandSender sender, @NotNull String alias, @NotNull String[] args) throws IllegalArgumentException
public @NotNull List<String> smartTabComplete(@NotNull CommandSender sender, @NotNull String alias, @NotNull String[] args) throws IllegalArgumentException
{
return args.length == 1 && silentCheckPermission(sender, "plex.whohas") ? Arrays.stream(Material.values()).map(Enum::name).toList() : ImmutableList.of();
return args.length == 1 && silentCheckPermission(sender, this.getPermission()) ? Arrays.stream(Material.values()).map(Enum::name).toList() : ImmutableList.of();
}
}

View File

@ -6,7 +6,6 @@ import dev.plex.command.PlexCommand;
import dev.plex.command.annotation.CommandParameters;
import dev.plex.command.annotation.CommandPermissions;
import dev.plex.command.source.RequiredCommandSource;
import net.kyori.adventure.text.Component;
import org.bukkit.Bukkit;
import org.bukkit.World;
@ -38,19 +37,18 @@ public class WorldCMD extends PlexCommand
boolean playerWorld = args[0].matches("[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}");
if (playerWorld && Plex.get().getModuleManager().getModules().stream().anyMatch(plexModule -> plexModule.getPlexModuleFile().getName().equalsIgnoreCase("Module-TFMExtras")))
{
checkPermission(playerSender,"plex.world.playerworlds");
checkPermission(playerSender, "plex.world.playerworlds");
}
playerSender.teleportAsync(world.getSpawnLocation());
return messageComponent("playerWorldTeleport", world.getName());
}
@Override
public @NotNull List<String> tabComplete(@NotNull CommandSender sender, @NotNull String alias, @NotNull String[] args) throws IllegalArgumentException
public @NotNull List<String> smartTabComplete(@NotNull CommandSender sender, @NotNull String alias, @NotNull String[] args) throws IllegalArgumentException
{
final List<String> completions = Lists.newArrayList();
final Player player = (Player) sender;
if (args.length == 1)
if (args.length == 1 && silentCheckPermission(sender, this.getPermission()))
{
@NotNull List<World> worlds = Bukkit.getWorlds();
for (World world : worlds)
@ -60,7 +58,7 @@ public class WorldCMD extends PlexCommand
try
{
final UUID uuid = UUID.fromString(worldName);
if (uuid.equals(player.getUniqueId()) || silentCheckPermission(player,"plex.world.playerworlds"))
if (uuid.equals(player.getUniqueId()) || silentCheckPermission(player, "plex.world.playerworlds"))
{
completions.add(worldName);
}

View File

@ -0,0 +1,30 @@
package dev.plex.event;
import lombok.Data;
import lombok.EqualsAndHashCode;
import net.kyori.adventure.text.Component;
import org.bukkit.event.Event;
import org.bukkit.event.HandlerList;
import org.jetbrains.annotations.NotNull;
@EqualsAndHashCode(callSuper = false)
@Data
public class BroadcastEvent extends Event
{
private static final HandlerList handlers = new HandlerList();
private final Component message;
private final String string;
public static HandlerList getHandlerList()
{
return handlers;
}
@Override
public @NotNull HandlerList getHandlers()
{
return handlers;
}
}

View File

@ -0,0 +1,63 @@
package dev.plex.hook;
import dev.plex.Plex;
import dev.plex.player.PlexPlayer;
import dev.plex.util.PlexLog;
import dev.plex.util.PlexUtils;
import dev.plex.util.minimessage.SafeMiniMessage;
import net.coreprotect.CoreProtect;
import net.coreprotect.CoreProtectAPI;
import net.kyori.adventure.text.Component;
import net.milkbowl.vault.chat.Chat;
import net.milkbowl.vault.permission.Permission;
import org.bukkit.Bukkit;
import org.bukkit.OfflinePlayer;
import org.bukkit.plugin.Plugin;
import org.bukkit.plugin.RegisteredServiceProvider;
import java.util.UUID;
public class CoreProtectHook
{
private CoreProtectAPI coreProtectAPI;
private boolean hasApi;
public CoreProtectHook(Plex plex)
{
Plugin plugin = plex.getServer().getPluginManager().getPlugin("CoreProtect");
// Check that CoreProtect is loaded
if (!(plugin instanceof CoreProtect))
{
PlexLog.debug("Plugin was not CoreProtect.");
return;
}
// Check that the API is enabled
CoreProtectAPI coreProtectAPI = ((CoreProtect) plugin).getAPI();
this.hasApi = coreProtectAPI.isEnabled();
if (!hasApi)
{
PlexLog.debug("CoreProtect API was disabled.");
return;
}
// Check that a compatible version of the API is loaded
if (coreProtectAPI.APIVersion() < 9)
{
PlexLog.debug("CoreProtect API version is: {0}", coreProtectAPI.APIVersion());
return;
}
this.coreProtectAPI = coreProtectAPI;
this.coreProtectAPI.testAPI();
}
public boolean hasCoreProtect() {
return hasApi;
}
public CoreProtectAPI coreProtectAPI()
{
return coreProtectAPI;
}
}

View File

@ -0,0 +1,34 @@
package dev.plex.hook;
import dev.plex.Plex;
import network.darkhelmet.prism.api.PrismApi;
import org.bukkit.plugin.Plugin;
public class PrismHook
{
private PrismApi prismApi;
public PrismHook(Plex plex)
{
Plugin plugin = plex.getServer().getPluginManager().getPlugin("Prism");
// Check that Prism is loaded
if (!plugin.isEnabled())
{
return;
}
// Check that the API is enabled
this.prismApi = (PrismApi) plugin;
}
public boolean hasPrism() {
return prismApi != null;
}
public PrismApi prismApi()
{
return prismApi;
}
}

View File

@ -7,6 +7,8 @@ import dev.plex.player.PlexPlayer;
import dev.plex.punishment.Punishment;
import dev.plex.punishment.PunishmentManager;
import dev.plex.punishment.PunishmentType;
import dev.plex.util.PlexLog;
import it.unimi.dsi.fastutil.Pair;
import org.bukkit.Bukkit;
import org.bukkit.event.EventHandler;
import org.bukkit.event.player.AsyncPlayerPreLoginEvent;
@ -43,11 +45,26 @@ public class BanListener extends PlexListener
if (plugin.getPunishmentManager().isBanned(event.getUniqueId()))
{
if (Plex.get().getPermissions() != null && Plex.get().getPermissions().playerHas(null, Bukkit.getOfflinePlayer(event.getUniqueId()), "plex.ban.bypass")) return;
if (Plex.get().getPermissions() != null && Plex.get().getPermissions().playerHas(null, Bukkit.getOfflinePlayer(event.getUniqueId()), "plex.ban.bypass"))
{
return;
}
PlexPlayer player = DataUtils.getPlayer(event.getUniqueId());
player.getPunishments().stream().filter(punishment -> (punishment.getType() == PunishmentType.BAN || punishment.getType() == PunishmentType.TEMPBAN) && punishment.isActive()).findFirst().ifPresent(punishment ->
event.disallow(AsyncPlayerPreLoginEvent.Result.KICK_BANNED,
Punishment.generateBanMessage(punishment)));
return;
}
Punishment ipBannedPunishment = plugin.getPunishmentManager().getBanByIP(event.getAddress().getHostAddress());
if (ipBannedPunishment != null)
{
// Don't check if the other account that's banned has bypass abilities, check if current has only
if (Plex.get().getPermissions() != null && Plex.get().getPermissions().playerHas(null, Bukkit.getOfflinePlayer(event.getUniqueId()), "plex.ban.bypass"))
{
return;
}
event.disallow(AsyncPlayerPreLoginEvent.Result.KICK_BANNED,
Punishment.generateBanMessage(ipBannedPunishment));
}
}
}

View File

@ -13,7 +13,6 @@ import org.bukkit.Bukkit;
public class PlayerMeta
{
public static Component getPrefix(PlexPlayer plexPlayer)
{
if (plexPlayer.getPrefix() != null && !plexPlayer.getPrefix().isEmpty())

View File

@ -3,21 +3,14 @@ package dev.plex.punishment;
import com.google.common.collect.Lists;
import com.google.common.reflect.TypeToken;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import dev.plex.Plex;
import dev.plex.PlexBase;
import dev.plex.cache.DataUtils;
import dev.plex.player.PlexPlayer;
import dev.plex.storage.StorageType;
import dev.plex.util.PlexLog;
import dev.plex.util.PlexUtils;
import dev.plex.util.TimeUtils;
import lombok.Data;
import lombok.Getter;
import org.apache.commons.io.FileUtils;
import org.bukkit.Bukkit;
import org.bukkit.scheduler.BukkitRunnable;
import org.jetbrains.annotations.Nullable;
import java.io.File;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
@ -28,7 +21,17 @@ import java.util.Collection;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.CompletableFuture;
import java.util.stream.Collectors;
import java.util.concurrent.atomic.AtomicReference;
import java.util.function.Consumer;
import dev.plex.util.adapter.ZonedDateTimeAdapter;
import it.unimi.dsi.fastutil.Pair;
import lombok.Data;
import lombok.Getter;
import org.apache.commons.io.FileUtils;
import org.bukkit.Bukkit;
import org.bukkit.scheduler.BukkitRunnable;
import org.jetbrains.annotations.Nullable;
public class PunishmentManager implements PlexBase
{
@ -135,7 +138,6 @@ public class PunishmentManager implements PlexBase
public boolean isBanned(UUID uuid)
{
// TODO: If a person is using MongoDB, this will error out because it is checking for bans on a player that doesn't exist yet
if (!DataUtils.hasPlayedBefore(uuid))
{
return false;
@ -143,6 +145,12 @@ public class PunishmentManager implements PlexBase
return DataUtils.getPlayer(uuid).getPunishments().stream().anyMatch(punishment -> (punishment.getType() == PunishmentType.BAN || punishment.getType() == PunishmentType.TEMPBAN) && punishment.isActive());
}
public Punishment getBanByIP(String ip)
{
final Gson gson = new GsonBuilder().registerTypeAdapter(ZonedDateTime.class, new ZonedDateTimeAdapter()).setPrettyPrinting().create();
return plugin.getSqlPunishment().getPunishments(ip).stream().filter(punishment -> punishment.getType() == PunishmentType.TEMPBAN || punishment.getType() == PunishmentType.BAN).filter(Punishment::isActive).filter(punishment -> punishment.getIp().equals(ip)).findFirst().orElse(null);
}
public boolean isBanned(PlexPlayer player)
{
return isBanned(player.getUuid());

View File

@ -21,6 +21,7 @@ import java.util.concurrent.CompletableFuture;
public class SQLPunishment
{
private static final String SELECT = "SELECT * FROM `punishments` WHERE punished=?";
private static final String SELECT_BY_IP = "SELECT * FROM `punishments` WHERE ip=?";
private static final String SELECT_BY = "SELECT * FROM `punishments` WHERE punisher=?";
private static final String INSERT = "INSERT INTO `punishments` (`punished`, `punisher`, `punishedUsername`, `ip`, `type`, `reason`, `customTime`, `active`, `endDate`) VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?)";
@ -84,6 +85,33 @@ public class SQLPunishment
}
return punishments;
}
public List<Punishment> getPunishments(String ip)
{
List<Punishment> punishments = Lists.newArrayList();
try (Connection con = Plex.get().getSqlConnection().getCon())
{
PreparedStatement statement = con.prepareStatement(SELECT_BY_IP);
statement.setString(1, ip);
ResultSet set = statement.executeQuery();
while (set.next())
{
Punishment punishment = new Punishment(UUID.fromString(set.getString("punished")), set.getString("punisher") == null ? null : UUID.fromString(set.getString("punisher")));
punishment.setActive(set.getBoolean("active"));
punishment.setType(PunishmentType.valueOf(set.getString("type")));
punishment.setCustomTime(set.getBoolean("customTime"));
punishment.setPunishedUsername(set.getString("punishedUsername"));
punishment.setEndDate(ZonedDateTime.ofInstant(Instant.ofEpochMilli(set.getLong("endDate")), ZoneId.of(TimeUtils.TIMEZONE)));
punishment.setReason(set.getString("reason"));
punishment.setIp(set.getString("ip"));
punishments.add(punishment);
}
}
catch (SQLException e)
{
e.printStackTrace();
}
return punishments;
}
public CompletableFuture<Void> insertPunishment(Punishment punishment)
{

View File

@ -8,30 +8,30 @@ import java.util.Properties;
public class BuildInfo
{
@Getter
public static String number;
@Getter
public static String author;
@Getter
public static String commit;
@Getter
public static String date;
@Getter
public static String head;
public static String number;
public void load(Plex plugin)
{
try
{
Properties props;
try (InputStream in = plugin.getResource("build.properties"))
try (InputStream in = plugin.getResource("build-vars.properties"))
{
props = new Properties();
props.load(in);
}
author = props.getProperty("author", "unknown");
commit = props.getProperty("gitCommit", "unknown");
date = props.getProperty("date", "unknown");
number = props.getProperty("buildNumber", "unknown");
author = props.getProperty("buildAuthor", "unknown");
date = props.getProperty("buildDate", "unknown");
head = props.getProperty("buildHead", "unknown");
}
catch (Exception ignored)
{

View File

@ -4,6 +4,7 @@ import com.google.common.base.CharMatcher;
import com.google.common.collect.Lists;
import dev.plex.Plex;
import dev.plex.PlexBase;
import dev.plex.event.BroadcastEvent;
import dev.plex.listener.impl.ChatListener;
import dev.plex.storage.StorageType;
import net.kyori.adventure.text.Component;
@ -274,11 +275,13 @@ public class PlexUtils implements PlexBase
public static void broadcast(String s)
{
Bukkit.broadcast(MINI_MESSAGE.deserialize(s));
Bukkit.getServer().getPluginManager().callEvent(new BroadcastEvent(null, s));
}
public static void broadcast(Component component)
{
Bukkit.broadcast(component);
Bukkit.getServer().getPluginManager().callEvent(new BroadcastEvent(component, null));
}
public static void broadcastToAdmins(Component component, String permission)

View File

@ -96,7 +96,7 @@ public class UpdateChecker implements PlexBase
// If it's -4, it hasn't checked for updates yet
if (distance == -4)
{
distance = fetchDistanceFromGitHub(REPO, BRANCH, BuildInfo.getHead());
distance = fetchDistanceFromGitHub(REPO, BRANCH, BuildInfo.getCommit());
PlexLog.debug("Never checked for updates, checking now...");
}
else
@ -104,7 +104,7 @@ public class UpdateChecker implements PlexBase
// If the request isn't asked to be cached, fetch it
if (!cached)
{
distance = fetchDistanceFromGitHub(REPO, BRANCH, BuildInfo.getHead());
distance = fetchDistanceFromGitHub(REPO, BRANCH, BuildInfo.getCommit());
PlexLog.debug("We have checked for updates before, but this request was not asked to be cached.");
}
else

View File

@ -0,0 +1,7 @@
author={{ author | default("unknown") }}
buildNumber={{ buildNumber | default("unknown") }}
date={{ date }}
gitCommit={{ gitCommit | default("unknown") }}

View File

@ -160,6 +160,11 @@ removedEntitiesOfType: "<gray>Removed {1} {2}"
# 0 - Entity type that is invalid
invalidEntityType: "<gray>Notice: Entity type {0} is invalid!"
noRemovedEntities: "<gray>No entities were removed."
# 0 - Number of mobs removed
# 1 - Type of mob removed
amountOfMobsRemoved: "<gray>{0} {1} removed."
notAValidMob: "<red>That is not a valid mob."
notAValidMobButValidEntity: "<red>That is a valid entity, but is not a valid mob."
# 0 - The command sender
# 1 - Number of mobs removed
removedMobs: "<red>{0} - Removed {1} mobs"

View File

@ -1,4 +0,0 @@
rootProject.name = "Plex"
include 'server'
include 'proxy'

2
settings.gradle.kts Normal file
View File

@ -0,0 +1,2 @@
rootProject.name = "Plex"
include("server", "proxy")