Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support Minecraft 1.20.x and 1.21.x #287

Merged
merged 4 commits into from
Feb 20, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
java: [ '11', '17' ]
java: [ '21' ]
name: Build with Java ${{ matrix.java }}
steps:
- name: Checkout Git repository
Expand Down Expand Up @@ -70,11 +70,11 @@ jobs:
key: ${{ runner.os }}-sonar
restore-keys: ${{ runner.os }}-sonar

- name: Setup JDK 17
- name: Setup JDK 21
uses: actions/setup-java@v4
with:
distribution: adopt
java-version: 17
java-version: 21

- name: Build with Gradle
run: |
Expand Down
8 changes: 4 additions & 4 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,18 +20,18 @@ jobs:
fetch-depth: 0

- name: Restore Gradle cache
uses: actions/cache@v3
uses: actions/cache@v4
with:
path: ~/.gradle/caches
key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*') }}
restore-keys: |
${{ runner.os }}-gradle-

- name: Setup JDK 17
uses: actions/setup-java@v3
- name: Setup JDK 21
uses: actions/setup-java@v4
with:
distribution: adopt
java-version: 17
java-version: 21

- name: Validate Gradle Wrapper
uses: gradle/wrapper-validation-action@v1
Expand Down
8 changes: 4 additions & 4 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,18 +14,18 @@ jobs:
fetch-depth: 0

- name: Restore Gradle cache
uses: actions/cache@v2
uses: actions/cache@v4
with:
path: ~/.gradle/caches
key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*') }}
restore-keys: |
${{ runner.os }}-gradle-

- name: Setup JDK 17
uses: actions/setup-java@v2
- name: Setup JDK 21
uses: actions/setup-java@v4
with:
distribution: adopt
java-version: 17
java-version: 21

- name: Validate Gradle Wrapper
uses: gradle/wrapper-validation-action@v1
Expand Down
2 changes: 1 addition & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,5 +43,5 @@ Maybe the usage of [`git rebase`](http://learn.github.com/p/rebasing.html) could
Requirements
------------

- Java 11+
- Java 21+
- Gradle 8+
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
<h4 align="center">
A modern Bukkit plugin to divide enderchest into multiple inventories.
<br>
Works with Bukkit/Spigot 1.8 to 1.20!
Works with Bukkit/Spigot 1.8 to 1.21!
</h4>

<p align="center">
Expand Down Expand Up @@ -52,7 +52,7 @@ Works with Bukkit/Spigot 1.8 to 1.20!
|-----------|------------------------------|-------------|----------------------------------------------------------------------------------------------|
| 2.2.2 | 1.8 to 1.17 | Stable | [Click here](https://www.spigotmc.org/resources/endercontainers.4750/) |
| 2.2.3-dev | 1.8 to 1.20 | Beta | [Click here](https://utarwyn.fr/projects/EnderContainers/EnderContainers-2.2.3-SNAPSHOT.jar) |
| 2.3.0-dev | 1.8 to 1.20 | Development | [Click here](https://utarwyn.fr/projects/EnderContainers/EnderContainers-2.3.0-SNAPSHOT.jar) |
| 2.3.0-dev | 1.8 to 1.21 | Development | [Click here](https://utarwyn.fr/projects/EnderContainers/EnderContainers-2.3.0-SNAPSHOT.jar) |


## Technical Features
Expand Down
8 changes: 4 additions & 4 deletions buildSrc/src/main/groovy/fr.utarwyn.java-conventions.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,13 @@ configurations {
}

dependencies {
compileOnly 'org.spigotmc:spigot-api:1.20-R0.1-SNAPSHOT'
compileOnly 'org.spigotmc:spigot-api:1.20-R0.1-SNAPSHOT' // cannot upgrade due to Inventory errors

testImplementation platform('org.junit:junit-bom:5.10.1')
testImplementation 'org.junit.jupiter:junit-jupiter'
testImplementation 'org.mockito:mockito-core:4.11.0' // cannot upgrade to 5+ because of Java 8 compatibility
testImplementation 'org.mockito:mockito-junit-jupiter:4.11.0'
testImplementation 'org.assertj:assertj-core:3.24.2'
testImplementation 'org.mockito:mockito-core:5.15.2'
testImplementation 'org.mockito:mockito-junit-jupiter:5.15.2'
testImplementation 'org.assertj:assertj-core:3.27.3'
}

publishing {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package fr.utarwyn.endercontainers.compatibility;

import fr.utarwyn.endercontainers.hologram.HologramException;
import org.bukkit.Location;
import org.bukkit.entity.Player;
import org.bukkit.plugin.Plugin;

/**
* Adapter interface for managing armor stands as holographic displays.
* This interface provides methods to spawn and destroy armor stands for specific players,
* typically used for version-specific implementations.
*
* @author Utarwyn
* @since 2.3.0
*/
public interface ArmorStandAdapter {

/**
* Spawns an armor stand with text at a specific location for a player.
*
* @param plugin the plugin instance
* @param observer the player who will see the armor stand
* @param location the location where to spawn the armor stand
* @param text the text to display above the armor stand
* @return the entity ID of the spawned armor stand
*/
int spawnArmorStandFor(Plugin plugin, Player observer, Location location, String text) throws HologramException;

/**
* Destroys an armor stand for a specific player.
*
* @param observer the player who can see the armor stand
* @param entityId the entity ID of the armor stand to destroy
*/
void destroyArmorStandFor(Player observer, int entityId) throws HologramException;

}
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package fr.utarwyn.endercontainers.compatibility;

import com.google.common.base.Preconditions;
import fr.utarwyn.endercontainers.compatibility.bukkit.BukkitArmorStandAdapter;
import fr.utarwyn.endercontainers.compatibility.nms.NMSArmorStandAdapter;
import org.bukkit.Material;
import org.bukkit.Sound;

Expand Down Expand Up @@ -63,4 +65,15 @@ public static Sound searchSound(String... names) throws IllegalArgumentException
});
}

/**
* Creates a new armor stand adapter instance based on the server version.
*
* @return a new armor stand adapter instance
*/
public static ArmorStandAdapter createArmorStandAdapter() {
return ServerVersion.isNewerThan(ServerVersion.V1_18)
? new BukkitArmorStandAdapter()
: new NMSArmorStandAdapter();
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
*/
public enum ServerVersion {

NEWER,
V1_20,
V1_19_R3,
V1_19_R2,
Expand All @@ -35,10 +36,15 @@ public enum ServerVersion {
String path = Bukkit.getServer().getClass().getPackage().getName();
BUKKIT_VERSION = path.substring(path.lastIndexOf('.') + 1);

for (ServerVersion version : values()) {
if (BUKKIT_VERSION.toUpperCase().startsWith(version.name())) {
currentVersion = version;
break;
// starting from 1.20.5, version is no more in package name
if ("craftbukkit".equals(BUKKIT_VERSION)) {
currentVersion = NEWER;
} else {
for (ServerVersion version : values()) {
if (BUKKIT_VERSION.toUpperCase().startsWith(version.name())) {
currentVersion = version;
break;
}
}
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package fr.utarwyn.endercontainers.compatibility.bukkit;

import fr.utarwyn.endercontainers.compatibility.ArmorStandAdapter;
import org.bukkit.Location;
import org.bukkit.entity.ArmorStand;
import org.bukkit.entity.Entity;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.Player;
import org.bukkit.plugin.Plugin;

import java.util.Objects;

public class BukkitArmorStandAdapter implements ArmorStandAdapter {

@Override
public int spawnArmorStandFor(Plugin plugin, Player observer, Location location, String text) {
ArmorStand armorStand = (ArmorStand) Objects.requireNonNull(location.getWorld()).spawnEntity(location.add(0, 2, 0), EntityType.ARMOR_STAND);

armorStand.setInvisible(true);
armorStand.setCustomName(text);
armorStand.setCustomNameVisible(true);
armorStand.setGravity(false);
armorStand.setInvulnerable(true);
armorStand.setMarker(true);

observer.showEntity(plugin, armorStand);

return armorStand.getEntityId();
}

@Override
public void destroyArmorStandFor(Player observer, int entityId) {
observer.getWorld().getEntities().stream()
.filter(e -> e.getEntityId() == entityId)
.findFirst()
.ifPresent(Entity::remove);

}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package fr.utarwyn.endercontainers.compatibility.nms;

import fr.utarwyn.endercontainers.compatibility.ArmorStandAdapter;
import fr.utarwyn.endercontainers.hologram.HologramException;
import org.bukkit.Location;
import org.bukkit.entity.Player;
import org.bukkit.plugin.Plugin;

/**
* Adapter for managing armor stands as holographic displays.
* This adapter provides methods to spawn and destroy armor stands for specific players.
* This adapter is used for NMS implementations prior MC 1.19.
*
* @author Utarwyn
* @since 2.3.0
*/
public class NMSArmorStandAdapter implements ArmorStandAdapter {

@Override
public int spawnArmorStandFor(Plugin plugin, Player observer, Location location, String text) throws HologramException {
try {
return NMSHologramUtil.get().spawnHologram(location, text, observer);
} catch (ReflectiveOperationException cause) {
throw new HologramException("cannot spawn hologram entity", cause);
}
}

@Override
public void destroyArmorStandFor(Player observer, int entityId) throws HologramException {
if (!observer.isOnline()) {
return;
}
try {
NMSHologramUtil.get().destroyEntity(entityId, observer);
} catch (ReflectiveOperationException cause) {
throw new HologramException("cannot destroy hologram entity", cause);
}
}

}
Loading