20 Commits

Author SHA1 Message Date
6b7c076c41 Revert "Add BroadcastEvent"
This reverts commit aab5083f78.
2024-01-26 17:13:11 -06:00
7b56bd70e9 Revert "attempt to add discordsrv"
This reverts commit 912dff0ec9.
2024-01-26 17:13:08 -06:00
fbd36161d4 Better legacy component support, removes SignListener (#81)
* Better legacy component support, removes SignListener

* Removes unused imports
2024-01-26 17:12:17 -06:00
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
66 changed files with 952 additions and 458 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 distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists 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 networkTimeout=10000
validateDistributionUrl=true validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME

View File

@ -1,7 +1,3 @@
plugins {
id("net.kyori.blossom") version "1.3.1"
}
group = rootProject.group group = rootProject.group
version = rootProject.version version = rootProject.version
description = "Plex-Velocity" description = "Plex-Velocity"
@ -24,8 +20,14 @@ tasks {
} }
} }
blossom { sourceSets {
replaceToken("@version@", rootProject.version) main {
blossom {
javaSources {
property("version", project.version.toString())
}
}
}
} }
publishing { publishing {

View File

@ -0,0 +1,5 @@
package dev.plex;
class BuildParameters {
public static final String VERSION = "{{ version }}";
}

View File

@ -28,7 +28,7 @@ import java.util.logging.Logger;
@Plugin( @Plugin(
name = "Plex", name = "Plex",
id = "plex", id = "plex",
version = "@version@", version = BuildParameters.VERSION,
url = "https://plex.us.org", url = "https://plex.us.org",
description = "Plex provides a new experience for freedom servers.", description = "Plex provides a new experience for freedom servers.",
authors = {"Telesphoreo", "Taah"} authors = {"Telesphoreo", "Taah"}

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]
}
}
}

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

@ -0,0 +1,158 @@
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("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; package dev.plex;
import com.google.common.collect.Lists;
import dev.plex.cache.DataUtils; import dev.plex.cache.DataUtils;
import dev.plex.cache.PlayerCache; import dev.plex.cache.PlayerCache;
import dev.plex.config.Config; import dev.plex.config.Config;
import dev.plex.handlers.CommandHandler; import dev.plex.handlers.CommandHandler;
import dev.plex.handlers.ListenerHandler; import dev.plex.handlers.ListenerHandler;
import dev.plex.hook.CoreProtectHook;
import dev.plex.hook.PrismHook;
import dev.plex.module.ModuleManager; import dev.plex.module.ModuleManager;
import dev.plex.player.PlexPlayer; import dev.plex.player.PlexPlayer;
import dev.plex.punishment.PunishmentManager; import dev.plex.punishment.PunishmentManager;
@ -16,22 +17,23 @@ import dev.plex.storage.StorageType;
import dev.plex.storage.player.SQLPlayerData; import dev.plex.storage.player.SQLPlayerData;
import dev.plex.storage.punishment.SQLNotes; import dev.plex.storage.punishment.SQLNotes;
import dev.plex.storage.punishment.SQLPunishment; 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.redis.MessageUtil;
import dev.plex.util.sql.SQLUtil;
import dev.plex.world.CustomWorld; import dev.plex.world.CustomWorld;
import java.io.File;
import lombok.Getter; import lombok.Getter;
import lombok.Setter; import lombok.Setter;
import net.milkbowl.vault.chat.Chat; import net.milkbowl.vault.chat.Chat;
import net.milkbowl.vault.permission.Permission; import net.milkbowl.vault.permission.Permission;
import org.apache.commons.lang3.StringUtils;
import org.bstats.bukkit.Metrics; import org.bstats.bukkit.Metrics;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.plugin.RegisteredServiceProvider; import org.bukkit.plugin.RegisteredServiceProvider;
import org.bukkit.plugin.java.JavaPlugin; import org.bukkit.plugin.java.JavaPlugin;
import java.io.File;
@Getter @Getter
@Setter @Setter
public class Plex extends JavaPlugin public class Plex extends JavaPlugin
@ -46,7 +48,6 @@ public class Plex extends JavaPlugin
public File modulesFolder; public File modulesFolder;
private StorageType storageType = StorageType.SQLITE; private StorageType storageType = StorageType.SQLITE;
private SQLConnection sqlConnection; private SQLConnection sqlConnection;
// private MongoConnection mongoConnection;
private RedisConnection redisConnection; private RedisConnection redisConnection;
private PlayerCache playerCache; private PlayerCache playerCache;
@ -63,6 +64,9 @@ public class Plex extends JavaPlugin
private Permission permissions; private Permission permissions;
private Chat chat; private Chat chat;
private CoreProtectHook coreProtectHook;
private PrismHook prismHook;
public static Plex get() public static Plex get()
{ {
return plugin; return plugin;
@ -124,12 +128,31 @@ public class Plex extends JavaPlugin
if (!getServer().getPluginManager().isPluginEnabled("Vault")) 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(); permissions = setupPermissions();
chat = setupChat(); 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(); updateChecker = new UpdateChecker();
PlexLog.log("Update checking enabled"); PlexLog.log("Update checking enabled");

View File

@ -29,9 +29,9 @@ public class PlexLibraryManager implements PluginLoader
// The plugin is null, a hacky way to check whether to load Jetty or not // 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()) 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-server:11.0.19"), 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-servlet:11.0.19"), 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-proxy:11.0.19"), null));
} }
classpathBuilder.addLibrary(resolver); classpathBuilder.addLibrary(resolver);
} }

View File

@ -1,5 +1,6 @@
package dev.plex.command; package dev.plex.command;
import com.google.common.collect.Lists;
import dev.plex.Plex; import dev.plex.Plex;
import dev.plex.cache.DataUtils; import dev.plex.cache.DataUtils;
import dev.plex.command.annotation.CommandParameters; 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.format.NamedTextColor;
import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer; import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.World; import org.bukkit.World;
import org.bukkit.command.*; import org.bukkit.command.*;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.util.StringUtil;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import java.util.Arrays; import java.util.Arrays;
import java.util.List;
import java.util.UUID; import java.util.UUID;
/** /**
@ -61,6 +63,7 @@ public abstract class PlexCommand extends Command implements PluginIdentifiableC
setName(this.params.name()); setName(this.params.name());
setLabel(this.params.name()); setLabel(this.params.name());
setDescription(params.description()); setDescription(params.description());
setPermission(this.perms.permission());
setUsage(params.usage().replace("<command>", this.params.name())); setUsage(params.usage().replace("<command>", this.params.name()));
if (params.aliases().split(",").length > 0) if (params.aliases().split(",").length > 0)
{ {
@ -74,7 +77,8 @@ public abstract class PlexCommand extends Command implements PluginIdentifiableC
{ {
getMap().getKnownCommands().remove(this.getName().toLowerCase()); getMap().getKnownCommands().remove(this.getName().toLowerCase());
} }
this.getAliases().forEach(s -> { this.getAliases().forEach(s ->
{
if (getMap().getKnownCommands().containsKey(s.toLowerCase())) if (getMap().getKnownCommands().containsKey(s.toLowerCase()))
{ {
getMap().getKnownCommands().remove(s.toLowerCase()); getMap().getKnownCommands().remove(s.toLowerCase());
@ -166,6 +170,17 @@ public abstract class PlexCommand extends Command implements PluginIdentifiableC
return true; 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 * 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); 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 * Gets the UUID of the sender
* *

View File

@ -1,6 +1,5 @@
package dev.plex.command.impl; package dev.plex.command.impl;
import dev.plex.cache.DataUtils;
import dev.plex.command.PlexCommand; import dev.plex.command.PlexCommand;
import dev.plex.command.annotation.CommandParameters; import dev.plex.command.annotation.CommandParameters;
import dev.plex.command.annotation.CommandPermissions; 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.minimessage.SafeMiniMessage;
import dev.plex.util.redis.MessageUtil; import dev.plex.util.redis.MessageUtil;
import net.kyori.adventure.text.Component; 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.BooleanUtils;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
@ -21,6 +18,8 @@ import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import java.util.Collections;
import java.util.List;
import java.util.UUID; import java.util.UUID;
@CommandPermissions(permission = "plex.adminchat", source = RequiredCommandSource.ANY) @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)); MessageUtil.sendStaffChat(sender, SafeMiniMessage.mmDeserialize(message), PlexUtils.adminChat(sender.getName(), prefix, message).toArray(UUID[]::new));
return null; 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.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import java.util.Collections;
import java.util.List;
@CommandPermissions(permission = "plex.adminworld", source = RequiredCommandSource.IN_GAME) @CommandPermissions(permission = "plex.adminworld", source = RequiredCommandSource.IN_GAME)
@CommandParameters(name = "adminworld", aliases = "aw", description = "Teleport to the adminworld") @CommandParameters(name = "adminworld", aliases = "aw", description = "Teleport to the adminworld")
public class AdminworldCMD extends PlexCommand public class AdminworldCMD extends PlexCommand
@ -29,4 +32,10 @@ public class AdminworldCMD extends PlexCommand
} }
return null; 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 @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")) if (silentCheckPermission(sender, "plex.gamemode.adventure.others"))
{ {

View File

@ -1,6 +1,5 @@
package dev.plex.command.impl; package dev.plex.command.impl;
import com.google.common.collect.ImmutableList;
import dev.plex.Plex; import dev.plex.Plex;
import dev.plex.cache.DataUtils; import dev.plex.cache.DataUtils;
import dev.plex.command.PlexCommand; import dev.plex.command.PlexCommand;
@ -11,8 +10,21 @@ import dev.plex.command.source.RequiredCommandSource;
import dev.plex.player.PlexPlayer; import dev.plex.player.PlexPlayer;
import dev.plex.punishment.Punishment; import dev.plex.punishment.Punishment;
import dev.plex.punishment.PunishmentType; 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 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.apache.commons.lang3.StringUtils;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
@ -20,11 +32,7 @@ import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import java.time.ZoneId; @CommandParameters(name = "ban", usage = "/<command> <player> [-nrb] [reason] [-nrb]", aliases = "offlineban,gtfo", description = "Bans a player, offline or online")
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")
@CommandPermissions(permission = "plex.ban", source = RequiredCommandSource.ANY) @CommandPermissions(permission = "plex.ban", source = RequiredCommandSource.ANY)
public class BanCMD extends PlexCommand public class BanCMD extends PlexCommand
@ -56,10 +64,13 @@ public class BanCMD extends PlexCommand
String reason; String reason;
Punishment punishment = new Punishment(plexPlayer.getUuid(), getUUID(sender)); Punishment punishment = new Punishment(plexPlayer.getUuid(), getUUID(sender));
punishment.setType(PunishmentType.BAN); punishment.setType(PunishmentType.BAN);
boolean rollBack = true;
if (args.length > 1) if (args.length > 1)
{ {
reason = StringUtils.join(args, " ", 1, args.length); 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 else
{ {
@ -70,10 +81,7 @@ public class BanCMD extends PlexCommand
punishment.setEndDate(date.plusDays(1)); punishment.setEndDate(date.plusDays(1));
punishment.setCustomTime(false); punishment.setCustomTime(false);
punishment.setActive(true); punishment.setActive(true);
if (player != null) punishment.setIp(player != null ? player.getAddress().getAddress().getHostAddress().trim() : plexPlayer.getIps().get(plexPlayer.getIps().size() - 1));
{
punishment.setIp(player.getAddress().getAddress().getHostAddress().trim());
}
plugin.getPunishmentManager().punish(plexPlayer, punishment); plugin.getPunishmentManager().punish(plexPlayer, punishment);
PlexUtils.broadcast(messageComponent("banningPlayer", sender.getName(), plexPlayer.getName())); PlexUtils.broadcast(messageComponent("banningPlayer", sender.getName(), plexPlayer.getName()));
Bukkit.getScheduler().runTask(Plex.get(), () -> Bukkit.getScheduler().runTask(Plex.get(), () ->
@ -84,14 +92,59 @@ public class BanCMD extends PlexCommand
} }
}); });
PlexLog.debug("(From /ban command) PunishedPlayer UUID: " + plexPlayer.getUuid()); 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; return null;
} }
@Override @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.NotNull;
import org.jetbrains.annotations.Nullable; 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") @CommandPermissions(permission = "plex.blockedit")
@CommandParameters(name = "blockedit", usage = "/<command> [list | purge | all | <player>]", aliases = "bedit", description = "Prevent players from modifying blocks") @CommandParameters(name = "blockedit", usage = "/<command> [list | purge | all | <player>]", aliases = "bedit", description = "Prevent players from modifying blocks")
public class BlockEditCMD extends PlexCommand public class BlockEditCMD extends PlexCommand
@ -94,4 +99,20 @@ public class BlockEditCMD extends PlexCommand
} }
return null; 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.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import java.util.Collections;
import java.util.List;
@CommandPermissions(permission = "plex.commandspy", source = RequiredCommandSource.IN_GAME) @CommandPermissions(permission = "plex.commandspy", source = RequiredCommandSource.IN_GAME)
@CommandParameters(name = "commandspy", aliases = "cmdspy", description = "Spy on other player's commands") @CommandParameters(name = "commandspy", aliases = "cmdspy", description = "Spy on other player's commands")
public class CommandSpyCMD extends PlexCommand public class CommandSpyCMD extends PlexCommand
@ -30,4 +33,10 @@ public class CommandSpyCMD extends PlexCommand
} }
return null; 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.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import java.util.Collections;
import java.util.List;
@CommandPermissions(permission = "plex.consolesay", source = RequiredCommandSource.CONSOLE) @CommandPermissions(permission = "plex.consolesay", source = RequiredCommandSource.CONSOLE)
@CommandParameters(name = "consolesay", usage = "/<command> <message>", description = "Displays a message to everyone", aliases = "csay") @CommandParameters(name = "consolesay", usage = "/<command> <message>", description = "Displays a message to everyone", aliases = "csay")
public class ConsoleSayCMD extends PlexCommand 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, " ")))); PlexUtils.broadcast(PlexUtils.messageComponent("consoleSayMessage", sender.getName(), PlexUtils.mmStripColor(StringUtils.join(args, " "))));
return null; 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 @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")) 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.Arrays;
import java.util.List; import java.util.List;
import java.util.Locale; 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>") @CommandParameters(name = "pdebug", description = "Plex's debug command", usage = "/<command> <aliases <command> | redis-reset <player> | gamerules>")
@CommandPermissions(permission = "plex.debug") @CommandPermissions(permission = "plex.debug")
@ -91,8 +90,8 @@ public class DebugCMD extends PlexCommand
} }
@Override @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,7 +106,9 @@ public class EntityWipeCMD extends PlexCommand
return null; 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
{
if (silentCheckPermission(sender, this.getPermission()))
{ {
List<String> entities = new ArrayList<>(); List<String> entities = new ArrayList<>();
for (World world : Bukkit.getWorlds()) for (World world : Bukkit.getWorlds())
@ -121,6 +123,8 @@ public class EntityWipeCMD extends PlexCommand
} }
return entities.stream().toList(); return entities.stream().toList();
} }
return Collections.emptyList();
}
private Integer parseInt(CommandSender sender, String string) 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.CommandParameters;
import dev.plex.command.annotation.CommandPermissions; import dev.plex.command.annotation.CommandPermissions;
import dev.plex.command.source.RequiredCommandSource; import dev.plex.command.source.RequiredCommandSource;
import net.kyori.adventure.text.Component; import net.kyori.adventure.text.Component;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.Location; import org.bukkit.Location;
@ -13,6 +12,9 @@ import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import java.util.Collections;
import java.util.List;
@CommandPermissions(permission = "plex.flatlands", source = RequiredCommandSource.IN_GAME) @CommandPermissions(permission = "plex.flatlands", source = RequiredCommandSource.IN_GAME)
@CommandParameters(name = "flatlands", description = "Teleport to the flatlands") @CommandParameters(name = "flatlands", description = "Teleport to the flatlands")
public class FlatlandsCMD extends PlexCommand public class FlatlandsCMD extends PlexCommand
@ -29,4 +31,10 @@ public class FlatlandsCMD extends PlexCommand
} }
return null; 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.player.PlexPlayer;
import dev.plex.punishment.Punishment; import dev.plex.punishment.Punishment;
import dev.plex.punishment.PunishmentType; import dev.plex.punishment.PunishmentType;
import dev.plex.util.PlexUtils; import dev.plex.util.PlexUtils;
import dev.plex.util.TimeUtils; import dev.plex.util.TimeUtils;
import net.kyori.adventure.text.Component; import net.kyori.adventure.text.Component;
@ -54,8 +53,8 @@ public class FreezeCMD extends PlexCommand
} }
@Override @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,16 +88,19 @@ public class GamemodeCMD extends PlexCommand
} }
@Override @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 (args.length == 1)
{ {
return Arrays.asList("creative", "survival", "adventure", "spectator", "default"); return Arrays.asList("creative", "survival", "adventure", "spectator", "default");
} }
if (args.length == 2) if (args.length == 2)
{
if (silentCheckPermission(sender, "plex.gamemode.others"))
{ {
return PlexUtils.getPlayerNameList(); return PlexUtils.getPlayerNameList();
} }
}
return Collections.emptyList(); return Collections.emptyList();
} }
} }

View File

@ -1,5 +1,6 @@
package dev.plex.command.impl; package dev.plex.command.impl;
import com.google.common.collect.ImmutableList;
import dev.plex.cache.DataUtils; import dev.plex.cache.DataUtils;
import dev.plex.command.PlexCommand; import dev.plex.command.PlexCommand;
import dev.plex.command.annotation.CommandParameters; import dev.plex.command.annotation.CommandParameters;
@ -9,7 +10,6 @@ import dev.plex.command.source.RequiredCommandSource;
import dev.plex.player.PlexPlayer; import dev.plex.player.PlexPlayer;
import dev.plex.punishment.Punishment; import dev.plex.punishment.Punishment;
import dev.plex.punishment.PunishmentType; import dev.plex.punishment.PunishmentType;
import dev.plex.util.BungeeUtil; import dev.plex.util.BungeeUtil;
import dev.plex.util.PlexUtils; import dev.plex.util.PlexUtils;
import dev.plex.util.TimeUtils; import dev.plex.util.TimeUtils;
@ -23,6 +23,7 @@ import org.jetbrains.annotations.Nullable;
import java.time.ZoneId; import java.time.ZoneId;
import java.time.ZonedDateTime; import java.time.ZonedDateTime;
import java.util.List;
@CommandParameters(name = "kick", description = "Kicks a player", usage = "/<command> <player>") @CommandParameters(name = "kick", description = "Kicks a player", usage = "/<command> <player>")
@CommandPermissions(permission = "plex.kick", source = RequiredCommandSource.ANY) @CommandPermissions(permission = "plex.kick", source = RequiredCommandSource.ANY)
@ -67,4 +68,10 @@ public class KickCMD extends PlexCommand
BungeeUtil.kickPlayer(player, Punishment.generateKickMessage(punishment)); BungeeUtil.kickPlayer(player, Punishment.generateKickMessage(punishment));
return null; 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; 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"); return Collections.singletonList("-d");
} }

View File

@ -11,6 +11,9 @@ import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; 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") @CommandParameters(name = "localspawn", description = "Teleport to the spawnpoint of the world you are in")
@CommandPermissions(permission = "plex.localspawn", source = RequiredCommandSource.IN_GAME) @CommandPermissions(permission = "plex.localspawn", source = RequiredCommandSource.IN_GAME)
public class LocalSpawnCMD extends PlexCommand public class LocalSpawnCMD extends PlexCommand
@ -22,4 +25,10 @@ public class LocalSpawnCMD extends PlexCommand
playerSender.teleportAsync(playerSender.getWorld().getSpawnLocation()); playerSender.teleportAsync(playerSender.getWorld().getSpawnLocation());
return messageComponent("teleportedToWorldSpawn"); 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.CommandParameters;
import dev.plex.command.annotation.CommandPermissions; import dev.plex.command.annotation.CommandPermissions;
import dev.plex.player.PlexPlayer; import dev.plex.player.PlexPlayer;
import dev.plex.util.PlexUtils; import dev.plex.util.PlexUtils;
import net.kyori.adventure.text.Component; import net.kyori.adventure.text.Component;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
@ -39,8 +38,8 @@ public class LockupCMD extends PlexCommand
} }
@Override @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.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import java.util.Collections;
import java.util.List;
@CommandPermissions(permission = "plex.masterbuilderworld", source = RequiredCommandSource.IN_GAME) @CommandPermissions(permission = "plex.masterbuilderworld", source = RequiredCommandSource.IN_GAME)
@CommandParameters(name = "masterbuilderworld", aliases = "mbw", description = "Teleport to the Master Builder world") @CommandParameters(name = "masterbuilderworld", aliases = "mbw", description = "Teleport to the Master Builder world")
public class MasterbuilderworldCMD extends PlexCommand public class MasterbuilderworldCMD extends PlexCommand
@ -30,4 +33,10 @@ public class MasterbuilderworldCMD extends PlexCommand
} }
return null; 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.CommandParameters;
import dev.plex.command.annotation.CommandPermissions; import dev.plex.command.annotation.CommandPermissions;
import dev.plex.command.source.RequiredCommandSource; import dev.plex.command.source.RequiredCommandSource;
import dev.plex.util.PlexLog;
import dev.plex.util.PlexUtils; import dev.plex.util.PlexUtils;
import net.kyori.adventure.text.Component; import net.kyori.adventure.text.Component;
import org.apache.commons.lang3.text.WordUtils;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.World; import org.bukkit.World;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import org.bukkit.entity.Entity; 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.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; 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) @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 public class MobPurgeCMD extends PlexCommand
{ {
private final List<EntityType> MOB_TYPES = new ArrayList<>();
@Override @Override
protected Component execute(@NotNull CommandSender sender, @Nullable Player playerSender, @NotNull String[] args) protected Component execute(@NotNull CommandSender sender, @Nullable Player playerSender, @NotNull String[] args)
{ {
HashMap<String, Integer> entityCounts = new HashMap<>(); EntityType type = null;
String mobName = null;
for (World world : Bukkit.getWorlds()) if (args.length > 0)
{ {
for (Entity entity : world.getEntities()) try
{ {
if (entity instanceof Mob) type = EntityType.valueOf(args[0].toUpperCase());
}
catch (Exception e)
{ {
String type = entity.getType().name(); PlexLog.debug("A genius tried and failed removing the following invalid mob: " + args[0].toUpperCase());
entity.remove(); send(sender, messageComponent("notAValidMob"));
entityCounts.put(type, entityCounts.getOrDefault(type, 0) + 1);
}
}
}
int entityCount = entityCounts.values().stream().mapToInt(a -> a).sum();
PlexUtils.broadcast(messageComponent("removedMobs", sender.getName(), entityCount));
/*entityCounts.forEach((entityName, numRemoved) -> {
sender.sendMessage(messageComponent("removedEntitiesOfType", sender.getName(), numRemoved, entityName));
});*/
return null; 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.getLivingEntities())
{
if (entity instanceof LivingEntity && !(entity instanceof Player))
{
if (type != null && !entity.getType().equals(type))
{
continue;
}
entity.remove();
removed++;
}
}
}
return removed;
}
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;
}
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.player.PlexPlayer;
import dev.plex.punishment.Punishment; import dev.plex.punishment.Punishment;
import dev.plex.punishment.PunishmentType; import dev.plex.punishment.PunishmentType;
import dev.plex.util.PlexUtils; import dev.plex.util.PlexUtils;
import dev.plex.util.TimeUtils; import dev.plex.util.TimeUtils;
import net.kyori.adventure.text.Component; import net.kyori.adventure.text.Component;
@ -39,7 +38,7 @@ public class MuteCMD extends PlexCommand
return messageComponent("playerMuted"); return messageComponent("playerMuted");
} }
if (silentCheckPermission(player,"plex.mute")) if (silentCheckPermission(player, "plex.mute"))
{ {
send(sender, messageComponent("higherRankThanYou")); send(sender, messageComponent("higherRankThanYou"));
return null; return null;
@ -60,8 +59,8 @@ public class MuteCMD extends PlexCommand
} }
@Override @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.command.annotation.CommandPermissions;
import dev.plex.player.PlexPlayer; import dev.plex.player.PlexPlayer;
import dev.plex.punishment.extra.Note; import dev.plex.punishment.extra.Note;
import dev.plex.util.PlexUtils; import dev.plex.util.PlexUtils;
import dev.plex.util.TimeUtils; import dev.plex.util.TimeUtils;
import net.kyori.adventure.text.Component; import net.kyori.adventure.text.Component;
@ -137,7 +136,9 @@ public class NotesCMD extends PlexCommand
} }
@Override @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, this.getPermission()))
{ {
if (args.length == 1) if (args.length == 1)
{ {
@ -149,4 +150,6 @@ public class NotesCMD extends PlexCommand
} }
return Collections.emptyList(); return Collections.emptyList();
} }
return Collections.emptyList();
}
} }

View File

@ -35,7 +35,7 @@ public class PlexCMD extends PlexCommand
if (args.length == 0) if (args.length == 0)
{ {
send(sender, mmString("<light_purple>Plex - A new freedom plugin.")); 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>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>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.")); 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 @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 (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.annotation.CommandPermissions;
import dev.plex.command.exception.PlayerNotFoundException; import dev.plex.command.exception.PlayerNotFoundException;
import dev.plex.command.source.RequiredCommandSource; import dev.plex.command.source.RequiredCommandSource;
import dev.plex.menu.impl.PunishedPlayerMenu; import dev.plex.menu.impl.PunishedPlayerMenu;
import dev.plex.menu.impl.PunishmentMenu; import dev.plex.menu.impl.PunishmentMenu;
import dev.plex.player.PlexPlayer; import dev.plex.player.PlexPlayer;
@ -50,8 +49,8 @@ public class PunishmentsCMD extends PlexCommand
} }
@Override @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.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import java.util.Collections;
import java.util.List;
@CommandPermissions(permission = "plex.rawsay", source = RequiredCommandSource.ANY) @CommandPermissions(permission = "plex.rawsay", source = RequiredCommandSource.ANY)
@CommandParameters(name = "rawsay", usage = "/<command> <message>", description = "Displays a raw message to everyone") @CommandParameters(name = "rawsay", usage = "/<command> <message>", description = "Displays a raw message to everyone")
public class RawSayCMD extends PlexCommand public class RawSayCMD extends PlexCommand
@ -28,4 +31,10 @@ public class RawSayCMD extends PlexCommand
PlexUtils.broadcast(StringUtils.join(args, " ")); PlexUtils.broadcast(StringUtils.join(args, " "));
return null; 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; package dev.plex.command.impl;
import com.google.common.collect.ImmutableList;
import dev.plex.cache.DataUtils; import dev.plex.cache.DataUtils;
import dev.plex.command.PlexCommand; import dev.plex.command.PlexCommand;
import dev.plex.command.annotation.CommandParameters; import dev.plex.command.annotation.CommandParameters;
import dev.plex.command.annotation.CommandPermissions; import dev.plex.command.annotation.CommandPermissions;
import dev.plex.command.source.RequiredCommandSource; import dev.plex.command.source.RequiredCommandSource;
import dev.plex.player.PlexPlayer; import dev.plex.player.PlexPlayer;
import dev.plex.util.PlexUtils;
import net.kyori.adventure.text.Component; import net.kyori.adventure.text.Component;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import java.util.List;
@CommandPermissions(permission = "plex.removeloginmessage", source = RequiredCommandSource.ANY) @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") @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 public class RemoveLoginMessageCMD extends PlexCommand
@ -51,4 +55,17 @@ public class RemoveLoginMessageCMD extends PlexCommand
} }
return null; 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.CommandParameters;
import dev.plex.command.annotation.CommandPermissions; import dev.plex.command.annotation.CommandPermissions;
import dev.plex.command.source.RequiredCommandSource; import dev.plex.command.source.RequiredCommandSource;
import dev.plex.util.PlexUtils; import dev.plex.util.PlexUtils;
import net.kyori.adventure.text.Component; import net.kyori.adventure.text.Component;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
@ -13,6 +12,9 @@ import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import java.util.Collections;
import java.util.List;
@CommandPermissions(permission = "plex.say", source = RequiredCommandSource.ANY) @CommandPermissions(permission = "plex.say", source = RequiredCommandSource.ANY)
@CommandParameters(name = "say", usage = "/<command> <message>", description = "Displays a message to everyone") @CommandParameters(name = "say", usage = "/<command> <message>", description = "Displays a message to everyone")
public class SayCMD extends PlexCommand 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, " ")))); PlexUtils.broadcast(PlexUtils.messageComponent("sayMessage", sender.getName(), PlexUtils.mmStripColor(StringUtils.join(args, " "))));
return null; 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; package dev.plex.command.impl;
import com.google.common.collect.ImmutableList;
import dev.plex.cache.DataUtils; import dev.plex.cache.DataUtils;
import dev.plex.command.PlexCommand; import dev.plex.command.PlexCommand;
import dev.plex.command.annotation.CommandParameters; import dev.plex.command.annotation.CommandParameters;
@ -10,12 +11,15 @@ import dev.plex.player.PlexPlayer;
import dev.plex.util.PlexLog; import dev.plex.util.PlexLog;
import dev.plex.util.PlexUtils; import dev.plex.util.PlexUtils;
import net.kyori.adventure.text.Component; import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.minimessage.MiniMessage;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import java.util.List;
@CommandPermissions(permission = "plex.setloginmessage", source = RequiredCommandSource.ANY) @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") @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 public class SetLoginMessageCMD extends PlexCommand
@ -53,20 +57,18 @@ public class SetLoginMessageCMD extends PlexCommand
validateMessage(message); validateMessage(message);
plexPlayer.setLoginMessage(message); plexPlayer.setLoginMessage(message);
return messageComponent("setOtherPlayersLoginMessage", plexPlayer.getName(), return messageComponent("setOtherPlayersLoginMessage", plexPlayer.getName(),
message.replace("%player%", plexPlayer.getName())); MiniMessage.miniMessage().serialize(PlexUtils.stringToComponent(message.replace("%player%", plexPlayer.getName()))));
} }
if (isConsole(sender)) if (isConsole(sender))
{ {
return messageComponent("noPermissionConsole"); return messageComponent("noPermissionConsole");
} }
PlexPlayer plexPlayer = plugin.getPlayerCache().getPlexPlayer(playerSender.getUniqueId()); PlexPlayer plexPlayer = plugin.getPlayerCache().getPlexPlayer(playerSender.getUniqueId());
String message = StringUtils.join(args, " ", 0, args.length); String message = StringUtils.join(args, " ", 0, args.length)
message = message.replace(plexPlayer.getName(), "%player%"); .replace(plexPlayer.getName(), "%player%");
message = PlexUtils.legacyToMiniString(message);
validateMessage(message); validateMessage(message);
plexPlayer.setLoginMessage(message); plexPlayer.setLoginMessage(message);
return messageComponent("setOwnLoginMessage", return messageComponent("setOwnLoginMessage", PlexUtils.stringToComponent(message.replace("%player%", plexPlayer.getName())));
message.replace("%player%", plexPlayer.getName()));
} }
return null; return null;
} }
@ -79,4 +81,17 @@ public class SetLoginMessageCMD extends PlexCommand
throw new CommandFailException(messageString("nameRequired")); 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.player.PlexPlayer;
import dev.plex.punishment.Punishment; import dev.plex.punishment.Punishment;
import dev.plex.punishment.PunishmentType; import dev.plex.punishment.PunishmentType;
import dev.plex.util.PlexUtils; import dev.plex.util.PlexUtils;
import dev.plex.util.TimeUtils; import dev.plex.util.TimeUtils;
import net.kyori.adventure.text.Component; import net.kyori.adventure.text.Component;
@ -136,9 +135,9 @@ public class SmiteCMD extends PlexCommand
} }
@Override @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(); return PlexUtils.getPlayerNameList();
} }

View File

@ -56,7 +56,7 @@ public class SpectatorCMD extends PlexCommand
} }
@Override @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")) if (silentCheckPermission(sender,"plex.gamemode.spectator.others"))
{ {

View File

@ -57,7 +57,7 @@ public class SurvivalCMD extends PlexCommand
} }
@Override @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")) 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.annotation.CommandPermissions;
import dev.plex.command.source.RequiredCommandSource; import dev.plex.command.source.RequiredCommandSource;
import dev.plex.player.PlexPlayer; import dev.plex.player.PlexPlayer;
import dev.plex.util.PlexUtils; import dev.plex.util.PlexUtils;
import dev.plex.util.minimessage.SafeMiniMessage; import dev.plex.util.minimessage.SafeMiniMessage;
import net.kyori.adventure.text.Component; import net.kyori.adventure.text.Component;
@ -19,6 +18,10 @@ import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
@CommandPermissions(permission = "plex.tag", source = RequiredCommandSource.ANY) @CommandPermissions(permission = "plex.tag", source = RequiredCommandSource.ANY)
@CommandParameters(name = "tag", aliases = "prefix", description = "Set or clear your prefix", usage = "/<command> <set <prefix> | clear <player>>") @CommandParameters(name = "tag", aliases = "prefix", description = "Set or clear your prefix", usage = "/<command> <set <prefix> | clear <player>>")
public class TagCMD extends PlexCommand public class TagCMD extends PlexCommand
@ -47,16 +50,15 @@ public class TagCMD extends PlexCommand
{ {
return usage("/tag set <prefix>"); return usage("/tag set <prefix>");
} }
String prefix = PlexUtils.legacyToMiniString(StringUtils.join(args, " ", 1, args.length));
Component convertedComponent = SafeMiniMessage.mmDeserializeWithoutEvents(prefix); Component convertedComponent = PlexUtils.stringToComponent(StringUtils.join(args, " ", 1, args.length));
if (PlainTextComponentSerializer.plainText().serialize(convertedComponent).length() > plugin.config.getInt("chat.max-tag-length", 16)) if (PlainTextComponentSerializer.plainText().serialize(convertedComponent).length() > plugin.config.getInt("chat.max-tag-length", 16))
{ {
return messageComponent("maximumPrefixLength", plugin.config.getInt("chat.max-tag-length", 16)); return messageComponent("maximumPrefixLength", plugin.config.getInt("chat.max-tag-length", 16));
} }
player.setPrefix(prefix); player.setPrefix(MiniMessage.miniMessage().serialize(convertedComponent));
DataUtils.update(player); DataUtils.update(player);
return messageComponent("prefixSetTo", MiniMessage.miniMessage().serialize(convertedComponent)); return messageComponent("prefixSetTo", MiniMessage.miniMessage().serialize(convertedComponent));
} }
@ -80,7 +82,7 @@ public class TagCMD extends PlexCommand
DataUtils.update(player); DataUtils.update(player);
return messageComponent("prefixCleared"); return messageComponent("prefixCleared");
} }
checkPermission(sender,"plex.tag.clear.others"); checkPermission(sender, "plex.tag.clear.others");
Player target = getNonNullPlayer(args[1]); Player target = getNonNullPlayer(args[1]);
PlexPlayer plexTarget = DataUtils.getPlayer(target.getUniqueId()); PlexPlayer plexTarget = DataUtils.getPlayer(target.getUniqueId());
plexTarget.setPrefix(null); plexTarget.setPrefix(null);
@ -89,6 +91,26 @@ public class TagCMD extends PlexCommand
} }
return usage(); 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.player.PlexPlayer;
import dev.plex.punishment.Punishment; import dev.plex.punishment.Punishment;
import dev.plex.punishment.PunishmentType; import dev.plex.punishment.PunishmentType;
import dev.plex.util.BungeeUtil; import dev.plex.util.BungeeUtil;
import dev.plex.util.PlexLog;
import dev.plex.util.PlexUtils; import dev.plex.util.PlexUtils;
import dev.plex.util.TimeUtils; import dev.plex.util.TimeUtils;
import net.kyori.adventure.text.Component; import net.kyori.adventure.text.Component;
@ -22,6 +22,7 @@ import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import java.util.Collections;
import java.util.List; import java.util.List;
@CommandParameters(name = "tempban", usage = "/<command> <player> <time> [reason]", description = "Temporarily ban a player") @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 punishment = new Punishment(target.getUuid(), getUUID(sender));
punishment.setType(PunishmentType.TEMPBAN); punishment.setType(PunishmentType.TEMPBAN);
boolean rollBack = true;
if (args.length > 2) if (args.length > 2)
{ {
reason = StringUtils.join(args, " ", 2, args.length); 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 else
{ {
@ -75,12 +79,46 @@ public class TempbanCMD extends PlexCommand
{ {
BungeeUtil.kickPlayer(player, Punishment.generateBanMessage(punishment)); 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; return null;
} }
@Override @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.annotation.CommandPermissions;
import dev.plex.command.source.RequiredCommandSource; import dev.plex.command.source.RequiredCommandSource;
import dev.plex.menu.impl.ToggleMenu; import dev.plex.menu.impl.ToggleMenu;
import dev.plex.util.PlexUtils; import dev.plex.util.PlexUtils;
import net.kyori.adventure.text.Component; import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.format.NamedTextColor; import net.kyori.adventure.text.format.NamedTextColor;
@ -64,9 +63,9 @@ public class ToggleCMD extends PlexCommand
} }
@Override @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) 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.exception.PlayerNotFoundException;
import dev.plex.command.source.RequiredCommandSource; import dev.plex.command.source.RequiredCommandSource;
import dev.plex.player.PlexPlayer; import dev.plex.player.PlexPlayer;
import dev.plex.util.PlexUtils; import dev.plex.util.PlexUtils;
import net.kyori.adventure.text.Component; import net.kyori.adventure.text.Component;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
@ -56,8 +55,8 @@ public class UnbanCMD extends PlexCommand
} }
@Override @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.annotation.CommandPermissions;
import dev.plex.command.exception.CommandFailException; import dev.plex.command.exception.CommandFailException;
import dev.plex.player.PlexPlayer; import dev.plex.player.PlexPlayer;
import dev.plex.util.PlexUtils; import dev.plex.util.PlexUtils;
import net.kyori.adventure.text.Component; import net.kyori.adventure.text.Component;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
@ -39,8 +38,8 @@ public class UnfreezeCMD extends PlexCommand
} }
@Override @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.annotation.CommandPermissions;
import dev.plex.command.exception.CommandFailException; import dev.plex.command.exception.CommandFailException;
import dev.plex.player.PlexPlayer; import dev.plex.player.PlexPlayer;
import dev.plex.util.PlexUtils; import dev.plex.util.PlexUtils;
import net.kyori.adventure.text.Component; import net.kyori.adventure.text.Component;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
@ -39,8 +38,8 @@ public class UnmuteCMD extends PlexCommand
} }
@Override @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 @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.CommandParameters;
import dev.plex.command.annotation.CommandPermissions; import dev.plex.command.annotation.CommandPermissions;
import dev.plex.command.source.RequiredCommandSource; import dev.plex.command.source.RequiredCommandSource;
import net.kyori.adventure.text.Component; import net.kyori.adventure.text.Component;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.World; 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}"); 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"))) 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()); playerSender.teleportAsync(world.getSpawnLocation());
return messageComponent("playerWorldTeleport", world.getName()); return messageComponent("playerWorldTeleport", world.getName());
} }
@Override @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 List<String> completions = Lists.newArrayList();
final Player player = (Player) sender; final Player player = (Player) sender;
if (args.length == 1) if (args.length == 1 && silentCheckPermission(sender, this.getPermission()))
{ {
@NotNull List<World> worlds = Bukkit.getWorlds(); @NotNull List<World> worlds = Bukkit.getWorlds();
for (World world : worlds) for (World world : worlds)
@ -60,7 +58,7 @@ public class WorldCMD extends PlexCommand
try try
{ {
final UUID uuid = UUID.fromString(worldName); 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); completions.add(worldName);
} }

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

@ -82,8 +82,8 @@ public class VaultHook
if (vaultPrefix == null || vaultPrefix.isEmpty()) { if (vaultPrefix == null || vaultPrefix.isEmpty()) {
return Component.empty(); return Component.empty();
} }
PlexLog.debug("prefix: {0}", PlexUtils.legacyToMiniString(vaultPrefix).replace("<", "\\<")); PlexLog.debug("prefix: {0}", SafeMiniMessage.mmSerializeWithoutEvents(PlexUtils.stringToComponent(vaultPrefix)).replace("<", "\\<"));
return SafeMiniMessage.mmDeserializeWithoutEvents(PlexUtils.legacyToMiniString(vaultPrefix)); return PlexUtils.stringToComponent(vaultPrefix);
} }
public static Permission getPermission() public static Permission getPermission()

View File

@ -7,6 +7,8 @@ import dev.plex.player.PlexPlayer;
import dev.plex.punishment.Punishment; import dev.plex.punishment.Punishment;
import dev.plex.punishment.PunishmentManager; import dev.plex.punishment.PunishmentManager;
import dev.plex.punishment.PunishmentType; import dev.plex.punishment.PunishmentType;
import dev.plex.util.PlexLog;
import it.unimi.dsi.fastutil.Pair;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.event.EventHandler; import org.bukkit.event.EventHandler;
import org.bukkit.event.player.AsyncPlayerPreLoginEvent; import org.bukkit.event.player.AsyncPlayerPreLoginEvent;
@ -43,11 +45,26 @@ public class BanListener extends PlexListener
if (plugin.getPunishmentManager().isBanned(event.getUniqueId())) 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()); PlexPlayer player = DataUtils.getPlayer(event.getUniqueId());
player.getPunishments().stream().filter(punishment -> (punishment.getType() == PunishmentType.BAN || punishment.getType() == PunishmentType.TEMPBAN) && punishment.isActive()).findFirst().ifPresent(punishment -> player.getPunishments().stream().filter(punishment -> (punishment.getType() == PunishmentType.BAN || punishment.getType() == PunishmentType.TEMPBAN) && punishment.isActive()).findFirst().ifPresent(punishment ->
event.disallow(AsyncPlayerPreLoginEvent.Result.KICK_BANNED, event.disallow(AsyncPlayerPreLoginEvent.Result.KICK_BANNED,
Punishment.generateBanMessage(punishment))); 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

@ -12,7 +12,6 @@ import io.papermc.paper.chat.ChatRenderer;
import io.papermc.paper.event.player.AsyncChatEvent; import io.papermc.paper.event.player.AsyncChatEvent;
import net.kyori.adventure.audience.Audience; import net.kyori.adventure.audience.Audience;
import net.kyori.adventure.text.Component; import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.TextComponent;
import net.kyori.adventure.text.TextReplacementConfig; import net.kyori.adventure.text.TextReplacementConfig;
import net.kyori.adventure.text.event.ClickEvent; import net.kyori.adventure.text.event.ClickEvent;
import net.kyori.adventure.text.format.NamedTextColor; import net.kyori.adventure.text.format.NamedTextColor;
@ -47,7 +46,7 @@ public class ChatListener extends PlexListener
{ {
String prefix = PlexUtils.mmSerialize(VaultHook.getPrefix(event.getPlayer())); // Don't use PlexPlayer#getPrefix because that returns their custom set prefix and not their group's String prefix = PlexUtils.mmSerialize(VaultHook.getPrefix(event.getPlayer())); // Don't use PlexPlayer#getPrefix because that returns their custom set prefix and not their group's
MessageUtil.sendStaffChat(event.getPlayer(), event.message(), PlexUtils.adminChat(event.getPlayer().getName(), prefix, SafeMiniMessage.mmSerialize(event.message())).toArray(UUID[]::new)); MessageUtil.sendStaffChat(event.getPlayer(), event.message(), PlexUtils.adminChat(event.getPlayer().getName(), prefix, SafeMiniMessage.mmSerialize(event.message())).toArray(UUID[]::new));
plugin.getServer().getConsoleSender().sendMessage(PlexUtils.messageComponent("adminChatFormat", event.getPlayer().getName(), prefix, PlexUtils.legacyToMiniString(SafeMiniMessage.mmSerializeWithoutEvents(event.message()))).replaceText(URL_REPLACEMENT_CONFIG)); plugin.getServer().getConsoleSender().sendMessage(PlexUtils.messageComponent("adminChatFormat", event.getPlayer().getName(), prefix, SafeMiniMessage.mmSerialize(event.message().replaceText(URL_REPLACEMENT_CONFIG))));
event.setCancelled(true); event.setCancelled(true);
return; return;
} }
@ -105,7 +104,7 @@ public class ChatListener extends PlexListener
private static void defaultChatProcessing(AsyncChatEvent event, PlexPlayer plexPlayer) private static void defaultChatProcessing(AsyncChatEvent event, PlexPlayer plexPlayer)
{ {
String text = PlexUtils.legacyToMiniString(PlexUtils.getTextFromComponent(event.message())); String text = PlexUtils.getTextFromComponent(event.message());
event.message(SafeMiniMessage.mmDeserializeWithoutEvents(text)); event.message(PlexUtils.stringToComponent(text));
} }
} }

View File

@ -65,7 +65,7 @@ public class PlayerListener<T> extends PlexListener
String loginMessage = PlayerMeta.getLoginMessage(plexPlayer); String loginMessage = PlayerMeta.getLoginMessage(plexPlayer);
if (!loginMessage.isEmpty()) if (!loginMessage.isEmpty())
{ {
PlexUtils.broadcast(loginMessage); PlexUtils.broadcast(PlexUtils.stringToComponent(loginMessage));
} }
plexPlayer.loadNotes(); plexPlayer.loadNotes();

View File

@ -1,22 +0,0 @@
package dev.plex.listener.impl;
import dev.plex.listener.PlexListener;
import dev.plex.util.PlexUtils;
import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.block.SignChangeEvent;
public class SignListener extends PlexListener
{
private static final LegacyComponentSerializer LEGACY_COMPONENT_SERIALIZER = LegacyComponentSerializer.legacyAmpersand();
@EventHandler(priority = EventPriority.LOW)
public void onSignEdit(SignChangeEvent event)
{
for (int i = 0; i < event.lines().size(); i++)
{
event.line(i, LEGACY_COMPONENT_SERIALIZER.deserialize(PlexUtils.getTextFromComponent(event.line(i))));
}
}
}

View File

@ -13,7 +13,6 @@ import org.bukkit.Bukkit;
public class PlayerMeta public class PlayerMeta
{ {
public static Component getPrefix(PlexPlayer plexPlayer) public static Component getPrefix(PlexPlayer plexPlayer)
{ {
if (plexPlayer.getPrefix() != null && !plexPlayer.getPrefix().isEmpty()) 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.collect.Lists;
import com.google.common.reflect.TypeToken; import com.google.common.reflect.TypeToken;
import com.google.gson.Gson; import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import dev.plex.Plex; import dev.plex.Plex;
import dev.plex.PlexBase; import dev.plex.PlexBase;
import dev.plex.cache.DataUtils; import dev.plex.cache.DataUtils;
import dev.plex.player.PlexPlayer; import dev.plex.player.PlexPlayer;
import dev.plex.storage.StorageType;
import dev.plex.util.PlexLog; import dev.plex.util.PlexLog;
import dev.plex.util.PlexUtils; import dev.plex.util.PlexUtils;
import dev.plex.util.TimeUtils; 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.File;
import java.io.IOException; import java.io.IOException;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
@ -28,7 +21,17 @@ import java.util.Collection;
import java.util.List; import java.util.List;
import java.util.UUID; import java.util.UUID;
import java.util.concurrent.CompletableFuture; 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 public class PunishmentManager implements PlexBase
{ {
@ -135,7 +138,6 @@ public class PunishmentManager implements PlexBase
public boolean isBanned(UUID uuid) 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)) if (!DataUtils.hasPlayedBefore(uuid))
{ {
return false; 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()); 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) public boolean isBanned(PlexPlayer player)
{ {
return isBanned(player.getUuid()); return isBanned(player.getUuid());

View File

@ -21,6 +21,7 @@ import java.util.concurrent.CompletableFuture;
public class SQLPunishment public class SQLPunishment
{ {
private static final String SELECT = "SELECT * FROM `punishments` WHERE punished=?"; 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 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(?, ?, ?, ?, ?, ?, ?, ?, ?)"; 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; 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) public CompletableFuture<Void> insertPunishment(Punishment punishment)
{ {

View File

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

View File

@ -6,10 +6,13 @@ import dev.plex.Plex;
import dev.plex.PlexBase; import dev.plex.PlexBase;
import dev.plex.listener.impl.ChatListener; import dev.plex.listener.impl.ChatListener;
import dev.plex.storage.StorageType; import dev.plex.storage.StorageType;
import dev.plex.util.minimessage.SafeMiniMessage;
import net.kyori.adventure.text.Component; import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.TextComponent; import net.kyori.adventure.text.TextComponent;
import net.kyori.adventure.text.format.TextDecoration;
import net.kyori.adventure.text.minimessage.MiniMessage; import net.kyori.adventure.text.minimessage.MiniMessage;
import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver; import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver;
import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
import net.kyori.adventure.text.serializer.plain.PlainTextComponentSerializer; import net.kyori.adventure.text.serializer.plain.PlainTextComponentSerializer;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.Location; import org.bukkit.Location;
@ -28,6 +31,7 @@ import java.util.Arrays;
import java.util.List; import java.util.List;
import java.util.Stack; import java.util.Stack;
import java.util.UUID; import java.util.UUID;
import java.util.regex.Pattern;
import java.util.stream.Collectors; import java.util.stream.Collectors;
public class PlexUtils implements PlexBase public class PlexUtils implements PlexBase
@ -43,6 +47,8 @@ public class PlexUtils implements PlexBase
"a52f1f08-a398-400a-bca4-2b74b81feae6" // Allink "a52f1f08-a398-400a-bca4-2b74b81feae6" // Allink
); );
private static final Pattern LEGACY_FORMATTING_PATTERN = Pattern.compile(".*(?i)(([§&])((#[a-f0-9]{3,6})|([0-9a-fklmnor]))).*");
public static <T> T addToArrayList(List<T> list, T object) public static <T> T addToArrayList(List<T> list, T object)
{ {
list.add(object); list.add(object);
@ -145,6 +151,17 @@ public class PlexUtils implements PlexBase
return component; return component;
} }
public static Component stringToComponent(String input)
{
input = cleanString(input);
return LEGACY_FORMATTING_PATTERN.matcher(input).find() ?
LegacyComponentSerializer.legacyAmpersand().deserialize(input.replaceAll("([§&]+)(k+)", "") // Ugly hack, but it tries to prevent &k and any attempts to bypass it.
).decoration(TextDecoration.OBFUSCATED, TextDecoration.State.FALSE) :
SafeMiniMessage.mmDeserializeWithoutEvents(input);
}
@Deprecated
public static String legacyToMiniString(String input) public static String legacyToMiniString(String input)
{ {
return cleanString(input.replace("&a", "<green>") return cleanString(input.replace("&a", "<green>")

View File

@ -96,7 +96,7 @@ public class UpdateChecker implements PlexBase
// If it's -4, it hasn't checked for updates yet // If it's -4, it hasn't checked for updates yet
if (distance == -4) if (distance == -4)
{ {
distance = fetchDistanceFromGitHub(REPO, BRANCH, BuildInfo.getHead()); distance = fetchDistanceFromGitHub(REPO, BRANCH, BuildInfo.getCommit());
PlexLog.debug("Never checked for updates, checking now..."); PlexLog.debug("Never checked for updates, checking now...");
} }
else else
@ -104,7 +104,7 @@ public class UpdateChecker implements PlexBase
// If the request isn't asked to be cached, fetch it // If the request isn't asked to be cached, fetch it
if (!cached) 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."); PlexLog.debug("We have checked for updates before, but this request was not asked to be cached.");
} }
else 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 # 0 - Entity type that is invalid
invalidEntityType: "<gray>Notice: Entity type {0} is invalid!" invalidEntityType: "<gray>Notice: Entity type {0} is invalid!"
noRemovedEntities: "<gray>No entities were removed." 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 # 0 - The command sender
# 1 - Number of mobs removed # 1 - Number of mobs removed
removedMobs: "<red>{0} - Removed {1} mobs" 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")