47 Commits

Author SHA1 Message Date
5a1436afae Release Plex v1.4 2024-06-14 20:29:08 -05:00
e066d9b3a1 Implemented the ability to toggle pvp (#97)
* Implemented the ability to toggle pvp

* Changed listener to  PrePlayerAttackEntityEvent

* ... Updated the formatting so I don't get screamed at !

* _
2024-06-04 10:30:34 -05:00
9e974ae737 Add a /tempmute command (#96)
* Update WhoHasCMD.java

Added functionality that clears all players with a specified item

* Added functionality that clears all players with a specified item

* Altered tab completion to include "clear" argument

* Update WhoHasCMD.java

* Implemented a mob limiter that can be configured via a command

* Fixed some imports

* Refined tab complete

* Implemented reviewed changes

* Added a /tempmute command

* Removed unnecessary imports & simplified the reason assignment

* Fixed the usage for the moblimit command

---------

Co-authored-by: Telesphoreo <me@telesphoreo.me>
2024-06-04 09:23:51 -05:00
23611e218b Implemented a moblimiter (#95)
* Update WhoHasCMD.java

Added functionality that clears all players with a specified item

* Added functionality that clears all players with a specified item

* Altered tab completion to include "clear" argument

* Update WhoHasCMD.java

* Implemented a mob limiter that can be configured via a command

* Fixed some imports

* Refined tab complete

* Implemented reviewed changes

---------

Co-authored-by: Telesphoreo <me@telesphoreo.me>
2024-05-31 15:41:14 -05:00
5f12a1532f Add vanish filtering to list 2024-05-31 15:38:56 -05:00
fff35ad34c fix -rb showing in ban message 2024-05-26 13:35:35 -05:00
83ec997125 Merge pull request #90 from Deauthorized/messagesincursion
Move most hard coded messages to messages.yml to allow customization.
2024-05-09 17:09:37 -06:00
2ed88da151 Merge branch 'master' into messagesincursion 2024-05-09 17:06:13 -06:00
c5b356e45a fix merge conflict for hopefully the last time 2024-05-06 15:51:04 -04:00
58fe304118 oops oops oops 2024-05-06 12:40:29 -07:00
50d969975c fix merge conflict 2024-05-06 15:37:56 -04:00
52cc738d4d fix merge conflict 2024-05-06 15:34:18 -04:00
fd19d8417c add banlist to plex instead of having it in tfm extras 2024-05-06 12:31:07 -07:00
efcb9b45df oh update usage too 2024-05-06 12:29:30 -07:00
a5d77036a9 closes #91
add rollback only if -rb is specified
2024-05-06 12:26:21 -07:00
5c609b3d8f Since this'll be a problem for some reason I'm restoring the original message 2024-05-04 05:19:41 -04:00
7383e0d9bb Update BanService.java 2024-05-04 02:46:07 -04:00
f1680174ae Update DebugCMD.java 2024-05-04 02:45:39 -04:00
c0966a0f5e Update messages.yml 2024-05-04 02:44:53 -04:00
fa1a8a91ba add jenkins webhook for tf 2024-05-03 14:54:04 -07:00
129ef7b6bf Remind me to read the documentation next time... coreprotect is supposed to be called asynchronously lol 2024-05-03 14:41:12 -07:00
d7ad94d270 overrwrote the wrong file :( 2024-05-02 17:43:06 -04:00
a0471e63f6 Update WorldListener.java 2024-05-02 17:42:33 -04:00
e2b3488aa7 Update ServerListener.java 2024-05-02 17:31:33 -04:00
5b3a37835a Update PlayerListener.java 2024-05-02 17:30:22 -04:00
344df2b225 Update AntiSpamListener.java 2024-05-02 17:29:38 -04:00
6e5f0d7beb Update AntiNukerListener.java 2024-05-02 17:29:24 -04:00
0c7b280aef Update TempbanCMD.java 2024-05-02 17:28:34 -04:00
647f17b5bd Update SmiteCMD.java 2024-05-02 17:27:47 -04:00
773f320cb6 Update NotesCMD.java 2024-05-02 17:27:17 -04:00
8f55be369f Update ListCMD.java 2024-05-02 17:26:20 -04:00
5a7a2c1835 Update KickCMD.java 2024-05-02 17:25:49 -04:00
bc163aa51a Update EntityWipeCMD.java 2024-05-02 17:25:26 -04:00
5040c76dc6 Update BcastLoginMessageCMD.java 2024-05-02 17:24:49 -04:00
7d94717de5 Update BanCMD.java 2024-05-02 17:23:37 -04:00
0add60322e Update messages.yml 2024-05-02 17:22:05 -04:00
068dd28fd4 Temporary fix for displaying login messages on join 2024-04-28 12:52:21 -05:00
357683a0f6 Add a toggle option for toggling chat (#89)
* Add moderated mode toggle option

* Add new messages to messages.yml for modmode toggle

* Add block_on_modmode list for commands to block, should be separate from block_on_mute so pms can still work

* Implement the restricted chat toggle

* Add the restricted chat toggle to the toggle gui

* Add the restricted chat toggle to the consoles version of the command as well

* Update toggles.yml / requested changes

* Update messages.yml / requested changes

* Update commands.yml / requested changes

* Update ToggleMenu.java / requested changes

* Update TogglesListener.java / requested changes

* Update ToggleCMD.java / requested changes

* Update messages.yml / requested changes

* Update ToggleMenu.java / requested changes

* Update ToggleCMD.java / requested changes
2024-04-28 12:04:18 -05:00
315e16488b adds support for vanish plugins 2024-04-27 22:24:03 -05:00
85605774cf fix mute & freeze not staying after relog
add configurable timers for mute and freeze
2024-03-23 08:14:36 -07:00
54015f668a Fixes NPE if Prism or CoreProtect are not installed (#87) 2024-03-02 15:38:49 -06:00
532e82472b Added functionality that clears all players with a specified item (#82)
* Update WhoHasCMD.java

Added functionality that clears all players with a specified item

* Added functionality that clears all players with a specified item

* Altered tab completion to include "clear" argument

* Update WhoHasCMD.java

---------

Co-authored-by: Telesphoreo <me@telesphoreo.me>
2024-02-04 13:35:11 -06:00
6ce4843829 Minor fix 2024-01-27 15:56:40 -06:00
7298c8669a Attempt to fix bans not working 2024-01-27 15:48:21 -06:00
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
54 changed files with 970 additions and 232 deletions

1
Jenkinsfile vendored
View File

@ -14,6 +14,7 @@ pipeline {
archiveArtifacts artifacts: "build/libs/*.jar", fingerprint: true archiveArtifacts artifacts: "build/libs/*.jar", fingerprint: true
javadoc javadocDir: "server/build/docs/javadoc", keepAll: false javadoc javadocDir: "server/build/docs/javadoc", keepAll: false
discordSend description: "**Build:** ${env.BUILD_NUMBER}\n**Status:** ${currentBuild.currentResult}", enableArtifactsList: true, footer: "Built with Jenkins", link: env.BUILD_URL, result: currentBuild.currentResult, scmWebUrl: "https://github.com/plexusorg/Plex", showChangeset: true, title: env.JOB_NAME, webhookURL: env.WEBHOOK_URL discordSend description: "**Build:** ${env.BUILD_NUMBER}\n**Status:** ${currentBuild.currentResult}", enableArtifactsList: true, footer: "Built with Jenkins", link: env.BUILD_URL, result: currentBuild.currentResult, scmWebUrl: "https://github.com/plexusorg/Plex", showChangeset: true, title: env.JOB_NAME, webhookURL: env.WEBHOOK_URL
discordSend description: "**Build:** ${env.BUILD_NUMBER}\n**Status:** ${currentBuild.currentResult}", enableArtifactsList: true, footer: "Built with Jenkins", link: env.BUILD_URL, result: currentBuild.currentResult, scmWebUrl: "https://github.com/plexusorg/Plex", showChangeset: true, title: env.JOB_NAME, webhookURL: env.TF_WEBHOOK_URL
cleanWs() cleanWs()
} }
} }

View File

@ -1,13 +1,13 @@
plugins { plugins {
id("java") id("java")
id("maven-publish") id("maven-publish")
id("org.jetbrains.gradle.plugin.idea-ext") version "1.1.7" id("org.jetbrains.gradle.plugin.idea-ext") version "1.1.8"
id("net.kyori.blossom") version "2.1.0" id("net.kyori.blossom") version "2.1.0"
id("com.github.johnrengelman.shadow") version "8.1.1" id("io.github.goooler.shadow") version "8.1.7"
} }
group = "dev.plex" group = "dev.plex"
version = "1.4-SNAPSHOT" version = "1.4"
description = "Plex" description = "Plex"
subprojects { subprojects {
@ -15,7 +15,7 @@ subprojects {
apply(plugin = "maven-publish") apply(plugin = "maven-publish")
apply(plugin = "org.jetbrains.gradle.plugin.idea-ext") apply(plugin = "org.jetbrains.gradle.plugin.idea-ext")
apply(plugin = "net.kyori.blossom") apply(plugin = "net.kyori.blossom")
apply(plugin = "com.github.johnrengelman.shadow") apply(plugin = "io.github.goooler.shadow")
repositories { repositories {
maven { maven {
@ -34,6 +34,7 @@ subprojects {
url = uri("https://jitpack.io") url = uri("https://jitpack.io")
content { content {
includeGroup("com.github.MilkBowl") includeGroup("com.github.MilkBowl")
includeGroup("com.github.LeonMangler")
} }
} }

Binary file not shown.

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.5-bin.zip distributionUrl=https\://services.gradle.org/distributions/gradle-8.8-bin.zip
networkTimeout=10000 networkTimeout=10000
validateDistributionUrl=true validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME

View File

@ -39,9 +39,9 @@ publishing {
} }
dependencies { dependencies {
compileOnly("org.projectlombok:lombok:1.18.30") compileOnly("org.projectlombok:lombok:1.18.32")
annotationProcessor("org.projectlombok:lombok:1.18.30") annotationProcessor("org.projectlombok:lombok:1.18.32")
compileOnly("org.json:json:20231013") compileOnly("org.json:json:20240303")
compileOnly("com.velocitypowered:velocity-api:3.2.0-SNAPSHOT") compileOnly("com.velocitypowered:velocity-api:3.2.0-SNAPSHOT")
annotationProcessor("com.velocitypowered:velocity-api:3.2.0-SNAPSHOT") annotationProcessor("com.velocitypowered:velocity-api:3.2.0-SNAPSHOT")
} }

View File

@ -14,26 +14,28 @@ repositories {
} }
dependencies { dependencies {
library("org.projectlombok:lombok:1.18.30") library("org.projectlombok:lombok:1.18.32")
library("org.json:json:20231013") library("org.json:json:20240303")
library("commons-io:commons-io:2.15.1") library("commons-io:commons-io:2.16.1")
library("redis.clients:jedis:5.1.0") library("redis.clients:jedis:5.1.3")
library("org.mariadb.jdbc:mariadb-java-client:3.3.1") library("org.mariadb.jdbc:mariadb-java-client:3.4.0")
library("com.zaxxer:HikariCP:5.1.0") library("com.zaxxer:HikariCP:5.1.0")
library("org.apache.maven.resolver:maven-resolver-transport-http:1.9.18") library("org.apache.maven.resolver:maven-resolver-transport-http:1.9.20")
library("org.jetbrains:annotations:24.1.0") library("org.jetbrains:annotations:24.1.0")
compileOnly("dev.folia:folia-api:1.20.2-R0.1-SNAPSHOT") compileOnly("dev.folia:folia-api:1.20.4-R0.1-SNAPSHOT")
compileOnly("com.github.MilkBowl:VaultAPI:1.7.1") { compileOnly("com.github.MilkBowl:VaultAPI:1.7.1") {
exclude("org.bukkit", "bukkit") exclude("org.bukkit", "bukkit")
} }
compileOnly("net.coreprotect:coreprotect:22.2") compileOnly("net.coreprotect:coreprotect:22.4")
compileOnly("network.darkhelmet.prism:Prism-Api:1.0.0") compileOnly("network.darkhelmet.prism:Prism-Api:1.0.0")
implementation("org.bstats:bstats-base:3.0.2") implementation("org.bstats:bstats-base:3.0.2")
implementation("org.bstats:bstats-bukkit:3.0.2") implementation("org.bstats:bstats-bukkit:3.0.2")
annotationProcessor("org.projectlombok:lombok:1.18.30") implementation("com.github.LeonMangler:SuperVanish:6.2.18-3")
annotationProcessor("org.projectlombok:lombok:1.18.32")
} }
group = rootProject.group group = rootProject.group
@ -57,10 +59,6 @@ paper {
required = false required = false
load = PaperPluginDescription.RelativeLoadOrder.BEFORE load = PaperPluginDescription.RelativeLoadOrder.BEFORE
} }
register("DiscordSRV") {
required = false
load = PaperPluginDescription.RelativeLoadOrder.AFTER
}
register("Essentials") { register("Essentials") {
required = false required = false
load = PaperPluginDescription.RelativeLoadOrder.BEFORE load = PaperPluginDescription.RelativeLoadOrder.BEFORE
@ -77,10 +75,18 @@ paper {
required = false required = false
load = PaperPluginDescription.RelativeLoadOrder.BEFORE load = PaperPluginDescription.RelativeLoadOrder.BEFORE
} }
register("PremiumVanish") {
required = false
load = PaperPluginDescription.RelativeLoadOrder.BEFORE
}
register("SlimeWorldManager") { register("SlimeWorldManager") {
required = false required = false
load = PaperPluginDescription.RelativeLoadOrder.AFTER load = PaperPluginDescription.RelativeLoadOrder.AFTER
} }
register("SuperVanish") {
required = false
load = PaperPluginDescription.RelativeLoadOrder.BEFORE
}
register("Vault") { register("Vault") {
required = false required = false
load = PaperPluginDescription.RelativeLoadOrder.BEFORE load = PaperPluginDescription.RelativeLoadOrder.BEFORE

View File

@ -109,7 +109,6 @@ public class Plex extends JavaPlugin
commands.load(false); commands.load(false);
sqlConnection = new SQLConnection(); sqlConnection = new SQLConnection();
// mongoConnection = new MongoConnection();
redisConnection = new RedisConnection(); redisConnection = new RedisConnection();
playerCache = new PlayerCache(); playerCache = new PlayerCache();
@ -153,6 +152,13 @@ public class Plex extends JavaPlugin
PlexLog.debug("Not hooking into Prism"); PlexLog.debug("Not hooking into Prism");
} }
if (PlexUtils.hasVanishPlugin())
{
PlexLog.log("Hooked into SuperVanish / PremiumVanish!");
} else {
PlexLog.debug("Not hooking into SuperVanish / PremiumVanish");
}
updateChecker = new UpdateChecker(); updateChecker = new UpdateChecker();
PlexLog.log("Update checking enabled"); PlexLog.log("Update checking enabled");

View File

@ -33,11 +33,6 @@ public class PlexLibraryManager implements PluginLoader
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-servlet:11.0.19"), null));
resolver.addDependency(new Dependency(new DefaultArtifact("org.eclipse.jetty:jetty-proxy:11.0.19"), null)); resolver.addDependency(new Dependency(new DefaultArtifact("org.eclipse.jetty:jetty-proxy:11.0.19"), null));
} }
if (new File("plugins/Plex/modules/Module-DiscordSRV.jar").isFile())
{
resolver.addRepository(new RemoteRepository.Builder("discordsrv", "default", "https://nexus.scarsz.me/content/groups/public/").build());
resolver.addDependency(new Dependency(new DefaultArtifact("com.discordsrv:discordsrv:1.27.0"), null));
}
classpathBuilder.addLibrary(resolver); classpathBuilder.addLibrary(resolver);
} }

View File

@ -1,6 +1,5 @@
package dev.plex.command.impl; package dev.plex.command.impl;
import dev.plex.Plex;
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;
@ -14,17 +13,7 @@ import dev.plex.util.BungeeUtil;
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 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;
@ -32,7 +21,12 @@ 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;
@CommandParameters(name = "ban", usage = "/<command> <player> [-nrb] [reason] [-nrb]", aliases = "offlineban,gtfo", description = "Bans a player, offline or online") import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.util.Collections;
import java.util.List;
@CommandParameters(name = "ban", usage = "/<command> <player> [reason] [-rb]", 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
@ -64,17 +58,17 @@ 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; boolean rollBack = false;
if (args.length > 1) if (args.length > 1)
{ {
reason = StringUtils.join(args, " ", 1, args.length); reason = StringUtils.join(args, " ", 1, args.length);
String newReason = StringUtils.normalizeSpace(reason.replace("-nrb", "")); String newReason = StringUtils.normalizeSpace(reason.replace("-rb", ""));
punishment.setReason(newReason.trim().isEmpty() ? "No reason provided." : newReason); punishment.setReason(newReason.trim().isEmpty() ? messageString("noReasonProvided") : newReason);
rollBack = !reason.startsWith("-nrb") && !reason.endsWith("-nrb"); rollBack = reason.startsWith("-rb") || reason.endsWith("-rb");
} }
else else
{ {
punishment.setReason("No reason provided."); punishment.setReason(messageString("noReasonProvided"));
} }
punishment.setPunishedUsername(plexPlayer.getName()); punishment.setPunishedUsername(plexPlayer.getName());
ZonedDateTime date = ZonedDateTime.now(ZoneId.of(TimeUtils.TIMEZONE)); ZonedDateTime date = ZonedDateTime.now(ZoneId.of(TimeUtils.TIMEZONE));
@ -84,7 +78,7 @@ public class BanCMD extends PlexCommand
punishment.setIp(player != null ? player.getAddress().getAddress().getHostAddress().trim() : plexPlayer.getIps().get(plexPlayer.getIps().size() - 1)); punishment.setIp(player != null ? player.getAddress().getAddress().getHostAddress().trim() : plexPlayer.getIps().get(plexPlayer.getIps().size() - 1));
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.getGlobalRegionScheduler().execute(plugin, () ->
{ {
if (player != null) if (player != null)
{ {
@ -95,7 +89,7 @@ public class BanCMD extends PlexCommand
if (rollBack) if (rollBack)
{ {
if (plugin.getPrismHook().hasPrism()) /*if (plugin.getPrismHook() != null && plugin.getPrismHook().hasPrism())
{ {
PrismParameters parameters = plugin.getPrismHook().prismApi().createParameters(); PrismParameters parameters = plugin.getPrismHook().prismApi().createParameters();
parameters.addActionType("block-place"); parameters.addActionType("block-place");
@ -120,9 +114,9 @@ public class BanCMD extends PlexCommand
} }
}); });
} }
else if (plugin.getCoreProtectHook().hasCoreProtect()) else */
if (plugin.getCoreProtectHook() != null && plugin.getCoreProtectHook().hasCoreProtect())
{ {
PlexLog.debug("Testing coreprotect");
Bukkit.getAsyncScheduler().runNow(plugin, scheduledTask -> Bukkit.getAsyncScheduler().runNow(plugin, scheduledTask ->
{ {
plugin.getCoreProtectHook().coreProtectAPI().performRollback(86400, Collections.singletonList(plexPlayer.getName()), null, null, null, null, 0, null); plugin.getCoreProtectHook().coreProtectAPI().performRollback(86400, Collections.singletonList(plexPlayer.getName()), null, null, null, null, 0, null);
@ -141,9 +135,9 @@ public class BanCMD extends PlexCommand
{ {
return PlexUtils.getPlayerNameList(); return PlexUtils.getPlayerNameList();
} }
if (args.length != 1 && silentCheckPermission(sender, this.getPermission())) if (args.length > 1 && silentCheckPermission(sender, this.getPermission()))
{ {
return Collections.singletonList("-nrb"); return Collections.singletonList("-rb");
} }
return Collections.emptyList(); return Collections.emptyList();
} }

View File

@ -0,0 +1,61 @@
package dev.plex.command.impl;
import com.google.common.collect.ImmutableList;
import dev.plex.command.PlexCommand;
import dev.plex.command.annotation.CommandParameters;
import dev.plex.command.annotation.CommandPermissions;
import dev.plex.punishment.Punishment;
import net.kyori.adventure.text.Component;
import org.apache.commons.lang3.StringUtils;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
@CommandParameters(name = "banlist", description = "Manages the banlist", usage = "/<command> [purge]")
@CommandPermissions(permission = "plex.banlist")
public class BanListCommand extends PlexCommand
{
@Override
protected Component execute(@NotNull CommandSender sender, @Nullable Player player, @NotNull String[] args)
{
if (args.length == 0)
{
plugin.getPunishmentManager().getActiveBans().whenComplete((punishments, throwable) ->
{
send(sender, mmString("<gold>Active Bans (" + punishments.size() + "): <yellow>" + StringUtils.join(punishments.stream().map(Punishment::getPunishedUsername).collect(Collectors.toList()), ", ")));
});
return null;
}
if (args[0].equalsIgnoreCase("purge") || args[0].equalsIgnoreCase("clear"))
{
if (sender instanceof Player)
{
return messageComponent("noPermissionInGame");
}
if (!sender.getName().equalsIgnoreCase("console"))
{
if (!checkPermission(sender, "plex.banlist.clear"))
{
return null;
}
}
plugin.getPunishmentManager().getActiveBans().whenComplete((punishments, throwable) ->
{
punishments.forEach(plugin.getPunishmentManager()::unban);
send(sender, mmString("<gold>Unbanned " + punishments.size() + " players."));
});
}
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, "plex.banlist.clear") ? List.of("purge", "clear") : ImmutableList.of();
}
}

View File

@ -0,0 +1,59 @@
package dev.plex.command.impl;
import com.google.common.collect.ImmutableList;
import dev.plex.cache.DataUtils;
import dev.plex.command.PlexCommand;
import dev.plex.command.annotation.CommandParameters;
import dev.plex.command.annotation.CommandPermissions;
import dev.plex.command.exception.PlayerNotFoundException;
import dev.plex.command.source.RequiredCommandSource;
import dev.plex.meta.PlayerMeta;
import dev.plex.player.PlexPlayer;
import dev.plex.util.PlexUtils;
import net.kyori.adventure.text.Component;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.List;
@CommandPermissions(permission = "plex.broadcastloginmessage", source = RequiredCommandSource.ANY)
@CommandParameters(name = "bcastloginmessage", usage = "/<command> <player>", description = "Broadcast your login message (for vanish support)", aliases = "bcastlm")
public class BcastLoginMessageCMD extends PlexCommand
{
@Override
protected Component execute(@NotNull CommandSender sender, @Nullable Player playerSender, String[] args)
{
if (args.length == 0)
{
return usage();
}
PlexPlayer plexPlayer = DataUtils.getPlayer(args[0]);
if (plexPlayer == null)
{
throw new PlayerNotFoundException();
}
String loginMessage = PlayerMeta.getLoginMessage(plexPlayer);
if (!loginMessage.isEmpty())
{
PlexUtils.broadcast(PlexUtils.stringToComponent(loginMessage));
PlexUtils.broadcast(messageComponent("loginMessage", plexPlayer.getName()));
}
else
{
return mmString("<red>This player does not have a login message.");
}
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

@ -41,9 +41,9 @@ public class DebugCMD extends PlexCommand
if (plugin.getRedisConnection().getJedis().exists(player.getUniqueId().toString())) if (plugin.getRedisConnection().getJedis().exists(player.getUniqueId().toString()))
{ {
plugin.getRedisConnection().getJedis().del(player.getUniqueId().toString()); plugin.getRedisConnection().getJedis().del(player.getUniqueId().toString());
return componentFromString("Successfully reset " + player.getName() + "'s Redis punishments!").color(NamedTextColor.YELLOW); return messageComponent("redisResetSuccessful", player.getName());
} }
return componentFromString("Couldn't find player in Redis punishments."); return messageComponent("redisResetPlayerNotFound");
} }
} }
if (args[0].equalsIgnoreCase("gamerules")) if (args[0].equalsIgnoreCase("gamerules"))
@ -62,7 +62,7 @@ public class DebugCMD extends PlexCommand
PlexLog.log("Set specific gamerules for world: " + world.toLowerCase(Locale.ROOT)); PlexLog.log("Set specific gamerules for world: " + world.toLowerCase(Locale.ROOT));
} }
} }
return mmString("<aqua>Re-applied game all the game rules!"); return messageComponent("reappliedGamerules");
} }
if (args[0].equalsIgnoreCase("aliases")) if (args[0].equalsIgnoreCase("aliases"))
{ {
@ -72,9 +72,9 @@ public class DebugCMD extends PlexCommand
Command command = plugin.getServer().getCommandMap().getCommand(commandName); Command command = plugin.getServer().getCommandMap().getCommand(commandName);
if (command == null) if (command == null)
{ {
return mmString("<red>That command could not be found!"); return messageComponent("commandNotFound");
} }
return mmString("<aqua>Aliases for " + commandName + " are: " + Arrays.toString(command.getAliases().toArray(new String[0]))); return messageComponent("commandAliases", commandName, Arrays.toString(command.getAliases().toArray(new String[0])));
} }
} }
if (args[0].equalsIgnoreCase("pagination")) if (args[0].equalsIgnoreCase("pagination"))
@ -94,4 +94,4 @@ public class DebugCMD extends PlexCommand
{ {
return args.length == 1 && silentCheckPermission(sender, this.getPermission()) ? PlexUtils.getPlayerNameList() : ImmutableList.of(); return args.length == 1 && silentCheckPermission(sender, this.getPermission()) ? PlexUtils.getPlayerNameList() : ImmutableList.of();
} }
} }

View File

@ -134,7 +134,7 @@ public class EntityWipeCMD extends PlexCommand
} }
catch (NumberFormatException ex) catch (NumberFormatException ex)
{ {
sender.sendMessage(mmString("<red>" + string + "<red> is not a valid number!")); sender.sendMessage(messageComponent("notANumber", string));
} }
return null; return null;
} }
@ -155,4 +155,4 @@ public class EntityWipeCMD extends PlexCommand
} }
return true; return true;
} }
} }

View File

@ -41,11 +41,12 @@ public class FreezeCMD extends PlexCommand
Punishment punishment = new Punishment(punishedPlayer.getUuid(), getUUID(sender)); Punishment punishment = new Punishment(punishedPlayer.getUuid(), getUUID(sender));
punishment.setCustomTime(false); punishment.setCustomTime(false);
ZonedDateTime date = ZonedDateTime.now(ZoneId.of(TimeUtils.TIMEZONE)); ZonedDateTime date = ZonedDateTime.now(ZoneId.of(TimeUtils.TIMEZONE));
punishment.setEndDate(date.plusMinutes(5)); punishment.setEndDate(date.plusSeconds(plugin.config.getInt("punishments.freeze-timer", 300)));
punishment.setType(PunishmentType.FREEZE); punishment.setType(PunishmentType.FREEZE);
punishment.setPunishedUsername(player.getName()); punishment.setPunishedUsername(player.getName());
punishment.setIp(player.getAddress().getAddress().getHostAddress().trim()); punishment.setIp(player.getAddress().getAddress().getHostAddress().trim());
punishment.setReason(""); punishment.setReason("");
punishment.setActive(true);
plugin.getPunishmentManager().punish(punishedPlayer, punishment); plugin.getPunishmentManager().punish(punishedPlayer, punishment);
PlexUtils.broadcast(messageComponent("frozePlayer", sender.getName(), player.getName())); PlexUtils.broadcast(messageComponent("frozePlayer", sender.getName(), player.getName()));

View File

@ -38,7 +38,7 @@ public class KickCMD extends PlexCommand
} }
PlexPlayer plexPlayer = DataUtils.getPlayer(args[0]); PlexPlayer plexPlayer = DataUtils.getPlayer(args[0]);
String reason = "No reason provided"; String reason = messageString("noReasonProvided");
if (plexPlayer == null) if (plexPlayer == null)
{ {
@ -74,4 +74,4 @@ public class KickCMD extends PlexCommand
{ {
return args.length == 1 && silentCheckPermission(sender, this.getPermission()) ? PlexUtils.getPlayerNameList() : ImmutableList.of(); return args.length == 1 && silentCheckPermission(sender, this.getPermission()) ? PlexUtils.getPlayerNameList() : ImmutableList.of();
} }
} }

View File

@ -2,9 +2,11 @@ package dev.plex.command.impl;
import com.google.common.collect.Lists; import com.google.common.collect.Lists;
import dev.plex.command.PlexCommand; import dev.plex.command.PlexCommand;
import dev.plex.util.PlexUtils;
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.hook.VaultHook; import dev.plex.hook.VaultHook;
import dev.plex.meta.PlayerMeta;
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;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
@ -16,7 +18,7 @@ import org.jetbrains.annotations.Nullable;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
@CommandParameters(name = "list", description = "Show a list of all online players", usage = "/<command> [-d]", aliases = "lsit,who,playerlist,online") @CommandParameters(name = "list", description = "Show a list of all online players", usage = "/<command> [-d | -v]", aliases = "lsit,who,playerlist,online")
@CommandPermissions(permission = "plex.list") @CommandPermissions(permission = "plex.list")
public class ListCMD extends PlexCommand public class ListCMD extends PlexCommand
{ {
@ -24,18 +26,17 @@ public class ListCMD extends PlexCommand
protected Component execute(@NotNull CommandSender sender, @Nullable Player playerSender, String[] args) protected Component execute(@NotNull CommandSender sender, @Nullable Player playerSender, String[] args)
{ {
List<Player> players = Lists.newArrayList(Bukkit.getOnlinePlayers()); List<Player> players = Lists.newArrayList(Bukkit.getOnlinePlayers());
if (args.length > 0 && args[0].equalsIgnoreCase("-v"))
{
checkPermission(sender, "plex.list.vanished");
players.removeIf(player -> !PlayerMeta.isVanished(player));
}
else
{
players.removeIf(PlayerMeta::isVanished);
}
Component list = Component.empty(); Component list = Component.empty();
Component header = Component.text("There " + (players.size() == 1 ? "is" : "are") + " currently").color(NamedTextColor.GRAY) Component header = PlexUtils.messageComponent(players.size() == 1 ? "listHeader" : "listHeaderPlural", players.size(), Bukkit.getMaxPlayers());
.append(Component.space())
.append(Component.text(players.size()).color(NamedTextColor.YELLOW))
.append(Component.space())
.append(Component.text(players.size() == 1 ? "player" : "players").color(NamedTextColor.GRAY))
.append(Component.space())
.append(Component.text("online out of").color(NamedTextColor.GRAY))
.append(Component.space())
.append(Component.text(Bukkit.getMaxPlayers()).color(NamedTextColor.YELLOW))
.append(Component.space())
.append(Component.text(Bukkit.getMaxPlayers() == 1 ? "player." : "players.").color(NamedTextColor.GRAY));
send(sender, header); send(sender, header);
if (players.isEmpty()) if (players.isEmpty())
{ {
@ -69,7 +70,7 @@ public class ListCMD extends PlexCommand
{ {
if (args.length == 1 && silentCheckPermission(sender, this.getPermission())) if (args.length == 1 && silentCheckPermission(sender, this.getPermission()))
{ {
return Collections.singletonList("-d"); return List.of("-d", "-v");
} }
return Collections.emptyList(); return Collections.emptyList();
} }

View File

@ -0,0 +1,96 @@
package dev.plex.command.impl;
import dev.plex.command.PlexCommand;
import dev.plex.command.annotation.CommandParameters;
import dev.plex.command.annotation.CommandPermissions;
import dev.plex.command.source.RequiredCommandSource;
import dev.plex.util.PlexUtils;
import net.kyori.adventure.text.Component;
import org.bukkit.Bukkit;
import org.bukkit.Chunk;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
@CommandParameters(name = "moblimit", usage = "/<command> [on | off | setmax <limit>]", aliases = "entitylimit", description = "Manages the mob limit per chunk.")
@CommandPermissions(permission = "plex.moblimit", source = RequiredCommandSource.ANY)
public class MobLimitCMD extends PlexCommand
{
@Override
protected Component execute(@NotNull CommandSender sender, @Nullable Player playerSender, String[] args)
{
if (args.length == 0)
{
Chunk chunk = playerSender != null ? playerSender.getLocation().getChunk() : Bukkit.getWorlds().get(0).getChunkAt(0, 0);
int currentLimit = plugin.config.getInt("entity_limit.max_mobs_per_chunk");
int currentMobCount = (int) Arrays.stream(chunk.getEntities())
.filter(entity -> entity instanceof LivingEntity && !(entity instanceof Player))
.count();
String status = plugin.config.getBoolean("entity_limit.mob_limit_enabled") ? "<green>Enabled" : "<red>Disabled";
return PlexUtils.messageComponent("mobLimitStatus", status, currentMobCount, currentLimit, chunk.getX(), chunk.getZ());
}
switch (args[0].toLowerCase())
{
case "on":
plugin.config.set("entity_limit.mob_limit_enabled", true);
plugin.config.save();
return PlexUtils.messageComponent("mobLimitToggle", "enabled");
case "off":
plugin.config.set("entity_limit.mob_limit_enabled", false);
plugin.config.save();
return PlexUtils.messageComponent("mobLimitToggle", "disabled");
case "setmax":
try
{
if (args.length != 2) return usage();
int newLimit = Integer.parseInt(args[1]);
if (newLimit < 0) throw new NumberFormatException();
int limitCeiling = plugin.config.getInt("entity_limit.mob_limit_ceiling");
if (newLimit > limitCeiling)
{
newLimit = limitCeiling;
sender.sendMessage(PlexUtils.messageComponent("mobLimitCeiling"));
}
plugin.config.set("entity_limit.max_mobs_per_chunk", newLimit);
plugin.config.save();
return PlexUtils.messageComponent("mobLimitSet", newLimit);
}
catch (NumberFormatException e)
{
return PlexUtils.messageComponent("unableToParseNumber", args[1]);
}
default:
return usage();
}
}
@Override
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)
{
return Arrays.asList("on", "off", "setmax");
}
if (args.length == 2 && args[0].equals("setmax"))
{
return Collections.emptyList();
}
return Collections.emptyList();
}
return Collections.emptyList();
}
}

View File

@ -47,11 +47,12 @@ public class MuteCMD extends PlexCommand
Punishment punishment = new Punishment(punishedPlayer.getUuid(), getUUID(sender)); Punishment punishment = new Punishment(punishedPlayer.getUuid(), getUUID(sender));
punishment.setCustomTime(false); punishment.setCustomTime(false);
ZonedDateTime date = ZonedDateTime.now(ZoneId.of(TimeUtils.TIMEZONE)); ZonedDateTime date = ZonedDateTime.now(ZoneId.of(TimeUtils.TIMEZONE));
punishment.setEndDate(date.plusMinutes(5)); punishment.setEndDate(date.plusSeconds(plugin.config.getInt("punishments.mute-timer", 300)));
punishment.setType(PunishmentType.MUTE); punishment.setType(PunishmentType.MUTE);
punishment.setPunishedUsername(player.getName()); punishment.setPunishedUsername(player.getName());
punishment.setIp(player.getAddress().getAddress().getHostAddress().trim()); punishment.setIp(player.getAddress().getAddress().getHostAddress().trim());
punishment.setReason(""); punishment.setReason("");
punishment.setActive(true);
plugin.getPunishmentManager().punish(punishedPlayer, punishment); plugin.getPunishmentManager().punish(punishedPlayer, punishment);
PlexUtils.broadcast(messageComponent("mutedPlayer", sender.getName(), player.getName())); PlexUtils.broadcast(messageComponent("mutedPlayer", sender.getName(), player.getName()));

View File

@ -124,11 +124,11 @@ public class NotesCMD extends PlexCommand
private void readNotes(@NotNull CommandSender sender, PlexPlayer plexPlayer, List<Note> notes) private void readNotes(@NotNull CommandSender sender, PlexPlayer plexPlayer, List<Note> notes)
{ {
AtomicReference<Component> noteList = new AtomicReference<>(Component.text("Player notes for: " + plexPlayer.getName()).color(NamedTextColor.GREEN)); AtomicReference<Component> noteList = new AtomicReference<>(messageComponent("notesHeader", plexPlayer.getName()));
for (Note note : notes) for (Note note : notes)
{ {
Component noteLine = mmString("<gold><!italic>" + note.getId() + " - Written by: " + DataUtils.getPlayer(note.getWrittenBy()).getName() + " on " + TimeUtils.useTimezone(note.getTimestamp())); Component noteLine = messageComponent("notePrefix", note.getId(), DataUtils.getPlayer(note.getWrittenBy()).getName(), TimeUtils.useTimezone(note.getTimestamp()));
noteLine = noteLine.append(mmString("<newline><yellow># " + note.getNote())); noteLine = noteLine.append(messageComponent("noteLine", note.getNote()));
noteList.set(noteList.get().append(Component.newline())); noteList.set(noteList.get().append(Component.newline()));
noteList.set(noteList.get().append(noteLine)); noteList.set(noteList.get().append(noteLine));
} }
@ -152,4 +152,4 @@ public class NotesCMD extends PlexCommand
} }
return Collections.emptyList(); return Collections.emptyList();
} }
} }

View File

@ -11,6 +11,7 @@ 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;
@ -56,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;
} }

View File

@ -78,21 +78,16 @@ public class SmiteCMD extends PlexCommand
final Player player = getNonNullPlayer(args[0]); final Player player = getNonNullPlayer(args[0]);
final PlexPlayer plexPlayer = getPlexPlayer(player); final PlexPlayer plexPlayer = getPlexPlayer(player);
Title title = Title.title(Component.text("You've been smitten.").color(NamedTextColor.RED), Component.text("Be sure to follow the rules!").color(NamedTextColor.YELLOW)); Title title = Title.title(messageComponent("smiteTitleHeader"), messageComponent("smiteTitleMessage", reason, sender.getName()));
player.showTitle(title); player.showTitle(title);
if (!silent) if (!silent)
{ {
PlexUtils.broadcast(mmString("<red>" + player.getName() + " has been a naughty, naughty boy.")); PlexUtils.broadcast(messageComponent("smiteBroadcast", player.getName(), reason != null ? reason : messageString("noReasonProvided"), sender.getName()));
if (reason != null)
{
PlexUtils.broadcast(mmString(" <red>Reason: " + "<yellow>" + reason));
}
PlexUtils.broadcast(mmString(" <red>Smitten by: " + "<yellow>" + sender.getName()));
} }
else else
{ {
send(sender, "Smitten " + player.getName() + " quietly."); send(sender, messageComponent("smittenQuietly", player.getName()));
} }
// Set gamemode to survival // Set gamemode to survival
@ -129,8 +124,8 @@ public class SmiteCMD extends PlexCommand
if (reason != null) if (reason != null)
{ {
punishment.setReason(reason); punishment.setReason(reason);
send(player, mmString("<red>You've been smitten. Reason: <yellow>" + reason));
} }
send(player, messageComponent("smitten", reason != null ? reason : messageString("noReasonProvided")));
return null; return null;
} }
@ -143,4 +138,4 @@ public class SmiteCMD extends PlexCommand
} }
return Collections.emptyList(); return Collections.emptyList();
} }
} }

View File

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

View File

@ -25,7 +25,7 @@ import org.jetbrains.annotations.Nullable;
import java.util.Collections; 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] [-rb]", description = "Temporarily ban a player")
@CommandPermissions(permission = "plex.tempban", source = RequiredCommandSource.ANY) @CommandPermissions(permission = "plex.tempban", source = RequiredCommandSource.ANY)
public class TempbanCMD extends PlexCommand public class TempbanCMD extends PlexCommand
@ -53,17 +53,17 @@ 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; boolean rollBack = false;
if (args.length > 2) if (args.length > 2)
{ {
reason = StringUtils.join(args, " ", 2, args.length); reason = StringUtils.join(args, " ", 2, args.length);
String newReason = StringUtils.normalizeSpace(reason.replace("-nrb", "")); String newReason = StringUtils.normalizeSpace(reason.replace("-nrb", ""));
punishment.setReason(newReason.trim().isEmpty() ? "No reason provided." : newReason); punishment.setReason(newReason.trim().isEmpty() ? messageString("noReasonProvided") : newReason);
rollBack = !reason.startsWith("-nrb") && !reason.endsWith("-nrb"); rollBack = reason.startsWith("-rb") || reason.endsWith("-rb");
} }
else else
{ {
punishment.setReason("No reason provided."); punishment.setReason(messageString("noReasonProvided"));
} }
punishment.setPunishedUsername(target.getName()); punishment.setPunishedUsername(target.getName());
punishment.setEndDate(TimeUtils.createDate(args[1])); punishment.setEndDate(TimeUtils.createDate(args[1]));
@ -104,7 +104,7 @@ public class TempbanCMD extends PlexCommand
}); });
} }
else */ else */
if (plugin.getCoreProtectHook().hasCoreProtect()) if (plugin.getCoreProtectHook() != null && plugin.getCoreProtectHook().hasCoreProtect())
{ {
PlexLog.debug("Testing coreprotect"); PlexLog.debug("Testing coreprotect");
Bukkit.getAsyncScheduler().runNow(plugin, scheduledTask -> Bukkit.getAsyncScheduler().runNow(plugin, scheduledTask ->

View File

@ -0,0 +1,92 @@
package dev.plex.command.impl;
import com.google.common.collect.ImmutableList;
import dev.plex.command.PlexCommand;
import dev.plex.command.annotation.CommandParameters;
import dev.plex.command.annotation.CommandPermissions;
import dev.plex.player.PlexPlayer;
import dev.plex.punishment.Punishment;
import dev.plex.punishment.PunishmentType;
import dev.plex.util.PlexUtils;
import dev.plex.util.TimeUtils; // Import your TimeUtils
import net.kyori.adventure.text.Component;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.time.ZonedDateTime;
import java.util.Arrays;
import java.util.List;
@CommandParameters(name = "tempmute", description = "Temporarily mute a player on the server",
usage = "/<command> <player> <time> [reason]", aliases = "tmute")
@CommandPermissions(permission = "plex.tempmute")
public class TempmuteCMD extends PlexCommand
{
@Override
protected Component execute(@NotNull CommandSender sender, @Nullable Player playerSender, String[] args)
{
if (args.length < 2)
{
return usage();
}
Player player = getNonNullPlayer(args[0]);
PlexPlayer punishedPlayer = getOfflinePlexPlayer(player.getUniqueId());
if (punishedPlayer.isMuted())
{
return messageComponent("playerMuted");
}
if (silentCheckPermission(player, "plex.tempmute"))
{
send(sender, messageComponent("higherRankThanYou"));
return null;
}
ZonedDateTime endDate;
try
{
endDate = TimeUtils.createDate(args[1]);
}
catch (NumberFormatException e)
{
return messageComponent("invalidTimeFormat");
}
if (endDate.isBefore(ZonedDateTime.now()))
{
return messageComponent("timeMustBeFuture");
}
ZonedDateTime oneWeekFromNow = ZonedDateTime.now().plusWeeks(1);
if (endDate.isAfter(oneWeekFromNow))
{
return messageComponent("maxTimeExceeded");
}
final String reason = args.length >= 3 ? String.join(" ", Arrays.copyOfRange(args, 2, args.length))
: messageString("noReasonProvided");
Punishment punishment = new Punishment(punishedPlayer.getUuid(), getUUID(sender));
punishment.setCustomTime(true);
punishment.setEndDate(endDate);
punishment.setType(PunishmentType.MUTE);
punishment.setPunishedUsername(player.getName());
punishment.setIp(player.getAddress().getAddress().getHostAddress().trim());
punishment.setReason(reason);
punishment.setActive(true);
plugin.getPunishmentManager().punish(punishedPlayer, punishment);
PlexUtils.broadcast(messageComponent("tempMutedPlayer", sender.getName(), player.getName(), TimeUtils.formatRelativeTime(endDate)));
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

@ -32,6 +32,8 @@ public class ToggleCMD extends PlexCommand
sender.sendMessage(PlexUtils.mmDeserialize("<gray> - Fluidspread" + status("fluidspread"))); sender.sendMessage(PlexUtils.mmDeserialize("<gray> - Fluidspread" + status("fluidspread")));
sender.sendMessage(PlexUtils.mmDeserialize("<gray> - Drops" + status("drops"))); sender.sendMessage(PlexUtils.mmDeserialize("<gray> - Drops" + status("drops")));
sender.sendMessage(PlexUtils.mmDeserialize("<gray> - Redstone" + status("redstone"))); sender.sendMessage(PlexUtils.mmDeserialize("<gray> - Redstone" + status("redstone")));
sender.sendMessage(PlexUtils.mmDeserialize("<gray> - PVP" + status("pvp")));
sender.sendMessage(PlexUtils.mmDeserialize("<gray> - Chat" + status("chat")));
return null; return null;
} }
switch (args[0].toLowerCase()) switch (args[0].toLowerCase())
@ -52,6 +54,15 @@ public class ToggleCMD extends PlexCommand
{ {
return toggle("redstone"); return toggle("redstone");
} }
case "pvp" ->
{
return toggle("pvp");
}
case "chat" ->
{
PlexUtils.broadcast(PlexUtils.messageComponent("chatToggled", sender.getName(), plugin.toggles.getBoolean("chat") ? "off" : "on"));
return toggle("chat");
}
default -> default ->
{ {
return messageComponent("invalidToggle"); return messageComponent("invalidToggle");

View File

@ -1,11 +1,14 @@
package dev.plex.command.impl; package dev.plex.command.impl;
import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableList;
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.exception.CommandFailException; import dev.plex.command.exception.CommandFailException;
import dev.plex.command.exception.PlayerNotFoundException;
import dev.plex.player.PlexPlayer; import dev.plex.player.PlexPlayer;
import dev.plex.punishment.PunishmentType;
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;
@ -26,14 +29,22 @@ public class UnfreezeCMD extends PlexCommand
{ {
return usage(); return usage();
} }
Player player = getNonNullPlayer(args[0]); PlexPlayer punishedPlayer = DataUtils.getPlayer(args[0]);
PlexPlayer punishedPlayer = getOfflinePlexPlayer(player.getUniqueId()); if (punishedPlayer == null)
{
throw new PlayerNotFoundException();
}
if (!punishedPlayer.isFrozen()) if (!punishedPlayer.isFrozen())
{ {
throw new CommandFailException(PlexUtils.messageString("playerNotFrozen")); throw new CommandFailException(PlexUtils.messageString("playerNotFrozen"));
} }
punishedPlayer.setFrozen(false); punishedPlayer.setFrozen(false);
PlexUtils.broadcast(messageComponent("unfrozePlayer", sender.getName(), player.getName())); punishedPlayer.getPunishments().stream().filter(punishment -> punishment.getType() == PunishmentType.FREEZE && punishment.isActive()).forEach(punishment -> {
punishment.setActive(false);
plugin.getSqlPunishment().updatePunishment(punishment.getType(), false, punishment.getPunished());
});
PlexUtils.broadcast(messageComponent("unfrozePlayer", sender.getName(), punishedPlayer.getName()));
return null; return null;
} }

View File

@ -1,11 +1,14 @@
package dev.plex.command.impl; package dev.plex.command.impl;
import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableList;
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.exception.CommandFailException; import dev.plex.command.exception.CommandFailException;
import dev.plex.command.exception.PlayerNotFoundException;
import dev.plex.player.PlexPlayer; import dev.plex.player.PlexPlayer;
import dev.plex.punishment.PunishmentType;
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;
@ -26,14 +29,22 @@ public class UnmuteCMD extends PlexCommand
{ {
return usage(); return usage();
} }
Player player = getNonNullPlayer(args[0]); PlexPlayer punishedPlayer = DataUtils.getPlayer(args[0]);
PlexPlayer punishedPlayer = getOfflinePlexPlayer(player.getUniqueId()); if (punishedPlayer == null)
{
throw new PlayerNotFoundException();
}
if (!punishedPlayer.isMuted()) if (!punishedPlayer.isMuted())
{ {
throw new CommandFailException(PlexUtils.messageString("playerNotMuted")); throw new CommandFailException(PlexUtils.messageString("playerNotMuted"));
} }
punishedPlayer.setMuted(false); punishedPlayer.setMuted(false);
PlexUtils.broadcast(messageComponent("unmutedPlayer", sender.getName(), player.getName())); punishedPlayer.getPunishments().stream().filter(punishment -> punishment.getType() == PunishmentType.MUTE && punishment.isActive()).forEach(punishment -> {
punishment.setActive(false);
plugin.getSqlPunishment().updatePunishment(punishment.getType(), false, punishment.getPunished());
});
PlexUtils.broadcast(messageComponent("unmutedPlayer", sender.getName(), punishedPlayer.getName()));
return null; return null;
} }

View File

@ -16,6 +16,7 @@ import org.jetbrains.annotations.Nullable;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.List;
import java.util.Collections;
@CommandPermissions(permission = "plex.whohas") @CommandPermissions(permission = "plex.whohas")
@CommandParameters(name = "whohas", description = "Returns a list of players with a specific item in their inventory.", usage = "/<command> <material>", aliases = "wh") @CommandParameters(name = "whohas", description = "Returns a list of players with a specific item in their inventory.", usage = "/<command> <material>", aliases = "wh")
@ -36,17 +37,43 @@ public class WhoHasCMD extends PlexCommand
return messageComponent("materialNotFound", args[0]); return messageComponent("materialNotFound", args[0]);
} }
final List<TextComponent> players = Bukkit.getOnlinePlayers().stream().filter(player -> boolean clearInventory = args.length > 1 && args[1].equalsIgnoreCase("clear");
player.getInventory().contains(material)).map(player -> Component.text(player.getName())).toList();
return players.isEmpty() ? messageComponent("nobodyHasThatMaterial") : if (clearInventory && !sender.hasPermission("plex.whohas.clear"))
messageComponent("playersWithMaterial", Component.text(material.name()), {
Component.join(JoinConfiguration.commas(true), players)); return messageComponent("noPermissionNode", "plex.whohas.clear");
}
List<TextComponent> players = Bukkit.getOnlinePlayers().stream().filter(player ->
player.getInventory().contains(material)).map(player -> {
if (clearInventory)
{
player.getInventory().remove(material);
player.updateInventory();
}
return Component.text(player.getName());
}).toList();
return players.isEmpty() ?
messageComponent("nobodyHasThatMaterial") :
(clearInventory ?
messageComponent("playersMaterialCleared", Component.text(material.name()),
Component.join(JoinConfiguration.commas(true), players)) :
messageComponent("playersWithMaterial", Component.text(material.name()),
Component.join(JoinConfiguration.commas(true), players)));
} }
@Override @Override
public @NotNull List<String> smartTabComplete(@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, this.getPermission()) ? Arrays.stream(Material.values()).map(Enum::name).toList() : ImmutableList.of(); if (args.length == 1 && silentCheckPermission(sender, this.getPermission()))
{
return Arrays.stream(Material.values()).map(Enum::name).toList();
}
else if (args.length == 2 && silentCheckPermission(sender, "plex.whohas.clear"))
{
return Collections.singletonList("clear");
}
return ImmutableList.of();
} }
} }

View File

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

View File

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

@ -1,6 +1,7 @@
package dev.plex.listener.impl; package dev.plex.listener.impl;
import dev.plex.listener.PlexListener; import dev.plex.listener.PlexListener;
import dev.plex.util.PlexUtils;
import dev.plex.services.impl.TimingService; import dev.plex.services.impl.TimingService;
import net.kyori.adventure.text.Component; import net.kyori.adventure.text.Component;
import org.bukkit.event.EventHandler; import org.bukkit.event.EventHandler;
@ -19,7 +20,7 @@ public class AntiNukerListener extends PlexListener
if (getCount(event.getPlayer().getUniqueId()) > 200L) if (getCount(event.getPlayer().getUniqueId()) > 200L)
{ {
TimingService.strikes.merge(event.getPlayer().getUniqueId(), 1L, Long::sum); TimingService.strikes.merge(event.getPlayer().getUniqueId(), 1L, Long::sum);
event.getPlayer().kick(Component.text("Please turn off your nuker!")); event.getPlayer().kick(PlexUtils.messageComponent("nukerKickMessage"));
event.setCancelled(true); event.setCancelled(true);
} }
} }
@ -31,7 +32,7 @@ public class AntiNukerListener extends PlexListener
if (getCount(event.getPlayer().getUniqueId()) > 200L) if (getCount(event.getPlayer().getUniqueId()) > 200L)
{ {
TimingService.strikes.merge(event.getPlayer().getUniqueId(), 1L, Long::sum); TimingService.strikes.merge(event.getPlayer().getUniqueId(), 1L, Long::sum);
event.getPlayer().kick(Component.text("Please turn off your nuker!")); event.getPlayer().kick(PlexUtils.messageComponent("nukerKickMessage"));
event.setCancelled(true); event.setCancelled(true);
} }
} }

View File

@ -1,6 +1,7 @@
package dev.plex.listener.impl; package dev.plex.listener.impl;
import dev.plex.listener.PlexListener; import dev.plex.listener.PlexListener;
import dev.plex.util.PlexUtils;
import dev.plex.services.impl.TimingService; import dev.plex.services.impl.TimingService;
import io.papermc.paper.event.player.AsyncChatEvent; import io.papermc.paper.event.player.AsyncChatEvent;
import net.kyori.adventure.text.Component; import net.kyori.adventure.text.Component;
@ -19,7 +20,7 @@ public class AntiSpamListener extends PlexListener
TimingService.spamCooldown.merge(event.getPlayer().getUniqueId(), 1L, Long::sum); TimingService.spamCooldown.merge(event.getPlayer().getUniqueId(), 1L, Long::sum);
if (getCount(event.getPlayer().getUniqueId()) > 8L) if (getCount(event.getPlayer().getUniqueId()) > 8L)
{ {
event.getPlayer().sendMessage(Component.text("Please refrain from spamming messages.").color(NamedTextColor.GRAY)); event.getPlayer().sendMessage(PlexUtils.messageComponent("antiSpamMessage"));
event.setCancelled(true); event.setCancelled(true);
} }
} }
@ -30,7 +31,7 @@ public class AntiSpamListener extends PlexListener
TimingService.spamCooldown.merge(event.getPlayer().getUniqueId(), 1L, Long::sum); TimingService.spamCooldown.merge(event.getPlayer().getUniqueId(), 1L, Long::sum);
if (getCount(event.getPlayer().getUniqueId()) > 8L) if (getCount(event.getPlayer().getUniqueId()) > 8L)
{ {
event.getPlayer().sendMessage(Component.text("Please refrain from spamming commands.").color(NamedTextColor.GRAY)); event.getPlayer().sendMessage(PlexUtils.messageComponent("antiSpamMessage"));
event.setCancelled(true); event.setCancelled(true);
} }
} }

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

@ -3,6 +3,7 @@ package dev.plex.listener.impl;
import dev.plex.listener.PlexListener; import dev.plex.listener.PlexListener;
import dev.plex.util.BlockUtils; import dev.plex.util.BlockUtils;
import dev.plex.util.PlexUtils; import dev.plex.util.PlexUtils;
import org.bukkit.Chunk;
import org.bukkit.Location; import org.bukkit.Location;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.block.Block; import org.bukkit.block.Block;
@ -11,6 +12,7 @@ import org.bukkit.entity.Ageable;
import org.bukkit.entity.Entity; import org.bukkit.entity.Entity;
import org.bukkit.entity.EntityType; import org.bukkit.entity.EntityType;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.entity.LivingEntity;
import org.bukkit.event.Event; import org.bukkit.event.Event;
import org.bukkit.event.EventHandler; import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority; import org.bukkit.event.EventPriority;
@ -70,6 +72,17 @@ public class MobListener extends PlexListener
Collection<Player> coll = location.getNearbyEntitiesByType(Player.class, 10); Collection<Player> coll = location.getNearbyEntitiesByType(Player.class, 10);
PlexUtils.disabledEffectMultiple(coll.toArray(new Player[coll.size()]), location); // dont let intellij auto correct toArray to an empty array (for efficiency) PlexUtils.disabledEffectMultiple(coll.toArray(new Player[coll.size()]), location); // dont let intellij auto correct toArray to an empty array (for efficiency)
} }
if (plugin.config.getBoolean("entity_limit.mob_limit_enabled"))
{
Location location = event.getLocation();
Chunk chunk = location.getChunk();
if (isEntityLimitReached(chunk, plugin.config.getInt("entity_limit.max_mobs_per_chunk")))
{
event.setCancelled(true);
}
}
} }
@EventHandler @EventHandler
@ -135,4 +148,11 @@ public class MobListener extends PlexListener
} }
} }
} }
public static boolean isEntityLimitReached(Chunk chunk, int limit)
{
return Arrays.stream(chunk.getEntities())
.filter(entity -> entity instanceof LivingEntity && !(entity instanceof Player))
.count() >= limit;
}
} }

View File

@ -6,6 +6,7 @@ import dev.plex.meta.PlayerMeta;
import dev.plex.player.PlexPlayer; 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 java.util.List;
import net.kyori.adventure.text.Component; import net.kyori.adventure.text.Component;
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;
@ -18,9 +19,7 @@ import org.bukkit.event.inventory.InventoryCloseEvent;
import org.bukkit.event.player.PlayerJoinEvent; import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.event.player.PlayerQuitEvent; import org.bukkit.event.player.PlayerQuitEvent;
import java.util.List; public class PlayerListener extends PlexListener
public class PlayerListener<T> extends PlexListener
{ {
// setting up a player's data // setting up a player's data
@EventHandler(priority = EventPriority.HIGHEST) @EventHandler(priority = EventPriority.HIGHEST)
@ -63,20 +62,18 @@ public class PlayerListener<T> extends PlexListener
} }
String loginMessage = PlayerMeta.getLoginMessage(plexPlayer); String loginMessage = PlayerMeta.getLoginMessage(plexPlayer);
if (!loginMessage.isEmpty()) if (!loginMessage.isEmpty() && !PlayerMeta.isVanished(player))
{ {
PlexUtils.broadcast(loginMessage); PlexUtils.broadcast(PlexUtils.stringToComponent(loginMessage));
} }
plexPlayer.loadNotes(); plexPlayer.loadNotes();
plugin.getSqlNotes().getNotes(plexPlayer.getUuid()).whenComplete((notes, ex) -> plugin.getSqlNotes().getNotes(plexPlayer.getUuid()).whenComplete((notes, ex) ->
{ {
String plural = notes.size() == 1 ? "note." : "notes.";
if (!notes.isEmpty()) if (!notes.isEmpty())
{ {
PlexUtils.broadcastToAdmins(Component.text(plexPlayer.getName() + " has " + notes.size() + " " + plural).color(NamedTextColor.GOLD), "plex.notes.notify"); PlexUtils.broadcastToAdmins(PlexUtils.messageComponent(notes.size() == 1 ? "playerNoteAlert" : "playerNoteAlertPlural", plexPlayer.getName(), notes.size()), "plex.notes.notify");
PlexUtils.broadcastToAdmins(Component.text("Click to view their " + plural).clickEvent(ClickEvent.runCommand("/notes " + plexPlayer.getName() + " list")).color(NamedTextColor.GOLD), "plex.notes.notify");
} }
}); });
} }
@ -96,7 +93,7 @@ public class PlayerListener<T> extends PlexListener
PlexPlayer player = DataUtils.getPlayer(event.getPlayer().getUniqueId()); PlexPlayer player = DataUtils.getPlayer(event.getPlayer().getUniqueId());
if (player.isLockedUp()) if (player.isLockedUp())
{ {
Bukkit.getScheduler().runTaskLater(plugin, () -> event.getPlayer().openInventory(event.getInventory()), 1L); Bukkit.getGlobalRegionScheduler().runDelayed(plugin, (scheduledTask) -> event.getPlayer().openInventory(event.getInventory()), 1L);
} }
} }

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

@ -1,16 +1,29 @@
package dev.plex.listener.impl; package dev.plex.listener.impl;
import dev.plex.Plex;
import dev.plex.listener.PlexListener; import dev.plex.listener.PlexListener;
import dev.plex.util.PlexUtils;
import io.papermc.paper.event.player.AsyncChatEvent;
import io.papermc.paper.event.player.PrePlayerAttackEntityEvent;
import org.bukkit.Bukkit;
import org.bukkit.command.Command;
import org.bukkit.entity.Player;
import org.bukkit.entity.ThrownPotion;
import org.bukkit.event.EventHandler; import org.bukkit.event.EventHandler;
import org.bukkit.event.block.BlockExplodeEvent; import org.bukkit.event.block.BlockExplodeEvent;
import org.bukkit.event.block.BlockFromToEvent; import org.bukkit.event.block.BlockFromToEvent;
import org.bukkit.event.block.BlockRedstoneEvent; import org.bukkit.event.block.BlockRedstoneEvent;
import org.bukkit.event.entity.EntityExplodeEvent; import org.bukkit.event.entity.*;
import org.bukkit.event.entity.ExplosionPrimeEvent;
import org.bukkit.event.player.PlayerDropItemEvent; import org.bukkit.event.player.PlayerDropItemEvent;
import org.bukkit.event.player.PlayerCommandPreprocessEvent;
import org.bukkit.projectiles.ProjectileSource;
import java.util.List;
public class TogglesListener extends PlexListener public class TogglesListener extends PlexListener
{ {
List<String> commands = plugin.commands.getStringList("block_on_mute");
@EventHandler @EventHandler
public void onExplosionPrime(ExplosionPrimeEvent event) public void onExplosionPrime(ExplosionPrimeEvent event)
{ {
@ -22,7 +35,8 @@ public class TogglesListener extends PlexListener
} }
@EventHandler @EventHandler
public void onBlockExplode(BlockExplodeEvent event) { public void onBlockExplode(BlockExplodeEvent event)
{
if (!plugin.toggles.getBoolean("explosions")) if (!plugin.toggles.getBoolean("explosions"))
{ {
event.getBlock().breakNaturally(); event.getBlock().breakNaturally();
@ -58,6 +72,100 @@ public class TogglesListener extends PlexListener
} }
} }
@EventHandler
public void onChat(AsyncChatEvent event)
{
Player player = event.getPlayer();
if (!plugin.toggles.getBoolean("chat") && !Plex.get().getPermissions().has(player, "plex.mute.bypass"))
{
event.getPlayer().sendMessage(PlexUtils.messageComponent("chatIsOff"));
event.setCancelled(true);
}
}
@EventHandler
public void onCommand(PlayerCommandPreprocessEvent event)
{
Player player = event.getPlayer();
if (!plugin.toggles.getBoolean("chat") && !Plex.get().getPermissions().has(player, "plex.mute.bypass"))
{
String message = event.getMessage();
message = message.replaceAll("\\s.*", "").replaceFirst("/", "");
if (commands.contains(message.toLowerCase()))
{
event.getPlayer().sendMessage(PlexUtils.messageComponent("chatIsOff"));
event.setCancelled(true);
return;
}
for (String command : commands)
{
Command cmd = Bukkit.getCommandMap().getCommand(command);
if (cmd == null)
{
return;
}
if (cmd.getAliases().contains(message.toLowerCase()))
{
event.getPlayer().sendMessage(PlexUtils.messageComponent("chatIsOff"));
event.setCancelled(true);
return;
}
}
}
}
@EventHandler
public void onPlayerAttack(PrePlayerAttackEntityEvent event)
{
if (!plugin.toggles.getBoolean("pvp"))
{
if (event.getAttacked() instanceof Player)
{
event.setCancelled(true);
event.getPlayer().sendMessage(PlexUtils.messageComponent("pvpDisabled"));
}
}
}
@EventHandler
public void onPotionSplash(PotionSplashEvent event)
{
if (!plugin.toggles.getBoolean("pvp"))
{
ProjectileSource shooter = event.getEntity().getShooter();
if (shooter instanceof Player)
{
ThrownPotion potion = event.getPotion();
if (potion.getEffects().stream().anyMatch(effect -> effect.getType().getName().startsWith("HARM") ||
effect.getType().getName().startsWith("POISON")) &&
event.getAffectedEntities().stream().anyMatch(entity -> entity instanceof Player))
{
event.setCancelled(true);
((Player) shooter).sendMessage(PlexUtils.messageComponent("pvpDisabled"));
}
}
}
}
@EventHandler
public void onProjectileHit(ProjectileHitEvent event)
{
if (!plugin.toggles.getBoolean("pvp"))
{
ProjectileSource shooter = event.getEntity().getShooter();
if (shooter instanceof Player && event.getHitEntity() instanceof Player)
{
event.setCancelled(true);
((Player) shooter).sendMessage(PlexUtils.messageComponent("pvpDisabled"));
}
}
}
/* I have no idea if this is the best way to do this /* I have no idea if this is the best way to do this
There is a very weird bug where if you try to create a loop using two repeaters and a lever, after disabling There is a very weird bug where if you try to create a loop using two repeaters and a lever, after disabling
and re-enabling redstone, you are unable to recreate the loop with a lever. Using a redstone torch works fine. and re-enabling redstone, you are unable to recreate the loop with a lever. Using a redstone torch works fine.

View File

@ -0,0 +1,32 @@
package dev.plex.listener.impl;
import de.myzelyam.api.vanish.PlayerShowEvent;
import dev.plex.cache.DataUtils;
import dev.plex.listener.PlexListener;
import dev.plex.meta.PlayerMeta;
import dev.plex.player.PlexPlayer;
import dev.plex.util.PlexUtils;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
public class VanishListener extends PlexListener
{
@EventHandler(priority = EventPriority.MONITOR)
public void onPlayerUnvanish(PlayerShowEvent event)
{
if (!PlexUtils.hasVanishPlugin())
{
return;
}
if (event.isSilent())
{
return;
}
PlexPlayer plexPlayer = DataUtils.getPlayer(event.getPlayer().getUniqueId());
String loginMessage = PlayerMeta.getLoginMessage(plexPlayer);
if (!loginMessage.isEmpty())
{
PlexUtils.broadcast(PlexUtils.stringToComponent(loginMessage));
}
}
}

View File

@ -112,7 +112,8 @@ public class WorldListener extends PlexListener
boolean isFaweCommand = command instanceof PluginIdentifiableCommand && ((PluginIdentifiableCommand) command).getPlugin().equals(Bukkit.getPluginManager().getPlugin("FastAsyncWorldEdit")); boolean isFaweCommand = command instanceof PluginIdentifiableCommand && ((PluginIdentifiableCommand) command).getPlugin().equals(Bukkit.getPluginManager().getPlugin("FastAsyncWorldEdit"));
if (isWeCommand || isFaweCommand || EDIT_COMMANDS.contains(message.toLowerCase())) if (isWeCommand || isFaweCommand || EDIT_COMMANDS.contains(message.toLowerCase()))
{ {
event.getPlayer().sendMessage(Component.text("You do not have permission to use that command in this world.").color(NamedTextColor.RED)); String noEdit = plugin.config.getString("worlds." + event.getPlayer().getWorld().getName().toLowerCase() + ".modification.message");
event.getPlayer().sendMessage(MiniMessage.miniMessage().deserialize(noEdit));
event.setCancelled(true); event.setCancelled(true);
} }
} }
@ -183,4 +184,4 @@ public class WorldListener extends PlexListener
} }
return false; return false;
} }
} }

View File

@ -26,7 +26,7 @@ public class PunishedPlayerMenu extends PageableMenu<Punishment>
@Override @Override
protected ItemStack toItem(Punishment object) protected ItemStack toItem(Punishment object)
{ {
return new ItemBuilder(Material.PAPER).displayName("<!italic><red>" + object.getType().name()).lore("<!italic><red>By: <gold>" + (object.getPunisher() == null ? "CONSOLE" : Plex.get().getSqlPlayerData().getNameByUUID(object.getPunished())), "<!italic><red>Expire(d/s): <gold>" + TimeUtils.useTimezone(object.getEndDate()), "<!italic><red>Reason: <gold>" + object.getReason()).build(); return new ItemBuilder(Material.PAPER).displayName("<!italic><red>" + object.getType().name()).lore("<!italic><red>By: <gold>" + (object.getPunisher() == null ? "CONSOLE" : Plex.get().getSqlPlayerData().getNameByUUID(object.getPunisher())), "<!italic><red>Expire(d/s): <gold>" + TimeUtils.useTimezone(object.getEndDate()), "<!italic><red>Reason: <gold>" + object.getReason()).build();
} }
@Override @Override

View File

@ -7,6 +7,7 @@ import org.bukkit.Material;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.inventory.Inventory; import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.InventoryView; import org.bukkit.inventory.InventoryView;
import org.bukkit.inventory.ItemFlag;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta; import org.bukkit.inventory.meta.ItemMeta;
@ -24,6 +25,8 @@ public class ToggleMenu extends AbstractMenu
resetFluidspreadItem(this.inventory()); resetFluidspreadItem(this.inventory());
resetDropsItem(this.inventory()); resetDropsItem(this.inventory());
resetRedstoneItem(this.inventory()); resetRedstoneItem(this.inventory());
resetPVPItem(this.inventory());
resetChatItem(this.inventory());
} }
private void resetExplosionItem(Inventory inventory) private void resetExplosionItem(Inventory inventory)
@ -66,6 +69,27 @@ public class ToggleMenu extends AbstractMenu
inventory.setItem(3, redstone); inventory.setItem(3, redstone);
} }
private void resetPVPItem(Inventory inventory)
{
ItemStack pvp = new ItemStack(Material.IRON_SWORD);
ItemMeta pvpItemMeta = pvp.getItemMeta();
pvpItemMeta.addItemFlags(ItemFlag.HIDE_ATTRIBUTES);
pvpItemMeta.displayName(PlexUtils.mmDeserialize("<!italic><light_purple>PVP"));
pvpItemMeta.lore(List.of(PlexUtils.mmDeserialize("<!italic><yellow>PVP is " + (plugin.toggles.getBoolean("pvp") ? "<green>enabled" : "<red>disabled"))));
pvp.setItemMeta(pvpItemMeta);
inventory.setItem(4, pvp);
}
private void resetChatItem(Inventory inventory)
{
ItemStack chat = new ItemStack(Material.OAK_SIGN);
ItemMeta chatItemMeta = chat.getItemMeta();
chatItemMeta.displayName(PlexUtils.mmDeserialize("<!italic><light_purple>Toggle chat"));
chatItemMeta.lore(List.of(PlexUtils.mmDeserialize("<!italic><yellow>Chat is currently " + (plugin.toggles.getBoolean("chat") ? "<green>on" : "<red>off"))));
chat.setItemMeta(chatItemMeta);
inventory.setItem(5, chat);
}
@Override @Override
public boolean onClick(InventoryView view, Inventory inventory, Player player, ItemStack clicked) public boolean onClick(InventoryView view, Inventory inventory, Player player, ItemStack clicked)
{ {
@ -93,6 +117,19 @@ public class ToggleMenu extends AbstractMenu
resetRedstoneItem(inventory); resetRedstoneItem(inventory);
player.sendMessage(PlexUtils.mmDeserialize("<gray>Toggled redstone.")); player.sendMessage(PlexUtils.mmDeserialize("<gray>Toggled redstone."));
} }
if (clicked.getType() == Material.IRON_SWORD)
{
plugin.toggles.set("pvp", !plugin.toggles.getBoolean("pvp"));
resetPVPItem(inventory);
player.sendMessage(PlexUtils.mmDeserialize("<gray>Toggled PVP"));
}
if (clicked.getType() == Material.OAK_SIGN)
{
plugin.toggles.set("chat", !plugin.toggles.getBoolean("chat"));
PlexUtils.broadcast(PlexUtils.messageComponent("chatToggled", player.getName(), plugin.toggles.getBoolean("chat") ? "on" : "off"));
resetChatItem(inventory);
player.sendMessage(PlexUtils.mmDeserialize("<gray>Toggled chat."));
}
return true; return true;
} }
} }

View File

@ -10,9 +10,28 @@ import net.kyori.adventure.text.format.NamedTextColor;
import net.kyori.adventure.text.format.TextColor; import net.kyori.adventure.text.format.TextColor;
import net.kyori.adventure.text.minimessage.MiniMessage; import net.kyori.adventure.text.minimessage.MiniMessage;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.bukkit.metadata.MetadataValue;
public class PlayerMeta public class PlayerMeta
{ {
public static boolean isVanished(Player player)
{
for (MetadataValue meta : player.getMetadata("vanished"))
{
if (meta.asBoolean())
{
return true;
}
}
return false;
}
public static boolean isVanished(PlexPlayer player)
{
return isVanished(player.getPlayer());
}
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

@ -4,6 +4,7 @@ import com.google.common.collect.Lists;
import com.google.gson.GsonBuilder; import com.google.gson.GsonBuilder;
import dev.plex.Plex; import dev.plex.Plex;
import dev.plex.punishment.Punishment; import dev.plex.punishment.Punishment;
import dev.plex.punishment.PunishmentType;
import dev.plex.punishment.extra.Note; import dev.plex.punishment.extra.Note;
import dev.plex.storage.annotation.MapObjectList; import dev.plex.storage.annotation.MapObjectList;
import dev.plex.storage.annotation.PrimaryKey; import dev.plex.storage.annotation.PrimaryKey;
@ -79,6 +80,7 @@ public class PlexPlayer
if (loadPunishments) if (loadPunishments)
{ {
this.loadPunishments(); this.loadPunishments();
this.checkMutesAndFreeze();
// this.permissions.addAll(Plex.get().getSqlPermissions().getPermissions(this.uuid)); // this.permissions.addAll(Plex.get().getSqlPermissions().getPermissions(this.uuid));
} }
} }
@ -93,6 +95,12 @@ public class PlexPlayer
return PlainTextComponentSerializer.plainText().serialize(getPlayer().displayName()); return PlainTextComponentSerializer.plainText().serialize(getPlayer().displayName());
} }
public void checkMutesAndFreeze() {
final ZonedDateTime now = ZonedDateTime.now();
this.muted = this.punishments.stream().filter(punishment -> punishment.getType() == PunishmentType.MUTE).anyMatch(punishment -> punishment.isActive() && now.isBefore(punishment.getEndDate()));
this.frozen = this.punishments.stream().filter(punishment -> punishment.getType() == PunishmentType.FREEZE).anyMatch(punishment -> punishment.isActive() && now.isBefore(punishment.getEndDate()));
}
public void loadPunishments() public void loadPunishments()
{ {
this.setPunishments(Plex.get().getSqlPunishment().getPunishments(this.getUuid())); this.setPunishments(Plex.get().getSqlPunishment().getPunishments(this.getUuid()));

View File

@ -147,7 +147,6 @@ public class PunishmentManager implements PlexBase
public Punishment getBanByIP(String ip) 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); 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);
} }
@ -180,6 +179,11 @@ public class PunishmentManager implements PlexBase
return Plex.get().getSqlPunishment().removeBan(uuid); return Plex.get().getSqlPunishment().removeBan(uuid);
} }
public void updateOutdatedPunishments(PlexPlayer player)
{
}
private void doPunishment(PlexPlayer player, Punishment punishment) private void doPunishment(PlexPlayer player, Punishment punishment)
{ {
if (punishment.getType() == PunishmentType.FREEZE) if (punishment.getType() == PunishmentType.FREEZE)
@ -193,13 +197,18 @@ public class PunishmentManager implements PlexBase
@Override @Override
public void run() public void run()
{ {
if (!player.isFrozen()) PlexPlayer afterPlayer = DataUtils.getPlayer(player.getUuid());
if (!afterPlayer.isFrozen())
{ {
this.cancel(); this.cancel();
return; return;
} }
player.setFrozen(false); afterPlayer.setFrozen(false);
Bukkit.broadcast(PlexUtils.messageComponent("unfrozePlayer", "Plex", Bukkit.getOfflinePlayer(player.getUuid()).getName())); punishment.setActive(false);
plugin.getSqlPunishment().updatePunishment(punishment.getType(), false, punishment.getPunished());
DataUtils.update(afterPlayer);
Bukkit.broadcast(PlexUtils.messageComponent("unfrozePlayer", "Plex", Bukkit.getOfflinePlayer(afterPlayer.getUuid()).getName()));
} }
}.runTaskLater(Plex.get(), 20 * seconds); }.runTaskLater(Plex.get(), 20 * seconds);
} }
@ -214,13 +223,17 @@ public class PunishmentManager implements PlexBase
@Override @Override
public void run() public void run()
{ {
if (!player.isMuted()) PlexPlayer afterPlayer = DataUtils.getPlayer(player.getUuid());
if (!afterPlayer.isMuted())
{ {
this.cancel(); this.cancel();
return; return;
} }
player.setMuted(false); afterPlayer.setMuted(false);
Bukkit.broadcast(PlexUtils.messageComponent("unmutedPlayer", "Plex", Bukkit.getOfflinePlayer(player.getUuid()).getName())); punishment.setActive(false);
plugin.getSqlPunishment().updatePunishment(punishment.getType(), false, punishment.getPunished());
Bukkit.broadcast(PlexUtils.messageComponent("unmutedPlayer", "Plex", Bukkit.getOfflinePlayer(afterPlayer.getUuid()).getName()));
} }
}.runTaskLater(Plex.get(), 20 * seconds); }.runTaskLater(Plex.get(), 20 * seconds);
} }

View File

@ -3,6 +3,7 @@ package dev.plex.services.impl;
import dev.plex.Plex; import dev.plex.Plex;
import dev.plex.services.AbstractService; import dev.plex.services.AbstractService;
import dev.plex.util.TimeUtils; import dev.plex.util.TimeUtils;
import dev.plex.util.PlexUtils;
import io.papermc.paper.threadedregions.scheduler.ScheduledTask; import io.papermc.paper.threadedregions.scheduler.ScheduledTask;
import net.kyori.adventure.text.Component; import net.kyori.adventure.text.Component;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
@ -27,7 +28,7 @@ public class BanService extends AbstractService
if (ZonedDateTime.now(ZoneId.of(TimeUtils.TIMEZONE)).isAfter(punishment.getEndDate())) if (ZonedDateTime.now(ZoneId.of(TimeUtils.TIMEZONE)).isAfter(punishment.getEndDate()))
{ {
Plex.get().getPunishmentManager().unban(punishment); Plex.get().getPunishmentManager().unban(punishment);
Bukkit.broadcast(Component.text("Plex - Unbanned " + Bukkit.getOfflinePlayer(punishment.getPunished()).getName())); Bukkit.broadcast(PlexUtils.messageComponent("banExpiredBroadcast", Bukkit.getOfflinePlayer(punishment.getPunished()).getName()));
} }
}); });
}); });

View File

@ -25,7 +25,7 @@ public class SQLPunishment
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(?, ?, ?, ?, ?, ?, ?, ?, ?)";
private static final String UPDATE_BAN = "UPDATE `punishments` SET active=? WHERE active=? AND punished=? AND type=?"; private static final String UPDATE_PUNISHMENT = "UPDATE `punishments` SET active=? WHERE punished=? AND type=?";
public CompletableFuture<List<Punishment>> getPunishments() public CompletableFuture<List<Punishment>> getPunishments()
{ {
@ -145,17 +145,16 @@ public class SQLPunishment
{ {
try (Connection con = Plex.get().getSqlConnection().getCon()) try (Connection con = Plex.get().getSqlConnection().getCon())
{ {
PreparedStatement statement = con.prepareStatement(UPDATE_BAN); PreparedStatement statement = con.prepareStatement(UPDATE_PUNISHMENT);
statement.setBoolean(1, false); statement.setBoolean(1, false);
statement.setBoolean(2, true); statement.setString(2, uuid.toString());
statement.setString(3, uuid.toString()); statement.setString(3, PunishmentType.BAN.name());
statement.setString(4, PunishmentType.BAN.name()); statement.executeUpdate();
PreparedStatement statement1 = con.prepareStatement(UPDATE_BAN); PreparedStatement statement1 = con.prepareStatement(UPDATE_PUNISHMENT);
statement1.setBoolean(1, false); statement1.setBoolean(1, false);
statement1.setBoolean(2, true); statement1.setString(2, uuid.toString());
statement1.setString(3, uuid.toString()); statement1.setString(3, PunishmentType.TEMPBAN.name());
statement1.setString(4, PunishmentType.TEMPBAN.name());
statement1.executeUpdate(); statement1.executeUpdate();
} }
catch (SQLException e) catch (SQLException e)
@ -164,24 +163,41 @@ public class SQLPunishment
} }
} }
public CompletableFuture<Void> updatePunishment(PunishmentType type, boolean active, UUID punished)
{
return CompletableFuture.runAsync(() ->
{
try (Connection con = Plex.get().getSqlConnection().getCon())
{
PreparedStatement statement = con.prepareStatement(UPDATE_PUNISHMENT);
statement.setBoolean(1, active);
statement.setString(2, punished.toString());
statement.setString(3, type.name());
statement.executeUpdate();
}
catch (SQLException e)
{
e.printStackTrace();
}
});
}
public CompletableFuture<Void> removeBan(UUID uuid) public CompletableFuture<Void> removeBan(UUID uuid)
{ {
return CompletableFuture.runAsync(() -> return CompletableFuture.runAsync(() ->
{ {
try (Connection con = Plex.get().getSqlConnection().getCon()) try (Connection con = Plex.get().getSqlConnection().getCon())
{ {
PreparedStatement statement = con.prepareStatement(UPDATE_BAN); PreparedStatement statement = con.prepareStatement(UPDATE_PUNISHMENT);
statement.setBoolean(1, false); statement.setBoolean(1, false);
statement.setBoolean(2, true); statement.setString(2, uuid.toString());
statement.setString(3, uuid.toString()); statement.setString(3, PunishmentType.BAN.name());
statement.setString(4, PunishmentType.BAN.name());
statement.executeUpdate(); statement.executeUpdate();
PreparedStatement statement1 = con.prepareStatement(UPDATE_BAN); PreparedStatement statement1 = con.prepareStatement(UPDATE_PUNISHMENT);
statement1.setBoolean(1, false); statement1.setBoolean(1, false);
statement1.setBoolean(2, true); statement1.setString(2, uuid.toString());
statement1.setString(3, uuid.toString()); statement1.setString(3, PunishmentType.TEMPBAN.name());
statement1.setString(4, PunishmentType.TEMPBAN.name());
statement1.executeUpdate(); statement1.executeUpdate();
} }
catch (SQLException e) catch (SQLException e)
@ -190,4 +206,5 @@ public class SQLPunishment
} }
}); });
} }
} }

View File

@ -4,19 +4,23 @@ import com.google.common.base.CharMatcher;
import com.google.common.collect.Lists; import com.google.common.collect.Lists;
import dev.plex.Plex; import dev.plex.Plex;
import dev.plex.PlexBase; import dev.plex.PlexBase;
import dev.plex.event.BroadcastEvent;
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.Chunk;
import org.bukkit.Location; import org.bukkit.Location;
import org.bukkit.Particle; import org.bukkit.Particle;
import org.bukkit.command.Command; import org.bukkit.command.Command;
import org.bukkit.command.PluginCommandYamlParser; import org.bukkit.command.PluginCommandYamlParser;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.plugin.Plugin; import org.bukkit.plugin.Plugin;
@ -29,6 +33,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
@ -44,6 +49,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);
@ -113,6 +120,15 @@ public class PlexUtils implements PlexBase
return true; return true;
} }
public static boolean hasVanishPlugin()
{
if (Bukkit.getPluginManager().isPluginEnabled("SuperVanish") || Bukkit.getPluginManager().isPluginEnabled("PremiumVanish"))
{
return true;
}
return false;
}
public static boolean isPluginCMD(String cmd, String pluginName) public static boolean isPluginCMD(String cmd, String pluginName)
{ {
Plugin plugin = Bukkit.getServer().getPluginManager().getPlugin(pluginName); Plugin plugin = Bukkit.getServer().getPluginManager().getPlugin(pluginName);
@ -146,6 +162,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>")
@ -275,13 +302,11 @@ public class PlexUtils implements PlexBase
public static void broadcast(String s) public static void broadcast(String s)
{ {
Bukkit.broadcast(MINI_MESSAGE.deserialize(s)); Bukkit.broadcast(MINI_MESSAGE.deserialize(s));
Bukkit.getServer().getPluginManager().callEvent(new BroadcastEvent(null, s));
} }
public static void broadcast(Component component) public static void broadcast(Component component)
{ {
Bukkit.broadcast(component); Bukkit.broadcast(component);
Bukkit.getServer().getPluginManager().callEvent(new BroadcastEvent(component, null));
} }
public static void broadcastToAdmins(Component component, String permission) public static void broadcastToAdmins(Component component, String permission)

View File

@ -7,6 +7,7 @@ import java.time.LocalDateTime;
import java.time.ZoneId; import java.time.ZoneId;
import java.time.ZonedDateTime; import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter; import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Set; import java.util.Set;
@ -79,4 +80,41 @@ public class TimeUtils
} }
return DATE_FORMAT.withZone(ZoneId.of(TIMEZONE)).format(date); return DATE_FORMAT.withZone(ZoneId.of(TIMEZONE)).format(date);
} }
public static String formatRelativeTime(ZonedDateTime date)
{
long seconds = ChronoUnit.SECONDS.between(ZonedDateTime.now(), date);
if (seconds <= 0)
{
return "now";
}
long minute = seconds / 60;
long hour = minute / 60;
long day = hour / 24;
long week = day / 7;
if (week > 0)
{
return week + " week" + (week > 1 ? "s" : "");
}
else if (day > 0)
{
return day + " day" + (day > 1 ? "s" : "");
}
else if (hour > 0)
{
return hour + " hour" + (hour > 1 ? "s" : "");
}
else if (minute > 0)
{
return minute + " minute" + (minute > 1 ? "s" : "");
}
else
{
return seconds + " second" + (seconds > 1 ? "s" : "");
}
}
} }

View File

@ -2,6 +2,7 @@ package dev.plex.util.sql;
import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableList;
import com.google.common.collect.Lists; import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import dev.plex.punishment.PunishmentType; import dev.plex.punishment.PunishmentType;
import dev.plex.storage.annotation.*; import dev.plex.storage.annotation.*;
import dev.plex.util.PlexLog; import dev.plex.util.PlexLog;
@ -13,10 +14,7 @@ import org.jetbrains.annotations.NotNull;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.lang.reflect.Modifier; import java.lang.reflect.Modifier;
import java.time.ZonedDateTime; import java.time.ZonedDateTime;
import java.util.Arrays; import java.util.*;
import java.util.Collection;
import java.util.List;
import java.util.UUID;
import java.util.stream.Collectors; import java.util.stream.Collectors;
/** /**
@ -25,7 +23,7 @@ import java.util.stream.Collectors;
*/ */
public class SQLUtil public class SQLUtil
{ {
public static final List<Table> TABLES = Lists.newArrayList(); public static final Map<String, Table> TABLES = Maps.newHashMap();
public static List<String> createTable(List<String> result, Class<?> clazz) public static List<String> createTable(List<String> result, Class<?> clazz)
{ {
@ -83,7 +81,7 @@ public class SQLUtil
mainResult.append(");"); mainResult.append(");");
result.add(mainResult.toString()); result.add(mainResult.toString());
TABLES.add(table); TABLES.put(table.name(), table);
if (primaryKey == null && !collectionFields.isEmpty()) if (primaryKey == null && !collectionFields.isEmpty())
{ {
@ -113,11 +111,22 @@ public class SQLUtil
writeFieldToSQL(listTable, sql, Mapper.getByClass(finalPrimaryKey.getType()), finalPrimaryKey); writeFieldToSQL(listTable, sql, Mapper.getByClass(finalPrimaryKey.getType()), finalPrimaryKey);
sql.append(");"); sql.append(");");
result.add(sql.toString()); result.add(sql.toString());
table.mappedTables().add(listTable); table.mappedTables().put(field, listTable);
}); });
return result; return result;
} }
public static void update(String tableName, Object object)
{
final Table table = TABLES.get(tableName);
if (table == null)
{
PlexLog.error("Table {0} was not found", tableName);
return;
}
}
private static void writeFieldToSQL(Table table, StringBuilder sb, Mapper mapped, Field field) private static void writeFieldToSQL(Table table, StringBuilder sb, Mapper mapped, Field field)
{ {

View File

@ -5,6 +5,7 @@ import com.google.common.collect.Maps;
import lombok.Data; import lombok.Data;
import lombok.experimental.Accessors; import lombok.experimental.Accessors;
import java.lang.reflect.Field;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
@ -19,5 +20,5 @@ public class Table
{ {
private final String name; private final String name;
private final Map<String, SQLUtil.Mapper> columns = Maps.newHashMap(); private final Map<String, SQLUtil.Mapper> columns = Maps.newHashMap();
private final List<Table> mappedTables = Lists.newArrayList(); private final Map<Field, Table> mappedTables = Maps.newHashMap();
} }

View File

@ -54,10 +54,10 @@ commands:
- "r:a:^(co|core|coreprotect) (rb|rollback|l|lookup|rl|reload):_" - "r:a:^(co|core|coreprotect) (rb|rollback|l|lookup|rl|reload):_"
- "r:e:^[A-z]*:[A-z]*::<gray>Plugin specific commands are disabled." - "r:e:^[A-z]*:[A-z]*::<gray>Plugin specific commands are disabled."
# These commands will be blocked when a player is muted # These commands will be blocked when a player is muted or when chat is toggled off.
block_on_mute: block_on_mute:
- me - me
- say - say
- msg - msg
- reply - reply
- mail - mail

View File

@ -14,6 +14,10 @@ server:
banning: banning:
ban_url: "https://forum.plex.us.org" ban_url: "https://forum.plex.us.org"
punishments:
mute-timer: 300
freeze-timer: 300
chat: chat:
# Should the server use Plex's chat system? It is recommended to keep this on if you are using ranks. # Should the server use Plex's chat system? It is recommended to keep this on if you are using ranks.
# If you are using permissions, you should turn this off and use Vault to handle prefixes with a different chat plugin # If you are using permissions, you should turn this off and use Vault to handle prefixes with a different chat plugin
@ -152,6 +156,15 @@ blocked_entities:
- "ENDER_DRAGON" - "ENDER_DRAGON"
- "MINECART_TNT" - "MINECART_TNT"
# Limit entities per chunk
entity_limit:
# Is the mob limit enabled?
mob_limit_enabled: true
# The maximum number of mobs allowed in a chunk
max_mobs_per_chunk: 50
# The available ceiling for the maximum number of mobs
mob_limit_ceiling: 500
# See https://docs.plex.us.org/docs/customization/config#worlds for documentation # See https://docs.plex.us.org/docs/customization/config#worlds for documentation
# These gamerules apply to all worlds on the server # These gamerules apply to all worlds on the server
global_gamerules: global_gamerules:

View File

@ -27,6 +27,8 @@ indefBanMessageReason: "<red>Your {0} is indefinitely banned! You may appeal at
playerNotFound: "<red>Player not found!" playerNotFound: "<red>Player not found!"
specifyPlayer: "<red>You must specify a player!" specifyPlayer: "<red>You must specify a player!"
worldNotFound: "<red>World not found!" worldNotFound: "<red>World not found!"
# This will always be used for punishments where the sanctioning administrator has not provided a reason. Will ignore MiniMessage tags.
noReasonProvided: "No reason provided."
# 0 - The world you have been teleported to # 0 - The world you have been teleported to
playerWorldTeleport: "<aqua>You have been teleported to {0}." playerWorldTeleport: "<aqua>You have been teleported to {0}."
# 0 - The person who is freezing # 0 - The person who is freezing
@ -41,6 +43,13 @@ mutedPlayer: "<red>{0} - Muted {1}"
# 0 - The command sender # 0 - The command sender
# 1 - The person who has been unmuted # 1 - The person who has been unmuted
unmutedPlayer: "<aqua>{0} - Unmuted {1}" unmutedPlayer: "<aqua>{0} - Unmuted {1}"
invalidTimeFormat: "<red>Invalid time format. Use s, m, h, d, w, mo, or y (e.g., 1h30m)."
timeMustBeFuture: "<red>The specified time must be in the future."
# 0 - The command sender
# 1 - The person who has been muted
# 2 - The time that the person is muted for
tempMutedPlayer: "<red>{0} - Muted {1} for {2}"
maxTimeExceeded: "<red>The specified time must be under a week."
# 0 - The person who is locking up # 0 - The person who is locking up
# 1 - The person who has been locked up # 1 - The person who has been locked up
lockedUpPlayer: "<aqua>{0} - Locking up {1}" lockedUpPlayer: "<aqua>{0} - Locking up {1}"
@ -110,6 +119,11 @@ playerFrozen: "<red>That player is already frozen!"
playerMuted: "<red>That player is already muted!" playerMuted: "<red>That player is already muted!"
playerLockedUp: "<red>That player is already locked up!" playerLockedUp: "<red>That player is already locked up!"
muted: "<red>You are currently muted - STFU!" muted: "<red>You are currently muted - STFU!"
pvpDisabled: "<red>PVP has been disabled!"
chatIsOff: "<red>Chat is currently toggled off!"
# 0 - The command sender
# 1 - The set value of the chat toggle
chatToggled: "<red>{0} - Toggled chat {1}"
# 0 - The command sender # 0 - The command sender
# 1 - The player # 1 - The player
kickedPlayer: "<red>{0} - Kicking {1}" kickedPlayer: "<red>{0} - Kicking {1}"
@ -169,6 +183,18 @@ notAValidMobButValidEntity: "<red>That is a valid entity, but is not a valid mob
# 1 - Number of mobs removed # 1 - Number of mobs removed
removedMobs: "<red>{0} - Removed {1} mobs" removedMobs: "<red>{0} - Removed {1} mobs"
autoWipeDisabled: "<gray>Item wiping is currently disabled in the config!" autoWipeDisabled: "<gray>Item wiping is currently disabled in the config!"
# 0 - The boolean for whether the limit is enabled or disabled
mobLimitToggle: "<gray>The mob limit has been {0}"
# 0 - The amount that the mob limit has been set to
mobLimitSet: "<gray>The mob limit has been set to: <em><white>{0}"
# 0 - The boolean for whether the limit is enabled or disabled
# 1 - The current amount of mobs in the world
# 2 - The current set mob limit
# 3 - Chunk x value
# 4 - Chunk z value
mobLimitStatus: "<gray>({0}<gray>) <em><white>{1} <reset><gray>/ <em><white>{2} <reset><gray>per chunk (<em><white>Chunk<gray>: <reset>{3}, {4}<gray>)"
# 0 - The max set limit in config
mobLimitCeiling: "<gray>The limit you have entered is too high. Defaulting to the ceiling value from config"
commandBlocked: "<gray>That command is blocked." commandBlocked: "<gray>That command is blocked."
# 0 - The command sender # 0 - The command sender
# 1 - The message being said # 1 - The message being said
@ -200,6 +226,57 @@ rankRequired: "<red>Policy requires that you must state your rank in your login
# 0 - The material name # 0 - The material name
# 1 - The players who have the material in their inventory # 1 - The players who have the material in their inventory
playersWithMaterial: "<gray>Players with {0} in their inventory: {1}" playersWithMaterial: "<gray>Players with {0} in their inventory: {1}"
# 0 - The material name
# 1 - The players who have the material in their inventory
playersMaterialCleared: "<gray>{0} has been removed from the following players: {1}"
nobodyHasThatMaterial: "<gray>No one online has that in their inventory." nobodyHasThatMaterial: "<gray>No one online has that in their inventory."
# 0 - The attempted material name # 0 - The attempted material name
materialNotFound: "<red>{0} is not a valid item/block name." materialNotFound: "<red>{0} is not a valid item/block name."
# 0 - The players name
loginMessage: "<yellow>{0} joined the game"
# 0 - The string that wasn't a valid integer
notANumber: "<red>{0} is not a valid number!"
# 0 - Players currently online
# 1 - Max players
listHeader: "<gray>There is currently <yellow>{0}<gray> player online out of <yellow>{1}<gray> players."
# 0 - Players currently online
# 1 - Max players
listHeaderPlural: "<gray>There are currently <yellow>{0}<gray> players online out of <yellow>{1}<gray> players."
# 0 - Player who is having their notes fetched
notesHeader: "Player notes for: <green>{0}"
# 0 - Note ID
# 1 - Author of the note
# 2 - Timestamp
notePrefix: "<gold><!italic>{0} - Written by: {1} on {2}"
# 0 - The content of the note
noteLine: "<newline><yellow># {0}"
# 0 - The player
# 1 - The number of notes logged for said player
playerNoteAlert: "<gold>{0} has {1} note. <click:run_command:/notes {0} list><underlined>Click here to view their note."
# 0 - The player
# 1 - The number of notes logged for said player
playerNoteAlertPlural: "<gold>{0} has {1} notes. <click:run_command:/notes {0} list><underlined>Click here to view their notes."
smiteTitleHeader: "<red>You've been smitten."
# 0 - The reason for the smite. Will default to noReasonProvided if no reason is specified.
# 1 - The admin / staff member
smiteTitleMessage: "<yellow>Be sure to follow the rules!"
# 0 - The player
# 1 - The reason for the smite. Will default to noReasonProvided if no reason is specified.
# 2 - The admin / staff member
smiteBroadcast: "<red>{0} has been a naughty, naughty boy.<newline><red> - Reason: <yellow>{1}<newline><red> - Smitten by: <yellow>{2}"
# 0 - The player
smittenQuietly: "<gray>Smitten {0} quietly."
# 0 - The reason for being smitten
smitten: "<red>You've been smitten. Reason: <yellow>{0}"
nukerKickMessage: "Please turn off your nuker!"
antiSpamMessage: "<gray>Please refrain from spamming messages."
# 0 - The player
banExpiredBroadcast: "Plex - Automatically unbanning {0}"
# 0 - The player
redisResetSuccessful: "<yellow>Successfuly reset {0}'s Redis punishments!"
redisResetPlayerNotFound: "Couldn't find player in Redis punishments."
reappliedGamerules: "<aqua>All game rules have been re-applied!"
commandNotFound: "<red>That command could not be found!"
# 0 - The command
# 1 - A list of aliases found
commandAliases: "<aqua>Aliases for {0} are: {1}"

View File

@ -10,4 +10,10 @@ fluidspread: true
drops: true drops: true
# Should redstone be enabled? # Should redstone be enabled?
redstone: true redstone: true
# Is chat enabled?
chat: true
# Is PVP enabled?
pvp: true