Class ChestOpener

java.lang.Object
com.enhancedechest.service.ChestOpener

public final class ChestOpener extends Object
Decides what to open for /ec, /eclist, right-click and the admin /ee view, and orchestrates the management dialogs. The actual attach-to-shared-session work is delegated to ChestSessionManager.open(org.bukkit.entity.Player, java.util.UUID, int, org.bukkit.Location) (the single dupe-safe funnel); this class is the GUI-flow layer on top of it.

Open routing for /ec / right-click (open(org.bukkit.entity.Player, org.bukkit.Location)):

  • 0 or 1 normal chest and no temp chest — opens that chest directly (creating chest #1 if the player owns none);
  • 2+ normal chests, no temp chest, an explicit main is set and the player may use it — opens the main directly;
  • otherwise — opens the management list dialog so the player picks (or sets a main).
A main is never auto-assigned at creation, so a multi-chest player who has not chosen one always lands on the management dialog. /eclist always reaches the dialog regardless.
  • Constructor Summary

    Constructors
    Constructor
    Description
    ChestOpener(ChestSessionManager sessions, StorageGateway storageGateway, PlayerSettingsCache settings, EnderChestStorage storage, DbExecutor db, LanguageManager lang, Scheduler scheduler, org.slf4j.Logger logger, int defaultSize, PermissionChestService permService, ChestSpillService spillService, PluginConfig config, DatabaseImportService importService, Telemetry telemetry)
     
  • Method Summary

    Modifier and Type
    Method
    Description
    void
    adminClear(org.bukkit.entity.Player admin, String targetName, UUID target, int index)
    Empties the target's chest (admin "Clear chest" action), re-checking the permission, then returns the admin to the detail dialog with a confirmation message.
    void
    adminOpen(org.bukkit.entity.Player admin, UUID owner, int index)
    Opens another player's chest for an admin, sharing the live session.
    void
    Drops a player's sort-cooldown entry, called on quit so the lastSortAt map stays bounded by the online-player count (it holds one timestamp per player who has sorted, and entries never expire on their own).
    void
    open(org.bukkit.entity.Player player, @Nullable org.bukkit.Location sourceBlock)
    Default open entry point for /enderchest and right-click: 0 or 1 normal chest and no temp chest — opens that chest directly (creating chest #1 if the player owns none); 2+ normal chests, no temp chest, an explicit main is set and the player may use it — opens the main directly; otherwise — opens the management list dialog so the player picks (or sets a main).
    void
    openAdminClearConfirm(org.bukkit.entity.Player admin, String targetName, UUID target, int index)
    Shows the "are you sure?" confirmation before an admin clears a chest (guards the destructive wipe).
    void
    openAdminDetail(org.bukkit.entity.Player admin, String targetName, UUID target, int index)
    Shows the per-chest detail dialog for the target's chest, in an admin context: same menu the owner sees, but mutations target the owner's chest.
    void
    openAdminViewList(org.bukkit.entity.Player admin, String targetName, UUID target)
    Reloads the target's chests and shows the admin view-list dialog (used for Back from a detail dialog).
    void
    openByQuery(org.bukkit.entity.Player player, String query)
    Opens a chest selected by a free-text query from /ec <chest>: #N (or a bare positive integer) opens the chest with that index; anything else is matched case-insensitively against players' custom chest names. A miss reports chest.not-found rather than silently opening the primary chest.
    void
    openChest(org.bukkit.entity.Player player, int index, @Nullable org.bukkit.Location sourceBlock)
    Opens a specific chest by index (from the management dialog), sharing the live session.
    void
    openDetailDialog(org.bukkit.entity.Player player, int index)
    Shows the per-chest detail dialog for the player's own chest (Open / Rename / Icon / Sort / Set-main / Back).
    void
    openDetailDialog(org.bukkit.entity.Player viewer, ChestDialogs.DetailContext ctx, int index)
    Re-shows the detail dialog in an explicit context (own or admin), reloading the chest first.
    void
    openListDialog(org.bukkit.entity.Player player)
    Loads the player's chests and shows the /eclist management dialog, seeding edit mode from their saved preference.
    void
    openListDialog(org.bukkit.entity.Player player, boolean editInitial, @Nullable org.bukkit.Location sourceBlock)
    Loads the player's chests and shows the management dialog with the edit-mode checkbox in the given starting state.
    void
    openListDialog(org.bukkit.entity.Player player, @Nullable org.bukkit.Location sourceBlock)
    Same as openListDialog(Player), but remembers the ender chest block the list was opened from (shift + right-click) so a chest picked from it still animates that block's lid.
    void
    openRenameDialog(org.bukkit.entity.Player player, int index)
    Shows the dedicated rename dialog for the player's own chest.
    void
    performImport(org.bukkit.entity.Player admin, SourceSpec spec)
    Validates the submitted source connection form, runs the pre-flight guards, and — if they pass — copies the source database into the active backend off the region thread, reporting the result.
    void
    runForPlayer(org.bukkit.entity.Player player, Runnable action)
    Runs the given action on the player's entity thread (helper for command/dialog callbacks).
    void
    setDefaultSize(int defaultSize)
    Re-applies the runtime-tunable default chest size after a /ee reload.
    void
    showAdminViewList(org.bukkit.entity.Player admin, String targetName, UUID target, List<ChestSummary> chests)
    Shows the admin "view another player's chests" list dialog.
    void
    showImportDialog(org.bukkit.entity.Player admin)
    Shows the DB→DB import dialog (source connection form) to the admin.
    void
    sortChest(org.bukkit.entity.Player viewer, ChestDialogs.DetailContext ctx, int index)
    Sorts a chest's contents (the Sort button), then re-shows the detail dialog.

    Methods inherited from class java.lang.Object

    clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
  • Constructor Details

  • Method Details

    • setDefaultSize

      public void setDefaultSize(int defaultSize)
      Re-applies the runtime-tunable default chest size after a /ee reload. Read only when bootstrapping a brand-new chest, so it is dupe-safe to set on the main thread while async storage work is pending.
    • open

      public void open(org.bukkit.entity.Player player, @Nullable @Nullable org.bukkit.Location sourceBlock)
      Default open entry point for /enderchest and right-click:
      • 0 or 1 normal chest and no temp chest — opens that chest directly (creating chest #1 if the player owns none);
      • 2+ normal chests, no temp chest, an explicit main is set and the player may use it — opens the main directly;
      • otherwise — opens the management list dialog so the player picks (or sets a main).

      A main is never auto-assigned at creation, so a multi-chest player who has not chosen one always lands on the management dialog. Setting a main returns them to the open-directly path. Players without the open-by-command permission can never have an effective main, so with 2+ chests they always get the dialog. Any TEMP (overflow) chest also forces the dialog, since spilled items can only be retrieved from the list. /eclist still reaches the dialog regardless.

      Parameters:
      sourceBlock - ender chest block location if opened via right-click; null for command/dialog
    • openByQuery

      public void openByQuery(org.bukkit.entity.Player player, String query)
      Opens a chest selected by a free-text query from /ec <chest>:
      • #N (or a bare positive integer) opens the chest with that index;
      • anything else is matched case-insensitively against players' custom chest names.
      A miss reports chest.not-found rather than silently opening the primary chest.
    • openChest

      public void openChest(org.bukkit.entity.Player player, int index, @Nullable @Nullable org.bukkit.Location sourceBlock)
      Opens a specific chest by index (from the management dialog), sharing the live session.
    • adminOpen

      public void adminOpen(org.bukkit.entity.Player admin, UUID owner, int index)
      Opens another player's chest for an admin, sharing the live session. The admin becomes a viewer of the same inventory the owner sees (concurrent edit on Paper; exclusive on Folia). Read-only vs editable is enforced per-click in the GUI listener via the admin's permissions, so this method itself simply joins the session.
    • openListDialog

      public void openListDialog(org.bukkit.entity.Player player)
      Loads the player's chests and shows the /eclist management dialog, seeding edit mode from their saved preference.
    • openListDialog

      public void openListDialog(org.bukkit.entity.Player player, @Nullable @Nullable org.bukkit.Location sourceBlock)
      Same as openListDialog(Player), but remembers the ender chest block the list was opened from (shift + right-click) so a chest picked from it still animates that block's lid.
      Parameters:
      sourceBlock - ender chest block location, or null when opened by command
    • openListDialog

      public void openListDialog(org.bukkit.entity.Player player, boolean editInitial, @Nullable @Nullable org.bukkit.Location sourceBlock)
      Loads the player's chests and shows the management dialog with the edit-mode checkbox in the given starting state. Fresh opens seed it from the player's saved preference (see the no-arg overload and open(org.bukkit.entity.Player, org.bukkit.Location)); returning from a detail dialog's Back seeds it on so the player stays in edit mode. The checkbox itself toggles client-side without re-showing.
      Parameters:
      editInitial - starting state of the dialog's edit-mode checkbox
      sourceBlock - ender chest block this menu was opened from (threaded through so direct opens still animate), or null when opened by command
    • showAdminViewList

      public void showAdminViewList(org.bukkit.entity.Player admin, String targetName, UUID target, List<ChestSummary> chests)
      Shows the admin "view another player's chests" list dialog. Each button opens the target's chest for the admin via the shared session (adminOpen(org.bukkit.entity.Player, java.util.UUID, int)) — no edit-mode/rename/set-main. The chests are passed in already loaded (the command lists them to route 0/1/2+), so this only builds and pushes the dialog on the admin's entity thread.
    • openAdminViewList

      public void openAdminViewList(org.bukkit.entity.Player admin, String targetName, UUID target)
      Reloads the target's chests and shows the admin view-list dialog (used for Back from a detail dialog).
    • openAdminDetail

      public void openAdminDetail(org.bukkit.entity.Player admin, String targetName, UUID target, int index)
      Shows the per-chest detail dialog for the target's chest, in an admin context: same menu the owner sees, but mutations target the owner's chest. The appearance edits (rename / icon / sort) are built only when the admin holds enhancedechest.admin.edit; the Clear button only when they hold enhancedechest.admin.clear — so a view-only admin gets just Open / Back. Reachable from /ee view and the admin view-list dialog.
    • openAdminClearConfirm

      public void openAdminClearConfirm(org.bukkit.entity.Player admin, String targetName, UUID target, int index)
      Shows the "are you sure?" confirmation before an admin clears a chest (guards the destructive wipe).
    • adminClear

      public void adminClear(org.bukkit.entity.Player admin, String targetName, UUID target, int index)
      Empties the target's chest (admin "Clear chest" action), re-checking the permission, then returns the admin to the detail dialog with a confirmation message. Dupe-safe: the clear force-closes every viewer and runs exclusively (see ChestSpillService.clearChest(java.util.UUID, int)).
    • openDetailDialog

      public void openDetailDialog(org.bukkit.entity.Player player, int index)
      Shows the per-chest detail dialog for the player's own chest (Open / Rename / Icon / Sort / Set-main / Back).
    • openDetailDialog

      public void openDetailDialog(org.bukkit.entity.Player viewer, ChestDialogs.DetailContext ctx, int index)
      Re-shows the detail dialog in an explicit context (own or admin), reloading the chest first. Used by the dialog callbacks (rename / icon / sort / set-main) to refresh after a mutation, so an admin's refresh stays an admin dialog and the owner's stays an owner dialog.
    • sortChest

      public void sortChest(org.bukkit.entity.Player viewer, ChestDialogs.DetailContext ctx, int index)
      Sorts a chest's contents (the Sort button), then re-shows the detail dialog. Per-player rate-limited by enderchest.features.sort-cooldown: a sort while still on cooldown is rejected with a chat notice and does no work, so the button can't be spammed (each sort re-reads and re-writes the chest). The cooldown is keyed on the clicking viewer, so an admin sorting players' chests is limited too.
    • clearSortCooldown

      public void clearSortCooldown(UUID playerId)
      Drops a player's sort-cooldown entry, called on quit so the lastSortAt map stays bounded by the online-player count (it holds one timestamp per player who has sorted, and entries never expire on their own). Idempotent — a no-op for a player who never sorted.
    • openRenameDialog

      public void openRenameDialog(org.bukkit.entity.Player player, int index)
      Shows the dedicated rename dialog for the player's own chest.
    • runForPlayer

      public void runForPlayer(org.bukkit.entity.Player player, Runnable action)
      Runs the given action on the player's entity thread (helper for command/dialog callbacks).
    • showImportDialog

      public void showImportDialog(org.bukkit.entity.Player admin)
      Shows the DB→DB import dialog (source connection form) to the admin.
    • performImport

      public void performImport(org.bukkit.entity.Player admin, SourceSpec spec)
      Validates the submitted source connection form, runs the pre-flight guards, and — if they pass — copies the source database into the active backend off the region thread, reporting the result.

      Guards: (1) the form must be complete for its chosen type; (2) no player other than the running admin may be online (the copy assumes a quiet server); (3) the source must not be the active destination; (4) the destination must be empty (import only into a fresh DB — checked on the DB executor). All user-facing text goes through LanguageManager.