diff --git a/NookureStaff-API/src/main/java/com/nookure/staff/api/StaffPlayerWrapper.java b/NookureStaff-API/src/main/java/com/nookure/staff/api/StaffPlayerWrapper.java index 3a81d2d59..152cc4a88 100644 --- a/NookureStaff-API/src/main/java/com/nookure/staff/api/StaffPlayerWrapper.java +++ b/NookureStaff-API/src/main/java/com/nookure/staff/api/StaffPlayerWrapper.java @@ -56,8 +56,19 @@ default void toggleStaffMode() { * Set the player's staff chat mode. * * @param staffChatAsDefault if true, the player will be in staff chat mode + * by default + * @param saveInDB if true, the player's staff chat mode will be saved */ - void setStaffChatAsDefault(boolean staffChatAsDefault); + void setStaffChatAsDefault(boolean staffChatAsDefault, boolean saveInDB); + + /** + * Set the player's staff chat mode. + * + * @param staffChatAsDefault if true, the player will be in staff chat mode + */ + default void setStaffChatAsDefault(boolean staffChatAsDefault) { + setStaffChatAsDefault(staffChatAsDefault, true); + } /** * Reload/load the player's items. @@ -138,4 +149,6 @@ default void disableVanish() { * @return the player's items */ @NotNull Map getItems(); + + @NotNull Map, StaffPlayerExtension> getExtensions(); } diff --git a/NookureStaff-API/src/main/java/com/nookure/staff/api/annotation/staff/StaffChatAsDefaultBool.java b/NookureStaff-API/src/main/java/com/nookure/staff/api/annotation/staff/StaffChatAsDefaultBool.java new file mode 100644 index 000000000..a62c9a13b --- /dev/null +++ b/NookureStaff-API/src/main/java/com/nookure/staff/api/annotation/staff/StaffChatAsDefaultBool.java @@ -0,0 +1,14 @@ +package com.nookure.staff.api.annotation.staff; + +import com.google.inject.BindingAnnotation; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target({ElementType.FIELD, ElementType.PARAMETER}) +@Retention(RetentionPolicy.RUNTIME) +@BindingAnnotation +public @interface StaffChatAsDefaultBool { +} diff --git a/NookureStaff-API/src/main/java/com/nookure/staff/api/annotation/staff/StaffModeBool.java b/NookureStaff-API/src/main/java/com/nookure/staff/api/annotation/staff/StaffModeBool.java new file mode 100644 index 000000000..ec6ed7b9d --- /dev/null +++ b/NookureStaff-API/src/main/java/com/nookure/staff/api/annotation/staff/StaffModeBool.java @@ -0,0 +1,14 @@ +package com.nookure.staff.api.annotation.staff; + +import com.google.inject.BindingAnnotation; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target({ElementType.FIELD, ElementType.PARAMETER}) +@Retention(RetentionPolicy.RUNTIME) +@BindingAnnotation +public @interface StaffModeBool { +} diff --git a/NookureStaff-API/src/main/java/com/nookure/staff/api/extension/StaffPlayerExtension.java b/NookureStaff-API/src/main/java/com/nookure/staff/api/extension/StaffPlayerExtension.java index 4c908f1c8..53492328a 100644 --- a/NookureStaff-API/src/main/java/com/nookure/staff/api/extension/StaffPlayerExtension.java +++ b/NookureStaff-API/src/main/java/com/nookure/staff/api/extension/StaffPlayerExtension.java @@ -1,9 +1,12 @@ package com.nookure.staff.api.extension; +import com.google.inject.Inject; import com.nookure.staff.api.StaffPlayerWrapper; +import org.jetbrains.annotations.NotNull; public abstract class StaffPlayerExtension { - public StaffPlayerExtension(StaffPlayerWrapper player) { + @Inject + public StaffPlayerExtension(@NotNull final StaffPlayerWrapper player) { } /** diff --git a/NookureStaff-API/src/main/java/com/nookure/staff/api/extension/VanishExtension.java b/NookureStaff-API/src/main/java/com/nookure/staff/api/extension/VanishExtension.java index 3fd77b38e..b63f8b496 100644 --- a/NookureStaff-API/src/main/java/com/nookure/staff/api/extension/VanishExtension.java +++ b/NookureStaff-API/src/main/java/com/nookure/staff/api/extension/VanishExtension.java @@ -1,6 +1,8 @@ package com.nookure.staff.api.extension; +import com.google.inject.Inject; import com.nookure.staff.api.StaffPlayerWrapper; +import org.jetbrains.annotations.NotNull; /** * This class represents an extension for the vanish feature @@ -12,7 +14,8 @@ public abstract class VanishExtension extends StaffPlayerExtension { * * @param player the player */ - public VanishExtension(StaffPlayerWrapper player) { + @Inject + public VanishExtension(@NotNull final StaffPlayerWrapper player) { super(player); } diff --git a/NookureStaff-API/src/main/java/com/nookure/staff/api/extension/staff/StaffModeExtension.java b/NookureStaff-API/src/main/java/com/nookure/staff/api/extension/staff/StaffModeExtension.java new file mode 100644 index 000000000..8cd565955 --- /dev/null +++ b/NookureStaff-API/src/main/java/com/nookure/staff/api/extension/staff/StaffModeExtension.java @@ -0,0 +1,41 @@ +package com.nookure.staff.api.extension.staff; + +import com.nookure.staff.api.StaffPlayerWrapper; +import com.nookure.staff.api.extension.StaffPlayerExtension; +import com.nookure.staff.api.item.StaffItem; +import org.jetbrains.annotations.NotNull; + +import java.util.Map; + +public abstract class StaffModeExtension extends StaffPlayerExtension { + public StaffModeExtension(StaffPlayerWrapper player) { + super(player); + } + + public abstract void enableStaffMode(final boolean silentJoin); + + public abstract void disableStaffMode(); + + public abstract void checkStaffMode(); + + public abstract void writeStaffModeState(final boolean state); + + public abstract void toggleStaffMode(boolean silentJoin); + + public abstract boolean isStaffMode(); + + public abstract void setItems(); + + @NotNull + public abstract Map getItems(); + + public abstract void saveInventory(); + + public abstract void clearInventory(); + + public abstract void restoreInventory(); + + public abstract void saveLocation(); + + public abstract void restoreLocation(); +} diff --git a/NookureStaff-API/src/main/java/com/nookure/staff/api/item/StaffItem.java b/NookureStaff-API/src/main/java/com/nookure/staff/api/item/StaffItem.java index 786cf0519..cda0adac7 100644 --- a/NookureStaff-API/src/main/java/com/nookure/staff/api/item/StaffItem.java +++ b/NookureStaff-API/src/main/java/com/nookure/staff/api/item/StaffItem.java @@ -4,6 +4,7 @@ import com.nookure.staff.api.util.ServerUtils; import com.nookure.staff.api.util.TextUtils; import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.format.TextDecoration; import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer; import org.bukkit.NamespacedKey; import org.bukkit.entity.Player; @@ -33,7 +34,10 @@ public StaffItem(ItemPartial itemConfig) { ItemMeta meta = itemStack.getItemMeta(); if (ServerUtils.isPaper) { - meta.displayName(TextUtils.toComponent(itemConfig.getName())); + Component displayName = TextUtils.toComponent(itemConfig.getName()); + displayName = displayName.decoration(TextDecoration.ITALIC, TextDecoration.State.FALSE); + meta.displayName(displayName); + meta.lore(itemConfig.lore()); } else { meta.setDisplayName( diff --git a/NookureStaff-Common/src/main/java/com/nookure/staff/messaging/DecoderPluginMessenger.java b/NookureStaff-Common/src/main/java/com/nookure/staff/messaging/DecoderPluginMessenger.java index 24700347e..cf3e9ee06 100644 --- a/NookureStaff-Common/src/main/java/com/nookure/staff/messaging/DecoderPluginMessenger.java +++ b/NookureStaff-Common/src/main/java/com/nookure/staff/messaging/DecoderPluginMessenger.java @@ -4,7 +4,7 @@ import com.nookure.staff.api.messaging.EventMessenger; import org.jetbrains.annotations.NotNull; -public abstract class DecoderPluginMessenger extends EventMessenger { +public final class DecoderPluginMessenger extends EventMessenger { @Override public void prepare() { // Nothing to do here diff --git a/NookureStaff-Common/src/main/resources/migrations/mysql/22_22_25_11_2024_create_nookure_staff_data.sql b/NookureStaff-Common/src/main/resources/migrations/mysql/22_22_25_11_2024_create_nookure_staff_data.sql index 92f5e74e1..33469723a 100644 --- a/NookureStaff-Common/src/main/resources/migrations/mysql/22_22_25_11_2024_create_nookure_staff_data.sql +++ b/NookureStaff-Common/src/main/resources/migrations/mysql/22_22_25_11_2024_create_nookure_staff_data.sql @@ -5,4 +5,4 @@ `vanished` TINYINT(1) NOT NULL DEFAULT 0, `staff_chat_enabled` TINYINT(1) NOT NULL DEFAULT 0, PRIMARY KEY (`id`) USING BTREE -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLTE=utf8mb4_general_ci; \ No newline at end of file +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; \ No newline at end of file diff --git a/NookureStaff-Paper/src/main/java/com/nookure/staff/paper/NookureStaff.java b/NookureStaff-Paper/src/main/java/com/nookure/staff/paper/NookureStaff.java index 5177779d9..5b71f6b3f 100644 --- a/NookureStaff-Paper/src/main/java/com/nookure/staff/paper/NookureStaff.java +++ b/NookureStaff-Paper/src/main/java/com/nookure/staff/paper/NookureStaff.java @@ -18,6 +18,7 @@ import com.nookure.staff.api.event.EventManager; import com.nookure.staff.api.extension.StaffPlayerExtensionManager; import com.nookure.staff.api.extension.VanishExtension; +import com.nookure.staff.api.extension.staff.StaffModeExtension; import com.nookure.staff.api.manager.PlayerWrapperManager; import com.nookure.staff.api.messaging.Channels; import com.nookure.staff.api.messaging.EventMessenger; @@ -27,6 +28,7 @@ import com.nookure.staff.paper.command.main.NookureStaffCommand; import com.nookure.staff.paper.command.staff.StaffCommandParent; import com.nookure.staff.paper.extension.FreezePlayerExtension; +import com.nookure.staff.paper.extension.staff.PaperStaffModeExtension; import com.nookure.staff.paper.extension.vanish.InternalVanishExtension; import com.nookure.staff.paper.extension.vanish.SuperVanishExtension; import com.nookure.staff.paper.listener.OnPlayerJoin; @@ -316,6 +318,10 @@ private void loadExtensions() { extensionManager.registerExtension(SuperVanishExtension.class, VanishExtension.class); } } + + if (config.get().modules.isStaffMode()) { + extensionManager.registerExtension(PaperStaffModeExtension.class, StaffModeExtension.class); + } } public void onDisable() { diff --git a/NookureStaff-Paper/src/main/java/com/nookure/staff/paper/StaffPaperPlayerWrapper.java b/NookureStaff-Paper/src/main/java/com/nookure/staff/paper/StaffPaperPlayerWrapper.java index c1a5c3800..6ef097b84 100644 --- a/NookureStaff-Paper/src/main/java/com/nookure/staff/paper/StaffPaperPlayerWrapper.java +++ b/NookureStaff-Paper/src/main/java/com/nookure/staff/paper/StaffPaperPlayerWrapper.java @@ -10,24 +10,20 @@ import com.nookure.staff.api.config.bukkit.BukkitMessages; import com.nookure.staff.api.database.model.StaffStateModel; import com.nookure.staff.api.database.repository.StaffStateRepository; -import com.nookure.staff.api.event.server.BroadcastMessageExcept; -import com.nookure.staff.api.event.staff.StaffModeDisabledEvent; -import com.nookure.staff.api.event.staff.StaffModeEnabledEvent; import com.nookure.staff.api.extension.StaffPlayerExtension; import com.nookure.staff.api.extension.StaffPlayerExtensionManager; import com.nookure.staff.api.extension.VanishExtension; +import com.nookure.staff.api.extension.staff.StaffModeExtension; import com.nookure.staff.api.item.StaffItem; -import com.nookure.staff.api.manager.StaffItemsManager; -import com.nookure.staff.api.messaging.EventMessenger; import com.nookure.staff.api.state.PlayerState; import com.nookure.staff.api.util.Scheduler; import com.nookure.staff.api.util.ServerUtils; -import com.nookure.staff.paper.data.StaffModeData; +import com.nookure.staff.paper.bootstrap.StaffPaperPlayerWrapperModule; +import com.nookure.staff.paper.data.ServerStaffModeData; import io.ebean.Database; import net.kyori.adventure.text.minimessage.MiniMessage; import org.bukkit.*; import org.bukkit.entity.Player; -import org.bukkit.inventory.ItemStack; import org.bukkit.plugin.java.JavaPlugin; import org.bukkit.potion.PotionEffect; import org.bukkit.potion.PotionEffectType; @@ -35,24 +31,22 @@ import org.jetbrains.annotations.Nullable; import java.util.*; +import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicReference; public class StaffPaperPlayerWrapper extends PaperPlayerWrapper implements StaffPlayerWrapper { private final Map, StaffPlayerExtension> extensionMap = new HashMap<>(); - private final Map items = new HashMap<>(); private final ConfigurationContainer messages; private final ConfigurationContainer config; - private final StaffItemsManager itemsManager; private final Scheduler scheduler; - private final EventMessenger eventMessenger; private final StaffPlayerExtensionManager extensionManager; private final StaffStateRepository staffStateRepository; private final Injector injector; - private StaffStateModel staffDataModel; - private boolean staffMode = false; - private boolean staffChatAsDefault = false; - private StaffModeData staffModeData; + private final AtomicReference staffDataModel = new AtomicReference<>(); + private final AtomicBoolean staffMode = new AtomicBoolean(false); + private final AtomicBoolean staffChatAsDefault = new AtomicBoolean(false); private VanishExtension vanishExtension; + private StaffModeExtension staffModeExtension; @Inject public StaffPaperPlayerWrapper( @@ -62,9 +56,7 @@ public StaffPaperPlayerWrapper( @NotNull final ConfigurationContainer messages, @NotNull final ConfigurationContainer config, @NotNull final AtomicReference db, - @NotNull final StaffItemsManager itemsManager, @NotNull final Scheduler scheduler, - @NotNull final EventMessenger eventMessenger, @NotNull final StaffPlayerExtensionManager extensionManager, @NotNull final StaffStateRepository staffStateRepository, @NotNull @Assisted final Player player, @@ -73,13 +65,22 @@ public StaffPaperPlayerWrapper( super(plugin, nookPlugin, logger, config, scheduler, db, player, states); this.messages = messages; this.config = config; - this.itemsManager = itemsManager; this.scheduler = scheduler; - this.eventMessenger = eventMessenger; this.extensionManager = extensionManager; - this.injector = nookPlugin.getInjector(); this.staffStateRepository = staffStateRepository; + AtomicReference serverStaffModeData = new AtomicReference<>(); + this.injector = nookPlugin.getInjector().createChildInjector( + new StaffPaperPlayerWrapperModule( + this, + serverStaffModeData, + staffDataModel, + staffMode, + staffChatAsDefault + ) + ); + + this.loadDBState(); this.addExtensions(); this.checkStaffModeState(); this.checkVanishState(); @@ -141,7 +142,7 @@ public void checkVanishState() { logger.debug("StaffDataModel state: %s", staffDataModel); if (staffDataModel.vanished()) { - enableVanish(staffMode); + enableVanish(staffMode.get()); } else { disableVanish(true); } @@ -149,12 +150,30 @@ public void checkVanishState() { vanishExtension.setVanished(staffDataModel.vanished()); } - private void writeVanishState(boolean state) { - staffDataModel = StaffStateModel.builder(staffDataModel) + public void loadDBState() { + if (staffDataModel.get() == null) { + staffDataModel.set(staffStateRepository.fromUUID(player.getUniqueId())); + + if (staffDataModel.get() == null) { + staffDataModel.set(StaffStateModel + .builder() + .uuid(player.getUniqueId()) + .staffMode(false) + .vanished(false) + .staffChatEnabled(false) + .build()); + + staffStateRepository.savePlayerModel(staffDataModel.get()); + } + } + } + + public void writeVanishState(boolean state) { + staffDataModel.set(StaffStateModel.builder(staffDataModel.get()) .vanished(state) - .build(); + .build()); - staffStateRepository.saveOrUpdateModelAsync(staffDataModel) + staffStateRepository.saveOrUpdateModelAsync(staffDataModel.get()) .thenRun(() -> logger.debug("Vanish state for %s has been set to %s on the database", player.getName(), state)); if (vanishExtension != null) { @@ -165,161 +184,42 @@ private void writeVanishState(boolean state) { // private void enableStaffMode(boolean silentJoin) { - long time = System.currentTimeMillis(); - - enablePlayerPerks(); - - if (!silentJoin) { - saveLocation(); - saveInventory(); - } - - setItems(); - sendMiniMessage(messages.get().staffMode.toggledOn()); - writeStaffModeState(true); - - if (config.get().staffMode.enableVanishOnStaffEnable()) { - enableVanish(silentJoin); - writeVanishState(true); - } - - eventMessenger.publish(this, new StaffModeEnabledEvent(getUniqueId())); - eventMessenger.publish(this, new BroadcastMessageExcept(messages.get().staffMode.toggledOnOthers() - .replace("{player}", player.getName()), - getUniqueId()) - ); - - try { - extensionMap.values().forEach(StaffPlayerExtension::onStaffModeEnabled); - } catch (Exception e) { - logger.severe("An error occurred while enabling staff mode for %s: %s", player.getName(), e.getMessage()); - } - - logger.debug("Staff mode enabled for %s in %dms", player.getName(), System.currentTimeMillis() - time); + if (staffModeExtension != null) staffModeExtension.enableStaffMode(silentJoin); } private void disableStaffMode() { - long time = System.currentTimeMillis(); - disablePlayerPerks(); - restoreInventory(); - if (config.get().staffMode.teleportToPreviousLocation()) loadPreviousLocation(); - sendMiniMessage(messages.get().staffMode.toggledOff()); - writeStaffModeState(false); - - if (config.get().staffMode.disableVanishOnStaffDisable()) { - disableVanish(false); - writeVanishState(false); - } - - eventMessenger.publish(this, new StaffModeDisabledEvent(getUniqueId())); - eventMessenger.publish(this, new BroadcastMessageExcept(messages.get().staffMode.toggledOffOthers() - .replace("{player}", player.getName()), - getUniqueId()) - ); - - try { - extensionMap.values().forEach(StaffPlayerExtension::onStaffModeDisabled); - } catch (Exception e) { - logger.severe("An error occurred while enabling staff mode for %s: %s", player.getName(), e.getMessage()); - } - - logger.debug("Staff mode disabled for %s in %dms", player.getName(), System.currentTimeMillis() - time); + if (staffModeExtension != null) staffModeExtension.disableStaffMode(); } private void checkStaffModeState() { - if (staffModeData == null) { - staffModeData = StaffModeData.read(nookPlugin, this); - } - - if (staffDataModel == null) { - staffDataModel = staffStateRepository.fromUUID(getUniqueId()); - - if (staffDataModel == null) { - StaffStateModel staffStateModel = StaffStateModel - .builder() - .uuid(getUniqueId()) - .staffMode(false) - .vanished(false) - .staffChatEnabled(false) - .build(); - - staffStateRepository.savePlayerModel(staffStateModel); - } - } - - if (staffModeData == null) { - logger.severe("StaffModeData is null for %s", player.getName()); - return; - } - - if (staffModeData.record().staffMode()) { - clearInventory(); - enableStaffMode(true); - } - - if (staffDataModel.staffMode()) { - if (!isInStaffMode()) { - saveInventory(); - saveLocation(); - enableStaffMode(true); - } - } - - logger.debug("StaffDataModel state: %s", staffDataModel); - staffChatAsDefault = staffDataModel.staffChatEnabled(); + if (staffModeExtension != null) staffModeExtension.checkStaffMode(); } private void writeStaffModeState(boolean state) { - scheduler.async(() -> { - StaffStateModel staffDataModel = staffStateRepository.fromUUID(getUniqueId()); - - if (staffDataModel == null) { - return; - } - - staffDataModel = StaffStateModel.builder(staffDataModel) - .staffMode(state) - .build(); - - staffStateRepository.saveOrUpdateModel(staffDataModel); - logger.debug("Staff mode state for %s has been set to %s on the database", player.getName(), state); - }); - - staffModeData.record().staffMode(state); - staffModeData.write(); - - staffMode = state; + if (staffModeExtension != null) staffModeExtension.writeStaffModeState(state); } @Override public void toggleStaffMode(boolean silentJoin) { - if (!staffMode) enableStaffMode(silentJoin); - else disableStaffMode(); + if (staffModeExtension != null) staffModeExtension.toggleStaffMode(silentJoin); } @Override public boolean isInStaffMode() { - return staffMode; + return staffMode.get(); } // // @Override public void setItems() { - if (items.isEmpty()) { - itemsManager.getItems().forEach((identifier, item) -> { - if (item.getPermission() != null && !player.hasPermission(item.getPermission())) return; - - items.put(item.getSlot(), item); - }); - } - - items.forEach((identifier, item) -> item.setItem(player)); + if (staffModeExtension != null) staffModeExtension.setItems(); } @Override public @NotNull Map getItems() { - return items; + if (staffModeExtension != null) return staffModeExtension.getItems(); + return Map.of(); } // @@ -349,69 +249,49 @@ public void disablePlayerPerks() { // @Override public void saveInventory() { - if (staffModeData == null) { - staffModeData = StaffModeData.read(nookPlugin, this); - } - - assert staffModeData != null; - - staffModeData.record().playerInventory(player.getInventory().getContents()); - staffModeData.record().playerInventoryArmor(player.getInventory().getArmorContents()); - - staffModeData.write(); - - clearInventory(); + if (staffModeExtension != null) staffModeExtension.saveInventory(); } @Override public void clearInventory() { - player.getInventory().clear(); - player.getInventory().setArmorContents(new ItemStack[0]); + if (staffModeExtension != null) staffModeExtension.clearInventory(); } @Override public void restoreInventory() { - if (staffModeData == null) { - staffModeData = StaffModeData.read(nookPlugin, this); - } - - assert staffModeData != null; - - player.getInventory().setContents(staffModeData.record().playerInventory()); - player.getInventory().setArmorContents(staffModeData.record().playerInventoryArmor()); - - staffModeData.write(); + if (staffModeExtension != null) staffModeExtension.restoreInventory(); } // // public void saveLocation() { - staffModeData.record().enabledLocation(player.getLocation()); - staffModeData.write(); + if (staffModeExtension != null) staffModeExtension.saveLocation(); } public void loadPreviousLocation() { - Location location = staffModeData.record().enabledLocation(); - if (location == null) return; - player.teleport(location); + if (staffModeExtension != null) staffModeExtension.restoreLocation(); } // // @Override public boolean isStaffChatAsDefault() { - return staffChatAsDefault; + return staffChatAsDefault.get(); } @Override - public void setStaffChatAsDefault(boolean staffChatAsDefault) { - this.staffChatAsDefault = staffChatAsDefault; + public void setStaffChatAsDefault(boolean staffChatAsDefault, boolean saveInDB) { + this.staffChatAsDefault.set(staffChatAsDefault); - staffDataModel = StaffStateModel.builder(staffDataModel) + if (!saveInDB) { + return; + } + + staffDataModel.set(StaffStateModel.builder(staffDataModel.get()) .staffChatEnabled(staffChatAsDefault) - .build(); + .build()); - staffStateRepository.saveOrUpdateModelAsync(staffDataModel) + staffStateRepository.saveOrUpdateModelAsync(staffDataModel.get()) .thenRun(() -> logger.debug("Staff chat state for %s has been set to %s on the database", player.getName(), staffChatAsDefault)); } // @@ -488,12 +368,12 @@ private PotionEffectType getEffect(@NotNull final String effect) { // public void addActionBar() { - if (!staffMode) return; + if (!staffMode.get()) return; if (!config.get().staffMode.actionBar()) return; if (!hasPermission(Permissions.ACTION_BAR_PERMISSION)) return; String vanished = isInVanish() ? messages.get().placeholder.placeholderTrue() : messages.get().placeholder.placeholderFalse(); - String staffChat = staffChatAsDefault ? messages.get().placeholder.placeholderTrue() : messages.get().placeholder.placeholderFalse(); + String staffChat = staffChatAsDefault.get() ? messages.get().placeholder.placeholderTrue() : messages.get().placeholder.placeholderFalse(); double tpsCount = Bukkit.getTPS()[0]; String tps = String.valueOf(tpsCount); tps = tps.substring(0, Math.min(tps.length(), 5)); @@ -530,8 +410,7 @@ public Optional getExtension(Class extens public void addExtensions() { extensionManager.getExtensionsStream().forEach(extension -> { try { - StaffPlayerExtension instance = extension.extension().getConstructor(StaffPlayerWrapper.class).newInstance(this); - injector.injectMembers(instance); + StaffPlayerExtension instance = injector.getInstance(extension.extension()); extensionMap.put(extension.extension(), instance); @@ -544,6 +423,12 @@ public void addExtensions() { }); vanishExtension = getExtension(VanishExtension.class).orElse(null); + staffModeExtension = getExtension(StaffModeExtension.class).orElse(null); } // + + @Override + public @NotNull Map, StaffPlayerExtension> getExtensions() { + return extensionMap; + } } diff --git a/NookureStaff-Paper/src/main/java/com/nookure/staff/paper/bootstrap/StaffPaperPlayerWrapperModule.java b/NookureStaff-Paper/src/main/java/com/nookure/staff/paper/bootstrap/StaffPaperPlayerWrapperModule.java new file mode 100644 index 000000000..60f243aab --- /dev/null +++ b/NookureStaff-Paper/src/main/java/com/nookure/staff/paper/bootstrap/StaffPaperPlayerWrapperModule.java @@ -0,0 +1,64 @@ +package com.nookure.staff.paper.bootstrap; + +import com.google.inject.AbstractModule; +import com.google.inject.TypeLiteral; +import com.nookure.staff.api.StaffPlayerWrapper; +import com.nookure.staff.api.annotation.staff.StaffChatAsDefaultBool; +import com.nookure.staff.api.annotation.staff.StaffModeBool; +import com.nookure.staff.api.database.model.StaffStateModel; +import com.nookure.staff.paper.StaffPaperPlayerWrapper; +import com.nookure.staff.paper.data.ServerStaffModeData; +import org.bukkit.entity.Player; +import org.jetbrains.annotations.NotNull; + +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.atomic.AtomicReference; + +import static java.util.Objects.requireNonNull; + +public final class StaffPaperPlayerWrapperModule extends AbstractModule { + private final StaffPaperPlayerWrapper staffPaperPlayerWrapper; + private final Player player; + private final AtomicReference serverStaffModeData; + private final AtomicReference staffStateModel; + private final AtomicBoolean staffModeEnabled; + private final AtomicBoolean staffChatEnabled; + + public StaffPaperPlayerWrapperModule( + @NotNull final StaffPaperPlayerWrapper staffPaperPlayerWrapper, + @NotNull final AtomicReference serverStaffModeData, + @NotNull final AtomicReference staffStateModel, + @NotNull final AtomicBoolean staffModeEnabled, + @NotNull final AtomicBoolean staffChatEnabled + ) { + requireNonNull(staffPaperPlayerWrapper, "StaffPaperPlayerWrapper cannot be null"); + + this.staffPaperPlayerWrapper = staffPaperPlayerWrapper; + this.player = staffPaperPlayerWrapper.getPlayer(); + this.serverStaffModeData = serverStaffModeData; + this.staffStateModel = staffStateModel; + this.staffModeEnabled = staffModeEnabled; + this.staffChatEnabled = staffChatEnabled; + } + + @Override + protected void configure() { + bind(StaffPaperPlayerWrapper.class).toInstance(staffPaperPlayerWrapper); + bind(StaffPlayerWrapper.class).toInstance(staffPaperPlayerWrapper); + bind(Player.class).toInstance(player); + + bind(AtomicBoolean.class) + .annotatedWith(StaffChatAsDefaultBool.class) + .toInstance(staffChatEnabled); + + bind(AtomicBoolean.class) + .annotatedWith(StaffModeBool.class) + .toInstance(staffModeEnabled); + + bind(new TypeLiteral>() { + }).toInstance(staffStateModel); + + bind(new TypeLiteral>() { + }).toInstance(serverStaffModeData); + } +} diff --git a/NookureStaff-Paper/src/main/java/com/nookure/staff/paper/data/StaffModeData.java b/NookureStaff-Paper/src/main/java/com/nookure/staff/paper/data/ServerStaffModeData.java similarity index 93% rename from NookureStaff-Paper/src/main/java/com/nookure/staff/paper/data/StaffModeData.java rename to NookureStaff-Paper/src/main/java/com/nookure/staff/paper/data/ServerStaffModeData.java index 27b68be5c..02b9e28cd 100644 --- a/NookureStaff-Paper/src/main/java/com/nookure/staff/paper/data/StaffModeData.java +++ b/NookureStaff-Paper/src/main/java/com/nookure/staff/paper/data/ServerStaffModeData.java @@ -16,7 +16,7 @@ import java.nio.file.Path; import java.nio.file.StandardCopyOption; -public class StaffModeData { +public class ServerStaffModeData { //TODO: Pending recode private final NookureStaff plugin; private final StaffModeDataRecord record; private final PlayerWrapper player; @@ -37,7 +37,7 @@ public class StaffModeData { * @param record the staff mode user record * @param player the player */ - private StaffModeData(NookureStaff plugin, StaffModeDataRecord record, PlayerWrapper player) { + private ServerStaffModeData(NookureStaff plugin, StaffModeDataRecord record, PlayerWrapper player) { this.plugin = plugin; this.logger = plugin.getPLogger(); this.record = record; @@ -51,7 +51,7 @@ private StaffModeData(NookureStaff plugin, StaffModeDataRecord record, PlayerWra * @param player the player * @return the staff mode user data container */ - public static StaffModeData read(NookureStaff plugin, PlayerWrapper player) { + public static ServerStaffModeData read(NookureStaff plugin, PlayerWrapper player) { Logger logger = plugin.getPLogger(); logger.debug("Reading staff mode user record for player %s from database", player.getName()); @@ -65,7 +65,7 @@ public static StaffModeData read(NookureStaff plugin, PlayerWrapper player) { if (!(player instanceof PaperPlayerWrapper playerWrapper)) return null; Player bukkitPlayer = playerWrapper.getPlayer(); - return new StaffModeData(plugin, new StaffModeDataRecord( + return new ServerStaffModeData(plugin, new StaffModeDataRecord( bukkitPlayer.getInventory().getContents(), bukkitPlayer.getInventory().getArmorContents(), new ItemStack[0], @@ -89,7 +89,7 @@ record = (StaffModeDataRecord) new PluginObjectInputStream(Files.newInputStream( logger.debug("Read staff mode user record for player %s from database in %dms", player.getName(), System.currentTimeMillis() - start); - return new StaffModeData(plugin, record, player); + return new ServerStaffModeData(plugin, record, player); } public void write() { diff --git a/NookureStaff-Paper/src/main/java/com/nookure/staff/paper/extension/FreezePlayerExtension.java b/NookureStaff-Paper/src/main/java/com/nookure/staff/paper/extension/FreezePlayerExtension.java index b241f4942..32bb19e42 100644 --- a/NookureStaff-Paper/src/main/java/com/nookure/staff/paper/extension/FreezePlayerExtension.java +++ b/NookureStaff-Paper/src/main/java/com/nookure/staff/paper/extension/FreezePlayerExtension.java @@ -20,21 +20,28 @@ public class FreezePlayerExtension extends StaffPlayerExtension { private final StaffPlayerWrapper player; - @Inject - private FreezeManager freezeManager; - @Inject - private ConfigurationContainer config; - @Inject - private ConfigurationContainer messages; - @Inject - private EventMessenger eventMessenger; - @Inject - @PluginMessageMessenger - private EventMessenger pluginMessageManager; + private final FreezeManager freezeManager; + private final ConfigurationContainer config; + private final ConfigurationContainer messages; + private final EventMessenger eventMessenger; + private final EventMessenger pluginMessageManager; - public FreezePlayerExtension(StaffPlayerWrapper player) { + @Inject + public FreezePlayerExtension( + @NotNull final StaffPlayerWrapper player, + @NotNull final FreezeManager freezeManager, + @NotNull final ConfigurationContainer config, + @NotNull final ConfigurationContainer messages, + @NotNull final EventMessenger eventMessenger, + @NotNull @PluginMessageMessenger final EventMessenger pluginMessageManager + ) { super(player); this.player = player; + this.freezeManager = freezeManager; + this.config = config; + this.messages = messages; + this.eventMessenger = eventMessenger; + this.pluginMessageManager = pluginMessageManager; } public void freezePlayer(PlayerWrapper target) { diff --git a/NookureStaff-Paper/src/main/java/com/nookure/staff/paper/extension/staff/PaperStaffModeExtension.java b/NookureStaff-Paper/src/main/java/com/nookure/staff/paper/extension/staff/PaperStaffModeExtension.java new file mode 100644 index 000000000..c42b72e54 --- /dev/null +++ b/NookureStaff-Paper/src/main/java/com/nookure/staff/paper/extension/staff/PaperStaffModeExtension.java @@ -0,0 +1,269 @@ +package com.nookure.staff.paper.extension.staff; + +import com.google.inject.Inject; +import com.nookure.staff.api.Logger; +import com.nookure.staff.api.NookureStaff; +import com.nookure.staff.api.StaffPlayerWrapper; +import com.nookure.staff.api.annotation.staff.StaffChatAsDefaultBool; +import com.nookure.staff.api.annotation.staff.StaffModeBool; +import com.nookure.staff.api.config.ConfigurationContainer; +import com.nookure.staff.api.config.bukkit.BukkitConfig; +import com.nookure.staff.api.config.bukkit.BukkitMessages; +import com.nookure.staff.api.database.model.StaffStateModel; +import com.nookure.staff.api.database.repository.StaffStateRepository; +import com.nookure.staff.api.event.server.BroadcastMessageExcept; +import com.nookure.staff.api.event.staff.StaffModeDisabledEvent; +import com.nookure.staff.api.event.staff.StaffModeEnabledEvent; +import com.nookure.staff.api.extension.StaffPlayerExtension; +import com.nookure.staff.api.extension.staff.StaffModeExtension; +import com.nookure.staff.api.item.StaffItem; +import com.nookure.staff.api.manager.StaffItemsManager; +import com.nookure.staff.api.messaging.EventMessenger; +import com.nookure.staff.paper.StaffPaperPlayerWrapper; +import com.nookure.staff.paper.data.ServerStaffModeData; +import org.bukkit.Location; +import org.bukkit.inventory.ItemStack; +import org.jetbrains.annotations.NotNull; + +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.atomic.AtomicReference; + +public class PaperStaffModeExtension extends StaffModeExtension { + private final EventMessenger eventMessenger; + private final ConfigurationContainer messages; + private final ConfigurationContainer config; + private final Logger logger; + private final StaffStateRepository staffStateRepository; + private final StaffPaperPlayerWrapper player; + private final NookureStaff nookPlugin; + private final AtomicReference serverStaffModeData; + private final AtomicReference staffStateModel; + private final AtomicBoolean staffMode; + private final Map items = new HashMap<>(); + private final StaffItemsManager itemsManager; + + @Inject + public PaperStaffModeExtension( + @NotNull final StaffPlayerWrapper player, + @NotNull final Logger logger, + @NotNull final EventMessenger eventMessenger, + @NotNull final ConfigurationContainer messages, + @NotNull final ConfigurationContainer config, + @NotNull final StaffStateRepository staffStateRepository, + @NotNull final NookureStaff nookPlugin, + @NotNull final AtomicReference serverStaffModeData, + @NotNull final AtomicReference staffStateModel, + @NotNull @StaffChatAsDefaultBool final AtomicBoolean staffChatAsDefault, + @NotNull @StaffModeBool final AtomicBoolean staffMode, + @NotNull final StaffItemsManager itemsManager + ) { + super(player); + this.player = (StaffPaperPlayerWrapper) player; + this.logger = logger; + this.eventMessenger = eventMessenger; + this.messages = messages; + this.config = config; + this.serverStaffModeData = serverStaffModeData; + this.staffStateModel = staffStateModel; + this.nookPlugin = nookPlugin; + this.staffStateRepository = staffStateRepository; + this.staffMode = staffMode; + this.itemsManager = itemsManager; + } + + @Override + public void enableStaffMode(boolean silentJoin) { + long time = System.currentTimeMillis(); + + player.enablePlayerPerks(); + + if (!silentJoin) { + saveLocation(); + saveInventory(); + } + + setItems(); + player.sendMiniMessage(messages.get().staffMode.toggledOn()); + writeStaffModeState(true); + + if (config.get().staffMode.enableVanishOnStaffEnable()) { + player.enableVanish(silentJoin); + player.writeVanishState(true); + } + + eventMessenger.publish(player, new StaffModeEnabledEvent(player.getUniqueId())); + eventMessenger.publish(player, + new BroadcastMessageExcept(messages.get().staffMode.toggledOnOthers() + .replace("{player}", player.getName()), + player.getUniqueId() + ) + ); + + try { + player.getExtensions().values().forEach(StaffPlayerExtension::onStaffModeEnabled); + } catch (Exception e) { + logger.severe("An error occurred while enabling staff mode for %s: %s", player.getName(), e.getMessage()); + } + + logger.debug("Staff mode enabled for %s in %dms", player.getName(), System.currentTimeMillis() - time); + } + + @Override + public void disableStaffMode() { + long time = System.currentTimeMillis(); + player.disablePlayerPerks(); + restoreInventory(); + if (config.get().staffMode.teleportToPreviousLocation()) restoreInventory(); + player.sendMiniMessage(messages.get().staffMode.toggledOff()); + writeStaffModeState(false); + + if (config.get().staffMode.disableVanishOnStaffDisable()) { + player.disableVanish(false); + player.writeVanishState(false); + } + + eventMessenger.publish(player, new StaffModeDisabledEvent(player.getUniqueId())); + eventMessenger.publish(player, new BroadcastMessageExcept(messages.get().staffMode.toggledOffOthers() + .replace("{player}", player.getName()), + player.getUniqueId()) + ); + + try { + player.getExtensions().values().forEach(StaffPlayerExtension::onStaffModeDisabled); + } catch (Exception e) { + logger.severe("An error occurred while enabling staff mode for %s: %s", player.getName(), e.getMessage()); + } + + logger.debug("Staff mode disabled for %s in %dms", player.getName(), System.currentTimeMillis() - time); + } + + @Override + public void checkStaffMode() { + if (serverStaffModeData.get() == null) { + serverStaffModeData.set(ServerStaffModeData.read(nookPlugin, player)); + } + + if (staffStateModel.get() == null) { + logger.severe("StaffModeData is null for %s", player.getName()); + return; + } + + if (serverStaffModeData.get().record().staffMode()) { + clearInventory(); + enableStaffMode(true); + } + + if (staffStateModel.get().staffMode()) { + if (!player.isInStaffMode()) { + saveInventory(); + saveLocation(); + enableStaffMode(true); + } + } + + logger.debug("StaffDataModel state: %s", staffStateModel.get()); + player.setStaffChatAsDefault(staffStateModel.get().staffChatEnabled()); + } + + @Override + public void writeStaffModeState(boolean state) { + staffStateRepository.fromUUIDAsync(player.getUniqueId()) + .thenAccept((model) -> { + if (model == null) { + return; + } + + staffStateModel.set(StaffStateModel.builder(model) + .staffMode(state) + .build()); + + staffStateRepository.saveOrUpdateModel(staffStateModel.get()); + logger.debug("Staff mode state for %s has been set to %s on the database", player.getName(), state); + }); + + serverStaffModeData.get().record().staffMode(state); + serverStaffModeData.get().write(); + + staffMode.set(state); + } + + @Override + public void toggleStaffMode(boolean silentJoin) { + if (!staffMode.get()) enableStaffMode(silentJoin); + else disableStaffMode(); + } + + @Override + public boolean isStaffMode() { + return staffMode.get(); + } + + @Override + public void setItems() { + if (items.isEmpty()) { + itemsManager.getItems().forEach((identifier, item) -> { + if (item.getPermission() != null && !player.hasPermission(item.getPermission())) return; + + items.put(item.getSlot(), item); + }); + } + + items.forEach((identifier, item) -> item.setItem(player.getPlayer())); + } + + @Override + public @NotNull Map getItems() { + return items; + } + + @Override + public void saveInventory() { + if (serverStaffModeData.get() == null) { + serverStaffModeData.set(ServerStaffModeData.read(nookPlugin, player)); + } + + assert serverStaffModeData.get() != null; + + serverStaffModeData.get().record().playerInventory(player.getPlayer().getInventory().getContents()); + serverStaffModeData.get().record().playerInventoryArmor(player.getPlayer().getInventory().getArmorContents()); + + serverStaffModeData.get().write(); + + clearInventory(); + } + + @Override + public void clearInventory() { + player.getPlayer().getInventory().clear(); + player.getPlayer().getInventory().setArmorContents(new ItemStack[0]); + } + + @Override + public void restoreInventory() { + if (serverStaffModeData.get() == null) { + serverStaffModeData.set(ServerStaffModeData.read(nookPlugin, player)); + } + + assert serverStaffModeData.get() != null; + + player.getPlayer().getInventory().setContents(serverStaffModeData.get().record().playerInventory()); + player.getPlayer().getInventory().setArmorContents(serverStaffModeData.get().record().playerInventoryArmor()); + + serverStaffModeData.get().write(); + } + + @Override + public void saveLocation() { + serverStaffModeData.get().record().enabledLocation(player.getPlayer().getLocation()); + serverStaffModeData.get().write(); + } + + @Override + public void restoreLocation() { + Location location = serverStaffModeData.get().record().enabledLocation(); + if (location == null) return; + player.getPlayer().teleport(location); + } +} diff --git a/NookureStaff-Paper/src/main/java/com/nookure/staff/paper/extension/vanish/InternalVanishExtension.java b/NookureStaff-Paper/src/main/java/com/nookure/staff/paper/extension/vanish/InternalVanishExtension.java index 4a7680182..619bb70d9 100644 --- a/NookureStaff-Paper/src/main/java/com/nookure/staff/paper/extension/vanish/InternalVanishExtension.java +++ b/NookureStaff-Paper/src/main/java/com/nookure/staff/paper/extension/vanish/InternalVanishExtension.java @@ -12,23 +12,30 @@ import org.bukkit.Bukkit; import org.bukkit.entity.Player; import org.bukkit.plugin.java.JavaPlugin; +import org.jetbrains.annotations.NotNull; public class InternalVanishExtension extends VanishExtension { private final StaffPaperPlayerWrapper player; - @Inject - private Logger logger; - @Inject - private ConfigurationContainer messages; - @Inject - private PlayerWrapperManager playerWrapperManager; - @Inject - private JavaPlugin javaPlugin; - + private final Logger logger; + private final ConfigurationContainer messages; + private final PlayerWrapperManager playerWrapperManager; + private final JavaPlugin javaPlugin; private boolean vanished = false; - public InternalVanishExtension(StaffPlayerWrapper player) { + @Inject + public InternalVanishExtension( + @NotNull final StaffPlayerWrapper player, + @NotNull final Logger logger, + @NotNull final ConfigurationContainer messages, + @NotNull final PlayerWrapperManager playerWrapperManager, + @NotNull final JavaPlugin javaPlugin + ) { super(player); this.player = (StaffPaperPlayerWrapper) player; + this.logger = logger; + this.messages = messages; + this.playerWrapperManager = playerWrapperManager; + this.javaPlugin = javaPlugin; } @Override diff --git a/NookureStaff-Paper/src/main/java/com/nookure/staff/paper/extension/vanish/SuperVanishExtension.java b/NookureStaff-Paper/src/main/java/com/nookure/staff/paper/extension/vanish/SuperVanishExtension.java index 4e413da98..213b25243 100644 --- a/NookureStaff-Paper/src/main/java/com/nookure/staff/paper/extension/vanish/SuperVanishExtension.java +++ b/NookureStaff-Paper/src/main/java/com/nookure/staff/paper/extension/vanish/SuperVanishExtension.java @@ -1,14 +1,17 @@ package com.nookure.staff.paper.extension.vanish; +import com.google.inject.Inject; import com.nookure.staff.api.StaffPlayerWrapper; import com.nookure.staff.api.extension.VanishExtension; import com.nookure.staff.paper.StaffPaperPlayerWrapper; import de.myzelyam.api.vanish.VanishAPI; +import org.jetbrains.annotations.NotNull; public class SuperVanishExtension extends VanishExtension { private final StaffPaperPlayerWrapper player; - public SuperVanishExtension(StaffPlayerWrapper player) { + @Inject + public SuperVanishExtension(@NotNull final StaffPlayerWrapper player) { super(player); this.player = (StaffPaperPlayerWrapper) player; }