[Idea]: Folia support for OpenInv #196
@@ -70,51 +70,114 @@ public class OpenInv extends JavaPlugin implements IOpenInv {
|
|||||||
private boolean isSpigot = false;
|
private boolean isSpigot = false;
|
||||||
private OfflineHandler offlineHandler;
|
private OfflineHandler offlineHandler;
|
||||||
|
|
||||||
/**
|
@Override
|
||||||
* Evict all viewers lacking cross-world permissions from a Player's inventory.
|
public void reloadConfig() {
|
||||||
*
|
super.reloadConfig();
|
||||||
* @param player the Player
|
this.offlineHandler = disableOfflineAccess() ? OfflineHandler.REMOVE_AND_CLOSE : OfflineHandler.REQUIRE_PERMISSIONS;
|
||||||
*/
|
|
||||||
void changeWorld(@NotNull Player player) {
|
|
||||||
UUID key = player.getUniqueId();
|
|
||||||
|
|
||||||
if (this.inventories.containsKey(key)) {
|
|
||||||
kickCrossWorldViewers(player, this.inventories.get(key));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.enderChests.containsKey(key)) {
|
|
||||||
kickCrossWorldViewers(player, this.enderChests.get(key));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void kickCrossWorldViewers(@NotNull Player player, @NotNull ISpecialInventory inventory) {
|
@Override
|
||||||
ejectViewers(
|
public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) {
|
||||||
inventory,
|
if (!isSpigot || !this.accessor.isSupported()) {
|
||||||
viewer ->
|
this.sendVersionError(sender::sendMessage);
|
||||||
!Permissions.CROSSWORLD.hasPermission(viewer)
|
return true;
|
||||||
&& Objects.equals(viewer.getWorld(), player.getWorld()));
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ejectViewers(@NotNull ISpecialInventory inventory, Predicate<HumanEntity> predicate) {
|
@Override
|
||||||
for (HumanEntity viewer : new ArrayList<>(inventory.getBukkitInventory().getViewers())) {
|
public void onDisable() {
|
||||||
if (predicate.test(viewer)) {
|
if (this.disableSaving()) {
|
||||||
viewer.closeInventory();
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Stream.concat(inventories.values().stream(), enderChests.values().stream())
|
||||||
|
.map(inventory -> {
|
||||||
|
// Cheat a bit - rather than stream twice, evict all viewers during remapping.
|
||||||
|
ejectViewers(inventory, viewer -> true);
|
||||||
|
if (inventory.getPlayer() instanceof Player player) {
|
||||||
|
return player;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
})
|
||||||
|
.filter(Objects::nonNull)
|
||||||
|
.distinct()
|
||||||
|
.forEach(player -> {
|
||||||
|
if (!player.isOnline()) {
|
||||||
|
player = accessor.getPlayerDataManager().inject(player);
|
||||||
|
}
|
||||||
|
player.saveData();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onEnable() {
|
||||||
|
// Save default configuration if not present.
|
||||||
|
this.saveDefaultConfig();
|
||||||
|
|
||||||
|
// Get plugin manager
|
||||||
|
PluginManager pm = this.getServer().getPluginManager();
|
||||||
|
|
||||||
|
this.accessor = new InternalAccessor(this);
|
||||||
|
|
||||||
|
this.languageManager = new LanguageManager(this, "en_us");
|
||||||
|
this.offlineHandler = disableOfflineAccess() ? OfflineHandler.REMOVE_AND_CLOSE : OfflineHandler.REQUIRE_PERMISSIONS;
|
||||||
|
|
||||||
|
try {
|
||||||
|
Class.forName("org.bukkit.entity.Player$Spigot");
|
||||||
|
isSpigot = true;
|
||||||
|
} catch (ClassNotFoundException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
isSpigot = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Version check
|
||||||
|
if (isSpigot && this.accessor.isSupported()) {
|
||||||
|
// Update existing configuration. May require internal access.
|
||||||
|
new ConfigUpdater(this).checkForUpdates();
|
||||||
|
|
||||||
|
// Register listeners
|
||||||
|
pm.registerEvents(new PlayerListener(this), this);
|
||||||
|
pm.registerEvents(new InventoryListener(this), this);
|
||||||
|
|
||||||
|
// Register commands to their executors
|
||||||
|
this.setCommandExecutor(new OpenInvCommand(this), "openinv", "openender");
|
||||||
|
this.setCommandExecutor(new SearchContainerCommand(this), "searchcontainer");
|
||||||
|
this.setCommandExecutor(new SearchInvCommand(this), "searchinv", "searchender");
|
||||||
|
this.setCommandExecutor(new SearchEnchantCommand(this), "searchenchant");
|
||||||
|
this.setCommandExecutor(new ContainerSettingCommand(this), "silentcontainer", "anycontainer");
|
||||||
|
|
||||||
|
} else {
|
||||||
|
this.sendVersionError(this.getLogger()::warning);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setCommandExecutor(@NotNull CommandExecutor executor, String @NotNull ... commands) {
|
||||||
|
for (String commandName : commands) {
|
||||||
|
PluginCommand command = this.getCommand(commandName);
|
||||||
|
if (command != null) {
|
||||||
|
command.setExecutor(executor);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
private void sendVersionError(@NotNull Consumer<String> messageMethod) {
|
||||||
* Convert a raw slot number into a player inventory slot number.
|
if (!this.accessor.isSupported()) {
|
||||||
*
|
messageMethod.accept("Your server version (" + this.accessor.getVersion() + ") is not supported.");
|
||||||
* <p>Note that this method is specifically for converting an ISpecialPlayerInventory slot number into a regular
|
messageMethod.accept("Please download the correct version of OpenInv here: " + this.accessor.getReleasesLink());
|
||||||
* player inventory slot number.
|
}
|
||||||
*
|
if (!isSpigot) {
|
||||||
* @param view the open inventory view
|
messageMethod.accept("OpenInv requires that you use Spigot or a Spigot fork. Per the 1.14 update thread");
|
||||||
* @param rawSlot the raw slot in the view
|
messageMethod.accept("(https://www.spigotmc.org/threads/369724/ \"A Note on CraftBukkit\"), if you are");
|
||||||
* @return the converted slot number
|
messageMethod.accept("encountering an inconsistency with vanilla that prevents you from using Spigot,");
|
||||||
*/
|
messageMethod.accept("that is considered a Spigot bug and should be reported as such.");
|
||||||
int convertToPlayerSlot(InventoryView view, int rawSlot) {
|
}
|
||||||
return this.accessor.getPlayerDataManager().convertToPlayerSlot(view, rawSlot);
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isSupportedVersion() {
|
||||||
|
return this.accessor != null && this.accessor.isSupported();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -146,6 +209,12 @@ public class OpenInv extends JavaPlugin implements IOpenInv {
|
|||||||
return this.getConfig().getBoolean("toggles.any-chest." + offline.getUniqueId(), defaultState);
|
return this.getConfig().getBoolean("toggles.any-chest." + offline.getUniqueId(), defaultState);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setAnyContainerStatus(@NotNull final OfflinePlayer offline, final boolean status) {
|
||||||
|
this.getConfig().set("toggles.any-chest." + offline.getUniqueId(), status);
|
||||||
|
this.saveConfig();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean getSilentContainerStatus(@NotNull final OfflinePlayer offline) {
|
public boolean getSilentContainerStatus(@NotNull final OfflinePlayer offline) {
|
||||||
boolean defaultState = false;
|
boolean defaultState = false;
|
||||||
@@ -160,6 +229,12 @@ public class OpenInv extends JavaPlugin implements IOpenInv {
|
|||||||
return this.getConfig().getBoolean("toggles.silent-chest." + offline.getUniqueId(), defaultState);
|
return this.getConfig().getBoolean("toggles.silent-chest." + offline.getUniqueId(), defaultState);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setSilentContainerStatus(@NotNull final OfflinePlayer offline, final boolean status) {
|
||||||
|
this.getConfig().set("toggles.silent-chest." + offline.getUniqueId(), status);
|
||||||
|
this.saveConfig();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public @NotNull ISpecialEnderChest getSpecialEnderChest(@NotNull final Player player, final boolean online)
|
public @NotNull ISpecialEnderChest getSpecialEnderChest(@NotNull final Player player, final boolean online)
|
||||||
throws InstantiationException {
|
throws InstantiationException {
|
||||||
@@ -189,8 +264,8 @@ public class OpenInv extends JavaPlugin implements IOpenInv {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isSupportedVersion() {
|
public @Nullable InventoryView openInventory(@NotNull Player player, @NotNull ISpecialInventory inventory) {
|
||||||
return this.accessor != null && this.accessor.isSupported();
|
return this.accessor.getPlayerDataManager().openInventory(player, inventory);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -237,20 +312,78 @@ public class OpenInv extends JavaPlugin implements IOpenInv {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public @Nullable InventoryView openInventory(@NotNull Player player, @NotNull ISpecialInventory inventory) {
|
public void unload(@NotNull final OfflinePlayer offline) {
|
||||||
return this.accessor.getPlayerDataManager().openInventory(player, inventory);
|
setPlayerOffline(offline, OfflineHandler.REMOVE_AND_CLOSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Evict all viewers lacking cross-world permissions when a {@link Player} changes worlds.
|
||||||
|
*
|
||||||
|
* @param player the Player
|
||||||
|
*/
|
||||||
|
void changeWorld(@NotNull Player player) {
|
||||||
|
UUID key = player.getUniqueId();
|
||||||
|
|
||||||
|
if (this.inventories.containsKey(key)) {
|
||||||
|
kickCrossWorldViewers(player, this.inventories.get(key));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.enderChests.containsKey(key)) {
|
||||||
|
kickCrossWorldViewers(player, this.enderChests.get(key));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void kickCrossWorldViewers(@NotNull Player player, @NotNull ISpecialInventory inventory) {
|
||||||
|
ejectViewers(
|
||||||
|
inventory,
|
||||||
|
viewer ->
|
||||||
|
!Permissions.CROSSWORLD.hasPermission(viewer)
|
||||||
|
&& Objects.equals(viewer.getWorld(), player.getWorld()));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert a raw slot number into a player inventory slot number.
|
||||||
|
*
|
||||||
|
* <p>Note that this method is specifically for converting an ISpecialPlayerInventory slot number into a regular
|
||||||
|
* player inventory slot number.
|
||||||
|
*
|
||||||
|
* @param view the open inventory view
|
||||||
|
* @param rawSlot the raw slot in the view
|
||||||
|
* @return the converted slot number
|
||||||
|
*/
|
||||||
|
int convertToPlayerSlot(InventoryView view, int rawSlot) {
|
||||||
|
return this.accessor.getPlayerDataManager().convertToPlayerSlot(view, rawSlot);
|
||||||
|
}
|
||||||
|
|
||||||
|
public @Nullable String getLocalizedMessage(@NotNull CommandSender sender, @NotNull String key) {
|
||||||
|
return this.languageManager.getValue(key, getLocale(sender));
|
||||||
|
}
|
||||||
|
|
||||||
|
public @Nullable String getLocalizedMessage(
|
||||||
|
@NotNull CommandSender sender,
|
||||||
|
@NotNull String key,
|
||||||
|
String @NotNull ... replacements) {
|
||||||
|
return this.languageManager.getValue(key, getLocale(sender), replacements);
|
||||||
|
}
|
||||||
|
|
||||||
|
private @NotNull String getLocale(@NotNull CommandSender sender) {
|
||||||
|
if (sender instanceof Player) {
|
||||||
|
return ((Player) sender).getLocale();
|
||||||
|
} else {
|
||||||
|
return this.getConfig().getString("settings.locale", "en_us");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void sendMessage(@NotNull CommandSender sender, @NotNull String key) {
|
public void sendMessage(@NotNull CommandSender sender, @NotNull String key) {
|
||||||
String message = this.languageManager.getValue(key, getLocale(sender));
|
String message = getLocalizedMessage(sender, key);
|
||||||
|
|
||||||
if (message != null && !message.isEmpty()) {
|
if (message != null && !message.isEmpty()) {
|
||||||
sender.sendMessage(message);
|
sender.sendMessage(message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void sendMessage(@NotNull CommandSender sender, @NotNull String key, String... replacements) {
|
public void sendMessage(@NotNull CommandSender sender, @NotNull String key, String @NotNull... replacements) {
|
||||||
String message = this.languageManager.getValue(key, getLocale(sender), replacements);
|
String message = getLocalizedMessage(sender, key, replacements);
|
||||||
|
|
||||||
if (message != null && !message.isEmpty()) {
|
if (message != null && !message.isEmpty()) {
|
||||||
sender.sendMessage(message);
|
sender.sendMessage(message);
|
||||||
@@ -258,7 +391,7 @@ public class OpenInv extends JavaPlugin implements IOpenInv {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void sendSystemMessage(@NotNull Player player, @NotNull String key) {
|
public void sendSystemMessage(@NotNull Player player, @NotNull String key) {
|
||||||
String message = this.languageManager.getValue(key, getLocale(player));
|
String message = getLocalizedMessage(player, key);
|
||||||
|
|
||||||
if (message == null) {
|
if (message == null) {
|
||||||
return;
|
return;
|
||||||
@@ -277,135 +410,6 @@ public class OpenInv extends JavaPlugin implements IOpenInv {
|
|||||||
player.spigot().sendMessage(ChatMessageType.ACTION_BAR, TextComponent.fromLegacyText(message));
|
player.spigot().sendMessage(ChatMessageType.ACTION_BAR, TextComponent.fromLegacyText(message));
|
||||||
}
|
}
|
||||||
|
|
||||||
public @Nullable String getLocalizedMessage(@NotNull CommandSender sender, @NotNull String key) {
|
|
||||||
return this.languageManager.getValue(key, getLocale(sender));
|
|
||||||
}
|
|
||||||
|
|
||||||
public @Nullable String getLocalizedMessage(@NotNull CommandSender sender, @NotNull String key, String... replacements) {
|
|
||||||
return this.languageManager.getValue(key, getLocale(sender), replacements);
|
|
||||||
}
|
|
||||||
|
|
||||||
private @NotNull String getLocale(@NotNull CommandSender sender) {
|
|
||||||
if (sender instanceof Player) {
|
|
||||||
return ((Player) sender).getLocale();
|
|
||||||
} else {
|
|
||||||
return this.getConfig().getString("settings.locale", "en_us");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onDisable() {
|
|
||||||
|
|
||||||
if (this.disableSaving()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Stream.concat(inventories.values().stream(), enderChests.values().stream())
|
|
||||||
.map(inventory -> {
|
|
||||||
// Cheat a bit - rather than stream twice, evict all viewers during remapping.
|
|
||||||
ejectViewers(inventory, viewer -> true);
|
|
||||||
if (inventory.getPlayer() instanceof Player player) {
|
|
||||||
return player;
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
})
|
|
||||||
.filter(Objects::nonNull)
|
|
||||||
.distinct()
|
|
||||||
.forEach(player -> {
|
|
||||||
if (!player.isOnline()) {
|
|
||||||
player = accessor.getPlayerDataManager().inject(player);
|
|
||||||
}
|
|
||||||
player.saveData();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onEnable() {
|
|
||||||
|
|
||||||
// Save default configuration if not present.
|
|
||||||
this.saveDefaultConfig();
|
|
||||||
|
|
||||||
// Get plugin manager
|
|
||||||
PluginManager pm = this.getServer().getPluginManager();
|
|
||||||
|
|
||||||
this.accessor = new InternalAccessor(this);
|
|
||||||
|
|
||||||
this.languageManager = new LanguageManager(this, "en_us");
|
|
||||||
this.offlineHandler = disableOfflineAccess() ? OfflineHandler.REMOVE_AND_CLOSE : OfflineHandler.REQUIRE_PERMISSIONS;
|
|
||||||
|
|
||||||
try {
|
|
||||||
Class.forName("org.bukkit.entity.Player$Spigot");
|
|
||||||
isSpigot = true;
|
|
||||||
} catch (ClassNotFoundException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
isSpigot = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Version check
|
|
||||||
if (isSpigot && this.accessor.isSupported()) {
|
|
||||||
// Update existing configuration. May require internal access.
|
|
||||||
new ConfigUpdater(this).checkForUpdates();
|
|
||||||
|
|
||||||
// Register listeners
|
|
||||||
pm.registerEvents(new PlayerListener(this), this);
|
|
||||||
pm.registerEvents(new InventoryListener(this), this);
|
|
||||||
|
|
||||||
// Register commands to their executors
|
|
||||||
this.setCommandExecutor(new OpenInvCommand(this), "openinv", "openender");
|
|
||||||
this.setCommandExecutor(new SearchContainerCommand(this), "searchcontainer");
|
|
||||||
this.setCommandExecutor(new SearchInvCommand(this), "searchinv", "searchender");
|
|
||||||
this.setCommandExecutor(new SearchEnchantCommand(this), "searchenchant");
|
|
||||||
this.setCommandExecutor(new ContainerSettingCommand(this), "silentcontainer", "anycontainer");
|
|
||||||
|
|
||||||
} else {
|
|
||||||
this.sendVersionError(this.getLogger()::warning);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private void sendVersionError(Consumer<String> messageMethod) {
|
|
||||||
if (!this.accessor.isSupported()) {
|
|
||||||
messageMethod.accept("Your server version (" + this.accessor.getVersion() + ") is not supported.");
|
|
||||||
messageMethod.accept("Please download the correct version of OpenInv here: " + this.accessor.getReleasesLink());
|
|
||||||
}
|
|
||||||
if (!isSpigot) {
|
|
||||||
messageMethod.accept("OpenInv requires that you use Spigot or a Spigot fork. Per the 1.14 update thread");
|
|
||||||
messageMethod.accept("(https://www.spigotmc.org/threads/369724/ \"A Note on CraftBukkit\"), if you are");
|
|
||||||
messageMethod.accept("encountering an inconsistency with vanilla that prevents you from using Spigot,");
|
|
||||||
messageMethod.accept("that is considered a Spigot bug and should be reported as such.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void setCommandExecutor(CommandExecutor executor, String... commands) {
|
|
||||||
for (String commandName : commands) {
|
|
||||||
PluginCommand command = this.getCommand(commandName);
|
|
||||||
if (command != null) {
|
|
||||||
command.setExecutor(executor);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) {
|
|
||||||
if (!isSpigot || !this.accessor.isSupported()) {
|
|
||||||
this.sendVersionError(sender::sendMessage);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void reloadConfig() {
|
|
||||||
super.reloadConfig();
|
|
||||||
this.offlineHandler = disableOfflineAccess() ? OfflineHandler.REMOVE_AND_CLOSE : OfflineHandler.REQUIRE_PERMISSIONS;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setAnyContainerStatus(@NotNull final OfflinePlayer offline, final boolean status) {
|
|
||||||
this.getConfig().set("toggles.any-chest." + offline.getUniqueId(), status);
|
|
||||||
this.saveConfig();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Method for handling a Player going offline.
|
* Method for handling a Player going offline.
|
||||||
*
|
*
|
||||||
@@ -448,6 +452,7 @@ public class OpenInv extends JavaPlugin implements IOpenInv {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// This should only be possible if a plugin is doing funky things with our inventories.
|
||||||
if (loaded != inventory) {
|
if (loaded != inventory) {
|
||||||
Inventory bukkitInventory = inventory.getBukkitInventory();
|
Inventory bukkitInventory = inventory.getBukkitInventory();
|
||||||
// Just in case, respect contents of the inventory that was just used.
|
// Just in case, respect contents of the inventory that was just used.
|
||||||
@@ -455,7 +460,7 @@ public class OpenInv extends JavaPlugin implements IOpenInv {
|
|||||||
// We need to close this inventory to reduce risk of duplication bugs if the user is offline.
|
// We need to close this inventory to reduce risk of duplication bugs if the user is offline.
|
||||||
// We don't want to risk recursively closing the same inventory repeatedly, so we schedule dumping viewers.
|
// We don't want to risk recursively closing the same inventory repeatedly, so we schedule dumping viewers.
|
||||||
// Worst case we schedule a couple redundant tasks if several people had the inventory open.
|
// Worst case we schedule a couple redundant tasks if several people had the inventory open.
|
||||||
if (!bukkitInventory.getViewers().isEmpty()) {
|
if (inventory.isInUse()) {
|
||||||
getServer().getScheduler().runTask(this, () -> ejectViewers(inventory, viewer -> true));
|
getServer().getScheduler().runTask(this, () -> ejectViewers(inventory, viewer -> true));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -514,15 +519,13 @@ public class OpenInv extends JavaPlugin implements IOpenInv {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
static void ejectViewers(@NotNull ISpecialInventory inventory, @NotNull Predicate<@NotNull HumanEntity> predicate) {
|
||||||
public void setSilentContainerStatus(@NotNull final OfflinePlayer offline, final boolean status) {
|
Inventory bukkitInventory = inventory.getBukkitInventory();
|
||||||
this.getConfig().set("toggles.silent-chest." + offline.getUniqueId(), status);
|
for (HumanEntity viewer : new ArrayList<>(bukkitInventory.getViewers())) {
|
||||||
this.saveConfig();
|
if (predicate.test(viewer)) {
|
||||||
}
|
viewer.closeInventory();
|
||||||
|
}
|
||||||
@Override
|
}
|
||||||
public void unload(@NotNull final OfflinePlayer offline) {
|
|
||||||
setPlayerOffline(offline, OfflineHandler.REMOVE_AND_CLOSE);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user