mirror of
https://github.com/Jikoo/OpenInv.git
synced 2026-11-04 08:42:05 -05:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
55053dacbf | ||
|
|
dacb07bd41 | ||
|
|
06d3fd7df9 | ||
|
|
4acf43b0fe | ||
|
|
a570001eaf | ||
|
|
70c53521c1 | ||
|
|
9021ef9a22 | ||
|
|
722ab4d2a3 |
No files matched your search
@@ -24,13 +24,15 @@ jobs:
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
with:
|
||||
name: OpenInv ${{ env.VERSIONED_NAME }}
|
||||
name: "OpenInv ${{ github.ref_name }}"
|
||||
body: |-
|
||||
## Supported server versions
|
||||
**Paper:** TODO VERSION, 1.21.8, 1.21.7, 1.21.6, 1.21.5, 1.21.4, 1.21.3, 1.21.1
|
||||
|
||||
**Paper:** TODO VERSION, 26.1.2, 1.21.11, 1.21.10, 1.21.9, 1.21.8, 1.21.7, 1.21.6
|
||||
**Spigot:** TODO VERSION
|
||||
|
||||
TODO HELLO HUMAN, PRESS THE GENERATE CHANGELOG BUTTON PLEASE.
|
||||
Don't forget to add a newline after the resulting header and prettify the tag compare link!
|
||||
draft: true
|
||||
prerelease: false
|
||||
files: ./dist/**
|
||||
@@ -59,6 +59,7 @@ jobs:
|
||||
with:
|
||||
modrinth-id: 1UlvXbzL
|
||||
modrinth-featured: false
|
||||
modrinth-unfeature-mode: none
|
||||
modrinth-token: ${{ secrets.MODRINTH_TOKEN }}
|
||||
files: ./OpenInv.jar
|
||||
game-versions: "${{ steps.parse_versions.outputs.PAPER_VERSIONS }}"
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
# Project meta
|
||||
group=com.lishid.openinv
|
||||
version=5.3.2
|
||||
version=5.3.3
|
||||
description=A Bukkit plugin for opening normally-inaccessible inventories.
|
||||
|
||||
# Gradle configuration
|
||||
|
||||
@@ -4,11 +4,11 @@ planarwrappers = "3.3.0"
|
||||
jspecify = "1.0.0"
|
||||
annotations = "26.1.0"
|
||||
paperweight = "2.0.0-beta.21"
|
||||
shadow = "9.4.1"
|
||||
shadow = "9.4.2"
|
||||
folia-scheduler-wrapper = "v0.0.3"
|
||||
errorprone-core = "2.49.0"
|
||||
errorprone-gradle = "5.1.0"
|
||||
slf4j = "2.0.17"
|
||||
slf4j = "2.0.18"
|
||||
sqlite-jdbc = "3.49.1.0"
|
||||
|
||||
[libraries]
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-9.5.0-bin.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-9.5.1-bin.zip
|
||||
networkTimeout=10000
|
||||
retries=0
|
||||
retryBackOffMs=500
|
||||
|
||||
+2
-2
@@ -1,8 +1,8 @@
|
||||
package com.lishid.openinv.internal.paper1_21_10.container;
|
||||
|
||||
import com.lishid.openinv.internal.paper1_21_11.container.menu.OpenInventoryMenu;
|
||||
import com.lishid.openinv.internal.paper26_1.container.BaseOpenInventory;
|
||||
import com.lishid.openinv.internal.paper26_1.container.menu.OpenChestMenu;
|
||||
import com.lishid.openinv.internal.paper26_2.container.BaseOpenInventory;
|
||||
import com.lishid.openinv.internal.paper26_2.container.menu.OpenChestMenu;
|
||||
import net.minecraft.ChatFormatting;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.network.chat.FontDescription;
|
||||
|
||||
+1
-1
@@ -8,7 +8,7 @@ import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.nio.file.Path;
|
||||
|
||||
public class OpenPlayer extends com.lishid.openinv.internal.paper26_1.player.OpenPlayer {
|
||||
public class OpenPlayer extends com.lishid.openinv.internal.paper26_2.player.OpenPlayer {
|
||||
|
||||
protected OpenPlayer(
|
||||
CraftServer server,
|
||||
|
||||
+2
-2
@@ -1,14 +1,14 @@
|
||||
package com.lishid.openinv.internal.paper1_21_11.container;
|
||||
|
||||
import com.lishid.openinv.internal.paper1_21_11.container.menu.OpenEnderChestMenu;
|
||||
import com.lishid.openinv.internal.paper26_1.container.menu.OpenChestMenu;
|
||||
import com.lishid.openinv.internal.paper26_2.container.menu.OpenChestMenu;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jspecify.annotations.NullMarked;
|
||||
|
||||
@NullMarked
|
||||
public class OpenEnderChest extends com.lishid.openinv.internal.paper26_1.container.OpenEnderChest {
|
||||
public class OpenEnderChest extends com.lishid.openinv.internal.paper26_2.container.OpenEnderChest {
|
||||
|
||||
public OpenEnderChest(org.bukkit.entity.Player player) {
|
||||
super(player);
|
||||
|
||||
+2
-2
@@ -1,14 +1,14 @@
|
||||
package com.lishid.openinv.internal.paper1_21_11.container;
|
||||
|
||||
import com.lishid.openinv.internal.paper1_21_11.container.menu.OpenInventoryMenu;
|
||||
import com.lishid.openinv.internal.paper26_1.container.menu.OpenChestMenu;
|
||||
import com.lishid.openinv.internal.paper26_2.container.menu.OpenChestMenu;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jspecify.annotations.NullMarked;
|
||||
|
||||
@NullMarked
|
||||
public class OpenInventory extends com.lishid.openinv.internal.paper26_1.container.OpenInventory {
|
||||
public class OpenInventory extends com.lishid.openinv.internal.paper26_2.container.OpenInventory {
|
||||
|
||||
public OpenInventory(org.bukkit.entity.Player bukkitPlayer) {
|
||||
super(bukkitPlayer);
|
||||
|
||||
+2
-2
@@ -1,7 +1,7 @@
|
||||
package com.lishid.openinv.internal.paper1_21_11.container.menu;
|
||||
|
||||
import com.lishid.openinv.internal.paper26_1.container.OpenEnderChest;
|
||||
import com.lishid.openinv.internal.paper26_1.container.menu.OpenSyncMenu;
|
||||
import com.lishid.openinv.internal.paper26_2.container.OpenEnderChest;
|
||||
import com.lishid.openinv.internal.paper26_2.container.menu.OpenSyncMenu;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraft.world.inventory.ClickType;
|
||||
|
||||
+2
-2
@@ -1,7 +1,7 @@
|
||||
package com.lishid.openinv.internal.paper1_21_11.container.menu;
|
||||
|
||||
import com.lishid.openinv.internal.paper26_1.container.BaseOpenInventory;
|
||||
import com.lishid.openinv.internal.paper26_1.container.menu.BaseOpenInventoryMenu;
|
||||
import com.lishid.openinv.internal.paper26_2.container.BaseOpenInventory;
|
||||
import com.lishid.openinv.internal.paper26_2.container.menu.BaseOpenInventoryMenu;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraft.world.inventory.ClickType;
|
||||
|
||||
@@ -1,28 +0,0 @@
|
||||
plugins {
|
||||
alias(libs.plugins.paperweight)
|
||||
}
|
||||
|
||||
java {
|
||||
toolchain.languageVersion = JavaLanguageVersion.of(21)
|
||||
}
|
||||
|
||||
tasks.withType<JavaCompile>().configureEach {
|
||||
options.release = 21
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation(project(":openinvapi")) {
|
||||
exclude(group = "org.spigotmc", module = "spigot-api")
|
||||
}
|
||||
implementation(project(":openinvcommon")) {
|
||||
exclude(group = "org.spigotmc", module = "spigot-api")
|
||||
}
|
||||
implementation(project(":openinvadapterpaper26_1")) {
|
||||
exclude(group = "io.papermc.paper", module = "dev-bundle")
|
||||
}
|
||||
implementation(project(":openinvadapterpaper1_21_11")) {
|
||||
exclude(group = "io.papermc.paper", module = "dev-bundle")
|
||||
}
|
||||
|
||||
paperweight.paperDevBundle("1.21.8-R0.1-SNAPSHOT")
|
||||
}
|
||||
-31
@@ -1,31 +0,0 @@
|
||||
package com.lishid.openinv.internal.paper1_21_8;
|
||||
|
||||
import com.lishid.openinv.internal.ISpecialPlayerInventory;
|
||||
import com.lishid.openinv.internal.paper1_21_8.container.OpenInventory;
|
||||
import com.lishid.openinv.internal.paper1_21_8.player.PlayerManager;
|
||||
import com.lishid.openinv.util.lang.LanguageManager;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.logging.Logger;
|
||||
|
||||
public class InternalAccessor extends com.lishid.openinv.internal.paper1_21_11.InternalAccessor {
|
||||
|
||||
private final @NotNull PlayerManager manager;
|
||||
|
||||
public InternalAccessor(@NotNull Logger logger, @NotNull LanguageManager lang) {
|
||||
super(logger, lang);
|
||||
manager = new PlayerManager(logger);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull PlayerManager getPlayerManager() {
|
||||
return manager;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull ISpecialPlayerInventory createPlayerInventory(@NotNull Player player) {
|
||||
return new OpenInventory(player);
|
||||
}
|
||||
|
||||
}
|
||||
-58
@@ -1,58 +0,0 @@
|
||||
package com.lishid.openinv.internal.paper1_21_8.container;
|
||||
|
||||
import com.lishid.openinv.internal.paper1_21_11.container.menu.OpenInventoryMenu;
|
||||
import com.lishid.openinv.internal.paper26_1.container.BaseOpenInventory;
|
||||
import com.lishid.openinv.internal.paper26_1.container.menu.OpenChestMenu;
|
||||
import net.minecraft.ChatFormatting;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.network.chat.MutableComponent;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public class OpenInventory extends BaseOpenInventory {
|
||||
|
||||
public OpenInventory(@NotNull Player bukkitPlayer) {
|
||||
super(bukkitPlayer);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull Component getTitle(@Nullable ServerPlayer viewer, @Nullable OpenChestMenu<?> menu) {
|
||||
MutableComponent component = Component.empty();
|
||||
// Prefix for use with custom bitmap image fonts.
|
||||
if (owner.equals(viewer)) {
|
||||
component.append(
|
||||
Component.translatableWithFallback("openinv.container.inventory.self", "")
|
||||
.withStyle(style -> style
|
||||
.withFont(ResourceLocation.parse("openinv:font/inventory"))
|
||||
.withColor(ChatFormatting.WHITE)));
|
||||
} else {
|
||||
component.append(
|
||||
Component.translatableWithFallback("openinv.container.inventory.other", "")
|
||||
.withStyle(style -> style
|
||||
.withFont(ResourceLocation.parse("openinv:font/inventory"))
|
||||
.withColor(ChatFormatting.WHITE)));
|
||||
}
|
||||
if (menu != null && menu.isViewOnly()) {
|
||||
component.append(Component.translatableWithFallback("openinv.container.inventory.viewonly", "[RO] "));
|
||||
} else {
|
||||
component.append(Component.translatableWithFallback("openinv.container.inventory.editable", ""));
|
||||
}
|
||||
// Normal title: "Inventory - OwnerName"
|
||||
component.append(Component.translatableWithFallback("openinv.container.inventory.prefix", "", owner.getName()))
|
||||
.append(Component.translatable("container.inventory"))
|
||||
.append(Component.translatableWithFallback("openinv.container.inventory.suffix", " - %s", owner.getName()));
|
||||
return component;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable OpenChestMenu<?> createMenu(net.minecraft.world.entity.player.Player player, int i, boolean viewOnly) {
|
||||
if (player instanceof ServerPlayer serverPlayer) {
|
||||
return new OpenInventoryMenu(this, serverPlayer, i, viewOnly);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
-44
@@ -1,44 +0,0 @@
|
||||
package com.lishid.openinv.internal.paper1_21_8.player;
|
||||
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.util.ProblemReporter;
|
||||
import net.minecraft.world.level.storage.PlayerDataStorage;
|
||||
import org.bukkit.craftbukkit.CraftServer;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.nio.file.Path;
|
||||
import java.util.Optional;
|
||||
|
||||
public class OpenPlayer extends com.lishid.openinv.internal.paper26_1.player.OpenPlayer {
|
||||
|
||||
protected OpenPlayer(
|
||||
CraftServer server,
|
||||
ServerPlayer entity,
|
||||
PlayerManager manager
|
||||
) {
|
||||
super(server, entity, manager);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Optional<CompoundTag> load(
|
||||
PlayerDataStorage storage,
|
||||
ServerPlayer player,
|
||||
ProblemReporter.ScopedCollector collector
|
||||
) {
|
||||
return storage.load(player.getName().getString(), player.getStringUUID(), collector);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void safeReplaceFile(@NotNull Path dataFile, @NotNull Path tempFile, @NotNull Path backupFile) {
|
||||
net.minecraft.Util.safeReplaceFile(dataFile, tempFile, backupFile);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void remove(@NotNull CompoundTag tag, @NotNull String key) {
|
||||
// Note that the method signature here is different, though the usage
|
||||
// appears identical. This version does not return the removed tag.
|
||||
tag.remove(key);
|
||||
}
|
||||
|
||||
}
|
||||
-100
@@ -1,100 +0,0 @@
|
||||
package com.lishid.openinv.internal.paper1_21_8.player;
|
||||
|
||||
import com.lishid.openinv.internal.paper26_1.player.OpenPlayer;
|
||||
import com.lishid.openinv.util.JulLoggerAdapter;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.util.ProblemReporter;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.storage.ValueInput;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.craftbukkit.CraftServer;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.logging.Logger;
|
||||
|
||||
public class PlayerManager extends com.lishid.openinv.internal.paper26_1.player.PlayerManager {
|
||||
|
||||
public PlayerManager(@NotNull Logger logger) {
|
||||
super(logger);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean loadData(@NotNull MinecraftServer server, @NotNull ServerPlayer player) {
|
||||
// See CraftPlayer#loadData
|
||||
|
||||
try (ProblemReporter.ScopedCollector scopedCollector = new ProblemReporter.ScopedCollector(player.problemPath(), new JulLoggerAdapter(logger))) {
|
||||
ValueInput loadedData = server.getPlayerList().playerIo.load(player, scopedCollector).orElse(null);
|
||||
|
||||
if (loadedData == null) {
|
||||
// Exceptions with loading are logged.
|
||||
return false;
|
||||
}
|
||||
|
||||
// Read basic data into the player.
|
||||
player.load(loadedData);
|
||||
// Game type settings are loaded separately.
|
||||
player.loadGameTypes(loadedData);
|
||||
|
||||
// World is not loaded by ServerPlayer#load(CompoundTag) on Paper.
|
||||
parseWorld(server, player, loadedData);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void spawnInDefaultWorld(@NotNull MinecraftServer server, @NotNull ServerPlayer player) {
|
||||
ServerLevel level = server.getLevel(Level.OVERWORLD);
|
||||
if (level != null) {
|
||||
// Adjust player to default spawn (in keeping with Paper handling) when world not found.
|
||||
player.snapTo(player.adjustSpawnLocation(level, level.getSharedSpawnPos()).getBottomCenter(), level.getSharedSpawnAngle(), 0.0F);
|
||||
player.spawnIn(level);
|
||||
} else {
|
||||
logger.warning("Tried to load player with invalid world when no fallback was available!");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void injectPlayer(@NotNull MinecraftServer server, @NotNull ServerPlayer player) throws IllegalAccessException {
|
||||
if (bukkitEntity == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
bukkitEntity.setAccessible(true);
|
||||
|
||||
bukkitEntity.set(player, new com.lishid.openinv.internal.paper1_21_8.player.OpenPlayer(server.server, player, this));
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull Player inject(@NotNull Player player) {
|
||||
try {
|
||||
ServerPlayer nmsPlayer = getHandle(player);
|
||||
if (nmsPlayer.getBukkitEntity() instanceof OpenPlayer openPlayer) {
|
||||
return openPlayer;
|
||||
}
|
||||
MinecraftServer server = nmsPlayer.getServer();
|
||||
if (server == null) {
|
||||
if (!(Bukkit.getServer() instanceof CraftServer craftServer)) {
|
||||
logger.warning(() ->
|
||||
"Unable to inject ServerPlayer, certain player data may be lost when saving! Server is not a CraftServer: "
|
||||
+ Bukkit.getServer().getClass().getName());
|
||||
return player;
|
||||
}
|
||||
server = craftServer.getServer();
|
||||
}
|
||||
injectPlayer(server, nmsPlayer);
|
||||
return nmsPlayer.getBukkitEntity();
|
||||
} catch (IllegalAccessException e) {
|
||||
logger.log(
|
||||
java.util.logging.Level.WARNING,
|
||||
e,
|
||||
() -> "Unable to inject ServerPlayer, certain player data may be lost when saving!"
|
||||
);
|
||||
return player;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -57,6 +57,9 @@ dependencies {
|
||||
implementation(project(":openinvcommon")) {
|
||||
exclude(group = "org.spigotmc", module = "spigot-api")
|
||||
}
|
||||
api(project(":openinvadapterpaper26_2")) {
|
||||
exclude(group = "io.papermc.paper", module = "dev-bundle")
|
||||
}
|
||||
|
||||
paperweight.paperDevBundle("26.1.2.build.5-alpha")
|
||||
}
|
||||
|
||||
+12
-49
@@ -1,52 +1,38 @@
|
||||
package com.lishid.openinv.internal.paper26_1;
|
||||
|
||||
import com.lishid.openinv.internal.Accessor;
|
||||
import com.lishid.openinv.internal.IAnySilentContainer;
|
||||
import com.lishid.openinv.internal.ISpecialEnderChest;
|
||||
import com.lishid.openinv.internal.ISpecialInventory;
|
||||
import com.lishid.openinv.internal.ISpecialPlayerInventory;
|
||||
import com.lishid.openinv.internal.paper26_1.container.AnySilentContainer;
|
||||
import com.lishid.openinv.internal.paper26_1.container.OpenEnderChest;
|
||||
import com.lishid.openinv.internal.paper26_1.container.OpenInventory;
|
||||
import com.lishid.openinv.internal.paper26_1.container.slot.placeholder.PlaceholderLoader;
|
||||
import com.lishid.openinv.internal.paper26_1.player.PlayerManager;
|
||||
import com.lishid.openinv.internal.paper26_2.container.slot.placeholder.PlaceholderLoader;
|
||||
import com.lishid.openinv.util.lang.LanguageManager;
|
||||
import net.minecraft.world.Container;
|
||||
import org.bukkit.configuration.ConfigurationSection;
|
||||
import org.bukkit.craftbukkit.inventory.CraftInventory;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.Inventory;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
public class InternalAccessor implements Accessor {
|
||||
|
||||
protected final @NotNull Logger logger;
|
||||
private final @NotNull PlayerManager manager;
|
||||
private final @NotNull AnySilentContainer anySilentContainer;
|
||||
public class InternalAccessor extends com.lishid.openinv.internal.paper26_2.InternalAccessor {
|
||||
|
||||
public InternalAccessor(@NotNull Logger logger, @NotNull LanguageManager lang) {
|
||||
this.logger = logger;
|
||||
manager = new PlayerManager(logger);
|
||||
anySilentContainer = new AnySilentContainer(logger, lang);
|
||||
super(logger, lang);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull PlayerManager getPlayerManager() {
|
||||
return manager;
|
||||
protected @NotNull PlayerManager createPlayerManager(@NotNull Logger logger) {
|
||||
return new PlayerManager(logger);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull IAnySilentContainer getAnySilentContainer() {
|
||||
return anySilentContainer;
|
||||
protected @NotNull AnySilentContainer createAnySilentContainer(
|
||||
@NotNull Logger logger,
|
||||
@NotNull LanguageManager lang
|
||||
) {
|
||||
return new AnySilentContainer(logger, lang);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull ISpecialPlayerInventory createPlayerInventory(@NotNull Player player) {
|
||||
return new OpenInventory(player);
|
||||
protected @NotNull PlaceholderLoader createPlaceholderLoader() {
|
||||
return new com.lishid.openinv.internal.paper26_1.container.slot.placeholder.PlaceholderLoader();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -54,27 +40,4 @@ public class InternalAccessor implements Accessor {
|
||||
return new OpenEnderChest(player);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends ISpecialInventory> @Nullable T get(@NotNull Inventory bukkitInventory, @NotNull Class<T> clazz) {
|
||||
if (!(bukkitInventory instanceof CraftInventory craftInventory)) {
|
||||
return null;
|
||||
}
|
||||
Container container = craftInventory.getInventory();
|
||||
if (clazz.isInstance(container)) {
|
||||
return clazz.cast(container);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reload(@NotNull ConfigurationSection config) {
|
||||
ConfigurationSection placeholders = config.getConfigurationSection("placeholders");
|
||||
try {
|
||||
// Reset placeholders to defaults and try to load configuration.
|
||||
new PlaceholderLoader().load(placeholders);
|
||||
} catch (Exception e) {
|
||||
logger.log(Level.WARNING, "Caught exception loading placeholder overrides!", e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
+4
-212
@@ -1,228 +1,20 @@
|
||||
/*
|
||||
* Copyright (C) 2011-2023 lishid. All rights reserved.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.lishid.openinv.internal.paper26_1.container;
|
||||
|
||||
import com.lishid.openinv.internal.AnySilentContainerBase;
|
||||
import com.lishid.openinv.internal.paper26_1.container.menu.OpenChestMenu;
|
||||
import com.lishid.openinv.internal.paper26_1.player.PlayerManager;
|
||||
import com.lishid.openinv.util.ReflectionHelper;
|
||||
import com.lishid.openinv.util.lang.LanguageManager;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.server.level.ServerPlayerGameMode;
|
||||
import net.minecraft.world.MenuProvider;
|
||||
import net.minecraft.world.SimpleMenuProvider;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.inventory.ChestMenu;
|
||||
import net.minecraft.world.inventory.MenuType;
|
||||
import net.minecraft.world.inventory.PlayerEnderChestContainer;
|
||||
import net.minecraft.world.level.GameType;
|
||||
import net.minecraft.world.level.block.BarrelBlock;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.ChestBlock;
|
||||
import net.minecraft.world.level.block.ShulkerBoxBlock;
|
||||
import net.minecraft.world.level.block.TrappedChestBlock;
|
||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
import net.minecraft.world.level.block.entity.EnderChestBlockEntity;
|
||||
import net.minecraft.world.level.block.entity.RandomizableContainerBlockEntity;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import org.bukkit.GameMode;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.Statistic;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.Inventory;
|
||||
import org.bukkit.inventory.InventoryHolder;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
public class AnySilentContainer extends AnySilentContainerBase {
|
||||
|
||||
private final @NotNull Logger logger;
|
||||
private final @NotNull LanguageManager lang;
|
||||
private @Nullable Field serverPlayerGameModeGameType;
|
||||
public class AnySilentContainer extends com.lishid.openinv.internal.paper26_2.container.AnySilentContainer {
|
||||
|
||||
public AnySilentContainer(@NotNull Logger logger, @NotNull LanguageManager lang) {
|
||||
this.logger = logger;
|
||||
this.lang = lang;
|
||||
try {
|
||||
try {
|
||||
this.serverPlayerGameModeGameType = ServerPlayerGameMode.class.getDeclaredField("gameModeForPlayer");
|
||||
this.serverPlayerGameModeGameType.setAccessible(true);
|
||||
} catch (NoSuchFieldException e) {
|
||||
logger.warning("The field ServerPlayerGameMode#gameModeForPlayer is no longer present!");
|
||||
logger.warning("Please report this at https://github.com/Jikoo/OpenInv/issues");
|
||||
logger.warning("Attempting to fall through using reflection. Please verify that SilentContainer does not fail.");
|
||||
// N.B. gameModeForPlayer is (for now) declared before previousGameModeForPlayer so silent shouldn't break.
|
||||
this.serverPlayerGameModeGameType = ReflectionHelper.grabFieldByType(ServerPlayerGameMode.class, GameType.class);
|
||||
}
|
||||
} catch (SecurityException e) {
|
||||
logger.warning("Unable to directly write player game mode! SilentContainer will fail.");
|
||||
logger.log(java.util.logging.Level.WARNING, "Error obtaining GameType field", e);
|
||||
}
|
||||
super(logger, lang);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean activateContainer(
|
||||
@NotNull final Player bukkitPlayer,
|
||||
final boolean silentchest,
|
||||
@NotNull final org.bukkit.block.Block bukkitBlock
|
||||
) {
|
||||
|
||||
// Silent ender chest is API-only
|
||||
if (silentchest && bukkitBlock.getType() == Material.ENDER_CHEST) {
|
||||
bukkitPlayer.openInventory(bukkitPlayer.getEnderChest());
|
||||
bukkitPlayer.incrementStatistic(Statistic.ENDERCHEST_OPENED);
|
||||
return true;
|
||||
}
|
||||
|
||||
ServerPlayer player = PlayerManager.getHandle(bukkitPlayer);
|
||||
|
||||
final net.minecraft.world.level.Level level = ((Entity) player).level();
|
||||
final BlockPos blockPos = new BlockPos(bukkitBlock.getX(), bukkitBlock.getY(), bukkitBlock.getZ());
|
||||
final BlockEntity blockEntity = level.getBlockEntity(blockPos);
|
||||
|
||||
if (blockEntity == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (blockEntity instanceof EnderChestBlockEntity enderChestTile) {
|
||||
// Anychest ender chest. See net.minecraft.world.level.block.EnderChestBlock
|
||||
PlayerEnderChestContainer enderChest = player.getEnderChestInventory();
|
||||
enderChest.setActiveChest(enderChestTile);
|
||||
player.openMenu(
|
||||
new SimpleMenuProvider(
|
||||
(containerCounter, playerInventory, ignored) -> {
|
||||
MenuType<?> containers = OpenChestMenu.getChestMenuType(enderChest.getContainerSize());
|
||||
int rows = enderChest.getContainerSize() / 9;
|
||||
return new ChestMenu(containers, containerCounter, playerInventory, enderChest, rows);
|
||||
}, Component.translatable("container.enderchest")
|
||||
)
|
||||
);
|
||||
bukkitPlayer.incrementStatistic(Statistic.ENDERCHEST_OPENED);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!(blockEntity instanceof MenuProvider menuProvider)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
BlockState blockState = level.getBlockState(blockPos);
|
||||
Block block = blockState.getBlock();
|
||||
|
||||
if (block instanceof ChestBlock chestBlock) {
|
||||
|
||||
// boolean flag: do not check if chest is blocked
|
||||
menuProvider = chestBlock.getMenuProvider(blockState, level, blockPos, true);
|
||||
|
||||
if (menuProvider == null) {
|
||||
lang.sendSystemMessage(bukkitPlayer, "messages.error.lootNotGenerated");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (block instanceof TrappedChestBlock) {
|
||||
bukkitPlayer.incrementStatistic(Statistic.TRAPPED_CHEST_TRIGGERED);
|
||||
} else {
|
||||
bukkitPlayer.incrementStatistic(Statistic.CHEST_OPENED);
|
||||
}
|
||||
}
|
||||
|
||||
if (block instanceof ShulkerBoxBlock) {
|
||||
bukkitPlayer.incrementStatistic(Statistic.SHULKER_BOX_OPENED);
|
||||
}
|
||||
|
||||
if (block instanceof BarrelBlock) {
|
||||
bukkitPlayer.incrementStatistic(Statistic.OPEN_BARREL);
|
||||
}
|
||||
|
||||
// AnyChest only - SilentChest not active, container unsupported, or unnecessary.
|
||||
if (!silentchest || player.gameMode.getGameModeForPlayer() == GameType.SPECTATOR) {
|
||||
player.openMenu(menuProvider);
|
||||
return true;
|
||||
}
|
||||
|
||||
// SilentChest requires access to setting players' game mode directly.
|
||||
if (this.serverPlayerGameModeGameType == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (blockEntity instanceof RandomizableContainerBlockEntity lootable) {
|
||||
if (lootable.lootTable != null) {
|
||||
lang.sendSystemMessage(bukkitPlayer, "messages.error.lootNotGenerated");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
GameType gameType = player.gameMode.getGameModeForPlayer();
|
||||
this.forceGameType(player, GameType.SPECTATOR);
|
||||
player.openMenu(menuProvider);
|
||||
this.forceGameType(player, gameType);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deactivateContainer(@NotNull final Player bukkitPlayer) {
|
||||
if (this.serverPlayerGameModeGameType == null || bukkitPlayer.getGameMode() == GameMode.SPECTATOR) {
|
||||
return;
|
||||
}
|
||||
|
||||
ServerPlayer player = PlayerManager.getHandle(bukkitPlayer);
|
||||
|
||||
// Force game mode change without informing plugins or players.
|
||||
// Regular game mode set calls GameModeChangeEvent and is cancellable.
|
||||
GameType gameType = player.gameMode.getGameModeForPlayer();
|
||||
this.forceGameType(player, GameType.SPECTATOR);
|
||||
|
||||
// ServerPlayer#closeContainer cannot be called without entering an
|
||||
// infinite loop because this method is called during inventory close.
|
||||
// From ServerPlayer#closeContainer -> CraftEventFactory#handleInventoryCloseEvent
|
||||
player.containerMenu.transferTo(player.inventoryMenu, player.getBukkitEntity());
|
||||
// From ServerPlayer#closeContainer
|
||||
player.doCloseContainer();
|
||||
// Regular inventory close will handle the rest - packet sending, etc.
|
||||
|
||||
// Revert forced game mode.
|
||||
this.forceGameType(player, gameType);
|
||||
}
|
||||
|
||||
private void forceGameType(final ServerPlayer player, final GameType gameMode) {
|
||||
if (this.serverPlayerGameModeGameType == null) {
|
||||
// No need to warn repeatedly, error on startup and lack of function should be enough.
|
||||
return;
|
||||
}
|
||||
try {
|
||||
this.serverPlayerGameModeGameType.setAccessible(true);
|
||||
this.serverPlayerGameModeGameType.set(player.gameMode, gameMode);
|
||||
} catch (IllegalArgumentException | IllegalAccessException e) {
|
||||
logger.log(java.util.logging.Level.WARNING, "Error bypassing GameModeChangeEvent", e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected org.bukkit.block.BlockState getState(@NotNull org.bukkit.block.Block block) {
|
||||
return block.getState(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected InventoryHolder getHolder(@NotNull Inventory inventory) {
|
||||
return inventory.getHolder(false);
|
||||
protected boolean hasLootTable(@NotNull RandomizableContainerBlockEntity lootable) {
|
||||
return lootable.lootTable != null;
|
||||
}
|
||||
|
||||
}
|
||||
+4
-186
@@ -1,201 +1,19 @@
|
||||
package com.lishid.openinv.internal.paper26_1.container;
|
||||
|
||||
import com.lishid.openinv.internal.ISpecialEnderChest;
|
||||
import com.lishid.openinv.internal.InternalOwned;
|
||||
import com.lishid.openinv.internal.paper26_1.container.menu.OpenChestMenu;
|
||||
import com.lishid.openinv.internal.paper26_1.container.menu.OpenEnderChestMenu;
|
||||
import com.lishid.openinv.internal.paper26_1.player.PlayerManager;
|
||||
import net.minecraft.core.NonNullList;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.network.chat.MutableComponent;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.world.Container;
|
||||
import net.minecraft.world.ContainerHelper;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraft.world.entity.player.StackedItemContents;
|
||||
import net.minecraft.world.inventory.StackedContentsCompatible;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.craftbukkit.entity.CraftHumanEntity;
|
||||
import org.bukkit.craftbukkit.inventory.CraftInventory;
|
||||
import org.bukkit.entity.HumanEntity;
|
||||
import org.bukkit.event.inventory.InventoryType;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class OpenEnderChest implements Container, StackedContentsCompatible, InternalOwned<ServerPlayer>,
|
||||
ISpecialEnderChest {
|
||||
|
||||
private CraftInventory inventory;
|
||||
private @NotNull ServerPlayer owner;
|
||||
private NonNullList<ItemStack> items;
|
||||
private int maxStack = 64;
|
||||
private final List<HumanEntity> transaction = new ArrayList<>();
|
||||
public class OpenEnderChest extends com.lishid.openinv.internal.paper26_2.container.OpenEnderChest {
|
||||
|
||||
public OpenEnderChest(@NotNull org.bukkit.entity.Player player) {
|
||||
this.owner = PlayerManager.getHandle(player);
|
||||
this.items = owner.getEnderChestInventory().items;
|
||||
super(player);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull ServerPlayer getOwnerHandle() {
|
||||
return owner;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull org.bukkit.inventory.Inventory getBukkitInventory() {
|
||||
if (inventory == null) {
|
||||
inventory = new CraftInventory(this) {
|
||||
@Override
|
||||
public @NotNull InventoryType getType() {
|
||||
return InventoryType.ENDER_CHEST;
|
||||
}
|
||||
};
|
||||
}
|
||||
return inventory;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPlayerOnline(@NotNull org.bukkit.entity.Player player) {
|
||||
owner = PlayerManager.getHandle(player);
|
||||
NonNullList<ItemStack> activeItems = owner.getEnderChestInventory().items;
|
||||
|
||||
// Guard against size changing. Theoretically on Purpur all row variations still have 6 rows internally.
|
||||
int max = Math.min(items.size(), activeItems.size());
|
||||
for (int index = 0; index < max; ++index) {
|
||||
activeItems.set(index, items.get(index));
|
||||
}
|
||||
|
||||
items = activeItems;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull org.bukkit.entity.Player getPlayer() {
|
||||
return owner.getBukkitEntity();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getContainerSize() {
|
||||
return items.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEmpty() {
|
||||
return items.stream().allMatch(ItemStack::isEmpty);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull ItemStack getItem(int index) {
|
||||
return index >= 0 && index < items.size() ? items.get(index) : ItemStack.EMPTY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull ItemStack removeItem(int index, int amount) {
|
||||
ItemStack itemstack = ContainerHelper.removeItem(items, index, amount);
|
||||
|
||||
if (!itemstack.isEmpty()) {
|
||||
setChanged();
|
||||
}
|
||||
|
||||
return itemstack;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull ItemStack removeItemNoUpdate(int index) {
|
||||
return index >= 0 && index < items.size() ? items.set(index, ItemStack.EMPTY) : ItemStack.EMPTY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setItem(int index, @NotNull ItemStack itemStack) {
|
||||
if (index >= 0 && index < items.size()) {
|
||||
items.set(index, itemStack);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMaxStackSize() {
|
||||
return maxStack;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setChanged() {
|
||||
this.owner.getEnderChestInventory().setChanged();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean stillValid(@NotNull Player player) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull List<ItemStack> getContents() {
|
||||
return items;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onOpen(@NotNull CraftHumanEntity craftHumanEntity) {
|
||||
transaction.add(craftHumanEntity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClose(@NotNull CraftHumanEntity craftHumanEntity) {
|
||||
transaction.remove(craftHumanEntity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull List<HumanEntity> getViewers() {
|
||||
return transaction;
|
||||
}
|
||||
|
||||
@Override
|
||||
public org.bukkit.entity.Player getOwner() {
|
||||
return getPlayer();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setMaxStackSize(int size) {
|
||||
maxStack = size;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable Location getLocation() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clearContent() {
|
||||
items.clear();
|
||||
setChanged();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fillStackedContents(@NotNull StackedItemContents stackedContents) {
|
||||
for (ItemStack itemstack : items) {
|
||||
stackedContents.accountStack(itemstack);
|
||||
}
|
||||
}
|
||||
|
||||
public Component getTitle(@Nullable OpenChestMenu<?> menu) {
|
||||
MutableComponent component;
|
||||
if (menu != null && menu.isViewOnly()) {
|
||||
component = Component.translatableWithFallback("openinv.container.enderchest.viewonly", "[RO] ");
|
||||
} else {
|
||||
component = Component.translatableWithFallback("openinv.container.enderchest.editable", "");
|
||||
}
|
||||
return component
|
||||
.append(Component.translatableWithFallback("openinv.container.enderchest.prefix", "", owner.getName()))
|
||||
.append(Component.translatable("container.enderchest"))
|
||||
.append(Component.translatableWithFallback("openinv.container.enderchest.suffix", " - %s", owner.getName()));
|
||||
}
|
||||
|
||||
public @Nullable OpenChestMenu<?> createMenu(Player player, int i, boolean viewOnly) {
|
||||
if (player instanceof ServerPlayer serverPlayer) {
|
||||
return new OpenEnderChestMenu(this, serverPlayer, i, viewOnly);
|
||||
}
|
||||
return null;
|
||||
protected @NotNull NonNullList<ItemStack> getEnderChestItems(@NotNull ServerPlayer owner) {
|
||||
return owner.getEnderChestInventory().items;
|
||||
}
|
||||
|
||||
}
|
||||
+7
-28
@@ -1,40 +1,19 @@
|
||||
package com.lishid.openinv.internal.paper26_1.container.slot.placeholder;
|
||||
|
||||
import net.minecraft.core.component.DataComponents;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.nbt.TagParser;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.item.component.CustomModelData;
|
||||
import net.minecraft.world.item.component.DyedItemColor;
|
||||
import net.minecraft.world.item.component.TooltipDisplay;
|
||||
import net.minecraft.world.item.Item;
|
||||
import net.minecraft.world.item.Items;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
|
||||
public class PlaceholderLoader extends PlaceholderLoaderBase {
|
||||
|
||||
private static final CustomModelData DEFAULT_CUSTOM_MODEL_DATA = new CustomModelData(List.of(), List.of(), List.of("openinv:custom"), List.of());
|
||||
private static final TooltipDisplay HIDE_TOOLTIP = new TooltipDisplay(true, new LinkedHashSet<>());
|
||||
public class PlaceholderLoader extends com.lishid.openinv.internal.paper26_2.container.slot.placeholder.PlaceholderLoader {
|
||||
|
||||
@Override
|
||||
protected @NotNull CompoundTag parseTag(@NotNull String itemText) throws Exception {
|
||||
return TagParser.parseCompoundFully(itemText);
|
||||
protected @NotNull Item getDefaultCursorItem() {
|
||||
return Items.WHITE_BANNER;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void addModelData(@NotNull ItemStack itemStack) {
|
||||
itemStack.set(DataComponents.CUSTOM_MODEL_DATA, DEFAULT_CUSTOM_MODEL_DATA);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void hideTooltip(@NotNull ItemStack itemStack) {
|
||||
itemStack.set(DataComponents.TOOLTIP_DISPLAY, HIDE_TOOLTIP);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected DyedItemColor getDye(int rgb) {
|
||||
return new DyedItemColor(rgb);
|
||||
protected @NotNull Item getDefaultNotSlotItem() {
|
||||
return Items.WHITE_STAINED_GLASS_PANE;
|
||||
}
|
||||
|
||||
}
|
||||
+14
-281
@@ -1,309 +1,42 @@
|
||||
package com.lishid.openinv.internal.paper26_1.player;
|
||||
|
||||
import com.lishid.openinv.internal.ISpecialInventory;
|
||||
import com.lishid.openinv.internal.paper26_1.container.BaseOpenInventory;
|
||||
import com.lishid.openinv.internal.paper26_1.container.OpenEnderChest;
|
||||
import com.lishid.openinv.internal.paper26_1.container.menu.OpenChestMenu;
|
||||
import com.lishid.openinv.util.JulLoggerAdapter;
|
||||
import com.mojang.authlib.GameProfile;
|
||||
import com.mojang.logging.LogUtils;
|
||||
import io.papermc.paper.adventure.PaperAdventure;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.network.protocol.game.ClientboundOpenScreenPacket;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.server.level.ClientInformation;
|
||||
import net.minecraft.server.level.ParticleStatus;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.util.ProblemReporter;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.entity.player.ChatVisiblity;
|
||||
import net.minecraft.world.inventory.AbstractContainerMenu;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.storage.LevelData;
|
||||
import net.minecraft.world.level.storage.TagValueInput;
|
||||
import net.minecraft.world.level.storage.TagValueOutput;
|
||||
import net.minecraft.world.level.storage.ValueInput;
|
||||
import net.minecraft.world.level.storage.ValueOutput;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
import org.bukkit.Server;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.craftbukkit.CraftServer;
|
||||
import org.bukkit.craftbukkit.CraftWorld;
|
||||
import org.bukkit.craftbukkit.entity.CraftPlayer;
|
||||
import org.bukkit.craftbukkit.event.CraftEventFactory;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.InventoryView;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
import org.jspecify.annotations.NullMarked;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
@NullMarked
|
||||
public class PlayerManager implements com.lishid.openinv.internal.PlayerManager {
|
||||
|
||||
protected final Logger logger;
|
||||
protected @Nullable Field bukkitEntity;
|
||||
public class PlayerManager extends com.lishid.openinv.internal.paper26_2.player.PlayerManager {
|
||||
|
||||
public PlayerManager(Logger logger) {
|
||||
this.logger = logger;
|
||||
try {
|
||||
bukkitEntity = Entity.class.getDeclaredField("bukkitEntity");
|
||||
} catch (NoSuchFieldException e) {
|
||||
logger.warning("Unable to obtain field to inject custom save process - certain player data may be lost when saving!");
|
||||
logger.log(java.util.logging.Level.WARNING, e.getMessage(), e);
|
||||
bukkitEntity = null;
|
||||
}
|
||||
}
|
||||
|
||||
public static ServerPlayer getHandle(final Player player) {
|
||||
if (player instanceof CraftPlayer craftPlayer) {
|
||||
return craftPlayer.getHandle();
|
||||
}
|
||||
|
||||
Server server = player.getServer();
|
||||
ServerPlayer nmsPlayer = null;
|
||||
|
||||
if (server instanceof CraftServer craftServer) {
|
||||
nmsPlayer = craftServer.getHandle().getPlayer(player.getUniqueId());
|
||||
}
|
||||
|
||||
if (nmsPlayer == null) {
|
||||
// Could use reflection to examine fields, but it's honestly not worth the bother.
|
||||
throw new RuntimeException("Unable to fetch EntityPlayer from Player implementation " + player.getClass().getName());
|
||||
}
|
||||
|
||||
return nmsPlayer;
|
||||
super(logger);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable Player loadPlayer(final OfflinePlayer offline) {
|
||||
if (!(Bukkit.getServer() instanceof CraftServer craftServer)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
MinecraftServer server = craftServer.getServer();
|
||||
ServerLevel worldServer = server.getLevel(Level.OVERWORLD);
|
||||
|
||||
if (worldServer == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Create a new ServerPlayer.
|
||||
ServerPlayer entity = createNewPlayer(server, worldServer, offline);
|
||||
|
||||
// Stop listening for advancement progression - if this is not cleaned up, loading causes a memory leak.
|
||||
protected void removeAdvancementListeners(ServerPlayer entity) {
|
||||
entity.getAdvancements().stopListening();
|
||||
|
||||
// Try to load the player's data.
|
||||
if (loadData(server, entity)) {
|
||||
// If data is loaded successfully, return the Bukkit entity.
|
||||
return entity.getBukkitEntity();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
protected ServerPlayer createNewPlayer(
|
||||
MinecraftServer server,
|
||||
ServerLevel worldServer,
|
||||
final OfflinePlayer offline
|
||||
) {
|
||||
// See net.minecraft.server.players.PlayerList#canPlayerLogin(ServerLoginPacketListenerImpl, GameProfile)
|
||||
// See net.minecraft.server.network.ServerLoginPacketListenerImpl#handleHello(ServerboundHelloPacket)
|
||||
GameProfile profile = new GameProfile(offline.getUniqueId(),
|
||||
offline.getName() != null ? offline.getName() : offline.getUniqueId().toString()
|
||||
);
|
||||
|
||||
ClientInformation dummyInfo = new ClientInformation(
|
||||
"en_us",
|
||||
1, // Reduce distance just in case.
|
||||
ChatVisiblity.HIDDEN, // Don't accept chat.
|
||||
false,
|
||||
ServerPlayer.DEFAULT_MODEL_CUSTOMIZATION,
|
||||
ServerPlayer.DEFAULT_MAIN_HAND,
|
||||
true,
|
||||
false, // Don't list in player list (not that this player is in the list anyway).
|
||||
ParticleStatus.MINIMAL
|
||||
);
|
||||
|
||||
ServerPlayer entity = new ServerPlayer(server, worldServer, profile, dummyInfo);
|
||||
|
||||
try {
|
||||
injectPlayer(server, entity);
|
||||
} catch (IllegalAccessException e) {
|
||||
logger.log(
|
||||
java.util.logging.Level.WARNING,
|
||||
e,
|
||||
() -> "Unable to inject ServerPlayer, certain player data may be lost when saving!"
|
||||
);
|
||||
}
|
||||
|
||||
return entity;
|
||||
@Override
|
||||
protected LevelData.RespawnData getRespawnData(ServerLevel level) {
|
||||
return level.levelData.getRespawnData();
|
||||
}
|
||||
|
||||
protected boolean loadData(MinecraftServer server, ServerPlayer player) {
|
||||
// See CraftPlayer#loadData
|
||||
|
||||
try (ProblemReporter.ScopedCollector scopedCollector = new ProblemReporter.ScopedCollector(player.problemPath(), new JulLoggerAdapter(logger))) {
|
||||
CompoundTag loadedData = server.getPlayerList().playerIo.load(player.nameAndId()).orElse(null);
|
||||
|
||||
if (loadedData == null) {
|
||||
// Exceptions with loading are logged.
|
||||
return false;
|
||||
}
|
||||
|
||||
ValueInput valueInput = TagValueInput.create(scopedCollector, player.registryAccess(), loadedData);
|
||||
|
||||
// Read basic data into the player.
|
||||
player.load(valueInput);
|
||||
|
||||
// World is not loaded by ServerPlayer#load(CompoundTag) on Paper.
|
||||
parseWorld(server, player, valueInput);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
protected void parseWorld(
|
||||
MinecraftServer server,
|
||||
@Override
|
||||
protected Vec3 getAdjustedSpawnLocation(
|
||||
ServerPlayer player,
|
||||
ValueInput loadedData
|
||||
ServerLevel level,
|
||||
LevelData.RespawnData respawnData
|
||||
) {
|
||||
// See PlayerList#placeNewPlayer
|
||||
World bukkitWorld;
|
||||
Optional<Long> msbs = loadedData.getLong("WorldUUIDMost");
|
||||
Optional<Long> lsbs = loadedData.getLong("WorldUUIDLeast");
|
||||
if (msbs.isPresent() && lsbs.isPresent()) {
|
||||
// Modern Bukkit world.
|
||||
bukkitWorld = Bukkit.getServer().getWorld(new UUID(msbs.get(), lsbs.get()));
|
||||
} else {
|
||||
bukkitWorld = loadedData.getString("world").map(Bukkit::getWorld).orElse(null);
|
||||
}
|
||||
if (bukkitWorld == null) {
|
||||
spawnInDefaultWorld(server, player);
|
||||
return;
|
||||
}
|
||||
player.setServerLevel(((CraftWorld) bukkitWorld).getHandle());
|
||||
}
|
||||
|
||||
protected void spawnInDefaultWorld(MinecraftServer server, ServerPlayer player) {
|
||||
ServerLevel level = server.getLevel(Level.OVERWORLD);
|
||||
if (level != null) {
|
||||
// Adjust player to default spawn (in keeping with Paper handling) when world not found.
|
||||
LevelData.RespawnData respawnData = level.levelData.getRespawnData();
|
||||
player.snapTo(player.adjustSpawnLocation(level, respawnData.pos()).getBottomCenter(), respawnData.yaw(), 0.0F);
|
||||
player.spawnIn(level);
|
||||
} else {
|
||||
logger.warning("Tried to load player with invalid world when no fallback was available!");
|
||||
}
|
||||
}
|
||||
|
||||
protected void injectPlayer(MinecraftServer server, ServerPlayer player) throws IllegalAccessException {
|
||||
if (bukkitEntity == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
bukkitEntity.setAccessible(true);
|
||||
|
||||
bukkitEntity.set(player, new OpenPlayer(server.server, player, this));
|
||||
return player.adjustSpawnLocation(level, respawnData.pos()).getBottomCenter();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Player inject(Player player) {
|
||||
try {
|
||||
ServerPlayer nmsPlayer = getHandle(player);
|
||||
if (nmsPlayer.getBukkitEntity() instanceof OpenPlayer openPlayer) {
|
||||
return openPlayer;
|
||||
}
|
||||
|
||||
org.slf4j.Logger logger = LogUtils.getLogger();
|
||||
|
||||
try (ProblemReporter.ScopedCollector scopedCollector = new ProblemReporter.ScopedCollector(nmsPlayer.problemPath(), logger)) {
|
||||
CompoundTag extraData = new CompoundTag();
|
||||
|
||||
// Copy extra data out of existing player.
|
||||
ValueOutput output = TagValueOutput.createWrappingWithContext(scopedCollector, nmsPlayer.registryAccess(), extraData);
|
||||
nmsPlayer.getBukkitEntity().setExtraData(output);
|
||||
|
||||
MinecraftServer server = nmsPlayer.level().getServer();
|
||||
injectPlayer(server, nmsPlayer);
|
||||
CraftPlayer newPlayer = nmsPlayer.getBukkitEntity();
|
||||
|
||||
// Set extra data in new player.
|
||||
ValueInput input = TagValueInput.create(scopedCollector, nmsPlayer.registryAccess(), extraData);
|
||||
newPlayer.readExtraData(input);
|
||||
|
||||
return newPlayer;
|
||||
}
|
||||
} catch (IllegalAccessException e) {
|
||||
logger.log(
|
||||
java.util.logging.Level.WARNING,
|
||||
e,
|
||||
() -> "Unable to inject ServerPlayer, certain player data may be lost when saving!"
|
||||
);
|
||||
return player;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable InventoryView openInventory(
|
||||
Player bukkitPlayer,
|
||||
ISpecialInventory inventory,
|
||||
boolean viewOnly
|
||||
) {
|
||||
ServerPlayer player = getHandle(bukkitPlayer);
|
||||
|
||||
if (!OpenPlayer.isConnected(player.connection)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// See net.minecraft.server.level.ServerPlayer#openMenu(MenuProvider)
|
||||
OpenChestMenu<?> menu;
|
||||
Component title;
|
||||
if (inventory instanceof BaseOpenInventory playerInv) {
|
||||
menu = playerInv.createMenu(player, player.nextContainerCounter(), viewOnly);
|
||||
title = playerInv.getTitle(player, menu);
|
||||
} else if (inventory instanceof OpenEnderChest enderChest) {
|
||||
menu = enderChest.createMenu(player, player.nextContainerCounter(), viewOnly);
|
||||
title = enderChest.getTitle(menu);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Should never happen, player is a ServerPlayer with an active connection.
|
||||
if (menu == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Set up title. Title can only be set once for a menu, and is set during the open process.
|
||||
// Further title changes are a hack where the client is sent a "new" inventory with the same ID,
|
||||
// resulting in a title change but no other state modifications (like cursor position).
|
||||
menu.setTitle(title);
|
||||
|
||||
var pair = CraftEventFactory.callInventoryOpenEventWithTitle(player, menu);
|
||||
AbstractContainerMenu opened = pair.getSecond();
|
||||
|
||||
// Menu is null if event is cancelled.
|
||||
if (opened == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
var newTitle = pair.getFirst();
|
||||
if (newTitle != null) {
|
||||
title = PaperAdventure.asVanilla(newTitle);
|
||||
}
|
||||
|
||||
player.containerMenu = opened;
|
||||
player.connection.send(new ClientboundOpenScreenPacket(opened.containerId, opened.getType(), title));
|
||||
player.initMenu(opened);
|
||||
|
||||
return opened.getBukkitView();
|
||||
protected void setServerLevel(ServerPlayer player, ServerLevel level) {
|
||||
player.spawnIn(level);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
import org.gradle.api.internal.attributes.DefaultCompatibilityRuleChain
|
||||
|
||||
plugins {
|
||||
alias(libs.plugins.paperweight)
|
||||
}
|
||||
|
||||
repositories {
|
||||
maven("https://repo.papermc.io/repository/maven-public/")
|
||||
}
|
||||
|
||||
java {
|
||||
toolchain.languageVersion.set(JavaLanguageVersion.of(25))
|
||||
}
|
||||
|
||||
tasks.withType<JavaCompile>().configureEach {
|
||||
options.release = 21
|
||||
}
|
||||
|
||||
class ToolchainJvmVersion: AttributeCompatibilityRule<Int> {
|
||||
override fun execute(details: CompatibilityCheckDetails<Int>) {
|
||||
if (details.consumerValue == details.producerValue) {
|
||||
details.compatible()
|
||||
return
|
||||
}
|
||||
if (details.producerValue == null) {
|
||||
details.incompatible()
|
||||
return
|
||||
}
|
||||
if (25 >= details.producerValue!!) {
|
||||
details.compatible()
|
||||
} else {
|
||||
details.incompatible()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
attributesSchema {
|
||||
attribute(TargetJvmVersion.TARGET_JVM_VERSION_ATTRIBUTE) {
|
||||
// Gradle thinks that depending on a library with a certain language level requires
|
||||
// any project that depends on it to also require that language level no matter what.
|
||||
// This is a bit obnoxious when we're specifically adding compatiblity patches to shared common code.
|
||||
// Realistically Gradle is correct and the chain should be reversed - the oldest, least common
|
||||
// denominator should be targeted and patches should be slapped on top as necessary.
|
||||
// However, I don't want to spend a week restructuring the project to cut a release.
|
||||
// Hack out Gradle's rules and replace them with our own less-restrictive version.
|
||||
val rules = compatibilityRules as DefaultCompatibilityRuleChain
|
||||
rules.rules.clear()
|
||||
|
||||
compatibilityRules.add(ToolchainJvmVersion::class.java)
|
||||
}
|
||||
}
|
||||
|
||||
implementation(project(":openinvapi")) {
|
||||
exclude(group = "org.spigotmc", module = "spigot-api")
|
||||
}
|
||||
implementation(project(":openinvcommon")) {
|
||||
exclude(group = "org.spigotmc", module = "spigot-api")
|
||||
}
|
||||
|
||||
paperweight.paperDevBundle("26.2.build.31-alpha")
|
||||
}
|
||||
|
||||
tasks.reobfJar {
|
||||
enabled = false
|
||||
}
|
||||
|
||||
configurations.reobf.get().outgoing.artifacts.clear()
|
||||
+95
@@ -0,0 +1,95 @@
|
||||
package com.lishid.openinv.internal.paper26_2;
|
||||
|
||||
import com.lishid.openinv.internal.Accessor;
|
||||
import com.lishid.openinv.internal.IAnySilentContainer;
|
||||
import com.lishid.openinv.internal.ISpecialEnderChest;
|
||||
import com.lishid.openinv.internal.ISpecialInventory;
|
||||
import com.lishid.openinv.internal.ISpecialPlayerInventory;
|
||||
import com.lishid.openinv.internal.paper26_2.container.AnySilentContainer;
|
||||
import com.lishid.openinv.internal.paper26_2.container.OpenEnderChest;
|
||||
import com.lishid.openinv.internal.paper26_2.container.OpenInventory;
|
||||
import com.lishid.openinv.internal.paper26_2.container.slot.placeholder.PlaceholderLoader;
|
||||
import com.lishid.openinv.internal.paper26_2.player.PlayerManager;
|
||||
import com.lishid.openinv.util.lang.LanguageManager;
|
||||
import net.minecraft.world.Container;
|
||||
import org.bukkit.configuration.ConfigurationSection;
|
||||
import org.bukkit.craftbukkit.inventory.CraftInventory;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.Inventory;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
public class InternalAccessor implements Accessor {
|
||||
|
||||
protected final @NotNull Logger logger;
|
||||
private final @NotNull PlayerManager manager;
|
||||
private final @NotNull AnySilentContainer anySilentContainer;
|
||||
|
||||
public InternalAccessor(@NotNull Logger logger, @NotNull LanguageManager lang) {
|
||||
this.logger = logger;
|
||||
manager = createPlayerManager(logger);
|
||||
anySilentContainer = createAnySilentContainer(logger, lang);
|
||||
}
|
||||
|
||||
protected @NotNull PlayerManager createPlayerManager(@NotNull Logger logger) {
|
||||
return new PlayerManager(logger);
|
||||
}
|
||||
|
||||
protected @NotNull AnySilentContainer createAnySilentContainer(
|
||||
@NotNull Logger logger,
|
||||
@NotNull LanguageManager lang
|
||||
) {
|
||||
return new AnySilentContainer(logger, lang);
|
||||
}
|
||||
|
||||
protected @NotNull PlaceholderLoader createPlaceholderLoader() {
|
||||
return new PlaceholderLoader();
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull PlayerManager getPlayerManager() {
|
||||
return manager;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull IAnySilentContainer getAnySilentContainer() {
|
||||
return anySilentContainer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull ISpecialPlayerInventory createPlayerInventory(@NotNull Player player) {
|
||||
return new OpenInventory(player);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull ISpecialEnderChest createEnderChest(@NotNull Player player) {
|
||||
return new OpenEnderChest(player);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends ISpecialInventory> @Nullable T get(@NotNull Inventory bukkitInventory, @NotNull Class<T> clazz) {
|
||||
if (!(bukkitInventory instanceof CraftInventory craftInventory)) {
|
||||
return null;
|
||||
}
|
||||
Container container = craftInventory.getInventory();
|
||||
if (clazz.isInstance(container)) {
|
||||
return clazz.cast(container);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reload(@NotNull ConfigurationSection config) {
|
||||
ConfigurationSection placeholders = config.getConfigurationSection("placeholders");
|
||||
try {
|
||||
// Reset placeholders to defaults and try to load configuration.
|
||||
createPlaceholderLoader().load(placeholders);
|
||||
} catch (Exception e) {
|
||||
logger.log(Level.WARNING, "Caught exception loading placeholder overrides!", e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
+232
@@ -0,0 +1,232 @@
|
||||
/*
|
||||
* Copyright (C) 2011-2023 lishid. All rights reserved.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.lishid.openinv.internal.paper26_2.container;
|
||||
|
||||
import com.lishid.openinv.internal.AnySilentContainerBase;
|
||||
import com.lishid.openinv.internal.paper26_2.container.menu.OpenChestMenu;
|
||||
import com.lishid.openinv.internal.paper26_2.player.PlayerManager;
|
||||
import com.lishid.openinv.util.ReflectionHelper;
|
||||
import com.lishid.openinv.util.lang.LanguageManager;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.server.level.ServerPlayerGameMode;
|
||||
import net.minecraft.world.MenuProvider;
|
||||
import net.minecraft.world.SimpleMenuProvider;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.inventory.ChestMenu;
|
||||
import net.minecraft.world.inventory.MenuType;
|
||||
import net.minecraft.world.inventory.PlayerEnderChestContainer;
|
||||
import net.minecraft.world.level.GameType;
|
||||
import net.minecraft.world.level.block.BarrelBlock;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.ChestBlock;
|
||||
import net.minecraft.world.level.block.ShulkerBoxBlock;
|
||||
import net.minecraft.world.level.block.TrappedChestBlock;
|
||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
import net.minecraft.world.level.block.entity.EnderChestBlockEntity;
|
||||
import net.minecraft.world.level.block.entity.RandomizableContainerBlockEntity;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import org.bukkit.GameMode;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.Statistic;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.Inventory;
|
||||
import org.bukkit.inventory.InventoryHolder;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
public class AnySilentContainer extends AnySilentContainerBase {
|
||||
|
||||
private final @NotNull Logger logger;
|
||||
private final @NotNull LanguageManager lang;
|
||||
private @Nullable Field serverPlayerGameModeGameType;
|
||||
|
||||
public AnySilentContainer(@NotNull Logger logger, @NotNull LanguageManager lang) {
|
||||
this.logger = logger;
|
||||
this.lang = lang;
|
||||
try {
|
||||
try {
|
||||
this.serverPlayerGameModeGameType = ServerPlayerGameMode.class.getDeclaredField("gameModeForPlayer");
|
||||
this.serverPlayerGameModeGameType.setAccessible(true);
|
||||
} catch (NoSuchFieldException e) {
|
||||
logger.warning("The field ServerPlayerGameMode#gameModeForPlayer is no longer present!");
|
||||
logger.warning("Please report this at https://github.com/Jikoo/OpenInv/issues");
|
||||
logger.warning("Attempting to fall through using reflection. Please verify that SilentContainer does not fail.");
|
||||
// N.B. gameModeForPlayer is (for now) declared before previousGameModeForPlayer so silent shouldn't break.
|
||||
this.serverPlayerGameModeGameType = ReflectionHelper.grabFieldByType(ServerPlayerGameMode.class, GameType.class);
|
||||
}
|
||||
} catch (SecurityException e) {
|
||||
logger.warning("Unable to directly write player game mode! SilentContainer will fail.");
|
||||
logger.log(java.util.logging.Level.WARNING, "Error obtaining GameType field", e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean activateContainer(
|
||||
@NotNull final Player bukkitPlayer,
|
||||
final boolean silentchest,
|
||||
@NotNull final org.bukkit.block.Block bukkitBlock
|
||||
) {
|
||||
|
||||
// Silent ender chest is API-only
|
||||
if (silentchest && bukkitBlock.getType() == Material.ENDER_CHEST) {
|
||||
bukkitPlayer.openInventory(bukkitPlayer.getEnderChest());
|
||||
bukkitPlayer.incrementStatistic(Statistic.ENDERCHEST_OPENED);
|
||||
return true;
|
||||
}
|
||||
|
||||
ServerPlayer player = PlayerManager.getHandle(bukkitPlayer);
|
||||
|
||||
final net.minecraft.world.level.Level level = ((Entity) player).level();
|
||||
final BlockPos blockPos = new BlockPos(bukkitBlock.getX(), bukkitBlock.getY(), bukkitBlock.getZ());
|
||||
final BlockEntity blockEntity = level.getBlockEntity(blockPos);
|
||||
|
||||
if (blockEntity == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (blockEntity instanceof EnderChestBlockEntity enderChestTile) {
|
||||
// Anychest ender chest. See net.minecraft.world.level.block.EnderChestBlock
|
||||
PlayerEnderChestContainer enderChest = player.getEnderChestInventory();
|
||||
enderChest.setActiveChest(enderChestTile);
|
||||
player.openMenu(
|
||||
new SimpleMenuProvider(
|
||||
(containerCounter, playerInventory, ignored) -> {
|
||||
MenuType<?> containers = OpenChestMenu.getChestMenuType(enderChest.getContainerSize());
|
||||
int rows = enderChest.getContainerSize() / 9;
|
||||
return new ChestMenu(containers, containerCounter, playerInventory, enderChest, rows);
|
||||
}, Component.translatable("container.enderchest")
|
||||
)
|
||||
);
|
||||
bukkitPlayer.incrementStatistic(Statistic.ENDERCHEST_OPENED);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!(blockEntity instanceof MenuProvider menuProvider)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
BlockState blockState = level.getBlockState(blockPos);
|
||||
Block block = blockState.getBlock();
|
||||
|
||||
if (block instanceof ChestBlock chestBlock) {
|
||||
|
||||
// boolean flag: do not check if chest is blocked
|
||||
menuProvider = chestBlock.getMenuProvider(blockState, level, blockPos, true);
|
||||
|
||||
if (menuProvider == null) {
|
||||
lang.sendSystemMessage(bukkitPlayer, "messages.error.lootNotGenerated");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (block instanceof TrappedChestBlock) {
|
||||
bukkitPlayer.incrementStatistic(Statistic.TRAPPED_CHEST_TRIGGERED);
|
||||
} else {
|
||||
bukkitPlayer.incrementStatistic(Statistic.CHEST_OPENED);
|
||||
}
|
||||
}
|
||||
|
||||
if (block instanceof ShulkerBoxBlock) {
|
||||
bukkitPlayer.incrementStatistic(Statistic.SHULKER_BOX_OPENED);
|
||||
}
|
||||
|
||||
if (block instanceof BarrelBlock) {
|
||||
bukkitPlayer.incrementStatistic(Statistic.OPEN_BARREL);
|
||||
}
|
||||
|
||||
// AnyChest only - SilentChest not active, container unsupported, or unnecessary.
|
||||
if (!silentchest || player.gameMode.getGameModeForPlayer() == GameType.SPECTATOR) {
|
||||
player.openMenu(menuProvider);
|
||||
return true;
|
||||
}
|
||||
|
||||
// SilentChest requires access to setting players' game mode directly.
|
||||
if (this.serverPlayerGameModeGameType == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (blockEntity instanceof RandomizableContainerBlockEntity lootable) {
|
||||
if (hasLootTable(lootable)) {
|
||||
lang.sendSystemMessage(bukkitPlayer, "messages.error.lootNotGenerated");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
GameType gameType = player.gameMode.getGameModeForPlayer();
|
||||
this.forceGameType(player, GameType.SPECTATOR);
|
||||
player.openMenu(menuProvider);
|
||||
this.forceGameType(player, gameType);
|
||||
return true;
|
||||
}
|
||||
|
||||
protected boolean hasLootTable(@NotNull RandomizableContainerBlockEntity lootable) {
|
||||
return lootable.getLootTable() != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deactivateContainer(@NotNull final Player bukkitPlayer) {
|
||||
if (this.serverPlayerGameModeGameType == null || bukkitPlayer.getGameMode() == GameMode.SPECTATOR) {
|
||||
return;
|
||||
}
|
||||
|
||||
ServerPlayer player = PlayerManager.getHandle(bukkitPlayer);
|
||||
|
||||
// Force game mode change without informing plugins or players.
|
||||
// Regular game mode set calls GameModeChangeEvent and is cancellable.
|
||||
GameType gameType = player.gameMode.getGameModeForPlayer();
|
||||
this.forceGameType(player, GameType.SPECTATOR);
|
||||
|
||||
// ServerPlayer#closeContainer cannot be called without entering an
|
||||
// infinite loop because this method is called during inventory close.
|
||||
// From ServerPlayer#closeContainer -> CraftEventFactory#handleInventoryCloseEvent
|
||||
player.containerMenu.transferTo(player.inventoryMenu, player.getBukkitEntity());
|
||||
// From ServerPlayer#closeContainer
|
||||
player.doCloseContainer();
|
||||
// Regular inventory close will handle the rest - packet sending, etc.
|
||||
|
||||
// Revert forced game mode.
|
||||
this.forceGameType(player, gameType);
|
||||
}
|
||||
|
||||
private void forceGameType(final ServerPlayer player, final GameType gameMode) {
|
||||
if (this.serverPlayerGameModeGameType == null) {
|
||||
// No need to warn repeatedly, error on startup and lack of function should be enough.
|
||||
return;
|
||||
}
|
||||
try {
|
||||
this.serverPlayerGameModeGameType.setAccessible(true);
|
||||
this.serverPlayerGameModeGameType.set(player.gameMode, gameMode);
|
||||
} catch (IllegalArgumentException | IllegalAccessException e) {
|
||||
logger.log(java.util.logging.Level.WARNING, "Error bypassing GameModeChangeEvent", e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected org.bukkit.block.BlockState getState(@NotNull org.bukkit.block.Block block) {
|
||||
return block.getState(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected InventoryHolder getHolder(@NotNull Inventory inventory) {
|
||||
return inventory.getHolder(false);
|
||||
}
|
||||
|
||||
}
|
||||
+16
-16
@@ -1,22 +1,22 @@
|
||||
package com.lishid.openinv.internal.paper26_1.container;
|
||||
package com.lishid.openinv.internal.paper26_2.container;
|
||||
|
||||
import com.lishid.openinv.internal.ISpecialPlayerInventory;
|
||||
import com.lishid.openinv.internal.InternalOwned;
|
||||
import com.lishid.openinv.internal.paper26_1.container.bukkit.OpenPlayerInventory;
|
||||
import com.lishid.openinv.internal.paper26_1.container.menu.OpenChestMenu;
|
||||
import com.lishid.openinv.internal.paper26_1.container.menu.OpenInventoryMenu;
|
||||
import com.lishid.openinv.internal.paper26_1.container.slot.Content;
|
||||
import com.lishid.openinv.internal.paper26_1.container.slot.ContentCrafting;
|
||||
import com.lishid.openinv.internal.paper26_1.container.slot.ContentCraftingResult;
|
||||
import com.lishid.openinv.internal.paper26_1.container.slot.ContentCursor;
|
||||
import com.lishid.openinv.internal.paper26_1.container.slot.ContentDrop;
|
||||
import com.lishid.openinv.internal.paper26_1.container.slot.ContentEquipment;
|
||||
import com.lishid.openinv.internal.paper26_1.container.slot.ContentList;
|
||||
import com.lishid.openinv.internal.paper26_1.container.slot.ContentOffHand;
|
||||
import com.lishid.openinv.internal.paper26_1.container.slot.ContentViewOnly;
|
||||
import com.lishid.openinv.internal.paper26_1.container.slot.SlotViewOnly;
|
||||
import com.lishid.openinv.internal.paper26_1.container.slot.placeholder.Placeholders;
|
||||
import com.lishid.openinv.internal.paper26_1.player.PlayerManager;
|
||||
import com.lishid.openinv.internal.paper26_2.container.bukkit.OpenPlayerInventory;
|
||||
import com.lishid.openinv.internal.paper26_2.container.menu.OpenChestMenu;
|
||||
import com.lishid.openinv.internal.paper26_2.container.menu.OpenInventoryMenu;
|
||||
import com.lishid.openinv.internal.paper26_2.container.slot.Content;
|
||||
import com.lishid.openinv.internal.paper26_2.container.slot.ContentCrafting;
|
||||
import com.lishid.openinv.internal.paper26_2.container.slot.ContentCraftingResult;
|
||||
import com.lishid.openinv.internal.paper26_2.container.slot.ContentCursor;
|
||||
import com.lishid.openinv.internal.paper26_2.container.slot.ContentDrop;
|
||||
import com.lishid.openinv.internal.paper26_2.container.slot.ContentEquipment;
|
||||
import com.lishid.openinv.internal.paper26_2.container.slot.ContentList;
|
||||
import com.lishid.openinv.internal.paper26_2.container.slot.ContentOffHand;
|
||||
import com.lishid.openinv.internal.paper26_2.container.slot.ContentViewOnly;
|
||||
import com.lishid.openinv.internal.paper26_2.container.slot.SlotViewOnly;
|
||||
import com.lishid.openinv.internal.paper26_2.container.slot.placeholder.Placeholders;
|
||||
import com.lishid.openinv.internal.paper26_2.player.PlayerManager;
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
|
||||
import net.minecraft.core.NonNullList;
|
||||
import net.minecraft.network.chat.Component;
|
||||
+205
@@ -0,0 +1,205 @@
|
||||
package com.lishid.openinv.internal.paper26_2.container;
|
||||
|
||||
import com.lishid.openinv.internal.ISpecialEnderChest;
|
||||
import com.lishid.openinv.internal.InternalOwned;
|
||||
import com.lishid.openinv.internal.paper26_2.container.menu.OpenChestMenu;
|
||||
import com.lishid.openinv.internal.paper26_2.container.menu.OpenEnderChestMenu;
|
||||
import com.lishid.openinv.internal.paper26_2.player.PlayerManager;
|
||||
import net.minecraft.core.NonNullList;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.network.chat.MutableComponent;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.world.Container;
|
||||
import net.minecraft.world.ContainerHelper;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraft.world.entity.player.StackedItemContents;
|
||||
import net.minecraft.world.inventory.StackedContentsCompatible;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.craftbukkit.entity.CraftHumanEntity;
|
||||
import org.bukkit.craftbukkit.inventory.CraftInventory;
|
||||
import org.bukkit.entity.HumanEntity;
|
||||
import org.bukkit.event.inventory.InventoryType;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class OpenEnderChest implements Container, StackedContentsCompatible, InternalOwned<ServerPlayer>,
|
||||
ISpecialEnderChest {
|
||||
|
||||
private CraftInventory inventory;
|
||||
private @NotNull ServerPlayer owner;
|
||||
private NonNullList<ItemStack> items;
|
||||
private int maxStack = 64;
|
||||
private final List<HumanEntity> transaction = new ArrayList<>();
|
||||
|
||||
public OpenEnderChest(@NotNull org.bukkit.entity.Player player) {
|
||||
this.owner = PlayerManager.getHandle(player);
|
||||
this.items = getEnderChestItems(owner);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull ServerPlayer getOwnerHandle() {
|
||||
return owner;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull org.bukkit.inventory.Inventory getBukkitInventory() {
|
||||
if (inventory == null) {
|
||||
inventory = new CraftInventory(this) {
|
||||
@Override
|
||||
public @NotNull InventoryType getType() {
|
||||
return InventoryType.ENDER_CHEST;
|
||||
}
|
||||
};
|
||||
}
|
||||
return inventory;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPlayerOnline(@NotNull org.bukkit.entity.Player player) {
|
||||
owner = PlayerManager.getHandle(player);
|
||||
NonNullList<ItemStack> activeItems = getEnderChestItems(owner);
|
||||
|
||||
// Guard against size changing. Theoretically on Purpur all row variations still have 6 rows internally.
|
||||
int max = Math.min(items.size(), activeItems.size());
|
||||
for (int index = 0; index < max; ++index) {
|
||||
activeItems.set(index, items.get(index));
|
||||
}
|
||||
|
||||
items = activeItems;
|
||||
}
|
||||
|
||||
protected @NotNull NonNullList<ItemStack> getEnderChestItems(@NotNull ServerPlayer owner) {
|
||||
return owner.getEnderChestInventory().getItems();
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull org.bukkit.entity.Player getPlayer() {
|
||||
return owner.getBukkitEntity();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getContainerSize() {
|
||||
return items.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEmpty() {
|
||||
return items.stream().allMatch(ItemStack::isEmpty);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull ItemStack getItem(int index) {
|
||||
return index >= 0 && index < items.size() ? items.get(index) : ItemStack.EMPTY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull ItemStack removeItem(int index, int amount) {
|
||||
ItemStack itemstack = ContainerHelper.removeItem(items, index, amount);
|
||||
|
||||
if (!itemstack.isEmpty()) {
|
||||
setChanged();
|
||||
}
|
||||
|
||||
return itemstack;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull ItemStack removeItemNoUpdate(int index) {
|
||||
return index >= 0 && index < items.size() ? items.set(index, ItemStack.EMPTY) : ItemStack.EMPTY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setItem(int index, @NotNull ItemStack itemStack) {
|
||||
if (index >= 0 && index < items.size()) {
|
||||
items.set(index, itemStack);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMaxStackSize() {
|
||||
return maxStack;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setChanged() {
|
||||
this.owner.getEnderChestInventory().setChanged();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean stillValid(@NotNull Player player) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull List<ItemStack> getContents() {
|
||||
return items;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onOpen(@NotNull CraftHumanEntity craftHumanEntity) {
|
||||
transaction.add(craftHumanEntity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClose(@NotNull CraftHumanEntity craftHumanEntity) {
|
||||
transaction.remove(craftHumanEntity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull List<HumanEntity> getViewers() {
|
||||
return transaction;
|
||||
}
|
||||
|
||||
@Override
|
||||
public org.bukkit.entity.Player getOwner() {
|
||||
return getPlayer();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setMaxStackSize(int size) {
|
||||
maxStack = size;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable Location getLocation() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clearContent() {
|
||||
items.clear();
|
||||
setChanged();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fillStackedContents(@NotNull StackedItemContents stackedContents) {
|
||||
for (ItemStack itemstack : items) {
|
||||
stackedContents.accountStack(itemstack);
|
||||
}
|
||||
}
|
||||
|
||||
public Component getTitle(@Nullable OpenChestMenu<?> menu) {
|
||||
MutableComponent component;
|
||||
if (menu != null && menu.isViewOnly()) {
|
||||
component = Component.translatableWithFallback("openinv.container.enderchest.viewonly", "[RO] ");
|
||||
} else {
|
||||
component = Component.translatableWithFallback("openinv.container.enderchest.editable", "");
|
||||
}
|
||||
return component
|
||||
.append(Component.translatableWithFallback("openinv.container.enderchest.prefix", "", owner.getName()))
|
||||
.append(Component.translatable("container.enderchest"))
|
||||
.append(Component.translatableWithFallback("openinv.container.enderchest.suffix", " - %s", owner.getName()));
|
||||
}
|
||||
|
||||
public @Nullable OpenChestMenu<?> createMenu(Player player, int i, boolean viewOnly) {
|
||||
if (player instanceof ServerPlayer serverPlayer) {
|
||||
return new OpenEnderChestMenu(this, serverPlayer, i, viewOnly);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
+2
-2
@@ -1,6 +1,6 @@
|
||||
package com.lishid.openinv.internal.paper26_1.container;
|
||||
package com.lishid.openinv.internal.paper26_2.container;
|
||||
|
||||
import com.lishid.openinv.internal.paper26_1.container.menu.OpenChestMenu;
|
||||
import com.lishid.openinv.internal.paper26_2.container.menu.OpenChestMenu;
|
||||
import net.minecraft.ChatFormatting;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.network.chat.FontDescription;
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
package com.lishid.openinv.internal.paper26_1.container.bukkit;
|
||||
package com.lishid.openinv.internal.paper26_2.container.bukkit;
|
||||
|
||||
import com.lishid.openinv.internal.ViewOnly;
|
||||
import net.minecraft.world.Container;
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
package com.lishid.openinv.internal.paper26_1.container.bukkit;
|
||||
package com.lishid.openinv.internal.paper26_2.container.bukkit;
|
||||
|
||||
import net.minecraft.world.Container;
|
||||
import org.bukkit.Material;
|
||||
+2
-2
@@ -1,7 +1,7 @@
|
||||
package com.lishid.openinv.internal.paper26_1.container.bukkit;
|
||||
package com.lishid.openinv.internal.paper26_2.container.bukkit;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
import com.lishid.openinv.internal.paper26_1.container.BaseOpenInventory;
|
||||
import com.lishid.openinv.internal.paper26_2.container.BaseOpenInventory;
|
||||
import net.minecraft.core.NonNullList;
|
||||
import net.minecraft.world.entity.EquipmentSlot;
|
||||
import net.minecraft.world.entity.player.Inventory;
|
||||
+2
-2
@@ -1,6 +1,6 @@
|
||||
package com.lishid.openinv.internal.paper26_1.container.bukkit;
|
||||
package com.lishid.openinv.internal.paper26_2.container.bukkit;
|
||||
|
||||
import com.lishid.openinv.internal.paper26_1.container.BaseOpenInventory;
|
||||
import com.lishid.openinv.internal.paper26_2.container.BaseOpenInventory;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
+7
-7
@@ -1,12 +1,12 @@
|
||||
package com.lishid.openinv.internal.paper26_1.container.menu;
|
||||
package com.lishid.openinv.internal.paper26_2.container.menu;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
import com.lishid.openinv.internal.paper26_1.container.BaseOpenInventory;
|
||||
import com.lishid.openinv.internal.paper26_1.container.bukkit.OpenDummyPlayerInventory;
|
||||
import com.lishid.openinv.internal.paper26_1.container.bukkit.OpenPlayerInventorySelf;
|
||||
import com.lishid.openinv.internal.paper26_1.container.slot.ContentDrop;
|
||||
import com.lishid.openinv.internal.paper26_1.container.slot.ContentEquipment;
|
||||
import com.lishid.openinv.internal.paper26_1.container.slot.SlotViewOnly;
|
||||
import com.lishid.openinv.internal.paper26_2.container.BaseOpenInventory;
|
||||
import com.lishid.openinv.internal.paper26_2.container.bukkit.OpenDummyPlayerInventory;
|
||||
import com.lishid.openinv.internal.paper26_2.container.bukkit.OpenPlayerInventorySelf;
|
||||
import com.lishid.openinv.internal.paper26_2.container.slot.ContentDrop;
|
||||
import com.lishid.openinv.internal.paper26_2.container.slot.ContentEquipment;
|
||||
import com.lishid.openinv.internal.paper26_2.container.slot.SlotViewOnly;
|
||||
import com.lishid.openinv.util.Permissions;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.world.entity.EquipmentSlot;
|
||||
+3
-3
@@ -1,9 +1,9 @@
|
||||
package com.lishid.openinv.internal.paper26_1.container.menu;
|
||||
package com.lishid.openinv.internal.paper26_2.container.menu;
|
||||
|
||||
import com.lishid.openinv.internal.ISpecialInventory;
|
||||
import com.lishid.openinv.internal.InternalOwned;
|
||||
import com.lishid.openinv.internal.paper26_1.container.bukkit.OpenDummyInventory;
|
||||
import com.lishid.openinv.internal.paper26_1.container.slot.SlotViewOnly;
|
||||
import com.lishid.openinv.internal.paper26_2.container.bukkit.OpenDummyInventory;
|
||||
import com.lishid.openinv.internal.paper26_2.container.slot.SlotViewOnly;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.world.Container;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
+2
-2
@@ -1,6 +1,6 @@
|
||||
package com.lishid.openinv.internal.paper26_1.container.menu;
|
||||
package com.lishid.openinv.internal.paper26_2.container.menu;
|
||||
|
||||
import com.lishid.openinv.internal.paper26_1.container.OpenEnderChest;
|
||||
import com.lishid.openinv.internal.paper26_2.container.OpenEnderChest;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraft.world.inventory.ContainerInput;
|
||||
+2
-2
@@ -1,6 +1,6 @@
|
||||
package com.lishid.openinv.internal.paper26_1.container.menu;
|
||||
package com.lishid.openinv.internal.paper26_2.container.menu;
|
||||
|
||||
import com.lishid.openinv.internal.paper26_1.container.BaseOpenInventory;
|
||||
import com.lishid.openinv.internal.paper26_2.container.BaseOpenInventory;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraft.world.inventory.ContainerInput;
|
||||
+2
-2
@@ -1,9 +1,9 @@
|
||||
package com.lishid.openinv.internal.paper26_1.container.menu;
|
||||
package com.lishid.openinv.internal.paper26_2.container.menu;
|
||||
|
||||
import com.google.common.base.Suppliers;
|
||||
import com.lishid.openinv.internal.ISpecialInventory;
|
||||
import com.lishid.openinv.internal.InternalOwned;
|
||||
import com.lishid.openinv.internal.paper26_1.container.slot.SlotPlaceholder;
|
||||
import com.lishid.openinv.internal.paper26_2.container.slot.SlotPlaceholder;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.world.Container;
|
||||
import net.minecraft.world.inventory.AbstractContainerMenu;
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
package com.lishid.openinv.internal.paper26_1.container.slot;
|
||||
package com.lishid.openinv.internal.paper26_2.container.slot;
|
||||
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.world.Container;
|
||||
+3
-3
@@ -1,7 +1,7 @@
|
||||
package com.lishid.openinv.internal.paper26_1.container.slot;
|
||||
package com.lishid.openinv.internal.paper26_2.container.slot;
|
||||
|
||||
import com.lishid.openinv.internal.paper26_1.container.slot.placeholder.Placeholders;
|
||||
import com.lishid.openinv.internal.paper26_1.player.OpenPlayer;
|
||||
import com.lishid.openinv.internal.paper26_2.container.slot.placeholder.Placeholders;
|
||||
import com.lishid.openinv.internal.paper26_2.player.OpenPlayer;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.world.Container;
|
||||
import net.minecraft.world.ContainerHelper;
|
||||
+2
-2
@@ -1,6 +1,6 @@
|
||||
package com.lishid.openinv.internal.paper26_1.container.slot;
|
||||
package com.lishid.openinv.internal.paper26_2.container.slot;
|
||||
|
||||
import com.lishid.openinv.internal.paper26_1.container.slot.placeholder.Placeholders;
|
||||
import com.lishid.openinv.internal.paper26_2.container.slot.placeholder.Placeholders;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.world.Container;
|
||||
import net.minecraft.world.inventory.InventoryMenu;
|
||||
+3
-3
@@ -1,7 +1,7 @@
|
||||
package com.lishid.openinv.internal.paper26_1.container.slot;
|
||||
package com.lishid.openinv.internal.paper26_2.container.slot;
|
||||
|
||||
import com.lishid.openinv.internal.paper26_1.container.slot.placeholder.Placeholders;
|
||||
import com.lishid.openinv.internal.paper26_1.player.OpenPlayer;
|
||||
import com.lishid.openinv.internal.paper26_2.container.slot.placeholder.Placeholders;
|
||||
import com.lishid.openinv.internal.paper26_2.player.OpenPlayer;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.world.Container;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
+3
-3
@@ -1,7 +1,7 @@
|
||||
package com.lishid.openinv.internal.paper26_1.container.slot;
|
||||
package com.lishid.openinv.internal.paper26_2.container.slot;
|
||||
|
||||
import com.lishid.openinv.internal.paper26_1.container.slot.placeholder.Placeholders;
|
||||
import com.lishid.openinv.internal.paper26_1.player.OpenPlayer;
|
||||
import com.lishid.openinv.internal.paper26_2.container.slot.placeholder.Placeholders;
|
||||
import com.lishid.openinv.internal.paper26_2.player.OpenPlayer;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.world.Container;
|
||||
import net.minecraft.world.inventory.Slot;
|
||||
+2
-2
@@ -1,6 +1,6 @@
|
||||
package com.lishid.openinv.internal.paper26_1.container.slot;
|
||||
package com.lishid.openinv.internal.paper26_2.container.slot;
|
||||
|
||||
import com.lishid.openinv.internal.paper26_1.container.slot.placeholder.Placeholders;
|
||||
import com.lishid.openinv.internal.paper26_2.container.slot.placeholder.Placeholders;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.world.Container;
|
||||
import net.minecraft.world.entity.EntityEquipment;
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
package com.lishid.openinv.internal.paper26_1.container.slot;
|
||||
package com.lishid.openinv.internal.paper26_2.container.slot;
|
||||
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.world.Container;
|
||||
+2
-2
@@ -1,6 +1,6 @@
|
||||
package com.lishid.openinv.internal.paper26_1.container.slot;
|
||||
package com.lishid.openinv.internal.paper26_2.container.slot;
|
||||
|
||||
import com.lishid.openinv.internal.paper26_1.player.OpenPlayer;
|
||||
import com.lishid.openinv.internal.paper26_2.player.OpenPlayer;
|
||||
import net.minecraft.network.protocol.game.ClientboundContainerSetSlotPacket;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.world.Container;
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
package com.lishid.openinv.internal.paper26_1.container.slot;
|
||||
package com.lishid.openinv.internal.paper26_2.container.slot;
|
||||
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.world.Container;
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
package com.lishid.openinv.internal.paper26_1.container.slot;
|
||||
package com.lishid.openinv.internal.paper26_2.container.slot;
|
||||
|
||||
import net.minecraft.world.Container;
|
||||
import net.minecraft.world.inventory.Slot;
|
||||
+9
-9
@@ -1,6 +1,6 @@
|
||||
package com.lishid.openinv.internal.paper26_1.container.slot;
|
||||
package com.lishid.openinv.internal.paper26_2.container.slot;
|
||||
|
||||
import com.lishid.openinv.internal.paper26_1.container.slot.placeholder.Placeholders;
|
||||
import com.lishid.openinv.internal.paper26_2.container.slot.placeholder.Placeholders;
|
||||
import net.minecraft.world.Container;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraft.world.inventory.Slot;
|
||||
@@ -17,14 +17,14 @@ public class SlotViewOnly extends SlotPlaceholder {
|
||||
public static @NotNull SlotViewOnly wrap(@NotNull Slot wrapped) {
|
||||
SlotViewOnly wrapper;
|
||||
if (wrapped instanceof SlotPlaceholder placeholder) {
|
||||
wrapper = new SlotViewOnly(wrapped.container, wrapped.slot, wrapped.x, wrapped.y) {
|
||||
wrapper = new SlotViewOnly(wrapped.container, wrapped.getContainerSlot(), wrapped.x, wrapped.y) {
|
||||
@Override
|
||||
public ItemStack getOrDefault() {
|
||||
return placeholder.getOrDefault();
|
||||
}
|
||||
};
|
||||
} else {
|
||||
wrapper = new SlotViewOnly(wrapped.container, wrapped.slot, wrapped.x, wrapped.y) {
|
||||
wrapper = new SlotViewOnly(wrapped.container, wrapped.getContainerSlot(), wrapped.x, wrapped.y) {
|
||||
@Override
|
||||
public ItemStack getOrDefault() {
|
||||
return wrapped.getItem();
|
||||
@@ -118,6 +118,11 @@ public class SlotViewOnly extends SlotPlaceholder {
|
||||
return ItemStack.EMPTY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull ItemStack safeClone(@NotNull Player player) {
|
||||
return ItemStack.EMPTY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull ItemStack safeInsert(@NotNull ItemStack itemStack) {
|
||||
return itemStack;
|
||||
@@ -133,11 +138,6 @@ public class SlotViewOnly extends SlotPlaceholder {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getContainerSlot() {
|
||||
return this.slot;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isHighlightable() {
|
||||
return false;
|
||||
+27
-11
@@ -1,4 +1,4 @@
|
||||
package com.lishid.openinv.internal.paper26_1.container.slot.placeholder;
|
||||
package com.lishid.openinv.internal.paper26_2.container.slot.placeholder;
|
||||
|
||||
import com.mojang.serialization.DataResult;
|
||||
import net.minecraft.core.Registry;
|
||||
@@ -7,11 +7,15 @@ import net.minecraft.core.component.DataComponents;
|
||||
import net.minecraft.core.registries.Registries;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.nbt.NbtOps;
|
||||
import net.minecraft.nbt.TagParser;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.world.item.DyeColor;
|
||||
import net.minecraft.world.item.Item;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.item.Items;
|
||||
import net.minecraft.world.item.component.CustomModelData;
|
||||
import net.minecraft.world.item.component.DyedItemColor;
|
||||
import net.minecraft.world.item.component.TooltipDisplay;
|
||||
import net.minecraft.world.level.GameType;
|
||||
import net.minecraft.world.level.ItemLike;
|
||||
import net.minecraft.world.level.block.entity.BannerPattern;
|
||||
@@ -22,9 +26,10 @@ import org.bukkit.craftbukkit.CraftRegistry;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
|
||||
public abstract class PlaceholderLoaderBase {
|
||||
public class PlaceholderLoader {
|
||||
|
||||
public void load(@Nullable ConfigurationSection section) throws Exception {
|
||||
Placeholders.craftingOutput = parse(section, "crafting-output", defaultCraftingOutput());
|
||||
@@ -67,7 +72,7 @@ public abstract class PlaceholderLoaderBase {
|
||||
return defaultStack;
|
||||
}
|
||||
|
||||
CompoundTag compoundTag = parseTag(itemText);
|
||||
CompoundTag compoundTag = TagParser.parseCompoundFully(itemText);
|
||||
DataResult<ItemStack> parsed = ItemStack.CODEC.parse(CraftRegistry.getMinecraftRegistry().createSerializationContext(NbtOps.INSTANCE), compoundTag);
|
||||
ItemStack itemStack;
|
||||
try {
|
||||
@@ -78,13 +83,16 @@ public abstract class PlaceholderLoaderBase {
|
||||
return itemStack == null ? defaultStack : itemStack;
|
||||
}
|
||||
|
||||
protected abstract @NotNull CompoundTag parseTag(@NotNull String itemText) throws Exception;
|
||||
private static final CustomModelData DEFAULT_CUSTOM_MODEL_DATA = new CustomModelData(List.of(), List.of(), List.of("openinv:custom"), List.of());
|
||||
private static final TooltipDisplay HIDE_TOOLTIP = new TooltipDisplay(true, new LinkedHashSet<>());
|
||||
|
||||
protected abstract void addModelData(@NotNull ItemStack itemStack);
|
||||
protected void addModelData(@NotNull ItemStack itemStack) {
|
||||
itemStack.set(DataComponents.CUSTOM_MODEL_DATA, DEFAULT_CUSTOM_MODEL_DATA);
|
||||
}
|
||||
|
||||
protected abstract void hideTooltip(@NotNull ItemStack itemStack);
|
||||
|
||||
protected abstract DyedItemColor getDye(int rgb);
|
||||
protected void hideTooltip(@NotNull ItemStack itemStack) {
|
||||
itemStack.set(DataComponents.TOOLTIP_DISPLAY, HIDE_TOOLTIP);
|
||||
}
|
||||
|
||||
protected @NotNull ItemStack defaultCraftingOutput() {
|
||||
// Crafting table: "Crafting"
|
||||
@@ -96,7 +104,7 @@ public abstract class PlaceholderLoaderBase {
|
||||
|
||||
protected @NotNull ItemStack defaultCursor() {
|
||||
// Cursor-like banner with no tooltip
|
||||
ItemStack itemStack = new ItemStack(Items.WHITE_BANNER);
|
||||
ItemStack itemStack = new ItemStack(getDefaultCursorItem());
|
||||
RegistryAccess minecraftRegistry = CraftRegistry.getMinecraftRegistry();
|
||||
Registry<BannerPattern> bannerPatterns = minecraftRegistry.lookupOrThrow(Registries.BANNER_PATTERN);
|
||||
BannerPattern halfDiagBottomRight = bannerPatterns.getOrThrow(BannerPatterns.DIAGONAL_RIGHT).value();
|
||||
@@ -126,7 +134,7 @@ public abstract class PlaceholderLoaderBase {
|
||||
protected @NotNull ItemStack getEmptyArmor(@NotNull ItemLike item) {
|
||||
// Inventory-background-grey-ish leather armor with no tooltip
|
||||
ItemStack itemStack = new ItemStack(item);
|
||||
DyedItemColor color = getDye(0xC8C8C8);
|
||||
DyedItemColor color = new DyedItemColor(0xC8C8C8);
|
||||
itemStack.set(DataComponents.DYED_COLOR, color);
|
||||
hideTooltip(itemStack);
|
||||
addModelData(itemStack);
|
||||
@@ -160,12 +168,20 @@ public abstract class PlaceholderLoaderBase {
|
||||
|
||||
protected @NotNull ItemStack defaultNotSlot() {
|
||||
// White pane with no tooltip
|
||||
ItemStack itemStack = new ItemStack(Items.WHITE_STAINED_GLASS_PANE);
|
||||
ItemStack itemStack = new ItemStack(getDefaultNotSlotItem());
|
||||
hideTooltip(itemStack);
|
||||
addModelData(itemStack);
|
||||
return itemStack;
|
||||
}
|
||||
|
||||
protected @NotNull Item getDefaultCursorItem() {
|
||||
return Items.BANNER.white();
|
||||
}
|
||||
|
||||
protected @NotNull Item getDefaultNotSlotItem() {
|
||||
return Items.STAINED_GLASS_PANE.white();
|
||||
}
|
||||
|
||||
protected @NotNull ItemStack defaultBlockedOffline() {
|
||||
// Barrier: "Not available - Offline"
|
||||
ItemStack itemStack = new ItemStack(Items.BARRIER);
|
||||
+6
-2
@@ -1,6 +1,6 @@
|
||||
package com.lishid.openinv.internal.paper26_1.container.slot.placeholder;
|
||||
package com.lishid.openinv.internal.paper26_2.container.slot.placeholder;
|
||||
|
||||
import com.lishid.openinv.internal.paper26_1.player.OpenPlayer;
|
||||
import com.lishid.openinv.internal.paper26_2.player.OpenPlayer;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.level.GameType;
|
||||
@@ -10,6 +10,10 @@ import java.util.EnumMap;
|
||||
|
||||
public final class Placeholders {
|
||||
|
||||
// N.B. Slot#getNoItemIcon is still clientside, unfortunately.
|
||||
// Worth checking every few updates just in case - it would be nice to
|
||||
// get rid of some of the placeholders.
|
||||
|
||||
static final @NotNull EnumMap<GameType, ItemStack> BLOCKED_GAME_TYPE = new EnumMap<>(GameType.class);
|
||||
public static @NotNull ItemStack craftingOutput = ItemStack.EMPTY;
|
||||
public static @NotNull ItemStack cursor = ItemStack.EMPTY;
|
||||
+4
-13
@@ -1,4 +1,4 @@
|
||||
package com.lishid.openinv.internal.paper26_1.player;
|
||||
package com.lishid.openinv.internal.paper26_2.player;
|
||||
|
||||
import com.lishid.openinv.event.OpenEvents;
|
||||
import com.mojang.logging.LogUtils;
|
||||
@@ -23,7 +23,6 @@ import org.slf4j.Logger;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
|
||||
public class OpenPlayer extends CraftPlayer {
|
||||
@@ -54,6 +53,7 @@ public class OpenPlayer extends CraftPlayer {
|
||||
// Intentional omissions to prevent mount loss: Attach, Entity, and RootVehicle
|
||||
"warden_spawn_tracker", // No longer needed as of 1.21.11
|
||||
"entered_nether_pos",
|
||||
"last_explosion_impact_pos",
|
||||
"respawn",
|
||||
"raid_omen_position",
|
||||
"ender_pearls",
|
||||
@@ -98,9 +98,8 @@ public class OpenPlayer extends CraftPlayer {
|
||||
try (ProblemReporter.ScopedCollector scopedCollector = new ProblemReporter.ScopedCollector(player.problemPath(), logger)) {
|
||||
PlayerDataStorage worldNbtStorage = server.getServer().getPlayerList().playerIo;
|
||||
|
||||
CompoundTag oldData = isOnline()
|
||||
? null
|
||||
: load(worldNbtStorage, player, scopedCollector).orElse(null);
|
||||
CompoundTag oldData;
|
||||
oldData = isOnline() ? null : worldNbtStorage.load(player.nameAndId()).orElse(null);
|
||||
CompoundTag playerData = getWritableTag(oldData);
|
||||
|
||||
ValueOutput valueOutput = TagValueOutput.createWrappingWithContext(scopedCollector, player.registryAccess(), playerData);
|
||||
@@ -112,14 +111,6 @@ public class OpenPlayer extends CraftPlayer {
|
||||
}
|
||||
}
|
||||
|
||||
protected Optional<CompoundTag> load(
|
||||
PlayerDataStorage storage,
|
||||
ServerPlayer player,
|
||||
ProblemReporter.ScopedCollector collector
|
||||
) {
|
||||
return storage.load(player.nameAndId());
|
||||
}
|
||||
|
||||
protected void saveSafe(
|
||||
@NotNull ServerPlayer player,
|
||||
@Nullable CompoundTag oldData,
|
||||
+330
@@ -0,0 +1,330 @@
|
||||
package com.lishid.openinv.internal.paper26_2.player;
|
||||
|
||||
import com.lishid.openinv.internal.ISpecialInventory;
|
||||
import com.lishid.openinv.internal.paper26_2.container.BaseOpenInventory;
|
||||
import com.lishid.openinv.internal.paper26_2.container.OpenEnderChest;
|
||||
import com.lishid.openinv.internal.paper26_2.container.menu.OpenChestMenu;
|
||||
import com.lishid.openinv.util.JulLoggerAdapter;
|
||||
import com.mojang.authlib.GameProfile;
|
||||
import com.mojang.logging.LogUtils;
|
||||
import io.papermc.paper.adventure.PaperAdventure;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.network.protocol.game.ClientboundOpenScreenPacket;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.server.level.ClientInformation;
|
||||
import net.minecraft.server.level.ParticleStatus;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.util.ProblemReporter;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.entity.player.ChatVisiblity;
|
||||
import net.minecraft.world.inventory.AbstractContainerMenu;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.storage.LevelData;
|
||||
import net.minecraft.world.level.storage.TagValueInput;
|
||||
import net.minecraft.world.level.storage.TagValueOutput;
|
||||
import net.minecraft.world.level.storage.ValueInput;
|
||||
import net.minecraft.world.level.storage.ValueOutput;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
import org.bukkit.Server;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.craftbukkit.CraftServer;
|
||||
import org.bukkit.craftbukkit.CraftWorld;
|
||||
import org.bukkit.craftbukkit.entity.CraftPlayer;
|
||||
import org.bukkit.craftbukkit.event.CraftEventFactory;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.InventoryView;
|
||||
import org.jspecify.annotations.NullMarked;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
@NullMarked
|
||||
public class PlayerManager implements com.lishid.openinv.internal.PlayerManager {
|
||||
|
||||
protected final Logger logger;
|
||||
protected @Nullable Field bukkitEntity;
|
||||
|
||||
public PlayerManager(Logger logger) {
|
||||
this.logger = logger;
|
||||
try {
|
||||
bukkitEntity = Entity.class.getDeclaredField("bukkitEntity");
|
||||
} catch (NoSuchFieldException e) {
|
||||
logger.warning("Unable to obtain field to inject custom save process - certain player data may be lost when saving!");
|
||||
logger.log(java.util.logging.Level.WARNING, e.getMessage(), e);
|
||||
bukkitEntity = null;
|
||||
}
|
||||
}
|
||||
|
||||
public static ServerPlayer getHandle(final Player player) {
|
||||
if (player instanceof CraftPlayer craftPlayer) {
|
||||
return craftPlayer.getHandle();
|
||||
}
|
||||
|
||||
Server server = player.getServer();
|
||||
ServerPlayer nmsPlayer = null;
|
||||
|
||||
if (server instanceof CraftServer craftServer) {
|
||||
nmsPlayer = craftServer.getHandle().getPlayer(player.getUniqueId());
|
||||
}
|
||||
|
||||
if (nmsPlayer == null) {
|
||||
// Could use reflection to examine fields, but it's honestly not worth the bother.
|
||||
throw new RuntimeException("Unable to fetch EntityPlayer from Player implementation " + player.getClass().getName());
|
||||
}
|
||||
|
||||
return nmsPlayer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable Player loadPlayer(final OfflinePlayer offline) {
|
||||
if (!(Bukkit.getServer() instanceof CraftServer craftServer)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
MinecraftServer server = craftServer.getServer();
|
||||
ServerLevel worldServer = server.getLevel(Level.OVERWORLD);
|
||||
|
||||
if (worldServer == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Create a new ServerPlayer.
|
||||
ServerPlayer entity = createNewPlayer(server, worldServer, offline);
|
||||
|
||||
// Stop listening for advancement progression - if this is not cleaned up, loading causes a memory leak.
|
||||
removeAdvancementListeners(entity);
|
||||
|
||||
// Try to load the player's data.
|
||||
if (loadData(server, entity)) {
|
||||
// If data is loaded successfully, return the Bukkit entity.
|
||||
return entity.getBukkitEntity();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
protected ServerPlayer createNewPlayer(
|
||||
MinecraftServer server,
|
||||
ServerLevel worldServer,
|
||||
final OfflinePlayer offline
|
||||
) {
|
||||
// See net.minecraft.server.players.PlayerList#canPlayerLogin(ServerLoginPacketListenerImpl, GameProfile)
|
||||
// See net.minecraft.server.network.ServerLoginPacketListenerImpl#handleHello(ServerboundHelloPacket)
|
||||
GameProfile profile = new GameProfile(offline.getUniqueId(),
|
||||
offline.getName() != null ? offline.getName() : offline.getUniqueId().toString()
|
||||
);
|
||||
|
||||
ClientInformation dummyInfo = new ClientInformation(
|
||||
"en_us",
|
||||
1, // Reduce distance just in case.
|
||||
ChatVisiblity.HIDDEN, // Don't accept chat.
|
||||
false,
|
||||
ServerPlayer.DEFAULT_MODEL_CUSTOMIZATION,
|
||||
ServerPlayer.DEFAULT_MAIN_HAND,
|
||||
true,
|
||||
false, // Don't list in player list (not that this player is in the list anyway).
|
||||
ParticleStatus.MINIMAL
|
||||
);
|
||||
|
||||
ServerPlayer entity = new ServerPlayer(server, worldServer, profile, dummyInfo);
|
||||
|
||||
try {
|
||||
injectPlayer(server, entity);
|
||||
} catch (IllegalAccessException e) {
|
||||
logger.log(
|
||||
java.util.logging.Level.WARNING,
|
||||
e,
|
||||
() -> "Unable to inject ServerPlayer, certain player data may be lost when saving!"
|
||||
);
|
||||
}
|
||||
|
||||
return entity;
|
||||
}
|
||||
|
||||
protected void removeAdvancementListeners(ServerPlayer entity) {
|
||||
entity.getAdvancements().clearTriggers();
|
||||
}
|
||||
|
||||
protected boolean loadData(MinecraftServer server, ServerPlayer player) {
|
||||
// See CraftPlayer#loadData
|
||||
|
||||
try (ProblemReporter.ScopedCollector scopedCollector = new ProblemReporter.ScopedCollector(player.problemPath(), new JulLoggerAdapter(logger))) {
|
||||
CompoundTag loadedData = server.getPlayerList().playerIo.load(player.nameAndId()).orElse(null);
|
||||
|
||||
if (loadedData == null) {
|
||||
// Exceptions with loading are logged.
|
||||
return false;
|
||||
}
|
||||
|
||||
ValueInput valueInput = TagValueInput.create(scopedCollector, player.registryAccess(), loadedData);
|
||||
|
||||
// Read basic data into the player.
|
||||
player.load(valueInput);
|
||||
|
||||
// World is not loaded by ServerPlayer#load(CompoundTag) on Paper.
|
||||
parseWorld(server, player, valueInput);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
protected void parseWorld(
|
||||
MinecraftServer server,
|
||||
ServerPlayer player,
|
||||
ValueInput loadedData
|
||||
) {
|
||||
// See PlayerList#placeNewPlayer
|
||||
World bukkitWorld;
|
||||
Optional<Long> msbs = loadedData.getLong("WorldUUIDMost");
|
||||
Optional<Long> lsbs = loadedData.getLong("WorldUUIDLeast");
|
||||
if (msbs.isPresent() && lsbs.isPresent()) {
|
||||
// Modern Bukkit world.
|
||||
bukkitWorld = Bukkit.getServer().getWorld(new UUID(msbs.get(), lsbs.get()));
|
||||
} else {
|
||||
bukkitWorld = loadedData.getString("world").map(Bukkit::getWorld).orElse(null);
|
||||
}
|
||||
if (bukkitWorld == null) {
|
||||
spawnInDefaultWorld(server, player);
|
||||
return;
|
||||
}
|
||||
player.setServerLevel(((CraftWorld) bukkitWorld).getHandle());
|
||||
}
|
||||
|
||||
protected void spawnInDefaultWorld(MinecraftServer server, ServerPlayer player) {
|
||||
ServerLevel level = server.getLevel(Level.OVERWORLD);
|
||||
if (level != null) {
|
||||
// Adjust player to default spawn (in keeping with Paper handling) when world not found.
|
||||
LevelData.RespawnData respawnData = getRespawnData(level);
|
||||
player.snapTo(getAdjustedSpawnLocation(player, level, respawnData), respawnData.yaw(), 0.0F);
|
||||
setServerLevel(player, level);
|
||||
} else {
|
||||
logger.warning("Tried to load player with invalid world when no fallback was available!");
|
||||
}
|
||||
}
|
||||
|
||||
protected LevelData.RespawnData getRespawnData(ServerLevel level) {
|
||||
return level.getRespawnData();
|
||||
}
|
||||
|
||||
protected Vec3 getAdjustedSpawnLocation(
|
||||
ServerPlayer player,
|
||||
ServerLevel level,
|
||||
LevelData.RespawnData respawnData
|
||||
) {
|
||||
return Vec3.atBottomCenterOf(player.adjustSpawnLocation(level, respawnData.pos()));
|
||||
}
|
||||
|
||||
protected void setServerLevel(ServerPlayer player, ServerLevel level) {
|
||||
player.setServerLevel(level);
|
||||
}
|
||||
|
||||
protected void injectPlayer(MinecraftServer server, ServerPlayer player) throws IllegalAccessException {
|
||||
if (bukkitEntity == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
bukkitEntity.setAccessible(true);
|
||||
|
||||
bukkitEntity.set(player, new OpenPlayer(server.server, player, this));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Player inject(Player player) {
|
||||
try {
|
||||
ServerPlayer nmsPlayer = getHandle(player);
|
||||
if (nmsPlayer.getBukkitEntity() instanceof OpenPlayer openPlayer) {
|
||||
return openPlayer;
|
||||
}
|
||||
|
||||
org.slf4j.Logger logger = LogUtils.getLogger();
|
||||
|
||||
try (ProblemReporter.ScopedCollector scopedCollector = new ProblemReporter.ScopedCollector(nmsPlayer.problemPath(), logger)) {
|
||||
CompoundTag extraData = new CompoundTag();
|
||||
|
||||
// Copy extra data out of existing player.
|
||||
ValueOutput output = TagValueOutput.createWrappingWithContext(scopedCollector, nmsPlayer.registryAccess(), extraData);
|
||||
nmsPlayer.getBukkitEntity().setExtraData(output);
|
||||
|
||||
MinecraftServer server = nmsPlayer.level().getServer();
|
||||
injectPlayer(server, nmsPlayer);
|
||||
CraftPlayer newPlayer = nmsPlayer.getBukkitEntity();
|
||||
|
||||
// Set extra data in new player.
|
||||
ValueInput input = TagValueInput.create(scopedCollector, nmsPlayer.registryAccess(), extraData);
|
||||
newPlayer.readExtraData(input);
|
||||
|
||||
return newPlayer;
|
||||
}
|
||||
} catch (IllegalAccessException e) {
|
||||
logger.log(
|
||||
java.util.logging.Level.WARNING,
|
||||
e,
|
||||
() -> "Unable to inject ServerPlayer, certain player data may be lost when saving!"
|
||||
);
|
||||
return player;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable InventoryView openInventory(
|
||||
Player bukkitPlayer,
|
||||
ISpecialInventory inventory,
|
||||
boolean viewOnly
|
||||
) {
|
||||
ServerPlayer player = getHandle(bukkitPlayer);
|
||||
|
||||
if (!OpenPlayer.isConnected(player.connection)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// See net.minecraft.server.level.ServerPlayer#openMenu(MenuProvider)
|
||||
OpenChestMenu<?> menu;
|
||||
Component title;
|
||||
if (inventory instanceof BaseOpenInventory playerInv) {
|
||||
menu = playerInv.createMenu(player, player.nextContainerCounter(), viewOnly);
|
||||
title = playerInv.getTitle(player, menu);
|
||||
} else if (inventory instanceof OpenEnderChest enderChest) {
|
||||
menu = enderChest.createMenu(player, player.nextContainerCounter(), viewOnly);
|
||||
title = enderChest.getTitle(menu);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Should never happen, player is a ServerPlayer with an active connection.
|
||||
if (menu == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Set up title. Title can only be set once for a menu, and is set during the open process.
|
||||
// Further title changes are a hack where the client is sent a "new" inventory with the same ID,
|
||||
// resulting in a title change but no other state modifications (like cursor position).
|
||||
menu.setTitle(title);
|
||||
|
||||
var pair = CraftEventFactory.callInventoryOpenEventWithTitle(player, menu);
|
||||
AbstractContainerMenu opened = pair.getSecond();
|
||||
|
||||
// Menu is null if event is cancelled.
|
||||
if (opened == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
var newTitle = pair.getFirst();
|
||||
if (newTitle != null) {
|
||||
title = PaperAdventure.asVanilla(newTitle);
|
||||
}
|
||||
|
||||
player.containerMenu = opened;
|
||||
player.connection.send(new ClientboundOpenScreenPacket(opened.containerId, opened.getType(), title));
|
||||
player.initMenu(opened);
|
||||
|
||||
return opened.getBukkitView();
|
||||
}
|
||||
|
||||
}
|
||||
-40
@@ -1,40 +0,0 @@
|
||||
package com.github.jikoo.openinv.internal.spigot26_1.container.slot.placeholder;
|
||||
|
||||
import net.minecraft.core.component.DataComponents;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.nbt.TagParser;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.item.component.CustomModelData;
|
||||
import net.minecraft.world.item.component.DyedItemColor;
|
||||
import net.minecraft.world.item.component.TooltipDisplay;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
|
||||
public class PlaceholderLoader extends PlaceholderLoaderBase {
|
||||
|
||||
private static final CustomModelData DEFAULT_CUSTOM_MODEL_DATA = new CustomModelData(List.of(), List.of(), List.of("openinv:custom"), List.of());
|
||||
private static final TooltipDisplay HIDE_TOOLTIP = new TooltipDisplay(true, new LinkedHashSet<>());
|
||||
|
||||
@Override
|
||||
protected @NotNull CompoundTag parseTag(@NotNull String itemText) throws Exception {
|
||||
return TagParser.parseCompoundFully(itemText);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void addModelData(@NotNull ItemStack itemStack) {
|
||||
itemStack.set(DataComponents.CUSTOM_MODEL_DATA, DEFAULT_CUSTOM_MODEL_DATA);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void hideTooltip(@NotNull ItemStack itemStack) {
|
||||
itemStack.set(DataComponents.TOOLTIP_DISPLAY, HIDE_TOOLTIP);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected DyedItemColor getDye(int rgb) {
|
||||
return new DyedItemColor(rgb);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
import com.github.jikoo.openinv.SpigotDependencyExtension
|
||||
import com.github.jikoo.openinv.SpigotSetup
|
||||
|
||||
plugins {
|
||||
alias(libs.plugins.shadow)
|
||||
}
|
||||
|
||||
repositories {
|
||||
maven("https://repo.papermc.io/repository/maven-public/")
|
||||
}
|
||||
|
||||
java {
|
||||
toolchain.languageVersion = JavaLanguageVersion.of(25)
|
||||
}
|
||||
|
||||
tasks.withType<JavaCompile>().configureEach {
|
||||
options.release = 21
|
||||
}
|
||||
|
||||
apply<SpigotSetup>()
|
||||
|
||||
dependencies {
|
||||
compileOnly(libs.spigotapi)
|
||||
extensions.getByType(SpigotDependencyExtension::class.java).version = "26.1.2-R0.1-SNAPSHOT"
|
||||
compileOnly("com.mojang:logging:1.6.11")
|
||||
compileOnly("com.mojang:brigadier:1.3.10")
|
||||
compileOnly("com.mojang:datafixerupper:9.0.19")
|
||||
compileOnly("com.mojang:authlib:7.0.62")
|
||||
|
||||
compileOnly(project(":openinvapi"))
|
||||
compileOnly(project(":openinvcommon"))
|
||||
|
||||
compileOnly(project(":openinvadapterspigot26_2")) {
|
||||
exclude(group = "org.spigotmc", module = "spigot")
|
||||
}
|
||||
}
|
||||
+38
@@ -0,0 +1,38 @@
|
||||
package com.github.jikoo.openinv.internal.spigot26_1;
|
||||
|
||||
import com.github.jikoo.openinv.internal.spigot26_1.container.slot.placeholder.PlaceholderLoader;
|
||||
import com.github.jikoo.openinv.internal.spigot26_1.player.PlayerManager;
|
||||
import com.lishid.openinv.util.lang.LanguageManager;
|
||||
import org.bukkit.configuration.ConfigurationSection;
|
||||
import org.jspecify.annotations.NullMarked;
|
||||
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
@NullMarked
|
||||
public class InternalAccessor extends com.github.jikoo.openinv.internal.spigot26_2.InternalAccessor {
|
||||
|
||||
private final PlayerManager manager;
|
||||
|
||||
public InternalAccessor(Logger logger, LanguageManager lang) {
|
||||
super(logger, lang);
|
||||
this.manager = new PlayerManager(logger);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PlayerManager getPlayerManager() {
|
||||
return manager;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reload(ConfigurationSection config) {
|
||||
ConfigurationSection placeholders = config.getConfigurationSection("placeholders");
|
||||
try {
|
||||
// Reset placeholders to defaults and try to load configuration.
|
||||
new PlaceholderLoader().load(placeholders);
|
||||
} catch (Exception e) {
|
||||
logger.log(Level.WARNING, "Caught exception loading placeholder overrides!", e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
package com.github.jikoo.openinv.internal.spigot26_1.container.slot.placeholder;
|
||||
|
||||
import com.github.jikoo.openinv.internal.spigot26_2.container.slot.placeholder.PlaceholderLoaderBase;
|
||||
import net.minecraft.world.item.Item;
|
||||
import net.minecraft.world.item.Items;
|
||||
import org.jspecify.annotations.NullMarked;
|
||||
|
||||
@NullMarked
|
||||
public class PlaceholderLoader extends PlaceholderLoaderBase {
|
||||
|
||||
@Override
|
||||
protected Item getWhiteBanner() {
|
||||
return Items.WHITE_BANNER;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Item getWhiteGlassPane() {
|
||||
return Items.WHITE_STAINED_GLASS_PANE;
|
||||
}
|
||||
|
||||
}
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
package com.github.jikoo.openinv.internal.spigot26_1.player;
|
||||
|
||||
import net.minecraft.server.PlayerAdvancements;
|
||||
import org.jspecify.annotations.NullMarked;
|
||||
|
||||
import java.util.logging.Logger;
|
||||
|
||||
@NullMarked
|
||||
public class PlayerManager extends com.github.jikoo.openinv.internal.spigot26_2.player.PlayerManager {
|
||||
|
||||
public PlayerManager(Logger logger) {
|
||||
super(logger);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void removeListeners(PlayerAdvancements advancements) {
|
||||
advancements.stopListening();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -21,7 +21,7 @@ apply<SpigotSetup>()
|
||||
|
||||
dependencies {
|
||||
compileOnly(libs.spigotapi)
|
||||
extensions.getByType(SpigotDependencyExtension::class.java).version = "26.1.2-R0.1-SNAPSHOT"
|
||||
extensions.getByType(SpigotDependencyExtension::class.java).version = "26.2-R0.1-SNAPSHOT"
|
||||
compileOnly("com.mojang:logging:1.6.11")
|
||||
compileOnly("com.mojang:brigadier:1.3.10")
|
||||
compileOnly("com.mojang:datafixerupper:9.0.19")
|
||||
+6
-6
@@ -1,10 +1,10 @@
|
||||
package com.github.jikoo.openinv.internal.spigot26_1;
|
||||
package com.github.jikoo.openinv.internal.spigot26_2;
|
||||
|
||||
import com.github.jikoo.openinv.internal.spigot26_1.container.AnySilentContainer;
|
||||
import com.github.jikoo.openinv.internal.spigot26_1.container.OpenInventory;
|
||||
import com.github.jikoo.openinv.internal.spigot26_1.container.OpenEnderChest;
|
||||
import com.github.jikoo.openinv.internal.spigot26_1.container.slot.placeholder.PlaceholderLoader;
|
||||
import com.github.jikoo.openinv.internal.spigot26_1.player.PlayerManager;
|
||||
import com.github.jikoo.openinv.internal.spigot26_2.container.AnySilentContainer;
|
||||
import com.github.jikoo.openinv.internal.spigot26_2.container.OpenInventory;
|
||||
import com.github.jikoo.openinv.internal.spigot26_2.container.OpenEnderChest;
|
||||
import com.github.jikoo.openinv.internal.spigot26_2.container.slot.placeholder.PlaceholderLoader;
|
||||
import com.github.jikoo.openinv.internal.spigot26_2.player.PlayerManager;
|
||||
import com.lishid.openinv.internal.Accessor;
|
||||
import com.lishid.openinv.internal.IAnySilentContainer;
|
||||
import com.lishid.openinv.internal.ISpecialEnderChest;
|
||||
+3
-3
@@ -1,8 +1,8 @@
|
||||
package com.github.jikoo.openinv.internal.spigot26_1.container;
|
||||
package com.github.jikoo.openinv.internal.spigot26_2.container;
|
||||
|
||||
import com.lishid.openinv.internal.AnySilentContainerBase;
|
||||
import com.github.jikoo.openinv.internal.spigot26_1.container.menu.OpenChestMenu;
|
||||
import com.github.jikoo.openinv.internal.spigot26_1.player.PlayerManager;
|
||||
import com.github.jikoo.openinv.internal.spigot26_2.container.menu.OpenChestMenu;
|
||||
import com.github.jikoo.openinv.internal.spigot26_2.player.PlayerManager;
|
||||
import com.lishid.openinv.util.ReflectionHelper;
|
||||
import com.lishid.openinv.util.lang.LanguageManager;
|
||||
import net.minecraft.core.BlockPos;
|
||||
+4
-4
@@ -1,8 +1,8 @@
|
||||
package com.github.jikoo.openinv.internal.spigot26_1.container;
|
||||
package com.github.jikoo.openinv.internal.spigot26_2.container;
|
||||
|
||||
import com.github.jikoo.openinv.internal.spigot26_1.container.menu.OpenChestMenu;
|
||||
import com.github.jikoo.openinv.internal.spigot26_1.container.menu.OpenEnderChestMenu;
|
||||
import com.github.jikoo.openinv.internal.spigot26_1.player.PlayerManager;
|
||||
import com.github.jikoo.openinv.internal.spigot26_2.container.menu.OpenChestMenu;
|
||||
import com.github.jikoo.openinv.internal.spigot26_2.container.menu.OpenEnderChestMenu;
|
||||
import com.github.jikoo.openinv.internal.spigot26_2.player.PlayerManager;
|
||||
import com.lishid.openinv.internal.ISpecialEnderChest;
|
||||
import com.lishid.openinv.internal.InternalOwned;
|
||||
import net.minecraft.core.NonNullList;
|
||||
+16
-16
@@ -1,20 +1,20 @@
|
||||
package com.github.jikoo.openinv.internal.spigot26_1.container;
|
||||
package com.github.jikoo.openinv.internal.spigot26_2.container;
|
||||
|
||||
import com.github.jikoo.openinv.internal.spigot26_1.container.bukkit.OpenPlayerInventory;
|
||||
import com.github.jikoo.openinv.internal.spigot26_1.container.menu.OpenChestMenu;
|
||||
import com.github.jikoo.openinv.internal.spigot26_1.container.menu.OpenInventoryMenu;
|
||||
import com.github.jikoo.openinv.internal.spigot26_1.container.slot.Content;
|
||||
import com.github.jikoo.openinv.internal.spigot26_1.container.slot.ContentCrafting;
|
||||
import com.github.jikoo.openinv.internal.spigot26_1.container.slot.ContentCraftingResult;
|
||||
import com.github.jikoo.openinv.internal.spigot26_1.container.slot.ContentCursor;
|
||||
import com.github.jikoo.openinv.internal.spigot26_1.container.slot.ContentDrop;
|
||||
import com.github.jikoo.openinv.internal.spigot26_1.container.slot.ContentEquipment;
|
||||
import com.github.jikoo.openinv.internal.spigot26_1.container.slot.ContentList;
|
||||
import com.github.jikoo.openinv.internal.spigot26_1.container.slot.ContentOffHand;
|
||||
import com.github.jikoo.openinv.internal.spigot26_1.container.slot.ContentViewOnly;
|
||||
import com.github.jikoo.openinv.internal.spigot26_1.container.slot.SlotViewOnly;
|
||||
import com.github.jikoo.openinv.internal.spigot26_1.container.slot.placeholder.Placeholders;
|
||||
import com.github.jikoo.openinv.internal.spigot26_1.player.PlayerManager;
|
||||
import com.github.jikoo.openinv.internal.spigot26_2.container.bukkit.OpenPlayerInventory;
|
||||
import com.github.jikoo.openinv.internal.spigot26_2.container.menu.OpenChestMenu;
|
||||
import com.github.jikoo.openinv.internal.spigot26_2.container.menu.OpenInventoryMenu;
|
||||
import com.github.jikoo.openinv.internal.spigot26_2.container.slot.Content;
|
||||
import com.github.jikoo.openinv.internal.spigot26_2.container.slot.ContentCrafting;
|
||||
import com.github.jikoo.openinv.internal.spigot26_2.container.slot.ContentCraftingResult;
|
||||
import com.github.jikoo.openinv.internal.spigot26_2.container.slot.ContentCursor;
|
||||
import com.github.jikoo.openinv.internal.spigot26_2.container.slot.ContentDrop;
|
||||
import com.github.jikoo.openinv.internal.spigot26_2.container.slot.ContentEquipment;
|
||||
import com.github.jikoo.openinv.internal.spigot26_2.container.slot.ContentList;
|
||||
import com.github.jikoo.openinv.internal.spigot26_2.container.slot.ContentOffHand;
|
||||
import com.github.jikoo.openinv.internal.spigot26_2.container.slot.ContentViewOnly;
|
||||
import com.github.jikoo.openinv.internal.spigot26_2.container.slot.SlotViewOnly;
|
||||
import com.github.jikoo.openinv.internal.spigot26_2.container.slot.placeholder.Placeholders;
|
||||
import com.github.jikoo.openinv.internal.spigot26_2.player.PlayerManager;
|
||||
import com.lishid.openinv.internal.ISpecialPlayerInventory;
|
||||
import com.lishid.openinv.internal.InternalOwned;
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
|
||||
+6
-1
@@ -1,4 +1,4 @@
|
||||
package com.github.jikoo.openinv.internal.spigot26_1.container.bukkit;
|
||||
package com.github.jikoo.openinv.internal.spigot26_2.container.bukkit;
|
||||
|
||||
import com.lishid.openinv.internal.ViewOnly;
|
||||
import net.minecraft.world.Container;
|
||||
@@ -40,16 +40,19 @@ public class OpenDummyInventory extends CraftInventory implements ViewOnly {
|
||||
|
||||
}
|
||||
|
||||
@SuppressWarnings("NonApiType")
|
||||
@Override
|
||||
public @NotNull HashMap<Integer, ItemStack> addItem(@NotNull ItemStack... items) throws IllegalArgumentException {
|
||||
return arrayToHashMap(items);
|
||||
}
|
||||
|
||||
@SuppressWarnings("NonApiType")
|
||||
@Override
|
||||
public @NotNull HashMap<Integer, ItemStack> removeItem(@NotNull ItemStack... items) throws IllegalArgumentException {
|
||||
return arrayToHashMap(items);
|
||||
}
|
||||
|
||||
@SuppressWarnings("NonApiType")
|
||||
private static @NotNull HashMap<Integer, ItemStack> arrayToHashMap(@NotNull ItemStack[] items) {
|
||||
HashMap<Integer, ItemStack> ignored = new HashMap<>();
|
||||
for (int index = 0; index < items.length; ++index) {
|
||||
@@ -103,6 +106,7 @@ public class OpenDummyInventory extends CraftInventory implements ViewOnly {
|
||||
return false;
|
||||
}
|
||||
|
||||
@SuppressWarnings("NonApiType")
|
||||
@Override
|
||||
public @NotNull HashMap<Integer, ItemStack> all(
|
||||
@NotNull Material material
|
||||
@@ -110,6 +114,7 @@ public class OpenDummyInventory extends CraftInventory implements ViewOnly {
|
||||
return new HashMap<>();
|
||||
}
|
||||
|
||||
@SuppressWarnings("NonApiType")
|
||||
@Override
|
||||
public @NotNull HashMap<Integer, ItemStack> all(@Nullable ItemStack item) {
|
||||
return new HashMap<>();
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
package com.github.jikoo.openinv.internal.spigot26_1.container.bukkit;
|
||||
package com.github.jikoo.openinv.internal.spigot26_2.container.bukkit;
|
||||
|
||||
import net.minecraft.world.Container;
|
||||
import org.bukkit.Material;
|
||||
+2
-2
@@ -1,7 +1,7 @@
|
||||
package com.github.jikoo.openinv.internal.spigot26_1.container.bukkit;
|
||||
package com.github.jikoo.openinv.internal.spigot26_2.container.bukkit;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
import com.github.jikoo.openinv.internal.spigot26_1.container.OpenInventory;
|
||||
import com.github.jikoo.openinv.internal.spigot26_2.container.OpenInventory;
|
||||
import net.minecraft.core.NonNullList;
|
||||
import net.minecraft.world.entity.player.Inventory;
|
||||
import org.bukkit.craftbukkit.inventory.CraftInventory;
|
||||
+2
-2
@@ -1,6 +1,6 @@
|
||||
package com.github.jikoo.openinv.internal.spigot26_1.container.bukkit;
|
||||
package com.github.jikoo.openinv.internal.spigot26_2.container.bukkit;
|
||||
|
||||
import com.github.jikoo.openinv.internal.spigot26_1.container.OpenInventory;
|
||||
import com.github.jikoo.openinv.internal.spigot26_2.container.OpenInventory;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
+3
-3
@@ -1,7 +1,7 @@
|
||||
package com.github.jikoo.openinv.internal.spigot26_1.container.menu;
|
||||
package com.github.jikoo.openinv.internal.spigot26_2.container.menu;
|
||||
|
||||
import com.github.jikoo.openinv.internal.spigot26_1.container.bukkit.OpenDummyInventory;
|
||||
import com.github.jikoo.openinv.internal.spigot26_1.container.slot.SlotViewOnly;
|
||||
import com.github.jikoo.openinv.internal.spigot26_2.container.bukkit.OpenDummyInventory;
|
||||
import com.github.jikoo.openinv.internal.spigot26_2.container.slot.SlotViewOnly;
|
||||
import com.lishid.openinv.internal.ISpecialInventory;
|
||||
import com.lishid.openinv.internal.InternalOwned;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
+2
-2
@@ -1,6 +1,6 @@
|
||||
package com.github.jikoo.openinv.internal.spigot26_1.container.menu;
|
||||
package com.github.jikoo.openinv.internal.spigot26_2.container.menu;
|
||||
|
||||
import com.github.jikoo.openinv.internal.spigot26_1.container.OpenEnderChest;
|
||||
import com.github.jikoo.openinv.internal.spigot26_2.container.OpenEnderChest;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraft.world.inventory.Slot;
|
||||
+7
-7
@@ -1,13 +1,13 @@
|
||||
package com.github.jikoo.openinv.internal.spigot26_1.container.menu;
|
||||
package com.github.jikoo.openinv.internal.spigot26_2.container.menu;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
import com.lishid.openinv.util.Permissions;
|
||||
import com.github.jikoo.openinv.internal.spigot26_1.container.OpenInventory;
|
||||
import com.github.jikoo.openinv.internal.spigot26_1.container.bukkit.OpenDummyPlayerInventory;
|
||||
import com.github.jikoo.openinv.internal.spigot26_1.container.bukkit.OpenPlayerInventorySelf;
|
||||
import com.github.jikoo.openinv.internal.spigot26_1.container.slot.ContentDrop;
|
||||
import com.github.jikoo.openinv.internal.spigot26_1.container.slot.ContentEquipment;
|
||||
import com.github.jikoo.openinv.internal.spigot26_1.container.slot.SlotViewOnly;
|
||||
import com.github.jikoo.openinv.internal.spigot26_2.container.OpenInventory;
|
||||
import com.github.jikoo.openinv.internal.spigot26_2.container.bukkit.OpenDummyPlayerInventory;
|
||||
import com.github.jikoo.openinv.internal.spigot26_2.container.bukkit.OpenPlayerInventorySelf;
|
||||
import com.github.jikoo.openinv.internal.spigot26_2.container.slot.ContentDrop;
|
||||
import com.github.jikoo.openinv.internal.spigot26_2.container.slot.ContentEquipment;
|
||||
import com.github.jikoo.openinv.internal.spigot26_2.container.slot.SlotViewOnly;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.world.entity.EquipmentSlot;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
+2
-2
@@ -1,9 +1,9 @@
|
||||
package com.github.jikoo.openinv.internal.spigot26_1.container.menu;
|
||||
package com.github.jikoo.openinv.internal.spigot26_2.container.menu;
|
||||
|
||||
import com.google.common.base.Suppliers;
|
||||
import com.lishid.openinv.internal.ISpecialInventory;
|
||||
import com.lishid.openinv.internal.InternalOwned;
|
||||
import com.github.jikoo.openinv.internal.spigot26_1.container.slot.SlotPlaceholder;
|
||||
import com.github.jikoo.openinv.internal.spigot26_2.container.slot.SlotPlaceholder;
|
||||
import it.unimi.dsi.fastutil.ints.IntArrayList;
|
||||
import it.unimi.dsi.fastutil.ints.IntList;
|
||||
import net.minecraft.network.HashedStack;
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
package com.github.jikoo.openinv.internal.spigot26_1.container.slot;
|
||||
package com.github.jikoo.openinv.internal.spigot26_2.container.slot;
|
||||
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.world.Container;
|
||||
+3
-3
@@ -1,7 +1,7 @@
|
||||
package com.github.jikoo.openinv.internal.spigot26_1.container.slot;
|
||||
package com.github.jikoo.openinv.internal.spigot26_2.container.slot;
|
||||
|
||||
import com.github.jikoo.openinv.internal.spigot26_1.container.slot.placeholder.Placeholders;
|
||||
import com.github.jikoo.openinv.internal.spigot26_1.player.OpenPlayer;
|
||||
import com.github.jikoo.openinv.internal.spigot26_2.container.slot.placeholder.Placeholders;
|
||||
import com.github.jikoo.openinv.internal.spigot26_2.player.OpenPlayer;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.world.Container;
|
||||
import net.minecraft.world.ContainerHelper;
|
||||
+2
-2
@@ -1,6 +1,6 @@
|
||||
package com.github.jikoo.openinv.internal.spigot26_1.container.slot;
|
||||
package com.github.jikoo.openinv.internal.spigot26_2.container.slot;
|
||||
|
||||
import com.github.jikoo.openinv.internal.spigot26_1.container.slot.placeholder.Placeholders;
|
||||
import com.github.jikoo.openinv.internal.spigot26_2.container.slot.placeholder.Placeholders;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.world.Container;
|
||||
import net.minecraft.world.inventory.InventoryMenu;
|
||||
+3
-3
@@ -1,7 +1,7 @@
|
||||
package com.github.jikoo.openinv.internal.spigot26_1.container.slot;
|
||||
package com.github.jikoo.openinv.internal.spigot26_2.container.slot;
|
||||
|
||||
import com.github.jikoo.openinv.internal.spigot26_1.container.slot.placeholder.Placeholders;
|
||||
import com.github.jikoo.openinv.internal.spigot26_1.player.OpenPlayer;
|
||||
import com.github.jikoo.openinv.internal.spigot26_2.container.slot.placeholder.Placeholders;
|
||||
import com.github.jikoo.openinv.internal.spigot26_2.player.OpenPlayer;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.world.Container;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
+3
-3
@@ -1,7 +1,7 @@
|
||||
package com.github.jikoo.openinv.internal.spigot26_1.container.slot;
|
||||
package com.github.jikoo.openinv.internal.spigot26_2.container.slot;
|
||||
|
||||
import com.github.jikoo.openinv.internal.spigot26_1.container.slot.placeholder.Placeholders;
|
||||
import com.github.jikoo.openinv.internal.spigot26_1.player.OpenPlayer;
|
||||
import com.github.jikoo.openinv.internal.spigot26_2.container.slot.placeholder.Placeholders;
|
||||
import com.github.jikoo.openinv.internal.spigot26_2.player.OpenPlayer;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.world.Container;
|
||||
import net.minecraft.world.inventory.Slot;
|
||||
+2
-2
@@ -1,6 +1,6 @@
|
||||
package com.github.jikoo.openinv.internal.spigot26_1.container.slot;
|
||||
package com.github.jikoo.openinv.internal.spigot26_2.container.slot;
|
||||
|
||||
import com.github.jikoo.openinv.internal.spigot26_1.container.slot.placeholder.Placeholders;
|
||||
import com.github.jikoo.openinv.internal.spigot26_2.container.slot.placeholder.Placeholders;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.world.Container;
|
||||
import net.minecraft.world.entity.EquipmentSlot;
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
package com.github.jikoo.openinv.internal.spigot26_1.container.slot;
|
||||
package com.github.jikoo.openinv.internal.spigot26_2.container.slot;
|
||||
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.world.Container;
|
||||
+2
-2
@@ -1,6 +1,6 @@
|
||||
package com.github.jikoo.openinv.internal.spigot26_1.container.slot;
|
||||
package com.github.jikoo.openinv.internal.spigot26_2.container.slot;
|
||||
|
||||
import com.github.jikoo.openinv.internal.spigot26_1.player.OpenPlayer;
|
||||
import com.github.jikoo.openinv.internal.spigot26_2.player.OpenPlayer;
|
||||
import net.minecraft.network.protocol.game.ClientboundContainerSetSlotPacket;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.world.Container;
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
package com.github.jikoo.openinv.internal.spigot26_1.container.slot;
|
||||
package com.github.jikoo.openinv.internal.spigot26_2.container.slot;
|
||||
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.world.Container;
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
package com.github.jikoo.openinv.internal.spigot26_1.container.slot;
|
||||
package com.github.jikoo.openinv.internal.spigot26_2.container.slot;
|
||||
|
||||
import net.minecraft.world.Container;
|
||||
import net.minecraft.world.inventory.Slot;
|
||||
+7
-7
@@ -1,6 +1,6 @@
|
||||
package com.github.jikoo.openinv.internal.spigot26_1.container.slot;
|
||||
package com.github.jikoo.openinv.internal.spigot26_2.container.slot;
|
||||
|
||||
import com.github.jikoo.openinv.internal.spigot26_1.container.slot.placeholder.Placeholders;
|
||||
import com.github.jikoo.openinv.internal.spigot26_2.container.slot.placeholder.Placeholders;
|
||||
import net.minecraft.world.Container;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraft.world.inventory.Slot;
|
||||
@@ -118,6 +118,11 @@ public class SlotViewOnly extends SlotPlaceholder {
|
||||
return ItemStack.EMPTY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull ItemStack safeClone(@NotNull Player player) {
|
||||
return ItemStack.EMPTY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull ItemStack safeInsert(@NotNull ItemStack itemStack) {
|
||||
return itemStack;
|
||||
@@ -133,11 +138,6 @@ public class SlotViewOnly extends SlotPlaceholder {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getContainerSlot() {
|
||||
return this.slot;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isHighlightable() {
|
||||
return false;
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
package com.github.jikoo.openinv.internal.spigot26_2.container.slot.placeholder;
|
||||
|
||||
import net.minecraft.world.item.Item;
|
||||
import net.minecraft.world.item.Items;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class PlaceholderLoader extends PlaceholderLoaderBase {
|
||||
|
||||
@Override
|
||||
protected @NotNull Item getWhiteBanner() {
|
||||
return Items.BANNER.white();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected @NotNull Item getWhiteGlassPane() {
|
||||
return Items.STAINED_GLASS_PANE.white();
|
||||
}
|
||||
|
||||
}
|
||||
+23
-11
@@ -1,4 +1,4 @@
|
||||
package com.github.jikoo.openinv.internal.spigot26_1.container.slot.placeholder;
|
||||
package com.github.jikoo.openinv.internal.spigot26_2.container.slot.placeholder;
|
||||
|
||||
import com.mojang.serialization.DataResult;
|
||||
import net.minecraft.core.Registry;
|
||||
@@ -7,11 +7,15 @@ import net.minecraft.core.component.DataComponents;
|
||||
import net.minecraft.core.registries.Registries;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.nbt.NbtOps;
|
||||
import net.minecraft.nbt.TagParser;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.world.item.DyeColor;
|
||||
import net.minecraft.world.item.Item;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.item.Items;
|
||||
import net.minecraft.world.item.component.CustomModelData;
|
||||
import net.minecraft.world.item.component.DyedItemColor;
|
||||
import net.minecraft.world.item.component.TooltipDisplay;
|
||||
import net.minecraft.world.level.GameType;
|
||||
import net.minecraft.world.level.ItemLike;
|
||||
import net.minecraft.world.level.block.entity.BannerPattern;
|
||||
@@ -22,10 +26,14 @@ import org.bukkit.craftbukkit.CraftRegistry;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
|
||||
public abstract class PlaceholderLoaderBase {
|
||||
|
||||
private static final CustomModelData DEFAULT_CUSTOM_MODEL_DATA = new CustomModelData(List.of(), List.of(), List.of("openinv:custom"), List.of());
|
||||
private static final TooltipDisplay HIDE_TOOLTIP = new TooltipDisplay(true, new LinkedHashSet<>());
|
||||
|
||||
public void load(@Nullable ConfigurationSection section) throws Exception {
|
||||
Placeholders.craftingOutput = parse(section, "crafting-output", defaultCraftingOutput());
|
||||
Placeholders.cursor = parse(section, "cursor", defaultCursor());
|
||||
@@ -67,7 +75,7 @@ public abstract class PlaceholderLoaderBase {
|
||||
return defaultStack;
|
||||
}
|
||||
|
||||
CompoundTag compoundTag = parseTag(itemText);
|
||||
CompoundTag compoundTag = TagParser.parseCompoundFully(itemText);
|
||||
DataResult<ItemStack> parsed = ItemStack.CODEC.parse(CraftRegistry.getMinecraftRegistry().createSerializationContext(NbtOps.INSTANCE), compoundTag);
|
||||
ItemStack itemStack;
|
||||
try {
|
||||
@@ -78,13 +86,13 @@ public abstract class PlaceholderLoaderBase {
|
||||
return itemStack == null ? defaultStack : itemStack;
|
||||
}
|
||||
|
||||
protected abstract @NotNull CompoundTag parseTag(@NotNull String itemText) throws Exception;
|
||||
protected void addModelData(@NotNull ItemStack itemStack) {
|
||||
itemStack.set(DataComponents.CUSTOM_MODEL_DATA, DEFAULT_CUSTOM_MODEL_DATA);
|
||||
}
|
||||
|
||||
protected abstract void addModelData(@NotNull ItemStack itemStack);
|
||||
|
||||
protected abstract void hideTooltip(@NotNull ItemStack itemStack);
|
||||
|
||||
protected abstract DyedItemColor getDye(int rgb);
|
||||
protected void hideTooltip(@NotNull ItemStack itemStack) {
|
||||
itemStack.set(DataComponents.TOOLTIP_DISPLAY, HIDE_TOOLTIP);
|
||||
}
|
||||
|
||||
protected @NotNull ItemStack defaultCraftingOutput() {
|
||||
// Crafting table: "Crafting"
|
||||
@@ -96,7 +104,7 @@ public abstract class PlaceholderLoaderBase {
|
||||
|
||||
protected @NotNull ItemStack defaultCursor() {
|
||||
// Cursor-like banner with no tooltip
|
||||
ItemStack itemStack = new ItemStack(Items.WHITE_BANNER);
|
||||
ItemStack itemStack = new ItemStack(getWhiteBanner());
|
||||
RegistryAccess minecraftRegistry = CraftRegistry.getMinecraftRegistry();
|
||||
Registry<BannerPattern> bannerPatterns = minecraftRegistry.lookupOrThrow(Registries.BANNER_PATTERN);
|
||||
BannerPattern halfDiagBottomRight = bannerPatterns.getOrThrow(BannerPatterns.DIAGONAL_RIGHT).value();
|
||||
@@ -114,6 +122,8 @@ public abstract class PlaceholderLoaderBase {
|
||||
return itemStack;
|
||||
}
|
||||
|
||||
protected abstract @NotNull Item getWhiteBanner();
|
||||
|
||||
protected @NotNull ItemStack defaultDrop() {
|
||||
// Dropper: "Drop Selected Item"
|
||||
ItemStack itemStack = new ItemStack(Items.DROPPER);
|
||||
@@ -126,7 +136,7 @@ public abstract class PlaceholderLoaderBase {
|
||||
protected @NotNull ItemStack getEmptyArmor(@NotNull ItemLike item) {
|
||||
// Inventory-background-grey-ish leather armor with no tooltip
|
||||
ItemStack itemStack = new ItemStack(item);
|
||||
DyedItemColor color = getDye(0xC8C8C8);
|
||||
DyedItemColor color = new DyedItemColor(0xC8C8C8);
|
||||
itemStack.set(DataComponents.DYED_COLOR, color);
|
||||
hideTooltip(itemStack);
|
||||
addModelData(itemStack);
|
||||
@@ -160,12 +170,14 @@ public abstract class PlaceholderLoaderBase {
|
||||
|
||||
protected @NotNull ItemStack defaultNotSlot() {
|
||||
// White pane with no tooltip
|
||||
ItemStack itemStack = new ItemStack(Items.WHITE_STAINED_GLASS_PANE);
|
||||
ItemStack itemStack = new ItemStack(getWhiteGlassPane());
|
||||
hideTooltip(itemStack);
|
||||
addModelData(itemStack);
|
||||
return itemStack;
|
||||
}
|
||||
|
||||
protected abstract @NotNull Item getWhiteGlassPane();
|
||||
|
||||
protected @NotNull ItemStack defaultBlockedOffline() {
|
||||
// Barrier: "Not available - Offline"
|
||||
ItemStack itemStack = new ItemStack(Items.BARRIER);
|
||||
+2
-2
@@ -1,6 +1,6 @@
|
||||
package com.github.jikoo.openinv.internal.spigot26_1.container.slot.placeholder;
|
||||
package com.github.jikoo.openinv.internal.spigot26_2.container.slot.placeholder;
|
||||
|
||||
import com.github.jikoo.openinv.internal.spigot26_1.player.OpenPlayer;
|
||||
import com.github.jikoo.openinv.internal.spigot26_2.player.OpenPlayer;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.level.GameType;
|
||||
+9
-19
@@ -1,4 +1,4 @@
|
||||
package com.github.jikoo.openinv.internal.spigot26_1.player;
|
||||
package com.github.jikoo.openinv.internal.spigot26_2.player;
|
||||
|
||||
import com.lishid.openinv.event.OpenEvents;
|
||||
import com.mojang.logging.LogUtils;
|
||||
@@ -31,7 +31,7 @@ public class OpenPlayer extends CraftPlayer {
|
||||
/**
|
||||
* List of tags to always reset when saving.
|
||||
*
|
||||
* @see net.minecraft.world.entity.Entity#saveWithoutId(ValueOutput)
|
||||
* @see net.minecraft.world.entity.Entity#saveWithoutId(ValueOutput, boolean)
|
||||
* @see ServerPlayer#addAdditionalSaveData(ValueOutput)
|
||||
* @see net.minecraft.world.entity.player.Player#addAdditionalSaveData(ValueOutput)
|
||||
* @see net.minecraft.world.entity.LivingEntity#addAdditionalSaveData(ValueOutput)
|
||||
@@ -47,33 +47,23 @@ public class OpenPlayer extends CraftPlayer {
|
||||
"TicksFrozen",
|
||||
"HasVisualFire",
|
||||
"Tags",
|
||||
"data",
|
||||
"Passengers",
|
||||
// ServerPlayer#addAdditionalSaveData(CompoundTag)
|
||||
// Intentional omissions to prevent mount loss: Attach, Entity, and RootVehicle
|
||||
"warden_spawn_tracker",
|
||||
"entered_nether_pos", // Replaces enteredNetherPosition
|
||||
"enteredNetherPosition",
|
||||
"respawn", // Replaces SpawnXyz fields as of 1.21.6
|
||||
"SpawnX",
|
||||
"SpawnY",
|
||||
"SpawnZ",
|
||||
"SpawnForced",
|
||||
"SpawnAngle",
|
||||
"SpawnDimension",
|
||||
"entered_nether_pos",
|
||||
"last_explosion_impact_pos",
|
||||
"respawn",
|
||||
"raid_omen_position",
|
||||
"ender_pearls",
|
||||
// Player#addAdditionalSaveData(CompoundTag)
|
||||
"ShoulderEntityLeft",
|
||||
"ShoulderEntityRight",
|
||||
// Player#addAdditionalSaveData(CompoundTag)
|
||||
"LastDeathLocation",
|
||||
"current_explosion_impact_pos",
|
||||
// LivingEntity#addAdditionalSaveData(CompoundTag)
|
||||
"current_explosion_impact_pos",
|
||||
"active_effects",
|
||||
"sleeping_pos", // Replaces SleepingXyz fields as of 1.21.6
|
||||
"SleepingX",
|
||||
"SleepingY",
|
||||
"SleepingZ",
|
||||
"Brain",
|
||||
"sleeping_pos",
|
||||
"last_hurt_by_player",
|
||||
"last_hurt_by_player_memory_time",
|
||||
"last_hurt_by_mob",
|
||||
+10
-5
@@ -1,8 +1,8 @@
|
||||
package com.github.jikoo.openinv.internal.spigot26_1.player;
|
||||
package com.github.jikoo.openinv.internal.spigot26_2.player;
|
||||
|
||||
import com.github.jikoo.openinv.internal.spigot26_1.container.OpenEnderChest;
|
||||
import com.github.jikoo.openinv.internal.spigot26_1.container.OpenInventory;
|
||||
import com.github.jikoo.openinv.internal.spigot26_1.container.menu.OpenChestMenu;
|
||||
import com.github.jikoo.openinv.internal.spigot26_2.container.OpenEnderChest;
|
||||
import com.github.jikoo.openinv.internal.spigot26_2.container.OpenInventory;
|
||||
import com.github.jikoo.openinv.internal.spigot26_2.container.menu.OpenChestMenu;
|
||||
import com.lishid.openinv.internal.ISpecialInventory;
|
||||
import com.lishid.openinv.util.JulLoggerAdapter;
|
||||
import com.mojang.authlib.GameProfile;
|
||||
@@ -11,6 +11,7 @@ import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.network.protocol.game.ClientboundOpenScreenPacket;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.server.PlayerAdvancements;
|
||||
import net.minecraft.server.level.ClientInformation;
|
||||
import net.minecraft.server.level.ParticleStatus;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
@@ -90,7 +91,7 @@ public class PlayerManager implements com.lishid.openinv.internal.PlayerManager
|
||||
ServerPlayer entity = createNewPlayer(server, worldServer, offline);
|
||||
|
||||
// Stop listening for advancement progression - if this is not cleaned up, loading causes a memory leak.
|
||||
entity.getAdvancements().stopListening();
|
||||
removeListeners(entity.getAdvancements());
|
||||
|
||||
// Try to load the player's data.
|
||||
if (loadData(entity)) {
|
||||
@@ -139,6 +140,10 @@ public class PlayerManager implements com.lishid.openinv.internal.PlayerManager
|
||||
return entity;
|
||||
}
|
||||
|
||||
protected void removeListeners(@NotNull PlayerAdvancements advancements) {
|
||||
advancements.clearTriggers();
|
||||
}
|
||||
|
||||
boolean loadData(@NotNull ServerPlayer player) {
|
||||
// See CraftPlayer#loadData
|
||||
|
||||
@@ -11,6 +11,9 @@ dependencies {
|
||||
compileOnly(libs.spigotapi)
|
||||
implementation(project(":openinvapi"))
|
||||
implementation(project(":openinvcommon"))
|
||||
implementation(project(":openinvadapterpaper26_2")) {
|
||||
exclude(group = "io.papermc.paper", module = "dev-bundle")
|
||||
}
|
||||
implementation(project(":openinvadapterpaper26_1")) {
|
||||
exclude(group = "io.papermc.paper", module = "dev-bundle")
|
||||
}
|
||||
@@ -20,11 +23,11 @@ dependencies {
|
||||
implementation(project(":openinvadapterpaper1_21_10")) {
|
||||
exclude(group = "io.papermc.paper", module = "dev-bundle")
|
||||
}
|
||||
implementation(project(":openinvadapterpaper1_21_8")) {
|
||||
exclude(group = "io.papermc.paper", module = "dev-bundle")
|
||||
implementation(project(":openinvadapterspigot26_2")) {
|
||||
exclude(group = "org.spigotmc", module = "spigot")
|
||||
}
|
||||
implementation(project(":openinvadapterspigot")) {
|
||||
exclude(group = "io.papermc.paper", module = "dev-bundle")
|
||||
implementation(project(":openinvadapterspigot26_1")) {
|
||||
exclude(group = "org.spigotmc", module = "spigot")
|
||||
}
|
||||
implementation(libs.planarwrappers)
|
||||
implementation(libs.folia.scheduler.wrapper)
|
||||
|
||||
@@ -188,7 +188,7 @@ public class OpenInv extends FoliaWrappedJavaPlugin implements IOpenInv {
|
||||
private void sendVersionError(@NotNull Consumer<String> messageMethod) {
|
||||
if (!accessor.isSupported()) {
|
||||
messageMethod.accept("Your server version (" + accessor.getVersion() + ") is not supported.");
|
||||
messageMethod.accept("Please download the correct version of OpenInv here: " + accessor.getReleasesLink());
|
||||
messageMethod.accept("Please check https://github.com/Jikoo/OpenInv/wiki/Supported-Versions to find a matching OI version.");
|
||||
}
|
||||
if (!isSpigot) {
|
||||
messageMethod.accept("OpenInv requires that you use Spigot or a Spigot fork. Per the 1.14 update thread");
|
||||
|
||||
@@ -65,6 +65,9 @@ public class InternalAccessor {
|
||||
|
||||
private @Nullable Accessor getAccessor(@NotNull Logger logger, @NotNull LanguageManager lang) {
|
||||
if (!PAPER) {
|
||||
if (BukkitVersions.MINECRAFT.equals(Version.of(26, 2))) {
|
||||
return new com.github.jikoo.openinv.internal.spigot26_2.InternalAccessor(logger, lang);
|
||||
}
|
||||
if (BukkitVersions.MINECRAFT.greaterThanOrEqual(Version.of(26, 1))
|
||||
&& BukkitVersions.MINECRAFT.lessThanOrEqual(Version.of(26, 1, 2))) {
|
||||
// Load Spigot accessor.
|
||||
@@ -73,8 +76,8 @@ public class InternalAccessor {
|
||||
return null;
|
||||
}
|
||||
|
||||
Version maxSupported = Version.of(26, 1, 2);
|
||||
Version minSupported = Version.of(1, 21, 6);
|
||||
Version maxSupported = Version.of(26, 2);
|
||||
Version minSupported = Version.of(1, 21, 9);
|
||||
|
||||
// Ensure version is in supported range.
|
||||
if (BukkitVersions.MINECRAFT.greaterThan(maxSupported) || BukkitVersions.MINECRAFT.lessThan(minSupported)) {
|
||||
@@ -82,142 +85,17 @@ public class InternalAccessor {
|
||||
}
|
||||
|
||||
// Paper or a Paper fork, can use Mojang-mapped internals.
|
||||
if (BukkitVersions.MINECRAFT.greaterThanOrEqual(Version.of(26, 2))) { // 26.2
|
||||
return new com.lishid.openinv.internal.paper26_2.InternalAccessor(logger, lang);
|
||||
}
|
||||
if (BukkitVersions.MINECRAFT.greaterThanOrEqual(Version.of(26, 1))) { // 26.1.1, 26.1.2
|
||||
return new com.lishid.openinv.internal.paper26_1.InternalAccessor(logger, lang);
|
||||
}
|
||||
if (BukkitVersions.MINECRAFT.equals(Version.of(1, 21, 11))) {
|
||||
if (BukkitVersions.MINECRAFT.equals(Version.of(1, 21, 11))) { // 1.21.11
|
||||
return new com.lishid.openinv.internal.paper1_21_11.InternalAccessor(logger, lang);
|
||||
}
|
||||
if (BukkitVersions.MINECRAFT.lessThanOrEqual(Version.of(1, 21, 10))
|
||||
&& BukkitVersions.MINECRAFT.greaterThanOrEqual(Version.of(1, 21, 9))) { // 1.21.9, 1.21.10
|
||||
return new com.lishid.openinv.internal.paper1_21_10.InternalAccessor(logger, lang);
|
||||
}
|
||||
return new com.lishid.openinv.internal.paper1_21_8.InternalAccessor(logger, lang);
|
||||
}
|
||||
|
||||
public String getReleasesLink() {
|
||||
if (PAPER) {
|
||||
// Paper 1.21.1+
|
||||
return getPaperReleaseLink();
|
||||
}
|
||||
// Spigot 1.21.1+
|
||||
return getSpigotReleaseLink();
|
||||
}
|
||||
|
||||
private String getPaperReleaseLink() {
|
||||
if (BukkitVersions.MINECRAFT.greaterThanOrEqual(Version.of(1, 21, 6))) {
|
||||
return "https://github.com/Jikoo/OpenInv/releases";
|
||||
}
|
||||
if (BukkitVersions.MINECRAFT.greaterThanOrEqual(Version.of(1, 21, 1))) {
|
||||
return "https://github.com/Jikoo/OpenInv/releases/tag/5.3.0";
|
||||
}
|
||||
return getLegacyReleaseLink();
|
||||
}
|
||||
|
||||
private String getSpigotReleaseLink() {
|
||||
if (BukkitVersions.MINECRAFT.greaterThanOrEqual(Version.of(26, 1))) {
|
||||
return "https://github.com/Jikoo/OpenInv/releases";
|
||||
}
|
||||
if (BukkitVersions.MINECRAFT.greaterThanOrEqual(Version.of(1, 21, 11))) { // 1.21.11
|
||||
return "https://github.com/Jikoo/OpenInv/releases/tag/5.3.0";
|
||||
}
|
||||
if (BukkitVersions.MINECRAFT.greaterThanOrEqual(Version.of(1, 21, 10))) { // 1.21.10
|
||||
return "https://github.com/Jikoo/OpenInv/releases/tag/5.1.15";
|
||||
}
|
||||
if (BukkitVersions.MINECRAFT.greaterThanOrEqual(Version.of(1, 21, 9))) { // 1.21.9
|
||||
return "Unsupported; upgrade to 1.21.10: https://github.com/Jikoo/OpenInv/releases/tag/5.1.15";
|
||||
}
|
||||
if (BukkitVersions.MINECRAFT.greaterThanOrEqual(Version.of(1, 21, 8))) { // 1.21.8, 1.21.7
|
||||
return "https://github.com/Jikoo/OpenInv/releases/tag/5.1.13";
|
||||
}
|
||||
if (BukkitVersions.MINECRAFT.greaterThanOrEqual(Version.of(1, 21, 6))) { // 1.21.6
|
||||
return "Unsupported; upgrade to 1.21.7: https://github.com/Jikoo/OpenInv/releases/tag/5.1.13";
|
||||
}
|
||||
if (BukkitVersions.MINECRAFT.greaterThanOrEqual(Version.of(1, 21, 5))) { // 1.21.5
|
||||
return "https://github.com/Jikoo/OpenInv/releases/tag/5.1.11";
|
||||
}
|
||||
if (BukkitVersions.MINECRAFT.greaterThanOrEqual(Version.of(1, 21, 4))) { // 1.21.4
|
||||
return "https://github.com/Jikoo/OpenInv/releases/tag/5.1.9";
|
||||
}
|
||||
if (BukkitVersions.MINECRAFT.greaterThanOrEqual(Version.of(1, 21, 3))) { // 1.21.3
|
||||
return "https://github.com/Jikoo/OpenInv/releases/tag/5.1.6";
|
||||
}
|
||||
if (BukkitVersions.MINECRAFT.greaterThanOrEqual(Version.of(1, 21, 1))) { // 1.21.1, 1.21.2
|
||||
return "https://github.com/Jikoo/OpenInv/releases/tag/5.1.3";
|
||||
}
|
||||
// 1.21.0 and lower
|
||||
return getLegacyReleaseLink();
|
||||
}
|
||||
|
||||
private String getLegacyReleaseLink() {
|
||||
if (BukkitVersions.MINECRAFT.lessThan(Version.of(1, 4, 4))) { // Good luck.
|
||||
return "https://dev.bukkit.org/projects/openinv/files?&sort=datecreated";
|
||||
}
|
||||
if (BukkitVersions.MINECRAFT.equals(Version.of(1, 8, 8))) { // 1.8.8
|
||||
return "https://github.com/lishid/OpenInv/releases/tag/4.1.5";
|
||||
}
|
||||
if (BukkitVersions.MINECRAFT.lessThan(Version.of(1, 13))) { // 1.4.4+ had versioned packages.
|
||||
return "https://github.com/lishid/OpenInv/releases/tag/4.0.0 (OpenInv-legacy)";
|
||||
}
|
||||
if (BukkitVersions.MINECRAFT.equals(Version.of(1, 13))) { // 1.13
|
||||
return "https://github.com/lishid/OpenInv/releases/tag/4.0.0";
|
||||
}
|
||||
if (BukkitVersions.MINECRAFT.lessThan(Version.of(1, 14))) { // 1.13.1, 1.13.2
|
||||
return "https://github.com/lishid/OpenInv/releases/tag/4.0.7";
|
||||
}
|
||||
if (BukkitVersions.MINECRAFT.equals(Version.of(1, 14))) { // 1.14 to 1.14.1 had no revision bump.
|
||||
return "https://github.com/lishid/OpenInv/releases/tag/4.0.0";
|
||||
}
|
||||
if (BukkitVersions.MINECRAFT.equals(Version.of(1, 14, 1))) { // 1.14.1 to 1.14.2 had no revision bump.
|
||||
return "https://github.com/lishid/OpenInv/releases/tag/4.0.1";
|
||||
}
|
||||
if (BukkitVersions.MINECRAFT.lessThan(Version.of(1, 15))) { // 1.14.2
|
||||
return "https://github.com/lishid/OpenInv/releases/tag/4.1.1";
|
||||
}
|
||||
if (BukkitVersions.MINECRAFT.lessThanOrEqual(Version.of(1, 15, 1))) { // 1.15, 1.15.1
|
||||
return "https://github.com/lishid/OpenInv/releases/tag/4.1.5";
|
||||
}
|
||||
if (BukkitVersions.MINECRAFT.lessThan(Version.of(1, 16))) { // 1.15.2
|
||||
return "https://github.com/Jikoo/OpenInv/commit/502f661be39ee85d300851dd571f3da226f12345 (never released)";
|
||||
}
|
||||
if (BukkitVersions.MINECRAFT.lessThanOrEqual(Version.of(1, 16, 1))) { // 1.16, 1.16.1
|
||||
return "https://github.com/lishid/OpenInv/releases/tag/4.1.4";
|
||||
}
|
||||
if (BukkitVersions.MINECRAFT.lessThanOrEqual(Version.of(1, 16, 3))) { // 1.16.2, 1.16.3
|
||||
return "https://github.com/lishid/OpenInv/releases/tag/4.1.5";
|
||||
}
|
||||
if (BukkitVersions.MINECRAFT.lessThan(Version.of(1, 17))) { // 1.16.4, 1.16.5
|
||||
return "https://github.com/Jikoo/OpenInv/releases/tag/4.1.8";
|
||||
}
|
||||
if (BukkitVersions.MINECRAFT.lessThanOrEqual(Version.of(1, 18, 1))) { // 1.17, 1.18, 1.18.1
|
||||
return "https://github.com/Jikoo/OpenInv/releases/tag/4.1.10";
|
||||
}
|
||||
if (BukkitVersions.MINECRAFT.lessThan(Version.of(1, 19))) { // 1.18.2
|
||||
return "https://github.com/Jikoo/OpenInv/releases/tag/4.3.0";
|
||||
}
|
||||
if (BukkitVersions.MINECRAFT.equals(Version.of(1, 19))) { // 1.19
|
||||
return "https://github.com/Jikoo/OpenInv/releases/tag/4.2.0";
|
||||
}
|
||||
if (BukkitVersions.MINECRAFT.equals(Version.of(1, 19, 1))) { // 1.19.1
|
||||
return "https://github.com/Jikoo/OpenInv/releases/tag/4.2.2";
|
||||
}
|
||||
if (BukkitVersions.MINECRAFT.lessThanOrEqual(Version.of(1, 19, 3))) { // 1.19.2, 1.19.3
|
||||
return "https://github.com/Jikoo/OpenInv/releases/tag/4.3.0";
|
||||
}
|
||||
if (BukkitVersions.MINECRAFT.lessThan(Version.of(1, 20))) { // 1.19.4
|
||||
return "https://github.com/Jikoo/OpenInv/releases/tag/4.4.3";
|
||||
}
|
||||
if (BukkitVersions.MINECRAFT.lessThanOrEqual(Version.of(1, 20, 1))) { // 1.20, 1.20.1
|
||||
return "https://github.com/Jikoo/OpenInv/releases/tag/4.4.1";
|
||||
}
|
||||
if (BukkitVersions.MINECRAFT.lessThanOrEqual(Version.of(1, 20, 3))) { // 1.20.2, 1.20.3
|
||||
return "https://github.com/Jikoo/OpenInv/releases/tag/4.4.3";
|
||||
}
|
||||
if (BukkitVersions.MINECRAFT.equals(Version.of(1, 20, 5))) { // 1.20.5
|
||||
return "Unsupported; upgrade to 1.20.6: https://github.com/Jikoo/OpenInv/releases/tag/5.1.2";
|
||||
}
|
||||
// 1.20.4, 1.20.6, 1.21
|
||||
return "https://github.com/Jikoo/OpenInv/releases/tag/5.1.2";
|
||||
// 1.21.9, 1.21.10
|
||||
return new com.lishid.openinv.internal.paper1_21_10.InternalAccessor(logger, lang);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -2,16 +2,16 @@
|
||||
"pack": {
|
||||
"description": "Improve OpenInv's legibility",
|
||||
"min_format": 34,
|
||||
"max_format": [85, 0],
|
||||
"max_format": [88, 0],
|
||||
"pack_format": 64,
|
||||
"supported_formats": [ 34, 85 ]
|
||||
"supported_formats": [ 34, 88 ]
|
||||
},
|
||||
"overlays": {
|
||||
"entries": [
|
||||
{
|
||||
"min_format": 44,
|
||||
"max_format": [85, 0],
|
||||
"formats": [ 44, 85 ],
|
||||
"max_format": [88, 0],
|
||||
"formats": [ 44, 88 ],
|
||||
"directory": "openinv_44"
|
||||
},
|
||||
{
|
||||
|
||||
+3
-2
@@ -18,11 +18,12 @@ if (!java.lang.Boolean.getBoolean("jitpack")) {
|
||||
project(":openinvcommon").projectDir = file("common")
|
||||
|
||||
val internals = listOf(
|
||||
"paper26_2",
|
||||
"paper26_1",
|
||||
"paper1_21_11",
|
||||
"paper1_21_10",
|
||||
"paper1_21_8",
|
||||
"spigot"
|
||||
"spigot26_2",
|
||||
"spigot26_1"
|
||||
)
|
||||
for (internal in internals) {
|
||||
include(":openinvadapter$internal")
|
||||
|
||||
Reference in new issue
Block a user