mirror of
https://github.com/Jikoo/OpenInv.git
synced 2026-11-04 16:50:04 -05:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8c2ec2121a | ||
|
|
ad06b46b37 | ||
|
|
05ac5c92c8 | ||
|
|
0c8c364c45 | ||
|
|
b89f34915e | ||
|
|
ada819b30a | ||
|
|
7a2cef50ec | ||
|
|
268e91007c | ||
|
|
f4ed616fb8 | ||
|
|
456909966f | ||
|
|
51649bf2ab | ||
|
|
e44697f856 | ||
|
|
414b141b37 | ||
|
|
0db487c6eb | ||
|
|
3b907e1b37 | ||
|
|
d564773be6 | ||
|
|
e834e940e2 | ||
|
|
cd73430bb2 | ||
|
|
1c1dc9505b | ||
|
|
1a76e6fd57 | ||
|
|
48a61e6043 | ||
|
|
4de2c2fe6d | ||
|
|
e4fdd613ae | ||
|
|
9f50de5dfe | ||
|
|
e9d63f31ed | ||
|
|
73e003bde4 | ||
|
|
04ed652073 | ||
|
|
49e408ee7a | ||
|
|
0df5e39a6d | ||
|
|
7ab3e0c03f | ||
|
|
348fde9173 | ||
|
|
6c69350c30 | ||
|
|
19eafddfac | ||
|
|
8a388b5620 | ||
|
|
206fff2c0a | ||
|
|
6656e431b6 |
No files matched your search
@@ -4,7 +4,7 @@ updates:
|
||||
directory: "/"
|
||||
schedule:
|
||||
interval: "monthly"
|
||||
- package-ecosystem: "maven"
|
||||
- package-ecosystem: "gradle"
|
||||
directory: "/"
|
||||
schedule:
|
||||
interval: "monthly"
|
||||
+16
-14
@@ -7,7 +7,7 @@ on:
|
||||
tags-ignore:
|
||||
- '**'
|
||||
paths-ignore:
|
||||
- resource-pack/**
|
||||
- resource-pack/openinv-legibility-pack/**
|
||||
# Enable running CI via other Actions, i.e. for drafting releases and handling PRs.
|
||||
workflow_call:
|
||||
|
||||
@@ -21,14 +21,22 @@ jobs:
|
||||
with:
|
||||
distribution: 'temurin'
|
||||
java-version: '21'
|
||||
cache: 'maven'
|
||||
|
||||
# Install Spigot dependencies if necessary.
|
||||
- name: Install Spigot Dependencies
|
||||
run: . scripts/install_spigot_dependencies.sh
|
||||
# We can't use 'maven' prebuilt cache setup because it requires that the project have a pom file.
|
||||
# BuildTools installs to Maven local if available, so it's easier to just rely on that.
|
||||
- name: Cache Spigot dependency
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: |
|
||||
~/.m2/repository/org/spigotmc/
|
||||
key: ${{ runner.os }}-buildtools-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-buildtools-
|
||||
|
||||
- name: Build With Maven
|
||||
run: mvn -e clean package -am -P all
|
||||
- uses: gradle/actions/setup-gradle@v4
|
||||
|
||||
- name: Build with Gradle
|
||||
run: ./gradlew clean build
|
||||
|
||||
# Upload artifacts
|
||||
- name: Upload Distributable Jar
|
||||
@@ -36,10 +44,4 @@ jobs:
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: dist
|
||||
path: ./target/*.jar
|
||||
- name: Upload API Jar
|
||||
id: upload-api
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: api
|
||||
path: ./api/target/openinvapi*.jar
|
||||
path: ./dist/*
|
||||
@@ -12,34 +12,25 @@ jobs:
|
||||
needs: [ run-ci ]
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
# Fetch all history - used to assemble changelog.
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Set Release Variables
|
||||
run: bash ./scripts/set_release_env.sh
|
||||
|
||||
- name: Download build
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: dist
|
||||
path: dist
|
||||
|
||||
- name: Package resource pack
|
||||
run: |-
|
||||
pushd resource-pack
|
||||
zip -r ../dist/openinv-legibility-pack.zip .
|
||||
popd
|
||||
|
||||
- name: Create Release
|
||||
id: create-release
|
||||
uses: softprops/action-gh-release@v2.2.1
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
with:
|
||||
name: ${{ env.VERSIONED_NAME }}
|
||||
body: ${{ env.GENERATED_CHANGELOG }}
|
||||
name: OpenInv ${{ env.VERSIONED_NAME }}
|
||||
body: |-
|
||||
## Supported server versions
|
||||
**Paper:** TODO VERSION, 1.21.4, 1.21.3, 1.21.1
|
||||
**Spigot:** TODO VERSION
|
||||
|
||||
TODO HELLO HUMAN, PRESS THE GENERATE CHANGELOG BUTTON PLEASE.
|
||||
draft: true
|
||||
prerelease: false
|
||||
files: ./dist/**
|
||||
@@ -34,4 +34,4 @@ jobs:
|
||||
game_versions: "${{ env.CURSEFORGE_MINECRAFT_VERSIONS }}"
|
||||
release_type: release
|
||||
changelog_type: markdown
|
||||
changelog: "${{ env.CURSEFORGE_CHANGELOG }}"
|
||||
changelog: "${{ github.event.release.body }}"
|
||||
@@ -7,7 +7,7 @@ on:
|
||||
tags-ignore:
|
||||
- '**'
|
||||
paths:
|
||||
- resource-pack/**
|
||||
- resource-pack/openinv-legibility-pack/**
|
||||
|
||||
jobs:
|
||||
build:
|
||||
@@ -20,5 +20,5 @@ jobs:
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: openinv-legibility-pack
|
||||
path: ./resource-pack/
|
||||
path: ./resource-pack/openinv-legibility-pack/
|
||||
compression-level: 9
|
||||
@@ -2,9 +2,12 @@
|
||||
**/.project
|
||||
**/.classpath
|
||||
**/.idea/
|
||||
**/.gradle/
|
||||
**.iml
|
||||
**/target/
|
||||
**/bin/
|
||||
**/out/
|
||||
**/build/
|
||||
**/dist/
|
||||
**/dependency-reduced-pom.xml
|
||||
**/pom.xml.versionsBackup
|
||||
@@ -36,22 +36,16 @@ The OpenInv API is available via [JitPack](https://jitpack.io/).
|
||||
```xml
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.github.jikoo.OpenInv</groupId>
|
||||
<artifactId>openinvapi</artifactId>
|
||||
<groupId>com.github.Jikoo</groupId>
|
||||
<artifactId>OpenInv</artifactId>
|
||||
<version>${openinv.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
```
|
||||
Note that since JitPack only builds the API now, the "full" OpenInv jar on JitPack is actually the openinvapi artifact. This is a change from previous dependency declaration that I hope to revert.
|
||||
|
||||
### Compilation
|
||||
To compile, the relevant Spigot jars must be installed in the local repository.
|
||||
As OpenInv is compiled against Mojang's mappings, you must run BuildTools with the `--remapped` argument:
|
||||
`java -jar BuildTools.jar --remapped --rev $serverVersion`
|
||||
`$serverVersion` is the version of the server, i.e. `1.18.1`
|
||||
Execute the gradle wrapper:
|
||||
`./gradlew build`
|
||||
|
||||
To compile just the API, execute Maven as usual:
|
||||
`mvn clean package`
|
||||
|
||||
To compile the full plugin, use the provided profile with `-P all`:
|
||||
`mvn clean package -am -P all`
|
||||
For more information, check out the [official Maven guide](http://maven.apache.org/guides/introduction/introduction-to-profiles.html).
|
||||
If you encounter issues with building the Spigot module, try running BuildTools manually.
|
||||
@@ -0,0 +1,21 @@
|
||||
plugins {
|
||||
`openinv-base`
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation(project(":openinvapi"))
|
||||
}
|
||||
|
||||
tasks.processResources {
|
||||
expand("version" to version)
|
||||
}
|
||||
|
||||
tasks.register<Copy>("distributeAddons") {
|
||||
into(rootProject.layout.projectDirectory.dir("dist"))
|
||||
from(tasks.jar)
|
||||
rename("openinvtogglepersist.*\\.jar", "OITogglePersist.jar")
|
||||
}
|
||||
|
||||
tasks.assemble {
|
||||
dependsOn(tasks.named("distributeAddons"))
|
||||
}
|
||||
@@ -1,72 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<parent>
|
||||
<artifactId>openinvparent</artifactId>
|
||||
<groupId>com.lishid</groupId>
|
||||
<relativePath>../../pom.xml</relativePath>
|
||||
<version>5.1.5</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>openinvtogglepersist</artifactId>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<artifactId>annotations</artifactId>
|
||||
<groupId>org.jetbrains</groupId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.spigotmc</groupId>
|
||||
<artifactId>spigot-api</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<artifactId>openinvapi</artifactId>
|
||||
<groupId>com.lishid</groupId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<finalName>OITogglePersist</finalName>
|
||||
<resources>
|
||||
<resource>
|
||||
<directory>src/main/resources</directory>
|
||||
<filtering>true</filtering>
|
||||
</resource>
|
||||
</resources>
|
||||
|
||||
<plugins>
|
||||
<plugin>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<artifactId>maven-resources-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>copy-final-jar</id>
|
||||
<phase>package</phase>
|
||||
<goals>
|
||||
<goal>copy-resources</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<outputDirectory>${project.parent.build.directory}</outputDirectory>
|
||||
<resources>
|
||||
<resource>
|
||||
<directory>${project.build.directory}</directory>
|
||||
<includes>
|
||||
<include>${project.build.finalName}.jar</include>
|
||||
</includes>
|
||||
</resource>
|
||||
</resources>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
|
||||
</build>
|
||||
|
||||
</project>
|
||||
@@ -1,6 +1,6 @@
|
||||
name: OITogglePersist
|
||||
main: com.github.jikoo.openinv.togglepersist.TogglePersist
|
||||
version: ${project.version}
|
||||
version: ${version}
|
||||
author: Jikoo
|
||||
description: An OpenInv addon allowing /anycontainer and /silentcontainer to persist across sessions.
|
||||
api-version: "1.20"
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
plugins {
|
||||
`openinv-base`
|
||||
`maven-publish`
|
||||
}
|
||||
|
||||
publishing {
|
||||
publications {
|
||||
create<MavenPublication>("jitpack") {
|
||||
groupId = "com.github.Jikoo.OpenInv"
|
||||
artifactId = "openinvapi"
|
||||
from(components["java"])
|
||||
}
|
||||
}
|
||||
}
|
||||
-49
@@ -1,49 +0,0 @@
|
||||
<!--
|
||||
~ Copyright (C) 2011-2022 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/>.
|
||||
-->
|
||||
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<parent>
|
||||
<artifactId>openinvparent</artifactId>
|
||||
<groupId>com.lishid</groupId>
|
||||
<version>5.1.5</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>openinvapi</artifactId>
|
||||
<name>OpenInvAPI</name>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<artifactId>annotations</artifactId>
|
||||
<groupId>org.jetbrains</groupId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<artifactId>spigot-api</artifactId>
|
||||
<groupId>org.spigotmc</groupId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
</project>
|
||||
@@ -0,0 +1,27 @@
|
||||
plugins {
|
||||
`java-library`
|
||||
alias(libs.plugins.paperweight) apply false
|
||||
alias(libs.plugins.shadow) apply false
|
||||
}
|
||||
|
||||
// Set by Spigot module, used by Paper module to convert to Spigot's version of Mojang mappings.
|
||||
project.ext.set("craftbukkitPackage", "UNKNOWN")
|
||||
|
||||
repositories {
|
||||
maven("https://repo.papermc.io/repository/maven-public/")
|
||||
}
|
||||
|
||||
// Allow submodules to target higher Java release versions.
|
||||
// Not currently necessary (as lowest supported version is in the 1.21 range)
|
||||
// but may become relevant in the future.
|
||||
java.disableAutoTargetJvm()
|
||||
|
||||
// Task to delete ./dist where final files are output.
|
||||
tasks.register("cleanDist") {
|
||||
delete("dist")
|
||||
}
|
||||
|
||||
tasks.clean {
|
||||
// Also delete distribution folder when cleaning.
|
||||
dependsOn(tasks.named("cleanDist"))
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
plugins {
|
||||
`kotlin-dsl`
|
||||
}
|
||||
|
||||
repositories {
|
||||
gradlePluginPortal()
|
||||
mavenCentral()
|
||||
}
|
||||
|
||||
dependencies {
|
||||
val libs = project.extensions.getByType(VersionCatalogsExtension::class.java).named("libs")
|
||||
implementation(libs.findLibrary("specialsource").orElseThrow())
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
dependencyResolutionManagement {
|
||||
versionCatalogs {
|
||||
create("libs") {
|
||||
from(files("../gradle/libs.versions.toml"))
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,98 @@
|
||||
package com.github.jikoo.openinv
|
||||
|
||||
import org.gradle.api.file.DirectoryProperty
|
||||
import org.gradle.api.provider.Property
|
||||
import org.gradle.api.provider.ValueSource
|
||||
import org.gradle.api.provider.ValueSourceParameters
|
||||
import org.gradle.process.ExecOperations
|
||||
import java.io.File
|
||||
import java.net.URI
|
||||
import java.nio.file.Files
|
||||
import javax.inject.Inject
|
||||
|
||||
abstract class BuildToolsValueSource: ValueSource<File, BuildToolsValueSource.Parameters> {
|
||||
|
||||
@get:Inject
|
||||
abstract val exec: ExecOperations
|
||||
|
||||
interface Parameters: ValueSourceParameters {
|
||||
val mavenLocal: Property<File>
|
||||
val workingDir: DirectoryProperty
|
||||
|
||||
val spigotVersion: Property<String>
|
||||
val spigotRevision: Property<String>
|
||||
|
||||
val ignoreCached: Property<Boolean>
|
||||
|
||||
val javaHome: DirectoryProperty
|
||||
val javaExecutable: Property<String>
|
||||
}
|
||||
|
||||
override fun obtain(): File {
|
||||
val version = parameters.spigotVersion.get()
|
||||
val revision = parameters.spigotRevision.get()
|
||||
val installLocation = getInstallLocation(version)
|
||||
// If Spigot is already installed, don't reinstall.
|
||||
if (!parameters.ignoreCached.get() && installLocation.exists()) {
|
||||
println("Skipping Spigot installation, $version is present")
|
||||
return installLocation
|
||||
}
|
||||
|
||||
val buildTools = installBuildTools(parameters.workingDir.get().asFile)
|
||||
|
||||
println("Installing Spigot $version (rev $revision)")
|
||||
|
||||
exec.javaexec {
|
||||
environment["JAVA_HOME"] = parameters.javaHome.get()
|
||||
executable = parameters.javaExecutable.get()
|
||||
workingDir = buildTools.parentFile
|
||||
classpath(buildTools)
|
||||
args = listOf("--nogui", "--rev", revision, "--remapped")
|
||||
}.rethrowFailure()
|
||||
|
||||
// Mark work for delete.
|
||||
cleanUp(buildTools.parentFile)
|
||||
|
||||
if (!installLocation.exists()) {
|
||||
throw IllegalStateException(
|
||||
"Failed to install Spigot $version from $revision. Does the revision point to a different version?")
|
||||
}
|
||||
return installLocation
|
||||
}
|
||||
|
||||
private fun getInstallLocation(version: String): File {
|
||||
return parameters.mavenLocal.get().resolve("org/spigotmc/spigot/$version/spigot-$version-remapped-mojang.jar")
|
||||
}
|
||||
|
||||
private fun installBuildTools(workingDir: File): File {
|
||||
val buildTools = workingDir.resolve("BuildTools.jar")
|
||||
if (buildTools.exists()) {
|
||||
return buildTools
|
||||
}
|
||||
|
||||
workingDir.mkdirs()
|
||||
|
||||
val buildToolsUrl = "https://hub.spigotmc.org/jenkins/job/BuildTools/lastSuccessfulBuild/artifact/target/BuildTools.jar"
|
||||
println("Downloading $buildToolsUrl")
|
||||
val stream = URI.create(buildToolsUrl).toURL().openStream()
|
||||
Files.copy(stream, buildTools.toPath())
|
||||
stream.close()
|
||||
|
||||
return buildTools
|
||||
}
|
||||
|
||||
private fun cleanUp(dir: File) {
|
||||
dir.deleteOnExit()
|
||||
if (!dir.isDirectory) {
|
||||
return
|
||||
}
|
||||
|
||||
dir.listFiles()?.forEach {
|
||||
if (it.isDirectory) {
|
||||
cleanUp(it)
|
||||
} else {
|
||||
it.deleteOnExit()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package com.github.jikoo.openinv
|
||||
|
||||
import org.gradle.api.model.ObjectFactory
|
||||
import org.gradle.jvm.toolchain.JavaToolchainSpec
|
||||
|
||||
abstract class SpigotDependencyExtension (
|
||||
objects: ObjectFactory
|
||||
) {
|
||||
|
||||
val version = objects.property(String::class.java)
|
||||
val revision = objects.property(String::class.java)
|
||||
.convention(version.map {
|
||||
it.replace("-R\\d+\\.\\d+-SNAPSHOT".toRegex(), "")
|
||||
})
|
||||
val configuration = objects.property(String::class.java)
|
||||
val classifier = objects.property(String::class.java).convention("remapped-mojang")
|
||||
val ext = objects.property(String::class.java)
|
||||
val java = objects.property(JavaToolchainSpec::class.java)
|
||||
val ignoreCached = objects.property(Boolean::class.java).convention(false)
|
||||
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
package com.github.jikoo.openinv
|
||||
|
||||
import org.gradle.api.Plugin
|
||||
import org.gradle.api.Project
|
||||
import org.gradle.api.attributes.Bundling
|
||||
import org.gradle.api.attributes.Category
|
||||
import org.gradle.api.attributes.LibraryElements
|
||||
import org.gradle.api.attributes.Usage
|
||||
import org.gradle.jvm.tasks.Jar
|
||||
import org.gradle.kotlin.dsl.named
|
||||
import org.gradle.kotlin.dsl.register
|
||||
import java.nio.file.Paths
|
||||
|
||||
class SpigotReobf: Plugin<Project> {
|
||||
|
||||
companion object {
|
||||
const val ARTIFACT_CONFIG = "reobf"
|
||||
}
|
||||
|
||||
override fun apply(target: Project) {
|
||||
// Re-use extension from Spigot dependency declaration if available to reduce configuration requirements.
|
||||
val spigotExt = target.dependencies.extensions.findByType(SpigotDependencyExtension::class.java)
|
||||
?: target.dependencies.extensions.create(
|
||||
"spigot",
|
||||
SpigotDependencyExtension::class.java,
|
||||
target.objects
|
||||
)
|
||||
|
||||
val mvnLocal = target.repositories.mavenLocal()
|
||||
|
||||
val reobfTask = target.tasks.register<SpigotReobfTask>("reobfTask") {
|
||||
dependsOn(target.tasks.named("shadowJar"))
|
||||
// ShadowJar extends Jar, so this should be a safe way to get the result without having
|
||||
// to jump through hoops and shift around shadow declarations in the rest of the project.
|
||||
inputFile.convention(target.tasks.named<Jar>("shadowJar").get().archiveFile)
|
||||
spigotVersion.convention(spigotExt.version)
|
||||
getMavenLocal().set(Paths.get(mvnLocal.url).toFile())
|
||||
}
|
||||
|
||||
// Set up configuration for producing reobf jar.
|
||||
target.configurations.consumable(ARTIFACT_CONFIG) {
|
||||
attributes {
|
||||
attribute(Category.CATEGORY_ATTRIBUTE, target.objects.named(Category.LIBRARY))
|
||||
attribute(Usage.USAGE_ATTRIBUTE, target.objects.named(Usage.JAVA_RUNTIME))
|
||||
attribute(Bundling.BUNDLING_ATTRIBUTE, target.objects.named(Bundling.EXTERNAL))
|
||||
attribute(LibraryElements.LIBRARY_ELEMENTS_ATTRIBUTE, target.objects.named(LibraryElements.JAR))
|
||||
}
|
||||
}
|
||||
|
||||
// Add artifact from reobf task.
|
||||
target.artifacts {
|
||||
add(ARTIFACT_CONFIG, reobfTask)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
package com.github.jikoo.openinv
|
||||
|
||||
import net.md_5.specialsource.Jar
|
||||
import net.md_5.specialsource.JarMapping
|
||||
import net.md_5.specialsource.JarRemapper
|
||||
import net.md_5.specialsource.RemapperProcessor
|
||||
import net.md_5.specialsource.provider.JarProvider
|
||||
import net.md_5.specialsource.provider.JointProvider
|
||||
import org.gradle.api.file.RegularFileProperty
|
||||
import org.gradle.api.provider.Property
|
||||
import org.gradle.api.tasks.Input
|
||||
import org.gradle.api.tasks.InputFile
|
||||
import org.gradle.api.tasks.Internal
|
||||
import org.gradle.api.tasks.TaskAction
|
||||
import java.io.File
|
||||
|
||||
abstract class SpigotReobfTask: org.gradle.api.tasks.bundling.Jar() {
|
||||
|
||||
@get:Input
|
||||
val spigotVersion: Property<String> = objectFactory.property(String::class.java)
|
||||
|
||||
@get:InputFile
|
||||
val inputFile: RegularFileProperty = objectFactory.fileProperty()
|
||||
|
||||
@get:Input
|
||||
val intermediaryClassifier: Property<String> = objectFactory.property(String::class.java).convention("mojang-mapped")
|
||||
|
||||
private val mavenLocal: Property<File> = objectFactory.property(File::class.java)
|
||||
|
||||
init {
|
||||
archiveClassifier.convention(SpigotReobf.ARTIFACT_CONFIG)
|
||||
}
|
||||
|
||||
@TaskAction
|
||||
override fun copy() {
|
||||
val spigotVer = spigotVersion.get()
|
||||
val inFile = inputFile.get().asFile
|
||||
val obfPath = inFile.resolveSibling(inFile.name.replace(".jar", "-${intermediaryClassifier.get()}.jar"))
|
||||
|
||||
// https://www.spigotmc.org/threads/510208/#post-4184317
|
||||
val repo = mavenLocal.get()
|
||||
val spigotDir = repo.resolve("org/spigotmc/spigot/$spigotVer/")
|
||||
val mappingDir = repo.resolve("org/spigotmc/minecraft-server/$spigotVer/")
|
||||
|
||||
// Remap original Mojang-mapped jar to obfuscated intermediary
|
||||
val mojangServer = spigotDir.resolve("spigot-$spigotVer-remapped-mojang.jar")
|
||||
val mojangMappings = mappingDir.resolve("minecraft-server-$spigotVer-maps-mojang.txt")
|
||||
remapPartial(mojangServer, mojangMappings, inFile, obfPath, true)
|
||||
|
||||
// Remap obfuscated intermediary jar to Spigot and replace original
|
||||
val obfServer = spigotDir.resolve("spigot-$spigotVer-remapped-obf.jar")
|
||||
val spigotMappings = mappingDir.resolve("minecraft-server-$spigotVer-maps-spigot.csrg")
|
||||
remapPartial(obfServer, spigotMappings, obfPath, archiveFile.get().asFile, false)
|
||||
}
|
||||
|
||||
private fun remapPartial(server: File, mapping: File, input: File, output: File, reverse: Boolean) {
|
||||
val jarMapping = JarMapping()
|
||||
jarMapping.loadMappings(mapping.path, reverse, false, null, null)
|
||||
|
||||
val inheritance = JointProvider()
|
||||
jarMapping.setFallbackInheritanceProvider(inheritance)
|
||||
|
||||
// Equivalent of --live with server jar on classpath.
|
||||
val serverJar = Jar.init(server)
|
||||
inheritance.add(JarProvider(serverJar))
|
||||
|
||||
val inputJar = Jar.init(input)
|
||||
inheritance.add(JarProvider(inputJar))
|
||||
|
||||
// Remap reflective access.
|
||||
val preprocessor = RemapperProcessor(null, jarMapping, null)
|
||||
|
||||
val remapper = JarRemapper(preprocessor, jarMapping, null)
|
||||
remapper.remapJar(inputJar, output, emptySet())
|
||||
|
||||
serverJar.close()
|
||||
inputJar.close()
|
||||
}
|
||||
|
||||
@Internal
|
||||
internal fun getMavenLocal(): Property<File> {
|
||||
return mavenLocal
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
package com.github.jikoo.openinv
|
||||
|
||||
import org.gradle.api.Plugin
|
||||
import org.gradle.api.Project
|
||||
import org.gradle.api.plugins.JavaPluginExtension
|
||||
import org.gradle.jvm.toolchain.JavaToolchainService
|
||||
import org.gradle.kotlin.dsl.create
|
||||
import java.nio.file.Paths
|
||||
import javax.inject.Inject
|
||||
|
||||
abstract class SpigotSetup: Plugin<Project> {
|
||||
|
||||
@get:Inject
|
||||
abstract val javaToolchainService: JavaToolchainService
|
||||
|
||||
override fun apply(target: Project) {
|
||||
target.plugins.apply("java")
|
||||
|
||||
// Set up extension for configuring Spigot dependency.
|
||||
val spigotExt = target.dependencies.extensions.findByType(SpigotDependencyExtension::class.java)
|
||||
?: target.dependencies.extensions.create(
|
||||
"spigot",
|
||||
SpigotDependencyExtension::class.java,
|
||||
target.objects
|
||||
)
|
||||
|
||||
val mvnLocal = target.repositories.mavenLocal()
|
||||
|
||||
target.afterEvaluate {
|
||||
// Get Java requirements, defaulting to version used for compilation.
|
||||
spigotExt.java.convention(target.extensions.getByType(JavaPluginExtension::class.java).toolchain)
|
||||
val launcher = javaToolchainService.launcherFor(spigotExt.java.get()).get()
|
||||
|
||||
// Install Spigot with BuildTools.
|
||||
target.providers.of(BuildToolsValueSource::class.java) {
|
||||
parameters {
|
||||
mavenLocal.set(Paths.get(mvnLocal.url).toFile())
|
||||
workingDir.set(target.layout.buildDirectory.dir("tmp/buildtools"))
|
||||
spigotVersion.set(spigotExt.version)
|
||||
spigotRevision.set(spigotExt.revision)
|
||||
ignoreCached.set(spigotExt.ignoreCached)
|
||||
javaHome.set(launcher.metadata.installationPath)
|
||||
javaExecutable.set(launcher.executablePath.asFile.path)
|
||||
}
|
||||
}.get()
|
||||
|
||||
// Add Spigot dependency.
|
||||
val dependency = target.dependencies.create(
|
||||
"org.spigotmc",
|
||||
"spigot",
|
||||
spigotExt.version.get(),
|
||||
spigotExt.configuration.orNull,
|
||||
spigotExt.classifier.orNull,
|
||||
spigotExt.ext.orNull)
|
||||
target.dependencies.add("compileOnly", dependency)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
import org.gradle.jvm.toolchain.JavaLanguageVersion
|
||||
import org.gradle.kotlin.dsl.maven
|
||||
import org.gradle.kotlin.dsl.repositories
|
||||
import org.gradle.kotlin.dsl.dependencies
|
||||
|
||||
plugins {
|
||||
`java-library`
|
||||
}
|
||||
|
||||
java {
|
||||
toolchain.languageVersion = JavaLanguageVersion.of(21)
|
||||
}
|
||||
|
||||
repositories {
|
||||
mavenCentral()
|
||||
maven("https://repo.papermc.io/repository/maven-public/")
|
||||
maven("https://hub.spigotmc.org/nexus/content/groups/public/")
|
||||
}
|
||||
|
||||
dependencies {
|
||||
val libs = versionCatalogs.named("libs")
|
||||
compileOnly(libs.findLibrary("annotations").orElseThrow())
|
||||
compileOnly(libs.findLibrary("spigotapi").orElseThrow())
|
||||
}
|
||||
|
||||
tasks {
|
||||
withType<JavaCompile>().configureEach {
|
||||
options.release = 21
|
||||
options.encoding = Charsets.UTF_8.name()
|
||||
}
|
||||
withType<Javadoc>().configureEach {
|
||||
options.encoding = Charsets.UTF_8.name()
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
plugins {
|
||||
`openinv-base`
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation(project(":openinvapi"))
|
||||
}
|
||||
@@ -1,30 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<parent>
|
||||
<groupId>com.lishid</groupId>
|
||||
<artifactId>openinvparent</artifactId>
|
||||
<version>5.1.5</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>openinvcommon</artifactId>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<artifactId>annotations</artifactId>
|
||||
<groupId>org.jetbrains</groupId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.spigotmc</groupId>
|
||||
<artifactId>spigot-api</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<artifactId>openinvapi</artifactId>
|
||||
<groupId>com.lishid</groupId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
@@ -0,0 +1,9 @@
|
||||
# Project meta
|
||||
group=com.lishid.openinv
|
||||
version=5.1.10
|
||||
description=A Bukkit plugin for opening normally-inaccessible inventories.
|
||||
|
||||
# Gradle configuration
|
||||
org.gradle.parallel=true
|
||||
org.gradle.caching=true
|
||||
org.gradle.configuration-cache=true
|
||||
@@ -0,0 +1,19 @@
|
||||
[versions]
|
||||
spigotapi = "1.21.5-R0.1-SNAPSHOT"
|
||||
specialsource = "1.11.5"
|
||||
planarwrappers = "3.3.0"
|
||||
annotations = "26.0.2"
|
||||
paperweight = "2.0.0-beta.16"
|
||||
shadow = "8.3.6"
|
||||
folia-scheduler-wrapper = "v0.0.3"
|
||||
|
||||
[libraries]
|
||||
spigotapi = { module = "org.spigotmc:spigot-api", version.ref = "spigotapi" }
|
||||
specialsource = { module = "net.md-5:SpecialSource", version.ref = "specialsource" }
|
||||
planarwrappers = { module = "com.github.jikoo:planarwrappers", version.ref = "planarwrappers" }
|
||||
annotations = { module = "org.jetbrains:annotations", version.ref = "annotations" }
|
||||
folia-scheduler-wrapper = { module = "com.github.NahuLD.folia-scheduler-wrapper:folia-scheduler-wrapper", version.ref = "folia-scheduler-wrapper" }
|
||||
|
||||
[plugins]
|
||||
paperweight = { id = "io.papermc.paperweight.userdev", version.ref = "paperweight" }
|
||||
shadow = { id = "com.gradleup.shadow", version.ref = "shadow" }
|
||||
Vendored
BIN
Binary file not shown.
+5
@@ -0,0 +1,5 @@
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.12-bin.zip
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
@@ -0,0 +1,234 @@
|
||||
#!/bin/sh
|
||||
|
||||
#
|
||||
# Copyright © 2015-2021 the original authors.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# https://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
|
||||
##############################################################################
|
||||
#
|
||||
# Gradle start up script for POSIX generated by Gradle.
|
||||
#
|
||||
# Important for running:
|
||||
#
|
||||
# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is
|
||||
# noncompliant, but you have some other compliant shell such as ksh or
|
||||
# bash, then to run this script, type that shell name before the whole
|
||||
# command line, like:
|
||||
#
|
||||
# ksh Gradle
|
||||
#
|
||||
# Busybox and similar reduced shells will NOT work, because this script
|
||||
# requires all of these POSIX shell features:
|
||||
# * functions;
|
||||
# * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,
|
||||
# «${var#prefix}», «${var%suffix}», and «$( cmd )»;
|
||||
# * compound commands having a testable exit status, especially «case»;
|
||||
# * various built-in commands including «command», «set», and «ulimit».
|
||||
#
|
||||
# Important for patching:
|
||||
#
|
||||
# (2) This script targets any POSIX shell, so it avoids extensions provided
|
||||
# by Bash, Ksh, etc; in particular arrays are avoided.
|
||||
#
|
||||
# The "traditional" practice of packing multiple parameters into a
|
||||
# space-separated string is a well documented source of bugs and security
|
||||
# problems, so this is (mostly) avoided, by progressively accumulating
|
||||
# options in "$@", and eventually passing that to Java.
|
||||
#
|
||||
# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,
|
||||
# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;
|
||||
# see the in-line comments for details.
|
||||
#
|
||||
# There are tweaks for specific operating systems such as AIX, CygWin,
|
||||
# Darwin, MinGW, and NonStop.
|
||||
#
|
||||
# (3) This script is generated from the Groovy template
|
||||
# https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
|
||||
# within the Gradle project.
|
||||
#
|
||||
# You can find Gradle at https://github.com/gradle/gradle/.
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
# Attempt to set APP_HOME
|
||||
|
||||
# Resolve links: $0 may be a link
|
||||
app_path=$0
|
||||
|
||||
# Need this for daisy-chained symlinks.
|
||||
while
|
||||
APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path
|
||||
[ -h "$app_path" ]
|
||||
do
|
||||
ls=$( ls -ld "$app_path" )
|
||||
link=${ls#*' -> '}
|
||||
case $link in #(
|
||||
/*) app_path=$link ;; #(
|
||||
*) app_path=$APP_HOME$link ;;
|
||||
esac
|
||||
done
|
||||
|
||||
APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit
|
||||
|
||||
APP_NAME="Gradle"
|
||||
APP_BASE_NAME=${0##*/}
|
||||
|
||||
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
|
||||
|
||||
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
||||
MAX_FD=maximum
|
||||
|
||||
warn () {
|
||||
echo "$*"
|
||||
} >&2
|
||||
|
||||
die () {
|
||||
echo
|
||||
echo "$*"
|
||||
echo
|
||||
exit 1
|
||||
} >&2
|
||||
|
||||
# OS specific support (must be 'true' or 'false').
|
||||
cygwin=false
|
||||
msys=false
|
||||
darwin=false
|
||||
nonstop=false
|
||||
case "$( uname )" in #(
|
||||
CYGWIN* ) cygwin=true ;; #(
|
||||
Darwin* ) darwin=true ;; #(
|
||||
MSYS* | MINGW* ) msys=true ;; #(
|
||||
NONSTOP* ) nonstop=true ;;
|
||||
esac
|
||||
|
||||
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
|
||||
|
||||
|
||||
# Determine the Java command to use to start the JVM.
|
||||
if [ -n "$JAVA_HOME" ] ; then
|
||||
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
|
||||
# IBM's JDK on AIX uses strange locations for the executables
|
||||
JAVACMD=$JAVA_HOME/jre/sh/java
|
||||
else
|
||||
JAVACMD=$JAVA_HOME/bin/java
|
||||
fi
|
||||
if [ ! -x "$JAVACMD" ] ; then
|
||||
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
|
||||
|
||||
Please set the JAVA_HOME variable in your environment to match the
|
||||
location of your Java installation."
|
||||
fi
|
||||
else
|
||||
JAVACMD=java
|
||||
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
|
||||
Please set the JAVA_HOME variable in your environment to match the
|
||||
location of your Java installation."
|
||||
fi
|
||||
|
||||
# Increase the maximum file descriptors if we can.
|
||||
if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
|
||||
case $MAX_FD in #(
|
||||
max*)
|
||||
MAX_FD=$( ulimit -H -n ) ||
|
||||
warn "Could not query maximum file descriptor limit"
|
||||
esac
|
||||
case $MAX_FD in #(
|
||||
'' | soft) :;; #(
|
||||
*)
|
||||
ulimit -n "$MAX_FD" ||
|
||||
warn "Could not set maximum file descriptor limit to $MAX_FD"
|
||||
esac
|
||||
fi
|
||||
|
||||
# Collect all arguments for the java command, stacking in reverse order:
|
||||
# * args from the command line
|
||||
# * the main class name
|
||||
# * -classpath
|
||||
# * -D...appname settings
|
||||
# * --module-path (only if needed)
|
||||
# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.
|
||||
|
||||
# For Cygwin or MSYS, switch paths to Windows format before running java
|
||||
if "$cygwin" || "$msys" ; then
|
||||
APP_HOME=$( cygpath --path --mixed "$APP_HOME" )
|
||||
CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" )
|
||||
|
||||
JAVACMD=$( cygpath --unix "$JAVACMD" )
|
||||
|
||||
# Now convert the arguments - kludge to limit ourselves to /bin/sh
|
||||
for arg do
|
||||
if
|
||||
case $arg in #(
|
||||
-*) false ;; # don't mess with options #(
|
||||
/?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath
|
||||
[ -e "$t" ] ;; #(
|
||||
*) false ;;
|
||||
esac
|
||||
then
|
||||
arg=$( cygpath --path --ignore --mixed "$arg" )
|
||||
fi
|
||||
# Roll the args list around exactly as many times as the number of
|
||||
# args, so each arg winds up back in the position where it started, but
|
||||
# possibly modified.
|
||||
#
|
||||
# NB: a `for` loop captures its iteration list before it begins, so
|
||||
# changing the positional parameters here affects neither the number of
|
||||
# iterations, nor the values presented in `arg`.
|
||||
shift # remove old arg
|
||||
set -- "$@" "$arg" # push replacement arg
|
||||
done
|
||||
fi
|
||||
|
||||
# Collect all arguments for the java command;
|
||||
# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of
|
||||
# shell script including quotes and variable substitutions, so put them in
|
||||
# double quotes to make sure that they get re-expanded; and
|
||||
# * put everything else in single quotes, so that it's not re-expanded.
|
||||
|
||||
set -- \
|
||||
"-Dorg.gradle.appname=$APP_BASE_NAME" \
|
||||
-classpath "$CLASSPATH" \
|
||||
org.gradle.wrapper.GradleWrapperMain \
|
||||
"$@"
|
||||
|
||||
# Use "xargs" to parse quoted args.
|
||||
#
|
||||
# With -n1 it outputs one arg per line, with the quotes and backslashes removed.
|
||||
#
|
||||
# In Bash we could simply go:
|
||||
#
|
||||
# readarray ARGS < <( xargs -n1 <<<"$var" ) &&
|
||||
# set -- "${ARGS[@]}" "$@"
|
||||
#
|
||||
# but POSIX shell has neither arrays nor command substitution, so instead we
|
||||
# post-process each arg (as a line of input to sed) to backslash-escape any
|
||||
# character that might be a shell metacharacter, then use eval to reverse
|
||||
# that process (while maintaining the separation between arguments), and wrap
|
||||
# the whole thing up as a single "set" statement.
|
||||
#
|
||||
# This will of course break if any of these variables contains a newline or
|
||||
# an unmatched quote.
|
||||
#
|
||||
|
||||
eval "set -- $(
|
||||
printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" |
|
||||
xargs -n1 |
|
||||
sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' |
|
||||
tr '\n' ' '
|
||||
)" '"$@"'
|
||||
|
||||
exec "$JAVACMD" "$@"
|
||||
Vendored
+89
@@ -0,0 +1,89 @@
|
||||
@rem
|
||||
@rem Copyright 2015 the original author or authors.
|
||||
@rem
|
||||
@rem Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@rem you may not use this file except in compliance with the License.
|
||||
@rem You may obtain a copy of the License at
|
||||
@rem
|
||||
@rem https://www.apache.org/licenses/LICENSE-2.0
|
||||
@rem
|
||||
@rem Unless required by applicable law or agreed to in writing, software
|
||||
@rem distributed under the License is distributed on an "AS IS" BASIS,
|
||||
@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
@rem See the License for the specific language governing permissions and
|
||||
@rem limitations under the License.
|
||||
@rem
|
||||
|
||||
@if "%DEBUG%" == "" @echo off
|
||||
@rem ##########################################################################
|
||||
@rem
|
||||
@rem Gradle startup script for Windows
|
||||
@rem
|
||||
@rem ##########################################################################
|
||||
|
||||
@rem Set local scope for the variables with windows NT shell
|
||||
if "%OS%"=="Windows_NT" setlocal
|
||||
|
||||
set DIRNAME=%~dp0
|
||||
if "%DIRNAME%" == "" set DIRNAME=.
|
||||
set APP_BASE_NAME=%~n0
|
||||
set APP_HOME=%DIRNAME%
|
||||
|
||||
@rem Resolve any "." and ".." in APP_HOME to make it shorter.
|
||||
for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
|
||||
|
||||
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
|
||||
|
||||
@rem Find java.exe
|
||||
if defined JAVA_HOME goto findJavaFromJavaHome
|
||||
|
||||
set JAVA_EXE=java.exe
|
||||
%JAVA_EXE% -version >NUL 2>&1
|
||||
if "%ERRORLEVEL%" == "0" goto execute
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
echo.
|
||||
echo Please set the JAVA_HOME variable in your environment to match the
|
||||
echo location of your Java installation.
|
||||
|
||||
goto fail
|
||||
|
||||
:findJavaFromJavaHome
|
||||
set JAVA_HOME=%JAVA_HOME:"=%
|
||||
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
|
||||
|
||||
if exist "%JAVA_EXE%" goto execute
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
|
||||
echo.
|
||||
echo Please set the JAVA_HOME variable in your environment to match the
|
||||
echo location of your Java installation.
|
||||
|
||||
goto fail
|
||||
|
||||
:execute
|
||||
@rem Setup the command line
|
||||
|
||||
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
|
||||
|
||||
|
||||
@rem Execute Gradle
|
||||
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
|
||||
|
||||
:end
|
||||
@rem End local scope for the variables with windows NT shell
|
||||
if "%ERRORLEVEL%"=="0" goto mainEnd
|
||||
|
||||
:fail
|
||||
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
|
||||
rem the _cmd.exe /c_ return code!
|
||||
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
|
||||
exit /b 1
|
||||
|
||||
:mainEnd
|
||||
if "%OS%"=="Windows_NT" endlocal
|
||||
|
||||
:omega
|
||||
@@ -0,0 +1,60 @@
|
||||
import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar
|
||||
|
||||
plugins {
|
||||
`openinv-base`
|
||||
alias(libs.plugins.paperweight)
|
||||
}
|
||||
|
||||
//tasks {
|
||||
// withType<JavaCompile> {
|
||||
// // OpenPlayer unchecked warning is due to superclass' messy inheritance and legacy methods.
|
||||
// options.compilerArgs.add("-Xlint:unchecked")
|
||||
// // PlayerManager uses "deprecated" method matching vanilla to support legacy save data.
|
||||
// // While vanilla still feels that it is appropriate to use in the load process, we will too.
|
||||
// options.compilerArgs.add("-Xlint:deprecation")
|
||||
// }
|
||||
//}
|
||||
|
||||
configurations.all {
|
||||
resolutionStrategy.capabilitiesResolution.withCapability("org.spigotmc:spigot-api") {
|
||||
val paper = candidates.firstOrNull {
|
||||
it.id.let {
|
||||
id -> id is ModuleComponentIdentifier && id.module == "paper-api"
|
||||
}
|
||||
}
|
||||
if (paper != null) {
|
||||
select(paper)
|
||||
}
|
||||
because("module is written for Paper servers")
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation(project(":openinvapi"))
|
||||
implementation(project(":openinvcommon"))
|
||||
|
||||
paperweight.paperDevBundle("1.21.5-R0.1-SNAPSHOT")
|
||||
}
|
||||
|
||||
val spigot = tasks.register<ShadowJar>("spigotRelocations") {
|
||||
dependsOn(tasks.jar)
|
||||
from(sourceSets.main.get().output)
|
||||
relocate("com.lishid.openinv.internal.common", "com.lishid.openinv.internal.reobf")
|
||||
relocate("org.bukkit.craftbukkit", "org.bukkit.craftbukkit.${rootProject.extra["craftbukkitPackage"]}")
|
||||
archiveClassifier = "spigot"
|
||||
}
|
||||
|
||||
configurations {
|
||||
consumable("spigotRelocated") {
|
||||
attributes {
|
||||
attribute(Category.CATEGORY_ATTRIBUTE, objects.named(Category.LIBRARY))
|
||||
attribute(Usage.USAGE_ATTRIBUTE, objects.named(Usage.JAVA_RUNTIME))
|
||||
attribute(Bundling.BUNDLING_ATTRIBUTE, objects.named(Bundling.EXTERNAL))
|
||||
attribute(LibraryElements.LIBRARY_ELEMENTS_ATTRIBUTE, objects.named(LibraryElements.JAR))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
artifacts {
|
||||
add("spigotRelocated", spigot)
|
||||
}
|
||||
+13
-14
@@ -1,19 +1,19 @@
|
||||
package com.lishid.openinv.internal.v1_21_R3;
|
||||
package com.lishid.openinv.internal.common;
|
||||
|
||||
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.v1_21_R3.container.AnySilentContainer;
|
||||
import com.lishid.openinv.internal.v1_21_R3.container.OpenEnderChest;
|
||||
import com.lishid.openinv.internal.v1_21_R3.container.OpenInventory;
|
||||
import com.lishid.openinv.internal.v1_21_R3.container.Placeholders;
|
||||
import com.lishid.openinv.internal.v1_21_R3.player.PlayerManager;
|
||||
import com.lishid.openinv.internal.common.container.AnySilentContainer;
|
||||
import com.lishid.openinv.internal.common.container.OpenEnderChest;
|
||||
import com.lishid.openinv.internal.common.container.OpenInventory;
|
||||
import com.lishid.openinv.internal.common.container.slot.placeholder.PlaceholderLoader;
|
||||
import com.lishid.openinv.internal.common.player.PlayerManager;
|
||||
import com.lishid.openinv.util.lang.LanguageManager;
|
||||
import net.minecraft.world.Container;
|
||||
import org.bukkit.configuration.ConfigurationSection;
|
||||
import org.bukkit.craftbukkit.v1_21_R3.inventory.CraftInventory;
|
||||
import org.bukkit.craftbukkit.inventory.CraftInventory;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.Inventory;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -24,7 +24,7 @@ import java.util.logging.Logger;
|
||||
|
||||
public class InternalAccessor implements Accessor {
|
||||
|
||||
private final @NotNull Logger logger;
|
||||
protected final @NotNull Logger logger;
|
||||
private final @NotNull PlayerManager manager;
|
||||
private final @NotNull AnySilentContainer anySilentContainer;
|
||||
|
||||
@@ -69,12 +69,11 @@ public class InternalAccessor implements Accessor {
|
||||
@Override
|
||||
public void reload(@NotNull ConfigurationSection config) {
|
||||
ConfigurationSection placeholders = config.getConfigurationSection("placeholders");
|
||||
if (placeholders != null) {
|
||||
try {
|
||||
Placeholders.load(placeholders);
|
||||
} catch (Exception e) {
|
||||
logger.log(Level.WARNING, "Caught exception loading placeholder overrides!", e);
|
||||
}
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
+5
-5
@@ -14,11 +14,11 @@
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.lishid.openinv.internal.v1_21_R2.container;
|
||||
package com.lishid.openinv.internal.common.container;
|
||||
|
||||
import com.lishid.openinv.internal.AnySilentContainerBase;
|
||||
import com.lishid.openinv.internal.v1_21_R2.container.menu.OpenChestMenu;
|
||||
import com.lishid.openinv.internal.v1_21_R2.player.PlayerManager;
|
||||
import com.lishid.openinv.internal.common.container.menu.OpenChestMenu;
|
||||
import com.lishid.openinv.internal.common.player.PlayerManager;
|
||||
import com.lishid.openinv.util.ReflectionHelper;
|
||||
import com.lishid.openinv.util.lang.LanguageManager;
|
||||
import net.minecraft.core.BlockPos;
|
||||
@@ -61,10 +61,10 @@ public class AnySilentContainer extends AnySilentContainerBase {
|
||||
this.lang = lang;
|
||||
try {
|
||||
try {
|
||||
this.serverPlayerGameModeGameType = ServerPlayerGameMode.class.getDeclaredField("b");
|
||||
this.serverPlayerGameModeGameType = ServerPlayerGameMode.class.getDeclaredField("gameModeForPlayer");
|
||||
this.serverPlayerGameModeGameType.setAccessible(true);
|
||||
} catch (NoSuchFieldException e) {
|
||||
logger.warning("ServerPlayerGameMode#gameModeForPlayer's obfuscated name has changed!");
|
||||
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.
|
||||
+15
-15
@@ -1,9 +1,9 @@
|
||||
package com.lishid.openinv.internal.v1_21_R3.container;
|
||||
package com.lishid.openinv.internal.common.container;
|
||||
|
||||
import com.lishid.openinv.internal.ISpecialEnderChest;
|
||||
import com.lishid.openinv.internal.InternalOwned;
|
||||
import com.lishid.openinv.internal.v1_21_R3.container.menu.OpenEnderChestMenu;
|
||||
import com.lishid.openinv.internal.v1_21_R3.player.PlayerManager;
|
||||
import com.lishid.openinv.internal.common.container.menu.OpenEnderChestMenu;
|
||||
import com.lishid.openinv.internal.common.player.PlayerManager;
|
||||
import net.minecraft.core.NonNullList;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
@@ -15,8 +15,8 @@ import net.minecraft.world.inventory.AbstractContainerMenu;
|
||||
import net.minecraft.world.inventory.StackedContentsCompatible;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.craftbukkit.v1_21_R3.entity.CraftHumanEntity;
|
||||
import org.bukkit.craftbukkit.v1_21_R3.inventory.CraftInventory;
|
||||
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;
|
||||
@@ -90,12 +90,12 @@ public class OpenEnderChest implements Container, StackedContentsCompatible, Int
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack getItem(int index) {
|
||||
public @NotNull ItemStack getItem(int index) {
|
||||
return index >= 0 && index < items.size() ? items.get(index) : ItemStack.EMPTY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack removeItem(int index, int amount) {
|
||||
public @NotNull ItemStack removeItem(int index, int amount) {
|
||||
ItemStack itemstack = ContainerHelper.removeItem(items, index, amount);
|
||||
|
||||
if (!itemstack.isEmpty()) {
|
||||
@@ -106,12 +106,12 @@ public class OpenEnderChest implements Container, StackedContentsCompatible, Int
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack removeItemNoUpdate(int index) {
|
||||
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, ItemStack itemStack) {
|
||||
public void setItem(int index, @NotNull ItemStack itemStack) {
|
||||
if (index >= 0 && index < items.size()) {
|
||||
items.set(index, itemStack);
|
||||
}
|
||||
@@ -128,27 +128,27 @@ public class OpenEnderChest implements Container, StackedContentsCompatible, Int
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean stillValid(Player player) {
|
||||
public boolean stillValid(@NotNull Player player) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ItemStack> getContents() {
|
||||
public @NotNull List<ItemStack> getContents() {
|
||||
return items;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onOpen(CraftHumanEntity craftHumanEntity) {
|
||||
public void onOpen(@NotNull CraftHumanEntity craftHumanEntity) {
|
||||
transaction.add(craftHumanEntity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClose(CraftHumanEntity craftHumanEntity) {
|
||||
public void onClose(@NotNull CraftHumanEntity craftHumanEntity) {
|
||||
transaction.remove(craftHumanEntity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<HumanEntity> getViewers() {
|
||||
public @NotNull List<HumanEntity> getViewers() {
|
||||
return transaction;
|
||||
}
|
||||
|
||||
@@ -174,7 +174,7 @@ public class OpenEnderChest implements Container, StackedContentsCompatible, Int
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fillStackedContents(StackedItemContents stackedContents) {
|
||||
public void fillStackedContents(@NotNull StackedItemContents stackedContents) {
|
||||
for (ItemStack itemstack : items) {
|
||||
stackedContents.accountStack(itemstack);
|
||||
}
|
||||
+64
-71
@@ -1,20 +1,22 @@
|
||||
package com.lishid.openinv.internal.v1_21_R3.container;
|
||||
package com.lishid.openinv.internal.common.container;
|
||||
|
||||
import com.lishid.openinv.internal.ISpecialPlayerInventory;
|
||||
import com.lishid.openinv.internal.InternalOwned;
|
||||
import com.lishid.openinv.internal.v1_21_R3.container.bukkit.OpenPlayerInventory;
|
||||
import com.lishid.openinv.internal.v1_21_R3.container.menu.OpenInventoryMenu;
|
||||
import com.lishid.openinv.internal.v1_21_R3.container.slot.Content;
|
||||
import com.lishid.openinv.internal.v1_21_R3.container.slot.ContentCrafting;
|
||||
import com.lishid.openinv.internal.v1_21_R3.container.slot.ContentCraftingResult;
|
||||
import com.lishid.openinv.internal.v1_21_R3.container.slot.ContentCursor;
|
||||
import com.lishid.openinv.internal.v1_21_R3.container.slot.ContentDrop;
|
||||
import com.lishid.openinv.internal.v1_21_R3.container.slot.ContentEquipment;
|
||||
import com.lishid.openinv.internal.v1_21_R3.container.slot.ContentList;
|
||||
import com.lishid.openinv.internal.v1_21_R3.container.slot.ContentOffHand;
|
||||
import com.lishid.openinv.internal.v1_21_R3.container.slot.ContentViewOnly;
|
||||
import com.lishid.openinv.internal.v1_21_R3.container.slot.SlotViewOnly;
|
||||
import com.lishid.openinv.internal.v1_21_R3.player.PlayerManager;
|
||||
import com.lishid.openinv.internal.common.container.bukkit.OpenPlayerInventory;
|
||||
import com.lishid.openinv.internal.common.container.menu.OpenInventoryMenu;
|
||||
import com.lishid.openinv.internal.common.container.slot.Content;
|
||||
import com.lishid.openinv.internal.common.container.slot.ContentCrafting;
|
||||
import com.lishid.openinv.internal.common.container.slot.ContentCraftingResult;
|
||||
import com.lishid.openinv.internal.common.container.slot.ContentCursor;
|
||||
import com.lishid.openinv.internal.common.container.slot.ContentDrop;
|
||||
import com.lishid.openinv.internal.common.container.slot.ContentEquipment;
|
||||
import com.lishid.openinv.internal.common.container.slot.ContentList;
|
||||
import com.lishid.openinv.internal.common.container.slot.ContentOffHand;
|
||||
import com.lishid.openinv.internal.common.container.slot.ContentViewOnly;
|
||||
import com.lishid.openinv.internal.common.container.slot.SlotViewOnly;
|
||||
import com.lishid.openinv.internal.common.container.slot.placeholder.Placeholders;
|
||||
import com.lishid.openinv.internal.common.player.PlayerManager;
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
|
||||
import net.minecraft.ChatFormatting;
|
||||
import net.minecraft.core.NonNullList;
|
||||
import net.minecraft.network.chat.Component;
|
||||
@@ -29,21 +31,23 @@ import net.minecraft.world.inventory.AbstractContainerMenu;
|
||||
import net.minecraft.world.inventory.Slot;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.craftbukkit.v1_21_R3.entity.CraftHumanEntity;
|
||||
import org.bukkit.craftbukkit.v1_21_R3.inventory.CraftInventory;
|
||||
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.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class OpenInventory implements Container, InternalOwned<ServerPlayer>, ISpecialPlayerInventory {
|
||||
|
||||
private final List<Content> slots;
|
||||
protected final List<Content> slots;
|
||||
private final int size;
|
||||
private ServerPlayer owner;
|
||||
protected ServerPlayer owner;
|
||||
private int maxStackSize = 99;
|
||||
private CraftInventory bukkitEntity;
|
||||
public List<HumanEntity> transaction = new ArrayList<>();
|
||||
@@ -59,15 +63,14 @@ public class OpenInventory implements Container, InternalOwned<ServerPlayer>, IS
|
||||
setupSlots();
|
||||
}
|
||||
|
||||
private void setupSlots() {
|
||||
protected void setupSlots() {
|
||||
// Top of inventory: Regular contents.
|
||||
int nextIndex = addMainInventory();
|
||||
|
||||
// If inventory is expected size, we can arrange slots to be pretty.
|
||||
Inventory ownerInv = owner.getInventory();
|
||||
if (ownerInv.items.size() == 36
|
||||
&& ownerInv.armor.size() == 4
|
||||
&& ownerInv.offhand.size() == 1
|
||||
if (ownerInv.getNonEquipmentItems().size() == 36
|
||||
&& Inventory.EQUIPMENT_SLOT_MAPPING.size() == 5
|
||||
&& owner.inventoryMenu.getCraftSlots().getContainerSize() == 4) {
|
||||
// Armor slots: Bottom left.
|
||||
addArmor(36);
|
||||
@@ -94,7 +97,7 @@ public class OpenInventory implements Container, InternalOwned<ServerPlayer>, IS
|
||||
}
|
||||
|
||||
private int addMainInventory() {
|
||||
int listSize = owner.getInventory().items.size();
|
||||
int listSize = owner.getInventory().getNonEquipmentItems().size();
|
||||
// Hotbar slots are 0-8. We want those to appear on the bottom of the inventory like a normal player inventory,
|
||||
// so everything else needs to move up a row.
|
||||
int hotbarDiff = listSize - 9;
|
||||
@@ -112,7 +115,7 @@ public class OpenInventory implements Container, InternalOwned<ServerPlayer>, IS
|
||||
slots.set(localIndex, new ContentList(owner, invIndex, type) {
|
||||
@Override
|
||||
public void setHolder(@NotNull ServerPlayer holder) {
|
||||
items = holder.getInventory().items;
|
||||
items = holder.getInventory().getNonEquipmentItems();
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -120,50 +123,36 @@ public class OpenInventory implements Container, InternalOwned<ServerPlayer>, IS
|
||||
}
|
||||
|
||||
private int addArmor(int startIndex) {
|
||||
int listSize = owner.getInventory().armor.size();
|
||||
|
||||
for (int i = 0; i < listSize; ++i) {
|
||||
// Armor slots go bottom to top; boots are slot 0, helmet is slot 3.
|
||||
// Since we have to display horizontally due to space restrictions,
|
||||
// making the left side the "top" is more user-friendly.
|
||||
int armorIndex;
|
||||
EquipmentSlot slot;
|
||||
switch (i) {
|
||||
case 3 -> {
|
||||
armorIndex = 0;
|
||||
slot = EquipmentSlot.FEET;
|
||||
}
|
||||
case 2 -> {
|
||||
armorIndex = 1;
|
||||
slot = EquipmentSlot.LEGS;
|
||||
}
|
||||
case 1 -> {
|
||||
armorIndex = 2;
|
||||
slot = EquipmentSlot.CHEST;
|
||||
}
|
||||
case 0 -> {
|
||||
armorIndex = 3;
|
||||
slot = EquipmentSlot.HEAD;
|
||||
}
|
||||
default -> {
|
||||
// In the event that new armor slots are added, they can be placed at the end.
|
||||
armorIndex = i;
|
||||
slot = EquipmentSlot.MAINHAND;
|
||||
}
|
||||
// Armor slots go bottom to top; boots are first and helmet is last.
|
||||
// Since we have to display horizontally due to space restrictions,
|
||||
// making the left side the "top" is more user-friendly.
|
||||
EquipmentSlot[] sorted = Inventory.EQUIPMENT_SLOT_MAPPING.int2ObjectEntrySet()
|
||||
.stream()
|
||||
.sorted(Comparator.comparingInt(Int2ObjectMap.Entry::getIntKey))
|
||||
.map(Map.Entry::getValue)
|
||||
.toArray(EquipmentSlot[]::new);
|
||||
int localIndex = 0;
|
||||
for (int i = sorted.length - 1; i >= 0; --i) {
|
||||
// Skip off-hand, handled separately.
|
||||
if (sorted[i] == EquipmentSlot.OFFHAND) {
|
||||
continue;
|
||||
}
|
||||
|
||||
slots.set(startIndex + i, new ContentEquipment(owner, armorIndex, slot));
|
||||
slots.set(startIndex + localIndex, new ContentEquipment(owner, sorted[i]));
|
||||
++localIndex;
|
||||
}
|
||||
|
||||
return startIndex + listSize;
|
||||
return startIndex + localIndex;
|
||||
}
|
||||
|
||||
private int addOffHand(int startIndex) {
|
||||
int listSize = owner.getInventory().offhand.size();
|
||||
for (int localIndex = 0; localIndex < listSize; ++localIndex) {
|
||||
slots.set(startIndex + localIndex, new ContentOffHand(owner, localIndex));
|
||||
// No off-hand?
|
||||
if (!Inventory.EQUIPMENT_SLOT_MAPPING.containsValue(EquipmentSlot.OFFHAND)) {
|
||||
return startIndex;
|
||||
}
|
||||
return startIndex + listSize;
|
||||
|
||||
slots.set(startIndex, new ContentOffHand(owner));
|
||||
return startIndex + 1;
|
||||
}
|
||||
|
||||
private int addCrafting(int startIndex, boolean pretty) {
|
||||
@@ -191,12 +180,16 @@ public class OpenInventory implements Container, InternalOwned<ServerPlayer>, IS
|
||||
};
|
||||
}
|
||||
});
|
||||
slots.set(startIndex + 11, new ContentCraftingResult(owner));
|
||||
slots.set(startIndex + 11, getCraftingResult(owner));
|
||||
}
|
||||
|
||||
return startIndex + listSize;
|
||||
}
|
||||
|
||||
protected Content getCraftingResult(@NotNull ServerPlayer serverPlayer) {
|
||||
return new ContentCraftingResult(serverPlayer);
|
||||
}
|
||||
|
||||
public Slot getMenuSlot(int index, int x, int y) {
|
||||
return slots.get(index).asSlot(this, index, x, y);
|
||||
}
|
||||
@@ -275,22 +268,22 @@ public class OpenInventory implements Container, InternalOwned<ServerPlayer>, IS
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack getItem(int index) {
|
||||
public @NotNull ItemStack getItem(int index) {
|
||||
return slots.get(index).get();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack removeItem(int index, int amount) {
|
||||
public @NotNull ItemStack removeItem(int index, int amount) {
|
||||
return slots.get(index).removePartial(amount);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack removeItemNoUpdate(int index) {
|
||||
public @NotNull ItemStack removeItemNoUpdate(int index) {
|
||||
return slots.get(index).remove();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setItem(int index, ItemStack itemStack) {
|
||||
public void setItem(int index, @NotNull ItemStack itemStack) {
|
||||
slots.get(index).set(itemStack);
|
||||
}
|
||||
|
||||
@@ -308,12 +301,12 @@ public class OpenInventory implements Container, InternalOwned<ServerPlayer>, IS
|
||||
public void setChanged() {}
|
||||
|
||||
@Override
|
||||
public boolean stillValid(Player player) {
|
||||
public boolean stillValid(@NotNull Player player) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ItemStack> getContents() {
|
||||
public @NotNull List<ItemStack> getContents() {
|
||||
NonNullList<ItemStack> contents = NonNullList.withSize(getContainerSize(), ItemStack.EMPTY);
|
||||
for (int i = 0; i < getContainerSize(); ++i) {
|
||||
contents.set(i, getItem(i));
|
||||
@@ -322,22 +315,22 @@ public class OpenInventory implements Container, InternalOwned<ServerPlayer>, IS
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onOpen(CraftHumanEntity viewer) {
|
||||
public void onOpen(@NotNull CraftHumanEntity viewer) {
|
||||
transaction.add(viewer);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClose(CraftHumanEntity viewer) {
|
||||
public void onClose(@NotNull CraftHumanEntity viewer) {
|
||||
transaction.remove(viewer);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<HumanEntity> getViewers() {
|
||||
public @NotNull List<HumanEntity> getViewers() {
|
||||
return transaction;
|
||||
}
|
||||
|
||||
@Override
|
||||
public org.bukkit.entity.Player getOwner() {
|
||||
public @NotNull org.bukkit.entity.Player getOwner() {
|
||||
return owner.getBukkitEntity();
|
||||
}
|
||||
|
||||
+4
-4
@@ -1,9 +1,9 @@
|
||||
package com.lishid.openinv.internal.v1_21_R2.container.bukkit;
|
||||
package com.lishid.openinv.internal.common.container.bukkit;
|
||||
|
||||
import com.lishid.openinv.internal.ViewOnly;
|
||||
import net.minecraft.world.Container;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.craftbukkit.v1_21_R2.inventory.CraftInventory;
|
||||
import org.bukkit.craftbukkit.inventory.CraftInventory;
|
||||
import org.bukkit.event.inventory.InventoryType;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -62,7 +62,7 @@ public class OpenDummyInventory extends CraftInventory implements ViewOnly {
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack[] getContents() {
|
||||
public ItemStack @NotNull [] getContents() {
|
||||
return new ItemStack[getSize()];
|
||||
}
|
||||
|
||||
@@ -72,7 +72,7 @@ public class OpenDummyInventory extends CraftInventory implements ViewOnly {
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull ItemStack[] getStorageContents() {
|
||||
public @NotNull ItemStack @NotNull [] getStorageContents() {
|
||||
return new ItemStack[getSize()];
|
||||
}
|
||||
|
||||
+9
-7
@@ -1,4 +1,4 @@
|
||||
package com.lishid.openinv.internal.v1_21_R2.container.bukkit;
|
||||
package com.lishid.openinv.internal.common.container.bukkit;
|
||||
|
||||
import net.minecraft.world.Container;
|
||||
import org.bukkit.Material;
|
||||
@@ -22,12 +22,12 @@ public class OpenDummyPlayerInventory extends OpenDummyInventory implements Play
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull ItemStack[] getArmorContents() {
|
||||
public @NotNull ItemStack @NotNull [] getArmorContents() {
|
||||
return new ItemStack[4];
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull ItemStack[] getExtraContents() {
|
||||
public @NotNull ItemStack @NotNull [] getExtraContents() {
|
||||
return new ItemStack[4];
|
||||
}
|
||||
|
||||
@@ -57,17 +57,17 @@ public class OpenDummyPlayerInventory extends OpenDummyInventory implements Play
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable ItemStack getItem(@NotNull EquipmentSlot slot) {
|
||||
return null;
|
||||
public @NotNull ItemStack getItem(@NotNull EquipmentSlot slot) {
|
||||
return new ItemStack(Material.AIR);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setArmorContents(@Nullable ItemStack[] items) {
|
||||
public void setArmorContents(ItemStack @NotNull [] items) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setExtraContents(@Nullable ItemStack[] items) {
|
||||
public void setExtraContents(ItemStack @NotNull [] items) {
|
||||
|
||||
}
|
||||
|
||||
@@ -111,11 +111,13 @@ public class OpenDummyPlayerInventory extends OpenDummyInventory implements Play
|
||||
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
@Override
|
||||
public @NotNull ItemStack getItemInHand() {
|
||||
return new ItemStack(Material.AIR);
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
@Override
|
||||
public void setItemInHand(@Nullable ItemStack stack) {
|
||||
|
||||
+54
-49
@@ -1,12 +1,12 @@
|
||||
package com.lishid.openinv.internal.v1_21_R3.container.bukkit;
|
||||
package com.lishid.openinv.internal.common.container.bukkit;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
import com.lishid.openinv.internal.v1_21_R3.container.OpenInventory;
|
||||
import com.lishid.openinv.internal.common.container.OpenInventory;
|
||||
import net.minecraft.core.NonNullList;
|
||||
import net.minecraft.world.entity.EquipmentSlot;
|
||||
import net.minecraft.world.entity.player.Inventory;
|
||||
import org.bukkit.craftbukkit.v1_21_R3.inventory.CraftInventory;
|
||||
import org.bukkit.craftbukkit.v1_21_R3.inventory.CraftItemStack;
|
||||
import org.bukkit.craftbukkit.inventory.CraftInventory;
|
||||
import org.bukkit.craftbukkit.inventory.CraftItemStack;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.inventory.InventoryType;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
@@ -14,6 +14,8 @@ import org.bukkit.inventory.PlayerInventory;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class OpenPlayerInventory extends CraftInventory implements PlayerInventory {
|
||||
|
||||
public OpenPlayerInventory(@NotNull OpenInventory inventory) {
|
||||
@@ -26,7 +28,7 @@ public class OpenPlayerInventory extends CraftInventory implements PlayerInvento
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack[] getContents() {
|
||||
public ItemStack @NotNull [] getContents() {
|
||||
return asCraftMirror(getInventory().getOwnerHandle().getInventory().getContents());
|
||||
}
|
||||
|
||||
@@ -46,13 +48,13 @@ public class OpenPlayerInventory extends CraftInventory implements PlayerInvento
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack[] getStorageContents() {
|
||||
return asCraftMirror(getInventory().getOwnerHandle().getInventory().items);
|
||||
public ItemStack @NotNull [] getStorageContents() {
|
||||
return asCraftMirror(getInventory().getOwnerHandle().getInventory().getNonEquipmentItems());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setStorageContents(ItemStack[] items) throws IllegalArgumentException {
|
||||
NonNullList<net.minecraft.world.item.ItemStack> list = getInventory().getOwnerHandle().getInventory().items;
|
||||
NonNullList<net.minecraft.world.item.ItemStack> list = getInventory().getOwnerHandle().getInventory().getNonEquipmentItems();
|
||||
int size = list.size();
|
||||
Preconditions.checkArgument(items.length <= size, "items.length must be <= %s", size);
|
||||
for (int index = 0; index < items.length; ++index) {
|
||||
@@ -71,110 +73,113 @@ public class OpenPlayerInventory extends CraftInventory implements PlayerInvento
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull ItemStack[] getArmorContents() {
|
||||
return asCraftMirror(getInventory().getOwnerHandle().getInventory().armor);
|
||||
public @NotNull ItemStack @NotNull [] getArmorContents() {
|
||||
return asCraftMirror(getInventory().getOwnerHandle().getInventory().getArmorContents());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setArmorContents(@Nullable ItemStack[] items) {
|
||||
NonNullList<net.minecraft.world.item.ItemStack> list = getInventory().getOwnerHandle().getInventory().armor;
|
||||
int size = list.size();
|
||||
public void setArmorContents(ItemStack @NotNull [] items) {
|
||||
int size = Inventory.EQUIPMENT_SLOTS_SORTED_BY_INDEX.length;
|
||||
Preconditions.checkArgument(items.length <= size, "items.length must be <= %s", size);
|
||||
for (int index = 0; index < items.length; ++index) {
|
||||
list.set(index, CraftItemStack.asNMSCopy(items[index]));
|
||||
getInventory().getOwnerHandle().getInventory().equipment.set(
|
||||
Inventory.EQUIPMENT_SLOTS_SORTED_BY_INDEX[index],
|
||||
CraftItemStack.asNMSCopy(items[index]));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull ItemStack[] getExtraContents() {
|
||||
return asCraftMirror(getInventory().getOwnerHandle().getInventory().offhand);
|
||||
public @NotNull ItemStack @NotNull [] getExtraContents() {
|
||||
return asCraftMirror(List.of(getInventory().getOwnerHandle().getInventory().equipment.get(EquipmentSlot.OFFHAND)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setExtraContents(@Nullable ItemStack[] items) {
|
||||
NonNullList<net.minecraft.world.item.ItemStack> list = getInventory().getOwnerHandle().getInventory().offhand;
|
||||
int size = list.size();
|
||||
Preconditions.checkArgument(items.length <= size, "items.length must be <= %s", size);
|
||||
for (int index = 0; index < items.length; ++index) {
|
||||
list.set(index, CraftItemStack.asNMSCopy(items[index]));
|
||||
public void setExtraContents(ItemStack @NotNull [] items) {
|
||||
Preconditions.checkArgument(items.length <= 1, "items.length must be <= 1");
|
||||
for (ItemStack item : items) {
|
||||
getInventory().getOwnerHandle().getInventory().equipment.set(EquipmentSlot.OFFHAND, CraftItemStack.asNMSCopy(item));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable ItemStack getHelmet() {
|
||||
return CraftItemStack.asCraftMirror(getInventory().getOwnerHandle().getInventory()
|
||||
.getArmor(EquipmentSlot.HEAD.getIndex()));
|
||||
public @NotNull ItemStack getHelmet() {
|
||||
return CraftItemStack.asCraftMirror(getInventory().getOwnerHandle().getInventory().equipment
|
||||
.get(EquipmentSlot.HEAD));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setHelmet(@Nullable ItemStack helmet) {
|
||||
getInventory().getOwnerHandle().getInventory().armor
|
||||
.set(EquipmentSlot.HEAD.getIndex(), CraftItemStack.asNMSCopy(helmet));
|
||||
getInventory().getOwnerHandle().getInventory().equipment
|
||||
.set(EquipmentSlot.HEAD, CraftItemStack.asNMSCopy(helmet));
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable ItemStack getChestplate() {
|
||||
return CraftItemStack.asCraftMirror(getInventory().getOwnerHandle().getInventory()
|
||||
.getArmor(EquipmentSlot.HEAD.getIndex()));
|
||||
public @NotNull ItemStack getChestplate() {
|
||||
return CraftItemStack.asCraftMirror(getInventory().getOwnerHandle().getInventory().equipment
|
||||
.get(EquipmentSlot.CHEST));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setChestplate(@Nullable ItemStack chestplate) {
|
||||
getInventory().getOwnerHandle().getInventory().armor
|
||||
.set(EquipmentSlot.CHEST.getIndex(), CraftItemStack.asNMSCopy(chestplate));
|
||||
getInventory().getOwnerHandle().getInventory().equipment
|
||||
.set(EquipmentSlot.CHEST, CraftItemStack.asNMSCopy(chestplate));
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable ItemStack getLeggings() {
|
||||
return CraftItemStack.asCraftMirror(getInventory().getOwnerHandle().getInventory()
|
||||
.getArmor(EquipmentSlot.LEGS.getIndex()));
|
||||
public @NotNull ItemStack getLeggings() {
|
||||
return CraftItemStack.asCraftMirror(getInventory().getOwnerHandle().getInventory().equipment
|
||||
.get(EquipmentSlot.LEGS));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setLeggings(@Nullable ItemStack leggings) {
|
||||
getInventory().getOwnerHandle().getInventory().armor
|
||||
.set(EquipmentSlot.LEGS.getIndex(), CraftItemStack.asNMSCopy(leggings));
|
||||
getInventory().getOwnerHandle().getInventory().equipment
|
||||
.set(EquipmentSlot.LEGS, CraftItemStack.asNMSCopy(leggings));
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable ItemStack getBoots() {
|
||||
return CraftItemStack.asCraftMirror(getInventory().getOwnerHandle().getInventory()
|
||||
.getArmor(EquipmentSlot.FEET.getIndex()));
|
||||
public @NotNull ItemStack getBoots() {
|
||||
return CraftItemStack.asCraftMirror(getInventory().getOwnerHandle().getInventory().equipment
|
||||
.get(EquipmentSlot.FEET));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBoots(@Nullable ItemStack boots) {
|
||||
getInventory().getOwnerHandle().getInventory().armor
|
||||
.set(EquipmentSlot.FEET.getIndex(), CraftItemStack.asNMSCopy(boots));
|
||||
getInventory().getOwnerHandle().getInventory().equipment
|
||||
.set(EquipmentSlot.FEET, CraftItemStack.asNMSCopy(boots));
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull ItemStack getItemInMainHand() {
|
||||
Inventory internal = getInventory().getOwnerHandle().getInventory();
|
||||
return CraftItemStack.asCraftMirror(internal.getItem(internal.selected));
|
||||
return CraftItemStack.asCraftMirror(internal.getSelectedItem());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setItemInMainHand(@Nullable ItemStack item) {
|
||||
Inventory internal = getInventory().getOwnerHandle().getInventory();
|
||||
internal.setItem(internal.selected, CraftItemStack.asNMSCopy(item));
|
||||
internal.setSelectedItem(CraftItemStack.asNMSCopy(item));
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull ItemStack getItemInOffHand() {
|
||||
return CraftItemStack.asCraftMirror(getInventory().getOwnerHandle().getInventory().offhand.getFirst());
|
||||
return CraftItemStack.asCraftMirror(getInventory().getOwnerHandle().getInventory().equipment
|
||||
.get(EquipmentSlot.OFFHAND));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setItemInOffHand(@Nullable ItemStack item) {
|
||||
getInventory().getOwnerHandle().getInventory().offhand.set(0, CraftItemStack.asNMSCopy(item));
|
||||
getInventory().getOwnerHandle().getInventory().equipment
|
||||
.set(EquipmentSlot.OFFHAND, CraftItemStack.asNMSCopy(item));
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
@Override
|
||||
public @NotNull ItemStack getItemInHand() {
|
||||
return getItemInMainHand();
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
@Override
|
||||
public void setItemInHand(@Nullable ItemStack stack) {
|
||||
setItemInMainHand(stack);
|
||||
@@ -183,17 +188,17 @@ public class OpenPlayerInventory extends CraftInventory implements PlayerInvento
|
||||
@Override
|
||||
public int getHeldItemSlot() {
|
||||
Inventory internal = getInventory().getOwnerHandle().getInventory();
|
||||
return internal.items.size() - 9 + internal.selected;
|
||||
return internal.getNonEquipmentItems().size() - 9 + internal.getSelectedSlot();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setHeldItemSlot(int slot) {
|
||||
slot %= 9;
|
||||
getInventory().getOwnerHandle().getInventory().selected = slot;
|
||||
getInventory().getOwnerHandle().getInventory().setSelectedSlot(slot);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable ItemStack getItem(@NotNull org.bukkit.inventory.EquipmentSlot slot) {
|
||||
public @NotNull ItemStack getItem(@NotNull org.bukkit.inventory.EquipmentSlot slot) {
|
||||
return switch (slot) {
|
||||
case HAND -> getItemInMainHand();
|
||||
case OFF_HAND -> getItemInOffHand();
|
||||
+2
-2
@@ -1,6 +1,6 @@
|
||||
package com.lishid.openinv.internal.v1_21_R2.container.bukkit;
|
||||
package com.lishid.openinv.internal.common.container.bukkit;
|
||||
|
||||
import com.lishid.openinv.internal.v1_21_R2.container.OpenInventory;
|
||||
import com.lishid.openinv.internal.common.container.OpenInventory;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
+49
-40
@@ -1,13 +1,14 @@
|
||||
package com.lishid.openinv.internal.v1_21_R2.container.menu;
|
||||
package com.lishid.openinv.internal.common.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.v1_21_R2.container.bukkit.OpenDummyInventory;
|
||||
import com.lishid.openinv.internal.v1_21_R2.container.slot.SlotPlaceholder;
|
||||
import com.lishid.openinv.internal.v1_21_R2.container.slot.SlotViewOnly;
|
||||
import com.lishid.openinv.internal.common.container.bukkit.OpenDummyInventory;
|
||||
import com.lishid.openinv.internal.common.container.slot.SlotPlaceholder;
|
||||
import com.lishid.openinv.internal.common.container.slot.SlotViewOnly;
|
||||
import it.unimi.dsi.fastutil.ints.IntArrayList;
|
||||
import it.unimi.dsi.fastutil.ints.IntList;
|
||||
import net.minecraft.network.HashedStack;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.world.Container;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
@@ -19,9 +20,10 @@ import net.minecraft.world.inventory.ContainerListener;
|
||||
import net.minecraft.world.inventory.ContainerSynchronizer;
|
||||
import net.minecraft.world.inventory.DataSlot;
|
||||
import net.minecraft.world.inventory.MenuType;
|
||||
import net.minecraft.world.inventory.RemoteSlot;
|
||||
import net.minecraft.world.inventory.Slot;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import org.bukkit.craftbukkit.v1_21_R2.inventory.CraftInventoryView;
|
||||
import org.bukkit.craftbukkit.inventory.CraftInventoryView;
|
||||
import org.bukkit.event.inventory.InventoryType;
|
||||
import org.bukkit.inventory.Inventory;
|
||||
import org.bukkit.inventory.InventoryView;
|
||||
@@ -47,12 +49,12 @@ public abstract class OpenChestMenu<T extends Container & ISpecialInventory & In
|
||||
protected final int topSize;
|
||||
private CraftInventoryView<OpenChestMenu<T>, Inventory> bukkitEntity;
|
||||
// Syncher fields
|
||||
private @Nullable ContainerSynchronizer synchronizer;
|
||||
private final List<DataSlot> dataSlots = new ArrayList<>();
|
||||
private final IntList remoteDataSlots = new IntArrayList();
|
||||
private final List<ContainerListener> containerListeners = new ArrayList<>();
|
||||
private ItemStack remoteCarried = ItemStack.EMPTY;
|
||||
private boolean suppressRemoteUpdates;
|
||||
protected @Nullable ContainerSynchronizer synchronizer;
|
||||
protected final List<DataSlot> dataSlots = new ArrayList<>();
|
||||
protected final IntList remoteDataSlots = new IntArrayList();
|
||||
protected final List<ContainerListener> containerListeners = new ArrayList<>();
|
||||
private RemoteSlot remoteCarried = RemoteSlot.PLACEHOLDER;
|
||||
protected boolean suppressRemoteUpdates;
|
||||
|
||||
protected OpenChestMenu(
|
||||
@NotNull MenuType<ChestMenu> type,
|
||||
@@ -124,10 +126,11 @@ public abstract class OpenChestMenu<T extends Container & ISpecialInventory & In
|
||||
protected void preSlotSetup() {}
|
||||
|
||||
protected @NotNull Slot getUpperSlot(int index, int x, int y) {
|
||||
Slot slot = new Slot(container, index, x, y);
|
||||
if (viewOnly) {
|
||||
return new SlotViewOnly(container, index, x, y);
|
||||
return SlotViewOnly.wrap(slot);
|
||||
}
|
||||
return new Slot(container, index, x, y);
|
||||
return slot;
|
||||
}
|
||||
|
||||
|
||||
@@ -176,9 +179,7 @@ public abstract class OpenChestMenu<T extends Container & ISpecialInventory & In
|
||||
|
||||
private int getTopSize(ServerPlayer viewer) {
|
||||
MenuType<?> menuType = getType();
|
||||
if (menuType == null) {
|
||||
throw new IllegalStateException("MenuType cannot be null!");
|
||||
} else if (menuType == MenuType.GENERIC_9x1) {
|
||||
if (menuType == MenuType.GENERIC_9x1) {
|
||||
return 9;
|
||||
} else if (menuType == MenuType.GENERIC_9x2) {
|
||||
return 18;
|
||||
@@ -284,7 +285,7 @@ public abstract class OpenChestMenu<T extends Container & ISpecialInventory & In
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clicked(int i, int j, ClickType clickType, Player player) {
|
||||
public void clicked(int i, int j, @NotNull ClickType clickType, @NotNull Player player) {
|
||||
if (viewOnly) {
|
||||
if (clickType == ClickType.QUICK_CRAFT) {
|
||||
sendAllDataToRemote();
|
||||
@@ -295,22 +296,22 @@ public abstract class OpenChestMenu<T extends Container & ISpecialInventory & In
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean stillValid(Player player) {
|
||||
public boolean stillValid(@NotNull Player player) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Overrides from here on are purely to modify the sync process to send placeholder items.
|
||||
@Override
|
||||
protected Slot addSlot(Slot slot) {
|
||||
protected @NotNull Slot addSlot(@NotNull Slot slot) {
|
||||
slot.index = this.slots.size();
|
||||
this.slots.add(slot);
|
||||
this.lastSlots.add(ItemStack.EMPTY);
|
||||
this.remoteSlots.add(ItemStack.EMPTY);
|
||||
this.remoteSlots.add(this.synchronizer != null ? this.synchronizer.createSlot() : RemoteSlot.PLACEHOLDER);
|
||||
return slot;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected DataSlot addDataSlot(DataSlot dataSlot) {
|
||||
protected @NotNull DataSlot addDataSlot(@NotNull DataSlot dataSlot) {
|
||||
this.dataSlots.add(dataSlot);
|
||||
this.remoteDataSlots.add(0);
|
||||
return dataSlot;
|
||||
@@ -324,7 +325,7 @@ public abstract class OpenChestMenu<T extends Container & ISpecialInventory & In
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addSlotListener(ContainerListener containerListener) {
|
||||
public void addSlotListener(@NotNull ContainerListener containerListener) {
|
||||
if (!this.containerListeners.contains(containerListener)) {
|
||||
this.containerListeners.add(containerListener);
|
||||
this.broadcastChanges();
|
||||
@@ -332,39 +333,45 @@ public abstract class OpenChestMenu<T extends Container & ISpecialInventory & In
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSynchronizer(ContainerSynchronizer containerSynchronizer) {
|
||||
public void setSynchronizer(@NotNull ContainerSynchronizer containerSynchronizer) {
|
||||
this.synchronizer = containerSynchronizer;
|
||||
this.remoteCarried = synchronizer.createSlot();
|
||||
this.remoteSlots.replaceAll(slot -> synchronizer.createSlot());
|
||||
this.sendAllDataToRemote();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendAllDataToRemote() {
|
||||
List<ItemStack> contentsCopy = new ArrayList<>();
|
||||
for (int index = 0; index < slots.size(); ++index) {
|
||||
Slot slot = slots.get(index);
|
||||
this.remoteSlots.set(index, (slot instanceof SlotPlaceholder placeholder ? placeholder.getOrDefault() : slot.getItem()).copy());
|
||||
ItemStack itemStack = slot instanceof SlotPlaceholder placeholder ? placeholder.getOrDefault() : slot.getItem();
|
||||
contentsCopy.add(itemStack);
|
||||
this.remoteSlots.get(index).force(itemStack);
|
||||
}
|
||||
|
||||
remoteCarried = getCarried().copy();
|
||||
remoteCarried.force(getCarried());
|
||||
|
||||
for (int index = 0; index < this.dataSlots.size(); ++index) {
|
||||
this.remoteDataSlots.set(index, this.dataSlots.get(index).get());
|
||||
}
|
||||
|
||||
if (this.synchronizer != null) {
|
||||
this.synchronizer.sendInitialData(this, this.remoteSlots, this.remoteCarried, this.remoteDataSlots.toIntArray());
|
||||
this.synchronizer.sendInitialData(this, contentsCopy, this.getCarried().copy(), this.remoteDataSlots.toIntArray());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void broadcastCarriedItem() {
|
||||
this.remoteCarried = this.getCarried().copy();
|
||||
ItemStack carried = this.getCarried();
|
||||
this.remoteCarried.force(carried);
|
||||
if (this.synchronizer != null) {
|
||||
this.synchronizer.sendCarriedChange(this, this.remoteCarried);
|
||||
this.synchronizer.sendCarriedChange(this, carried.copy());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeSlotListener(ContainerListener containerListener) {
|
||||
public void removeSlotListener(@NotNull ContainerListener containerListener) {
|
||||
this.containerListeners.remove(containerListener);
|
||||
}
|
||||
|
||||
@@ -428,12 +435,11 @@ public abstract class OpenChestMenu<T extends Container & ISpecialInventory & In
|
||||
|
||||
private void synchronizeSlotToRemote(int i, ItemStack itemStack, Supplier<ItemStack> supplier) {
|
||||
if (!this.suppressRemoteUpdates) {
|
||||
ItemStack itemStack1 = this.remoteSlots.get(i);
|
||||
if (!ItemStack.matches(itemStack1, itemStack)) {
|
||||
ItemStack itemstack2 = supplier.get();
|
||||
this.remoteSlots.set(i, itemstack2);
|
||||
RemoteSlot slot = this.remoteSlots.get(i);
|
||||
if (!slot.matches(itemStack)) {
|
||||
slot.force(itemStack);
|
||||
if (this.synchronizer != null) {
|
||||
this.synchronizer.sendSlotChange(this, i, itemstack2);
|
||||
this.synchronizer.sendSlotChange(this, i, supplier.get());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -452,17 +458,20 @@ public abstract class OpenChestMenu<T extends Container & ISpecialInventory & In
|
||||
}
|
||||
|
||||
private void synchronizeCarriedToRemote() {
|
||||
if (!this.suppressRemoteUpdates && !ItemStack.matches(this.getCarried(), this.remoteCarried)) {
|
||||
this.remoteCarried = this.getCarried().copy();
|
||||
if (this.synchronizer != null) {
|
||||
this.synchronizer.sendCarriedChange(this, this.remoteCarried);
|
||||
if (!this.suppressRemoteUpdates) {
|
||||
ItemStack carried = this.getCarried();
|
||||
if (!this.remoteCarried.matches(carried)) {
|
||||
this.remoteCarried.force(carried);
|
||||
if (this.synchronizer != null) {
|
||||
this.synchronizer.sendCarriedChange(this, carried.copy());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setRemoteCarried(ItemStack itemstack) {
|
||||
this.remoteCarried = itemstack.copy();
|
||||
public void setRemoteCarried(@NotNull HashedStack stack) {
|
||||
this.remoteCarried.receive(stack);
|
||||
}
|
||||
|
||||
@Override
|
||||
+3
-3
@@ -1,6 +1,6 @@
|
||||
package com.lishid.openinv.internal.v1_21_R3.container.menu;
|
||||
package com.lishid.openinv.internal.common.container.menu;
|
||||
|
||||
import com.lishid.openinv.internal.v1_21_R3.container.OpenEnderChest;
|
||||
import com.lishid.openinv.internal.common.container.OpenEnderChest;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraft.world.inventory.Slot;
|
||||
@@ -18,7 +18,7 @@ public class OpenEnderChestMenu extends OpenChestMenu<OpenEnderChest> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack quickMoveStack(Player player, int index) {
|
||||
public @NotNull ItemStack quickMoveStack(@NotNull Player player, int index) {
|
||||
if (viewOnly) {
|
||||
return ItemStack.EMPTY;
|
||||
}
|
||||
+14
-14
@@ -1,12 +1,12 @@
|
||||
package com.lishid.openinv.internal.v1_21_R3.container.menu;
|
||||
package com.lishid.openinv.internal.common.container.menu;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
import com.lishid.openinv.internal.v1_21_R3.container.OpenInventory;
|
||||
import com.lishid.openinv.internal.v1_21_R3.container.bukkit.OpenDummyPlayerInventory;
|
||||
import com.lishid.openinv.internal.v1_21_R3.container.bukkit.OpenPlayerInventorySelf;
|
||||
import com.lishid.openinv.internal.v1_21_R3.container.slot.ContentDrop;
|
||||
import com.lishid.openinv.internal.v1_21_R3.container.slot.ContentEquipment;
|
||||
import com.lishid.openinv.internal.v1_21_R3.container.slot.SlotViewOnly;
|
||||
import com.lishid.openinv.internal.common.container.OpenInventory;
|
||||
import com.lishid.openinv.internal.common.container.bukkit.OpenDummyPlayerInventory;
|
||||
import com.lishid.openinv.internal.common.container.bukkit.OpenPlayerInventorySelf;
|
||||
import com.lishid.openinv.internal.common.container.slot.ContentDrop;
|
||||
import com.lishid.openinv.internal.common.container.slot.ContentEquipment;
|
||||
import com.lishid.openinv.internal.common.container.slot.SlotViewOnly;
|
||||
import com.lishid.openinv.util.Permissions;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.world.entity.EquipmentSlot;
|
||||
@@ -15,8 +15,8 @@ import net.minecraft.world.inventory.ChestMenu;
|
||||
import net.minecraft.world.inventory.MenuType;
|
||||
import net.minecraft.world.inventory.Slot;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import org.bukkit.craftbukkit.v1_21_R3.inventory.CraftInventoryView;
|
||||
import org.bukkit.craftbukkit.v1_21_R3.inventory.CraftItemStack;
|
||||
import org.bukkit.craftbukkit.inventory.CraftInventoryView;
|
||||
import org.bukkit.craftbukkit.inventory.CraftItemStack;
|
||||
import org.bukkit.event.inventory.InventoryType;
|
||||
import org.bukkit.inventory.Inventory;
|
||||
import org.bukkit.inventory.InventoryView;
|
||||
@@ -35,7 +35,7 @@ public class OpenInventoryMenu extends OpenChestMenu<OpenInventory> {
|
||||
int size = inventory.getContainerSize();
|
||||
// Disallow duplicate access to own main inventory contents.
|
||||
if (inventory.getOwnerHandle().equals(viewer)) {
|
||||
size -= viewer.getInventory().items.size();
|
||||
size -= viewer.getInventory().getNonEquipmentItems().size();
|
||||
size = ((int) Math.ceil(size / 9.0)) * 9;
|
||||
}
|
||||
|
||||
@@ -44,7 +44,7 @@ public class OpenInventoryMenu extends OpenChestMenu<OpenInventory> {
|
||||
|
||||
@Override
|
||||
protected void preSlotSetup() {
|
||||
offset = ownContainer ? viewer.getInventory().items.size() : 0;
|
||||
offset = ownContainer ? viewer.getInventory().getNonEquipmentItems().size() : 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -195,7 +195,7 @@ public class OpenInventoryMenu extends OpenChestMenu<OpenInventory> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack quickMoveStack(Player player, int index) {
|
||||
public @NotNull ItemStack quickMoveStack(@NotNull Player player, int index) {
|
||||
if (viewOnly) {
|
||||
return ItemStack.EMPTY;
|
||||
}
|
||||
@@ -221,7 +221,7 @@ public class OpenInventoryMenu extends OpenChestMenu<OpenInventory> {
|
||||
// If this is gear, try to move it to the correct slot first.
|
||||
case OFFHAND, FEET, LEGS, CHEST, HEAD -> {
|
||||
// Locate the correct slot in the contents following the main inventory.
|
||||
for (int extra = container.getOwnerHandle().getInventory().items.size() - offset; extra < topSize; ++extra) {
|
||||
for (int extra = container.getOwnerHandle().getInventory().getNonEquipmentItems().size() - offset; extra < topSize; ++extra) {
|
||||
Slot extraSlot = getSlot(extra);
|
||||
if (extraSlot instanceof ContentEquipment.SlotEquipment equipSlot
|
||||
&& equipSlot.getEquipmentSlot() == equipmentSlot) {
|
||||
@@ -244,7 +244,7 @@ public class OpenInventoryMenu extends OpenChestMenu<OpenInventory> {
|
||||
}
|
||||
} else {
|
||||
// If we didn't move to a gear slot, try to move to a main inventory slot.
|
||||
if (!movedGear && !this.moveItemStackTo(itemStack, 0, container.getOwnerHandle().getInventory().items.size(), true)) {
|
||||
if (!movedGear && !this.moveItemStackTo(itemStack, 0, container.getOwnerHandle().getInventory().getNonEquipmentItems().size(), true)) {
|
||||
return ItemStack.EMPTY;
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
package com.lishid.openinv.internal.v1_21_R2.container.slot;
|
||||
package com.lishid.openinv.internal.common.container.slot;
|
||||
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.world.Container;
|
||||
+7
-6
@@ -1,6 +1,7 @@
|
||||
package com.lishid.openinv.internal.v1_21_R2.container.slot;
|
||||
package com.lishid.openinv.internal.common.container.slot;
|
||||
|
||||
import com.lishid.openinv.internal.v1_21_R2.container.Placeholders;
|
||||
import com.lishid.openinv.internal.common.container.slot.placeholder.Placeholders;
|
||||
import com.lishid.openinv.internal.common.player.OpenPlayer;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.world.Container;
|
||||
import net.minecraft.world.ContainerHelper;
|
||||
@@ -30,11 +31,11 @@ public class ContentCrafting implements Content {
|
||||
return isAvailable(holder);
|
||||
}
|
||||
|
||||
static boolean isAvailable(@NotNull ServerPlayer holder) {
|
||||
public static boolean isAvailable(@NotNull ServerPlayer holder) {
|
||||
// Player must be online and not in creative - since the creative client is (semi-)authoritative,
|
||||
// it ignores changes without extra help, and will delete the item as a result.
|
||||
// Spectator mode is technically possible but may cause the item to be dropped if the client opens an inventory.
|
||||
return holder.connection != null && !holder.connection.isDisconnected() && holder.gameMode.isSurvival();
|
||||
return OpenPlayer.isConnected(holder.connection) && holder.gameMode.isSurvival();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -107,12 +108,12 @@ public class ContentCrafting implements Content {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean mayPickup(Player player) {
|
||||
public boolean mayPickup(@NotNull Player player) {
|
||||
return isAvailable();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean mayPlace(ItemStack itemStack) {
|
||||
public boolean mayPlace(@NotNull ItemStack itemStack) {
|
||||
return isAvailable();
|
||||
}
|
||||
|
||||
+2
-2
@@ -1,6 +1,6 @@
|
||||
package com.lishid.openinv.internal.v1_21_R2.container.slot;
|
||||
package com.lishid.openinv.internal.common.container.slot;
|
||||
|
||||
import com.lishid.openinv.internal.v1_21_R2.container.Placeholders;
|
||||
import com.lishid.openinv.internal.common.container.slot.placeholder.Placeholders;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.world.Container;
|
||||
import net.minecraft.world.inventory.InventoryMenu;
|
||||
+6
-5
@@ -1,6 +1,7 @@
|
||||
package com.lishid.openinv.internal.v1_21_R2.container.slot;
|
||||
package com.lishid.openinv.internal.common.container.slot;
|
||||
|
||||
import com.lishid.openinv.internal.v1_21_R2.container.Placeholders;
|
||||
import com.lishid.openinv.internal.common.container.slot.placeholder.Placeholders;
|
||||
import com.lishid.openinv.internal.common.player.OpenPlayer;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.world.Container;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
@@ -63,7 +64,7 @@ public class ContentCursor implements Content {
|
||||
// Player must be online and not in creative - since the creative client is (semi-)authoritative,
|
||||
// it ignores changes without extra help, and will delete the item as a result.
|
||||
// Spectator mode is technically possible but may cause the item to be dropped if the client opens an inventory.
|
||||
return holder.connection != null && !holder.connection.isDisconnected() && holder.gameMode.isSurvival();
|
||||
return OpenPlayer.isConnected(holder.connection) && holder.gameMode.isSurvival();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -93,12 +94,12 @@ public class ContentCursor implements Content {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean mayPickup(Player player) {
|
||||
public boolean mayPickup(@NotNull Player player) {
|
||||
return isAvailable();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean mayPlace(ItemStack itemStack) {
|
||||
public boolean mayPlace(@NotNull ItemStack itemStack) {
|
||||
return isAvailable();
|
||||
}
|
||||
|
||||
+6
-5
@@ -1,6 +1,7 @@
|
||||
package com.lishid.openinv.internal.v1_21_R2.container.slot;
|
||||
package com.lishid.openinv.internal.common.container.slot;
|
||||
|
||||
import com.lishid.openinv.internal.v1_21_R2.container.Placeholders;
|
||||
import com.lishid.openinv.internal.common.container.slot.placeholder.Placeholders;
|
||||
import com.lishid.openinv.internal.common.player.OpenPlayer;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.world.Container;
|
||||
import net.minecraft.world.inventory.Slot;
|
||||
@@ -63,14 +64,14 @@ public class ContentDrop implements Content {
|
||||
|
||||
@Override
|
||||
public ItemStack getOrDefault() {
|
||||
return holder.connection != null && !holder.connection.isDisconnected()
|
||||
return OpenPlayer.isConnected(holder.connection)
|
||||
? Placeholders.drop
|
||||
: Placeholders.blockedOffline;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean mayPlace(ItemStack itemStack) {
|
||||
return holder.connection != null && !holder.connection.isDisconnected();
|
||||
public boolean mayPlace(@NotNull ItemStack itemStack) {
|
||||
return OpenPlayer.isConnected(holder.connection);
|
||||
}
|
||||
|
||||
@Override
|
||||
+40
-8
@@ -1,8 +1,10 @@
|
||||
package com.lishid.openinv.internal.v1_21_R2.container.slot;
|
||||
package com.lishid.openinv.internal.common.container.slot;
|
||||
|
||||
import com.lishid.openinv.internal.v1_21_R2.container.Placeholders;
|
||||
import com.lishid.openinv.internal.common.container.slot.placeholder.Placeholders;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.world.Container;
|
||||
import net.minecraft.world.ContainerHelper;
|
||||
import net.minecraft.world.entity.EntityEquipment;
|
||||
import net.minecraft.world.entity.EquipmentSlot;
|
||||
import net.minecraft.world.inventory.Slot;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
@@ -12,13 +14,14 @@ import org.jetbrains.annotations.NotNull;
|
||||
/**
|
||||
* A slot for equipment that displays placeholders if empty.
|
||||
*/
|
||||
public class ContentEquipment extends ContentList {
|
||||
public class ContentEquipment implements Content {
|
||||
|
||||
private EntityEquipment equipment;
|
||||
private final ItemStack placeholder;
|
||||
private final EquipmentSlot equipmentSlot;
|
||||
|
||||
public ContentEquipment(ServerPlayer holder, int index, EquipmentSlot equipmentSlot) {
|
||||
super(holder, index, InventoryType.SlotType.ARMOR);
|
||||
public ContentEquipment(ServerPlayer holder, EquipmentSlot equipmentSlot) {
|
||||
setHolder(holder);
|
||||
placeholder = switch (equipmentSlot) {
|
||||
case HEAD -> Placeholders.emptyHelmet;
|
||||
case CHEST -> Placeholders.emptyChestplate;
|
||||
@@ -31,7 +34,31 @@ public class ContentEquipment extends ContentList {
|
||||
|
||||
@Override
|
||||
public void setHolder(@NotNull ServerPlayer holder) {
|
||||
this.items = holder.getInventory().armor;
|
||||
this.equipment = holder.getInventory().equipment;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack get() {
|
||||
return equipment.get(equipmentSlot);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack remove() {
|
||||
return equipment.set(equipmentSlot, ItemStack.EMPTY);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack removePartial(int amount) {
|
||||
ItemStack current = get();
|
||||
if (!current.isEmpty() && amount > 0) {
|
||||
return current.split(amount);
|
||||
}
|
||||
return ItemStack.EMPTY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void set(ItemStack itemStack) {
|
||||
equipment.set(equipmentSlot, itemStack);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -39,6 +66,11 @@ public class ContentEquipment extends ContentList {
|
||||
return new SlotEquipment(container, slot, x, y);
|
||||
}
|
||||
|
||||
@Override
|
||||
public InventoryType.SlotType getSlotType() {
|
||||
return InventoryType.SlotType.ARMOR;
|
||||
}
|
||||
|
||||
public class SlotEquipment extends SlotPlaceholder {
|
||||
|
||||
private ServerPlayer viewer;
|
||||
@@ -65,12 +97,12 @@ public class ContentEquipment extends ContentList {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean mayPlace(ItemStack var0) {
|
||||
public boolean mayPlace(@NotNull ItemStack itemStack) {
|
||||
if (viewer == null) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return equipmentSlot == EquipmentSlot.OFFHAND || viewer.getEquipmentSlotForItem(var0) == equipmentSlot;
|
||||
return equipmentSlot == EquipmentSlot.OFFHAND || viewer.getEquipmentSlotForItem(itemStack) == equipmentSlot;
|
||||
}
|
||||
|
||||
}
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
package com.lishid.openinv.internal.v1_21_R3.container.slot;
|
||||
package com.lishid.openinv.internal.common.container.slot;
|
||||
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.world.Container;
|
||||
+14
-8
@@ -1,8 +1,11 @@
|
||||
package com.lishid.openinv.internal.v1_21_R2.container.slot;
|
||||
package com.lishid.openinv.internal.common.container.slot;
|
||||
|
||||
import com.lishid.openinv.internal.common.player.OpenPlayer;
|
||||
import net.minecraft.network.protocol.game.ClientboundContainerSetSlotPacket;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.world.Container;
|
||||
import net.minecraft.world.entity.EquipmentSlot;
|
||||
import net.minecraft.world.inventory.InventoryMenu;
|
||||
import net.minecraft.world.inventory.Slot;
|
||||
import org.bukkit.event.inventory.InventoryType;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -14,13 +17,13 @@ public class ContentOffHand extends ContentEquipment {
|
||||
|
||||
private ServerPlayer holder;
|
||||
|
||||
public ContentOffHand(ServerPlayer holder, int localIndex) {
|
||||
super(holder, localIndex, EquipmentSlot.OFFHAND);
|
||||
public ContentOffHand(ServerPlayer holder) {
|
||||
super(holder, EquipmentSlot.OFFHAND);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setHolder(@NotNull ServerPlayer holder) {
|
||||
this.items = holder.getInventory().offhand;
|
||||
super.setHolder(holder);
|
||||
this.holder = holder;
|
||||
}
|
||||
|
||||
@@ -34,10 +37,13 @@ public class ContentOffHand extends ContentEquipment {
|
||||
return new SlotEquipment(container, slot, x, y) {
|
||||
@Override
|
||||
public void setChanged() {
|
||||
if (holder.connection != null
|
||||
&& !holder.connection.isDisconnected()
|
||||
&& holder.containerMenu != holder.inventoryMenu) {
|
||||
holder.resendItemInHands();
|
||||
if (OpenPlayer.isConnected(holder.connection) && holder.containerMenu != holder.inventoryMenu) {
|
||||
holder.connection.send(
|
||||
new ClientboundContainerSetSlotPacket(
|
||||
holder.inventoryMenu.containerId,
|
||||
holder.inventoryMenu.incrementStateId(),
|
||||
InventoryMenu.SHIELD_SLOT,
|
||||
holder.getOffhandItem()));
|
||||
}
|
||||
}
|
||||
};
|
||||
+2
-2
@@ -1,4 +1,4 @@
|
||||
package com.lishid.openinv.internal.v1_21_R2.container.slot;
|
||||
package com.lishid.openinv.internal.common.container.slot;
|
||||
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.world.Container;
|
||||
@@ -12,7 +12,7 @@ import org.jetbrains.annotations.NotNull;
|
||||
*/
|
||||
public class ContentViewOnly implements Content {
|
||||
|
||||
@NotNull ServerPlayer holder;
|
||||
protected @NotNull ServerPlayer holder;
|
||||
|
||||
public ContentViewOnly(@NotNull ServerPlayer holder) {
|
||||
this.holder = holder;
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
package com.lishid.openinv.internal.v1_21_R2.container.slot;
|
||||
package com.lishid.openinv.internal.common.container.slot;
|
||||
|
||||
import net.minecraft.world.Container;
|
||||
import net.minecraft.world.inventory.Slot;
|
||||
+17
-17
@@ -1,6 +1,6 @@
|
||||
package com.lishid.openinv.internal.v1_21_R2.container.slot;
|
||||
package com.lishid.openinv.internal.common.container.slot;
|
||||
|
||||
import com.lishid.openinv.internal.v1_21_R2.container.Placeholders;
|
||||
import com.lishid.openinv.internal.common.container.slot.placeholder.Placeholders;
|
||||
import net.minecraft.world.Container;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraft.world.inventory.Slot;
|
||||
@@ -45,20 +45,20 @@ public class SlotViewOnly extends SlotPlaceholder {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onQuickCraft(ItemStack var0, ItemStack var1) {
|
||||
public void onQuickCraft(@NotNull ItemStack itemStack1, @NotNull ItemStack itemStack2) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTake(Player var0, ItemStack var1) {
|
||||
public void onTake(@NotNull Player player, @NotNull ItemStack itemStack) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean mayPlace(ItemStack var0) {
|
||||
public boolean mayPlace(@NotNull ItemStack itemStack) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack getItem() {
|
||||
public @NotNull ItemStack getItem() {
|
||||
return ItemStack.EMPTY;
|
||||
}
|
||||
|
||||
@@ -68,15 +68,15 @@ public class SlotViewOnly extends SlotPlaceholder {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setByPlayer(ItemStack newStack) {
|
||||
public void setByPlayer(@NotNull ItemStack newStack) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setByPlayer(ItemStack newStack, ItemStack oldStack) {
|
||||
public void setByPlayer(@NotNull ItemStack newStack, @NotNull ItemStack oldStack) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void set(ItemStack var0) {
|
||||
public void set(@NotNull ItemStack itemStack) {
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -89,17 +89,17 @@ public class SlotViewOnly extends SlotPlaceholder {
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMaxStackSize(ItemStack itemStack) {
|
||||
public int getMaxStackSize(@NotNull ItemStack itemStack) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack remove(int amount) {
|
||||
public @NotNull ItemStack remove(int amount) {
|
||||
return ItemStack.EMPTY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean mayPickup(Player var0) {
|
||||
public boolean mayPickup(@NotNull Player player) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -109,27 +109,27 @@ public class SlotViewOnly extends SlotPlaceholder {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<ItemStack> tryRemove(int var0, int var1, Player var2) {
|
||||
public @NotNull Optional<ItemStack> tryRemove(int var0, int var1, @NotNull Player player) {
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack safeTake(int var0, int var1, Player var2) {
|
||||
public @NotNull ItemStack safeTake(int var0, int var1, @NotNull Player player) {
|
||||
return ItemStack.EMPTY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack safeInsert(ItemStack itemStack) {
|
||||
public @NotNull ItemStack safeInsert(@NotNull ItemStack itemStack) {
|
||||
return itemStack;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack safeInsert(ItemStack itemStack, int amount) {
|
||||
public @NotNull ItemStack safeInsert(@NotNull ItemStack itemStack, int amount) {
|
||||
return itemStack;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean allowModification(Player var0) {
|
||||
public boolean allowModification(@NotNull Player player) {
|
||||
return false;
|
||||
}
|
||||
|
||||
+40
@@ -0,0 +1,40 @@
|
||||
package com.lishid.openinv.internal.common.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);
|
||||
}
|
||||
|
||||
}
|
||||
+61
-67
@@ -1,18 +1,14 @@
|
||||
package com.lishid.openinv.internal.v1_21_R2.container;
|
||||
package com.lishid.openinv.internal.common.container.slot.placeholder;
|
||||
|
||||
import net.minecraft.core.Registry;
|
||||
import net.minecraft.core.RegistryAccess;
|
||||
import net.minecraft.core.component.DataComponents;
|
||||
import net.minecraft.core.registries.Registries;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.nbt.TagParser;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.util.Unit;
|
||||
import net.minecraft.world.item.DyeColor;
|
||||
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.level.GameType;
|
||||
import net.minecraft.world.level.ItemLike;
|
||||
@@ -20,86 +16,87 @@ import net.minecraft.world.level.block.entity.BannerPattern;
|
||||
import net.minecraft.world.level.block.entity.BannerPatternLayers;
|
||||
import net.minecraft.world.level.block.entity.BannerPatterns;
|
||||
import org.bukkit.configuration.ConfigurationSection;
|
||||
import org.bukkit.craftbukkit.v1_21_R2.CraftRegistry;
|
||||
import org.bukkit.craftbukkit.CraftRegistry;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.EnumMap;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
public final class Placeholders {
|
||||
public abstract class PlaceholderLoaderBase {
|
||||
|
||||
private static final CustomModelData DEFAULT_CUSTOM_MODEL_DATA = new CustomModelData(9999);
|
||||
public static final @NotNull EnumMap<GameType, ItemStack> BLOCKED_GAME_TYPE = new EnumMap<>(GameType.class);
|
||||
public static @NotNull ItemStack craftingOutput = defaultCraftingOutput();
|
||||
public static @NotNull ItemStack cursor = defaultCursor();
|
||||
public static @NotNull ItemStack drop = defaultDrop();
|
||||
public static @NotNull ItemStack emptyHelmet = getEmptyArmor(Items.LEATHER_HELMET);
|
||||
public static @NotNull ItemStack emptyChestplate = getEmptyArmor(Items.LEATHER_CHESTPLATE);
|
||||
public static @NotNull ItemStack emptyLeggings = getEmptyArmor(Items.LEATHER_LEGGINGS);
|
||||
public static @NotNull ItemStack emptyBoots = getEmptyArmor(Items.LEATHER_BOOTS);
|
||||
public static @NotNull ItemStack emptyOffHand = getEmptyShield();
|
||||
public static @NotNull ItemStack notSlot = defaultNotSlot();
|
||||
public static @NotNull ItemStack blockedOffline = defaultBlockedOffline();
|
||||
|
||||
static {
|
||||
protected PlaceholderLoaderBase() {
|
||||
for (GameType type : GameType.values()) {
|
||||
// Barrier: "Not available - Creative" etc.
|
||||
ItemStack typeItem = new ItemStack(Items.BARRIER);
|
||||
typeItem.set(
|
||||
DataComponents.ITEM_NAME,
|
||||
Component.translatable("options.narrator.notavailable").append(" - ").append(type.getShortDisplayName()));
|
||||
BLOCKED_GAME_TYPE.put(type, typeItem);
|
||||
Placeholders.BLOCKED_GAME_TYPE.put(type, typeItem);
|
||||
}
|
||||
Placeholders.craftingOutput = defaultCraftingOutput();
|
||||
Placeholders.cursor = defaultCursor();
|
||||
Placeholders.drop = defaultDrop();
|
||||
Placeholders.emptyHelmet = getEmptyArmor(Items.LEATHER_HELMET);
|
||||
Placeholders.emptyChestplate = getEmptyArmor(Items.LEATHER_CHESTPLATE);
|
||||
Placeholders.emptyLeggings = getEmptyArmor(Items.LEATHER_LEGGINGS);
|
||||
Placeholders.emptyBoots = getEmptyArmor(Items.LEATHER_BOOTS);
|
||||
Placeholders.emptyOffHand = defaultShield();
|
||||
Placeholders.notSlot = defaultNotSlot();
|
||||
Placeholders.blockedOffline = defaultBlockedOffline();
|
||||
}
|
||||
|
||||
public static void load(@NotNull ConfigurationSection section) throws Exception {
|
||||
craftingOutput = parse(section, "crafting-output", craftingOutput);
|
||||
cursor = parse(section, "cursor", cursor);
|
||||
drop = parse(section, "drop", drop);
|
||||
emptyHelmet = parse(section, "empty-helmet", emptyHelmet);
|
||||
emptyChestplate = parse(section, "empty-chestplate", emptyChestplate);
|
||||
emptyLeggings = parse(section, "empty-leggings", emptyLeggings);
|
||||
emptyBoots = parse(section, "empty-boots", emptyBoots);
|
||||
emptyOffHand = parse(section, "empty-off-hand", emptyOffHand);
|
||||
notSlot = parse(section, "not-a-slot", notSlot);
|
||||
blockedOffline = parse(section, "blocked.offline", blockedOffline);
|
||||
BLOCKED_GAME_TYPE.put(GameType.CREATIVE, parse(section, "blocked.creative", BLOCKED_GAME_TYPE.get(GameType.CREATIVE)));
|
||||
BLOCKED_GAME_TYPE.put(GameType.SPECTATOR, parse(section, "blocked.spectator", BLOCKED_GAME_TYPE.get(GameType.SPECTATOR)));
|
||||
public void load(@Nullable ConfigurationSection section) throws Exception {
|
||||
Placeholders.craftingOutput = parse(section, "crafting-output", Placeholders.craftingOutput);
|
||||
Placeholders.cursor = parse(section, "cursor", Placeholders.cursor);
|
||||
Placeholders.drop = parse(section, "drop", Placeholders.drop);
|
||||
Placeholders.emptyHelmet = parse(section, "empty-helmet", Placeholders.emptyHelmet);
|
||||
Placeholders.emptyChestplate = parse(section, "empty-chestplate", Placeholders.emptyChestplate);
|
||||
Placeholders.emptyLeggings = parse(section, "empty-leggings", Placeholders.emptyLeggings);
|
||||
Placeholders.emptyBoots = parse(section, "empty-boots", Placeholders.emptyBoots);
|
||||
Placeholders.emptyOffHand = parse(section, "empty-off-hand", Placeholders.emptyOffHand);
|
||||
Placeholders.notSlot = parse(section, "not-a-slot", Placeholders.notSlot);
|
||||
Placeholders.blockedOffline = parse(section, "blocked.offline", Placeholders.blockedOffline);
|
||||
Placeholders.BLOCKED_GAME_TYPE.put(GameType.CREATIVE, parse(section, "blocked.creative", Placeholders.BLOCKED_GAME_TYPE.get(GameType.CREATIVE)));
|
||||
Placeholders.BLOCKED_GAME_TYPE.put(GameType.SPECTATOR, parse(section, "blocked.spectator", Placeholders.BLOCKED_GAME_TYPE.get(GameType.SPECTATOR)));
|
||||
}
|
||||
|
||||
private static @NotNull ItemStack parse(
|
||||
@NotNull ConfigurationSection section,
|
||||
private @NotNull ItemStack parse(
|
||||
@Nullable ConfigurationSection section,
|
||||
@NotNull String path,
|
||||
@NotNull ItemStack defaultStack) throws Exception {
|
||||
if (section == null) {
|
||||
return defaultStack;
|
||||
}
|
||||
|
||||
String itemText = section.getString(path);
|
||||
|
||||
if (itemText == null) {
|
||||
return defaultStack;
|
||||
}
|
||||
|
||||
CompoundTag compoundTag = TagParser.parseTag(itemText);
|
||||
CompoundTag compoundTag = parseTag(itemText);
|
||||
Optional<ItemStack> parsed = ItemStack.parse(CraftRegistry.getMinecraftRegistry(), compoundTag);
|
||||
return parsed.filter(itemStack -> !itemStack.isEmpty()).orElse(defaultStack);
|
||||
}
|
||||
|
||||
public static ItemStack survivalOnly(@NotNull ServerPlayer serverPlayer) {
|
||||
if (serverPlayer.connection == null || serverPlayer.connection.isDisconnected()) {
|
||||
return blockedOffline;
|
||||
}
|
||||
protected abstract @NotNull CompoundTag parseTag(@NotNull String itemText) throws Exception;
|
||||
|
||||
return BLOCKED_GAME_TYPE.getOrDefault(serverPlayer.gameMode.getGameModeForPlayer(), ItemStack.EMPTY);
|
||||
}
|
||||
protected abstract void addModelData(@NotNull ItemStack itemStack);
|
||||
|
||||
private static ItemStack defaultCraftingOutput() {
|
||||
protected abstract void hideTooltip(@NotNull ItemStack itemStack);
|
||||
|
||||
protected abstract DyedItemColor getDye(int rgb);
|
||||
|
||||
protected @NotNull ItemStack defaultCraftingOutput() {
|
||||
// Crafting table: "Crafting"
|
||||
ItemStack itemStack = new ItemStack(Items.CRAFTING_TABLE);
|
||||
itemStack.set(DataComponents.ITEM_NAME, Component.translatable("container.crafting"));
|
||||
itemStack.set(DataComponents.CUSTOM_MODEL_DATA, DEFAULT_CUSTOM_MODEL_DATA);
|
||||
addModelData(itemStack);
|
||||
return itemStack;
|
||||
}
|
||||
|
||||
private static ItemStack defaultCursor() {
|
||||
protected @NotNull ItemStack defaultCursor() {
|
||||
// Cursor-like banner with no tooltip
|
||||
ItemStack itemStack = new ItemStack(Items.WHITE_BANNER);
|
||||
RegistryAccess minecraftRegistry = CraftRegistry.getMinecraftRegistry();
|
||||
@@ -112,31 +109,32 @@ public final class Placeholders {
|
||||
new BannerPatternLayers.Layer(bannerPatterns.wrapAsHolder(halfDiagBottomRight), DyeColor.GRAY),
|
||||
new BannerPatternLayers.Layer(bannerPatterns.wrapAsHolder(downRight), DyeColor.WHITE),
|
||||
new BannerPatternLayers.Layer(bannerPatterns.wrapAsHolder(border), DyeColor.GRAY))));
|
||||
itemStack.set(DataComponents.CUSTOM_MODEL_DATA, DEFAULT_CUSTOM_MODEL_DATA);
|
||||
itemStack.set(DataComponents.HIDE_TOOLTIP, Unit.INSTANCE);
|
||||
addModelData(itemStack);
|
||||
hideTooltip(itemStack);
|
||||
return itemStack;
|
||||
}
|
||||
|
||||
private static ItemStack defaultDrop() {
|
||||
protected @NotNull ItemStack defaultDrop() {
|
||||
// Dropper: "Drop Selected Item"
|
||||
ItemStack itemStack = new ItemStack(Items.DROPPER);
|
||||
// Note: translatable component, not keybind component! We want the text identifying the keybind, not the key.
|
||||
itemStack.set(DataComponents.ITEM_NAME, Component.translatable("key.drop"));
|
||||
itemStack.set(DataComponents.CUSTOM_MODEL_DATA, DEFAULT_CUSTOM_MODEL_DATA);
|
||||
addModelData(itemStack);
|
||||
return itemStack;
|
||||
}
|
||||
|
||||
private static ItemStack getEmptyArmor(ItemLike item) {
|
||||
protected @NotNull ItemStack getEmptyArmor(@NotNull ItemLike item) {
|
||||
// Inventory-background-grey-ish leather armor with no tooltip
|
||||
ItemStack itemStack = new ItemStack(item);
|
||||
DyedItemColor color = new DyedItemColor(0xC8C8C8, false);
|
||||
DyedItemColor color = getDye(0xC8C8C8);
|
||||
itemStack.set(DataComponents.DYED_COLOR, color);
|
||||
itemStack.set(DataComponents.HIDE_TOOLTIP, Unit.INSTANCE);
|
||||
itemStack.set(DataComponents.CUSTOM_MODEL_DATA, DEFAULT_CUSTOM_MODEL_DATA);
|
||||
hideTooltip(itemStack);
|
||||
addModelData(itemStack);
|
||||
return itemStack;
|
||||
}
|
||||
|
||||
private static ItemStack getEmptyShield() {
|
||||
protected @NotNull ItemStack defaultShield() {
|
||||
// Shield with "missing texture" pattern, magenta and black squares.
|
||||
ItemStack itemStack = new ItemStack(Items.SHIELD);
|
||||
itemStack.set(DataComponents.BASE_COLOR, DyeColor.MAGENTA);
|
||||
RegistryAccess minecraftRegistry = CraftRegistry.getMinecraftRegistry();
|
||||
@@ -153,20 +151,20 @@ public final class Placeholders {
|
||||
new BannerPatternLayers.Layer(bannerPatterns.wrapAsHolder(bottomLeft), DyeColor.MAGENTA),
|
||||
new BannerPatternLayers.Layer(bannerPatterns.wrapAsHolder(topRight), DyeColor.BLACK),
|
||||
new BannerPatternLayers.Layer(bannerPatterns.wrapAsHolder(bottomRight), DyeColor.BLACK))));
|
||||
itemStack.set(DataComponents.HIDE_TOOLTIP, Unit.INSTANCE);
|
||||
itemStack.set(DataComponents.CUSTOM_MODEL_DATA, DEFAULT_CUSTOM_MODEL_DATA);
|
||||
hideTooltip(itemStack);
|
||||
addModelData(itemStack);
|
||||
return itemStack;
|
||||
}
|
||||
|
||||
private static ItemStack defaultNotSlot() {
|
||||
protected @NotNull ItemStack defaultNotSlot() {
|
||||
// White pane with no tooltip
|
||||
ItemStack itemStack = new ItemStack(Items.WHITE_STAINED_GLASS_PANE);
|
||||
itemStack.set(DataComponents.HIDE_TOOLTIP, Unit.INSTANCE);
|
||||
itemStack.set(DataComponents.CUSTOM_MODEL_DATA, DEFAULT_CUSTOM_MODEL_DATA);
|
||||
hideTooltip(itemStack);
|
||||
addModelData(itemStack);
|
||||
return itemStack;
|
||||
}
|
||||
|
||||
private static ItemStack defaultBlockedOffline() {
|
||||
protected @NotNull ItemStack defaultBlockedOffline() {
|
||||
// Barrier: "Not available - Offline"
|
||||
ItemStack itemStack = new ItemStack(Items.BARRIER);
|
||||
itemStack.set(DataComponents.ITEM_NAME,
|
||||
@@ -176,8 +174,4 @@ public final class Placeholders {
|
||||
return itemStack;
|
||||
}
|
||||
|
||||
private Placeholders() {
|
||||
throw new IllegalStateException("Cannot create instance of utility class.");
|
||||
}
|
||||
|
||||
}
|
||||
+37
@@ -0,0 +1,37 @@
|
||||
package com.lishid.openinv.internal.common.container.slot.placeholder;
|
||||
|
||||
import com.lishid.openinv.internal.common.player.OpenPlayer;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.level.GameType;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.EnumMap;
|
||||
|
||||
public final class 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;
|
||||
public static @NotNull ItemStack drop = ItemStack.EMPTY;
|
||||
public static @NotNull ItemStack emptyHelmet = ItemStack.EMPTY;
|
||||
public static @NotNull ItemStack emptyChestplate = ItemStack.EMPTY;
|
||||
public static @NotNull ItemStack emptyLeggings = ItemStack.EMPTY;
|
||||
public static @NotNull ItemStack emptyBoots = ItemStack.EMPTY;
|
||||
public static @NotNull ItemStack emptyOffHand = ItemStack.EMPTY;
|
||||
public static @NotNull ItemStack notSlot = ItemStack.EMPTY;
|
||||
public static @NotNull ItemStack blockedOffline = ItemStack.EMPTY;
|
||||
|
||||
public static ItemStack survivalOnly(@NotNull ServerPlayer serverPlayer) {
|
||||
if (!OpenPlayer.isConnected(serverPlayer.connection)) {
|
||||
return blockedOffline;
|
||||
}
|
||||
|
||||
return BLOCKED_GAME_TYPE.getOrDefault(serverPlayer.gameMode.getGameModeForPlayer(), ItemStack.EMPTY);
|
||||
}
|
||||
|
||||
private Placeholders() {
|
||||
throw new IllegalStateException("Cannot create instance of utility class.");
|
||||
}
|
||||
|
||||
}
|
||||
+22
-10
@@ -1,4 +1,4 @@
|
||||
package com.lishid.openinv.internal.v1_21_R3.player;
|
||||
package com.lishid.openinv.internal.common.player;
|
||||
|
||||
import com.lishid.openinv.event.OpenEvents;
|
||||
import com.mojang.logging.LogUtils;
|
||||
@@ -8,12 +8,14 @@ import net.minecraft.nbt.NbtIo;
|
||||
import net.minecraft.nbt.NumericTag;
|
||||
import net.minecraft.nbt.Tag;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.server.network.ServerGamePacketListenerImpl;
|
||||
import net.minecraft.world.level.storage.PlayerDataStorage;
|
||||
import org.bukkit.craftbukkit.v1_21_R3.CraftServer;
|
||||
import org.bukkit.craftbukkit.v1_21_R3.entity.CraftPlayer;
|
||||
import org.bukkit.craftbukkit.CraftServer;
|
||||
import org.bukkit.craftbukkit.entity.CraftPlayer;
|
||||
import org.jetbrains.annotations.Contract;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.annotations.Unmodifiable;
|
||||
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
@@ -29,7 +31,8 @@ public class OpenPlayer extends CraftPlayer {
|
||||
* @see net.minecraft.world.entity.player.Player#addAdditionalSaveData(CompoundTag)
|
||||
* @see net.minecraft.world.entity.LivingEntity#addAdditionalSaveData(CompoundTag)
|
||||
*/
|
||||
private static final Set<String> RESET_TAGS = Set.of(
|
||||
@Unmodifiable
|
||||
protected static final Set<String> RESET_TAGS = Set.of(
|
||||
// Entity#saveWithoutId(CompoundTag)
|
||||
"CustomName",
|
||||
"CustomNameVisible",
|
||||
@@ -42,6 +45,7 @@ public class OpenPlayer extends CraftPlayer {
|
||||
"Passengers",
|
||||
// ServerPlayer#addAdditionalSaveData(CompoundTag)
|
||||
// Intentional omissions to prevent mount loss: Attach, Entity, and RootVehicle
|
||||
// As of 1.21.5 only ender_pearls tag still needs to be reset. Rest are for backwards compatibility.
|
||||
"warden_spawn_tracker",
|
||||
"enteredNetherPosition",
|
||||
"SpawnX",
|
||||
@@ -56,18 +60,23 @@ public class OpenPlayer extends CraftPlayer {
|
||||
"ShoulderEntityLeft",
|
||||
"ShoulderEntityRight",
|
||||
"LastDeathLocation",
|
||||
"current_explosion_impact_pos",
|
||||
"current_explosion_impact_pos", // Unnecessary in 1.21.5
|
||||
// LivingEntity#addAdditionalSaveData(CompoundTag)
|
||||
"active_effects",
|
||||
"SleepingX",
|
||||
"SleepingY",
|
||||
"SleepingZ",
|
||||
"Brain"
|
||||
"Brain",
|
||||
"last_hurt_by_player",
|
||||
"last_hurt_by_player_memory_time",
|
||||
"last_hurt_by_mob",
|
||||
"ticks_since_last_hurt_by_mob",
|
||||
"equipment"
|
||||
);
|
||||
|
||||
private final PlayerManager manager;
|
||||
|
||||
OpenPlayer(CraftServer server, ServerPlayer entity, PlayerManager manager) {
|
||||
protected OpenPlayer(CraftServer server, ServerPlayer entity, PlayerManager manager) {
|
||||
super(server, entity);
|
||||
this.manager = manager;
|
||||
}
|
||||
@@ -110,7 +119,7 @@ public class OpenPlayer extends CraftPlayer {
|
||||
}
|
||||
|
||||
@Contract("null -> new")
|
||||
private @NotNull CompoundTag getWritableTag(@Nullable CompoundTag oldData) {
|
||||
protected @NotNull CompoundTag getWritableTag(@Nullable CompoundTag oldData) {
|
||||
if (oldData == null) {
|
||||
return new CompoundTag();
|
||||
}
|
||||
@@ -119,8 +128,7 @@ public class OpenPlayer extends CraftPlayer {
|
||||
oldData = oldData.copy();
|
||||
|
||||
// Remove vanilla/server data that is not written every time.
|
||||
oldData.getAllKeys()
|
||||
.removeIf(key -> RESET_TAGS.contains(key) || key.startsWith("Bukkit"));
|
||||
oldData.keySet().removeIf(key -> RESET_TAGS.contains(key) || key.startsWith("Bukkit") || key.startsWith("Paper") && key.length() > 5);
|
||||
|
||||
return oldData;
|
||||
}
|
||||
@@ -175,4 +183,8 @@ public class OpenPlayer extends CraftPlayer {
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean isConnected(@Nullable ServerGamePacketListenerImpl connection) {
|
||||
return connection != null && !connection.isDisconnected();
|
||||
}
|
||||
|
||||
}
|
||||
+54
-43
@@ -1,10 +1,11 @@
|
||||
package com.lishid.openinv.internal.v1_21_R2.player;
|
||||
package com.lishid.openinv.internal.common.player;
|
||||
|
||||
import com.lishid.openinv.internal.ISpecialInventory;
|
||||
import com.lishid.openinv.internal.v1_21_R2.container.OpenEnderChest;
|
||||
import com.lishid.openinv.internal.v1_21_R2.container.OpenInventory;
|
||||
import com.lishid.openinv.internal.common.container.OpenEnderChest;
|
||||
import com.lishid.openinv.internal.common.container.OpenInventory;
|
||||
import com.mojang.authlib.GameProfile;
|
||||
import com.mojang.serialization.Dynamic;
|
||||
import io.papermc.paper.adventure.PaperAdventure;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.nbt.NbtOps;
|
||||
import net.minecraft.network.chat.Component;
|
||||
@@ -23,34 +24,24 @@ import org.bukkit.Bukkit;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
import org.bukkit.Server;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.craftbukkit.v1_21_R2.CraftServer;
|
||||
import org.bukkit.craftbukkit.v1_21_R2.CraftWorld;
|
||||
import org.bukkit.craftbukkit.v1_21_R2.entity.CraftPlayer;
|
||||
import org.bukkit.craftbukkit.v1_21_R2.event.CraftEventFactory;
|
||||
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.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
public class PlayerManager implements com.lishid.openinv.internal.PlayerManager {
|
||||
|
||||
private static boolean paper;
|
||||
|
||||
static {
|
||||
try {
|
||||
Class.forName("io.papermc.paper.configuration.Configuration");
|
||||
paper = true;
|
||||
} catch (ClassNotFoundException ignored) {
|
||||
paper = false;
|
||||
}
|
||||
}
|
||||
|
||||
private final @NotNull Logger logger;
|
||||
private @Nullable Field bukkitEntity;
|
||||
protected final @NotNull Logger logger;
|
||||
protected @Nullable Field bukkitEntity;
|
||||
|
||||
public PlayerManager(@NotNull Logger logger) {
|
||||
this.logger = logger;
|
||||
@@ -107,7 +98,7 @@ public class PlayerManager implements com.lishid.openinv.internal.PlayerManager
|
||||
return null;
|
||||
}
|
||||
|
||||
private @NotNull ServerPlayer createNewPlayer(
|
||||
protected @NotNull ServerPlayer createNewPlayer(
|
||||
@NotNull MinecraftServer server,
|
||||
@NotNull ServerLevel worldServer,
|
||||
@NotNull final OfflinePlayer offline) {
|
||||
@@ -158,40 +149,54 @@ public class PlayerManager implements com.lishid.openinv.internal.PlayerManager
|
||||
// Game type settings are also loaded separately.
|
||||
player.loadGameTypes(loadedData);
|
||||
|
||||
if (paper) {
|
||||
// Paper: world is not loaded by ServerPlayer#load(CompoundTag).
|
||||
parseWorld(player, loadedData);
|
||||
}
|
||||
// World is not loaded by ServerPlayer#load(CompoundTag) on Paper.
|
||||
parseWorld(player, loadedData);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private void parseWorld(@NotNull ServerPlayer player, @NotNull CompoundTag loadedData) {
|
||||
protected void parseWorld(@NotNull ServerPlayer player, @NotNull CompoundTag loadedData) {
|
||||
// See PlayerList#placeNewPlayer
|
||||
World bukkitWorld;
|
||||
if (loadedData.contains("WorldUUIDMost") && loadedData.contains("WorldUUIDLeast")) {
|
||||
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(loadedData.getLong("WorldUUIDMost"), loadedData.getLong("WorldUUIDLeast")));
|
||||
} else if (loadedData.contains("world", net.minecraft.nbt.Tag.TAG_STRING)) {
|
||||
// Legacy Bukkit world.
|
||||
bukkitWorld = Bukkit.getServer().getWorld(loadedData.getString("world"));
|
||||
bukkitWorld = Bukkit.getServer().getWorld(new UUID(msbs.get(), lsbs.get()));
|
||||
} else {
|
||||
// Vanilla player data.
|
||||
DimensionType.parseLegacy(new Dynamic<>(NbtOps.INSTANCE, loadedData.get("Dimension")))
|
||||
.resultOrPartial(logger::warning)
|
||||
.map(player.server::getLevel)
|
||||
// If ServerLevel exists, set, otherwise move to spawn.
|
||||
.ifPresentOrElse(player::setServerLevel, () -> player.spawnIn(null));
|
||||
return;
|
||||
Optional<String> worldName = loadedData.getString("world");
|
||||
if (worldName.isPresent()) {
|
||||
// Legacy Bukkit world.
|
||||
bukkitWorld = Bukkit.getServer().getWorld(worldName.get());
|
||||
} else {
|
||||
// Vanilla player data.
|
||||
DimensionType.parseLegacy(new Dynamic<>(NbtOps.INSTANCE, loadedData.get("Dimension")))
|
||||
.resultOrPartial(logger::warning)
|
||||
.map(player.server::getLevel)
|
||||
// If ServerLevel exists, set, otherwise move to spawn.
|
||||
.ifPresentOrElse(player::setServerLevel, () -> spawnInDefaultWorld(player));
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (bukkitWorld == null) {
|
||||
player.spawnIn(null);
|
||||
spawnInDefaultWorld(player);
|
||||
return;
|
||||
}
|
||||
player.setServerLevel(((CraftWorld) bukkitWorld).getHandle());
|
||||
}
|
||||
|
||||
private void injectPlayer(ServerPlayer player) throws IllegalAccessException {
|
||||
protected void spawnInDefaultWorld(ServerPlayer player) {
|
||||
ServerLevel level = player.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!");
|
||||
}
|
||||
}
|
||||
|
||||
protected void injectPlayer(ServerPlayer player) throws IllegalAccessException {
|
||||
if (bukkitEntity == null) {
|
||||
return;
|
||||
}
|
||||
@@ -223,7 +228,7 @@ public class PlayerManager implements com.lishid.openinv.internal.PlayerManager
|
||||
public @Nullable InventoryView openInventory(@NotNull Player bukkitPlayer, @NotNull ISpecialInventory inventory, boolean viewOnly) {
|
||||
ServerPlayer player = getHandle(bukkitPlayer);
|
||||
|
||||
if (player.connection == null) {
|
||||
if (!OpenPlayer.isConnected(player.connection)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -250,15 +255,21 @@ public class PlayerManager implements com.lishid.openinv.internal.PlayerManager
|
||||
// resulting in a title change but no other state modifications (like cursor position).
|
||||
menu.setTitle(title);
|
||||
|
||||
menu = CraftEventFactory.callInventoryOpenEvent(player, menu, false);
|
||||
var pair = CraftEventFactory.callInventoryOpenEventWithTitle(player, menu);
|
||||
menu = pair.getSecond();
|
||||
|
||||
// Menu is null if event is cancelled.
|
||||
if (menu == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
var newTitle = pair.getFirst();
|
||||
if (newTitle != null) {
|
||||
title = PaperAdventure.asVanilla(newTitle);
|
||||
}
|
||||
|
||||
player.containerMenu = menu;
|
||||
player.connection.send(new ClientboundOpenScreenPacket(menu.containerId, menu.getType(), menu.getTitle()));
|
||||
player.connection.send(new ClientboundOpenScreenPacket(menu.containerId, menu.getType(), title));
|
||||
player.initMenu(menu);
|
||||
|
||||
return menu.getBukkitView();
|
||||
@@ -0,0 +1,28 @@
|
||||
plugins {
|
||||
`openinv-base`
|
||||
alias(libs.plugins.paperweight)
|
||||
}
|
||||
|
||||
configurations.all {
|
||||
resolutionStrategy.capabilitiesResolution.withCapability("org.spigotmc:spigot-api") {
|
||||
val paper = candidates.firstOrNull {
|
||||
it.id.let {
|
||||
id -> id is ModuleComponentIdentifier && id.module == "paper-api"
|
||||
}
|
||||
}
|
||||
if (paper != null) {
|
||||
select(paper)
|
||||
}
|
||||
because("module is written for Paper servers")
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation(project(":openinvapi"))
|
||||
implementation(project(":openinvcommon"))
|
||||
implementation(project(":openinvadaptercommon"))
|
||||
implementation(project(":openinvadapterpaper1_21_4"))
|
||||
implementation(project(":openinvadapterpaper1_21_3"))
|
||||
|
||||
paperweight.paperDevBundle("1.21.1-R0.1-SNAPSHOT")
|
||||
}
|
||||
+80
@@ -0,0 +1,80 @@
|
||||
package com.lishid.openinv.internal.paper1_21_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.common.container.AnySilentContainer;
|
||||
import com.lishid.openinv.internal.paper1_21_1.container.OpenInventory;
|
||||
import com.lishid.openinv.internal.paper1_21_1.container.slot.placeholder.PlaceholderLoader;
|
||||
import com.lishid.openinv.internal.paper1_21_1.player.PlayerManager;
|
||||
import com.lishid.openinv.internal.paper1_21_4.container.OpenEnderChest;
|
||||
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 {
|
||||
|
||||
private 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;
|
||||
this.manager = new PlayerManager(logger);
|
||||
this.anySilentContainer = new AnySilentContainer(logger, lang);
|
||||
}
|
||||
|
||||
@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.
|
||||
new PlaceholderLoader().load(placeholders);
|
||||
} catch (Exception e) {
|
||||
logger.log(Level.WARNING, "Caught exception loading placeholder overrides!", e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
package com.lishid.openinv.internal.paper1_21_1.container;
|
||||
|
||||
import com.lishid.openinv.internal.common.container.slot.Content;
|
||||
import com.lishid.openinv.internal.paper1_21_1.container.slot.ContentCraftingResult;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class OpenInventory extends com.lishid.openinv.internal.paper1_21_4.container.OpenInventory {
|
||||
|
||||
public OpenInventory(@NotNull Player bukkitPlayer) {
|
||||
super(bukkitPlayer);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Content getCraftingResult(@NotNull ServerPlayer serverPlayer) {
|
||||
return new ContentCraftingResult(serverPlayer);
|
||||
}
|
||||
|
||||
}
|
||||
+7
-9
@@ -1,6 +1,9 @@
|
||||
package com.lishid.openinv.internal.v1_21_R3.container.slot;
|
||||
package com.lishid.openinv.internal.paper1_21_1.container.slot;
|
||||
|
||||
import com.lishid.openinv.internal.v1_21_R3.container.Placeholders;
|
||||
import com.lishid.openinv.internal.common.container.slot.ContentCrafting;
|
||||
import com.lishid.openinv.internal.common.container.slot.ContentViewOnly;
|
||||
import com.lishid.openinv.internal.common.container.slot.SlotViewOnly;
|
||||
import com.lishid.openinv.internal.common.container.slot.placeholder.Placeholders;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.world.Container;
|
||||
import net.minecraft.world.inventory.InventoryMenu;
|
||||
@@ -9,11 +12,6 @@ import net.minecraft.world.item.ItemStack;
|
||||
import org.bukkit.event.inventory.InventoryType;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* A slot allowing viewing of the crafting result.
|
||||
*
|
||||
* <p>Unmodifiable because I said so. Use your own crafting grid.</p>
|
||||
*/
|
||||
public class ContentCraftingResult extends ContentViewOnly {
|
||||
|
||||
public ContentCraftingResult(@NotNull ServerPlayer holder) {
|
||||
@@ -23,7 +21,7 @@ public class ContentCraftingResult extends ContentViewOnly {
|
||||
@Override
|
||||
public ItemStack get() {
|
||||
InventoryMenu inventoryMenu = holder.inventoryMenu;
|
||||
return inventoryMenu.getResultSlot().getItem();
|
||||
return inventoryMenu.getSlot(inventoryMenu.getResultSlotIndex()).getItem();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -35,7 +33,7 @@ public class ContentCraftingResult extends ContentViewOnly {
|
||||
return Placeholders.survivalOnly(holder);
|
||||
}
|
||||
InventoryMenu inventoryMenu = holder.inventoryMenu;
|
||||
return inventoryMenu.getResultSlot().getItem();
|
||||
return inventoryMenu.getSlot(inventoryMenu.getResultSlotIndex()).getItem();
|
||||
}
|
||||
};
|
||||
}
|
||||
+65
@@ -0,0 +1,65 @@
|
||||
package com.lishid.openinv.internal.paper1_21_1.container.slot.placeholder;
|
||||
|
||||
import com.lishid.openinv.internal.paper1_21_3.container.slot.placeholder.NumericDataPlaceholderLoader;
|
||||
import net.minecraft.core.Registry;
|
||||
import net.minecraft.core.RegistryAccess;
|
||||
import net.minecraft.core.component.DataComponents;
|
||||
import net.minecraft.core.registries.Registries;
|
||||
import net.minecraft.util.Unit;
|
||||
import net.minecraft.world.item.DyeColor;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.item.Items;
|
||||
import net.minecraft.world.level.block.entity.BannerPattern;
|
||||
import net.minecraft.world.level.block.entity.BannerPatternLayers;
|
||||
import net.minecraft.world.level.block.entity.BannerPatterns;
|
||||
import org.bukkit.craftbukkit.CraftRegistry;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class PlaceholderLoader extends NumericDataPlaceholderLoader {
|
||||
|
||||
@Override
|
||||
protected @NotNull ItemStack defaultCursor() {
|
||||
// Cursor-like banner with no tooltip
|
||||
ItemStack itemStack = new ItemStack(Items.WHITE_BANNER);
|
||||
RegistryAccess minecraftRegistry = CraftRegistry.getMinecraftRegistry();
|
||||
Registry<BannerPattern> bannerPatterns = minecraftRegistry.registryOrThrow(Registries.BANNER_PATTERN);
|
||||
BannerPattern halfDiagBottomRight = bannerPatterns.getOrThrow(BannerPatterns.DIAGONAL_RIGHT);
|
||||
BannerPattern downRight = bannerPatterns.getOrThrow(BannerPatterns.STRIPE_DOWNRIGHT);
|
||||
BannerPattern border = bannerPatterns.getOrThrow(BannerPatterns.BORDER);
|
||||
itemStack.set(DataComponents.BANNER_PATTERNS,
|
||||
new BannerPatternLayers(List.of(
|
||||
new BannerPatternLayers.Layer(bannerPatterns.wrapAsHolder(halfDiagBottomRight), DyeColor.GRAY),
|
||||
new BannerPatternLayers.Layer(bannerPatterns.wrapAsHolder(downRight), DyeColor.WHITE),
|
||||
new BannerPatternLayers.Layer(bannerPatterns.wrapAsHolder(border), DyeColor.GRAY))));
|
||||
addModelData(itemStack);
|
||||
itemStack.set(DataComponents.HIDE_TOOLTIP, Unit.INSTANCE);
|
||||
return itemStack;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected @NotNull ItemStack defaultShield() {
|
||||
// Shield with "missing texture" pattern, magenta and black squares.
|
||||
ItemStack itemStack = new ItemStack(Items.SHIELD);
|
||||
itemStack.set(DataComponents.BASE_COLOR, DyeColor.MAGENTA);
|
||||
RegistryAccess minecraftRegistry = CraftRegistry.getMinecraftRegistry();
|
||||
Registry<BannerPattern> bannerPatterns = minecraftRegistry.registryOrThrow(Registries.BANNER_PATTERN);
|
||||
BannerPattern halfLeft = bannerPatterns.getOrThrow(BannerPatterns.HALF_VERTICAL);
|
||||
BannerPattern topLeft = bannerPatterns.getOrThrow(BannerPatterns.SQUARE_TOP_LEFT);
|
||||
BannerPattern topRight = bannerPatterns.getOrThrow(BannerPatterns.SQUARE_TOP_RIGHT);
|
||||
BannerPattern bottomLeft = bannerPatterns.getOrThrow(BannerPatterns.SQUARE_BOTTOM_LEFT);
|
||||
BannerPattern bottomRight = bannerPatterns.getOrThrow(BannerPatterns.SQUARE_BOTTOM_RIGHT);
|
||||
itemStack.set(DataComponents.BANNER_PATTERNS,
|
||||
new BannerPatternLayers(List.of(
|
||||
new BannerPatternLayers.Layer(bannerPatterns.wrapAsHolder(halfLeft), DyeColor.BLACK),
|
||||
new BannerPatternLayers.Layer(bannerPatterns.wrapAsHolder(topLeft), DyeColor.MAGENTA),
|
||||
new BannerPatternLayers.Layer(bannerPatterns.wrapAsHolder(bottomLeft), DyeColor.MAGENTA),
|
||||
new BannerPatternLayers.Layer(bannerPatterns.wrapAsHolder(topRight), DyeColor.BLACK),
|
||||
new BannerPatternLayers.Layer(bannerPatterns.wrapAsHolder(bottomRight), DyeColor.BLACK))));
|
||||
itemStack.set(DataComponents.HIDE_TOOLTIP, Unit.INSTANCE);
|
||||
addModelData(itemStack);
|
||||
return itemStack;
|
||||
}
|
||||
|
||||
}
|
||||
+55
@@ -0,0 +1,55 @@
|
||||
package com.lishid.openinv.internal.paper1_21_1.player;
|
||||
|
||||
import com.mojang.authlib.GameProfile;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.server.level.ClientInformation;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.world.entity.player.ChatVisiblity;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.logging.Logger;
|
||||
|
||||
public class PlayerManager extends com.lishid.openinv.internal.paper1_21_4.player.PlayerManager {
|
||||
|
||||
public PlayerManager(@NotNull Logger logger) {
|
||||
super(logger);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected @NotNull ServerPlayer createNewPlayer(
|
||||
@NotNull MinecraftServer server,
|
||||
@NotNull ServerLevel worldServer,
|
||||
@NotNull 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).
|
||||
);
|
||||
|
||||
ServerPlayer entity = new ServerPlayer(server, worldServer, profile, dummyInfo);
|
||||
|
||||
try {
|
||||
injectPlayer(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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
plugins {
|
||||
`openinv-base`
|
||||
alias(libs.plugins.paperweight)
|
||||
}
|
||||
|
||||
configurations.all {
|
||||
resolutionStrategy.capabilitiesResolution.withCapability("org.spigotmc:spigot-api") {
|
||||
val paper = candidates.firstOrNull {
|
||||
it.id.let {
|
||||
id -> id is ModuleComponentIdentifier && id.module == "paper-api"
|
||||
}
|
||||
}
|
||||
if (paper != null) {
|
||||
select(paper)
|
||||
}
|
||||
because("module is written for Paper servers")
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation(project(":openinvapi"))
|
||||
implementation(project(":openinvcommon"))
|
||||
implementation(project(":openinvadaptercommon"))
|
||||
implementation(project(":openinvadapterpaper1_21_4"))
|
||||
|
||||
paperweight.paperDevBundle("1.21.3-R0.1-SNAPSHOT")
|
||||
}
|
||||
+28
@@ -0,0 +1,28 @@
|
||||
package com.lishid.openinv.internal.paper1_21_3;
|
||||
|
||||
import com.lishid.openinv.internal.paper1_21_3.container.slot.placeholder.NumericDataPlaceholderLoader;
|
||||
import com.lishid.openinv.util.lang.LanguageManager;
|
||||
import org.bukkit.configuration.ConfigurationSection;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
public class InternalAccessor extends com.lishid.openinv.internal.paper1_21_4.InternalAccessor {
|
||||
|
||||
public InternalAccessor(@NotNull Logger logger, @NotNull LanguageManager lang) {
|
||||
super(logger, lang);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reload(@NotNull ConfigurationSection config) {
|
||||
ConfigurationSection placeholders = config.getConfigurationSection("placeholders");
|
||||
try {
|
||||
// Reset placeholders to defaults and try to load configuration.
|
||||
new NumericDataPlaceholderLoader().load(placeholders);
|
||||
} catch (Exception e) {
|
||||
logger.log(Level.WARNING, "Caught exception loading placeholder overrides!", e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
package com.lishid.openinv.internal.paper1_21_3.container.slot.placeholder;
|
||||
|
||||
import com.lishid.openinv.internal.paper1_21_4.container.slot.placeholder.CustomModelBase;
|
||||
import net.minecraft.world.item.component.CustomModelData;
|
||||
|
||||
public class NumericDataPlaceholderLoader extends CustomModelBase {
|
||||
|
||||
public NumericDataPlaceholderLoader() {
|
||||
super(new CustomModelData(9999));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
plugins {
|
||||
`openinv-base`
|
||||
alias(libs.plugins.paperweight)
|
||||
}
|
||||
|
||||
configurations.all {
|
||||
resolutionStrategy.capabilitiesResolution.withCapability("org.spigotmc:spigot-api") {
|
||||
val paper = candidates.firstOrNull {
|
||||
it.id.let {
|
||||
id -> id is ModuleComponentIdentifier && id.module == "paper-api"
|
||||
}
|
||||
}
|
||||
if (paper != null) {
|
||||
select(paper)
|
||||
}
|
||||
because("module is written for Paper servers")
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation(project(":openinvapi"))
|
||||
implementation(project(":openinvcommon"))
|
||||
implementation(project(":openinvadaptercommon"))
|
||||
|
||||
paperweight.paperDevBundle("1.21.4-R0.1-SNAPSHOT")
|
||||
}
|
||||
+13
-14
@@ -1,19 +1,19 @@
|
||||
package com.lishid.openinv.internal.v1_21_R2;
|
||||
package com.lishid.openinv.internal.paper1_21_4;
|
||||
|
||||
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.v1_21_R2.container.AnySilentContainer;
|
||||
import com.lishid.openinv.internal.v1_21_R2.container.OpenEnderChest;
|
||||
import com.lishid.openinv.internal.v1_21_R2.container.OpenInventory;
|
||||
import com.lishid.openinv.internal.v1_21_R2.container.Placeholders;
|
||||
import com.lishid.openinv.internal.v1_21_R2.player.PlayerManager;
|
||||
import com.lishid.openinv.internal.common.container.AnySilentContainer;
|
||||
import com.lishid.openinv.internal.paper1_21_4.container.OpenEnderChest;
|
||||
import com.lishid.openinv.internal.paper1_21_4.container.OpenInventory;
|
||||
import com.lishid.openinv.internal.paper1_21_4.container.slot.placeholder.CustomModelPlaceholderLoader;
|
||||
import com.lishid.openinv.internal.paper1_21_4.player.PlayerManager;
|
||||
import com.lishid.openinv.util.lang.LanguageManager;
|
||||
import net.minecraft.world.Container;
|
||||
import org.bukkit.configuration.ConfigurationSection;
|
||||
import org.bukkit.craftbukkit.v1_21_R2.inventory.CraftInventory;
|
||||
import org.bukkit.craftbukkit.inventory.CraftInventory;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.Inventory;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -24,7 +24,7 @@ import java.util.logging.Logger;
|
||||
|
||||
public class InternalAccessor implements Accessor {
|
||||
|
||||
private final @NotNull Logger logger;
|
||||
protected final @NotNull Logger logger;
|
||||
private final @NotNull PlayerManager manager;
|
||||
private final @NotNull AnySilentContainer anySilentContainer;
|
||||
|
||||
@@ -69,12 +69,11 @@ public class InternalAccessor implements Accessor {
|
||||
@Override
|
||||
public void reload(@NotNull ConfigurationSection config) {
|
||||
ConfigurationSection placeholders = config.getConfigurationSection("placeholders");
|
||||
if (placeholders != null) {
|
||||
try {
|
||||
Placeholders.load(placeholders);
|
||||
} catch (Exception e) {
|
||||
logger.log(Level.WARNING, "Caught exception loading placeholder overrides!", e);
|
||||
}
|
||||
try {
|
||||
// Reset placeholders to defaults and try to load configuration.
|
||||
new CustomModelPlaceholderLoader().load(placeholders);
|
||||
} catch (Exception e) {
|
||||
logger.log(Level.WARNING, "Caught exception loading placeholder overrides!", e);
|
||||
}
|
||||
}
|
||||
|
||||
+23
@@ -0,0 +1,23 @@
|
||||
package com.lishid.openinv.internal.paper1_21_4.container;
|
||||
|
||||
import com.lishid.openinv.internal.paper1_21_4.container.menu.OpenEnderChestMenu;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.world.inventory.AbstractContainerMenu;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public class OpenEnderChest extends com.lishid.openinv.internal.common.container.OpenEnderChest{
|
||||
|
||||
public OpenEnderChest(@NotNull Player player) {
|
||||
super(player);
|
||||
}
|
||||
|
||||
public @Nullable AbstractContainerMenu createMenu(net.minecraft.world.entity.player.Player player, int i, boolean viewOnly) {
|
||||
if (player instanceof ServerPlayer serverPlayer) {
|
||||
return new OpenEnderChestMenu(this, serverPlayer, i, viewOnly);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
+177
@@ -0,0 +1,177 @@
|
||||
package com.lishid.openinv.internal.paper1_21_4.container;
|
||||
|
||||
import com.lishid.openinv.internal.common.container.slot.ContentCrafting;
|
||||
import com.lishid.openinv.internal.common.container.slot.ContentCursor;
|
||||
import com.lishid.openinv.internal.common.container.slot.ContentDrop;
|
||||
import com.lishid.openinv.internal.common.container.slot.ContentList;
|
||||
import com.lishid.openinv.internal.common.container.slot.ContentViewOnly;
|
||||
import com.lishid.openinv.internal.common.container.slot.SlotViewOnly;
|
||||
import com.lishid.openinv.internal.common.container.slot.placeholder.Placeholders;
|
||||
import com.lishid.openinv.internal.paper1_21_4.container.menu.OpenInventoryMenu;
|
||||
import com.lishid.openinv.internal.paper1_21_4.container.slot.ContentEquipment;
|
||||
import com.lishid.openinv.internal.paper1_21_4.container.slot.ContentOffHand;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.world.Container;
|
||||
import net.minecraft.world.entity.EquipmentSlot;
|
||||
import net.minecraft.world.entity.player.Inventory;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraft.world.inventory.AbstractContainerMenu;
|
||||
import net.minecraft.world.inventory.Slot;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import org.bukkit.event.inventory.InventoryType;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public class OpenInventory extends com.lishid.openinv.internal.common.container.OpenInventory {
|
||||
|
||||
public OpenInventory(@NotNull org.bukkit.entity.Player bukkitPlayer) {
|
||||
super(bukkitPlayer);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setupSlots() {
|
||||
// Top of inventory: Regular contents.
|
||||
int nextIndex = addMainInventory();
|
||||
|
||||
// If inventory is expected size, we can arrange slots to be pretty.
|
||||
Inventory ownerInv = owner.getInventory();
|
||||
if (ownerInv.items.size() == 36
|
||||
&& ownerInv.armor.size() == 4
|
||||
&& ownerInv.offhand.size() == 1
|
||||
&& owner.inventoryMenu.getCraftSlots().getContainerSize() == 4) {
|
||||
// Armor slots: Bottom left.
|
||||
addArmor(36);
|
||||
// Off-hand: Below chestplate.
|
||||
addOffHand(46);
|
||||
// Drop slot: Bottom right.
|
||||
slots.set(53, new ContentDrop(owner));
|
||||
// Cursor slot: Above drop.
|
||||
slots.set(44, new ContentCursor(owner));
|
||||
|
||||
// Crafting is displayed in the bottom right corner.
|
||||
// As we're using the pretty view, this is a 3x2.
|
||||
addCrafting(41, true);
|
||||
return;
|
||||
}
|
||||
|
||||
// Otherwise we'll just add elements linearly.
|
||||
nextIndex = addArmor(nextIndex);
|
||||
nextIndex = addOffHand(nextIndex);
|
||||
nextIndex = addCrafting(nextIndex, false);
|
||||
slots.set(nextIndex, new ContentCursor(owner));
|
||||
// Drop slot last.
|
||||
slots.set(slots.size() - 1, new ContentDrop(owner));
|
||||
}
|
||||
|
||||
private int addMainInventory() {
|
||||
int listSize = owner.getInventory().items.size();
|
||||
// Hotbar slots are 0-8. We want those to appear on the bottom of the inventory like a normal player inventory,
|
||||
// so everything else needs to move up a row.
|
||||
int hotbarDiff = listSize - 9;
|
||||
for (int localIndex = 0; localIndex < listSize; ++localIndex) {
|
||||
InventoryType.SlotType type;
|
||||
int invIndex;
|
||||
if (localIndex < hotbarDiff) {
|
||||
invIndex = localIndex + 9;
|
||||
type = InventoryType.SlotType.CONTAINER;
|
||||
} else {
|
||||
type = InventoryType.SlotType.QUICKBAR;
|
||||
invIndex = localIndex - hotbarDiff;
|
||||
}
|
||||
|
||||
slots.set(localIndex, new ContentList(owner, invIndex, type) {
|
||||
@Override
|
||||
public void setHolder(@NotNull ServerPlayer holder) {
|
||||
items = holder.getInventory().items;
|
||||
}
|
||||
});
|
||||
}
|
||||
return listSize;
|
||||
}
|
||||
|
||||
private int addArmor(int startIndex) {
|
||||
int listSize = owner.getInventory().armor.size();
|
||||
|
||||
for (int i = 0; i < listSize; ++i) {
|
||||
// Armor slots go bottom to top; boots are slot 0, helmet is slot 3.
|
||||
// Since we have to display horizontally due to space restrictions,
|
||||
// making the left side the "top" is more user-friendly.
|
||||
int armorIndex;
|
||||
EquipmentSlot slot;
|
||||
switch (i) {
|
||||
case 3 -> {
|
||||
armorIndex = 0;
|
||||
slot = EquipmentSlot.FEET;
|
||||
}
|
||||
case 2 -> {
|
||||
armorIndex = 1;
|
||||
slot = EquipmentSlot.LEGS;
|
||||
}
|
||||
case 1 -> {
|
||||
armorIndex = 2;
|
||||
slot = EquipmentSlot.CHEST;
|
||||
}
|
||||
case 0 -> {
|
||||
armorIndex = 3;
|
||||
slot = EquipmentSlot.HEAD;
|
||||
}
|
||||
default -> {
|
||||
// In the event that new armor slots are added, they can be placed at the end.
|
||||
armorIndex = i;
|
||||
slot = EquipmentSlot.MAINHAND;
|
||||
}
|
||||
}
|
||||
|
||||
slots.set(startIndex + i, new ContentEquipment(owner, armorIndex, slot));
|
||||
}
|
||||
|
||||
return startIndex + listSize;
|
||||
}
|
||||
|
||||
private int addOffHand(int startIndex) {
|
||||
int listSize = owner.getInventory().offhand.size();
|
||||
for (int localIndex = 0; localIndex < listSize; ++localIndex) {
|
||||
slots.set(startIndex + localIndex, new ContentOffHand(owner, localIndex));
|
||||
}
|
||||
return startIndex + listSize;
|
||||
}
|
||||
|
||||
private int addCrafting(int startIndex, boolean pretty) {
|
||||
int listSize = owner.inventoryMenu.getCraftSlots().getContents().size();
|
||||
pretty &= listSize == 4;
|
||||
|
||||
for (int localIndex = 0; localIndex < listSize; ++localIndex) {
|
||||
// Pretty display is a 2x2 rather than linear.
|
||||
// If index is in top row, grid is not 2x2, or pretty is disabled, just use current index.
|
||||
// Otherwise, subtract 2 and add 9 to start in the same position on the next row.
|
||||
int modIndex = startIndex + (localIndex < 2 || !pretty ? localIndex : localIndex + 7);
|
||||
|
||||
slots.set(modIndex, new ContentCrafting(owner, localIndex));
|
||||
}
|
||||
|
||||
if (pretty) {
|
||||
slots.set(startIndex + 2, new ContentViewOnly(owner) {
|
||||
@Override
|
||||
public Slot asSlot(Container container, int slot, int x, int y) {
|
||||
return new SlotViewOnly(container, slot, x, y) {
|
||||
@Override
|
||||
public ItemStack getOrDefault() {
|
||||
return Placeholders.craftingOutput;
|
||||
}
|
||||
};
|
||||
}
|
||||
});
|
||||
slots.set(startIndex + 11, getCraftingResult(owner));
|
||||
}
|
||||
|
||||
return startIndex + listSize;
|
||||
}
|
||||
|
||||
public @Nullable AbstractContainerMenu createMenu(Player player, int i, boolean viewOnly) {
|
||||
if (player instanceof ServerPlayer serverPlayer) {
|
||||
return new OpenInventoryMenu(this, serverPlayer, i, viewOnly);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
+18
-16
@@ -1,12 +1,12 @@
|
||||
package com.lishid.openinv.internal.v1_21_R2.container.bukkit;
|
||||
package com.lishid.openinv.internal.paper1_21_4.container.bukkit;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
import com.lishid.openinv.internal.v1_21_R2.container.OpenInventory;
|
||||
import com.lishid.openinv.internal.paper1_21_4.container.OpenInventory;
|
||||
import net.minecraft.core.NonNullList;
|
||||
import net.minecraft.world.entity.EquipmentSlot;
|
||||
import net.minecraft.world.entity.player.Inventory;
|
||||
import org.bukkit.craftbukkit.v1_21_R2.inventory.CraftInventory;
|
||||
import org.bukkit.craftbukkit.v1_21_R2.inventory.CraftItemStack;
|
||||
import org.bukkit.craftbukkit.inventory.CraftInventory;
|
||||
import org.bukkit.craftbukkit.inventory.CraftItemStack;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.inventory.InventoryType;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
@@ -26,7 +26,7 @@ public class OpenPlayerInventory extends CraftInventory implements PlayerInvento
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack[] getContents() {
|
||||
public ItemStack @NotNull [] getContents() {
|
||||
return asCraftMirror(getInventory().getOwnerHandle().getInventory().getContents());
|
||||
}
|
||||
|
||||
@@ -46,7 +46,7 @@ public class OpenPlayerInventory extends CraftInventory implements PlayerInvento
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack[] getStorageContents() {
|
||||
public ItemStack @NotNull [] getStorageContents() {
|
||||
return asCraftMirror(getInventory().getOwnerHandle().getInventory().items);
|
||||
}
|
||||
|
||||
@@ -71,12 +71,12 @@ public class OpenPlayerInventory extends CraftInventory implements PlayerInvento
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull ItemStack[] getArmorContents() {
|
||||
public @NotNull ItemStack @NotNull [] getArmorContents() {
|
||||
return asCraftMirror(getInventory().getOwnerHandle().getInventory().armor);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setArmorContents(@Nullable ItemStack[] items) {
|
||||
public void setArmorContents(ItemStack @NotNull [] items) {
|
||||
NonNullList<net.minecraft.world.item.ItemStack> list = getInventory().getOwnerHandle().getInventory().armor;
|
||||
int size = list.size();
|
||||
Preconditions.checkArgument(items.length <= size, "items.length must be <= %s", size);
|
||||
@@ -86,12 +86,12 @@ public class OpenPlayerInventory extends CraftInventory implements PlayerInvento
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull ItemStack[] getExtraContents() {
|
||||
public @NotNull ItemStack @NotNull [] getExtraContents() {
|
||||
return asCraftMirror(getInventory().getOwnerHandle().getInventory().offhand);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setExtraContents(@Nullable ItemStack[] items) {
|
||||
public void setExtraContents(ItemStack @NotNull [] items) {
|
||||
NonNullList<net.minecraft.world.item.ItemStack> list = getInventory().getOwnerHandle().getInventory().offhand;
|
||||
int size = list.size();
|
||||
Preconditions.checkArgument(items.length <= size, "items.length must be <= %s", size);
|
||||
@@ -101,7 +101,7 @@ public class OpenPlayerInventory extends CraftInventory implements PlayerInvento
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable ItemStack getHelmet() {
|
||||
public @NotNull ItemStack getHelmet() {
|
||||
return CraftItemStack.asCraftMirror(getInventory().getOwnerHandle().getInventory()
|
||||
.getArmor(EquipmentSlot.HEAD.getIndex()));
|
||||
}
|
||||
@@ -113,9 +113,9 @@ public class OpenPlayerInventory extends CraftInventory implements PlayerInvento
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable ItemStack getChestplate() {
|
||||
public @NotNull ItemStack getChestplate() {
|
||||
return CraftItemStack.asCraftMirror(getInventory().getOwnerHandle().getInventory()
|
||||
.getArmor(EquipmentSlot.HEAD.getIndex()));
|
||||
.getArmor(EquipmentSlot.CHEST.getIndex()));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -125,7 +125,7 @@ public class OpenPlayerInventory extends CraftInventory implements PlayerInvento
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable ItemStack getLeggings() {
|
||||
public @NotNull ItemStack getLeggings() {
|
||||
return CraftItemStack.asCraftMirror(getInventory().getOwnerHandle().getInventory()
|
||||
.getArmor(EquipmentSlot.LEGS.getIndex()));
|
||||
}
|
||||
@@ -137,7 +137,7 @@ public class OpenPlayerInventory extends CraftInventory implements PlayerInvento
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable ItemStack getBoots() {
|
||||
public @NotNull ItemStack getBoots() {
|
||||
return CraftItemStack.asCraftMirror(getInventory().getOwnerHandle().getInventory()
|
||||
.getArmor(EquipmentSlot.FEET.getIndex()));
|
||||
}
|
||||
@@ -170,11 +170,13 @@ public class OpenPlayerInventory extends CraftInventory implements PlayerInvento
|
||||
getInventory().getOwnerHandle().getInventory().offhand.set(0, CraftItemStack.asNMSCopy(item));
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
@Override
|
||||
public @NotNull ItemStack getItemInHand() {
|
||||
return getItemInMainHand();
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
@Override
|
||||
public void setItemInHand(@Nullable ItemStack stack) {
|
||||
setItemInMainHand(stack);
|
||||
@@ -193,7 +195,7 @@ public class OpenPlayerInventory extends CraftInventory implements PlayerInvento
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable ItemStack getItem(@NotNull org.bukkit.inventory.EquipmentSlot slot) {
|
||||
public @NotNull ItemStack getItem(@NotNull org.bukkit.inventory.EquipmentSlot slot) {
|
||||
return switch (slot) {
|
||||
case HAND -> getItemInMainHand();
|
||||
case OFF_HAND -> getItemInOffHand();
|
||||
+2
-2
@@ -1,6 +1,6 @@
|
||||
package com.lishid.openinv.internal.v1_21_R3.container.bukkit;
|
||||
package com.lishid.openinv.internal.paper1_21_4.container.bukkit;
|
||||
|
||||
import com.lishid.openinv.internal.v1_21_R3.container.OpenInventory;
|
||||
import com.lishid.openinv.internal.paper1_21_4.container.OpenInventory;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
+16
-30
@@ -1,11 +1,11 @@
|
||||
package com.lishid.openinv.internal.v1_21_R3.container.menu;
|
||||
package com.lishid.openinv.internal.paper1_21_4.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.v1_21_R3.container.bukkit.OpenDummyInventory;
|
||||
import com.lishid.openinv.internal.v1_21_R3.container.slot.SlotPlaceholder;
|
||||
import com.lishid.openinv.internal.v1_21_R3.container.slot.SlotViewOnly;
|
||||
import com.lishid.openinv.internal.common.container.bukkit.OpenDummyInventory;
|
||||
import com.lishid.openinv.internal.common.container.slot.SlotPlaceholder;
|
||||
import com.lishid.openinv.internal.common.container.slot.SlotViewOnly;
|
||||
import it.unimi.dsi.fastutil.ints.IntArrayList;
|
||||
import it.unimi.dsi.fastutil.ints.IntList;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
@@ -21,7 +21,7 @@ import net.minecraft.world.inventory.DataSlot;
|
||||
import net.minecraft.world.inventory.MenuType;
|
||||
import net.minecraft.world.inventory.Slot;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import org.bukkit.craftbukkit.v1_21_R3.inventory.CraftInventoryView;
|
||||
import org.bukkit.craftbukkit.inventory.CraftInventoryView;
|
||||
import org.bukkit.event.inventory.InventoryType;
|
||||
import org.bukkit.inventory.Inventory;
|
||||
import org.bukkit.inventory.InventoryView;
|
||||
@@ -108,26 +108,14 @@ public abstract class OpenChestMenu<T extends Container & ISpecialInventory & In
|
||||
}
|
||||
}
|
||||
|
||||
public static @NotNull MenuType<ChestMenu> getChestMenuType(int inventorySize) {
|
||||
inventorySize = ((int) Math.ceil(inventorySize / 9.0)) * 9;
|
||||
return switch (inventorySize) {
|
||||
case 9 -> MenuType.GENERIC_9x1;
|
||||
case 18 -> MenuType.GENERIC_9x2;
|
||||
case 27 -> MenuType.GENERIC_9x3;
|
||||
case 36 -> MenuType.GENERIC_9x4;
|
||||
case 45 -> MenuType.GENERIC_9x5;
|
||||
case 54 -> MenuType.GENERIC_9x6;
|
||||
default -> throw new IllegalArgumentException("Inventory size unsupported: " + inventorySize);
|
||||
};
|
||||
}
|
||||
|
||||
protected void preSlotSetup() {}
|
||||
|
||||
protected @NotNull Slot getUpperSlot(int index, int x, int y) {
|
||||
Slot slot = new Slot(container, index, x, y);
|
||||
if (viewOnly) {
|
||||
return new SlotViewOnly(container, index, x, y);
|
||||
return SlotViewOnly.wrap(slot);
|
||||
}
|
||||
return new Slot(container, index, x, y);
|
||||
return slot;
|
||||
}
|
||||
|
||||
|
||||
@@ -176,9 +164,7 @@ public abstract class OpenChestMenu<T extends Container & ISpecialInventory & In
|
||||
|
||||
private int getTopSize(ServerPlayer viewer) {
|
||||
MenuType<?> menuType = getType();
|
||||
if (menuType == null) {
|
||||
throw new IllegalStateException("MenuType cannot be null!");
|
||||
} else if (menuType == MenuType.GENERIC_9x1) {
|
||||
if (menuType == MenuType.GENERIC_9x1) {
|
||||
return 9;
|
||||
} else if (menuType == MenuType.GENERIC_9x2) {
|
||||
return 18;
|
||||
@@ -284,7 +270,7 @@ public abstract class OpenChestMenu<T extends Container & ISpecialInventory & In
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clicked(int i, int j, ClickType clickType, Player player) {
|
||||
public void clicked(int i, int j, @NotNull ClickType clickType, @NotNull Player player) {
|
||||
if (viewOnly) {
|
||||
if (clickType == ClickType.QUICK_CRAFT) {
|
||||
sendAllDataToRemote();
|
||||
@@ -295,13 +281,13 @@ public abstract class OpenChestMenu<T extends Container & ISpecialInventory & In
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean stillValid(Player player) {
|
||||
public boolean stillValid(@NotNull Player player) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Overrides from here on are purely to modify the sync process to send placeholder items.
|
||||
@Override
|
||||
protected Slot addSlot(Slot slot) {
|
||||
protected @NotNull Slot addSlot(@NotNull Slot slot) {
|
||||
slot.index = this.slots.size();
|
||||
this.slots.add(slot);
|
||||
this.lastSlots.add(ItemStack.EMPTY);
|
||||
@@ -310,7 +296,7 @@ public abstract class OpenChestMenu<T extends Container & ISpecialInventory & In
|
||||
}
|
||||
|
||||
@Override
|
||||
protected DataSlot addDataSlot(DataSlot dataSlot) {
|
||||
protected @NotNull DataSlot addDataSlot(@NotNull DataSlot dataSlot) {
|
||||
this.dataSlots.add(dataSlot);
|
||||
this.remoteDataSlots.add(0);
|
||||
return dataSlot;
|
||||
@@ -324,7 +310,7 @@ public abstract class OpenChestMenu<T extends Container & ISpecialInventory & In
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addSlotListener(ContainerListener containerListener) {
|
||||
public void addSlotListener(@NotNull ContainerListener containerListener) {
|
||||
if (!this.containerListeners.contains(containerListener)) {
|
||||
this.containerListeners.add(containerListener);
|
||||
this.broadcastChanges();
|
||||
@@ -332,7 +318,7 @@ public abstract class OpenChestMenu<T extends Container & ISpecialInventory & In
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSynchronizer(ContainerSynchronizer containerSynchronizer) {
|
||||
public void setSynchronizer(@NotNull ContainerSynchronizer containerSynchronizer) {
|
||||
this.synchronizer = containerSynchronizer;
|
||||
this.sendAllDataToRemote();
|
||||
}
|
||||
@@ -364,7 +350,7 @@ public abstract class OpenChestMenu<T extends Container & ISpecialInventory & In
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeSlotListener(ContainerListener containerListener) {
|
||||
public void removeSlotListener(@NotNull ContainerListener containerListener) {
|
||||
this.containerListeners.remove(containerListener);
|
||||
}
|
||||
|
||||
+10
-4
@@ -1,6 +1,6 @@
|
||||
package com.lishid.openinv.internal.v1_21_R2.container.menu;
|
||||
package com.lishid.openinv.internal.paper1_21_4.container.menu;
|
||||
|
||||
import com.lishid.openinv.internal.v1_21_R2.container.OpenEnderChest;
|
||||
import com.lishid.openinv.internal.common.container.OpenEnderChest;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraft.world.inventory.Slot;
|
||||
@@ -14,11 +14,17 @@ public class OpenEnderChestMenu extends OpenChestMenu<OpenEnderChest> {
|
||||
@NotNull ServerPlayer viewer,
|
||||
int containerId,
|
||||
boolean viewOnly) {
|
||||
super(getChestMenuType(enderChest.getContainerSize()), containerId, enderChest, viewer, viewOnly);
|
||||
super(
|
||||
com.lishid.openinv.internal.common.container.menu.OpenChestMenu.getChestMenuType(enderChest.getContainerSize()),
|
||||
containerId,
|
||||
enderChest,
|
||||
viewer,
|
||||
viewOnly
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack quickMoveStack(Player player, int index) {
|
||||
public @NotNull ItemStack quickMoveStack(@NotNull Player player, int index) {
|
||||
if (viewOnly) {
|
||||
return ItemStack.EMPTY;
|
||||
}
|
||||
+11
-11
@@ -1,12 +1,12 @@
|
||||
package com.lishid.openinv.internal.v1_21_R2.container.menu;
|
||||
package com.lishid.openinv.internal.paper1_21_4.container.menu;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
import com.lishid.openinv.internal.v1_21_R2.container.OpenInventory;
|
||||
import com.lishid.openinv.internal.v1_21_R2.container.bukkit.OpenDummyPlayerInventory;
|
||||
import com.lishid.openinv.internal.v1_21_R2.container.bukkit.OpenPlayerInventorySelf;
|
||||
import com.lishid.openinv.internal.v1_21_R2.container.slot.ContentDrop;
|
||||
import com.lishid.openinv.internal.v1_21_R2.container.slot.ContentEquipment;
|
||||
import com.lishid.openinv.internal.v1_21_R2.container.slot.SlotViewOnly;
|
||||
import com.lishid.openinv.internal.common.container.bukkit.OpenDummyPlayerInventory;
|
||||
import com.lishid.openinv.internal.common.container.slot.ContentDrop;
|
||||
import com.lishid.openinv.internal.common.container.slot.SlotViewOnly;
|
||||
import com.lishid.openinv.internal.paper1_21_4.container.OpenInventory;
|
||||
import com.lishid.openinv.internal.paper1_21_4.container.bukkit.OpenPlayerInventorySelf;
|
||||
import com.lishid.openinv.internal.paper1_21_4.container.slot.ContentEquipment;
|
||||
import com.lishid.openinv.util.Permissions;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.world.entity.EquipmentSlot;
|
||||
@@ -15,8 +15,8 @@ import net.minecraft.world.inventory.ChestMenu;
|
||||
import net.minecraft.world.inventory.MenuType;
|
||||
import net.minecraft.world.inventory.Slot;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import org.bukkit.craftbukkit.v1_21_R2.inventory.CraftInventoryView;
|
||||
import org.bukkit.craftbukkit.v1_21_R2.inventory.CraftItemStack;
|
||||
import org.bukkit.craftbukkit.inventory.CraftInventoryView;
|
||||
import org.bukkit.craftbukkit.inventory.CraftItemStack;
|
||||
import org.bukkit.event.inventory.InventoryType;
|
||||
import org.bukkit.inventory.Inventory;
|
||||
import org.bukkit.inventory.InventoryView;
|
||||
@@ -39,7 +39,7 @@ public class OpenInventoryMenu extends OpenChestMenu<OpenInventory> {
|
||||
size = ((int) Math.ceil(size / 9.0)) * 9;
|
||||
}
|
||||
|
||||
return getChestMenuType(size);
|
||||
return com.lishid.openinv.internal.common.container.menu.OpenChestMenu.getChestMenuType(size);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -195,7 +195,7 @@ public class OpenInventoryMenu extends OpenChestMenu<OpenInventory> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack quickMoveStack(Player player, int index) {
|
||||
public @NotNull ItemStack quickMoveStack(@NotNull Player player, int index) {
|
||||
if (viewOnly) {
|
||||
return ItemStack.EMPTY;
|
||||
}
|
||||
+6
-4
@@ -1,6 +1,8 @@
|
||||
package com.lishid.openinv.internal.v1_21_R3.container.slot;
|
||||
package com.lishid.openinv.internal.paper1_21_4.container.slot;
|
||||
|
||||
import com.lishid.openinv.internal.v1_21_R3.container.Placeholders;
|
||||
import com.lishid.openinv.internal.common.container.slot.ContentList;
|
||||
import com.lishid.openinv.internal.common.container.slot.SlotPlaceholder;
|
||||
import com.lishid.openinv.internal.common.container.slot.placeholder.Placeholders;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.world.Container;
|
||||
import net.minecraft.world.entity.EquipmentSlot;
|
||||
@@ -65,12 +67,12 @@ public class ContentEquipment extends ContentList {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean mayPlace(ItemStack var0) {
|
||||
public boolean mayPlace(@NotNull ItemStack itemStack) {
|
||||
if (viewer == null) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return equipmentSlot == EquipmentSlot.OFFHAND || viewer.getEquipmentSlotForItem(var0) == equipmentSlot;
|
||||
return equipmentSlot == EquipmentSlot.OFFHAND || viewer.getEquipmentSlotForItem(itemStack) == equipmentSlot;
|
||||
}
|
||||
|
||||
}
|
||||
+11
-5
@@ -1,8 +1,11 @@
|
||||
package com.lishid.openinv.internal.v1_21_R3.container.slot;
|
||||
package com.lishid.openinv.internal.paper1_21_4.container.slot;
|
||||
|
||||
import com.lishid.openinv.internal.common.player.OpenPlayer;
|
||||
import net.minecraft.network.protocol.game.ClientboundContainerSetSlotPacket;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.world.Container;
|
||||
import net.minecraft.world.entity.EquipmentSlot;
|
||||
import net.minecraft.world.inventory.InventoryMenu;
|
||||
import net.minecraft.world.inventory.Slot;
|
||||
import org.bukkit.event.inventory.InventoryType;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -34,10 +37,13 @@ public class ContentOffHand extends ContentEquipment {
|
||||
return new SlotEquipment(container, slot, x, y) {
|
||||
@Override
|
||||
public void setChanged() {
|
||||
if (holder.connection != null
|
||||
&& !holder.connection.isDisconnected()
|
||||
&& holder.containerMenu != holder.inventoryMenu) {
|
||||
holder.resendItemInHands();
|
||||
if (OpenPlayer.isConnected(holder.connection) && holder.containerMenu != holder.inventoryMenu) {
|
||||
holder.connection.send(
|
||||
new ClientboundContainerSetSlotPacket(
|
||||
holder.inventoryMenu.containerId,
|
||||
holder.inventoryMenu.incrementStateId(),
|
||||
InventoryMenu.SHIELD_SLOT,
|
||||
holder.getOffhandItem()));
|
||||
}
|
||||
}
|
||||
};
|
||||
+41
@@ -0,0 +1,41 @@
|
||||
package com.lishid.openinv.internal.paper1_21_4.container.slot.placeholder;
|
||||
|
||||
import com.lishid.openinv.internal.common.container.slot.placeholder.PlaceholderLoaderBase;
|
||||
import net.minecraft.core.component.DataComponents;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.nbt.TagParser;
|
||||
import net.minecraft.util.Unit;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.item.component.CustomModelData;
|
||||
import net.minecraft.world.item.component.DyedItemColor;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class CustomModelBase extends PlaceholderLoaderBase {
|
||||
|
||||
private final @NotNull CustomModelData defaultCustomModelData;
|
||||
|
||||
public CustomModelBase(@NotNull CustomModelData defaultCustomModelData) {
|
||||
this.defaultCustomModelData = defaultCustomModelData;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected @NotNull CompoundTag parseTag(@NotNull String itemText) throws Exception {
|
||||
return TagParser.parseTag(itemText);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void addModelData(@NotNull ItemStack itemStack) {
|
||||
itemStack.set(DataComponents.CUSTOM_MODEL_DATA, defaultCustomModelData);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void hideTooltip(@NotNull ItemStack itemStack) {
|
||||
itemStack.set(DataComponents.HIDE_TOOLTIP, Unit.INSTANCE);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected DyedItemColor getDye(int rgb) {
|
||||
return new DyedItemColor(rgb, false);
|
||||
}
|
||||
|
||||
}
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
package com.lishid.openinv.internal.paper1_21_4.container.slot.placeholder;
|
||||
|
||||
import net.minecraft.world.item.component.CustomModelData;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class CustomModelPlaceholderLoader extends CustomModelBase {
|
||||
|
||||
public CustomModelPlaceholderLoader() {
|
||||
super(new CustomModelData(List.of(), List.of(), List.of("openinv:custom"), List.of()));
|
||||
}
|
||||
|
||||
}
|
||||
+35
@@ -0,0 +1,35 @@
|
||||
package com.lishid.openinv.internal.paper1_21_4.player;
|
||||
|
||||
import com.lishid.openinv.internal.common.player.PlayerManager;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import org.bukkit.craftbukkit.CraftServer;
|
||||
import org.jetbrains.annotations.Contract;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public class OpenPlayer extends com.lishid.openinv.internal.common.player.OpenPlayer {
|
||||
|
||||
protected OpenPlayer(CraftServer server, ServerPlayer entity,
|
||||
PlayerManager manager) {
|
||||
super(server, entity, manager);
|
||||
}
|
||||
|
||||
@Contract("null -> new")
|
||||
@Override
|
||||
protected @NotNull CompoundTag getWritableTag(@Nullable CompoundTag oldData) {
|
||||
if (oldData == null) {
|
||||
return new CompoundTag();
|
||||
}
|
||||
|
||||
// Copy old data. This is a deep clone, so operating on it should be safe.
|
||||
oldData = oldData.copy();
|
||||
|
||||
// Remove vanilla/server data that is not written every time.
|
||||
oldData.getAllKeys()
|
||||
.removeIf(key -> RESET_TAGS.contains(key) || key.startsWith("Bukkit"));
|
||||
|
||||
return oldData;
|
||||
}
|
||||
|
||||
}
|
||||
+70
@@ -0,0 +1,70 @@
|
||||
package com.lishid.openinv.internal.paper1_21_4.player;
|
||||
|
||||
import com.mojang.serialization.Dynamic;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.nbt.NbtOps;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.dimension.DimensionType;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.craftbukkit.CraftWorld;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.UUID;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
public class PlayerManager extends com.lishid.openinv.internal.common.player.PlayerManager {
|
||||
|
||||
public PlayerManager(@NotNull Logger logger) {
|
||||
super(logger);
|
||||
}
|
||||
|
||||
protected void parseWorld(@NotNull ServerPlayer player, @NotNull CompoundTag loadedData) {
|
||||
// See PlayerList#placeNewPlayer
|
||||
World bukkitWorld;
|
||||
if (loadedData.contains("WorldUUIDMost") && loadedData.contains("WorldUUIDLeast")) {
|
||||
// Modern Bukkit world.
|
||||
bukkitWorld = Bukkit.getServer().getWorld(new UUID(loadedData.getLong("WorldUUIDMost"), loadedData.getLong("WorldUUIDLeast")));
|
||||
} else if (loadedData.contains("world", net.minecraft.nbt.Tag.TAG_STRING)) {
|
||||
// Legacy Bukkit world.
|
||||
bukkitWorld = Bukkit.getServer().getWorld(loadedData.getString("world"));
|
||||
} else {
|
||||
// Vanilla player data.
|
||||
DimensionType.parseLegacy(new Dynamic<>(NbtOps.INSTANCE, loadedData.get("Dimension")))
|
||||
.resultOrPartial(logger::warning)
|
||||
.map(player.server::getLevel)
|
||||
// If ServerLevel exists, set, otherwise move to spawn.
|
||||
.ifPresentOrElse(player::setServerLevel, () -> spawnInDefaultWorld(player));
|
||||
return;
|
||||
}
|
||||
if (bukkitWorld == null) {
|
||||
spawnInDefaultWorld(player);
|
||||
return;
|
||||
}
|
||||
player.setServerLevel(((CraftWorld) bukkitWorld).getHandle());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void spawnInDefaultWorld(ServerPlayer player) {
|
||||
ServerLevel level = player.server.getLevel(Level.OVERWORLD);
|
||||
if (level != null) {
|
||||
// Adjust player to default spawn (in keeping with Paper handling) when world not found.
|
||||
player.moveTo(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!");
|
||||
}
|
||||
}
|
||||
|
||||
protected void injectPlayer(ServerPlayer player) throws IllegalAccessException {
|
||||
if (bukkitEntity == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
bukkitEntity.setAccessible(true);
|
||||
bukkitEntity.set(player, new OpenPlayer(player.server.server, player, this));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
import com.github.jikoo.openinv.SpigotDependencyExtension
|
||||
import com.github.jikoo.openinv.SpigotReobf
|
||||
import com.github.jikoo.openinv.SpigotSetup
|
||||
|
||||
plugins {
|
||||
`openinv-base`
|
||||
alias(libs.plugins.shadow)
|
||||
}
|
||||
|
||||
apply<SpigotSetup>()
|
||||
apply<SpigotReobf>()
|
||||
|
||||
val spigotVer = "1.21.5-R0.1-SNAPSHOT"
|
||||
// Used by common adapter to relocate Craftbukkit classes to a versioned package.
|
||||
rootProject.extra["craftbukkitPackage"] = "v1_21_R4"
|
||||
|
||||
configurations.all {
|
||||
resolutionStrategy.capabilitiesResolution.withCapability("org.spigotmc:spigot-api") {
|
||||
val spigot = candidates.firstOrNull {
|
||||
it.id.let {
|
||||
id -> id is ModuleComponentIdentifier && id.module == "spigot-api"
|
||||
}
|
||||
}
|
||||
if (spigot != null) {
|
||||
select(spigot)
|
||||
}
|
||||
because("module is written for Spigot servers")
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
compileOnly(libs.spigotapi)
|
||||
extensions.getByType(SpigotDependencyExtension::class.java).version = spigotVer
|
||||
|
||||
compileOnly(project(":openinvapi"))
|
||||
compileOnly(project(":openinvcommon"))
|
||||
|
||||
// Reduce duplicate code by lightly remapping common adapter.
|
||||
implementation(project(":openinvadaptercommon", configuration = "spigotRelocated"))
|
||||
}
|
||||
|
||||
tasks.shadowJar {
|
||||
relocate("com.lishid.openinv.internal.common", "com.lishid.openinv.internal.reobf")
|
||||
}
|
||||
+194
@@ -0,0 +1,194 @@
|
||||
package com.lishid.openinv.internal.reobf.container;
|
||||
|
||||
import com.lishid.openinv.internal.AnySilentContainerBase;
|
||||
import com.lishid.openinv.internal.reobf.container.menu.OpenChestMenu;
|
||||
import com.lishid.openinv.internal.reobf.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.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.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 = 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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
+188
@@ -0,0 +1,188 @@
|
||||
package com.lishid.openinv.internal.reobf.container.bukkit;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
import com.lishid.openinv.internal.reobf.container.OpenInventory;
|
||||
import net.minecraft.core.NonNullList;
|
||||
import net.minecraft.world.entity.player.Inventory;
|
||||
import org.bukkit.craftbukkit.v1_21_R4.inventory.CraftInventory;
|
||||
import org.bukkit.craftbukkit.v1_21_R4.inventory.CraftItemStack;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.inventory.InventoryType;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.PlayerInventory;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public class OpenPlayerInventory extends CraftInventory implements PlayerInventory {
|
||||
|
||||
public OpenPlayerInventory(@NotNull OpenInventory inventory) {
|
||||
super(inventory);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull OpenInventory getInventory() {
|
||||
return (OpenInventory) super.getInventory();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack @NotNull [] getContents() {
|
||||
return asCraftMirror(getInventory().getOwnerHandle().getInventory().getContents());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setContents(ItemStack[] items) {
|
||||
Inventory internal = getInventory().getOwnerHandle().getInventory();
|
||||
int size = internal.getContainerSize();
|
||||
Preconditions.checkArgument(items.length <= size, "items.length must be <= %s", size);
|
||||
|
||||
for (int index = 0; index < size; ++index) {
|
||||
if (index < items.length) {
|
||||
internal.setItem(index, CraftItemStack.asNMSCopy(items[index]));
|
||||
} else {
|
||||
internal.setItem(index, net.minecraft.world.item.ItemStack.EMPTY);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack @NotNull [] getStorageContents() {
|
||||
return asCraftMirror(getInventory().getOwnerHandle().getInventory().getNonEquipmentItems());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setStorageContents(ItemStack[] items) throws IllegalArgumentException {
|
||||
NonNullList<net.minecraft.world.item.ItemStack> list = getInventory().getOwnerHandle().getInventory().getNonEquipmentItems();
|
||||
int size = list.size();
|
||||
Preconditions.checkArgument(items.length <= size, "items.length must be <= %s", size);
|
||||
for (int index = 0; index < items.length; ++index) {
|
||||
list.set(index, CraftItemStack.asNMSCopy(items[index]));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull InventoryType getType() {
|
||||
return InventoryType.PLAYER;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull Player getHolder() {
|
||||
return getInventory().getOwner();
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull ItemStack @NotNull [] getArmorContents() {
|
||||
return getInventory().getOwnerHandle().getBukkitEntity().getInventory().getArmorContents();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setArmorContents(ItemStack @NotNull [] items) {
|
||||
getInventory().getOwnerHandle().getBukkitEntity().getInventory().setArmorContents(items);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull ItemStack @NotNull [] getExtraContents() {
|
||||
return getInventory().getOwnerHandle().getBukkitEntity().getInventory().getExtraContents();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setExtraContents(ItemStack @NotNull [] items) {
|
||||
getInventory().getOwnerHandle().getBukkitEntity().getInventory().setExtraContents(items);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable ItemStack getHelmet() {
|
||||
return getInventory().getOwnerHandle().getBukkitEntity().getInventory().getHelmet();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setHelmet(@Nullable ItemStack helmet) {
|
||||
getInventory().getOwnerHandle().getBukkitEntity().getInventory().setHelmet(helmet);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable ItemStack getChestplate() {
|
||||
return getInventory().getOwnerHandle().getBukkitEntity().getInventory().getChestplate();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setChestplate(@Nullable ItemStack chestplate) {
|
||||
getInventory().getOwnerHandle().getBukkitEntity().getInventory().setChestplate(chestplate);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable ItemStack getLeggings() {
|
||||
return getInventory().getOwnerHandle().getBukkitEntity().getInventory().getLeggings();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setLeggings(@Nullable ItemStack leggings) {
|
||||
getInventory().getOwnerHandle().getBukkitEntity().getInventory().setLeggings(leggings);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable ItemStack getBoots() {
|
||||
return getInventory().getOwnerHandle().getBukkitEntity().getInventory().getBoots();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBoots(@Nullable ItemStack boots) {
|
||||
getInventory().getOwnerHandle().getBukkitEntity().getInventory().setBoots(boots);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull ItemStack getItemInMainHand() {
|
||||
Inventory internal = getInventory().getOwnerHandle().getInventory();
|
||||
return CraftItemStack.asCraftMirror(internal.getSelectedItem());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setItemInMainHand(@Nullable ItemStack item) {
|
||||
Inventory internal = getInventory().getOwnerHandle().getInventory();
|
||||
internal.setSelectedItem(CraftItemStack.asNMSCopy(item));
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull ItemStack getItemInOffHand() {
|
||||
return getInventory().getOwnerHandle().getBukkitEntity().getInventory().getItemInOffHand();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setItemInOffHand(@Nullable ItemStack item) {
|
||||
getInventory().getOwnerHandle().getBukkitEntity().getInventory().setItemInOffHand(item);
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
@Override
|
||||
public @NotNull ItemStack getItemInHand() {
|
||||
return getItemInMainHand();
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
@Override
|
||||
public void setItemInHand(@Nullable ItemStack stack) {
|
||||
setItemInMainHand(stack);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getHeldItemSlot() {
|
||||
Inventory internal = getInventory().getOwnerHandle().getInventory();
|
||||
return internal.getNonEquipmentItems().size() - 9 + internal.getSelectedSlot();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setHeldItemSlot(int slot) {
|
||||
slot %= 9;
|
||||
getInventory().getOwnerHandle().getInventory().setSelectedSlot(slot);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable ItemStack getItem(@NotNull org.bukkit.inventory.EquipmentSlot slot) {
|
||||
return getInventory().getOwnerHandle().getBukkitEntity().getInventory().getItem(slot);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setItem(@NotNull org.bukkit.inventory.EquipmentSlot slot, @Nullable ItemStack item) {
|
||||
getInventory().getOwnerHandle().getBukkitEntity().getInventory().setItem(slot, item);
|
||||
}
|
||||
|
||||
}
|
||||
+116
@@ -0,0 +1,116 @@
|
||||
package com.lishid.openinv.internal.reobf.container.slot;
|
||||
|
||||
import com.lishid.openinv.internal.reobf.container.slot.placeholder.Placeholders;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.world.Container;
|
||||
import net.minecraft.world.entity.EquipmentSlot;
|
||||
import net.minecraft.world.inventory.Slot;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import org.bukkit.craftbukkit.v1_21_R4.CraftEquipmentSlot;
|
||||
import org.bukkit.craftbukkit.v1_21_R4.inventory.CraftItemStack;
|
||||
import org.bukkit.event.inventory.InventoryType;
|
||||
import org.bukkit.inventory.PlayerInventory;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class ContentEquipment implements Content {
|
||||
|
||||
private PlayerInventory equipment;
|
||||
private final ItemStack placeholder;
|
||||
private final org.bukkit.inventory.EquipmentSlot equipmentSlot;
|
||||
|
||||
public ContentEquipment(ServerPlayer holder, EquipmentSlot equipmentSlot) {
|
||||
setHolder(holder);
|
||||
placeholder = switch (equipmentSlot) {
|
||||
case HEAD -> Placeholders.emptyHelmet;
|
||||
case CHEST -> Placeholders.emptyChestplate;
|
||||
case LEGS -> Placeholders.emptyLeggings;
|
||||
case FEET -> Placeholders.emptyBoots;
|
||||
default -> Placeholders.emptyOffHand;
|
||||
};
|
||||
this.equipmentSlot = CraftEquipmentSlot.getSlot(equipmentSlot);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setHolder(@NotNull ServerPlayer holder) {
|
||||
this.equipment = holder.getBukkitEntity().getInventory();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack get() {
|
||||
return CraftItemStack.asNMSCopy(equipment.getItem(equipmentSlot));
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack remove() {
|
||||
org.bukkit.inventory.ItemStack old = equipment.getItem(equipmentSlot);
|
||||
equipment.setItem(equipmentSlot, null);
|
||||
return CraftItemStack.asNMSCopy(old);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack removePartial(int amount) {
|
||||
if (amount <= 0) {
|
||||
return ItemStack.EMPTY;
|
||||
}
|
||||
ItemStack current = get();
|
||||
if (current.isEmpty()) {
|
||||
return ItemStack.EMPTY;
|
||||
}
|
||||
ItemStack split = current.split(amount);
|
||||
set(current);
|
||||
return split;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void set(ItemStack itemStack) {
|
||||
equipment.setItem(equipmentSlot, CraftItemStack.asCraftMirror(itemStack));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Slot asSlot(Container container, int slot, int x, int y) {
|
||||
return new SlotEquipment(container, slot, x, y);
|
||||
}
|
||||
|
||||
@Override
|
||||
public InventoryType.SlotType getSlotType() {
|
||||
return InventoryType.SlotType.ARMOR;
|
||||
}
|
||||
|
||||
public class SlotEquipment extends SlotPlaceholder {
|
||||
|
||||
private ServerPlayer viewer;
|
||||
|
||||
SlotEquipment(Container container, int index, int x, int y) {
|
||||
super(container, index, x, y);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack getOrDefault() {
|
||||
ItemStack itemStack = getItem();
|
||||
if (!itemStack.isEmpty()) {
|
||||
return itemStack;
|
||||
}
|
||||
return placeholder;
|
||||
}
|
||||
|
||||
public EquipmentSlot getEquipmentSlot() {
|
||||
return CraftEquipmentSlot.getNMS(equipmentSlot);
|
||||
}
|
||||
|
||||
public void onlyEquipmentFor(ServerPlayer viewer) {
|
||||
this.viewer = viewer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean mayPlace(@NotNull ItemStack itemStack) {
|
||||
if (viewer == null) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return equipmentSlot == org.bukkit.inventory.EquipmentSlot.OFF_HAND
|
||||
|| viewer.getEquipmentSlotForItem(itemStack) == CraftEquipmentSlot.getNMS(equipmentSlot);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
+49
@@ -0,0 +1,49 @@
|
||||
package com.lishid.openinv.internal.reobf.container.slot;
|
||||
|
||||
import com.lishid.openinv.internal.reobf.player.OpenPlayer;
|
||||
import net.minecraft.network.protocol.game.ClientboundContainerSetSlotPacket;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.world.Container;
|
||||
import net.minecraft.world.entity.EquipmentSlot;
|
||||
import net.minecraft.world.inventory.InventoryMenu;
|
||||
import net.minecraft.world.inventory.Slot;
|
||||
import org.bukkit.event.inventory.InventoryType;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class ContentOffHand extends ContentEquipment {
|
||||
|
||||
private ServerPlayer holder;
|
||||
|
||||
public ContentOffHand(ServerPlayer holder) {
|
||||
super(holder, EquipmentSlot.OFFHAND);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setHolder(@NotNull ServerPlayer holder) {
|
||||
super.setHolder(holder);
|
||||
this.holder = holder;
|
||||
}
|
||||
|
||||
@Override
|
||||
public InventoryType.SlotType getSlotType() {
|
||||
return InventoryType.SlotType.QUICKBAR;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Slot asSlot(Container container, int slot, int x, int y) {
|
||||
return new SlotEquipment(container, slot, x, y) {
|
||||
@Override
|
||||
public void setChanged() {
|
||||
if (OpenPlayer.isConnected(holder.connection) && holder.containerMenu != holder.inventoryMenu) {
|
||||
holder.connection.send(
|
||||
new ClientboundContainerSetSlotPacket(
|
||||
holder.inventoryMenu.containerId,
|
||||
holder.inventoryMenu.incrementStateId(),
|
||||
InventoryMenu.SHIELD_SLOT,
|
||||
holder.getOffhandItem()));
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
+7
-54
@@ -1,12 +1,10 @@
|
||||
package com.lishid.openinv.internal.v1_21_R3.player;
|
||||
package com.lishid.openinv.internal.reobf.player;
|
||||
|
||||
import com.lishid.openinv.internal.ISpecialInventory;
|
||||
import com.lishid.openinv.internal.v1_21_R3.container.OpenEnderChest;
|
||||
import com.lishid.openinv.internal.v1_21_R3.container.OpenInventory;
|
||||
import com.lishid.openinv.internal.reobf.container.OpenEnderChest;
|
||||
import com.lishid.openinv.internal.reobf.container.OpenInventory;
|
||||
import com.mojang.authlib.GameProfile;
|
||||
import com.mojang.serialization.Dynamic;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.nbt.NbtOps;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.network.protocol.game.ClientboundOpenScreenPacket;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
@@ -18,37 +16,22 @@ 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.dimension.DimensionType;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
import org.bukkit.Server;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.craftbukkit.v1_21_R3.CraftServer;
|
||||
import org.bukkit.craftbukkit.v1_21_R3.CraftWorld;
|
||||
import org.bukkit.craftbukkit.v1_21_R3.entity.CraftPlayer;
|
||||
import org.bukkit.craftbukkit.v1_21_R3.event.CraftEventFactory;
|
||||
import org.bukkit.craftbukkit.v1_21_R4.CraftServer;
|
||||
import org.bukkit.craftbukkit.v1_21_R4.entity.CraftPlayer;
|
||||
import org.bukkit.craftbukkit.v1_21_R4.event.CraftEventFactory;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.InventoryView;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.UUID;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
public class PlayerManager implements com.lishid.openinv.internal.PlayerManager {
|
||||
|
||||
private static boolean paper;
|
||||
|
||||
static {
|
||||
try {
|
||||
Class.forName("io.papermc.paper.configuration.Configuration");
|
||||
paper = true;
|
||||
} catch (ClassNotFoundException ignored) {
|
||||
paper = false;
|
||||
}
|
||||
}
|
||||
|
||||
private final @NotNull Logger logger;
|
||||
private @Nullable Field bukkitEntity;
|
||||
|
||||
@@ -158,39 +141,9 @@ public class PlayerManager implements com.lishid.openinv.internal.PlayerManager
|
||||
// Game type settings are also loaded separately.
|
||||
player.loadGameTypes(loadedData);
|
||||
|
||||
if (paper) {
|
||||
// Paper: world is not loaded by ServerPlayer#load(CompoundTag).
|
||||
parseWorld(player, loadedData);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private void parseWorld(@NotNull ServerPlayer player, @NotNull CompoundTag loadedData) {
|
||||
// See PlayerList#placeNewPlayer
|
||||
World bukkitWorld;
|
||||
if (loadedData.contains("WorldUUIDMost") && loadedData.contains("WorldUUIDLeast")) {
|
||||
// Modern Bukkit world.
|
||||
bukkitWorld = Bukkit.getServer().getWorld(new UUID(loadedData.getLong("WorldUUIDMost"), loadedData.getLong("WorldUUIDLeast")));
|
||||
} else if (loadedData.contains("world", net.minecraft.nbt.Tag.TAG_STRING)) {
|
||||
// Legacy Bukkit world.
|
||||
bukkitWorld = Bukkit.getServer().getWorld(loadedData.getString("world"));
|
||||
} else {
|
||||
// Vanilla player data.
|
||||
DimensionType.parseLegacy(new Dynamic<>(NbtOps.INSTANCE, loadedData.get("Dimension")))
|
||||
.resultOrPartial(logger::warning)
|
||||
.map(player.server::getLevel)
|
||||
// If ServerLevel exists, set, otherwise move to spawn.
|
||||
.ifPresentOrElse(player::setServerLevel, () -> player.spawnIn(null));
|
||||
return;
|
||||
}
|
||||
if (bukkitWorld == null) {
|
||||
player.spawnIn(null);
|
||||
return;
|
||||
}
|
||||
player.setServerLevel(((CraftWorld) bukkitWorld).getHandle());
|
||||
}
|
||||
|
||||
private void injectPlayer(ServerPlayer player) throws IllegalAccessException {
|
||||
if (bukkitEntity == null) {
|
||||
return;
|
||||
@@ -223,7 +176,7 @@ public class PlayerManager implements com.lishid.openinv.internal.PlayerManager
|
||||
public @Nullable InventoryView openInventory(@NotNull Player bukkitPlayer, @NotNull ISpecialInventory inventory, boolean viewOnly) {
|
||||
ServerPlayer player = getHandle(bukkitPlayer);
|
||||
|
||||
if (player.connection == null) {
|
||||
if (!OpenPlayer.isConnected(player.connection)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -1,77 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
~ 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/>.
|
||||
-->
|
||||
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<parent>
|
||||
<artifactId>openinvparent</artifactId>
|
||||
<groupId>com.lishid</groupId>
|
||||
<relativePath>../../pom.xml</relativePath>
|
||||
<version>5.1.5</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>openinvadapter1_21_R2</artifactId>
|
||||
<name>OpenInvAdapter1_21_R2</name>
|
||||
|
||||
<properties>
|
||||
<maven.compiler.system>21</maven.compiler.system>
|
||||
<maven.compiler.release>21</maven.compiler.release>
|
||||
<spigot.version>1.21.3-R0.1-SNAPSHOT</spigot.version>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.spigotmc</groupId>
|
||||
<artifactId>spigot-api</artifactId>
|
||||
<version>${spigot.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<artifactId>spigot</artifactId>
|
||||
<groupId>org.spigotmc</groupId>
|
||||
<scope>provided</scope>
|
||||
<version>${spigot.version}</version>
|
||||
<classifier>remapped-mojang</classifier>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<artifactId>openinvapi</artifactId>
|
||||
<groupId>com.lishid</groupId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<artifactId>openinvcommon</artifactId>
|
||||
<groupId>com.lishid</groupId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<artifactId>annotations</artifactId>
|
||||
<groupId>org.jetbrains</groupId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>net.md-5</groupId>
|
||||
<artifactId>specialsource-maven-plugin</artifactId>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
</project>
|
||||
-196
@@ -1,196 +0,0 @@
|
||||
package com.lishid.openinv.internal.v1_21_R2.container;
|
||||
|
||||
import com.lishid.openinv.internal.ISpecialEnderChest;
|
||||
import com.lishid.openinv.internal.InternalOwned;
|
||||
import com.lishid.openinv.internal.v1_21_R2.container.menu.OpenEnderChestMenu;
|
||||
import com.lishid.openinv.internal.v1_21_R2.player.PlayerManager;
|
||||
import net.minecraft.core.NonNullList;
|
||||
import net.minecraft.network.chat.Component;
|
||||
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.AbstractContainerMenu;
|
||||
import net.minecraft.world.inventory.StackedContentsCompatible;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.craftbukkit.v1_21_R2.entity.CraftHumanEntity;
|
||||
import org.bukkit.craftbukkit.v1_21_R2.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 = owner.getEnderChestInventory().items;
|
||||
}
|
||||
|
||||
@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 void setPlayerOffline() {}
|
||||
|
||||
@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 ItemStack getItem(int index) {
|
||||
return index >= 0 && index < items.size() ? items.get(index) : ItemStack.EMPTY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack removeItem(int index, int amount) {
|
||||
ItemStack itemstack = ContainerHelper.removeItem(items, index, amount);
|
||||
|
||||
if (!itemstack.isEmpty()) {
|
||||
setChanged();
|
||||
}
|
||||
|
||||
return itemstack;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack removeItemNoUpdate(int index) {
|
||||
return index >= 0 && index < items.size() ? items.set(index, ItemStack.EMPTY) : ItemStack.EMPTY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setItem(int index, 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(Player player) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ItemStack> getContents() {
|
||||
return items;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onOpen(CraftHumanEntity craftHumanEntity) {
|
||||
transaction.add(craftHumanEntity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClose(CraftHumanEntity craftHumanEntity) {
|
||||
transaction.remove(craftHumanEntity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public 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(StackedItemContents stackedContents) {
|
||||
for (ItemStack itemstack : items) {
|
||||
stackedContents.accountStack(itemstack);
|
||||
}
|
||||
}
|
||||
|
||||
public Component getTitle() {
|
||||
return 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 AbstractContainerMenu createMenu(Player player, int i, boolean viewOnly) {
|
||||
if (player instanceof ServerPlayer serverPlayer) {
|
||||
return new OpenEnderChestMenu(this, serverPlayer, i, viewOnly);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
-364
@@ -1,364 +0,0 @@
|
||||
package com.lishid.openinv.internal.v1_21_R2.container;
|
||||
|
||||
import com.lishid.openinv.internal.ISpecialPlayerInventory;
|
||||
import com.lishid.openinv.internal.InternalOwned;
|
||||
import com.lishid.openinv.internal.v1_21_R2.container.bukkit.OpenPlayerInventory;
|
||||
import com.lishid.openinv.internal.v1_21_R2.container.menu.OpenInventoryMenu;
|
||||
import com.lishid.openinv.internal.v1_21_R2.container.slot.Content;
|
||||
import com.lishid.openinv.internal.v1_21_R2.container.slot.ContentCrafting;
|
||||
import com.lishid.openinv.internal.v1_21_R2.container.slot.ContentCraftingResult;
|
||||
import com.lishid.openinv.internal.v1_21_R2.container.slot.ContentCursor;
|
||||
import com.lishid.openinv.internal.v1_21_R2.container.slot.ContentDrop;
|
||||
import com.lishid.openinv.internal.v1_21_R2.container.slot.ContentEquipment;
|
||||
import com.lishid.openinv.internal.v1_21_R2.container.slot.ContentList;
|
||||
import com.lishid.openinv.internal.v1_21_R2.container.slot.ContentOffHand;
|
||||
import com.lishid.openinv.internal.v1_21_R2.container.slot.ContentViewOnly;
|
||||
import com.lishid.openinv.internal.v1_21_R2.container.slot.SlotViewOnly;
|
||||
import com.lishid.openinv.internal.v1_21_R2.player.PlayerManager;
|
||||
import net.minecraft.ChatFormatting;
|
||||
import net.minecraft.core.NonNullList;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.network.chat.MutableComponent;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.world.Container;
|
||||
import net.minecraft.world.entity.EquipmentSlot;
|
||||
import net.minecraft.world.entity.player.Inventory;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraft.world.inventory.AbstractContainerMenu;
|
||||
import net.minecraft.world.inventory.Slot;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.craftbukkit.v1_21_R2.entity.CraftHumanEntity;
|
||||
import org.bukkit.craftbukkit.v1_21_R2.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 OpenInventory implements Container, InternalOwned<ServerPlayer>, ISpecialPlayerInventory {
|
||||
|
||||
private final List<Content> slots;
|
||||
private final int size;
|
||||
private ServerPlayer owner;
|
||||
private int maxStackSize = 99;
|
||||
private CraftInventory bukkitEntity;
|
||||
public List<HumanEntity> transaction = new ArrayList<>();
|
||||
|
||||
public OpenInventory(@NotNull org.bukkit.entity.Player bukkitPlayer) {
|
||||
owner = PlayerManager.getHandle(bukkitPlayer);
|
||||
|
||||
// Get total size, rounding up to nearest 9 for client compatibility.
|
||||
int rawSize = owner.getInventory().getContainerSize() + owner.inventoryMenu.getCraftSlots().getContainerSize() + 1;
|
||||
size = ((int) Math.ceil(rawSize / 9.0)) * 9;
|
||||
|
||||
slots = NonNullList.withSize(size, new ContentViewOnly(owner));
|
||||
setupSlots();
|
||||
}
|
||||
|
||||
private void setupSlots() {
|
||||
// Top of inventory: Regular contents.
|
||||
int nextIndex = addMainInventory();
|
||||
|
||||
// If inventory is expected size, we can arrange slots to be pretty.
|
||||
Inventory ownerInv = owner.getInventory();
|
||||
if (ownerInv.items.size() == 36
|
||||
&& ownerInv.armor.size() == 4
|
||||
&& ownerInv.offhand.size() == 1
|
||||
&& owner.inventoryMenu.getCraftSlots().getContainerSize() == 4) {
|
||||
// Armor slots: Bottom left.
|
||||
addArmor(36);
|
||||
// Off-hand: Below chestplate.
|
||||
addOffHand(46);
|
||||
// Drop slot: Bottom right.
|
||||
slots.set(53, new ContentDrop(owner));
|
||||
// Cursor slot: Above drop.
|
||||
slots.set(44, new ContentCursor(owner));
|
||||
|
||||
// Crafting is displayed in the bottom right corner.
|
||||
// As we're using the pretty view, this is a 3x2.
|
||||
addCrafting(41, true);
|
||||
return;
|
||||
}
|
||||
|
||||
// Otherwise we'll just add elements linearly.
|
||||
nextIndex = addArmor(nextIndex);
|
||||
nextIndex = addOffHand(nextIndex);
|
||||
nextIndex = addCrafting(nextIndex, false);
|
||||
slots.set(nextIndex, new ContentCursor(owner));
|
||||
// Drop slot last.
|
||||
slots.set(slots.size() - 1, new ContentDrop(owner));
|
||||
}
|
||||
|
||||
private int addMainInventory() {
|
||||
int listSize = owner.getInventory().items.size();
|
||||
// Hotbar slots are 0-8. We want those to appear on the bottom of the inventory like a normal player inventory,
|
||||
// so everything else needs to move up a row.
|
||||
int hotbarDiff = listSize - 9;
|
||||
for (int localIndex = 0; localIndex < listSize; ++localIndex) {
|
||||
InventoryType.SlotType type;
|
||||
int invIndex;
|
||||
if (localIndex < hotbarDiff) {
|
||||
invIndex = localIndex + 9;
|
||||
type = InventoryType.SlotType.CONTAINER;
|
||||
} else {
|
||||
type = InventoryType.SlotType.QUICKBAR;
|
||||
invIndex = localIndex - hotbarDiff;
|
||||
}
|
||||
|
||||
slots.set(localIndex, new ContentList(owner, invIndex, type) {
|
||||
@Override
|
||||
public void setHolder(@NotNull ServerPlayer holder) {
|
||||
items = holder.getInventory().items;
|
||||
}
|
||||
});
|
||||
}
|
||||
return listSize;
|
||||
}
|
||||
|
||||
private int addArmor(int startIndex) {
|
||||
int listSize = owner.getInventory().armor.size();
|
||||
|
||||
for (int i = 0; i < listSize; ++i) {
|
||||
// Armor slots go bottom to top; boots are slot 0, helmet is slot 3.
|
||||
// Since we have to display horizontally due to space restrictions,
|
||||
// making the left side the "top" is more user-friendly.
|
||||
int armorIndex;
|
||||
EquipmentSlot slot;
|
||||
switch (i) {
|
||||
case 3 -> {
|
||||
armorIndex = 0;
|
||||
slot = EquipmentSlot.FEET;
|
||||
}
|
||||
case 2 -> {
|
||||
armorIndex = 1;
|
||||
slot = EquipmentSlot.LEGS;
|
||||
}
|
||||
case 1 -> {
|
||||
armorIndex = 2;
|
||||
slot = EquipmentSlot.CHEST;
|
||||
}
|
||||
case 0 -> {
|
||||
armorIndex = 3;
|
||||
slot = EquipmentSlot.HEAD;
|
||||
}
|
||||
default -> {
|
||||
// In the event that new armor slots are added, they can be placed at the end.
|
||||
armorIndex = i;
|
||||
slot = EquipmentSlot.MAINHAND;
|
||||
}
|
||||
}
|
||||
|
||||
slots.set(startIndex + i, new ContentEquipment(owner, armorIndex, slot));
|
||||
}
|
||||
|
||||
return startIndex + listSize;
|
||||
}
|
||||
|
||||
private int addOffHand(int startIndex) {
|
||||
int listSize = owner.getInventory().offhand.size();
|
||||
for (int localIndex = 0; localIndex < listSize; ++localIndex) {
|
||||
slots.set(startIndex + localIndex, new ContentOffHand(owner, localIndex));
|
||||
}
|
||||
return startIndex + listSize;
|
||||
}
|
||||
|
||||
private int addCrafting(int startIndex, boolean pretty) {
|
||||
int listSize = owner.inventoryMenu.getCraftSlots().getContents().size();
|
||||
pretty &= listSize == 4;
|
||||
|
||||
for (int localIndex = 0; localIndex < listSize; ++localIndex) {
|
||||
// Pretty display is a 2x2 rather than linear.
|
||||
// If index is in top row, grid is not 2x2, or pretty is disabled, just use current index.
|
||||
// Otherwise, subtract 2 and add 9 to start in the same position on the next row.
|
||||
int modIndex = startIndex + (localIndex < 2 || !pretty ? localIndex : localIndex + 7);
|
||||
|
||||
slots.set(modIndex, new ContentCrafting(owner, localIndex));
|
||||
}
|
||||
|
||||
if (pretty) {
|
||||
slots.set(startIndex + 2, new ContentViewOnly(owner) {
|
||||
@Override
|
||||
public Slot asSlot(Container container, int slot, int x, int y) {
|
||||
return new SlotViewOnly(container, slot, x, y) {
|
||||
@Override
|
||||
public ItemStack getOrDefault() {
|
||||
return Placeholders.craftingOutput;
|
||||
}
|
||||
};
|
||||
}
|
||||
});
|
||||
slots.set(startIndex + 11, new ContentCraftingResult(owner));
|
||||
}
|
||||
|
||||
return startIndex + listSize;
|
||||
}
|
||||
|
||||
public Slot getMenuSlot(int index, int x, int y) {
|
||||
return slots.get(index).asSlot(this, index, x, y);
|
||||
}
|
||||
|
||||
public InventoryType.SlotType getSlotType(int index) {
|
||||
return slots.get(index).getSlotType();
|
||||
}
|
||||
|
||||
public @NotNull Component getTitle(@Nullable ServerPlayer viewer) {
|
||||
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)));
|
||||
}
|
||||
// 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 ServerPlayer getOwnerHandle() {
|
||||
return owner;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull org.bukkit.inventory.Inventory getBukkitInventory() {
|
||||
if (bukkitEntity == null) {
|
||||
bukkitEntity = new OpenPlayerInventory(this);
|
||||
}
|
||||
return bukkitEntity;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPlayerOnline(@NotNull org.bukkit.entity.Player player) {
|
||||
ServerPlayer newOwner = PlayerManager.getHandle(player);
|
||||
// Only transfer regular inventory - crafting and cursor slots are transient.
|
||||
newOwner.getInventory().replaceWith(owner.getInventory());
|
||||
owner = newOwner;
|
||||
// Update slots to point to new inventory.
|
||||
slots.forEach(slot -> slot.setHolder(newOwner));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPlayerOffline() {}
|
||||
|
||||
@Override
|
||||
public boolean isInUse() {
|
||||
return !transaction.isEmpty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull org.bukkit.entity.Player getPlayer() {
|
||||
return getOwner();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getContainerSize() {
|
||||
return size;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEmpty() {
|
||||
return slots.stream().map(Content::get).allMatch(ItemStack::isEmpty);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack getItem(int index) {
|
||||
return slots.get(index).get();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack removeItem(int index, int amount) {
|
||||
return slots.get(index).removePartial(amount);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack removeItemNoUpdate(int index) {
|
||||
return slots.get(index).remove();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setItem(int index, ItemStack itemStack) {
|
||||
slots.get(index).set(itemStack);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMaxStackSize() {
|
||||
return maxStackSize;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setMaxStackSize(int maxStackSize) {
|
||||
this.maxStackSize = maxStackSize;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setChanged() {}
|
||||
|
||||
@Override
|
||||
public boolean stillValid(Player player) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ItemStack> getContents() {
|
||||
NonNullList<ItemStack> contents = NonNullList.withSize(getContainerSize(), ItemStack.EMPTY);
|
||||
for (int i = 0; i < getContainerSize(); ++i) {
|
||||
contents.set(i, getItem(i));
|
||||
}
|
||||
return contents;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onOpen(CraftHumanEntity viewer) {
|
||||
transaction.add(viewer);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClose(CraftHumanEntity viewer) {
|
||||
transaction.remove(viewer);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<HumanEntity> getViewers() {
|
||||
return transaction;
|
||||
}
|
||||
|
||||
@Override
|
||||
public org.bukkit.entity.Player getOwner() {
|
||||
return owner.getBukkitEntity();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Location getLocation() {
|
||||
return owner.getBukkitEntity().getLocation();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clearContent() {
|
||||
owner.getInventory().clearContent();
|
||||
owner.inventoryMenu.getCraftSlots().clearContent();
|
||||
owner.inventoryMenu.slotsChanged(owner.inventoryMenu.getCraftSlots());
|
||||
owner.containerMenu.setCarried(ItemStack.EMPTY);
|
||||
}
|
||||
|
||||
public @Nullable AbstractContainerMenu createMenu(Player player, int i, boolean viewOnly) {
|
||||
if (player instanceof ServerPlayer serverPlayer) {
|
||||
return new OpenInventoryMenu(this, serverPlayer, i, viewOnly);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
-58
@@ -1,58 +0,0 @@
|
||||
package com.lishid.openinv.internal.v1_21_R2.container.slot;
|
||||
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.world.Container;
|
||||
import net.minecraft.world.ContainerHelper;
|
||||
import net.minecraft.world.inventory.Slot;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import org.bukkit.event.inventory.InventoryType;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* A normal slot backed by an item list.
|
||||
*/
|
||||
public abstract class ContentList implements Content {
|
||||
|
||||
private final int index;
|
||||
private final InventoryType.SlotType slotType;
|
||||
protected List<ItemStack> items;
|
||||
|
||||
public ContentList(ServerPlayer holder, int index, InventoryType.SlotType slotType) {
|
||||
this.index = index;
|
||||
this.slotType = slotType;
|
||||
setHolder(holder);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack get() {
|
||||
return items.get(index);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack remove() {
|
||||
ItemStack removed = items.remove(index);
|
||||
return removed == null || removed.isEmpty() ? ItemStack.EMPTY : removed;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack removePartial(int amount) {
|
||||
return ContainerHelper.removeItem(items, index, amount);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void set(ItemStack itemStack) {
|
||||
items.set(index, itemStack);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Slot asSlot(Container container, int slot, int x, int y) {
|
||||
return new Slot(container, slot, x, y);
|
||||
}
|
||||
|
||||
@Override
|
||||
public InventoryType.SlotType getSlotType() {
|
||||
return slotType;
|
||||
}
|
||||
|
||||
}
|
||||
-178
@@ -1,178 +0,0 @@
|
||||
package com.lishid.openinv.internal.v1_21_R2.player;
|
||||
|
||||
import com.lishid.openinv.event.OpenEvents;
|
||||
import com.mojang.logging.LogUtils;
|
||||
import net.minecraft.Util;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.nbt.NbtIo;
|
||||
import net.minecraft.nbt.NumericTag;
|
||||
import net.minecraft.nbt.Tag;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.world.level.storage.PlayerDataStorage;
|
||||
import org.bukkit.craftbukkit.v1_21_R2.CraftServer;
|
||||
import org.bukkit.craftbukkit.v1_21_R2.entity.CraftPlayer;
|
||||
import org.jetbrains.annotations.Contract;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.Set;
|
||||
|
||||
public class OpenPlayer extends CraftPlayer {
|
||||
|
||||
/**
|
||||
* List of tags to always reset when saving.
|
||||
*
|
||||
* @see net.minecraft.world.entity.Entity#saveWithoutId(CompoundTag)
|
||||
* @see net.minecraft.server.level.ServerPlayer#addAdditionalSaveData(CompoundTag)
|
||||
* @see net.minecraft.world.entity.player.Player#addAdditionalSaveData(CompoundTag)
|
||||
* @see net.minecraft.world.entity.LivingEntity#addAdditionalSaveData(CompoundTag)
|
||||
*/
|
||||
private static final Set<String> RESET_TAGS = Set.of(
|
||||
// Entity#saveWithoutId(CompoundTag)
|
||||
"CustomName",
|
||||
"CustomNameVisible",
|
||||
"Silent",
|
||||
"NoGravity",
|
||||
"Glowing",
|
||||
"TicksFrozen",
|
||||
"HasVisualFire",
|
||||
"Tags",
|
||||
"Passengers",
|
||||
// ServerPlayer#addAdditionalSaveData(CompoundTag)
|
||||
// Intentional omissions to prevent mount loss: Attach, Entity, and RootVehicle
|
||||
"warden_spawn_tracker",
|
||||
"enteredNetherPosition",
|
||||
"SpawnX",
|
||||
"SpawnY",
|
||||
"SpawnZ",
|
||||
"SpawnForced",
|
||||
"SpawnAngle",
|
||||
"SpawnDimension",
|
||||
"raid_omen_position",
|
||||
"ender_pearls",
|
||||
// Player#addAdditionalSaveData(CompoundTag)
|
||||
"ShoulderEntityLeft",
|
||||
"ShoulderEntityRight",
|
||||
"LastDeathLocation",
|
||||
"current_explosion_impact_pos",
|
||||
// LivingEntity#addAdditionalSaveData(CompoundTag)
|
||||
"active_effects",
|
||||
"SleepingX",
|
||||
"SleepingY",
|
||||
"SleepingZ",
|
||||
"Brain"
|
||||
);
|
||||
|
||||
private final PlayerManager manager;
|
||||
|
||||
OpenPlayer(CraftServer server, ServerPlayer entity, PlayerManager manager) {
|
||||
super(server, entity);
|
||||
this.manager = manager;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loadData() {
|
||||
manager.loadData(getHandle());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void saveData() {
|
||||
if (OpenEvents.saveCancelled(this)) {
|
||||
return;
|
||||
}
|
||||
|
||||
ServerPlayer player = this.getHandle();
|
||||
// See net.minecraft.world.level.storage.PlayerDataStorage#save(EntityHuman)
|
||||
try {
|
||||
PlayerDataStorage worldNBTStorage = player.server.getPlayerList().playerIo;
|
||||
|
||||
CompoundTag oldData = isOnline() ? null : worldNBTStorage.load(player.getName().getString(), player.getStringUUID()).orElse(null);
|
||||
CompoundTag playerData = getWritableTag(oldData);
|
||||
playerData = player.saveWithoutId(playerData);
|
||||
setExtraData(playerData);
|
||||
|
||||
if (oldData != null) {
|
||||
// Revert certain special data values when offline.
|
||||
revertSpecialValues(playerData, oldData);
|
||||
}
|
||||
|
||||
Path playerDataDir = worldNBTStorage.getPlayerDir().toPath();
|
||||
Path tempFile = Files.createTempFile(playerDataDir, player.getStringUUID() + "-", ".dat");
|
||||
NbtIo.writeCompressed(playerData, tempFile);
|
||||
Path dataFile = playerDataDir.resolve(player.getStringUUID() + ".dat");
|
||||
Path backupFile = playerDataDir.resolve(player.getStringUUID() + ".dat_old");
|
||||
Util.safeReplaceFile(dataFile, tempFile, backupFile);
|
||||
} catch (Exception e) {
|
||||
LogUtils.getLogger().warn("Failed to save player data for {}: {}", player.getScoreboardName(), e);
|
||||
}
|
||||
}
|
||||
|
||||
@Contract("null -> new")
|
||||
private @NotNull CompoundTag getWritableTag(@Nullable CompoundTag oldData) {
|
||||
if (oldData == null) {
|
||||
return new CompoundTag();
|
||||
}
|
||||
|
||||
// Copy old data. This is a deep clone, so operating on it should be safe.
|
||||
oldData = oldData.copy();
|
||||
|
||||
// Remove vanilla/server data that is not written every time.
|
||||
oldData.getAllKeys()
|
||||
.removeIf(key -> RESET_TAGS.contains(key) || key.startsWith("Bukkit"));
|
||||
|
||||
return oldData;
|
||||
}
|
||||
|
||||
private void revertSpecialValues(@NotNull CompoundTag newData, @NotNull CompoundTag oldData) {
|
||||
// Revert automatic updates to play timestamps.
|
||||
copyValue(oldData, newData, "bukkit", "lastPlayed", NumericTag.class);
|
||||
copyValue(oldData, newData, "Paper", "LastSeen", NumericTag.class);
|
||||
copyValue(oldData, newData, "Paper", "LastLogin", NumericTag.class);
|
||||
}
|
||||
|
||||
private <T extends Tag> void copyValue(
|
||||
@NotNull CompoundTag source,
|
||||
@NotNull CompoundTag target,
|
||||
@NotNull String container,
|
||||
@NotNull String key,
|
||||
@SuppressWarnings("SameParameterValue") @NotNull Class<T> tagType) {
|
||||
CompoundTag oldContainer = getTag(source, container, CompoundTag.class);
|
||||
CompoundTag newContainer = getTag(target, container, CompoundTag.class);
|
||||
|
||||
// New container being null means the server implementation doesn't store this data.
|
||||
if (newContainer == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
// If old tag exists, copy it to new location, removing otherwise.
|
||||
setTag(newContainer, key, getTag(oldContainer, key, tagType));
|
||||
}
|
||||
|
||||
private <T extends Tag> @Nullable T getTag(
|
||||
@Nullable CompoundTag container,
|
||||
@NotNull String key,
|
||||
@NotNull Class<T> dataType) {
|
||||
if (container == null) {
|
||||
return null;
|
||||
}
|
||||
Tag value = container.get(key);
|
||||
if (value == null || !dataType.isAssignableFrom(value.getClass())) {
|
||||
return null;
|
||||
}
|
||||
return dataType.cast(value);
|
||||
}
|
||||
|
||||
private <T extends Tag> void setTag(
|
||||
@NotNull CompoundTag container,
|
||||
@NotNull String key,
|
||||
@Nullable T data) {
|
||||
if (data == null) {
|
||||
container.remove(key);
|
||||
} else {
|
||||
container.put(key, data);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,77 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
~ 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/>.
|
||||
-->
|
||||
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<parent>
|
||||
<artifactId>openinvparent</artifactId>
|
||||
<groupId>com.lishid</groupId>
|
||||
<relativePath>../../pom.xml</relativePath>
|
||||
<version>5.1.5</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>openinvadapter1_21_R3</artifactId>
|
||||
<name>OpenInvAdapter1_21_R3</name>
|
||||
|
||||
<properties>
|
||||
<maven.compiler.system>21</maven.compiler.system>
|
||||
<maven.compiler.release>21</maven.compiler.release>
|
||||
<spigot.version>1.21.4-R0.1-SNAPSHOT</spigot.version>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.spigotmc</groupId>
|
||||
<artifactId>spigot-api</artifactId>
|
||||
<version>${spigot.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<artifactId>spigot</artifactId>
|
||||
<groupId>org.spigotmc</groupId>
|
||||
<scope>provided</scope>
|
||||
<version>${spigot.version}</version>
|
||||
<classifier>remapped-mojang</classifier>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<artifactId>openinvapi</artifactId>
|
||||
<groupId>com.lishid</groupId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<artifactId>openinvcommon</artifactId>
|
||||
<groupId>com.lishid</groupId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<artifactId>annotations</artifactId>
|
||||
<groupId>org.jetbrains</groupId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>net.md-5</groupId>
|
||||
<artifactId>specialsource-maven-plugin</artifactId>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
</project>
|
||||
-210
@@ -1,210 +0,0 @@
|
||||
/*
|
||||
* 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.v1_21_R3.container;
|
||||
|
||||
import com.lishid.openinv.internal.AnySilentContainerBase;
|
||||
import com.lishid.openinv.internal.v1_21_R3.container.menu.OpenChestMenu;
|
||||
import com.lishid.openinv.internal.v1_21_R3.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.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.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("b");
|
||||
this.serverPlayerGameModeGameType.setAccessible(true);
|
||||
} catch (NoSuchFieldException e) {
|
||||
logger.warning("ServerPlayerGameMode#gameModeForPlayer's obfuscated name has changed!");
|
||||
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 = 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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
-183
@@ -1,183 +0,0 @@
|
||||
package com.lishid.openinv.internal.v1_21_R3.container;
|
||||
|
||||
import net.minecraft.core.Registry;
|
||||
import net.minecraft.core.RegistryAccess;
|
||||
import net.minecraft.core.component.DataComponents;
|
||||
import net.minecraft.core.registries.Registries;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.nbt.TagParser;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.util.Unit;
|
||||
import net.minecraft.world.item.DyeColor;
|
||||
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.level.GameType;
|
||||
import net.minecraft.world.level.ItemLike;
|
||||
import net.minecraft.world.level.block.entity.BannerPattern;
|
||||
import net.minecraft.world.level.block.entity.BannerPatternLayers;
|
||||
import net.minecraft.world.level.block.entity.BannerPatterns;
|
||||
import org.bukkit.configuration.ConfigurationSection;
|
||||
import org.bukkit.craftbukkit.v1_21_R3.CraftRegistry;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.EnumMap;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
public final class Placeholders {
|
||||
|
||||
private static final CustomModelData DEFAULT_CUSTOM_MODEL_DATA = new CustomModelData(List.of(), List.of(), List.of("openinv:custom"), List.of());
|
||||
public static final @NotNull EnumMap<GameType, ItemStack> BLOCKED_GAME_TYPE = new EnumMap<>(GameType.class);
|
||||
public static @NotNull ItemStack craftingOutput = defaultCraftingOutput();
|
||||
public static @NotNull ItemStack cursor = defaultCursor();
|
||||
public static @NotNull ItemStack drop = defaultDrop();
|
||||
public static @NotNull ItemStack emptyHelmet = getEmptyArmor(Items.LEATHER_HELMET);
|
||||
public static @NotNull ItemStack emptyChestplate = getEmptyArmor(Items.LEATHER_CHESTPLATE);
|
||||
public static @NotNull ItemStack emptyLeggings = getEmptyArmor(Items.LEATHER_LEGGINGS);
|
||||
public static @NotNull ItemStack emptyBoots = getEmptyArmor(Items.LEATHER_BOOTS);
|
||||
public static @NotNull ItemStack emptyOffHand = getEmptyShield();
|
||||
public static @NotNull ItemStack notSlot = defaultNotSlot();
|
||||
public static @NotNull ItemStack blockedOffline = defaultBlockedOffline();
|
||||
|
||||
static {
|
||||
for (GameType type : GameType.values()) {
|
||||
// Barrier: "Not available - Creative" etc.
|
||||
ItemStack typeItem = new ItemStack(Items.BARRIER);
|
||||
typeItem.set(
|
||||
DataComponents.ITEM_NAME,
|
||||
Component.translatable("options.narrator.notavailable").append(" - ").append(type.getShortDisplayName()));
|
||||
BLOCKED_GAME_TYPE.put(type, typeItem);
|
||||
}
|
||||
}
|
||||
|
||||
public static void load(@NotNull ConfigurationSection section) throws Exception {
|
||||
craftingOutput = parse(section, "crafting-output", craftingOutput);
|
||||
cursor = parse(section, "cursor", cursor);
|
||||
drop = parse(section, "drop", drop);
|
||||
emptyHelmet = parse(section, "empty-helmet", emptyHelmet);
|
||||
emptyChestplate = parse(section, "empty-chestplate", emptyChestplate);
|
||||
emptyLeggings = parse(section, "empty-leggings", emptyLeggings);
|
||||
emptyBoots = parse(section, "empty-boots", emptyBoots);
|
||||
emptyOffHand = parse(section, "empty-off-hand", emptyOffHand);
|
||||
notSlot = parse(section, "not-a-slot", notSlot);
|
||||
blockedOffline = parse(section, "blocked.offline", blockedOffline);
|
||||
BLOCKED_GAME_TYPE.put(GameType.CREATIVE, parse(section, "blocked.creative", BLOCKED_GAME_TYPE.get(GameType.CREATIVE)));
|
||||
BLOCKED_GAME_TYPE.put(GameType.SPECTATOR, parse(section, "blocked.spectator", BLOCKED_GAME_TYPE.get(GameType.SPECTATOR)));
|
||||
}
|
||||
|
||||
private static @NotNull ItemStack parse(
|
||||
@NotNull ConfigurationSection section,
|
||||
@NotNull String path,
|
||||
@NotNull ItemStack defaultStack) throws Exception {
|
||||
String itemText = section.getString(path);
|
||||
|
||||
if (itemText == null) {
|
||||
return defaultStack;
|
||||
}
|
||||
|
||||
CompoundTag compoundTag = TagParser.parseTag(itemText);
|
||||
Optional<ItemStack> parsed = ItemStack.parse(CraftRegistry.getMinecraftRegistry(), compoundTag);
|
||||
return parsed.filter(itemStack -> !itemStack.isEmpty()).orElse(defaultStack);
|
||||
}
|
||||
|
||||
public static ItemStack survivalOnly(@NotNull ServerPlayer serverPlayer) {
|
||||
if (serverPlayer.connection == null || serverPlayer.connection.isDisconnected()) {
|
||||
return blockedOffline;
|
||||
}
|
||||
|
||||
return BLOCKED_GAME_TYPE.getOrDefault(serverPlayer.gameMode.getGameModeForPlayer(), ItemStack.EMPTY);
|
||||
}
|
||||
|
||||
private static ItemStack defaultCraftingOutput() {
|
||||
// Crafting table: "Crafting"
|
||||
ItemStack itemStack = new ItemStack(Items.CRAFTING_TABLE);
|
||||
itemStack.set(DataComponents.ITEM_NAME, Component.translatable("container.crafting"));
|
||||
itemStack.set(DataComponents.CUSTOM_MODEL_DATA, DEFAULT_CUSTOM_MODEL_DATA);
|
||||
return itemStack;
|
||||
}
|
||||
|
||||
private static ItemStack defaultCursor() {
|
||||
// Cursor-like banner with no tooltip
|
||||
ItemStack itemStack = new ItemStack(Items.WHITE_BANNER);
|
||||
RegistryAccess minecraftRegistry = CraftRegistry.getMinecraftRegistry();
|
||||
Registry<BannerPattern> bannerPatterns = minecraftRegistry.lookupOrThrow(Registries.BANNER_PATTERN);
|
||||
BannerPattern halfDiagBottomRight = bannerPatterns.getOrThrow(BannerPatterns.DIAGONAL_RIGHT).value();
|
||||
BannerPattern downRight = bannerPatterns.getOrThrow(BannerPatterns.STRIPE_DOWNRIGHT).value();
|
||||
BannerPattern border = bannerPatterns.getOrThrow(BannerPatterns.BORDER).value();
|
||||
itemStack.set(DataComponents.BANNER_PATTERNS,
|
||||
new BannerPatternLayers(List.of(
|
||||
new BannerPatternLayers.Layer(bannerPatterns.wrapAsHolder(halfDiagBottomRight), DyeColor.GRAY),
|
||||
new BannerPatternLayers.Layer(bannerPatterns.wrapAsHolder(downRight), DyeColor.WHITE),
|
||||
new BannerPatternLayers.Layer(bannerPatterns.wrapAsHolder(border), DyeColor.GRAY))));
|
||||
itemStack.set(DataComponents.CUSTOM_MODEL_DATA, DEFAULT_CUSTOM_MODEL_DATA);
|
||||
itemStack.set(DataComponents.HIDE_TOOLTIP, Unit.INSTANCE);
|
||||
return itemStack;
|
||||
}
|
||||
|
||||
private static ItemStack defaultDrop() {
|
||||
// Dropper: "Drop Selected Item"
|
||||
ItemStack itemStack = new ItemStack(Items.DROPPER);
|
||||
// Note: translatable component, not keybind component! We want the text identifying the keybind, not the key.
|
||||
itemStack.set(DataComponents.ITEM_NAME, Component.translatable("key.drop"));
|
||||
itemStack.set(DataComponents.CUSTOM_MODEL_DATA, DEFAULT_CUSTOM_MODEL_DATA);
|
||||
return itemStack;
|
||||
}
|
||||
|
||||
private static ItemStack getEmptyArmor(ItemLike item) {
|
||||
// Inventory-background-grey-ish leather armor with no tooltip
|
||||
ItemStack itemStack = new ItemStack(item);
|
||||
DyedItemColor color = new DyedItemColor(0xC8C8C8, false);
|
||||
itemStack.set(DataComponents.DYED_COLOR, color);
|
||||
itemStack.set(DataComponents.HIDE_TOOLTIP, Unit.INSTANCE);
|
||||
itemStack.set(DataComponents.CUSTOM_MODEL_DATA, DEFAULT_CUSTOM_MODEL_DATA);
|
||||
return itemStack;
|
||||
}
|
||||
|
||||
private static ItemStack getEmptyShield() {
|
||||
ItemStack itemStack = new ItemStack(Items.SHIELD);
|
||||
itemStack.set(DataComponents.BASE_COLOR, DyeColor.MAGENTA);
|
||||
RegistryAccess minecraftRegistry = CraftRegistry.getMinecraftRegistry();
|
||||
Registry<BannerPattern> bannerPatterns = minecraftRegistry.lookupOrThrow(Registries.BANNER_PATTERN);
|
||||
BannerPattern halfLeft = bannerPatterns.getOrThrow(BannerPatterns.HALF_VERTICAL).value();
|
||||
BannerPattern topLeft = bannerPatterns.getOrThrow(BannerPatterns.SQUARE_TOP_LEFT).value();
|
||||
BannerPattern topRight = bannerPatterns.getOrThrow(BannerPatterns.SQUARE_TOP_RIGHT).value();
|
||||
BannerPattern bottomLeft = bannerPatterns.getOrThrow(BannerPatterns.SQUARE_BOTTOM_LEFT).value();
|
||||
BannerPattern bottomRight = bannerPatterns.getOrThrow(BannerPatterns.SQUARE_BOTTOM_RIGHT).value();
|
||||
itemStack.set(DataComponents.BANNER_PATTERNS,
|
||||
new BannerPatternLayers(List.of(
|
||||
new BannerPatternLayers.Layer(bannerPatterns.wrapAsHolder(halfLeft), DyeColor.BLACK),
|
||||
new BannerPatternLayers.Layer(bannerPatterns.wrapAsHolder(topLeft), DyeColor.MAGENTA),
|
||||
new BannerPatternLayers.Layer(bannerPatterns.wrapAsHolder(bottomLeft), DyeColor.MAGENTA),
|
||||
new BannerPatternLayers.Layer(bannerPatterns.wrapAsHolder(topRight), DyeColor.BLACK),
|
||||
new BannerPatternLayers.Layer(bannerPatterns.wrapAsHolder(bottomRight), DyeColor.BLACK))));
|
||||
itemStack.set(DataComponents.HIDE_TOOLTIP, Unit.INSTANCE);
|
||||
itemStack.set(DataComponents.CUSTOM_MODEL_DATA, DEFAULT_CUSTOM_MODEL_DATA);
|
||||
return itemStack;
|
||||
}
|
||||
|
||||
private static ItemStack defaultNotSlot() {
|
||||
// White pane with no tooltip
|
||||
ItemStack itemStack = new ItemStack(Items.WHITE_STAINED_GLASS_PANE);
|
||||
itemStack.set(DataComponents.HIDE_TOOLTIP, Unit.INSTANCE);
|
||||
itemStack.set(DataComponents.CUSTOM_MODEL_DATA, DEFAULT_CUSTOM_MODEL_DATA);
|
||||
return itemStack;
|
||||
}
|
||||
|
||||
private static ItemStack defaultBlockedOffline() {
|
||||
// Barrier: "Not available - Offline"
|
||||
ItemStack itemStack = new ItemStack(Items.BARRIER);
|
||||
itemStack.set(DataComponents.ITEM_NAME,
|
||||
Component.translatable("options.narrator.notavailable")
|
||||
.append(Component.literal(" - "))
|
||||
.append(Component.translatable("gui.socialInteractions.status_offline")));
|
||||
return itemStack;
|
||||
}
|
||||
|
||||
private Placeholders() {
|
||||
throw new IllegalStateException("Cannot create instance of utility class.");
|
||||
}
|
||||
|
||||
}
|
||||
-172
@@ -1,172 +0,0 @@
|
||||
package com.lishid.openinv.internal.v1_21_R3.container.bukkit;
|
||||
|
||||
import com.lishid.openinv.internal.ViewOnly;
|
||||
import net.minecraft.world.Container;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.craftbukkit.v1_21_R3.inventory.CraftInventory;
|
||||
import org.bukkit.event.inventory.InventoryType;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.ListIterator;
|
||||
|
||||
/**
|
||||
* A locked down "empty" inventory that rejects plugin interaction.
|
||||
*/
|
||||
public class OpenDummyInventory extends CraftInventory implements ViewOnly {
|
||||
|
||||
private final InventoryType type;
|
||||
|
||||
public OpenDummyInventory(Container inventory, InventoryType type) {
|
||||
super(inventory);
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull InventoryType getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable ItemStack getItem(int index) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setItem(int index, @Nullable ItemStack item) {
|
||||
|
||||
}
|
||||
|
||||
@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) {
|
||||
ignored.put(index, items[index]);
|
||||
}
|
||||
return ignored;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack[] getContents() {
|
||||
return new ItemStack[getSize()];
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setContents(@NotNull ItemStack[] items) throws IllegalArgumentException {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull ItemStack[] getStorageContents() {
|
||||
return new ItemStack[getSize()];
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setStorageContents(@NotNull ItemStack[] items) throws IllegalArgumentException {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean contains(@NotNull Material material) throws IllegalArgumentException {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean contains(@Nullable ItemStack item) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean contains(@NotNull Material material, int amount) throws IllegalArgumentException {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean contains(@Nullable ItemStack item, int amount) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean containsAtLeast(@Nullable ItemStack item, int amount) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@SuppressWarnings("NonApiType")
|
||||
@Override
|
||||
public @NotNull HashMap<Integer, ItemStack> all(
|
||||
@NotNull Material material) throws IllegalArgumentException {
|
||||
return new HashMap<>();
|
||||
}
|
||||
|
||||
@SuppressWarnings("NonApiType")
|
||||
@Override
|
||||
public @NotNull HashMap<Integer, ItemStack> all(@Nullable ItemStack item) {
|
||||
return new HashMap<>();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int first(@NotNull Material material) throws IllegalArgumentException {
|
||||
return -1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int first(@NotNull ItemStack item) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int firstEmpty() {
|
||||
return -1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEmpty() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void remove(@NotNull Material material) throws IllegalArgumentException {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void remove(@NotNull ItemStack item) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clear(int index) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clear() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull ListIterator<ItemStack> iterator() {
|
||||
return Collections.emptyListIterator();
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull ListIterator<ItemStack> iterator(int index) {
|
||||
return Collections.emptyListIterator();
|
||||
}
|
||||
|
||||
}
|
||||
-134
@@ -1,134 +0,0 @@
|
||||
package com.lishid.openinv.internal.v1_21_R3.container.bukkit;
|
||||
|
||||
import net.minecraft.world.Container;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.entity.HumanEntity;
|
||||
import org.bukkit.event.inventory.InventoryType;
|
||||
import org.bukkit.inventory.EquipmentSlot;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.PlayerInventory;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public class OpenDummyPlayerInventory extends OpenDummyInventory implements PlayerInventory {
|
||||
|
||||
public OpenDummyPlayerInventory(Container inventory) {
|
||||
super(inventory, InventoryType.PLAYER);
|
||||
}
|
||||
|
||||
@Override
|
||||
public HumanEntity getHolder() {
|
||||
return (HumanEntity) super.getHolder();
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull ItemStack[] getArmorContents() {
|
||||
return new ItemStack[4];
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull ItemStack[] getExtraContents() {
|
||||
return new ItemStack[4];
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable ItemStack getHelmet() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable ItemStack getChestplate() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable ItemStack getLeggings() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable ItemStack getBoots() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setItem(@NotNull EquipmentSlot slot, @Nullable ItemStack item) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable ItemStack getItem(@NotNull EquipmentSlot slot) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setArmorContents(@Nullable ItemStack[] items) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setExtraContents(@Nullable ItemStack[] items) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setHelmet(@Nullable ItemStack helmet) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setChestplate(@Nullable ItemStack chestplate) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setLeggings(@Nullable ItemStack leggings) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBoots(@Nullable ItemStack boots) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull ItemStack getItemInMainHand() {
|
||||
return new ItemStack(Material.AIR);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setItemInMainHand(@Nullable ItemStack item) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull ItemStack getItemInOffHand() {
|
||||
return new ItemStack(Material.AIR);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setItemInOffHand(@Nullable ItemStack item) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull ItemStack getItemInHand() {
|
||||
return new ItemStack(Material.AIR);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setItemInHand(@Nullable ItemStack stack) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getHeldItemSlot() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setHeldItemSlot(int slot) {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
-69
@@ -1,69 +0,0 @@
|
||||
package com.lishid.openinv.internal.v1_21_R3.container.slot;
|
||||
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.world.Container;
|
||||
import net.minecraft.world.inventory.Slot;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* An interface defining behaviors for entries in a {@link Container}. Used to reduce duplicate content reordering.
|
||||
*/
|
||||
public interface Content {
|
||||
|
||||
/**
|
||||
* Update internal holder.
|
||||
*
|
||||
* @param holder the new holder
|
||||
*/
|
||||
void setHolder(@NotNull ServerPlayer holder);
|
||||
|
||||
/**
|
||||
* Get the current item.
|
||||
*
|
||||
* @return the current item
|
||||
*/
|
||||
ItemStack get();
|
||||
|
||||
/**
|
||||
* Remove the current item.
|
||||
*
|
||||
* @return the current item
|
||||
*/
|
||||
ItemStack remove();
|
||||
|
||||
/**
|
||||
* Remove some of the current item.
|
||||
*
|
||||
* @return the current item
|
||||
*/
|
||||
ItemStack removePartial(int amount);
|
||||
|
||||
/**
|
||||
* Set the current item. If slot is currently not usable, will drop item instead.
|
||||
*
|
||||
* @param itemStack the item to set
|
||||
*/
|
||||
void set(ItemStack itemStack);
|
||||
|
||||
/**
|
||||
* Get a {@link Slot} for use in a {@link net.minecraft.world.inventory.AbstractContainerMenu ContainerMenu}. Will
|
||||
* impose any specific restrictions to insertion or removal.
|
||||
*
|
||||
* @param container the backing container
|
||||
* @param slot the slot of the backing container represented
|
||||
* @param x clientside x dimension from top left of inventory, not used
|
||||
* @param y clientside y dimension from top left of inventory, not used
|
||||
* @return a menu slot
|
||||
*/
|
||||
Slot asSlot(Container container, int slot, int x, int y);
|
||||
|
||||
/**
|
||||
* Get a loose Bukkit translation of what this slot stores. For example, any slot that drops items at the owner rather
|
||||
* than insert them will report itself as being {@link org.bukkit.event.inventory.InventoryType.SlotType#OUTSIDE}.
|
||||
*
|
||||
* @return the closes Bukkit slot type
|
||||
*/
|
||||
org.bukkit.event.inventory.InventoryType.SlotType getSlotType();
|
||||
|
||||
}
|
||||
-131
@@ -1,131 +0,0 @@
|
||||
package com.lishid.openinv.internal.v1_21_R3.container.slot;
|
||||
|
||||
import com.lishid.openinv.internal.v1_21_R3.container.Placeholders;
|
||||
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.inventory.Slot;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import org.bukkit.event.inventory.InventoryType;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* A slot in a survival crafting inventory. Unavailable when not online in a survival mode.
|
||||
*/
|
||||
public class ContentCrafting implements Content {
|
||||
|
||||
private final int index;
|
||||
private ServerPlayer holder;
|
||||
private List<ItemStack> items;
|
||||
|
||||
public ContentCrafting(@NotNull ServerPlayer holder, int index) {
|
||||
setHolder(holder);
|
||||
this.index = index;
|
||||
}
|
||||
|
||||
private boolean isAvailable() {
|
||||
return isAvailable(holder);
|
||||
}
|
||||
|
||||
static boolean isAvailable(@NotNull ServerPlayer holder) {
|
||||
// Player must be online and not in creative - since the creative client is (semi-)authoritative,
|
||||
// it ignores changes without extra help, and will delete the item as a result.
|
||||
// Spectator mode is technically possible but may cause the item to be dropped if the client opens an inventory.
|
||||
return holder.connection != null && !holder.connection.isDisconnected() && holder.gameMode.isSurvival();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setHolder(@NotNull ServerPlayer holder) {
|
||||
this.holder = holder;
|
||||
// Note: CraftingContainer#getItems is immutable! Be careful with updates.
|
||||
this.items = holder.inventoryMenu.getCraftSlots().getContents();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack get() {
|
||||
return isAvailable() ? items.get(index) : ItemStack.EMPTY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack remove() {
|
||||
if (!this.isAvailable()) {
|
||||
return ItemStack.EMPTY;
|
||||
}
|
||||
ItemStack removed = items.remove(index);
|
||||
if (removed.isEmpty()) {
|
||||
return ItemStack.EMPTY;
|
||||
}
|
||||
holder.inventoryMenu.slotsChanged(holder.inventoryMenu.getCraftSlots());
|
||||
return removed;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack removePartial(int amount) {
|
||||
if (!this.isAvailable()) {
|
||||
return ItemStack.EMPTY;
|
||||
}
|
||||
ItemStack removed = ContainerHelper.removeItem(items, index, amount);
|
||||
if (removed.isEmpty()) {
|
||||
return ItemStack.EMPTY;
|
||||
}
|
||||
holder.inventoryMenu.slotsChanged(holder.inventoryMenu.getCraftSlots());
|
||||
return removed;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void set(ItemStack itemStack) {
|
||||
if (isAvailable()) {
|
||||
items.set(index, itemStack);
|
||||
holder.inventoryMenu.slotsChanged(holder.inventoryMenu.getCraftSlots());
|
||||
} else {
|
||||
holder.drop(itemStack, false);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Slot asSlot(Container container, int slot, int x, int y) {
|
||||
return new SlotCrafting(container, slot, x, y);
|
||||
}
|
||||
|
||||
@Override
|
||||
public InventoryType.SlotType getSlotType() {
|
||||
return isAvailable() ? InventoryType.SlotType.CRAFTING : InventoryType.SlotType.OUTSIDE;
|
||||
}
|
||||
|
||||
public class SlotCrafting extends SlotPlaceholder {
|
||||
|
||||
private SlotCrafting(Container container, int index, int x, int y) {
|
||||
super(container, index, x, y);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack getOrDefault() {
|
||||
return isAvailable() ? items.get(ContentCrafting.this.index) : Placeholders.survivalOnly(holder);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean mayPickup(Player player) {
|
||||
return isAvailable();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean mayPlace(ItemStack itemStack) {
|
||||
return isAvailable();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasItem() {
|
||||
return isAvailable() && super.hasItem();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFake() {
|
||||
return !isAvailable();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
-117
@@ -1,117 +0,0 @@
|
||||
package com.lishid.openinv.internal.v1_21_R3.container.slot;
|
||||
|
||||
import com.lishid.openinv.internal.v1_21_R3.container.Placeholders;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.world.Container;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraft.world.inventory.Slot;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import org.bukkit.event.inventory.InventoryType;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* A slot wrapping the active menu's cursor. Unavailable when not online in a survival mode.
|
||||
*/
|
||||
public class ContentCursor implements Content {
|
||||
|
||||
private @NotNull ServerPlayer holder;
|
||||
|
||||
public ContentCursor(@NotNull ServerPlayer holder) {
|
||||
this.holder = holder;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setHolder(@NotNull ServerPlayer holder) {
|
||||
this.holder = holder;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack get() {
|
||||
return isAvailable() ? holder.containerMenu.getCarried() : ItemStack.EMPTY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack remove() {
|
||||
ItemStack carried = holder.containerMenu.getCarried();
|
||||
holder.containerMenu.setCarried(ItemStack.EMPTY);
|
||||
return carried;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack removePartial(int amount) {
|
||||
ItemStack carried = holder.containerMenu.getCarried();
|
||||
if (!carried.isEmpty() && carried.getCount() >= amount) {
|
||||
ItemStack value = carried.split(amount);
|
||||
if (carried.isEmpty()) {
|
||||
holder.containerMenu.setCarried(ItemStack.EMPTY);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
return ItemStack.EMPTY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void set(ItemStack itemStack) {
|
||||
if (isAvailable()) {
|
||||
holder.containerMenu.setCarried(itemStack);
|
||||
} else {
|
||||
holder.drop(itemStack, false);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isAvailable() {
|
||||
// Player must be online and not in creative - since the creative client is (semi-)authoritative,
|
||||
// it ignores changes without extra help, and will delete the item as a result.
|
||||
// Spectator mode is technically possible but may cause the item to be dropped if the client opens an inventory.
|
||||
return holder.connection != null && !holder.connection.isDisconnected() && holder.gameMode.isSurvival();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Slot asSlot(Container container, int slot, int x, int y) {
|
||||
return new SlotCursor(container, slot, x, y);
|
||||
}
|
||||
|
||||
@Override
|
||||
public InventoryType.SlotType getSlotType() {
|
||||
// As close as possible to "not real"
|
||||
return InventoryType.SlotType.OUTSIDE;
|
||||
}
|
||||
|
||||
public class SlotCursor extends SlotPlaceholder {
|
||||
|
||||
private SlotCursor(Container container, int index, int x, int y) {
|
||||
super(container, index, x, y);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack getOrDefault() {
|
||||
if (!isAvailable()) {
|
||||
return Placeholders.survivalOnly(holder);
|
||||
}
|
||||
ItemStack carried = holder.containerMenu.getCarried();
|
||||
return carried.isEmpty() ? Placeholders.cursor : carried;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean mayPickup(Player player) {
|
||||
return isAvailable();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean mayPlace(ItemStack itemStack) {
|
||||
return isAvailable();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasItem() {
|
||||
return isAvailable() && super.hasItem();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFake() {
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
Loaded 100 of 160 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user