33 Commits
Author SHA1 Message Date
Len 4dba5f3c41 Add RepairCommand 2024-10-04 21:05:26 +02:00
Len dbb3f45898 Move command permissions to EssentiaCommand interface. 2024-10-04 18:34:02 +02:00
Len 162ffd3599 Update GameModeCommand to use native GameModeArgument 2024-10-04 17:04:34 +02:00
Len 430e6fb898 Fix typo in EnchantmentArgument.java 2024-10-04 17:04:34 +02:00
Len aede22811a Add TimeCommand 2024-08-15 21:08:08 +02:00
Len a8221a68af Add reset option to pweather 2024-08-15 17:49:45 +02:00
Len 29559b83c4 Add SetSpawnCommand.java 2024-08-15 17:43:31 +02:00
Len be8b7e20df Add PlayerWeatherCommand.java and WeatherArgument.java 2024-08-15 17:23:12 +02:00
Len 6a8e21852c Add WeatherCommand.java 2024-08-15 17:15:31 +02:00
Len ff2824f287 Switch to brigadier for commands 2024-08-15 15:58:25 +02:00
Len c4055358b1 Add brigadier ArgumentTypes 2024-08-15 15:30:22 +02:00
Len ad7e61ffe8 Use Reflection to load commands. 2024-08-14 20:48:27 +02:00
Len 628e18858a Load more UserSettings in YamlStorageProvider 2024-08-14 20:47:15 +02:00
Len 563d17d53b Use plugin logger. 2024-08-14 20:46:24 +02:00
Len bd3e537199 Remove commands from plugin.yml 2024-08-14 20:43:36 +02:00
Len 3bc58b7f9c Use reflection to load event listeners 2024-08-14 20:43:00 +02:00
Len 52e51f99da Update default storageprovider to YAML. 2024-08-13 21:22:14 +02:00
Len 6a0fdbbc1e Update references to 1.12.1 2024-08-13 21:21:37 +02:00
Len 2df6a71e6a Update archiveFileName in build.gradle.kts 2024-08-12 10:01:45 +02:00
Len e2a32c1ebd Load homes from SQL 2024-08-12 09:53:44 +02:00
Len a7f14eb573 Remove lombok setters 2024-07-28 14:57:48 +02:00
Len cf0bcefd06 Add loading for EssentiaUserSettings 2024-07-28 14:47:49 +02:00
Len fe83919200 Refactor 2024-07-28 12:52:55 +02:00
Len 5cc798c482 Load user data from sql 2024-06-19 10:25:05 +02:00
Len f6dd31ba33 Do not expose saving tasks to the api and change the way saving data is handled. 2024-06-18 10:40:31 +02:00
Len d1872f6e95 Fix saving into sql 2024-06-18 09:53:44 +02:00
Len bacc44b2b9 Load in users and create new users if needed. 2024-06-17 10:56:07 +02:00
Len dacdacf68e Fix Config.java not loading and saving. 2024-06-17 10:12:26 +02:00
Len 2e2d370bc6 initiate and disable storage providers. 2024-06-17 09:29:22 +02:00
Len 5ed4c32cc1 Start working on storage providers. 2024-06-16 23:54:31 +02:00
Len 767d248ac8 Refactor to make use of the new user bean. 2024-06-16 21:30:07 +02:00
Len 41c5725ea8 Add API and beans for User and UserManager. 2024-06-16 20:40:12 +02:00
Len f5da67cc69 Switch to Galaxy 2024-06-16 16:14:27 +02:00
94 changed files with 4532 additions and 1040 deletions
+2 -2
View File
@@ -3,7 +3,7 @@ plugins {
} }
dependencies { dependencies {
compileOnly("com.alttd:Comet-API:1.20.4-R0.1-SNAPSHOT") compileOnly("com.alttd:Galaxy-API:1.21.1-R0.1-SNAPSHOT")
} }
tasks { tasks {
@@ -16,7 +16,7 @@ publishing {
publications { publications {
create<MavenPublication>("mavenJava") { create<MavenPublication>("mavenJava") {
from(components["java"]) from(components["java"])
artifactId = "${rootProject.name}-${project.name}-$version.jar" artifactId = "${project.name}-$version.jar"
} }
} }
} }
@@ -1,4 +1,4 @@
package com.alttd.essentia.events; package com.alttd.essentia.api.events;
import org.bukkit.event.Cancellable; import org.bukkit.event.Cancellable;
import org.bukkit.event.Event; import org.bukkit.event.Event;
@@ -0,0 +1,32 @@
package com.alttd.essentia.api.events;
import com.alttd.essentia.api.user.User;
import org.bukkit.event.HandlerList;
import org.jetbrains.annotations.NotNull;
public class EssentiaUserLoadEvent extends EssentiaEvent {
private static final HandlerList handlerList = new HandlerList();
private final User user;
public EssentiaUserLoadEvent(User user) {
this.user = user;
}
public User getUser() {
return user;
}
@NotNull
@Override
public HandlerList getHandlers() {
return handlerList;
}
@NotNull
public static HandlerList getHandlerList() {
return handlerList;
}
}
@@ -1,6 +1,5 @@
package com.alttd.essentia.events; package com.alttd.essentia.api.events;
import org.bukkit.Location;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.event.HandlerList; import org.bukkit.event.HandlerList;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
@@ -1,4 +1,4 @@
package com.alttd.essentia.events; package com.alttd.essentia.api.events;
import org.bukkit.Location; import org.bukkit.Location;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
@@ -1,4 +1,4 @@
package com.alttd.essentia.events; package com.alttd.essentia.api.events;
import org.bukkit.Location; import org.bukkit.Location;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
@@ -1,4 +1,4 @@
package com.alttd.essentia.events; package com.alttd.essentia.api.events;
import org.bukkit.Location; import org.bukkit.Location;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
@@ -1,4 +1,4 @@
package com.alttd.essentia.events; package com.alttd.essentia.api.events;
import org.bukkit.Location; import org.bukkit.Location;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
@@ -0,0 +1,10 @@
package com.alttd.essentia.api.model;
import org.bukkit.Location;
public interface Home {
String name();
Location location();
}
@@ -0,0 +1,16 @@
package com.alttd.essentia.api.model;
public interface UserSettings {
boolean godMode();
void godMode(boolean godMode);
boolean allowTeleports();
void allowTeleports(boolean allowTeleports);
boolean flying();
void flying(boolean flying);
}
@@ -0,0 +1,10 @@
package com.alttd.essentia.api.request;
public interface Request {
void accept();
void deny();
void cancel();
}
@@ -0,0 +1,46 @@
package com.alttd.essentia.api.user;
import com.alttd.essentia.api.model.Home;
import com.alttd.essentia.api.model.UserSettings;
import com.alttd.essentia.api.request.Request;
import org.bukkit.Location;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
public interface User {
UUID getUUID();
Location getBackLocation(boolean death);
void setBackLocation(boolean death, Location location);
boolean hasHome(String name);
Home getHome(String name);
void setHome(String name, Location location);
void removeHome(String name);
int getHomeCount();
List<String> getMatchingHomeNames(String homeName);
Map<String, Home> getHomeData();
Set<String> getHomes();
UserSettings getUserSettings();
Request request();
void request(Request request);
boolean isCuffed();
void setCuffed(boolean cuffed);
}
@@ -0,0 +1,26 @@
package com.alttd.essentia.api.user;
import org.bukkit.entity.Player;
import java.util.Map;
import java.util.UUID;
public interface UserManager {
User getUser(Player player);
User getUser(UUID uuid);
void addUser(User user);
void removeUser(UUID uuid);
boolean hasUser(UUID uuid);
Map<UUID, User> getUsers();
User createNewUser(UUID uuid);
void saveAllUsers();
}
+11 -13
View File
@@ -5,25 +5,27 @@ import java.io.ByteArrayOutputStream
plugins { plugins {
id("java") id("java")
id("java-library") id("java-library")
id("com.github.johnrengelman.shadow") version "8.1.1" id("io.github.goooler.shadow") version "8.1.8"
id("maven-publish") id("maven-publish")
} }
allprojects { allprojects {
group = "com.alttd.essentia" group = "com.alttd.essentia"
version = "Build-" + (System.getenv("BUILD_NUMBER") ?: gitCommit()) version = "Build-" + (System.getenv("BUILD_NUMBER") ?: gitCommit())
description = "Altitude essentials ;)" description = "Altitude essentials ;)"
apply<JavaLibraryPlugin>()
java {
toolchain {
languageVersion.set(JavaLanguageVersion.of(21))
}
}
} }
subprojects { subprojects {
apply<JavaLibraryPlugin>() apply<JavaLibraryPlugin>()
apply(plugin = "maven-publish") apply(plugin = "maven-publish")
java {
toolchain {
languageVersion.set(JavaLanguageVersion.of(17))
}
}
publishing { publishing {
configure<PublishingExtension> { configure<PublishingExtension> {
repositories { repositories {
@@ -45,7 +47,7 @@ dependencies {
tasks { tasks {
shadowJar { shadowJar {
archiveFileName.set("${project.name}.jar") archiveFileName.set("${project.name}.jar")
minimize() { minimize {
exclude { exclude {
it.moduleName == "api" it.moduleName == "api"
} }
@@ -64,14 +66,10 @@ tasks {
jar { jar {
// enabled = false // enabled = false
// archiveFileName.set("${rootProject.name}.jar") archiveFileName.set("${rootProject.name}.jar")
} }
} }
dependencies {
compileOnly("com.alttd:Comet-API:1.20.4-R0.1-SNAPSHOT")
}
fun gitCommit(): String { fun gitCommit(): String {
val os = ByteArrayOutputStream() val os = ByteArrayOutputStream()
project.exec { project.exec {
+5 -12
View File
@@ -5,10 +5,11 @@ plugins {
dependencies { dependencies {
implementation(project(":api")) implementation(project(":api"))
compileOnly("com.alttd:Comet-API:1.20.4-R0.1-SNAPSHOT") compileOnly("com.alttd:Galaxy-API:1.21.1-R0.1-SNAPSHOT")
api("org.reflections:reflections:0.10.2")
compileOnly("org.projectlombok:lombok:1.18.24") compileOnly("org.projectlombok:lombok:1.18.34")
annotationProcessor("org.projectlombok:lombok:1.18.24") annotationProcessor("org.projectlombok:lombok:1.18.34")
} }
tasks { tasks {
@@ -23,12 +24,4 @@ tasks {
expand(Pair("version", rootProject.version)) expand(Pair("version", rootProject.version))
} }
} }
} }
//bukkit {
// name = rootProject.name
// main = "$group.${rootProject.name}Plugin"
// version = "${rootProject.version}"
// apiVersion = "1.20"
// authors = listOf("destro174")
//}
@@ -1,21 +1,36 @@
package com.alttd.essentia; package com.alttd.essentia;
import com.alttd.essentia.commands.admin.*; import com.alttd.essentia.commands.EssentiaCommand;
import com.alttd.essentia.commands.player.*;
import com.alttd.essentia.configuration.Config; import com.alttd.essentia.configuration.Config;
import com.alttd.essentia.listeners.PlayerListener; import com.alttd.essentia.storage.StorageManager;
import com.alttd.essentia.storage.StorageProvider;
import com.alttd.essentia.storage.StorageType;
import com.alttd.essentia.user.EssentiaUserManager;
import com.alttd.essentia.api.user.UserManager;
import io.papermc.paper.command.brigadier.Commands;
import io.papermc.paper.plugin.lifecycle.event.LifecycleEventManager;
import io.papermc.paper.plugin.lifecycle.event.types.LifecycleEvents;
import lombok.Getter; import lombok.Getter;
import org.bukkit.event.Listener;
import org.bukkit.plugin.Plugin;
import org.bukkit.plugin.PluginManager; import org.bukkit.plugin.PluginManager;
import org.bukkit.plugin.java.JavaPlugin; import org.bukkit.plugin.java.JavaPlugin;
import org.slf4j.Logger; import org.reflections.Reflections;
import org.reflections.scanners.Scanners;
import java.nio.file.Path; import java.util.Set;
public class EssentiaPlugin extends JavaPlugin implements EssentiaAPI { public class EssentiaPlugin extends JavaPlugin implements EssentiaAPI {
@Getter @Getter
private static EssentiaPlugin instance; private static EssentiaPlugin instance;
@Getter
private UserManager userManager;
@Getter
private StorageProvider storageProvider;
@Override @Override
public void onLoad() { public void onLoad() {
instance = this; instance = this;
@@ -27,42 +42,62 @@ public class EssentiaPlugin extends JavaPlugin implements EssentiaAPI {
loadConfiguration(); loadConfiguration();
loadCommands(); loadCommands();
loadEventListeners(); loadEventListeners();
loadManagers();
loadStorageProvider();
} }
@Override @Override
public void onDisable() { public void onDisable() {
getServer().getScheduler().cancelTasks(this); getServer().getScheduler().cancelTasks(this);
userManager().saveAllUsers();
storageProvider().disable();
} }
public void loadConfiguration() { public void loadConfiguration() {
Config.init(); Config.init();
} }
public void loadCommands() { void loadCommands() {
getCommand("essentia").setExecutor(new EssentiaCommand(this)); Reflections reflections = new Reflections("com.alttd.essentia.commands.list");
getCommand("teleportaccept").setExecutor(new TeleportAcceptCommand(this)); Set<Class<?>> subTypes = reflections.get(Scanners.SubTypes.of(EssentiaCommand.class).asClass());
getCommand("teleportdeny").setExecutor(new TeleportDenyCommand(this));
getCommand("teleportrequest").setExecutor(new TeleportRequestCommand(this)); LifecycleEventManager<Plugin> manager = this.getLifecycleManager();
getCommand("teleportrequesthere").setExecutor(new TeleportRequestHereCommand(this)); manager.registerEventHandler(LifecycleEvents.COMMANDS, event -> {
getCommand("teleporttoggle").setExecutor(new TeleportToggleCommand(this)); final Commands commands = event.registrar();
getCommand("clearinventory").setExecutor(new ClearInventoryCommand(this)); subTypes.forEach(clazz -> {
getCommand("home").setExecutor(new HomeCommand(this)); try {
getCommand("homes").setExecutor(new HomeListCommand(this)); EssentiaCommand essentiaCommand = (EssentiaCommand) clazz.getDeclaredConstructor().newInstance();
getCommand("sethome").setExecutor(new SetHomeCommand(this)); commands.register(essentiaCommand.command(), essentiaCommand.description(), essentiaCommand.aliases());
getCommand("deletehome").setExecutor(new DelHomeCommand(this)); } catch (Exception e) {
getCommand("back").setExecutor(new BackCommand(this)); EssentiaPlugin.instance().getLogger().severe("Failed to register command " + clazz.getSimpleName());
getCommand("deathback").setExecutor(new DeathBackCommand(this)); }
getCommand("fly").setExecutor(new FlyCommand(this)); });
getCommand("gamemode").setExecutor(new GamemodeCommand(this)); });
getCommand("heal").setExecutor(new HealCommand(this));
getCommand("feed").setExecutor(new FeedCommand(this));
getCommand("enchant").setExecutor(new EnchantCommand(this));
getCommand("spawn").setExecutor(new SpawnCommand(this));
} }
public void loadEventListeners() { void loadEventListeners() {
final PluginManager pluginManager = getServer().getPluginManager(); final PluginManager pluginManager = getServer().getPluginManager();
pluginManager.registerEvents(new PlayerListener(this), this); Reflections reflections = new Reflections("com.alttd.essentia.listeners");
Set<Class<?>> subTypes = reflections.get(Scanners.SubTypes.of(Listener.class).asClass());
subTypes.forEach(clazz -> {
try {
Listener listener = (Listener) clazz.getDeclaredConstructor().newInstance();
pluginManager.registerEvents(listener, this);
} catch (Exception e) {
EssentiaPlugin.instance().getLogger().severe("Failed to register event listener " + clazz.getSimpleName());
}
});
}
void loadManagers() {
userManager = new EssentiaUserManager(this);
}
void loadStorageProvider() {
StorageManager storageManager = new StorageManager(this);
storageProvider = storageManager.storageProvider(StorageType.valueOf(Config.STORAGE_TYPE.toUpperCase()));
storageProvider.startAutoSaving();
} }
} }
@@ -1,13 +0,0 @@
package com.alttd.essentia.commands;
import com.alttd.essentia.EssentiaPlugin;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
public abstract class AdminSubCommand extends SubCommand {
protected AdminSubCommand(EssentiaPlugin plugin, String name, String... aliases) {
super(plugin, name, aliases);
}
}
@@ -0,0 +1,40 @@
package com.alttd.essentia.commands;
import com.mojang.brigadier.tree.LiteralCommandNode;
import io.papermc.paper.command.brigadier.CommandSourceStack;
import org.jetbrains.annotations.NotNull;
import java.util.Collections;
import java.util.List;
// TODO -- add optional -s -silent parameters to commands?
public interface EssentiaCommand {
String commandName();
@NotNull LiteralCommandNode<CommandSourceStack> command();
default String description() {
return null;
}
default List<String> aliases() {
return Collections.emptyList();
}
default String baseCommandPermission() {
return "essentia.command.player." + commandName();
}
default String baseOtherCommandPermission() {
return "essentia.command.player." + commandName() + "other";
}
default String adminCommandPermission() {
return "essentia.command.admin." + commandName();
}
default String adminOtherCommandPermission() {
return "essentia.command.admin." + commandName() + "other";
}
}
@@ -1,26 +0,0 @@
package com.alttd.essentia.commands;
import com.alttd.essentia.EssentiaPlugin;
import com.alttd.essentia.configuration.Config;
import com.alttd.essentia.configuration.PlayerConfig;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
public abstract class PlayerSubCommand extends SubCommand {
protected PlayerSubCommand(EssentiaPlugin plugin, String name, String... aliases) {
super(plugin, name, aliases);
}
@Override
public boolean execute(CommandSender sender, String... args) {
if (!(sender instanceof Player player)) {
sender.sendRichMessage(Config.PLAYER_ONLY_COMMAND);
return true;
}
return execute(player, PlayerConfig.getConfig(player), args);
}
protected abstract boolean execute(Player player, PlayerConfig playerConfig, String... args);
}
@@ -1,70 +0,0 @@
package com.alttd.essentia.commands;
import com.alttd.essentia.EssentiaPlugin;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.command.TabExecutor;
import org.jetbrains.annotations.NotNull;
import java.util.Arrays;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
public abstract class SubCommand implements TabExecutor {
protected EssentiaPlugin plugin;
private final String name;
private final String[] aliases;
private final Map<String, SubCommand> subCommands = new LinkedHashMap<>();
protected SubCommand(EssentiaPlugin plugin, String name, String... aliases) {
this.plugin = plugin;
this.name = name;
this.aliases = aliases;
}
protected abstract boolean execute(CommandSender sender, String... args);
@Override
public boolean onCommand(@NotNull CommandSender sender, @NotNull Command cmd, @NotNull String label, String[] args) {
if (args.length > 0) {
SubCommand subCommand = getSubCommand(args[0]);
if (subCommand != null) {
return subCommand.onCommand(sender, cmd, args[0], Arrays.copyOfRange(args, 1, args.length));
}
}
return execute(sender, args);
}
public List<String> onTabComplete(@NotNull CommandSender sender, @NotNull Command command, @NotNull String alias, String[] args) {
if (args.length == 0) {
return subCommands.keySet().stream()
.sorted(String::compareToIgnoreCase)
.collect(Collectors.toList());
}
SubCommand subCommand = getSubCommand(args[0]);
if (subCommand != null) {
return subCommand.onTabComplete(sender, command, args[0], Arrays.copyOfRange(args, 1, args.length));
} else if (args.length == 1) {
return subCommands.keySet().stream()
.filter(s -> s.toLowerCase().startsWith(args[0]))
.sorted(String::compareToIgnoreCase)
.collect(Collectors.toList());
}
return null;
}
public void registerSubCommand(SubCommand subCommand) {
subCommands.put(subCommand.name.toLowerCase(), subCommand);
for (String alias : subCommand.aliases) {
subCommands.putIfAbsent(alias.toLowerCase(), subCommand);
}
}
private SubCommand getSubCommand(String name) {
return subCommands.get(name.toLowerCase());
}
}
@@ -0,0 +1,69 @@
package com.alttd.essentia.commands.admin;
import com.alttd.essentia.commands.EssentiaCommand;
import com.alttd.essentia.configuration.Config;
import com.mojang.brigadier.builder.LiteralArgumentBuilder;
import com.mojang.brigadier.tree.LiteralCommandNode;
import io.papermc.paper.command.brigadier.CommandSourceStack;
import io.papermc.paper.command.brigadier.Commands;
import io.papermc.paper.command.brigadier.argument.ArgumentTypes;
import io.papermc.paper.command.brigadier.argument.resolvers.selector.PlayerSelectorArgumentResolver;
import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder;
import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
public class BurnCommand implements EssentiaCommand {
@Override
public String commandName() {
return "burn";
}
@Override
public @NotNull LiteralCommandNode<CommandSourceStack> command() {
final LiteralArgumentBuilder<CommandSourceStack> builder =
Commands.literal(commandName())
.requires(
commandSourceStack -> commandSourceStack.getSender().hasPermission(adminCommandPermission())
)
.executes((source) -> {
if (source.getSource().getSender() instanceof Player player)
execute(player, player);
return 1;
})
.then(
Commands.argument("player", ArgumentTypes.player())
.requires(commandSourceStack -> commandSourceStack.getSender().hasPermission(adminOtherCommandPermission()))
.executes((source) -> {
CommandSourceStack sourceStack = source.getSource();
Player target = source.getArgument("player", PlayerSelectorArgumentResolver.class).resolve(sourceStack).getFirst();
execute(source.getSource().getSender(), target);
return 1;
})
);
return builder.build();
}
@Override
public String description() {
return "Set yourself or another player on fire!";
}
public void execute(CommandSender sender, Player target) { // TODO - optional time?
TagResolver placeholders = TagResolver.resolver(
Placeholder.component("requester", sender.name()),
Placeholder.component("target", target.displayName())
);
target.setFireTicks((int) (3000L / 50));
sender.sendRichMessage(target == sender ? Config.BURN_SELF : Config.BURN_OTHER, placeholders);
if (target != sender)
target.sendRichMessage(Config.BURN_BY_OTHER, placeholders);
}
}
@@ -1,49 +1,66 @@
package com.alttd.essentia.commands.admin; package com.alttd.essentia.commands.admin;
import com.alttd.essentia.EssentiaPlugin; import com.alttd.essentia.commands.EssentiaCommand;
import com.alttd.essentia.commands.AdminSubCommand;
import com.alttd.essentia.configuration.Config; import com.alttd.essentia.configuration.Config;
import com.mojang.brigadier.builder.LiteralArgumentBuilder;
import com.mojang.brigadier.tree.LiteralCommandNode;
import io.papermc.paper.command.brigadier.CommandSourceStack;
import io.papermc.paper.command.brigadier.Commands;
import io.papermc.paper.command.brigadier.argument.ArgumentTypes;
import io.papermc.paper.command.brigadier.argument.resolvers.selector.PlayerSelectorArgumentResolver;
import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder; import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder;
import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver; import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver;
import org.bukkit.Bukkit;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
public class ClearInventoryCommand extends AdminSubCommand { public class ClearInventoryCommand implements EssentiaCommand {
public ClearInventoryCommand(EssentiaPlugin plugin) { @Override
super(plugin, "clearinventory"); public String commandName() {
// TODO - register clear other subcommand return "clearinventory";
} }
@Override @Override
protected boolean execute(CommandSender sender, String... args) { public @NotNull LiteralCommandNode<CommandSourceStack> command() {
if (args.length > 0) { // TODO - make this into a subcommand final LiteralArgumentBuilder<CommandSourceStack> builder =
if (!sender.hasPermission("essentia.command.clearinventory.other")) { Commands.literal(commandName())
sender.sendRichMessage(Config.COMMAND_NO_PERMISSION); .requires(
return true; commandSourceStack -> commandSourceStack.getSender().hasPermission(adminCommandPermission()) &&
} commandSourceStack.getSender() instanceof Player
Player player = Bukkit.getPlayer(args[0]); )
if (player == null) { .executes((source) -> {
sender.sendRichMessage(Config.PLAYER_NOT_FOUND); if (source.getSource().getSender() instanceof Player player)
return true; execute(player, player);
}
TagResolver placeholders = TagResolver.resolver( return 1;
Placeholder.component("requester", sender.name()), })
Placeholder.component("target", player.displayName()) .then(
); Commands.argument("player", ArgumentTypes.player())
sender.sendRichMessage(Config.PLAYER_INVENTORY_CLEARED, placeholders); .requires(commandSourceStack -> commandSourceStack.getSender().hasPermission(adminOtherCommandPermission()))
player.sendRichMessage(Config.INVENTORY_CLEARED_BY_OTHER, placeholders); .executes((source) -> {
player.getInventory().clear(); CommandSourceStack sourceStack = source.getSource();
return true; Player target = source.getArgument("player", PlayerSelectorArgumentResolver.class).resolve(sourceStack).getFirst();
}
if (!(sender instanceof Player player)) { execute(source.getSource().getSender(), target);
sender.sendRichMessage(Config.PLAYER_ONLY_COMMAND); return 1;
return true; })
} );
player.getInventory().clear(); return builder.build();
player.sendRichMessage(Config.INVENTORY_CLEARED);
return true;
} }
}
public void execute(CommandSender sender, Player target) {
TagResolver placeholders = TagResolver.resolver(
Placeholder.component("requester", sender.name()),
Placeholder.component("target", target.displayName())
);
target.getInventory().clear();
sender.sendRichMessage(target == sender ? Config.INVENTORY_CLEARED : Config.PLAYER_INVENTORY_CLEARED, placeholders);
if (target != sender)
target.sendRichMessage(Config.INVENTORY_CLEARED_BY_OTHER, placeholders);
}
}
@@ -0,0 +1,73 @@
package com.alttd.essentia.commands.admin;
import com.alttd.essentia.EssentiaPlugin;
import com.alttd.essentia.api.user.User;
import com.alttd.essentia.api.user.UserManager;
import com.alttd.essentia.commands.EssentiaCommand;
import com.alttd.essentia.configuration.Config;
import com.mojang.brigadier.builder.LiteralArgumentBuilder;
import com.mojang.brigadier.tree.LiteralCommandNode;
import io.papermc.paper.command.brigadier.CommandSourceStack;
import io.papermc.paper.command.brigadier.Commands;
import io.papermc.paper.command.brigadier.argument.ArgumentTypes;
import io.papermc.paper.command.brigadier.argument.resolvers.selector.PlayerSelectorArgumentResolver;
import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder;
import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
public class CuffCommand implements EssentiaCommand {
@Override
public String commandName() {
return "cuff";
}
@Override
public @NotNull LiteralCommandNode<CommandSourceStack> command() {
final LiteralArgumentBuilder<CommandSourceStack> builder =
Commands.literal(commandName())
.requires(
commandSourceStack -> commandSourceStack.getSender().hasPermission(adminCommandPermission())
)
.then(
Commands.argument("player", ArgumentTypes.player())
.requires(commandSourceStack -> commandSourceStack.getSender().hasPermission(adminOtherCommandPermission()))
.executes((source) -> {
CommandSourceStack sourceStack = source.getSource();
Player target = source.getArgument("player", PlayerSelectorArgumentResolver.class).resolve(sourceStack).getFirst();
execute(source.getSource().getSender(), target);
return 1;
})
);
return builder.build();
}
public void execute(CommandSender sender, Player target) {
TagResolver placeholders = TagResolver.resolver(
Placeholder.component("requester", sender.name()),
Placeholder.component("target", target.displayName())
);
UserManager userManager = EssentiaPlugin.instance().userManager();
if (!userManager.hasUser(target.getUniqueId())) {
return;
}
User user = userManager.getUser(target);
if (user.isCuffed()) {
sender.sendRichMessage("<target> is already cuffed."); // TODO - CONFIG messages
return;
}
user.setCuffed(true);
// TODO - CONFIG messages
sender.sendRichMessage(target == sender ? Config.BURN_SELF : Config.BURN_OTHER, placeholders);
if (target != sender)
target.sendRichMessage(Config.BURN_BY_OTHER, placeholders);
}
}
@@ -1,38 +1,113 @@
package com.alttd.essentia.commands.admin; package com.alttd.essentia.commands.admin;
import com.alttd.essentia.EssentiaPlugin; import com.alttd.essentia.commands.EssentiaCommand;
import com.alttd.essentia.commands.AdminSubCommand; import com.alttd.essentia.commands.argumement.EnchantmentArgument;
import org.bukkit.NamespacedKey; import com.mojang.brigadier.arguments.IntegerArgumentType;
import org.bukkit.command.Command; import com.mojang.brigadier.builder.LiteralArgumentBuilder;
import com.mojang.brigadier.tree.LiteralCommandNode;
import io.papermc.paper.command.brigadier.CommandSourceStack;
import io.papermc.paper.command.brigadier.Commands;
import io.papermc.paper.command.brigadier.argument.ArgumentTypes;
import io.papermc.paper.command.brigadier.argument.resolvers.selector.PlayerSelectorArgumentResolver;
import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder;
import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver;
import org.bukkit.Material;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import org.bukkit.enchantments.Enchantment; import org.bukkit.enchantments.Enchantment;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import java.util.Arrays; public class EnchantCommand implements EssentiaCommand {
import java.util.List;
import java.util.stream.Collectors;
public class EnchantCommand extends AdminSubCommand { @Override
public String commandName() {
public EnchantCommand(EssentiaPlugin plugin) { return "enchant";
super(plugin, "enchant");
} }
@Override @Override
protected boolean execute(CommandSender sender, String... args) { public @NotNull LiteralCommandNode<CommandSourceStack> command() {
// TODO final LiteralArgumentBuilder<CommandSourceStack> builder =
return true; Commands.literal(commandName())
.requires(
commandSourceStack -> commandSourceStack.getSender().hasPermission(adminCommandPermission())
)
.then(
Commands.argument("enchantment", new EnchantmentArgument())
.executes((source) -> {
if (!(source.getSource().getSender() instanceof Player player))
return 1;
Enchantment enchantment = source.getArgument("enchantment", Enchantment.class);
execute(source.getSource().getSender(), player, enchantment);
return 1;
}).then(
Commands.argument("level", IntegerArgumentType.integer(1, 100))
.executes((source) -> {
if (!(source.getSource().getSender() instanceof Player player))
return 1;
Enchantment enchantment = source.getArgument("enchantment", Enchantment.class);
int level = source.getArgument("level", Integer.class);
execute(source.getSource().getSender(), player, enchantment, level);
return 1;
})
.then(
Commands.argument("player", ArgumentTypes.player())
.requires(commandSourceStack -> commandSourceStack.getSender().hasPermission(adminOtherCommandPermission()))
.executes((source) -> {
CommandSourceStack sourceStack = source.getSource();
Player target = source.getArgument("player", PlayerSelectorArgumentResolver.class).resolve(sourceStack).getFirst();
Enchantment enchantment = source.getArgument("enchantment", Enchantment.class);
int level = source.getArgument("level", Integer.class);
execute(source.getSource().getSender(), target, enchantment, level);
return 1;
})
)
)
);
return builder.build();
} }
@Override private void execute(CommandSender sender, Player target, Enchantment enchantment) {
public List<String> onTabComplete(@NotNull CommandSender sender, @NotNull Command command, @NotNull String alias, String @NotNull [] args) { execute(sender, target, enchantment, 1, false);
if (args.length == 1) { }
return Arrays.stream(Enchantment.values())
.map(Enchantment::getKey) private void execute(CommandSender sender, Player target, Enchantment enchantment, int level) {
.map(NamespacedKey::getKey) execute(sender, target, enchantment, level, false);
.filter(name -> name.toLowerCase().startsWith(args[0].toLowerCase())) }
.collect(Collectors.toList());
public void execute(CommandSender sender, Player target, Enchantment enchantment, int level, boolean unsafe) {
TagResolver placeholders = TagResolver.resolver(
Placeholder.component("requester", sender.name()),
Placeholder.component("target", target.displayName()),
Placeholder.unparsed("enchantment", enchantment.getKey().value())
);
// target.setGameMode(gameMode);
ItemStack itemStack = target.getInventory().getItemInMainHand();
if (itemStack.getType() == Material.AIR) {
sender.sendRichMessage("Hold the item you want to enchant", placeholders);
return;
} }
return null; if (unsafe) {
itemStack.addUnsafeEnchantment(enchantment, level);
} else {
if ((level > enchantment.getMaxLevel())) {
level = enchantment.getMaxLevel();
}
if (!enchantment.canEnchantItem(itemStack)) {
sender.sendRichMessage("You can not enchant this item with <enchantment>", placeholders);
return;
}
itemStack.addEnchantment(enchantment, level);
}
sender.sendRichMessage(target == sender ? "You enchanted your item with <enchantment>." : "<sender> enchanted your item with <enchantment>.", placeholders);
if (target != sender)
target.sendRichMessage("You enchanted <target>'s item with <enchantment>.", placeholders);
} }
}
}
@@ -0,0 +1,35 @@
package com.alttd.essentia.commands.admin;
import com.alttd.essentia.EssentiaPlugin;
import com.alttd.essentia.commands.EssentiaCommand;
import com.mojang.brigadier.builder.LiteralArgumentBuilder;
import com.mojang.brigadier.tree.LiteralCommandNode;
import io.papermc.paper.command.brigadier.CommandSourceStack;
import io.papermc.paper.command.brigadier.Commands;
import org.jetbrains.annotations.NotNull;
public class EssentiaAdminCommand implements EssentiaCommand {
@Override
public String commandName() {
return "essentiareload";
}
@Override
public @NotNull LiteralCommandNode<CommandSourceStack> command() {
final LiteralArgumentBuilder<CommandSourceStack> builder =
Commands.literal(commandName())
.requires(commandSourceStack -> commandSourceStack.getSender().hasPermission(adminCommandPermission()))
.executes((commandContext -> 1))
.then(
Commands.literal("reload")
.executes((cmd) -> {
EssentiaPlugin.instance().reloadConfig();
return com.mojang.brigadier.Command.SINGLE_SUCCESS;
})
)
;
return builder.build();
}
}
@@ -1,19 +0,0 @@
package com.alttd.essentia.commands.admin;
import com.alttd.essentia.EssentiaPlugin;
import com.alttd.essentia.commands.SubCommand;
import org.bukkit.command.CommandSender;
public class EssentiaCommand extends SubCommand {
public EssentiaCommand(EssentiaPlugin plugin) {
super(plugin, "essentia");
registerSubCommand(new ReloadCommand(plugin));
}
@Override
protected boolean execute(CommandSender sender, String... args) {
return true;
}
}
@@ -1,31 +1,55 @@
package com.alttd.essentia.commands.admin; package com.alttd.essentia.commands.admin;
import com.alttd.essentia.EssentiaPlugin; import com.alttd.essentia.commands.EssentiaCommand;
import com.alttd.essentia.commands.AdminSubCommand;
import com.alttd.essentia.configuration.Config; import com.alttd.essentia.configuration.Config;
import com.mojang.brigadier.builder.LiteralArgumentBuilder;
import com.mojang.brigadier.tree.LiteralCommandNode;
import io.papermc.paper.command.brigadier.CommandSourceStack;
import io.papermc.paper.command.brigadier.Commands;
import io.papermc.paper.command.brigadier.argument.ArgumentTypes;
import io.papermc.paper.command.brigadier.argument.resolvers.selector.PlayerSelectorArgumentResolver;
import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder; import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder;
import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver; import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
public class FeedCommand extends AdminSubCommand { public class FeedCommand implements EssentiaCommand {
public FeedCommand(EssentiaPlugin plugin) { @Override
super(plugin, "feed"); public String commandName() {
return "feed";
} }
@Override @Override
protected boolean execute(CommandSender sender, String... args) { public @NotNull LiteralCommandNode<CommandSourceStack> command() {
Player target = args.length > 0 ? org.bukkit.Bukkit.getPlayer(args[0]) : sender instanceof Player player ? player : null; final LiteralArgumentBuilder<CommandSourceStack> builder =
if (target == null) { Commands.literal(commandName())
sender.sendRichMessage(Config.PLAYER_NOT_FOUND); .requires(
return true; commandSourceStack -> commandSourceStack.getSender().hasPermission(adminCommandPermission()) &&
} commandSourceStack.getSender() instanceof Player
if (!sender.hasPermission("essentia.command.feed" + (target != sender ? ".other" : "")) ) { )
sender.sendRichMessage(Config.COMMAND_NO_PERMISSION); .executes((source) -> {
return true; if (source.getSource().getSender() instanceof Player player)
} execute(player, player);
return 1;
})
.then(
Commands.argument("player", ArgumentTypes.player())
.requires(commandSourceStack -> commandSourceStack.getSender().hasPermission(adminOtherCommandPermission()))
.executes((source) -> {
CommandSourceStack sourceStack = source.getSource();
Player target = source.getArgument("player", PlayerSelectorArgumentResolver.class).resolve(sourceStack).getFirst();
execute(source.getSource().getSender(), target);
return 1;
})
);
return builder.build();
}
public void execute(CommandSender sender, Player target) {
TagResolver placeholders = TagResolver.resolver( TagResolver placeholders = TagResolver.resolver(
Placeholder.component("requester", sender.name()), Placeholder.component("requester", sender.name()),
Placeholder.component("target", target.displayName()) Placeholder.component("target", target.displayName())
@@ -36,6 +60,7 @@ public class FeedCommand extends AdminSubCommand {
sender.sendRichMessage(target == sender ? Config.FEED_SELF : Config.FEED_OTHER, placeholders); sender.sendRichMessage(target == sender ? Config.FEED_SELF : Config.FEED_OTHER, placeholders);
if (target != sender) if (target != sender)
target.sendRichMessage(Config.FEED_BY_OTHER, placeholders); target.sendRichMessage(Config.FEED_BY_OTHER, placeholders);
return true;
} }
} }
@@ -1,61 +1,77 @@
package com.alttd.essentia.commands.admin; package com.alttd.essentia.commands.admin;
import com.alttd.essentia.EssentiaPlugin; import com.alttd.essentia.EssentiaPlugin;
import com.alttd.essentia.commands.AdminSubCommand; import com.alttd.essentia.api.user.User;
import com.alttd.essentia.api.user.UserManager;
import com.alttd.essentia.commands.EssentiaCommand;
import com.alttd.essentia.configuration.Config; import com.alttd.essentia.configuration.Config;
import com.mojang.brigadier.builder.LiteralArgumentBuilder;
import com.mojang.brigadier.tree.LiteralCommandNode;
import io.papermc.paper.command.brigadier.CommandSourceStack;
import io.papermc.paper.command.brigadier.Commands;
import io.papermc.paper.command.brigadier.argument.ArgumentTypes;
import io.papermc.paper.command.brigadier.argument.resolvers.selector.PlayerSelectorArgumentResolver;
import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder; import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder;
import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver; import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver;
import org.apache.commons.lang3.BooleanUtils; import org.apache.commons.lang3.BooleanUtils;
import org.bukkit.Bukkit;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import java.util.List; public class FlyCommand implements EssentiaCommand {
import java.util.stream.Collectors;
public class FlyCommand extends AdminSubCommand { @Override
public String commandName() {
public FlyCommand(EssentiaPlugin plugin) { return "fly";
super(plugin, "fly");
} }
@Override @Override
protected boolean execute(CommandSender sender, String... args) { public @NotNull LiteralCommandNode<CommandSourceStack> command() {
if (args.length > 0) { final LiteralArgumentBuilder<CommandSourceStack> builder =
if (!sender.hasPermission("essentia.command.fly.other")) { Commands.literal(commandName())
sender.sendRichMessage(Config.COMMAND_NO_PERMISSION); .requires(
return true; commandSourceStack -> commandSourceStack.getSender().hasPermission(adminCommandPermission()) &&
} commandSourceStack.getSender() instanceof Player
)
.executes((source) -> {
if (source.getSource().getSender() instanceof Player player)
execute(player, player);
Player target = Bukkit.getPlayer(args[0]); return 1;
if (target == null) { })
sender.sendRichMessage(Config.PLAYER_NOT_FOUND); .then(
return true; Commands.argument("player", ArgumentTypes.player())
} .requires(commandSourceStack -> commandSourceStack.getSender().hasPermission(adminOtherCommandPermission()))
target.setAllowFlight(!target.getAllowFlight()); .executes((source) -> {
CommandSourceStack sourceStack = source.getSource();
Player target = source.getArgument("player", PlayerSelectorArgumentResolver.class).resolve(sourceStack).getFirst();
TagResolver placeholders = TagResolver.resolver( execute(source.getSource().getSender(), target);
Placeholder.component("player", sender.name()), return 1;
Placeholder.component("target", target.name()), })
Placeholder.unparsed("status", BooleanUtils.toStringOnOff(target.getAllowFlight())) );
); return builder.build();
sender.sendRichMessage(Config.TOGGLED_FLIGHT_BY_OTHER, placeholders);
target.sendRichMessage(Config.TOGGLED_FLIGHT_PLAYER, placeholders);
return true;
}
if (!(sender instanceof Player player)) {
sender.sendRichMessage(Config.PLAYER_ONLY_COMMAND);
return true;
}
player.setAllowFlight(!player.getAllowFlight());
TagResolver placeholders = TagResolver.resolver(
Placeholder.component("player", player.name()),
Placeholder.parsed("status", BooleanUtils.toStringOnOff(player.getAllowFlight()))
);
sender.sendRichMessage(Config.TOGGLED_FLIGHT, placeholders);
return true;
} }
}
public void execute(CommandSender sender, Player target) {
TagResolver placeholders = TagResolver.resolver(
Placeholder.component("player", sender.name()),
Placeholder.component("target", target.name()),
Placeholder.unparsed("status", BooleanUtils.toStringOnOff(!target.getAllowFlight()))
);
UserManager userManager = EssentiaPlugin.instance().userManager();
if (!userManager.hasUser(target.getUniqueId())) {
return;
}
User user = userManager.getUser(target);
user.getUserSettings().flying(!user.getUserSettings().flying());
target.setFlying(!user.getUserSettings().flying());
sender.sendRichMessage(target == sender ? Config.TOGGLED_FLIGHT : Config.TOGGLED_FLIGHT_PLAYER, placeholders);
if (target != sender)
target.sendRichMessage(Config.TOGGLED_FLIGHT_BY_OTHER, placeholders);
}
}
@@ -0,0 +1,73 @@
package com.alttd.essentia.commands.admin;
import com.alttd.essentia.commands.EssentiaCommand;
import com.alttd.essentia.configuration.Config;
import com.mojang.brigadier.arguments.FloatArgumentType;
import com.mojang.brigadier.builder.LiteralArgumentBuilder;
import com.mojang.brigadier.tree.LiteralCommandNode;
import io.papermc.paper.command.brigadier.CommandSourceStack;
import io.papermc.paper.command.brigadier.Commands;
import io.papermc.paper.command.brigadier.argument.ArgumentTypes;
import io.papermc.paper.command.brigadier.argument.resolvers.selector.PlayerSelectorArgumentResolver;
import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder;
import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver;
import org.bukkit.command.CommandSender;
import org.bukkit.enchantments.Enchantment;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
public class FlySpeedCommand implements EssentiaCommand {
@Override
public String commandName() {
return "flyspeed";
}
@Override
public @NotNull LiteralCommandNode<CommandSourceStack> command() {
final LiteralArgumentBuilder<CommandSourceStack> builder =
Commands.literal(commandName())
.requires(
commandSourceStack -> commandSourceStack.getSender().hasPermission(adminCommandPermission())
).then(
Commands.argument("speed", FloatArgumentType.floatArg(-1, 1))
.executes((source) -> {
if (!(source.getSource().getSender() instanceof Player player))
return 1;
Enchantment enchantment = source.getArgument("enchantment", Enchantment.class);
float speed = source.getArgument("speed", Float.class);
execute(source.getSource().getSender(), player, speed);
return 1;
})
.then(
Commands.argument("player", ArgumentTypes.player())
.requires(commandSourceStack -> commandSourceStack.getSender().hasPermission(adminOtherCommandPermission()))
.executes((source) -> {
CommandSourceStack sourceStack = source.getSource();
Player target = source.getArgument("player", PlayerSelectorArgumentResolver.class).resolve(sourceStack).getFirst();
float speed = source.getArgument("speed", Float.class);
execute(source.getSource().getSender(), target, speed);
return 1;
})
)
);
return builder.build();
}
public void execute(CommandSender sender, Player target, float speed) {
TagResolver placeholders = TagResolver.resolver(
Placeholder.component("requester", sender.name()),
Placeholder.component("target", target.displayName())
);
target.setFlySpeed(speed);
// TODO - Config messages
sender.sendRichMessage(target == sender ? Config.FEED_SELF : Config.FEED_OTHER, placeholders);
if (target != sender)
target.sendRichMessage(Config.FEED_BY_OTHER, placeholders);
}
}
@@ -0,0 +1,71 @@
package com.alttd.essentia.commands.admin;
import com.alttd.essentia.commands.EssentiaCommand;
import com.alttd.essentia.configuration.Config;
import com.mojang.brigadier.builder.LiteralArgumentBuilder;
import com.mojang.brigadier.tree.LiteralCommandNode;
import io.papermc.paper.command.brigadier.CommandSourceStack;
import io.papermc.paper.command.brigadier.Commands;
import io.papermc.paper.command.brigadier.argument.ArgumentTypes;
import io.papermc.paper.command.brigadier.argument.resolvers.selector.PlayerSelectorArgumentResolver;
import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder;
import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver;
import org.bukkit.GameMode;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
public class GameModeCommand implements EssentiaCommand {
@Override
public String commandName() {
return "gamemode";
}
@Override
public @NotNull LiteralCommandNode<CommandSourceStack> command() {
final LiteralArgumentBuilder<CommandSourceStack> builder =
Commands.literal(commandName())
.requires(
commandSourceStack -> commandSourceStack.getSender().hasPermission(adminCommandPermission())
)
.then(
Commands.argument("gamemode", ArgumentTypes.gameMode())
.executes((source) -> {
if (!(source.getSource().getSender() instanceof Player player))
return 1;
GameMode gameMode = source.getArgument("gamemode", GameMode.class);
execute(source.getSource().getSender(), player, gameMode);
return 1;
})
.then(
Commands.argument("player", ArgumentTypes.player())
.requires(commandSourceStack -> commandSourceStack.getSender().hasPermission(adminOtherCommandPermission()))
.executes((source) -> {
CommandSourceStack sourceStack = source.getSource();
Player target = source.getArgument("player", PlayerSelectorArgumentResolver.class).resolve(sourceStack).getFirst();
GameMode gameMode = source.getArgument("gamemode", GameMode.class);
execute(source.getSource().getSender(), target, gameMode);
return 1;
})
)
);
return builder.build();
}
public void execute(CommandSender sender, Player target, GameMode gameMode) {
TagResolver placeholders = TagResolver.resolver(
Placeholder.component("requester", sender.name()),
Placeholder.component("target", target.displayName()),
Placeholder.unparsed("gamemode", gameMode.toString().toLowerCase())
);
target.setGameMode(gameMode);
sender.sendRichMessage(target == sender ? Config.GAMEMODE_SET : Config.GAMEMODE_SET_OTHER, placeholders);
if (target != sender)
target.sendRichMessage(Config.GAMEMODE_SET_BY_OTHER, placeholders);
}
}
@@ -1,66 +0,0 @@
package com.alttd.essentia.commands.admin;
import com.alttd.essentia.EssentiaPlugin;
import com.alttd.essentia.commands.AdminSubCommand;
import com.alttd.essentia.configuration.Config;
import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder;
import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver;
import org.bukkit.Bukkit;
import org.bukkit.GameMode;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
public class GamemodeCommand extends AdminSubCommand {
public GamemodeCommand(EssentiaPlugin plugin) {
super(plugin, "gamemode");
}
@Override
protected boolean execute(CommandSender sender, String... args) {
// TODO -- refactor all "other" subcommands to follow this style, cleaner and easier?
Player target = args.length > 1 ? Bukkit.getPlayer(args[1]) : sender instanceof Player player ? player : null;
if (target == null) {
sender.sendRichMessage(Config.PLAYER_NOT_FOUND);
return true;
}
if (!sender.hasPermission("essentia.command.gamemode" + (target != sender ? ".other" : "")) ) {
sender.sendRichMessage(Config.COMMAND_NO_PERMISSION);
return true;
}
GameMode gameMode = GameMode.SURVIVAL;
switch (args[0].toLowerCase()) {
case "creative", "c" -> gameMode = GameMode.CREATIVE;
case "spectator", "sp" -> gameMode = GameMode.SPECTATOR;
}
target.setGameMode(gameMode);
TagResolver placeholders = TagResolver.resolver(
Placeholder.component("requester", sender.name()),
Placeholder.component("target", target.displayName()),
Placeholder.unparsed("gamemode", gameMode.toString())
);
sender.sendRichMessage(target == sender ? Config.GAMEMODE_SET : Config.GAMEMODE_SET_OTHER, placeholders);
if (target != sender)
target.sendRichMessage(Config.GAMEMODE_SET_BY_OTHER, placeholders);
return true;
}
@Override
public List<String> onTabComplete(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, String[] args) {
if (args.length == 1) {
String name = args[0].trim().toLowerCase();
return Arrays.stream(GameMode.values()).map(GameMode::toString)
.filter(string -> string.toLowerCase().startsWith(name)).collect(Collectors.toList());
}
return null;
}
}
@@ -0,0 +1,76 @@
package com.alttd.essentia.commands.admin;
import com.alttd.essentia.EssentiaPlugin;
import com.alttd.essentia.api.user.User;
import com.alttd.essentia.api.user.UserManager;
import com.alttd.essentia.commands.EssentiaCommand;
import com.alttd.essentia.configuration.Config;
import com.mojang.brigadier.builder.LiteralArgumentBuilder;
import com.mojang.brigadier.tree.LiteralCommandNode;
import io.papermc.paper.command.brigadier.CommandSourceStack;
import io.papermc.paper.command.brigadier.Commands;
import io.papermc.paper.command.brigadier.argument.ArgumentTypes;
import io.papermc.paper.command.brigadier.argument.resolvers.selector.PlayerSelectorArgumentResolver;
import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder;
import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver;
import org.apache.commons.lang3.BooleanUtils;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
public class GodCommand implements EssentiaCommand {
@Override
public String commandName() {
return "god";
}
@Override
public @NotNull LiteralCommandNode<CommandSourceStack> command() {
final LiteralArgumentBuilder<CommandSourceStack> builder =
Commands.literal(commandName())
.requires(
commandSourceStack -> commandSourceStack.getSender().hasPermission(adminCommandPermission()) &&
commandSourceStack.getSender() instanceof Player
)
.executes((source) -> {
if (source.getSource().getSender() instanceof Player player)
execute(player, player);
return 1;
})
.then(
Commands.argument("player", ArgumentTypes.player())
.requires(commandSourceStack -> commandSourceStack.getSender().hasPermission(adminOtherCommandPermission()))
.executes((source) -> {
CommandSourceStack sourceStack = source.getSource();
Player target = source.getArgument("player", PlayerSelectorArgumentResolver.class).resolve(sourceStack).getFirst();
execute(source.getSource().getSender(), target);
return 1;
})
);
return builder.build();
}
public void execute(CommandSender sender, Player target) {
UserManager userManager = EssentiaPlugin.instance().userManager();
User user = userManager.getUser(target);
if (user == null)
return;
TagResolver placeholders = TagResolver.resolver(
Placeholder.component("player", sender.name()),
Placeholder.component("target", target.name()),
Placeholder.unparsed("status", BooleanUtils.toStringOnOff(!user.getUserSettings().godMode()))
);
user.getUserSettings().godMode(!user.getUserSettings().godMode());
target.setInvulnerable(!user.getUserSettings().godMode());
sender.sendRichMessage(target == sender ? Config.TOGGLED_GOD : Config.TOGGLED_GOD_PLAYER, placeholders);
if (target != sender)
target.sendRichMessage(Config.TOGGLED_GOD_BY_OTHER, placeholders);
}
}
@@ -1,39 +1,65 @@
package com.alttd.essentia.commands.admin; package com.alttd.essentia.commands.admin;
import com.alttd.essentia.EssentiaPlugin; import com.alttd.essentia.commands.EssentiaCommand;
import com.alttd.essentia.commands.AdminSubCommand;
import com.alttd.essentia.configuration.Config; import com.alttd.essentia.configuration.Config;
import com.mojang.brigadier.builder.LiteralArgumentBuilder;
import com.mojang.brigadier.tree.LiteralCommandNode;
import io.papermc.paper.command.brigadier.CommandSourceStack;
import io.papermc.paper.command.brigadier.Commands;
import io.papermc.paper.command.brigadier.argument.ArgumentTypes;
import io.papermc.paper.command.brigadier.argument.resolvers.selector.PlayerSelectorArgumentResolver;
import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder; import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder;
import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver; import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
public class HealCommand extends AdminSubCommand { public class HealCommand implements EssentiaCommand {
public HealCommand(EssentiaPlugin plugin) { @Override
super(plugin, "heal"); public String commandName() {
return "heal";
} }
@Override @Override
protected boolean execute(CommandSender sender, String... args) { public @NotNull LiteralCommandNode<CommandSourceStack> command() {
Player target = args.length > 0 ? org.bukkit.Bukkit.getPlayer(args[0]) : sender instanceof Player player ? player : null; final LiteralArgumentBuilder<CommandSourceStack> builder =
if (target == null) { Commands.literal(commandName())
sender.sendRichMessage(Config.PLAYER_NOT_FOUND); .requires(
return true; commandSourceStack -> commandSourceStack.getSender().hasPermission(adminCommandPermission()) &&
} commandSourceStack.getSender() instanceof Player
if (!sender.hasPermission("essentia.command.heal" + (target != sender ? ".other" : "")) ) { )
sender.sendRichMessage(Config.COMMAND_NO_PERMISSION); .executes((source) -> {
return true; if (source.getSource().getSender() instanceof Player player)
} execute(player, player);
return 1;
})
.then(
Commands.argument("player", ArgumentTypes.player())
.requires(commandSourceStack -> commandSourceStack.getSender().hasPermission(adminOtherCommandPermission()))
.executes((source) -> {
CommandSourceStack sourceStack = source.getSource();
Player target = source.getArgument("player", PlayerSelectorArgumentResolver.class).resolve(sourceStack).getFirst();
execute(source.getSource().getSender(), target);
return 1;
})
);
return builder.build();
}
public void execute(CommandSender sender, Player target) {
TagResolver placeholders = TagResolver.resolver( TagResolver placeholders = TagResolver.resolver(
Placeholder.component("requester", sender.name()), Placeholder.component("requester", sender.name()),
Placeholder.component("target", target.displayName()) Placeholder.component("target", target.displayName())
); );
target.setHealth(20); target.setHealth(20);
sender.sendRichMessage(target == sender ? Config.HEAL_SELF : Config.HEAL_OTHER, placeholders); sender.sendRichMessage(target == sender ? Config.HEAL_SELF : Config.HEAL_OTHER, placeholders);
if (target != sender) if (target != sender)
target.sendRichMessage(Config.HEAL_BY_OTHER, placeholders); target.sendRichMessage(Config.HEAL_BY_OTHER, placeholders);
return true;
} }
}
}
@@ -0,0 +1,58 @@
package com.alttd.essentia.commands.admin;
import com.alttd.essentia.commands.EssentiaCommand;
import com.mojang.brigadier.builder.LiteralArgumentBuilder;
import com.mojang.brigadier.tree.LiteralCommandNode;
import io.papermc.paper.command.brigadier.CommandSourceStack;
import io.papermc.paper.command.brigadier.Commands;
import io.papermc.paper.command.brigadier.argument.ArgumentTypes;
import io.papermc.paper.command.brigadier.argument.resolvers.selector.PlayerSelectorArgumentResolver;
import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder;
import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
public class InfoCommand implements EssentiaCommand {
@Override
public String commandName() {
return "info";
}
@Override
public @NotNull LiteralCommandNode<CommandSourceStack> command() {
final LiteralArgumentBuilder<CommandSourceStack> builder =
Commands.literal(commandName())
.requires(
commandSourceStack -> commandSourceStack.getSender().hasPermission(adminCommandPermission())
)
.executes((source) -> {
if (source.getSource().getSender() instanceof Player player)
execute(player, player);
return 1;
})
.then(
Commands.argument("player", ArgumentTypes.player())
.requires(commandSourceStack -> commandSourceStack.getSender().hasPermission(adminOtherCommandPermission()))
.executes((source) -> {
CommandSourceStack sourceStack = source.getSource();
Player target = source.getArgument("player", PlayerSelectorArgumentResolver.class).resolve(sourceStack).getFirst();
execute(source.getSource().getSender(), target);
return 1;
})
);
return builder.build();
}
public void execute(CommandSender sender, Player target) { // TODO - implement player info
TagResolver placeholders = TagResolver.resolver(
Placeholder.component("requester", sender.name()),
Placeholder.component("target", target.displayName())
);
}
}
@@ -0,0 +1,97 @@
package com.alttd.essentia.commands.admin;
import com.alttd.essentia.commands.EssentiaCommand;
import com.mojang.brigadier.builder.LiteralArgumentBuilder;
import com.mojang.brigadier.tree.LiteralCommandNode;
import io.papermc.paper.command.brigadier.CommandSourceStack;
import io.papermc.paper.command.brigadier.Commands;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
import java.util.List;
// TODO -- output messages
public class PlayerTimeCommand implements EssentiaCommand {
@Override
public String commandName() {
return "playertime";
}
@Override
public @NotNull LiteralCommandNode<CommandSourceStack> command() {
final LiteralArgumentBuilder<CommandSourceStack> builder =
Commands.literal(commandName())
.requires(
commandSourceStack -> commandSourceStack.getSender().hasPermission(adminCommandPermission()) &&
commandSourceStack.getSender() instanceof Player
)
.then(
Commands.literal("freeze")
.executes(commandContext -> {
if (commandContext.getSource().getSender() instanceof Player player)
setTime(player, player.getPlayerTime());
return 1;
})
)
.then(
Commands.literal("unfreeze")
.executes(commandContext -> {
if (commandContext.getSource().getSender() instanceof Player player)
reset(player);
return 1;
})
)
.then(
Commands.literal("day")
.executes(commandContext -> {
if (commandContext.getSource().getSender() instanceof Player player)
setTime(player, 1000);
return 1;
})
)
.then(
Commands.literal("noon")
.executes(commandContext -> {
if (commandContext.getSource().getSender() instanceof Player player)
setTime(player, 6000);
return 1;
})
)
.then(
Commands.literal("night")
.executes(commandContext -> {
if (commandContext.getSource().getSender() instanceof Player player)
setTime(player, 13000);
return 1;
})
)
.then(
Commands.literal("midnight")
.executes(commandContext -> {
if (commandContext.getSource().getSender() instanceof Player player)
setTime(player, 18000);
return 1;
})
);
return builder.build();
}
void reset(Player player) {
player.resetPlayerTime();
}
void setTime(Player player, long time) {
player.setPlayerTime(time, false);
}
public List<String> aliases() {
return List.of("ptime");
}
}
@@ -0,0 +1,80 @@
package com.alttd.essentia.commands.admin;
import com.alttd.essentia.commands.EssentiaCommand;
import com.alttd.essentia.commands.argumement.WeatherArgument;
import com.mojang.brigadier.builder.LiteralArgumentBuilder;
import com.mojang.brigadier.tree.LiteralCommandNode;
import io.papermc.paper.command.brigadier.CommandSourceStack;
import io.papermc.paper.command.brigadier.Commands;
import io.papermc.paper.command.brigadier.argument.ArgumentTypes;
import io.papermc.paper.command.brigadier.argument.resolvers.selector.PlayerSelectorArgumentResolver;
import org.bukkit.WeatherType;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
import java.util.List;
// TODO -- output messages
public class PlayerWeatherCommand implements EssentiaCommand {
@Override
public String commandName() {
return "playerweather";
}
@Override
public @NotNull LiteralCommandNode<CommandSourceStack> command() {
final LiteralArgumentBuilder<CommandSourceStack> builder =
Commands.literal(commandName())
.requires(
commandSourceStack -> commandSourceStack.getSender().hasPermission(adminCommandPermission()) &&
commandSourceStack.getSender() instanceof Player
)
.then(
Commands.literal("reset")
.executes(commandContext -> {
if (commandContext.getSource().getSender() instanceof Player player)
resetWeather(player);
return 1;
})
)
.then(
Commands.argument("weather", new WeatherArgument())
.executes(commandContext -> {
if (!(commandContext.getSource().getSender() instanceof Player player))
return 1;
WeatherType weatherType = commandContext.getArgument("weather", WeatherType.class);
execute(commandContext.getSource().getSender(), player, weatherType);
return 1;
})
.then(
Commands.argument("player", ArgumentTypes.player())
.requires(commandSourceStack -> commandSourceStack.getSender().hasPermission(adminOtherCommandPermission()))
.executes(commandContext -> {
CommandSourceStack sourceStack = commandContext.getSource();
Player target = commandContext.getArgument("player", PlayerSelectorArgumentResolver.class).resolve(sourceStack).getFirst();
WeatherType weatherType = commandContext.getArgument("weather", WeatherType.class);
execute(commandContext.getSource().getSender(), target, weatherType);
return 1;
})
)
);
return builder.build();
}
public void execute(CommandSender sender, Player target, WeatherType weatherType) {
target.setPlayerWeather(weatherType);
}
void resetWeather(Player player) {
player.resetPlayerWeather();
}
public List<String> aliases() {
return List.of("pweather");
}
}
@@ -1,19 +0,0 @@
package com.alttd.essentia.commands.admin;
import com.alttd.essentia.EssentiaPlugin;
import com.alttd.essentia.commands.AdminSubCommand;
import org.bukkit.command.CommandSender;
public class ReloadCommand extends AdminSubCommand {
public ReloadCommand(EssentiaPlugin plugin) {
super(plugin, "reload");
}
@Override
protected boolean execute(CommandSender sender, String... args) {
plugin.loadConfiguration();
return true;
}
}
@@ -0,0 +1,79 @@
package com.alttd.essentia.commands.admin;
import com.alttd.essentia.commands.EssentiaCommand;
import com.alttd.essentia.commands.argumement.EquipmentArgumentType;
import com.mojang.brigadier.builder.LiteralArgumentBuilder;
import com.mojang.brigadier.tree.LiteralCommandNode;
import io.papermc.paper.command.brigadier.CommandSourceStack;
import io.papermc.paper.command.brigadier.Commands;
import io.papermc.paper.command.brigadier.argument.ArgumentTypes;
import io.papermc.paper.command.brigadier.argument.resolvers.selector.PlayerSelectorArgumentResolver;
import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder;
import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.bukkit.inventory.EquipmentSlot;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.Damageable;
import org.jetbrains.annotations.NotNull;
public class RepairCommand implements EssentiaCommand {
@Override
public String commandName() {
return "repair";
}
@Override
public @NotNull LiteralCommandNode<CommandSourceStack> command() {
final LiteralArgumentBuilder<CommandSourceStack> builder =
Commands.literal(commandName())
.requires(commandSourceStack -> commandSourceStack.getSender().hasPermission(adminCommandPermission()))
// .executes((source) -> {
// if (source.getSource().getSender() instanceof Player player)
// execute(player, player);
//
// return 1;
// })
.then(Commands.argument("equipmentslot", new EquipmentArgumentType())
.executes((source) -> {
if (!(source.getSource().getSender() instanceof Player player))
return 1;
EquipmentSlot equipmentSlot = source.getArgument("equipmentslot", EquipmentSlot.class);
execute(source.getSource().getSender(), player, equipmentSlot);
return 1;
})
.then(
Commands.argument("player", ArgumentTypes.player())
.requires(commandSourceStack -> commandSourceStack.getSender().hasPermission(adminOtherCommandPermission()))
.executes((source) -> {
CommandSourceStack sourceStack = source.getSource();
Player target = source.getArgument("player", PlayerSelectorArgumentResolver.class).resolve(sourceStack).getFirst();
EquipmentSlot equipmentSlot = source.getArgument("equipmentslot", EquipmentSlot.class);
execute(source.getSource().getSender(), target, equipmentSlot);
return 1;
})
)
);
return builder.build();
}
// TODO - placeholders and messages from config
public void execute(CommandSender sender, Player target, EquipmentSlot equipmentSlot) {
TagResolver placeholders = TagResolver.resolver(
Placeholder.component("requester", sender.name()),
Placeholder.component("target", target.displayName())
);
ItemStack itemStack = target.getInventory().getItem(equipmentSlot);
if (!(itemStack.getItemMeta() instanceof Damageable damageable))
return; // send message can not repair this item
damageable.setDamage(0);
sender.sendRichMessage(target == sender ? "You have repaired your <item>." : "<sender> has repaired your <item>.", placeholders);
if (target != sender)
target.sendRichMessage("You repaired <target>'s <item>.", placeholders);
}
}
@@ -0,0 +1,48 @@
package com.alttd.essentia.commands.admin;
import com.alttd.essentia.commands.EssentiaCommand;
import com.alttd.essentia.configuration.Config;
import com.mojang.brigadier.builder.LiteralArgumentBuilder;
import com.mojang.brigadier.tree.LiteralCommandNode;
import io.papermc.paper.command.brigadier.CommandSourceStack;
import io.papermc.paper.command.brigadier.Commands;
import org.bukkit.World;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
public class SetSpawnCommand implements EssentiaCommand {
@Override
public String commandName() {
return "setspawn";
}
@Override
public @NotNull LiteralCommandNode<CommandSourceStack> command() {
final LiteralArgumentBuilder<CommandSourceStack> builder =
Commands.literal(commandName())
.requires(
commandSourceStack -> commandSourceStack.getSender().hasPermission(adminCommandPermission()) &&
commandSourceStack.getSender() instanceof Player
)
.executes((source) -> {
if (source.getSource().getSender() instanceof Player player)
execute(player, player);
return 1;
});
return builder.build();
}
public void execute(CommandSender sender, Player target) {
// Todo - output messages
World world = target.getWorld();
world.setSpawnLocation(target.getLocation());
// TODO -- method in config to update & save
Config.config.set("spawn-world", world.getName());
Config.SPAWN_WORLD = world.getName();
Config.saveConfig();
}
}
@@ -0,0 +1,74 @@
package com.alttd.essentia.commands.admin;
import com.alttd.essentia.commands.EssentiaCommand;
import com.alttd.essentia.configuration.Config;
import com.mojang.brigadier.builder.LiteralArgumentBuilder;
import com.mojang.brigadier.tree.LiteralCommandNode;
import io.papermc.paper.command.brigadier.CommandSourceStack;
import io.papermc.paper.command.brigadier.Commands;
import io.papermc.paper.command.brigadier.argument.ArgumentTypes;
import io.papermc.paper.command.brigadier.argument.resolvers.selector.PlayerSelectorArgumentResolver;
import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder;
import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
import java.util.List;
public class SmiteCommand implements EssentiaCommand {
@Override
public String commandName() {
return "smite";
}
@Override
public @NotNull LiteralCommandNode<CommandSourceStack> command() {
final LiteralArgumentBuilder<CommandSourceStack> builder =
Commands.literal(commandName())
.requires(
commandSourceStack -> commandSourceStack.getSender().hasPermission(adminCommandPermission())
)
.executes((source) -> {
if (source.getSource().getSender() instanceof Player player)
execute(player, player);
return 1;
})
.then(
Commands.argument("player", ArgumentTypes.player())
.requires(commandSourceStack -> commandSourceStack.getSender().hasPermission(adminOtherCommandPermission()))
.executes((source) -> {
CommandSourceStack sourceStack = source.getSource();
Player target = source.getArgument("player", PlayerSelectorArgumentResolver.class).resolve(sourceStack).getFirst();
execute(source.getSource().getSender(), target);
return 1;
})
);
return builder.build();
}
public void execute(CommandSender sender, Player target) {
TagResolver placeholders = TagResolver.resolver(
Placeholder.component("requester", sender.name()),
Placeholder.component("target", target.displayName())
);
if (sender instanceof Player player)
target.damage(100.0D, player);
target.setHealth(0.0D);
target.getWorld().strikeLightningEffect(target.getLocation());
sender.sendRichMessage(target == sender ? Config.SMITE_SELF : Config.SMITE_OTHER, placeholders);
if (target != sender)
target.sendRichMessage(Config.SMITE_BY_OTHER, placeholders);
}
public List<String> aliases() {
return List.of("kill");
}
}
@@ -0,0 +1,52 @@
package com.alttd.essentia.commands.admin;
import com.alttd.essentia.commands.EssentiaCommand;
import com.mojang.brigadier.builder.LiteralArgumentBuilder;
import com.mojang.brigadier.tree.LiteralCommandNode;
import io.papermc.paper.command.brigadier.CommandSourceStack;
import io.papermc.paper.command.brigadier.Commands;
import io.papermc.paper.command.brigadier.argument.ArgumentTypes;
import io.papermc.paper.command.brigadier.argument.resolvers.selector.PlayerSelectorArgumentResolver;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
import java.util.List;
public class TeleportCommand implements EssentiaCommand {
@Override
public String commandName() {
return "teleport";
}
@Override
public @NotNull LiteralCommandNode<CommandSourceStack> command() {
final LiteralArgumentBuilder<CommandSourceStack> builder =
Commands.literal(commandName())
.requires(
commandSourceStack -> commandSourceStack.getSender().hasPermission(adminCommandPermission()) &&
commandSourceStack.getSender() instanceof Player
)
.then(
Commands.argument("player", ArgumentTypes.player())
.requires(commandSourceStack -> commandSourceStack.getSender().hasPermission(adminOtherCommandPermission()))
.executes((source) -> {
CommandSourceStack sourceStack = source.getSource();
Player target = source.getArgument("player", PlayerSelectorArgumentResolver.class).resolve(sourceStack).getFirst();
execute((Player) source.getSource().getSender(), target);
return 1;
})
);
return builder.build();
}
public void execute(Player sender, Player target) {
sender.teleport(target);
}
public List<String> aliases() {
return List.of("tp");
}
}
@@ -0,0 +1,52 @@
package com.alttd.essentia.commands.admin;
import com.alttd.essentia.commands.EssentiaCommand;
import com.mojang.brigadier.builder.LiteralArgumentBuilder;
import com.mojang.brigadier.tree.LiteralCommandNode;
import io.papermc.paper.command.brigadier.CommandSourceStack;
import io.papermc.paper.command.brigadier.Commands;
import io.papermc.paper.command.brigadier.argument.ArgumentTypes;
import io.papermc.paper.command.brigadier.argument.resolvers.selector.PlayerSelectorArgumentResolver;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
import java.util.List;
public class TeleportHereCommand implements EssentiaCommand {
@Override
public String commandName() {
return "teleporthere";
}
@Override
public @NotNull LiteralCommandNode<CommandSourceStack> command() {
final LiteralArgumentBuilder<CommandSourceStack> builder =
Commands.literal(commandName())
.requires(
commandSourceStack -> commandSourceStack.getSender().hasPermission(adminCommandPermission()) &&
commandSourceStack.getSender() instanceof Player
)
.then(
Commands.argument("player", ArgumentTypes.player())
.requires(commandSourceStack -> commandSourceStack.getSender().hasPermission(adminOtherCommandPermission()))
.executes((source) -> {
CommandSourceStack sourceStack = source.getSource();
Player target = source.getArgument("player", PlayerSelectorArgumentResolver.class).resolve(sourceStack).getFirst();
execute((Player) source.getSource().getSender(), target);
return 1;
})
);
return builder.build();
}
public void execute(Player sender, Player target) {
target.teleport(sender);
}
public List<String> aliases() {
return List.of("tp", "tphere");
}
}
@@ -0,0 +1,69 @@
package com.alttd.essentia.commands.admin;
import com.alttd.essentia.commands.EssentiaCommand;
import com.mojang.brigadier.builder.LiteralArgumentBuilder;
import com.mojang.brigadier.tree.LiteralCommandNode;
import io.papermc.paper.command.brigadier.CommandSourceStack;
import io.papermc.paper.command.brigadier.Commands;
import io.papermc.paper.command.brigadier.argument.ArgumentTypes;
import io.papermc.paper.command.brigadier.argument.resolvers.BlockPositionResolver;
import io.papermc.paper.command.brigadier.argument.resolvers.selector.PlayerSelectorArgumentResolver;
import io.papermc.paper.math.BlockPosition;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
import java.util.List;
public class TeleportPositionCommand implements EssentiaCommand {
@Override
public String commandName() {
return "teleportposition";
}
@Override
public @NotNull LiteralCommandNode<CommandSourceStack> command() {
final LiteralArgumentBuilder<CommandSourceStack> builder =
Commands.literal(commandName())
.requires(
commandSourceStack -> commandSourceStack.getSender().hasPermission(adminCommandPermission()) &&
commandSourceStack.getSender() instanceof Player
)
.then(
Commands.argument("pos", ArgumentTypes.blockPosition())
.executes((source) -> {
if (!(source.getSource().getSender() instanceof Player player))
return 1;
CommandSourceStack sourceStack = source.getSource();
BlockPosition position = source.getArgument("pos", BlockPositionResolver.class).resolve(sourceStack);
execute(player, player, position);
return 1;
})
.then(
Commands.argument("player", ArgumentTypes.player())
.requires(commandSourceStack -> commandSourceStack.getSender().hasPermission(adminOtherCommandPermission()))
.executes((source) -> {
if (!(source.getSource().getSender() instanceof Player player))
return 1;
CommandSourceStack sourceStack = source.getSource();
Player target = source.getArgument("player", PlayerSelectorArgumentResolver.class).resolve(sourceStack).getFirst();
BlockPosition position = source.getArgument("pos", BlockPositionResolver.class).resolve(sourceStack);
execute(player, target, position);
return 1;
})
)
);
return builder.build();
}
public void execute(Player sender, Player target, BlockPosition position) {
target.teleport(position.toLocation(target.getWorld()));
}
public List<String> aliases() {
return List.of("tppos");
}
}
@@ -0,0 +1,93 @@
package com.alttd.essentia.commands.admin;
import com.alttd.essentia.commands.EssentiaCommand;
import com.mojang.brigadier.builder.LiteralArgumentBuilder;
import com.mojang.brigadier.tree.LiteralCommandNode;
import io.papermc.paper.command.brigadier.CommandSourceStack;
import io.papermc.paper.command.brigadier.Commands;
import org.bukkit.GameRule;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
// TODO -- output messages
public class TimeCommand implements EssentiaCommand {
@Override
public String commandName() {
return "time";
}
@Override
public @NotNull LiteralCommandNode<CommandSourceStack> command() {
final LiteralArgumentBuilder<CommandSourceStack> builder =
Commands.literal(commandName())
.requires(
commandSourceStack -> commandSourceStack.getSender().hasPermission(adminCommandPermission()) &&
commandSourceStack.getSender() instanceof Player
)
.then(
Commands.literal("freeze")
.executes(commandContext -> {
if (commandContext.getSource().getSender() instanceof Player player)
freeze(player, true);
return 1;
})
)
.then(
Commands.literal("unfreeze")
.executes(commandContext -> {
if (commandContext.getSource().getSender() instanceof Player player)
freeze(player, false);
return 1;
})
)
.then(
Commands.literal("day")
.executes(commandContext -> {
if (commandContext.getSource().getSender() instanceof Player player)
setTime(player, 1000);
return 1;
})
)
.then(
Commands.literal("noon")
.executes(commandContext -> {
if (commandContext.getSource().getSender() instanceof Player player)
setTime(player, 6000);
return 1;
})
)
.then(
Commands.literal("night")
.executes(commandContext -> {
if (commandContext.getSource().getSender() instanceof Player player)
setTime(player, 13000);
return 1;
})
)
.then(
Commands.literal("midnight")
.executes(commandContext -> {
if (commandContext.getSource().getSender() instanceof Player player)
setTime(player, 18000);
return 1;
})
);
return builder.build();
}
void freeze(Player player, boolean value) {
player.getWorld().setGameRule(GameRule.DO_DAYLIGHT_CYCLE, value);
}
void setTime(Player player, int time) {
player.getWorld().setTime(time);
}
}
@@ -0,0 +1,73 @@
package com.alttd.essentia.commands.admin;
import com.alttd.essentia.EssentiaPlugin;
import com.alttd.essentia.api.user.User;
import com.alttd.essentia.api.user.UserManager;
import com.alttd.essentia.commands.EssentiaCommand;
import com.alttd.essentia.configuration.Config;
import com.mojang.brigadier.builder.LiteralArgumentBuilder;
import com.mojang.brigadier.tree.LiteralCommandNode;
import io.papermc.paper.command.brigadier.CommandSourceStack;
import io.papermc.paper.command.brigadier.Commands;
import io.papermc.paper.command.brigadier.argument.ArgumentTypes;
import io.papermc.paper.command.brigadier.argument.resolvers.selector.PlayerSelectorArgumentResolver;
import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder;
import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
public class UnCuffCommand implements EssentiaCommand {
@Override
public String commandName() {
return "uncuff";
}
@Override
public @NotNull LiteralCommandNode<CommandSourceStack> command() {
final LiteralArgumentBuilder<CommandSourceStack> builder =
Commands.literal(commandName())
.requires(
commandSourceStack -> commandSourceStack.getSender().hasPermission(adminCommandPermission())
)
.then(
Commands.argument("player", ArgumentTypes.player())
.requires(commandSourceStack -> commandSourceStack.getSender().hasPermission(adminOtherCommandPermission()))
.executes((source) -> {
CommandSourceStack sourceStack = source.getSource();
Player target = source.getArgument("player", PlayerSelectorArgumentResolver.class).resolve(sourceStack).getFirst();
execute(source.getSource().getSender(), target);
return 1;
})
);
return builder.build();
}
public void execute(CommandSender sender, Player target) {
TagResolver placeholders = TagResolver.resolver(
Placeholder.component("requester", sender.name()),
Placeholder.component("target", target.displayName())
);
UserManager userManager = EssentiaPlugin.instance().userManager();
if (!userManager.hasUser(target.getUniqueId())) {
return;
}
User user = userManager.getUser(target);
if (!user.isCuffed()) {
sender.sendRichMessage("<target> is not cuffed."); // TODO - CONFIG messages
return;
}
user.setCuffed(false);
// TODO - CONFIG messages
sender.sendRichMessage(target == sender ? Config.BURN_SELF : Config.BURN_OTHER, placeholders);
if (target != sender)
target.sendRichMessage(Config.BURN_BY_OTHER, placeholders);
}
}
@@ -0,0 +1,73 @@
package com.alttd.essentia.commands.admin;
import com.alttd.essentia.commands.EssentiaCommand;
import com.alttd.essentia.configuration.Config;
import com.mojang.brigadier.arguments.FloatArgumentType;
import com.mojang.brigadier.builder.LiteralArgumentBuilder;
import com.mojang.brigadier.tree.LiteralCommandNode;
import io.papermc.paper.command.brigadier.CommandSourceStack;
import io.papermc.paper.command.brigadier.Commands;
import io.papermc.paper.command.brigadier.argument.ArgumentTypes;
import io.papermc.paper.command.brigadier.argument.resolvers.selector.PlayerSelectorArgumentResolver;
import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder;
import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver;
import org.bukkit.command.CommandSender;
import org.bukkit.enchantments.Enchantment;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
public class WalkSpeedCommand implements EssentiaCommand {
@Override
public String commandName() {
return "walkspeed";
}
@Override
public @NotNull LiteralCommandNode<CommandSourceStack> command() {
final LiteralArgumentBuilder<CommandSourceStack> builder =
Commands.literal(commandName())
.requires(
commandSourceStack -> commandSourceStack.getSender().hasPermission(adminCommandPermission())
).then(
Commands.argument("speed", FloatArgumentType.floatArg(-1, 1))
.executes((source) -> {
if (!(source.getSource().getSender() instanceof Player player))
return 1;
Enchantment enchantment = source.getArgument("enchantment", Enchantment.class);
float speed = source.getArgument("speed", Float.class);
execute(source.getSource().getSender(), player, speed);
return 1;
})
.then(
Commands.argument("player", ArgumentTypes.player())
.requires(commandSourceStack -> commandSourceStack.getSender().hasPermission(adminOtherCommandPermission()))
.executes((source) -> {
CommandSourceStack sourceStack = source.getSource();
Player target = source.getArgument("player", PlayerSelectorArgumentResolver.class).resolve(sourceStack).getFirst();
float speed = source.getArgument("speed", Float.class);
execute(source.getSource().getSender(), target, speed);
return 1;
})
)
);
return builder.build();
}
public void execute(CommandSender sender, Player target, float speed) {
TagResolver placeholders = TagResolver.resolver(
Placeholder.component("requester", sender.name()),
Placeholder.component("target", target.displayName())
);
target.setFlySpeed(speed);
// TODO - Config messages
sender.sendRichMessage(target == sender ? Config.FEED_SELF : Config.FEED_OTHER, placeholders);
if (target != sender)
target.sendRichMessage(Config.FEED_BY_OTHER, placeholders);
}
}
@@ -0,0 +1,103 @@
package com.alttd.essentia.commands.admin;
import com.alttd.essentia.commands.EssentiaCommand;
import com.mojang.brigadier.arguments.IntegerArgumentType;
import com.mojang.brigadier.builder.LiteralArgumentBuilder;
import com.mojang.brigadier.tree.LiteralCommandNode;
import io.papermc.paper.command.brigadier.CommandSourceStack;
import io.papermc.paper.command.brigadier.Commands;
import io.papermc.paper.command.brigadier.argument.ArgumentTypes;
import io.papermc.paper.command.brigadier.argument.resolvers.selector.PlayerSelectorArgumentResolver;
import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder;
import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver;
import org.bukkit.World;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
import java.util.Random;
// TODO -- output messages
public class WeatherCommand implements EssentiaCommand {
@Override
public String commandName() {
return "weather";
}
@Override
public @NotNull LiteralCommandNode<CommandSourceStack> command() {
final LiteralArgumentBuilder<CommandSourceStack> builder =
Commands.literal(commandName())
.requires(
commandSourceStack -> commandSourceStack.getSender().hasPermission(adminCommandPermission()) &&
commandSourceStack.getSender() instanceof Player
)
.then(
Commands.literal("clear")
.executes(commandContext -> {
if (commandContext.getSource().getSender() instanceof Player player)
clearWeather(player, -1);
return 1;
})
.then(
Commands.argument("duration", ArgumentTypes.time())
.executes(commandContext -> {
int duration = commandContext.getArgument("duration", Integer.class);
if (commandContext.getSource().getSender() instanceof Player player)
clearWeather(player, duration);
return 1;
})
)
)
.then(
Commands.literal("rain")
.executes(commandContext -> {
if (commandContext.getSource().getSender() instanceof Player player)
setRain(player, -1, false);
return 1;
})
.then(
Commands.argument("duration", ArgumentTypes.time())
.executes(commandContext -> {
int duration = commandContext.getArgument("duration", Integer.class);
if (commandContext.getSource().getSender() instanceof Player player)
setRain(player, duration, false);
return 1;
})
)
)
.then(
Commands.literal("thunder")
.executes(commandContext -> {
if (commandContext.getSource().getSender() instanceof Player player)
setRain(player, -1, true);
return 1;
})
.then(
Commands.argument("duration", ArgumentTypes.time())
.executes(commandContext -> {
int duration = commandContext.getArgument("duration", Integer.class);
if (commandContext.getSource().getSender() instanceof Player player)
setRain(player, duration, true);
return 1;
})
)
);
return builder.build();
}
public void clearWeather(Player player, int duration) {
player.getWorld().setClearWeatherDuration(duration == -1 ? new Random().nextInt() : duration);
}
public void setRain(Player player, int duration, boolean thunder) {
player.getWorld().setStorm(thunder);
player.getWorld().setWeatherDuration(duration == -1 ? new Random().nextInt() : duration);
}
}
@@ -0,0 +1,68 @@
package com.alttd.essentia.commands.admin;
import com.alttd.essentia.commands.EssentiaCommand;
import com.mojang.brigadier.builder.LiteralArgumentBuilder;
import com.mojang.brigadier.tree.LiteralCommandNode;
import io.papermc.paper.command.brigadier.CommandSourceStack;
import io.papermc.paper.command.brigadier.Commands;
import io.papermc.paper.command.brigadier.argument.ArgumentTypes;
import io.papermc.paper.command.brigadier.argument.resolvers.selector.PlayerSelectorArgumentResolver;
import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder;
import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
import java.util.List;
public class WorkBenchCommand implements EssentiaCommand {
@Override
public String commandName() {
return "workbench";
}
@Override
public @NotNull LiteralCommandNode<CommandSourceStack> command() {
final LiteralArgumentBuilder<CommandSourceStack> builder =
Commands.literal(commandName())
.requires(
commandSourceStack -> commandSourceStack.getSender().hasPermission(adminCommandPermission())
)
.executes((source) -> {
if (source.getSource().getSender() instanceof Player player)
execute(player, player);
return 1;
})
.then(
Commands.argument("player", ArgumentTypes.player())
.requires(commandSourceStack -> commandSourceStack.getSender().hasPermission(adminOtherCommandPermission()))
.executes((source) -> {
CommandSourceStack sourceStack = source.getSource();
Player target = source.getArgument("player", PlayerSelectorArgumentResolver.class).resolve(sourceStack).getFirst();
execute(source.getSource().getSender(), target);
return 1;
})
);
return builder.build();
}
public void execute(CommandSender sender, Player target) {
TagResolver placeholders = TagResolver.resolver(
Placeholder.component("requester", sender.name()),
Placeholder.component("target", target.displayName())
);
target.openWorkbench(null, true);
// TODO - output config messages
}
@Override
public List<String> aliases() {
return List.of("craft", "craftingtable");
}
}
@@ -0,0 +1,51 @@
package com.alttd.essentia.commands.argumement;
import com.mojang.brigadier.Message;
import com.mojang.brigadier.arguments.ArgumentType;
import com.mojang.brigadier.arguments.StringArgumentType;
import com.mojang.brigadier.context.CommandContext;
import com.mojang.brigadier.exceptions.CommandSyntaxException;
import com.mojang.brigadier.exceptions.SimpleCommandExceptionType;
import com.mojang.brigadier.suggestion.Suggestions;
import com.mojang.brigadier.suggestion.SuggestionsBuilder;
import io.papermc.paper.command.brigadier.MessageComponentSerializer;
import io.papermc.paper.command.brigadier.argument.CustomArgumentType;
import io.papermc.paper.registry.RegistryAccess;
import io.papermc.paper.registry.RegistryKey;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.format.NamedTextColor;
import org.bukkit.NamespacedKey;
import org.bukkit.enchantments.Enchantment;
import org.jetbrains.annotations.NotNull;
import java.util.concurrent.CompletableFuture;
public class EnchantmentArgument implements CustomArgumentType.Converted<Enchantment, String> {
@Override
public @NotNull Enchantment convert(String nativeType) throws CommandSyntaxException {
try {
return Enchantment.getByKey(NamespacedKey.minecraft(nativeType));
} catch (Exception e) {
Message message = MessageComponentSerializer.message().serialize(Component.text("Invalid enchantment %s!".formatted(nativeType), NamedTextColor.RED));
throw new CommandSyntaxException(new SimpleCommandExceptionType(message), message);
}
}
@Override
public @NotNull ArgumentType<String> getNativeType() {
return StringArgumentType.word();
}
@Override
public <S> CompletableFuture<Suggestions> listSuggestions(CommandContext<S> context, SuggestionsBuilder builder) {
for (Enchantment enchantment : RegistryAccess.registryAccess().getRegistry(RegistryKey.ENCHANTMENT)) {
builder.suggest(enchantment.getKey().value());
}
return CompletableFuture.completedFuture(
builder.build()
);
}
}
@@ -0,0 +1,49 @@
package com.alttd.essentia.commands.argumement;
import com.mojang.brigadier.Message;
import com.mojang.brigadier.arguments.ArgumentType;
import com.mojang.brigadier.arguments.StringArgumentType;
import com.mojang.brigadier.context.CommandContext;
import com.mojang.brigadier.exceptions.CommandSyntaxException;
import com.mojang.brigadier.exceptions.SimpleCommandExceptionType;
import com.mojang.brigadier.suggestion.Suggestions;
import com.mojang.brigadier.suggestion.SuggestionsBuilder;
import io.papermc.paper.command.brigadier.MessageComponentSerializer;
import io.papermc.paper.command.brigadier.argument.CustomArgumentType;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.format.NamedTextColor;
import org.bukkit.inventory.EquipmentSlot;
import org.jetbrains.annotations.NotNull;
import java.util.concurrent.CompletableFuture;
public class EquipmentArgumentType implements CustomArgumentType.Converted<EquipmentSlot, String> {
@Override
public @NotNull EquipmentSlot convert(String nativeType) throws CommandSyntaxException {
try {
return EquipmentSlot.valueOf(nativeType.toUpperCase());
} catch (Exception e) {
Message message = MessageComponentSerializer.message().serialize(Component.text("Invalid EquipmentSlot %s!".formatted(nativeType), NamedTextColor.RED));
throw new CommandSyntaxException(new SimpleCommandExceptionType(message), message);
}
}
@Override
public @NotNull ArgumentType<String> getNativeType() {
return StringArgumentType.word();
}
@Override
public <S> CompletableFuture<Suggestions> listSuggestions(CommandContext<S> context, SuggestionsBuilder builder) {
for (EquipmentSlot equipmentSlot : EquipmentSlot.values()) {
builder.suggest(equipmentSlot.name().toLowerCase());
}
return CompletableFuture.completedFuture(
builder.build()
);
}
}
@@ -0,0 +1,58 @@
package com.alttd.essentia.commands.argumement;
import com.alttd.essentia.EssentiaPlugin;
import com.alttd.essentia.api.model.Home;
import com.alttd.essentia.api.user.User;
import com.mojang.brigadier.Message;
import com.mojang.brigadier.arguments.ArgumentType;
import com.mojang.brigadier.arguments.StringArgumentType;
import com.mojang.brigadier.context.CommandContext;
import com.mojang.brigadier.exceptions.CommandSyntaxException;
import com.mojang.brigadier.exceptions.SimpleCommandExceptionType;
import com.mojang.brigadier.suggestion.Suggestions;
import com.mojang.brigadier.suggestion.SuggestionsBuilder;
import io.papermc.paper.command.brigadier.MessageComponentSerializer;
import io.papermc.paper.command.brigadier.argument.CustomArgumentType;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.format.NamedTextColor;
import org.bukkit.OfflinePlayer;
import org.jetbrains.annotations.NotNull;
import java.util.concurrent.CompletableFuture;
public class HomeArgument implements CustomArgumentType.Converted<Home, String> {
User user;
public HomeArgument(OfflinePlayer offlinePlayer) {
user = EssentiaPlugin.instance().userManager().getUser(offlinePlayer.getUniqueId());
if (user == null)
user = EssentiaPlugin.instance().storageProvider().loadUser(offlinePlayer.getUniqueId());
}
@Override
public @NotNull Home convert(String nativeType) throws CommandSyntaxException {
try {
return user.getHome(nativeType);
} catch (Exception e) {
Message message = MessageComponentSerializer.message().serialize(Component.text("Invalid Home %s!".formatted(nativeType), NamedTextColor.RED));
throw new CommandSyntaxException(new SimpleCommandExceptionType(message), message);
}
}
@Override
public @NotNull ArgumentType<String> getNativeType() {
return StringArgumentType.word();
}
@Override
public <S> CompletableFuture<Suggestions> listSuggestions(CommandContext<S> context, SuggestionsBuilder builder) {
for (String home : user.getHomes()) {
builder.suggest(home);
}
return CompletableFuture.completedFuture(
builder.build()
);
}
}
@@ -0,0 +1,34 @@
package com.alttd.essentia.commands.argumement;
import com.mojang.brigadier.Message;
import com.mojang.brigadier.arguments.ArgumentType;
import com.mojang.brigadier.arguments.StringArgumentType;
import com.mojang.brigadier.exceptions.CommandSyntaxException;
import com.mojang.brigadier.exceptions.SimpleCommandExceptionType;
import io.papermc.paper.command.brigadier.MessageComponentSerializer;
import io.papermc.paper.command.brigadier.argument.CustomArgumentType;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.format.NamedTextColor;
import org.bukkit.Bukkit;
import org.bukkit.OfflinePlayer;
import org.jetbrains.annotations.NotNull;
public class OfflinePlayerArgument implements CustomArgumentType.Converted<OfflinePlayer, String> {
@Override
public @NotNull OfflinePlayer convert(String nativeType) throws CommandSyntaxException {
try {
return Bukkit.getOfflinePlayer(nativeType);
} catch (Exception e) {
Message message = MessageComponentSerializer.message().serialize(Component.text("Invalid PlayerName %s!".formatted(nativeType), NamedTextColor.RED));
throw new CommandSyntaxException(new SimpleCommandExceptionType(message), message);
}
}
@Override
public @NotNull ArgumentType<String> getNativeType() {
return StringArgumentType.word();
}
}
@@ -0,0 +1,50 @@
package com.alttd.essentia.commands.argumement;
import com.mojang.brigadier.Message;
import com.mojang.brigadier.arguments.ArgumentType;
import com.mojang.brigadier.arguments.StringArgumentType;
import com.mojang.brigadier.context.CommandContext;
import com.mojang.brigadier.exceptions.CommandSyntaxException;
import com.mojang.brigadier.exceptions.SimpleCommandExceptionType;
import com.mojang.brigadier.suggestion.Suggestions;
import com.mojang.brigadier.suggestion.SuggestionsBuilder;
import io.papermc.paper.command.brigadier.MessageComponentSerializer;
import io.papermc.paper.command.brigadier.argument.CustomArgumentType;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.format.NamedTextColor;
import org.bukkit.Bukkit;
import org.bukkit.OfflinePlayer;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
import java.util.concurrent.CompletableFuture;
public class OfflinePlayerCompletingArgument implements CustomArgumentType.Converted<OfflinePlayer, String> {
@Override
public @NotNull OfflinePlayer convert(String nativeType) throws CommandSyntaxException {
try {
return Bukkit.getOfflinePlayer(nativeType);
} catch (Exception e) {
Message message = MessageComponentSerializer.message().serialize(Component.text("Invalid PlayerName %s!".formatted(nativeType), NamedTextColor.RED));
throw new CommandSyntaxException(new SimpleCommandExceptionType(message), message);
}
}
@Override
public @NotNull ArgumentType<String> getNativeType() {
return StringArgumentType.word();
}
@Override
public <S> CompletableFuture<Suggestions> listSuggestions(CommandContext<S> context, SuggestionsBuilder builder) {
for (Player player : Bukkit.getOnlinePlayers()) {
builder.suggest(player.getName(), MessageComponentSerializer.message().serialize(player.displayName()));
}
return CompletableFuture.completedFuture(
builder.build()
);
}
}
@@ -0,0 +1,48 @@
package com.alttd.essentia.commands.argumement;
import com.mojang.brigadier.Message;
import com.mojang.brigadier.arguments.ArgumentType;
import com.mojang.brigadier.arguments.StringArgumentType;
import com.mojang.brigadier.context.CommandContext;
import com.mojang.brigadier.exceptions.CommandSyntaxException;
import com.mojang.brigadier.exceptions.SimpleCommandExceptionType;
import com.mojang.brigadier.suggestion.Suggestions;
import com.mojang.brigadier.suggestion.SuggestionsBuilder;
import io.papermc.paper.command.brigadier.MessageComponentSerializer;
import io.papermc.paper.command.brigadier.argument.CustomArgumentType;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.format.NamedTextColor;
import org.bukkit.WeatherType;
import org.jetbrains.annotations.NotNull;
import java.util.concurrent.CompletableFuture;
public class WeatherArgument implements CustomArgumentType.Converted<WeatherType, String> {
@Override
public @NotNull WeatherType convert(String nativeType) throws CommandSyntaxException {
try {
return WeatherType.valueOf(nativeType.toUpperCase());
} catch (Exception e) {
Message message = MessageComponentSerializer.message().serialize(Component.text("Invalid WeatherType %s!".formatted(nativeType), NamedTextColor.RED));
throw new CommandSyntaxException(new SimpleCommandExceptionType(message), message);
}
}
@Override
public @NotNull ArgumentType<String> getNativeType() {
return StringArgumentType.word();
}
@Override
public <S> CompletableFuture<Suggestions> listSuggestions(CommandContext<S> context, SuggestionsBuilder builder) {
for (WeatherType weatherType : WeatherType.values()) {
builder.suggest(weatherType.name().toLowerCase());
}
return CompletableFuture.completedFuture(
builder.build()
);
}
}
@@ -1,39 +1,65 @@
package com.alttd.essentia.commands.player; package com.alttd.essentia.commands.player;
import com.alttd.essentia.EssentiaPlugin; import com.alttd.essentia.EssentiaPlugin;
import com.alttd.essentia.commands.PlayerSubCommand; import com.alttd.essentia.api.events.EssentiaEvent;
import com.alttd.essentia.api.events.PlayerTeleportBackEvent;
import com.alttd.essentia.api.user.User;
import com.alttd.essentia.commands.EssentiaCommand;
import com.alttd.essentia.configuration.Config; import com.alttd.essentia.configuration.Config;
import com.alttd.essentia.configuration.PlayerConfig;
import com.alttd.essentia.events.EssentiaEvent;
import com.alttd.essentia.events.PlayerTeleportBackEvent;
import com.alttd.essentia.tasks.TeleportSounds; import com.alttd.essentia.tasks.TeleportSounds;
import com.mojang.brigadier.builder.LiteralArgumentBuilder;
import com.mojang.brigadier.tree.LiteralCommandNode;
import io.papermc.paper.command.brigadier.CommandSourceStack;
import io.papermc.paper.command.brigadier.Commands;
import org.bukkit.Location; import org.bukkit.Location;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
public class BackCommand extends PlayerSubCommand { public class BackCommand implements EssentiaCommand {
public BackCommand(EssentiaPlugin plugin) { @Override
super(plugin, "back"); public String commandName() {
return "back";
} }
@Override @Override
protected boolean execute(Player player, PlayerConfig playerConfig, String... args) { public @NotNull LiteralCommandNode<CommandSourceStack> command() {
Location back = playerConfig.getBackLocation(false); final LiteralArgumentBuilder<CommandSourceStack> builder =
Commands.literal(commandName())
.requires(
commandSourceStack -> commandSourceStack.getSender().hasPermission(baseCommandPermission()) &&
commandSourceStack.getSender() instanceof Player
)
.executes((source) -> {
if (source.getSource().getSender() instanceof Player player)
execute(player, player);
if (back == null) { return 1;
player.sendRichMessage(Config.NO_BACK_LOCATION); });
return true; return builder.build();
}
EssentiaEvent event = new PlayerTeleportBackEvent(player, back);
if (!event.callEvent()) {
return true;
}
new TeleportSounds(back, player.getLocation())
.runTaskLater(plugin, 1);
player.teleportAsync(back).thenAccept(result ->
player.sendRichMessage(Config.TELEPORTING_BACK));
return true;
} }
public void execute(CommandSender sender, Player target) {
User user = EssentiaPlugin.instance().userManager().getUser(target);
if (user == null)
return;
Location back = user.getBackLocation(false);
if (back == null) {
target.sendRichMessage(Config.NO_BACK_LOCATION);
return;
}
EssentiaEvent event = new PlayerTeleportBackEvent(target, back);
if (!event.callEvent()) {
return;
}
new TeleportSounds(back, target.getLocation())
.runTaskLater(EssentiaPlugin.instance(), 1);
target.teleportAsync(back).thenAccept(result ->
target.sendRichMessage(Config.TELEPORTING_BACK));
}
} }
@@ -1,39 +1,71 @@
package com.alttd.essentia.commands.player; package com.alttd.essentia.commands.player;
import com.alttd.essentia.EssentiaPlugin; import com.alttd.essentia.EssentiaPlugin;
import com.alttd.essentia.commands.PlayerSubCommand; import com.alttd.essentia.commands.EssentiaCommand;
import com.alttd.essentia.configuration.Config; import com.alttd.essentia.configuration.Config;
import com.alttd.essentia.configuration.PlayerConfig; import com.alttd.essentia.api.events.EssentiaEvent;
import com.alttd.essentia.events.EssentiaEvent; import com.alttd.essentia.api.events.PlayerTeleportBackEvent;
import com.alttd.essentia.events.PlayerTeleportBackEvent;
import com.alttd.essentia.tasks.TeleportSounds; import com.alttd.essentia.tasks.TeleportSounds;
import com.alttd.essentia.api.user.User;
import com.mojang.brigadier.builder.LiteralArgumentBuilder;
import com.mojang.brigadier.tree.LiteralCommandNode;
import io.papermc.paper.command.brigadier.CommandSourceStack;
import io.papermc.paper.command.brigadier.Commands;
import org.bukkit.Location; import org.bukkit.Location;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
public class DeathBackCommand extends PlayerSubCommand { import java.util.List;
public DeathBackCommand(EssentiaPlugin plugin) { public class DeathBackCommand implements EssentiaCommand {
super(plugin, "back");
@Override
public String commandName() {
return "deathback";
} }
@Override @Override
protected boolean execute(Player player, PlayerConfig playerConfig, String... args) { public @NotNull LiteralCommandNode<CommandSourceStack> command() {
Location back = playerConfig.getBackLocation(true); final LiteralArgumentBuilder<CommandSourceStack> builder =
Commands.literal(commandName())
.requires(
commandSourceStack -> commandSourceStack.getSender().hasPermission(baseCommandPermission()) &&
commandSourceStack.getSender() instanceof Player
)
.executes((source) -> {
if (source.getSource().getSender() instanceof Player player)
execute(player, player);
return 1;
});
return builder.build();
}
public void execute(CommandSender sender, Player target) {
User user = EssentiaPlugin.instance().userManager().getUser(target);
if (user == null)
return;
Location back = user.getBackLocation(true);
if (back == null) { if (back == null) {
player.sendRichMessage(Config.NO_DEATH_LOCATION); target.sendRichMessage(Config.NO_DEATH_LOCATION);
return true; return;
} }
EssentiaEvent event = new PlayerTeleportBackEvent(player, back); EssentiaEvent event = new PlayerTeleportBackEvent(target, back);
if (!event.callEvent()) { if (!event.callEvent()) {
return true; return;
} }
new TeleportSounds(back, player.getLocation()) new TeleportSounds(back, target.getLocation())
.runTaskLater(plugin, 1); .runTaskLater(EssentiaPlugin.instance(), 1);
player.teleportAsync(back).thenAccept(result -> target.teleportAsync(back).thenAccept(result ->
player.sendRichMessage(Config.TELEPORTING_BACK_DEATH)); target.sendRichMessage(Config.TELEPORTING_BACK_DEATH));
return true; }
public List<String> aliases() {
return List.of("dback");
} }
} }
@@ -1,42 +1,153 @@
package com.alttd.essentia.commands.player; package com.alttd.essentia.commands.player;
import com.alttd.essentia.EssentiaPlugin; import com.alttd.essentia.EssentiaPlugin;
import com.alttd.essentia.commands.PlayerSubCommand; import com.alttd.essentia.commands.EssentiaCommand;
import com.alttd.essentia.commands.argumement.OfflinePlayerArgument;
import com.alttd.essentia.configuration.Config; import com.alttd.essentia.configuration.Config;
import com.alttd.essentia.configuration.PlayerConfig; import com.alttd.essentia.api.events.EssentiaEvent;
import com.alttd.essentia.events.EssentiaEvent; import com.alttd.essentia.api.events.PlayerRemoveHomeEvent;
import com.alttd.essentia.events.PlayerRemoveHomeEvent; import com.alttd.essentia.api.user.User;
import com.alttd.essentia.events.PlayerTeleportBackEvent; import com.mojang.brigadier.arguments.StringArgumentType;
import com.mojang.brigadier.builder.LiteralArgumentBuilder;
import com.mojang.brigadier.suggestion.Suggestions;
import com.mojang.brigadier.tree.LiteralCommandNode;
import io.papermc.paper.command.brigadier.CommandSourceStack;
import io.papermc.paper.command.brigadier.Commands;
import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder; import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder;
import org.bukkit.OfflinePlayer;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
public class DelHomeCommand extends PlayerSubCommand { import java.util.ArrayList;
import java.util.Collection;
public DelHomeCommand(EssentiaPlugin plugin) { public class DelHomeCommand implements EssentiaCommand {
super(plugin, "deletehome");
@Override
public String commandName() {
return "delhome";
} }
@Override @Override
protected boolean execute(Player player, PlayerConfig playerConfig, String... args) { public @NotNull LiteralCommandNode<CommandSourceStack> command() {
// TODO -- subcommand to remove other player homes final LiteralArgumentBuilder<CommandSourceStack> builder =
// if (args.length > 1) { Commands.literal(commandName())
// if (!player.hasPermission("essentia.command.delhome.other")) { .requires(
// return true; commandSourceStack -> commandSourceStack.getSender().hasPermission(baseCommandPermission()) &&
// } commandSourceStack.getSender() instanceof Player
// } )
.executes((source) -> {
if (source.getSource().getSender() instanceof Player player)
execute(player, player);
String home = (args.length > 0) ? args[0] : "home"; return 1;
if (!playerConfig.hasHome(home)) { })
player.sendRichMessage(Config.HOME_DOES_NOT_EXIST, Placeholder.unparsed("home", home)); .then(
return true; Commands.argument("home", StringArgumentType.word())
.suggests((context, suggestionsBuilder) -> {
if (!(context.getSource().getSender() instanceof Player player))
return Suggestions.empty();
User user = EssentiaPlugin.instance().userManager().getUser(player);
Collection<String> possibleValues = new ArrayList<>(user.getHomes());
if(possibleValues.isEmpty())
return Suggestions.empty();
String remaining = suggestionsBuilder.getRemaining().toLowerCase();
for (String str : possibleValues) {
if (str.toLowerCase().startsWith(remaining)) {
suggestionsBuilder.suggest(StringArgumentType.escapeIfRequired(str));
}
}
return suggestionsBuilder.buildFuture();
})
.executes((source) -> {
if (!(source.getSource().getSender() instanceof Player player))
return 1;
String home = source.getArgument("home", String.class);
execute(player, player, home);
return 1;
})
)
.then(
Commands.argument("player", new OfflinePlayerArgument())
.requires(commandSourceStack -> commandSourceStack.getSender().hasPermission(baseOtherCommandPermission()))
.then(
Commands.argument("home", StringArgumentType.word())
.suggests((context, suggestionsBuilder) -> {
if (!(context.getSource().getSender() instanceof Player))
return Suggestions.empty();
OfflinePlayer target = context.getArgument("player", OfflinePlayer.class);
User user = EssentiaPlugin.instance().userManager().getUser(target.getUniqueId());
if (user == null)
user = EssentiaPlugin.instance().storageProvider().loadUser(target.getUniqueId());
Collection<String> possibleValues = new ArrayList<>(user.getHomes());
if(possibleValues.isEmpty())
return Suggestions.empty();
String remaining = suggestionsBuilder.getRemaining().toLowerCase();
for (String str : possibleValues) {
if (str.toLowerCase().startsWith(remaining)) {
suggestionsBuilder.suggest(StringArgumentType.escapeIfRequired(str));
}
}
return suggestionsBuilder.buildFuture();
})
.executes((source) -> {
if (!(source.getSource().getSender() instanceof Player player))
return 1;
OfflinePlayer target = source.getArgument("player", OfflinePlayer.class);
String home = source.getArgument("home", String.class);
execute(player, target, home);
return 1;
})
)
);
return builder.build();
}
public void execute(Player sender, Player target) {
execute(sender, target, "home");
}
public void execute(Player sender, OfflinePlayer target, String home) {
User user = EssentiaPlugin.instance().userManager().getUser(target.getUniqueId());
if (user == null)
return;
user = EssentiaPlugin.instance().storageProvider().loadUser(target.getUniqueId());
delHome(sender, user, home);
}
public void execute(Player sender, Player target, String home) {
User user = EssentiaPlugin.instance().userManager().getUser(target);
if (user == null)
return;
delHome(sender, user, home);
}
private void delHome(Player sender, User user, String home) {
if (!user.hasHome(home)) {
sender.sendRichMessage(Config.HOME_DOES_NOT_EXIST, Placeholder.unparsed("home", home));
return;
} }
EssentiaEvent event = new PlayerRemoveHomeEvent(player, home);
EssentiaEvent event = new PlayerRemoveHomeEvent(sender, home);
if (!event.callEvent()) { if (!event.callEvent()) {
return true; return;
} }
playerConfig.setHome(home, null);
player.sendRichMessage(Config.HOME_DELETED, Placeholder.unparsed("home", home)); user.setHome(home, null);
return true; sender.sendRichMessage(Config.HOME_DELETED, Placeholder.unparsed("home", home));
} }
} }
@@ -0,0 +1,64 @@
package com.alttd.essentia.commands.player;
import com.alttd.essentia.commands.EssentiaCommand;
import com.mojang.brigadier.builder.LiteralArgumentBuilder;
import com.mojang.brigadier.tree.LiteralCommandNode;
import io.papermc.paper.command.brigadier.CommandSourceStack;
import io.papermc.paper.command.brigadier.Commands;
import io.papermc.paper.command.brigadier.argument.ArgumentTypes;
import io.papermc.paper.command.brigadier.argument.resolvers.selector.PlayerSelectorArgumentResolver;
import net.kyori.adventure.text.minimessage.MiniMessage;
import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder;
import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver;
import org.bukkit.Bukkit;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.bukkit.inventory.Inventory;
import org.jetbrains.annotations.NotNull;
public class DisposeCommand implements EssentiaCommand {
@Override
public String commandName() {
return "dispose";
}
@Override
public @NotNull LiteralCommandNode<CommandSourceStack> command() {
final LiteralArgumentBuilder<CommandSourceStack> builder =
Commands.literal(commandName())
.requires(
commandSourceStack -> commandSourceStack.getSender().hasPermission(baseCommandPermission())
)
.executes((source) -> {
if (source.getSource().getSender() instanceof Player player)
execute(player, player);
return 1;
})
.then(
Commands.argument("player", ArgumentTypes.player())
.requires(commandSourceStack -> commandSourceStack.getSender().hasPermission(baseOtherCommandPermission()))
.executes((source) -> {
CommandSourceStack sourceStack = source.getSource();
Player target = source.getArgument("player", PlayerSelectorArgumentResolver.class).resolve(sourceStack).getFirst();
execute(source.getSource().getSender(), target);
return 1;
})
);
return builder.build();
}
public void execute(CommandSender sender, Player target) {
TagResolver placeholders = TagResolver.resolver(
Placeholder.component("requester", sender.name()),
Placeholder.component("target", target.displayName())
);
Inventory inventory = Bukkit.createInventory(null, 36, MiniMessage.miniMessage().deserialize("Item Disposal")); // TODO - config
// TODO - PlayerItemDisposeEvent
target.openInventory(inventory);
}
}
@@ -1,84 +1,111 @@
package com.alttd.essentia.commands.player; package com.alttd.essentia.commands.player;
import com.alttd.essentia.EssentiaPlugin; import com.alttd.essentia.EssentiaPlugin;
import com.alttd.essentia.commands.PlayerSubCommand; import com.alttd.essentia.api.events.EssentiaEvent;
import com.alttd.essentia.api.events.PlayerTeleportHomeEvent;
import com.alttd.essentia.api.model.Home;
import com.alttd.essentia.commands.EssentiaCommand;
import com.alttd.essentia.configuration.Config; import com.alttd.essentia.configuration.Config;
import com.alttd.essentia.configuration.PlayerConfig; import com.alttd.essentia.api.user.User;
import com.alttd.essentia.events.EssentiaEvent;
import com.alttd.essentia.events.PlayerTeleportBackEvent;
import com.alttd.essentia.events.PlayerTeleportHomeEvent;
import com.alttd.essentia.tasks.TeleportSounds; import com.alttd.essentia.tasks.TeleportSounds;
import com.mojang.brigadier.arguments.StringArgumentType;
import com.mojang.brigadier.builder.LiteralArgumentBuilder;
import com.mojang.brigadier.suggestion.Suggestions;
import com.mojang.brigadier.tree.LiteralCommandNode;
import io.papermc.paper.command.brigadier.CommandSourceStack;
import io.papermc.paper.command.brigadier.Commands;
import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder; import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder;
import org.bukkit.Location; import org.bukkit.Location;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import java.util.List; import java.util.ArrayList;
import java.util.Collection;
public class HomeCommand extends PlayerSubCommand { // TODO - home other
public class HomeCommand implements EssentiaCommand {
public HomeCommand(EssentiaPlugin plugin) { @Override
super(plugin, "home"); public String commandName() {
return "home";
} }
@Override @Override
protected boolean execute(Player player, PlayerConfig playerConfig, String... args) { public @NotNull LiteralCommandNode<CommandSourceStack> command() {
String home = null; final LiteralArgumentBuilder<CommandSourceStack> builder =
if (args.length == 0) { Commands.literal(commandName())
int count = playerConfig.getHomeCount(); .requires(
if (count == 0) { commandSourceStack -> commandSourceStack.getSender().hasPermission(baseCommandPermission()) &&
if (player.getBedSpawnLocation() != null) { commandSourceStack.getSender() instanceof Player
home = "bed"; )
} .executes((source) -> {
} else if (count == 1) { if (source.getSource().getSender() instanceof Player player)
home = playerConfig.getConfigurationSection("home").getKeys(false) execute(player, player, "home");
.stream().findFirst().orElse(null);
} else {
player.sendRichMessage(Config.SPECIFY_HOME, Placeholder.unparsed("homelist", String.join(", ", playerConfig.getHomeList())));
return true;
}
if (home == null || home.isEmpty()) {
player.sendRichMessage(Config.HOME_NOT_SET);
return true;
}
return true;
} else {
home = args[0];
}
// TODO - subcommand to teleport to others homes
// if (args.length > 1) {
// if (!player.hasPermission("essentia.command.home.other")) {
// return true
// }
// }
Location homeLoc = home.equalsIgnoreCase("bed") ? return 1;
player.getBedSpawnLocation() : playerConfig.getHome(home); })
.then(
Commands.argument("name", StringArgumentType.word())
.suggests((context, suggestionsBuilder) -> {
if (!(context.getSource().getSender() instanceof Player player))
return Suggestions.empty();
User user = EssentiaPlugin.instance().userManager().getUser(player);
Collection<String> possibleValues = new ArrayList<>(user.getHomes());
if(possibleValues.isEmpty())
return Suggestions.empty();
String remaining = suggestionsBuilder.getRemaining().toLowerCase();
for (String str : possibleValues) {
if (str.toLowerCase().startsWith(remaining)) {
suggestionsBuilder.suggest(StringArgumentType.escapeIfRequired(str));
}
}
return suggestionsBuilder.buildFuture();
})
.executes((source) -> {
if (!(source.getSource().getSender() instanceof Player player))
return 1;
String name = source.getArgument("name", String.class);
execute(player, player, name);
return 1;
})
);
return builder.build();
}
public void execute(CommandSender sender, Player target, String home) {
User user = EssentiaPlugin.instance().userManager().getUser(target);
if (user == null)
return;
Home essentiaHome = user.getHome(home);
if (essentiaHome == null) {
sender.sendRichMessage(Config.HOME_DOES_NOT_EXIST, Placeholder.parsed("home", home));
return;
}
Location homeLoc = essentiaHome.location();
if (homeLoc == null) { if (homeLoc == null) {
player.sendRichMessage(Config.HOME_DOES_NOT_EXIST, Placeholder.parsed("home", home)); sender.sendRichMessage(Config.HOME_DOES_NOT_EXIST, Placeholder.parsed("home", home));
return true; sender.sendRichMessage(Config.SPECIFY_HOME, Placeholder.unparsed("homelist", String.join(", ", user.getHomes())));
return;
} }
EssentiaEvent event = new PlayerTeleportHomeEvent(player, homeLoc, home);
EssentiaEvent event = new PlayerTeleportHomeEvent(target, homeLoc, home);
if (!event.callEvent()) { if (!event.callEvent()) {
return true; return;
} }
new TeleportSounds(homeLoc, player.getLocation()) new TeleportSounds(homeLoc, target.getLocation())
.runTaskLater(plugin, 1); .runTaskLater(EssentiaPlugin.instance(), 1);
String homeName = home; target.teleportAsync(homeLoc).thenAccept(result ->
player.teleportAsync(homeLoc).thenAccept(result -> target.sendRichMessage(Config.HOME_TELEPORT, Placeholder.unparsed("home", home))
player.sendRichMessage(Config.HOME_TELEPORT, Placeholder.unparsed("home", homeName))
); );
return true;
} }
@Override
public List<String> onTabComplete(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, String[] args) {
if (args.length == 1) {
return PlayerConfig.getConfig((Player) sender).getMatchingHomeNames(args[0]);
}
return null;
}
} }
@@ -1,29 +1,68 @@
package com.alttd.essentia.commands.player; package com.alttd.essentia.commands.player;
import com.alttd.essentia.EssentiaPlugin; import com.alttd.essentia.EssentiaPlugin;
import com.alttd.essentia.commands.PlayerSubCommand; import com.alttd.essentia.api.user.User;
import com.alttd.essentia.commands.EssentiaCommand;
import com.alttd.essentia.commands.argumement.OfflinePlayerCompletingArgument;
import com.alttd.essentia.configuration.Config; import com.alttd.essentia.configuration.Config;
import com.alttd.essentia.configuration.PlayerConfig; import com.mojang.brigadier.builder.LiteralArgumentBuilder;
import com.mojang.brigadier.tree.LiteralCommandNode;
import io.papermc.paper.command.brigadier.CommandSourceStack;
import io.papermc.paper.command.brigadier.Commands;
import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder; import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder;
import org.bukkit.OfflinePlayer;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
public class HomeListCommand extends PlayerSubCommand { import java.util.List;
public HomeListCommand(EssentiaPlugin plugin) { public class HomeListCommand implements EssentiaCommand {
super(plugin, "homes");
@Override
public String commandName() {
return "homelist";
} }
@Override @Override
protected boolean execute(Player player, PlayerConfig playerConfig, String... args) { public @NotNull LiteralCommandNode<CommandSourceStack> command() {
// TODO - subcommand to list other homes final LiteralArgumentBuilder<CommandSourceStack> builder =
// if (args.length > 0) { Commands.literal(commandName())
// if (!player.hasPermission("essentia.command.homes.other")) { .requires(
// return true; commandSourceStack -> commandSourceStack.getSender().hasPermission(baseCommandPermission())
// } )
// } .executes((source) -> {
if (source.getSource().getSender() instanceof Player player)
execute(player, player);
return 1;
})
.then(
Commands.argument("player", new OfflinePlayerCompletingArgument())
.requires(commandSourceStack -> commandSourceStack.getSender().hasPermission(baseOtherCommandPermission()))
.executes((source) -> {
OfflinePlayer target = source.getArgument("player", OfflinePlayer.class);
execute(source.getSource().getSender(), target);
return 1;
})
);
return builder.build();
}
public void execute(CommandSender sender, OfflinePlayer target) {
User user = EssentiaPlugin.instance().userManager().getUser(target.getUniqueId());
if (user == null)
return;
user = EssentiaPlugin.instance().storageProvider().loadUser(target.getUniqueId());
// TODO - clickable homes that run /home <name> // TODO - clickable homes that run /home <name>
player.sendRichMessage(Config.HOME_LIST, Placeholder.unparsed("homelist", String.join(", ", playerConfig.getHomeList()))); sender.sendRichMessage(Config.HOME_LIST, Placeholder.unparsed("homelist", String.join(", ", user.getHomes())));
return true;
} }
public List<String> aliases() {
return List.of("homes");
}
} }
@@ -1,51 +1,123 @@
package com.alttd.essentia.commands.player; package com.alttd.essentia.commands.player;
import com.alttd.essentia.EssentiaPlugin; import com.alttd.essentia.EssentiaPlugin;
import com.alttd.essentia.commands.PlayerSubCommand; import com.alttd.essentia.api.events.EssentiaEvent;
import com.alttd.essentia.api.events.PlayerSetHomeEvent;
import com.alttd.essentia.api.user.User;
import com.alttd.essentia.commands.EssentiaCommand;
import com.alttd.essentia.commands.argumement.OfflinePlayerArgument;
import com.alttd.essentia.configuration.Config; import com.alttd.essentia.configuration.Config;
import com.alttd.essentia.configuration.PlayerConfig; import com.mojang.brigadier.arguments.StringArgumentType;
import com.alttd.essentia.events.EssentiaEvent; import com.mojang.brigadier.builder.LiteralArgumentBuilder;
import com.alttd.essentia.events.PlayerSetHomeEvent; import com.mojang.brigadier.tree.LiteralCommandNode;
import com.alttd.essentia.events.PlayerTeleportHomeEvent; import io.papermc.paper.command.brigadier.CommandSourceStack;
import io.papermc.paper.command.brigadier.Commands;
import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder; import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder;
import org.bukkit.Location; import org.bukkit.Location;
import org.bukkit.OfflinePlayer;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
public class SetHomeCommand extends PlayerSubCommand { public class SetHomeCommand implements EssentiaCommand {
@Override
public SetHomeCommand(EssentiaPlugin plugin) { public String commandName() {
super(plugin, "sethome"); return "sethome";
} }
@Override @Override
protected boolean execute(Player player, PlayerConfig playerConfig, String... args) { public @NotNull LiteralCommandNode<CommandSourceStack> command() {
// TODO -- subcommand to allow setting other player homes final LiteralArgumentBuilder<CommandSourceStack> builder =
// if (args.length > 1) { Commands.literal(commandName())
// if (!player.hasPermission("essentia.command.sethome.other")) { .requires(
// return true; commandSourceStack -> commandSourceStack.getSender().hasPermission(baseCommandPermission()) &&
// } commandSourceStack.getSender() instanceof Player
// } )
.executes((source) -> {
if (source.getSource().getSender() instanceof Player player)
execute(player, player);
String home = (args.length > 0) ? args[0] : "home"; return 1;
if (home.equalsIgnoreCase("bed") || home.contains(".")) { })
player.sendRichMessage(Config.INVALID_HOME_NAME); .then(
return true; Commands.argument("name", StringArgumentType.word())
.executes((source) -> {
if (!(source.getSource().getSender() instanceof Player player))
return 1;
String name = source.getArgument("name", String.class);
execute(player, player, name);
return 1;
})
)
.then(
Commands.argument("player", new OfflinePlayerArgument())
.requires(commandSourceStack -> commandSourceStack.getSender().hasPermission(baseOtherCommandPermission()))
.then(
Commands.argument("name", StringArgumentType.word())
.executes((source) -> {
if (!(source.getSource().getSender() instanceof Player player))
return 1;
OfflinePlayer target = source.getArgument("player", OfflinePlayer.class);
String name = source.getArgument("name", String.class);
execute(player, target, name);
return 1;
})
)
);
return builder.build();
}
public void execute(Player sender, Player target) {
execute(sender, target, "home");
}
public void execute(Player sender, OfflinePlayer target, String home) {
User user = EssentiaPlugin.instance().userManager().getUser(target.getUniqueId());
if (user == null)
return;
user = EssentiaPlugin.instance().storageProvider().loadUser(target.getUniqueId());
setHome(sender, user, home);
}
public void execute(Player sender, Player target, String home) {
User user = EssentiaPlugin.instance().userManager().getUser(target);
if (user == null)
return;
setHome(sender, user, home);
}
private void setHome(Player sender, User user, String home) {
if (home.contains(".")) {
sender.sendRichMessage(Config.INVALID_HOME_NAME);
return;
} }
if (user.hasHome(home)) {
sender.sendRichMessage("<home> already exists.", Placeholder.unparsed("home", home)); // TODO -- CONFIG
return;
}
int limit = 5; // TODO -- player home limits hardcoded for now int limit = 5; // TODO -- player home limits hardcoded for now
int count = playerConfig.getHomeCount(); int count = user.getHomeCount();
if (limit >= 0 && count >= limit) { if (limit >= 0 && count >= limit) {
player.sendRichMessage(Config.HOME_SET_MAX, Placeholder.unparsed("limit", String.valueOf(limit))); sender.sendRichMessage(Config.HOME_SET_MAX, Placeholder.unparsed("limit", String.valueOf(limit)));
return true; return;
} }
Location homeLoc = player.getLocation();
EssentiaEvent event = new PlayerSetHomeEvent(player, homeLoc, home); Location homeLoc = sender.getLocation();
EssentiaEvent event = new PlayerSetHomeEvent(sender, homeLoc, home);
if (!event.callEvent()) { if (!event.callEvent()) {
return true; return;
} }
playerConfig.setHome(home, homeLoc);
player.sendRichMessage(Config.HOME_SET, Placeholder.unparsed("home", home)); user.setHome(home, homeLoc);
return true; sender.sendRichMessage(Config.HOME_SET, Placeholder.unparsed("home", home));
} }
} }
@@ -1,41 +1,78 @@
package com.alttd.essentia.commands.player; package com.alttd.essentia.commands.player;
import com.alttd.essentia.EssentiaPlugin; import com.alttd.essentia.EssentiaPlugin;
import com.alttd.essentia.commands.PlayerSubCommand; import com.alttd.essentia.api.events.PlayerTeleportSpawnEvent;
import com.alttd.essentia.commands.EssentiaCommand;
import com.alttd.essentia.configuration.Config; import com.alttd.essentia.configuration.Config;
import com.alttd.essentia.configuration.PlayerConfig; import com.alttd.essentia.api.events.EssentiaEvent;
import com.alttd.essentia.events.EssentiaEvent;
import com.alttd.essentia.events.PlayerSetHomeEvent;
import com.alttd.essentia.events.PlayerTeleportSpawnEvent;
import com.alttd.essentia.tasks.TeleportSounds; import com.alttd.essentia.tasks.TeleportSounds;
import com.alttd.essentia.api.user.User;
import com.mojang.brigadier.builder.LiteralArgumentBuilder;
import com.mojang.brigadier.tree.LiteralCommandNode;
import io.papermc.paper.command.brigadier.CommandSourceStack;
import io.papermc.paper.command.brigadier.Commands;
import io.papermc.paper.command.brigadier.argument.ArgumentTypes;
import io.papermc.paper.command.brigadier.argument.resolvers.selector.PlayerSelectorArgumentResolver;
import org.bukkit.Location; import org.bukkit.Location;
import org.bukkit.World; import org.bukkit.World;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
public class SpawnCommand extends PlayerSubCommand { public class SpawnCommand implements EssentiaCommand {
public SpawnCommand(EssentiaPlugin plugin) { @Override
super(plugin, "back"); public String commandName() {
return "spawn";
} }
@Override @Override
protected boolean execute(Player player, PlayerConfig playerConfig, String... args) { public @NotNull LiteralCommandNode<CommandSourceStack> command() {
World world = plugin.getServer().getWorld(Config.SPAWN_WORLD); final LiteralArgumentBuilder<CommandSourceStack> builder =
Commands.literal(commandName())
.requires(
commandSourceStack -> commandSourceStack.getSender().hasPermission(baseCommandPermission())
)
.executes((source) -> {
if (source.getSource().getSender() instanceof Player player)
execute(player, player);
return 1;
})
.then(
Commands.argument("player", ArgumentTypes.player())
.requires(commandSourceStack -> commandSourceStack.getSender().hasPermission(baseOtherCommandPermission()))
.executes((source) -> {
CommandSourceStack sourceStack = source.getSource();
Player target = source.getArgument("player", PlayerSelectorArgumentResolver.class).resolve(sourceStack).getFirst();
execute(source.getSource().getSender(), target);
return 1;
})
);
return builder.build();
}
public void execute(CommandSender sender, Player target) {
User user = EssentiaPlugin.instance().userManager().getUser(target);
if (user == null)
return;
World world = EssentiaPlugin.instance().getServer().getWorld(Config.SPAWN_WORLD);
if (world == null) { if (world == null) {
player.sendRichMessage("<red>Could not get the configured spawn world! contact and administrator"); sender.sendRichMessage("<red>Could not get the configured spawn world! contact an administrator");
return true; return;
} }
Location spawnLocation = world.getSpawnLocation(); Location spawnLocation = world.getSpawnLocation();
EssentiaEvent event = new PlayerTeleportSpawnEvent(player, spawnLocation); EssentiaEvent event = new PlayerTeleportSpawnEvent(target, spawnLocation);
if (!event.callEvent()) { if (!event.callEvent()) {
return true; return;
} }
new TeleportSounds(spawnLocation, player.getLocation()) new TeleportSounds(spawnLocation, target.getLocation())
.runTaskLater(plugin, 1); .runTaskLater(EssentiaPlugin.instance(), 1);
player.teleportAsync(spawnLocation).thenAccept(result -> target.teleportAsync(spawnLocation).thenAccept(result ->
player.sendRichMessage("Teleporting to spawn")); target.sendRichMessage("Teleporting to spawn"));
return true;
} }
} }
@@ -1,27 +1,60 @@
package com.alttd.essentia.commands.player; package com.alttd.essentia.commands.player;
import com.alttd.essentia.EssentiaPlugin; import com.alttd.essentia.EssentiaPlugin;
import com.alttd.essentia.commands.PlayerSubCommand; import com.alttd.essentia.commands.EssentiaCommand;
import com.alttd.essentia.configuration.Config; import com.alttd.essentia.configuration.Config;
import com.alttd.essentia.configuration.PlayerConfig; import com.alttd.essentia.api.request.Request;
import com.alttd.essentia.request.Request; import com.alttd.essentia.api.user.User;
import com.mojang.brigadier.builder.LiteralArgumentBuilder;
import com.mojang.brigadier.tree.LiteralCommandNode;
import io.papermc.paper.command.brigadier.CommandSourceStack;
import io.papermc.paper.command.brigadier.Commands;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
public class TeleportAcceptCommand extends PlayerSubCommand { import java.util.List;
public TeleportAcceptCommand(EssentiaPlugin plugin) { public class TeleportAcceptCommand implements EssentiaCommand {
super(plugin, "teleportaccept");
@Override
public String commandName() {
return "teleportaccept";
} }
@Override @Override
protected boolean execute(Player player, PlayerConfig playerConfig, String... args) { public @NotNull LiteralCommandNode<CommandSourceStack> command() {
Request request = playerConfig.request(); final LiteralArgumentBuilder<CommandSourceStack> builder =
Commands.literal(commandName())
.requires(
commandSourceStack -> commandSourceStack.getSender().hasPermission(baseCommandPermission()) &&
commandSourceStack.getSender() instanceof Player
)
.executes((source) -> {
if (source.getSource().getSender() instanceof Player player)
execute(player, player);
return 1;
});
return builder.build();
}
public void execute(Player player, Player target) {
User user = EssentiaPlugin.instance().userManager().getUser(target);
if (user == null)
return;
Request request = user.request();
if (request == null) { if (request == null) {
player.sendRichMessage(Config.NO_PENDING_REQUESTS); player.sendRichMessage(Config.NO_PENDING_REQUESTS);
return true; return;
} }
request.accept(); request.accept();
return true;
} }
@Override
public List<String> aliases() {
return List.of("tpyes", "tpaccpt");
}
} }
@@ -1,27 +1,60 @@
package com.alttd.essentia.commands.player; package com.alttd.essentia.commands.player;
import com.alttd.essentia.EssentiaPlugin; import com.alttd.essentia.EssentiaPlugin;
import com.alttd.essentia.commands.PlayerSubCommand; import com.alttd.essentia.commands.EssentiaCommand;
import com.alttd.essentia.configuration.Config; import com.alttd.essentia.configuration.Config;
import com.alttd.essentia.configuration.PlayerConfig; import com.alttd.essentia.api.request.Request;
import com.alttd.essentia.request.Request; import com.alttd.essentia.api.user.User;
import com.mojang.brigadier.builder.LiteralArgumentBuilder;
import com.mojang.brigadier.tree.LiteralCommandNode;
import io.papermc.paper.command.brigadier.CommandSourceStack;
import io.papermc.paper.command.brigadier.Commands;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
public class TeleportDenyCommand extends PlayerSubCommand { import java.util.List;
public TeleportDenyCommand(EssentiaPlugin plugin) { public class TeleportDenyCommand implements EssentiaCommand {
super(plugin, "teleportdeny");
@Override
public String commandName() {
return "teleportdeny";
} }
@Override @Override
protected boolean execute(Player player, PlayerConfig playerConfig, String... args) { public @NotNull LiteralCommandNode<CommandSourceStack> command() {
Request request = playerConfig.request(); final LiteralArgumentBuilder<CommandSourceStack> builder =
Commands.literal(commandName())
.requires(
commandSourceStack -> commandSourceStack.getSender().hasPermission(baseCommandPermission()) &&
commandSourceStack.getSender() instanceof Player
)
.executes((source) -> {
if (source.getSource().getSender() instanceof Player player)
execute(player, player);
return 1;
});
return builder.build();
}
public void execute(Player player, Player target) {
User user = EssentiaPlugin.instance().userManager().getUser(target);
if (user == null)
return;
Request request = user.request();
if (request == null) { if (request == null) {
player.sendRichMessage(Config.NO_PENDING_REQUESTS); player.sendRichMessage(Config.NO_PENDING_REQUESTS);
return true; return;
} }
request.deny(); request.deny();
return true;
} }
@Override
public List<String> aliases() {
return List.of("tpdeny", "tpno");
}
} }
@@ -1,72 +1,87 @@
package com.alttd.essentia.commands.player; package com.alttd.essentia.commands.player;
import com.alttd.essentia.EssentiaPlugin; import com.alttd.essentia.EssentiaPlugin;
import com.alttd.essentia.commands.PlayerSubCommand; import com.alttd.essentia.commands.EssentiaCommand;
import com.alttd.essentia.configuration.Config; import com.alttd.essentia.configuration.Config;
import com.alttd.essentia.configuration.PlayerConfig; import com.alttd.essentia.request.TeleportEssentiaRequest;
import com.alttd.essentia.request.TeleportRequest; import com.alttd.essentia.api.user.User;
import com.mojang.brigadier.builder.LiteralArgumentBuilder;
import com.mojang.brigadier.tree.LiteralCommandNode;
import io.papermc.paper.command.brigadier.CommandSourceStack;
import io.papermc.paper.command.brigadier.Commands;
import io.papermc.paper.command.brigadier.argument.ArgumentTypes;
import io.papermc.paper.command.brigadier.argument.resolvers.selector.PlayerSelectorArgumentResolver;
import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder; import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder;
import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver; import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver;
import org.bukkit.Bukkit;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import java.util.List; import java.util.List;
import java.util.stream.Collectors;
public class TeleportRequestCommand extends PlayerSubCommand { public class TeleportRequestCommand implements EssentiaCommand {
public TeleportRequestCommand(EssentiaPlugin plugin) { @Override
super(plugin, "teleportrequest"); public String commandName() {
return "teleportrequesthere";
} }
@Override @Override
protected boolean execute(Player player, PlayerConfig playerConfig, String... args) { public @NotNull LiteralCommandNode<CommandSourceStack> command() {
if (args.length < 1) { final LiteralArgumentBuilder<CommandSourceStack> builder =
player.sendRichMessage(Config.NO_PLAYER_SPECIFIED); Commands.literal(commandName())
return true; .requires(
} commandSourceStack -> commandSourceStack.getSender().hasPermission(baseCommandPermission()) &&
commandSourceStack.getSender() instanceof Player
)
.then(
Commands.argument("player", ArgumentTypes.player())
.requires(commandSourceStack -> commandSourceStack.getSender().hasPermission(baseOtherCommandPermission()))
.executes((source) -> {
if (!(source.getSource().getSender() instanceof Player player))
return 1;
Player target = Bukkit.getPlayer(args[0]); CommandSourceStack sourceStack = source.getSource();
Player target = source.getArgument("player", PlayerSelectorArgumentResolver.class).resolve(sourceStack).getFirst();
execute(player, target);
return 1;
})
);
return builder.build();
}
public void execute(Player player, Player target) {
if (target == null) { if (target == null) {
player.sendRichMessage(Config.PLAYER_NOT_ONLINE); player.sendRichMessage(Config.PLAYER_NOT_ONLINE);
return true; return;
} }
if (target == player) { if (target == player) {
player.sendRichMessage(Config.REQUEST_TO_SELF); player.sendRichMessage(Config.REQUEST_TO_SELF);
return true; return;
} }
TagResolver placeholders = TagResolver.resolver( TagResolver placeholders = TagResolver.resolver(
Placeholder.component("target", target.displayName()) Placeholder.component("target", target.displayName())
); );
PlayerConfig targetConfig = PlayerConfig.getConfig(target); User targetUser = EssentiaPlugin.instance().userManager().getUser(target);
if (targetConfig.request() != null) { if (targetUser.request() != null) {
player.sendRichMessage(Config.TARGET_HAS_PENDING_REQUEST, placeholders); player.sendRichMessage(Config.TARGET_HAS_PENDING_REQUEST, placeholders);
return true; return;
} }
if (!targetConfig.allowTeleports()) { if (!targetUser.getUserSettings().allowTeleports()) {
player.sendRichMessage(Config.TELEPORT_TOGGLED_OFF, placeholders); player.sendRichMessage(Config.TELEPORT_TOGGLED_OFF, placeholders);
return true; return;
} }
targetConfig.request(new TeleportRequest(plugin, player, target)); targetUser.request(new TeleportEssentiaRequest(EssentiaPlugin.instance(), player, target));
return true;
} }
@Override @Override
public List<String> onTabComplete(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, String[] args) { public List<String> aliases() {
if (args.length == 1) { return List.of("tpa");
String name = args[0].trim().toLowerCase();
return Bukkit.getOnlinePlayers().stream()
.map(Player::getName)
.filter(playerName -> playerName.toLowerCase().startsWith(name)).collect(Collectors.toList());
}
return null;
} }
} }
@@ -1,73 +1,87 @@
package com.alttd.essentia.commands.player; package com.alttd.essentia.commands.player;
import com.alttd.essentia.EssentiaPlugin; import com.alttd.essentia.EssentiaPlugin;
import com.alttd.essentia.commands.PlayerSubCommand; import com.alttd.essentia.commands.EssentiaCommand;
import com.alttd.essentia.configuration.Config; import com.alttd.essentia.configuration.Config;
import com.alttd.essentia.configuration.PlayerConfig; import com.alttd.essentia.api.user.User;
import com.alttd.essentia.request.TeleportHereRequest; import com.alttd.essentia.request.TeleportHereEssentiaRequest;
import com.alttd.essentia.request.TeleportRequest; import com.mojang.brigadier.builder.LiteralArgumentBuilder;
import com.mojang.brigadier.tree.LiteralCommandNode;
import io.papermc.paper.command.brigadier.CommandSourceStack;
import io.papermc.paper.command.brigadier.Commands;
import io.papermc.paper.command.brigadier.argument.ArgumentTypes;
import io.papermc.paper.command.brigadier.argument.resolvers.selector.PlayerSelectorArgumentResolver;
import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder; import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder;
import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver; import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver;
import org.bukkit.Bukkit;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import java.util.List; import java.util.List;
import java.util.stream.Collectors;
public class TeleportRequestHereCommand extends PlayerSubCommand { public class TeleportRequestHereCommand implements EssentiaCommand {
public TeleportRequestHereCommand(EssentiaPlugin plugin) { @Override
super(plugin, "teleportrequesthere"); public String commandName() {
return "teleportrequesthere";
} }
@Override @Override
protected boolean execute(Player player, PlayerConfig playerConfig, String... args) { public @NotNull LiteralCommandNode<CommandSourceStack> command() {
if (args.length < 1) { final LiteralArgumentBuilder<CommandSourceStack> builder =
player.sendRichMessage(Config.NO_PLAYER_SPECIFIED); Commands.literal(commandName())
return true; .requires(
} commandSourceStack -> commandSourceStack.getSender().hasPermission(baseCommandPermission()) &&
commandSourceStack.getSender() instanceof Player
)
.then(
Commands.argument("player", ArgumentTypes.player())
.requires(commandSourceStack -> commandSourceStack.getSender().hasPermission(baseOtherCommandPermission()))
.executes((source) -> {
if (!(source.getSource().getSender() instanceof Player player))
return 1;
Player target = Bukkit.getPlayer(args[0]); CommandSourceStack sourceStack = source.getSource();
Player target = source.getArgument("player", PlayerSelectorArgumentResolver.class).resolve(sourceStack).getFirst();
execute(player, target);
return 1;
})
);
return builder.build();
}
public void execute(Player player, Player target) {
if (target == null) { if (target == null) {
player.sendRichMessage(Config.PLAYER_NOT_ONLINE); player.sendRichMessage(Config.PLAYER_NOT_ONLINE);
return true; return;
} }
if (target == player) { if (target == player) {
player.sendRichMessage(Config.REQUEST_TO_SELF); player.sendRichMessage(Config.REQUEST_TO_SELF);
return true; return;
} }
TagResolver placeholders = TagResolver.resolver( TagResolver placeholders = TagResolver.resolver(
Placeholder.component("target", target.displayName()) Placeholder.component("target", target.displayName())
); );
PlayerConfig targetConfig = PlayerConfig.getConfig(target); User targetUser = EssentiaPlugin.instance().userManager().getUser(target);
if (targetConfig.request() != null) { if (targetUser.request() != null) {
player.sendRichMessage(Config.TARGET_HAS_PENDING_REQUEST, placeholders); player.sendRichMessage(Config.TARGET_HAS_PENDING_REQUEST, placeholders);
return true; return;
} }
if (!targetConfig.allowTeleports()) { if (!targetUser.getUserSettings().allowTeleports()) {
player.sendRichMessage(Config.TELEPORT_TOGGLED_OFF, placeholders); player.sendRichMessage(Config.TELEPORT_TOGGLED_OFF, placeholders);
return true; return;
} }
targetConfig.request(new TeleportHereRequest(plugin, player, target)); targetUser.request(new TeleportHereEssentiaRequest(EssentiaPlugin.instance(), player, target));
return true;
} }
@Override @Override
public List<String> onTabComplete(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, String[] args) { public List<String> aliases() {
if (args.length == 1) { return List.of("tpahere", "tphere");
String name = args[0].trim().toLowerCase();
return Bukkit.getOnlinePlayers().stream()
.map(Player::getName)
.filter(playerName -> playerName.toLowerCase().startsWith(name)).collect(Collectors.toList());
}
return null;
} }
} }
@@ -1,27 +1,73 @@
package com.alttd.essentia.commands.player; package com.alttd.essentia.commands.player;
import com.alttd.essentia.EssentiaPlugin; import com.alttd.essentia.EssentiaPlugin;
import com.alttd.essentia.commands.PlayerSubCommand; import com.alttd.essentia.commands.EssentiaCommand;
import com.alttd.essentia.configuration.Config; import com.alttd.essentia.configuration.Config;
import com.alttd.essentia.configuration.PlayerConfig; import com.alttd.essentia.api.user.User;
import com.mojang.brigadier.builder.LiteralArgumentBuilder;
import com.mojang.brigadier.tree.LiteralCommandNode;
import io.papermc.paper.command.brigadier.CommandSourceStack;
import io.papermc.paper.command.brigadier.Commands;
import io.papermc.paper.command.brigadier.argument.ArgumentTypes;
import io.papermc.paper.command.brigadier.argument.resolvers.selector.PlayerSelectorArgumentResolver;
import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder; import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder;
import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver; import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver;
import org.apache.commons.lang3.BooleanUtils; import org.apache.commons.lang3.BooleanUtils;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
public class TeleportToggleCommand extends PlayerSubCommand { import java.util.List;
public TeleportToggleCommand(EssentiaPlugin plugin) { public class TeleportToggleCommand implements EssentiaCommand {
super(plugin, "teleporttoggle");
@Override
public String commandName() {
return "teleporttoggle";
} }
@Override @Override
protected boolean execute(Player player, PlayerConfig playerConfig, String... args) { public @NotNull LiteralCommandNode<CommandSourceStack> command() {
playerConfig.setAllowTeleports(!playerConfig.allowTeleports()); final LiteralArgumentBuilder<CommandSourceStack> builder =
TagResolver placeholders = TagResolver.resolver( Commands.literal(commandName())
Placeholder.parsed("toggle", BooleanUtils.toStringOnOff(playerConfig.allowTeleports())) .requires(
); commandSourceStack -> commandSourceStack.getSender().hasPermission(baseCommandPermission())
player.sendRichMessage(Config.TELEPORT_TOGGLE_SET, placeholders); )
return true; .executes((source) -> {
if (source.getSource().getSender() instanceof Player player)
execute(player, player);
return 1;
})
.then(
Commands.argument("player", ArgumentTypes.player())
.requires(commandSourceStack -> commandSourceStack.getSender().hasPermission(baseOtherCommandPermission()))
.executes((source) -> {
CommandSourceStack sourceStack = source.getSource();
Player target = source.getArgument("player", PlayerSelectorArgumentResolver.class).resolve(sourceStack).getFirst();
execute(source.getSource().getSender(), target);
return 1;
})
);
return builder.build();
} }
public void execute(CommandSender sender, Player target) {
User user = EssentiaPlugin.instance().userManager().getUser(target);
if (user == null)
return;
user.getUserSettings().allowTeleports(!user.getUserSettings().allowTeleports());
TagResolver placeholders = TagResolver.resolver(
Placeholder.parsed("toggle", BooleanUtils.toStringOnOff(user.getUserSettings().allowTeleports()))
);
sender.sendRichMessage(Config.TELEPORT_TOGGLE_SET, placeholders);
}
@Override
public List<String> aliases() {
return List.of("tptoggle");
}
} }
@@ -2,7 +2,6 @@ package com.alttd.essentia.configuration;
import com.alttd.essentia.EssentiaPlugin; import com.alttd.essentia.EssentiaPlugin;
import com.google.common.base.Throwables; import com.google.common.base.Throwables;
import org.bukkit.Bukkit;
import org.bukkit.Sound; import org.bukkit.Sound;
import org.bukkit.configuration.InvalidConfigurationException; import org.bukkit.configuration.InvalidConfigurationException;
import org.bukkit.configuration.file.YamlConfiguration; import org.bukkit.configuration.file.YamlConfiguration;
@@ -35,7 +34,7 @@ public class Config {
config.load(CONFIG_FILE); config.load(CONFIG_FILE);
} catch (IOException ignore) { } catch (IOException ignore) {
} catch (InvalidConfigurationException ex) { } catch (InvalidConfigurationException ex) {
Bukkit.getLogger().log(Level.SEVERE, "Could not load config.yml, please correct your syntax errors", ex); EssentiaPlugin.instance().getLogger().log(Level.SEVERE, "Could not load config.yml, please correct your syntax errors", ex);
Throwables.throwIfUnchecked(ex); Throwables.throwIfUnchecked(ex);
} }
config.options().header(HEADER); config.options().header(HEADER);
@@ -44,6 +43,7 @@ public class Config {
version = getInt("config-version", 1); version = getInt("config-version", 1);
set("config-version", 1); set("config-version", 1);
EssentiaPlugin.instance().getLogger().info("Essentia Configuration loaded!");
readConfig(Config.class, null); readConfig(Config.class, null);
} }
@@ -57,7 +57,7 @@ public class Config {
} catch (InvocationTargetException ex) { } catch (InvocationTargetException ex) {
Throwables.throwIfUnchecked(ex); Throwables.throwIfUnchecked(ex);
} catch (Exception ex) { } catch (Exception ex) {
Bukkit.getLogger().log(Level.SEVERE, "Error invoking " + method, ex); EssentiaPlugin.instance().getLogger().log(Level.SEVERE, "Error invoking " + method, ex);
} }
} }
} }
@@ -65,11 +65,11 @@ public class Config {
saveConfig(); saveConfig();
} }
static void saveConfig() { public static void saveConfig() {
try { try {
config.save(CONFIG_FILE); config.save(CONFIG_FILE);
} catch (IOException ex) { } catch (IOException ex) {
Bukkit.getLogger().log(Level.SEVERE, "Could not save " + CONFIG_FILE, ex); EssentiaPlugin.instance().getLogger().log(Level.SEVERE, "Could not save " + CONFIG_FILE, ex);
} }
} }
@@ -104,7 +104,7 @@ public class Config {
} }
protected static void log(Level level, String s) { protected static void log(Level level, String s) {
Bukkit.getLogger().log(level, s); EssentiaPlugin.instance().getLogger().log(level, s);
} }
public static int TELEPORT_REQUEST_TIMEOUT = 30; public static int TELEPORT_REQUEST_TIMEOUT = 30;
@@ -171,6 +171,9 @@ public class Config {
public static String TOGGLED_FLIGHT_BY_OTHER = "Toggled flight <status> on <target>."; public static String TOGGLED_FLIGHT_BY_OTHER = "Toggled flight <status> on <target>.";
public static String TOGGLED_FLIGHT_PLAYER = "<player> toggled flight <status>."; public static String TOGGLED_FLIGHT_PLAYER = "<player> toggled flight <status>.";
public static String TOGGLED_FLIGHT = "Toggled fly <status>."; public static String TOGGLED_FLIGHT = "Toggled fly <status>.";
public static String TOGGLED_GOD_BY_OTHER = "Toggled God mode <status> on <target>.";
public static String TOGGLED_GOD_PLAYER = "<player> toggled God mode <status>.";
public static String TOGGLED_GOD = "Toggled God mode <status>.";
public static String NO_BACK_LOCATION = "No back location found!"; public static String NO_BACK_LOCATION = "No back location found!";
public static String TELEPORTING_BACK = "Teleporting back to previous location."; public static String TELEPORTING_BACK = "Teleporting back to previous location.";
public static String NO_DEATH_LOCATION = "No death location found!"; public static String NO_DEATH_LOCATION = "No death location found!";
@@ -187,6 +190,14 @@ public class Config {
public static String FEED_SELF = "You just fed yourself."; public static String FEED_SELF = "You just fed yourself.";
public static String FEED_OTHER = "You have fed <target>."; public static String FEED_OTHER = "You have fed <target>.";
public static String FEED_BY_OTHER = "<requester> has fed you."; public static String FEED_BY_OTHER = "<requester> has fed you.";
public static String BURN_SELF = "You have set yourself on fire.";
public static String BURN_OTHER = "<target>'s has been set in fire.";
public static String BURN_BY_OTHER = "<requester> has set you on fire.";
public static String SMITE_SELF = "You have smited yourself.";
public static String SMITE_OTHER = "<target> has been smited.";
public static String SMITE_BY_OTHER = "<requester> has smited you.";
private static void messages() { private static void messages() {
REQUEST_TIMED_OUT = getString("messages.request.time-out", REQUEST_TIMED_OUT); REQUEST_TIMED_OUT = getString("messages.request.time-out", REQUEST_TIMED_OUT);
TELEPORT_ACCEPT_TARGET = getString("messages.request.teleport-accept-target", TELEPORT_ACCEPT_TARGET); TELEPORT_ACCEPT_TARGET = getString("messages.request.teleport-accept-target", TELEPORT_ACCEPT_TARGET);
@@ -203,39 +214,60 @@ public class Config {
PLAYER_ONLY_COMMAND = getString("messages.command.player-only-command", PLAYER_ONLY_COMMAND); PLAYER_ONLY_COMMAND = getString("messages.command.player-only-command", PLAYER_ONLY_COMMAND);
NO_PLAYER_SPECIFIED = getString("messages.command.no-player-specified", NO_PLAYER_SPECIFIED); NO_PLAYER_SPECIFIED = getString("messages.command.no-player-specified", NO_PLAYER_SPECIFIED);
PLAYER_NOT_FOUND = config.getString("messages.command.player-not-found", PLAYER_NOT_FOUND); PLAYER_NOT_FOUND = getString("messages.command.player-not-found", PLAYER_NOT_FOUND);
PLAYER_NOT_ONLINE = config.getString("messages.command.player-not-online", PLAYER_NOT_ONLINE); PLAYER_NOT_ONLINE = getString("messages.command.player-not-online", PLAYER_NOT_ONLINE);
COMMAND_NO_PERMISSION = config.getString("messages.command.no-permission", COMMAND_NO_PERMISSION); COMMAND_NO_PERMISSION = getString("messages.command.no-permission", COMMAND_NO_PERMISSION);
PLAYER_INVENTORY_CLEARED = config.getString("messages.command.clear-inventory.player-inventory-cleared", PLAYER_INVENTORY_CLEARED); PLAYER_INVENTORY_CLEARED = getString("messages.command.clear-inventory.player-inventory-cleared", PLAYER_INVENTORY_CLEARED);
INVENTORY_CLEARED_BY_OTHER = config.getString("messages.command.clear-inventory.inventory-clear-by-other", INVENTORY_CLEARED_BY_OTHER); INVENTORY_CLEARED_BY_OTHER = getString("messages.command.clear-inventory.inventory-clear-by-other", INVENTORY_CLEARED_BY_OTHER);
INVENTORY_CLEARED = config.getString("messages.command.clear-inventory.inventory-cleared", INVENTORY_CLEARED); INVENTORY_CLEARED = getString("messages.command.clear-inventory.inventory-cleared", INVENTORY_CLEARED);
SPECIFY_HOME = config.getString("messages.command.home.specify-home", SPECIFY_HOME); SPECIFY_HOME = getString("messages.command.home.specify-home", SPECIFY_HOME);
HOME_NOT_SET = config.getString("messages.command.home.home-not-set", HOME_NOT_SET); HOME_NOT_SET = getString("messages.command.home.home-not-set", HOME_NOT_SET);
HOME_DOES_NOT_EXIST = config.getString("messages.command.home.home-does-not-exist", HOME_DOES_NOT_EXIST); HOME_DOES_NOT_EXIST = getString("messages.command.home.home-does-not-exist", HOME_DOES_NOT_EXIST);
HOME_TELEPORT = config.getString("messages.command.home.home-teleport", HOME_TELEPORT); HOME_TELEPORT = getString("messages.command.home.home-teleport", HOME_TELEPORT);
HOME_LIST = config.getString("messages.command.home.home-list", HOME_LIST); HOME_LIST = getString("messages.command.home.home-list", HOME_LIST);
HOME_SET = config.getString("messages.command.home.home-set", HOME_SET); HOME_SET = getString("messages.command.home.home-set", HOME_SET);
HOME_SET_MAX = config.getString("messages.command.home.home-set-max", HOME_SET_MAX); HOME_SET_MAX = getString("messages.command.home.home-set-max", HOME_SET_MAX);
INVALID_HOME_NAME = config.getString("messages.command.home.invalid-home-name", INVALID_HOME_NAME); INVALID_HOME_NAME = getString("messages.command.home.invalid-home-name", INVALID_HOME_NAME);
HOME_DELETED = config.getString("messages.command.home.invalid-home-name", HOME_DELETED); HOME_DELETED = getString("messages.command.home.invalid-home-name", HOME_DELETED);
TOGGLED_FLIGHT_BY_OTHER = config.getString("messages.command.fly.toggled-by-other", TOGGLED_FLIGHT_BY_OTHER); TOGGLED_FLIGHT_BY_OTHER = getString("messages.command.fly.toggled-by-other", TOGGLED_FLIGHT_BY_OTHER);
TOGGLED_FLIGHT_PLAYER = config.getString("messages.command.fly.toggled-flight-other", TOGGLED_FLIGHT_PLAYER); TOGGLED_FLIGHT_PLAYER = getString("messages.command.fly.toggled-flight-other", TOGGLED_FLIGHT_PLAYER);
TOGGLED_FLIGHT = config.getString("messages.command.fly.toggled-flight", TOGGLED_FLIGHT); TOGGLED_FLIGHT = getString("messages.command.fly.toggled-flight", TOGGLED_FLIGHT);
NO_BACK_LOCATION = config.getString("messages.command.back.no-back-location", NO_BACK_LOCATION); NO_BACK_LOCATION = getString("messages.command.back.no-back-location", NO_BACK_LOCATION);
TELEPORTING_BACK = config.getString("messages.command.back.teleporting-back", TELEPORTING_BACK); TELEPORTING_BACK = getString("messages.command.back.teleporting-back", TELEPORTING_BACK);
NO_DEATH_LOCATION = config.getString("messages.command.back.no-death-location", NO_DEATH_LOCATION); NO_DEATH_LOCATION = getString("messages.command.back.no-death-location", NO_DEATH_LOCATION);
TELEPORTING_BACK_DEATH = config.getString("messages.command.back.teleporting-back-death", TELEPORTING_BACK_DEATH); TELEPORTING_BACK_DEATH = getString("messages.command.back.teleporting-back-death", TELEPORTING_BACK_DEATH);
BACK_DEATH_HINT = config.getString("messages.command.back.dback-hint", BACK_DEATH_HINT); BACK_DEATH_HINT = getString("messages.command.back.dback-hint", BACK_DEATH_HINT);
GAMEMODE_SET = config.getString("messages.command.gamemode.gamemode-set", GAMEMODE_SET); GAMEMODE_SET = getString("messages.command.gamemode.gamemode-set", GAMEMODE_SET);
GAMEMODE_SET_OTHER = config.getString("messages.command.gamemode.gamemode-set-other", GAMEMODE_SET_OTHER); GAMEMODE_SET_OTHER = getString("messages.command.gamemode.gamemode-set-other", GAMEMODE_SET_OTHER);
GAMEMODE_SET_BY_OTHER = config.getString("messages.command.gamemode.gamemode-set-by-other", GAMEMODE_SET_BY_OTHER); GAMEMODE_SET_BY_OTHER = getString("messages.command.gamemode.gamemode-set-by-other", GAMEMODE_SET_BY_OTHER);
HEAL_SELF = config.getString("messages.command.heal.heal-self", HEAL_SELF); HEAL_SELF = getString("messages.command.heal.heal-self", HEAL_SELF);
HEAL_OTHER = config.getString("messages.command.heal.heal-other", HEAL_OTHER); HEAL_OTHER = getString("messages.command.heal.heal-other", HEAL_OTHER);
HEAL_BY_OTHER = config.getString("messages.command.heal.heal-by-other", HEAL_BY_OTHER); HEAL_BY_OTHER = getString("messages.command.heal.heal-by-other", HEAL_BY_OTHER);
FEED_SELF = config.getString("messages.command.feed.feed-self", FEED_SELF); FEED_SELF = getString("messages.command.feed.feed-self", FEED_SELF);
FEED_OTHER = config.getString("messages.command.feed.feed-other", FEED_OTHER); FEED_OTHER = getString("messages.command.feed.feed-other", FEED_OTHER);
FEED_BY_OTHER = config.getString("messages.command.feed.feed-by-other", FEED_BY_OTHER); FEED_BY_OTHER = getString("messages.command.feed.feed-by-other", FEED_BY_OTHER);
}
public static String STORAGE_TYPE = "YAML";
public static boolean AUTO_SAVE = true;
public static int AUTO_SAVE_DELAY = 60;
public static String MYSQL_IP = "localhost";
public static String MYSQL_PORT = "3306";
public static String MYSQL_DATABASE_NAME = "essentia";
public static String MYSQL_USERNAME = "root";
public static String MYSQL_PASSWORD = "root";
public static int MYSQL_CONNECTIONS = 10;
public static int MYSQL_QUEUE_DELAY = 5;
private static void storage() {
STORAGE_TYPE = getString("storage.type", STORAGE_TYPE);
AUTO_SAVE = getBoolean("storage.auto-save", AUTO_SAVE);
AUTO_SAVE_DELAY = getInt("storaeg.auto-save-delay", AUTO_SAVE_DELAY);
MYSQL_IP = getString("storage.mysql.ip", MYSQL_IP);
MYSQL_PORT = getString("storage.mysql.port", MYSQL_PORT);
MYSQL_DATABASE_NAME = getString("storage.mysql.database", MYSQL_DATABASE_NAME);
MYSQL_USERNAME = getString("storage.mysql.username", MYSQL_USERNAME);
MYSQL_PASSWORD = getString("storage.mysql.password", MYSQL_PASSWORD);
} }
} }
@@ -1,186 +0,0 @@
package com.alttd.essentia.configuration;
import com.alttd.essentia.EssentiaPlugin;
import com.alttd.essentia.request.Request;
import lombok.Getter;
import lombok.Setter;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.OfflinePlayer;
import org.bukkit.World;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.entity.Player;
import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
public class PlayerConfig extends YamlConfiguration {
private static final Map<Player, PlayerConfig> configs = new HashMap<>();
public static PlayerConfig getConfig(Player player) {
synchronized (configs) {
return configs.computeIfAbsent(player, k -> new PlayerConfig(player));
}
}
public static void remove(Player player) {
synchronized (configs) {
configs.remove(player);
}
}
public static void removeAll() {
synchronized (configs) {
configs.clear();
}
}
private final File file;
private final Object saveLock = new Object();
private final OfflinePlayer player;
@Getter @Setter private Request request;
private PlayerConfig(Player player) {
super();
this.player = player;
this.file = new File(EssentiaPlugin.instance().getDataFolder(), "PlayerData" + File.separator + player.getUniqueId() + ".yml");
reload();
}
private void reload() {
synchronized (saveLock) {
try {
load(file);
} catch (Exception ignore) {
}
}
}
private void save() {
synchronized (saveLock) {
try {
save(file);
} catch (Exception ignore) {
}
}
}
Location getStoredLocation(String path) {
if (get(path) == null) {
return null;
}
World world = Bukkit.getWorld(getString(path + ".world", ""));
if (world == null) {
return null;
}
double x = getDouble(path + ".x");
double y = getDouble(path + ".y");
double z = getDouble(path + ".z");
float pitch = (float) getDouble(path + ".pitch");
float yaw = (float) getDouble(path + ".yaw");
return new Location(world, x, y, z, yaw, pitch);
}
void setStoredLocation(String path, Location location) {
if (location == null) {
set(path, null);
save();
return;
}
set(path + ".world", location.getWorld().getName());
set(path + ".x", location.getX());
set(path + ".y", location.getY());
set(path + ".z", location.getZ());
set(path + ".pitch", location.getPitch());
set(path + ".yaw", location.getYaw());
save();
}
public Location getBackLocation(boolean death) {
return getStoredLocation(death ? "teleports.death" : "teleports.back");
}
public void setBackLocation(boolean death, Location location) {
setStoredLocation(death ? "teleports.death" : "teleports.back", location);
}
public boolean hasHome(String name) {
ConfigurationSection section = getConfigurationSection("home." + name);
return section != null;
}
public Location getHome(String name) {
return getStoredLocation("home." + name);
}
public void setHome(String name, Location location) {
setStoredLocation("home." + name, location);
}
public int getHomeCount() {
ConfigurationSection section = getConfigurationSection("home");
if (section == null) {
return 0;
}
return section.getKeys(false).size();
}
public List<String> getMatchingHomeNames(String name) {
ConfigurationSection section = getConfigurationSection("home");
if (section == null) {
return null;
}
List<String> list = section.getValues(false).keySet().stream()
.filter(home -> home.toLowerCase().startsWith(name.toLowerCase()))
.collect(Collectors.toList());
if (player.getBedSpawnLocation() != null && "bed".startsWith(name.toLowerCase()))
list.add("bed");
return list;
}
public Map<String, Location> getHomeData() {
ConfigurationSection section = getConfigurationSection("home");
if (section == null) {
return null;
}
Map<String, Location> map = new HashMap<>();
for (String key : section.getValues(false).keySet()) {
map.put(key, getHome(key));
}
if (player.getBedSpawnLocation() != null)
map.put("bed", player.getBedSpawnLocation());
return map;
}
public List<String> getHomeList() {
ConfigurationSection section = getConfigurationSection("home");
if (section == null) {
return null;
}
List<String> list = new ArrayList<>(section.getValues(false).keySet());
if (player.getBedSpawnLocation() != null)
list.add("bed");
return list;
}
public boolean allowTeleports() {
return getBoolean("allow-teleports", true);
}
public void setAllowTeleports(boolean allowTeleports) {
set("allow-teleports", allowTeleports);
save();
}
}
@@ -0,0 +1,130 @@
package com.alttd.essentia.listeners;
import com.alttd.essentia.EssentiaPlugin;
import com.alttd.essentia.api.user.User;
import com.alttd.essentia.api.user.UserManager;
import io.papermc.paper.event.player.AsyncChatEvent;
import org.bukkit.Location;
import org.bukkit.entity.Player;
import org.bukkit.event.Cancellable;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.entity.EntityDamageByEntityEvent;
import org.bukkit.event.entity.EntityDamageEvent;
import org.bukkit.event.entity.ProjectileLaunchEvent;
import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.event.player.*;
public class CuffListener implements Listener {
private final EssentiaPlugin plugin;
public CuffListener() {
this.plugin = EssentiaPlugin.instance();
}
private boolean isNotCuffed(Player player) {
UserManager userManager = plugin.userManager();
User user = userManager.getUser(player);
if (user == null)
return true;
return !user.isCuffed();
}
@EventHandler
public void onPlayerInteract(PlayerInteractEvent event) {
if (isNotCuffed(event.getPlayer()))
return;
cancelEvent(event, event.getPlayer());
}
@EventHandler
public void onAsyncPlayerChat(AsyncChatEvent event) {
if (isNotCuffed(event.getPlayer()))
return;
// TODO
// if (!Config.TALKWHILECUFFED)
// return;
cancelEvent(event, event.getPlayer());
}
@EventHandler
public void onInventoryClick(InventoryClickEvent event) {
if (!(event.getWhoClicked() instanceof Player player))
return;
if (isNotCuffed(player))
return;
cancelEvent(event, player);
}
@EventHandler
public void onPlayerDropItemEvent(PlayerDropItemEvent event) {
if (isNotCuffed(event.getPlayer()))
return;
cancelEvent(event, event.getPlayer());
}
@EventHandler
public void onProjectileLaunchEvent(ProjectileLaunchEvent event) {
if (!(event.getEntity().getShooter() instanceof Player player))
return;
if (isNotCuffed(player))
return;
cancelEvent(event, player);
}
@EventHandler
public void onnEntityDamageByEntity(EntityDamageByEntityEvent event) {
if (!(event.getDamager() instanceof Player player))
return;
if (isNotCuffed(player))
return;
cancelEvent(event, player);
}
@EventHandler
public void onEntityDamage(EntityDamageEvent event) {
if (!(event.getEntity() instanceof Player player))
return;
if (isNotCuffed(player))
return;
cancelEvent(event, player);
}
@EventHandler
public void onPlayerMove(PlayerMoveEvent event) {
Player player = event.getPlayer();
if (isNotCuffed(player))
return;
Location from = event.getFrom();
Location to = event.getTo();
if (from.getBlockY() < to.getBlockY() && player.isFlying()) {
cancelEvent(event, player);
return;
}
if (from.getWorld() != to.getWorld() || from.getBlockX() != to.getBlockX() || from.getBlockZ() != to.getBlockZ()) {
cancelEvent(event, player);
}
}
void cancelEvent(Cancellable event, Player player) {
event.setCancelled(true);
player.sendRichMessage("You can not do this while cuffed."); // TODO - config
}
}
@@ -0,0 +1,33 @@
package com.alttd.essentia.listeners;
import com.alttd.essentia.EssentiaPlugin;
import com.alttd.essentia.api.model.UserSettings;
import com.alttd.essentia.api.user.User;
import com.alttd.essentia.api.user.UserManager;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerChangedWorldEvent;
public class FlightListener implements Listener {
private final EssentiaPlugin plugin;
public FlightListener() {
this.plugin = EssentiaPlugin.instance();
}
@EventHandler
public void onPlayerChangedWorld(PlayerChangedWorldEvent event) {
Player player = event.getPlayer();
UserManager userManager = plugin.userManager();
User user = userManager.getUser(player);
if (user == null)
return;
UserSettings userSettings = user.getUserSettings();
if (userSettings.flying())
player.setFlying(true);
}
}
@@ -0,0 +1,67 @@
package com.alttd.essentia.listeners;
import com.alttd.essentia.EssentiaPlugin;
import com.alttd.essentia.api.model.UserSettings;
import com.alttd.essentia.api.user.User;
import com.alttd.essentia.api.user.UserManager;
import com.destroystokyo.paper.event.entity.PhantomPreSpawnEvent;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.entity.EntityTargetLivingEntityEvent;
import org.bukkit.event.entity.FoodLevelChangeEvent;
public class GodModeListener implements Listener {
private final EssentiaPlugin plugin;
public GodModeListener() {
this.plugin = EssentiaPlugin.instance();
}
@EventHandler
public void onFoodLevelChange(FoodLevelChangeEvent event) {
if (!(event.getEntity() instanceof Player player))
return;
if (!hasGodMode(player))
return;
event.setCancelled(true);
}
@EventHandler
public void onPhantomPreSpawn(PhantomPreSpawnEvent event) {
if (!(event.getSpawningEntity() instanceof Player player))
return;
if (!hasGodMode(player))
return;
event.setCancelled(true);
event.setShouldAbortSpawn(true);
}
@EventHandler
public void onEntityTargetLivingEntity(EntityTargetLivingEntityEvent event) {
if (!(event.getEntity() instanceof Player player))
return;
if (!hasGodMode(player))
return;
event.setCancelled(true);
}
private boolean hasGodMode(Player player) {
UserManager userManager = plugin.userManager();
User user = userManager.getUser(player);
if (user == null)
return false;
UserSettings userSettings = user.getUserSettings();
return userSettings.godMode();
}
}
@@ -2,12 +2,16 @@ package com.alttd.essentia.listeners;
import com.alttd.essentia.EssentiaPlugin; import com.alttd.essentia.EssentiaPlugin;
import com.alttd.essentia.configuration.Config; import com.alttd.essentia.configuration.Config;
import com.alttd.essentia.configuration.PlayerConfig; import com.alttd.essentia.user.EssentiaUser;
import com.alttd.essentia.api.user.User;
import com.alttd.essentia.api.user.UserManager;
import org.bukkit.Location; import org.bukkit.Location;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler; import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener; import org.bukkit.event.Listener;
import org.bukkit.event.entity.PlayerDeathEvent; import org.bukkit.event.entity.PlayerDeathEvent;
import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.event.player.PlayerQuitEvent;
import org.bukkit.event.player.PlayerTeleportEvent; import org.bukkit.event.player.PlayerTeleportEvent;
import java.util.HashSet; import java.util.HashSet;
@@ -15,11 +19,11 @@ import java.util.Set;
public class PlayerListener implements Listener { public class PlayerListener implements Listener {
private EssentiaPlugin plugin; private final EssentiaPlugin plugin;
private final Set<PlayerTeleportEvent.TeleportCause> backAllowCauses = new HashSet<>(); private final Set<PlayerTeleportEvent.TeleportCause> backAllowCauses = new HashSet<>();
public PlayerListener(EssentiaPlugin plugin) { public PlayerListener() {
this.plugin = plugin; this.plugin = EssentiaPlugin.instance();
backAllowCauses.add(PlayerTeleportEvent.TeleportCause.PLUGIN); backAllowCauses.add(PlayerTeleportEvent.TeleportCause.PLUGIN);
backAllowCauses.add(PlayerTeleportEvent.TeleportCause.COMMAND); backAllowCauses.add(PlayerTeleportEvent.TeleportCause.COMMAND);
@@ -36,8 +40,8 @@ public class PlayerListener implements Listener {
return; return;
} }
PlayerConfig playerConfig = PlayerConfig.getConfig(player); User user = plugin.userManager().getUser(player);
playerConfig.setBackLocation(true, player.getLocation()); user.setBackLocation(true, player.getLocation());
player.sendRichMessage(Config.BACK_DEATH_HINT); player.sendRichMessage(Config.BACK_DEATH_HINT);
} }
@@ -57,7 +61,33 @@ public class PlayerListener implements Listener {
// only save location if teleporting more than 5 blocks // only save location if teleporting more than 5 blocks
if (!to.getWorld().equals(from.getWorld()) || to.distanceSquared(from) > 25) { if (!to.getWorld().equals(from.getWorld()) || to.distanceSquared(from) > 25) {
PlayerConfig.getConfig(player).setBackLocation(false, event.getFrom()); User user = plugin.userManager().getUser(player);
user.setBackLocation(false, event.getFrom());
} }
} }
@EventHandler
public void onPlayerJoin(PlayerJoinEvent event) {
Player player = event.getPlayer();
if (plugin.userManager().hasUser(player.getUniqueId()))
return;
plugin.storageProvider().loadUser(player.getUniqueId());
}
@EventHandler
public void onPlayerQuit(PlayerQuitEvent event) {
Player player = event.getPlayer();
UserManager userManager = plugin.userManager();
if (!userManager.hasUser(player.getUniqueId())) {
return;
}
User user = userManager.getUser(player);
try {
if (user instanceof EssentiaUser essentiaUser)
plugin.storageProvider().save(essentiaUser);
userManager.removeUser(player.getUniqueId());
} catch (Exception ignored) {}
}
} }
@@ -0,0 +1,5 @@
package com.alttd.essentia.model;
import org.bukkit.Location;
public record EssentiaHome(String name, Location location) implements com.alttd.essentia.api.model.Home {}
@@ -0,0 +1,98 @@
package com.alttd.essentia.model;
import com.alttd.essentia.api.model.UserSettings;
import lombok.Getter;
@Getter
public class EssentiaUserSettings implements UserSettings {
boolean godMode;
boolean flying;
double flySpeed;
double walkSpeed;
boolean pTime;
boolean pWeather;
boolean allowTeleports;
private boolean needsSaving;
private EssentiaUserSettings(Builder builder) {
this.godMode = builder.godMode;
this.flying = builder.flying;
this.flySpeed = builder.flySpeed;
this.walkSpeed = builder.walkSpeed;
this.pTime = builder.pTime;
this.pWeather = builder.pWeather;
this.allowTeleports = builder.allowTeleports;
}
@Override
public void godMode(boolean godMode) {
this.godMode = godMode;
this.needsSaving = true;
}
@Override
public void allowTeleports(boolean allowTeleports) {
this.allowTeleports = allowTeleports;
this.needsSaving = true;
}
@Override
public void flying(boolean flying) {
this.flying = flying;
this.needsSaving = true;
}
public static class Builder {
// TODO - defaults?
protected boolean godMode;
protected boolean flying;
protected double flySpeed;
protected double walkSpeed;
protected boolean pTime;
protected boolean pWeather;
protected boolean allowTeleports;
public Builder godMode(boolean godMode) {
this.godMode = godMode;
return this;
}
public Builder flying(boolean flying) {
this.flying = flying;
return this;
}
public Builder flySpeed(double flySpeed) {
this.flySpeed = flySpeed;
return this;
}
public Builder walkSpeed(double walkSpeed) {
this.walkSpeed = walkSpeed;
return this;
}
public Builder pTime(boolean pTime) {
this.pTime = pTime;
return this;
}
public Builder pWeather(boolean pWeather) {
this.pWeather = pWeather;
return this;
}
public Builder allowTeleports(boolean allowTeleports) {
this.allowTeleports = allowTeleports;
return this;
}
public EssentiaUserSettings build() {
return new EssentiaUserSettings(this);
}
}
}
@@ -0,0 +1,3 @@
package com.alttd.essentia.model;
public record Kit() {}
@@ -0,0 +1,4 @@
package com.alttd.essentia.model;
public record PlayerInventory() {
}
@@ -1,8 +1,8 @@
package com.alttd.essentia.request; package com.alttd.essentia.request;
import com.alttd.essentia.EssentiaPlugin; import com.alttd.essentia.EssentiaPlugin;
import com.alttd.essentia.api.request.Request;
import com.alttd.essentia.configuration.Config; import com.alttd.essentia.configuration.Config;
import com.alttd.essentia.configuration.PlayerConfig;
import com.alttd.essentia.tasks.RequestTimeout; import com.alttd.essentia.tasks.RequestTimeout;
import com.alttd.essentia.tasks.TeleportSounds; import com.alttd.essentia.tasks.TeleportSounds;
import lombok.Getter; import lombok.Getter;
@@ -10,7 +10,7 @@ import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder;
import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver; import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
public abstract class Request { public abstract class EssentiaRequest implements Request {
private final EssentiaPlugin plugin; private final EssentiaPlugin plugin;
@Getter private final Player requester; @Getter private final Player requester;
@@ -19,7 +19,7 @@ public abstract class Request {
TagResolver placeholders; TagResolver placeholders;
public Request(EssentiaPlugin plugin, Player requester, Player target) { public EssentiaRequest(EssentiaPlugin plugin, Player requester, Player target) {
this.plugin = plugin; this.plugin = plugin;
this.requester = requester; this.requester = requester;
this.target = target; this.target = target;
@@ -65,7 +65,7 @@ public abstract class Request {
public void cancel() { public void cancel() {
try { try {
timeoutTask.cancel(); timeoutTask.cancel();
PlayerConfig.getConfig(target).request(null); plugin.userManager().getUser(target).request(null);
} catch (IllegalStateException ignore) { } catch (IllegalStateException ignore) {
} }
} }
@@ -4,9 +4,9 @@ import com.alttd.essentia.EssentiaPlugin;
import com.alttd.essentia.configuration.Config; import com.alttd.essentia.configuration.Config;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
public class TeleportRequest extends Request { public class TeleportEssentiaRequest extends EssentiaRequest {
public TeleportRequest(EssentiaPlugin plugin, Player requester, Player target) { public TeleportEssentiaRequest(EssentiaPlugin plugin, Player requester, Player target) {
super(plugin, requester, target); super(plugin, requester, target);
target.sendRichMessage(Config.TELEPORT_REQUESTHERE_TARGET, placeholders); target.sendRichMessage(Config.TELEPORT_REQUESTHERE_TARGET, placeholders);
@@ -4,9 +4,9 @@ import com.alttd.essentia.EssentiaPlugin;
import com.alttd.essentia.configuration.Config; import com.alttd.essentia.configuration.Config;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
public class TeleportHereRequest extends Request { public class TeleportHereEssentiaRequest extends EssentiaRequest {
public TeleportHereRequest(EssentiaPlugin plugin, Player requester, Player target) { public TeleportHereEssentiaRequest(EssentiaPlugin plugin, Player requester, Player target) {
super(plugin, requester, target); super(plugin, requester, target);
target.sendRichMessage(Config.TELEPORT_REQUEST_TARGET, placeholders); target.sendRichMessage(Config.TELEPORT_REQUEST_TARGET, placeholders);
@@ -0,0 +1,25 @@
package com.alttd.essentia.storage;
import com.alttd.essentia.EssentiaPlugin;
import com.alttd.essentia.storage.yaml.YamlStorageProvider;
import java.io.File;
public class StorageManager {
protected final EssentiaPlugin plugin;
public StorageManager(EssentiaPlugin plugin) {
this.plugin = plugin;
}
public StorageProvider storageProvider(StorageType type) {
return switch (type) {
// case MYSQL -> new SQLStorageProvider(plugin); // FIXME
case YAML -> new YamlStorageProvider(plugin, plugin.getDataFolder().getPath() + File.separator + "PlayerData");
// case SQLITE -> new SQLiteStorageProvider(plugin); // FIXME
default -> throw new UnsupportedOperationException();
};
}
}
@@ -0,0 +1,75 @@
package com.alttd.essentia.storage;
import com.alttd.essentia.EssentiaPlugin;
import com.alttd.essentia.api.events.EssentiaUserLoadEvent;
import com.alttd.essentia.configuration.Config;
import com.alttd.essentia.user.EssentiaUser;
import com.alttd.essentia.api.user.User;
import lombok.Getter;
import org.bukkit.scheduler.BukkitRunnable;
import org.jetbrains.annotations.NotNull;
import java.util.UUID;
public abstract class StorageProvider {
protected final EssentiaPlugin plugin;
@Getter
private AutoSaveTask autoSaveTask;
public StorageProvider(EssentiaPlugin plugin) {
this.plugin = plugin;
}
public User loadUser(UUID uuid) {
User user = load(uuid);
if (user == null) {
user = plugin.userManager().createNewUser(uuid);
}
plugin.userManager().addUser(user);
new EssentiaUserLoadEvent(user).callEvent();
return user;
}
public void startAutoSaving() {
if (!Config.AUTO_SAVE)
return;
autoSaveTask = new AutoSaveTask();
int delay = Config.AUTO_SAVE_DELAY * 20;
autoSaveTask.runTaskTimerAsynchronously(plugin, delay, delay);
}
public void disable() {
// Override if some extra steps are required when disabling the plugin.
}
protected abstract EssentiaUser load(UUID uuid);
public void startSaving(EssentiaUser user) throws Exception {
if (user.saving() || !user.needsSaving()) return;
user.saving(true);
save(user);
user.saving(false);
user.needsSaving(false);
}
public abstract void save(@NotNull EssentiaUser user) throws Exception;
public abstract void delete(UUID uuid) throws Exception;
private class AutoSaveTask extends BukkitRunnable {
@Override
public void run() {
plugin.userManager().saveAllUsers();
}
}
}
@@ -0,0 +1,7 @@
package com.alttd.essentia.storage;
public enum StorageType {
YAML,
MYSQL,
SQLITE
}
@@ -0,0 +1,86 @@
package com.alttd.essentia.storage.mysql;
import com.alttd.essentia.EssentiaPlugin;
import com.alttd.essentia.configuration.Config;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
public class DatabaseConnection implements AutoCloseable {
private Connection connection;
private volatile boolean isActive;
protected final EssentiaPlugin plugin;
public DatabaseConnection(EssentiaPlugin plugin) {
this.plugin = plugin;
try {
openConnection();
} catch (SQLException e) {
e.printStackTrace();
}
}
private synchronized void openConnection() throws SQLException {
if (connection != null && !connection.isClosed()) {
return;
}
synchronized (this) {
if (connection != null && !connection.isClosed()) {
return;
}
try {
Class.forName("com.mysql.cj.jdbc.Driver");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
connection = DriverManager.getConnection(
"jdbc:mysql://" + Config.MYSQL_IP + ":" + Config.MYSQL_PORT + "/" + Config.MYSQL_DATABASE_NAME +
"?autoReconnect=true&useSSL=false",
Config.MYSQL_USERNAME, Config.MYSQL_PASSWORD);
}
}
public synchronized Connection get() {
try {
openConnection();
} catch (SQLException e) {
e.printStackTrace();
}
return connection;
}
public synchronized boolean isValid() {
try {
return !connection.isClosed() && connection.isValid(8000);
} catch (SQLException e) {
e.printStackTrace();
return false;
}
}
synchronized void setActive(boolean active) {
isActive = active;
}
public synchronized boolean isActive() {
return isActive;
}
@Override
public synchronized void close() {
try {
if (!connection.isClosed()) {
if (!connection.getAutoCommit()) {
connection.commit();
}
connection.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
@@ -0,0 +1,56 @@
package com.alttd.essentia.storage.mysql;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
public class DatabaseQuery {
private final String statement;
private final DatabaseTask databaseTask;
public DatabaseQuery(String statement, DatabaseTask databaseTask) {
this.statement = statement;
this.databaseTask = databaseTask;
}
public DatabaseQuery(String statement) {
this(statement, ps -> {});
}
public ResultSet executeQuery(Connection connection) {
try (PreparedStatement preparedStatement = connection.prepareStatement(statement)) {
databaseTask.edit(preparedStatement);
ResultSet resultSet = preparedStatement.executeQuery();
databaseTask.onSuccess(resultSet);
return resultSet;
} catch (SQLException e) {
databaseTask.onFailure(e);
}
return null;
}
public void execute(Connection connection) {
try (PreparedStatement preparedStatement = connection.prepareStatement(statement)) {
databaseTask.edit(preparedStatement);
preparedStatement.execute();
databaseTask.onSuccess();
} catch (SQLException e) {
databaseTask.onFailure(e);
}
}
public interface DatabaseTask {
void edit(PreparedStatement preparedStatement) throws SQLException;
default void onSuccess(ResultSet resultSet) throws SQLException {}
default void onSuccess() throws SQLException {}
default void onFailure(SQLException e) {
e.printStackTrace();
}
}
}
@@ -0,0 +1,58 @@
package com.alttd.essentia.storage.mysql;
import lombok.Getter;
import org.bukkit.scheduler.BukkitRunnable;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Queue;
import java.util.concurrent.LinkedBlockingQueue;
public class DatabaseQueue extends BukkitRunnable {
private final SQLStorageProvider sqlStorageProvider;
public DatabaseQueue(SQLStorageProvider sqlStorageProvider) {
this.sqlStorageProvider = sqlStorageProvider;
}
@Getter
public final Queue<DatabaseQuery> databaseQueryQueue = new LinkedBlockingQueue<>();
@Override
public void run() {
runTaskQueue();
}
public synchronized void runTaskQueue() {
if (databaseQueryQueue.isEmpty())
return;
DatabaseConnection databaseConnection = sqlStorageProvider.getDatabaseConnection();
Connection connection = databaseConnection.get();
try {
databaseConnection.setActive(true);
connection.setAutoCommit(false);
while (!databaseQueryQueue.isEmpty()) {
if (!databaseConnection.isValid())
return;
DatabaseQuery databaseQuery = databaseQueryQueue.poll();
if (databaseQuery == null)
return;
databaseQuery.execute(connection);
}
if (!connection.getAutoCommit()) {
connection.commit();
connection.setAutoCommit(true);
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
databaseConnection.setActive(false);
}
}
}
@@ -0,0 +1,257 @@
package com.alttd.essentia.storage.mysql;
import com.alttd.essentia.EssentiaPlugin;
import com.alttd.essentia.configuration.Config;
import com.alttd.essentia.api.model.Home;
import com.alttd.essentia.model.EssentiaHome;
import com.alttd.essentia.model.EssentiaUserSettings;
import com.alttd.essentia.storage.StorageProvider;
import com.alttd.essentia.user.EssentiaUser;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.World;
import org.jetbrains.annotations.NotNull;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.*;
public class SQLStorageProvider extends StorageProvider {
private final DatabaseQueue databaseQueue;
private final List<DatabaseConnection> CONNECTIONPOOL = new ArrayList<>();
public SQLStorageProvider(EssentiaPlugin plugin) {
super(plugin);
databaseQueue = new DatabaseQueue(this);
int delay = Config.MYSQL_QUEUE_DELAY * 20;
databaseQueue.runTaskTimerAsynchronously(plugin, delay, delay);
// preload out database connections, TODO FIND A BETTER WAY TO LIMIT THIS
for (int i = 1; i < Config.MYSQL_CONNECTIONS; i++) {
CONNECTIONPOOL.add(null);
}
createTables();
}
private void createTables() {
// TODO -- create table
String userTable = "CREATE TABLE IF NOT EXISTS users(" +
"UUID VARCHAR(36) NOT NULL, " +
"DeathLocation mediumtext DEFAULT NULL, " +
"BackLocation mediumtext DEFAULT NULL, " +
"TeleportToggled tinyint(1) DEFAULT NULL, " +
"PRIMARY KEY (uuid)" +
")";
String homeTable = "CREATE TABLE IF NOT EXISTS homes(" +
"UUID VARCHAR(36) NOT NULL, " +
"Name mediumtext DEFAULT NULL, " +
"HomeLocation mediumtext DEFAULT NULL, "+
")";
String settingsTable = "CREATE TABLE IF NOT EXISTS homes(" +
"UUID VARCHAR(36) NOT NULL, " +
"TeleportToggled tinyint(1) DEFAULT NULL, " +
"GodMode tinyint(1) DEFAULT NULL, " +
"Flying tinyint(1) DEFAULT NULL, " +
"PRIMARY KEY (uuid)" +
")";
addDatabaseQuery(new DatabaseQuery(userTable), false);
addDatabaseQuery(new DatabaseQuery(homeTable), false);
addDatabaseQuery(new DatabaseQuery(settingsTable), false);
}
public DatabaseConnection getDatabaseConnection() {
for (int i = 0; i < Config.MYSQL_CONNECTIONS; i++) {
DatabaseConnection connection = CONNECTIONPOOL.get(i);
if (connection == null) {
return generateDatabaseConnection(i);
} else if (!connection.isActive()) {
if (connection.isValid()) {
return connection;
} else {
connection.close();
return generateDatabaseConnection(i);
}
}
}
// This will cause an infinite running loop, throw an exception or wait for a connection to be available?
return getDatabaseConnection();
}
private DatabaseConnection generateDatabaseConnection(int index) {
DatabaseConnection connection = new DatabaseConnection(plugin);
CONNECTIONPOOL.set(index, connection);
return connection;
}
private void closeDatabaseConnections() {
for (DatabaseConnection connection : CONNECTIONPOOL) {
if (connection == null || connection.isValid())
continue;
if (!connection.isActive()) {
connection.close();
} else {
while (connection.isActive()) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// This should not be interrupted as this is saving all the shops in the background for us.
e.printStackTrace();
}
}
connection.close();
}
}
}
@Override
public void disable() {
if (databaseQueue != null && !databaseQueue.isCancelled()) {
databaseQueue.cancel();
databaseQueue.runTaskQueue();
}
closeDatabaseConnections();
}
public void addDatabaseQuery(DatabaseQuery databaseQuery, boolean queue) {
if (queue) {
databaseQueue.databaseQueryQueue().offer(databaseQuery);
} else {
databaseQuery.execute(getDatabaseConnection().get());
}
}
// TODO -- make this async
@Override
protected EssentiaUser load(UUID uuid) {
String sql = "SELECT * FROM users WHERE uuid = ?";
DatabaseQuery databaseQuery = new DatabaseQuery(sql, ps -> ps.setString(1, uuid.toString()));
try (ResultSet resultSet = databaseQuery.executeQuery(getDatabaseConnection().get())) {
if (!resultSet.next()) {
return null; // user is not in the db
}
return new EssentiaUser.Builder()
.uuid(uuid)
.backLocation(locationStringToLocation(resultSet.getString("BackLocation")))
.deathLocation(locationStringToLocation(resultSet.getString("DeathLocation")))
.homes(loadHomes(uuid))
.userSettings(new EssentiaUserSettings
.Builder()
//.allowTeleports(resultSet.getBoolean("TeleportToggled")) // FIXME
.build())
.build();
} catch (SQLException e) {
// catch this nicely
}
return null;
}
private Map<String, Home> loadHomes(UUID uuid) {
String sql = "SELECT * FROM homes WHERE uuid = ?";
Map<String, Home> locationMap = new HashMap<>();
DatabaseQuery databaseQuery = new DatabaseQuery(sql, ps -> ps.setString(1, uuid.toString()));
try (ResultSet resultSet = databaseQuery.executeQuery(getDatabaseConnection().get())) {
if (!resultSet.next()) {
return locationMap;
}
String homeName = resultSet.getString("Name");
while (resultSet.next()) {
locationMap.put(
homeName,
new EssentiaHome(
homeName,
locationStringToLocation(resultSet.getString("HomeLocation"))
)
);
}
} catch (SQLException e) {
// catch this nicely
}
return locationMap;
}
@Override
public void save(@NotNull EssentiaUser user) throws Exception {
// TODO - convert to json object and save that in sql!
// Todo - use reflection to go over the fields to save?
// might not be the best way if new fields are added...
// split into multiple tables - users, userdata, userhomes, ... ?
String sql = "INSERT INTO users" +
"(uuid)" + // columns
"VALUES (?)" + // data
"ON DUPLICATE KEY UPDATE " + // data
"uuid = ?";
addDatabaseQuery(
new DatabaseQuery(sql, new DatabaseQuery.DatabaseTask() {
@Override
public void edit(PreparedStatement ps) throws SQLException {
ps.setString(1, user.getUUID().toString());
ps.setString(2, user.getUUID().toString());
}
}), true
);
saveHomes(user);
}
private void saveHomes(EssentiaUser essentiaUser) {
// TODO
}
@Override
public void delete(UUID uuid) throws Exception {
String sql = "DELETE FROM users WHERE uuid = ?";
addDatabaseQuery(
new DatabaseQuery(sql, new DatabaseQuery.DatabaseTask() {
@Override
public void edit(PreparedStatement ps) throws SQLException {
ps.setString(1, uuid.toString());
}
}), true
);
}
private String locationToString(Location location) {
if (location == null)
return "";
String wordName = location.getWorld().getName();
double x = location.getX();
double y = location.getY();
double z = location.getZ();
float pitch = location.getPitch();
float yaw = location.getYaw();
return wordName + ":" + x + ":" + y + ":" + z + ":" + pitch + ":" + yaw;
}
private Location locationStringToLocation(String locationString) {
if (locationString == null || locationString.isEmpty())
return null;
String[] split = locationString.split(":");
// should prob have some error catching
World wordName = Bukkit.getWorld(split[0]);
double x = Double.parseDouble(split[1]);
double y = Double.parseDouble(split[2]);
double z = Double.parseDouble(split[3]);
float pitch = Float.parseFloat(split[4]);
float yaw = Float.parseFloat(split[5]);
return new Location(wordName, x, y, z, pitch, yaw);
}
private String locationMapToString(Map<String, Location> map) {
// Todo -- can this be better?
StringBuilder stringBuilder = new StringBuilder();
for (Map.Entry<String, Location> entry : map.entrySet()) {
if (!stringBuilder.isEmpty())
stringBuilder.append(";");
stringBuilder.append(entry.getKey()).append("%").append(locationToString(entry.getValue()));
}
return stringBuilder.toString();
}
}
@@ -0,0 +1,31 @@
package com.alttd.essentia.storage.sqlite;
import com.alttd.essentia.EssentiaPlugin;
import com.alttd.essentia.storage.StorageProvider;
import com.alttd.essentia.user.EssentiaUser;
import org.jetbrains.annotations.NotNull;
import java.util.UUID;
// TODO -- add support for SQLite
public class SQLiteStorageProvider extends StorageProvider {
public SQLiteStorageProvider(EssentiaPlugin plugin) {
super(plugin);
}
@Override
protected EssentiaUser load(UUID uuid) {
return null;
}
@Override
public void save(@NotNull EssentiaUser user) throws Exception {
}
@Override
public void delete(UUID uuid) throws Exception {
}
}
@@ -0,0 +1,115 @@
package com.alttd.essentia.storage.yaml;
import com.alttd.essentia.EssentiaPlugin;
import com.alttd.essentia.api.model.Home;
import com.alttd.essentia.model.EssentiaHome;
import com.alttd.essentia.model.EssentiaUserSettings;
import com.alttd.essentia.storage.StorageProvider;
import com.alttd.essentia.user.EssentiaUser;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.World;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.configuration.file.YamlConfiguration;
import org.jetbrains.annotations.NotNull;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
// TODO -- switch to configurate?
public class YamlStorageProvider extends StorageProvider {
private final String dataDirectory;
public YamlStorageProvider(EssentiaPlugin plugin, String dataDirectory) {
super(plugin);
this.dataDirectory = dataDirectory;
}
@Override
protected EssentiaUser load(UUID uuid) {
File configFile = new File(dataDirectory, uuid + ".yml");
YamlConfiguration config = YamlConfiguration.loadConfiguration(configFile);
return new EssentiaUser.Builder()
.uuid(uuid)
.backLocation(getStoredLocation(config,"teleports.back"))
.deathLocation(getStoredLocation(config,"teleports.death"))
.homes(getHomeData(config))
.cuffed(config.getBoolean("cuffed", false))
.userSettings(new EssentiaUserSettings
.Builder()
.flying(config.getBoolean("flying", false))
.allowTeleports(config.getBoolean("allow-teleports", true))
.godMode(config.getBoolean("god", false))
.build())
.build();
}
@Override
public void save(@NotNull EssentiaUser user) throws Exception {
File configFile = new File(dataDirectory, user.getUUID() + ".yml");
YamlConfiguration config = YamlConfiguration.loadConfiguration(configFile);
setStoredLocation(config, "teleports.back", user.getBackLocation(false));
setStoredLocation(config, "teleports.death", user.getBackLocation(true));
for (Map.Entry<String, Home> entry : user.getHomeData().entrySet()) {
setStoredLocation(config, "home." + entry.getKey(), entry.getValue().location());
}
config.set("allow-teleports", user.getUserSettings().allowTeleports());
config.save(configFile);
}
@Override
public void delete(UUID uuid) throws Exception {
Path path = Path.of(dataDirectory, uuid.toString() + ".yml");
Files.deleteIfExists(path);
}
void setStoredLocation(YamlConfiguration config, String path, Location location) {
if (location == null) {
config.set(path, null);
return;
}
config.set(path + ".world", location.getWorld().getName());
config.set(path + ".x", location.getX());
config.set(path + ".y", location.getY());
config.set(path + ".z", location.getZ());
config.set(path + ".pitch", location.getPitch());
config.set(path + ".yaw", location.getYaw());
}
Location getStoredLocation(YamlConfiguration config, String path) {
if (config.get(path) == null) {
return null;
}
World world = Bukkit.getWorld(config.getString(path + ".world", ""));
if (world == null) {
return null;
}
double x = config.getDouble(path + ".x");
double y = config.getDouble(path + ".y");
double z = config.getDouble(path + ".z");
float pitch = (float) config.getDouble(path + ".pitch");
float yaw = (float) config.getDouble(path + ".yaw");
return new Location(world, x, y, z, yaw, pitch);
}
public Map<String, Home> getHomeData(YamlConfiguration config) {
ConfigurationSection section = config.getConfigurationSection("home");
if (section == null) {
return null;
}
Map<String, Home> map = new HashMap<>();
for (String key : section.getValues(false).keySet()) {
map.put(key, new EssentiaHome(key, getStoredLocation(config, "home." + key)));
}
return map;
}
}
@@ -1,15 +1,15 @@
package com.alttd.essentia.tasks; package com.alttd.essentia.tasks;
import com.alttd.essentia.configuration.Config; import com.alttd.essentia.configuration.Config;
import com.alttd.essentia.request.Request; import com.alttd.essentia.request.EssentiaRequest;
import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder; import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder;
import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver; import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver;
import org.bukkit.scheduler.BukkitRunnable; import org.bukkit.scheduler.BukkitRunnable;
public class RequestTimeout extends BukkitRunnable { public class RequestTimeout extends BukkitRunnable {
private final Request request; private final EssentiaRequest request;
public RequestTimeout(Request request) { public RequestTimeout(EssentiaRequest request) {
this.request = request; this.request = request;
} }
@@ -1,7 +1,6 @@
package com.alttd.essentia.tasks; package com.alttd.essentia.tasks;
import com.alttd.essentia.configuration.Config; import com.alttd.essentia.configuration.Config;
import org.bukkit.Location; import org.bukkit.Location;
import org.bukkit.scheduler.BukkitRunnable; import org.bukkit.scheduler.BukkitRunnable;
@@ -0,0 +1,184 @@
package com.alttd.essentia.user;
import com.alttd.essentia.api.model.Home;
import com.alttd.essentia.api.model.UserSettings;
import com.alttd.essentia.api.request.Request;
import com.alttd.essentia.api.user.User;
import com.alttd.essentia.model.EssentiaHome;
import org.bukkit.Location;
import java.util.*;
import java.util.stream.Collectors;
public class EssentiaUser implements User {
protected final UUID uuid;
protected Location backLocation;
protected Location deathLocation;
protected Map<String, Home> homes;
protected UserSettings userSettings;
protected Request request;
protected boolean cuffed;
private boolean saving;
private boolean needsSaving; // can we use a decorator for this to set it to true on every change?
private EssentiaUser(Builder builder) {
this.uuid = builder.uuid;
this.backLocation = builder.backLocation;
this.deathLocation = builder.deathLocation;
this.homes = builder.homes;
this.userSettings = builder.userSettings;
}
@Override
public UUID getUUID() {
return uuid;
}
@Override
public Location getBackLocation(boolean death) {
return death ? deathLocation : backLocation;
}
@Override
public void setBackLocation(boolean death, Location location) {
if (death) {
deathLocation = location;
return;
}
backLocation = location;
needsSaving = true;
}
@Override
public boolean hasHome(String name) {
return homes.containsKey(name);
}
@Override
public Home getHome(String name) {
return homes.get(name);
}
@Override
public void setHome(String name, Location location) {
homes.put(name, new EssentiaHome(name, location));
needsSaving = true;
}
@Override
public void removeHome(String name) {
homes.remove(name);
needsSaving = true;
}
@Override
public int getHomeCount() {
return homes.size();
}
@Override
public List<String> getMatchingHomeNames(String homeName) {
return getHomes().stream()
.filter(home -> home.toLowerCase().startsWith(homeName.toLowerCase()))
.collect(Collectors.toList());
}
@Override
public Map<String, Home> getHomeData() {
return homes;
}
@Override
public Set<String> getHomes() {
return homes.keySet();
}
@Override
public UserSettings getUserSettings() {
return userSettings;
}
public boolean saving() {
return saving;
}
public void saving(boolean saving) {
this.saving = saving;
}
public boolean needsSaving() {
return needsSaving;
}
public void needsSaving(boolean needsSaving) {
this.needsSaving = needsSaving;
}
@Override
public Request request() {
return request;
}
@Override
public void request(Request request) {
this.request = request;
}
@Override
public boolean isCuffed() {
return cuffed;
}
@Override
public void setCuffed(boolean cuffed) {
this.cuffed = cuffed;
}
public static class Builder {
protected UUID uuid;
protected Location backLocation = null;
protected Location deathLocation = null;
protected Map<String, Home> homes = new HashMap<>();
protected UserSettings userSettings = null;
protected boolean cuffed = false;
public Builder uuid(UUID uuid) {
this.uuid = uuid;
return this;
}
public Builder backLocation(Location location) {
this.backLocation = location;
return this;
}
public Builder deathLocation(Location location) {
this.deathLocation = location;
return this;
}
public Builder homes(Map<String, Home> homes) {
this.homes = homes;
return this;
}
public Builder userSettings(UserSettings userSettings) {
this.userSettings = userSettings;
return this;
}
public Builder cuffed(boolean cuffed) {
this.cuffed = cuffed;
return this;
}
public EssentiaUser build() {
return new EssentiaUser(this);
}
}
}
@@ -0,0 +1,80 @@
package com.alttd.essentia.user;
import com.alttd.essentia.EssentiaPlugin;
import com.alttd.essentia.api.user.User;
import com.alttd.essentia.api.user.UserManager;
import com.alttd.essentia.model.EssentiaUserSettings;
import org.bukkit.entity.Player;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
public class EssentiaUserManager implements UserManager {
protected final EssentiaPlugin plugin;
private final Map<UUID, User> essentiaPlayers = new ConcurrentHashMap<>();
public EssentiaUserManager(EssentiaPlugin plugin) {
this.plugin = plugin;
}
@Override
public User getUser(Player player) {
return getUser(player.getUniqueId());
}
@Override
public User getUser(UUID uuid) {
User user = essentiaPlayers.get(uuid);
if (user != null) {
return user;
} else {
return createNewUser(uuid);
}
}
@Override
public void addUser(User user) {
essentiaPlayers.put(user.getUUID(), user);
}
@Override
public void removeUser(UUID uuid) {
essentiaPlayers.remove(uuid);
}
@Override
public boolean hasUser(UUID uuid) {
return essentiaPlayers.containsKey(uuid);
}
@Override
public Map<UUID, User> getUsers() {
return essentiaPlayers;
}
@Override
public User createNewUser(UUID uuid) {
return new EssentiaUser.Builder().uuid(uuid).build();
}
@Override
public void saveAllUsers() {
for (User user : getUsers().values()) {
if (user instanceof EssentiaUser essentiaUser && essentiaUser.getUserSettings() instanceof EssentiaUserSettings essentiaUserSettings) {
try {
if (essentiaUser.saving() || !essentiaUser.needsSaving() || !essentiaUserSettings.needsSaving()) {
continue;
}
plugin.storageProvider().startSaving(essentiaUser);
} catch(Exception e){
essentiaUser.saving(false);
e.printStackTrace();
}
}
}
}
}
+1 -104
View File
@@ -4,107 +4,4 @@ main: com.alttd.essentia.EssentiaPlugin
description: Altitude essentials ;) description: Altitude essentials ;)
authors: authors:
- destro174 - destro174
api-version: "1.20" api-version: "1.21"
commands:
essentia:
description: Reload configs.
permission: essentia.command.essentia-reload
usage: /<command> (reload)
teleportaccept:
description: Accept teleport request.
permission: essentia.command.teleportaccept
usage: /<command>
aliases:
- tpaccept
teleportdeny:
description: Decline teleport request.
permission: essentia.command.teleportdeny
usage: /<command>
aliases:
- tpdeny
teleportrequest:
description: Request to teleport to another player.
permission: essentia.command.teleportrequest
usage: /<command> player
aliases:
- tpa
- tprequest
- tparequest
teleportrequesthere:
description: Request another player to teleport to you.
permission: essentia.command.teleportrequesthere
usage: /<command> player
aliases:
- tpah
- tpahere
teleporttoggle:
description: Toggle teleport requests on/off.
permission: essentia.command.teleporttoggle
usage: /<command>
aliases:
- tptoggle
clearinventory:
description: Clears your inventory.
permission: essentia.command.clearinventory
usage: /<command> (player)
home:
description: Teleports the player home.
permission: essentia.command.home
usage: /<command> (home (player))
homes:
description: List the player's homes.
permission: essentia.command.homes
usage: /<command> (player)
aliases:
- listhomes
sethome:
description: Sets the player's home.
permission: essentia.command.sethome
usage: /<command> (home (player))
aliases:
- homeset
deletehome:
description: Deletes a home.
permission: essentia.command.deletehome
usage: /<command> [home (player)]
aliases:
- delhome
back:
description: Go back to previous location.
permission: essentia.command.back
usage: /<command>
deathback:
description: Go back to previous death location.
permission: essentia.command.deathback
usage: /<command>
aliases:
- dback
fly:
description: Toggles creative flymode for yourself or another player.
permission: essentia.command.fly
usage: /<command> (player)
gamemode:
description: Set gamemode for yourself or another player.
permission: essentia.command.gamemode
usage: /<command> (player)
aliases:
- gm
heal:
description: Heals yourself or another player.
permission: essentia.command.heal
usage: /<command> (player)
aliases:
- health
feed:
description: Refill hunger and saturation.
permission: essentia.command.feed
usage: /<command> (player)
enchant:
description: Enchants the item in hand
permission: essentia.command.enchant
usage: /<command> [enchantment/all] (level) (unsafe)
spawn:
description: Teleport yourself or another player to spawn.
permission: essentia.command.spawn
usage: /<command>