Skip to content
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
Original file line number Diff line number Diff line change
Expand Up @@ -37,15 +37,6 @@
import com.leonardobishop.quests.bukkit.hook.vault.AbstractVaultHook;
import com.leonardobishop.quests.bukkit.hook.vault.VaultHook;
import com.leonardobishop.quests.bukkit.hook.versionspecific.VersionSpecificHandler;
import com.leonardobishop.quests.bukkit.hook.versionspecific.VersionSpecificHandler11;
import com.leonardobishop.quests.bukkit.hook.versionspecific.VersionSpecificHandler12;
import com.leonardobishop.quests.bukkit.hook.versionspecific.VersionSpecificHandler14;
import com.leonardobishop.quests.bukkit.hook.versionspecific.VersionSpecificHandler16;
import com.leonardobishop.quests.bukkit.hook.versionspecific.VersionSpecificHandler17;
import com.leonardobishop.quests.bukkit.hook.versionspecific.VersionSpecificHandler20;
import com.leonardobishop.quests.bukkit.hook.versionspecific.VersionSpecificHandler21;
import com.leonardobishop.quests.bukkit.hook.versionspecific.VersionSpecificHandler8;
import com.leonardobishop.quests.bukkit.hook.versionspecific.VersionSpecificHandler9;
import com.leonardobishop.quests.bukkit.hook.wildstacker.AbstractWildStackerHook;
import com.leonardobishop.quests.bukkit.hook.wildstacker.WildStackerHook;
import com.leonardobishop.quests.bukkit.item.ParsedQuestItem;
Expand Down Expand Up @@ -163,6 +154,7 @@
import com.leonardobishop.quests.common.tasktype.TaskType;
import com.leonardobishop.quests.common.tasktype.TaskTypeManager;
import com.leonardobishop.quests.common.updater.Updater;
import com.leonardobishop.quests.common.versioning.Version;
import com.mojang.authlib.GameProfile;
import net.md_5.bungee.api.ChatMessageType;
import net.md_5.bungee.api.chat.BaseComponent;
Expand Down Expand Up @@ -328,20 +320,6 @@ public void onEnable() {
e.printStackTrace();
}

// Setup version specific compatibility layers
int version;
try {
version = this.getServerVersion();
this.questsLogger.info("Your server is running version 1." + version);
} catch (final IllegalArgumentException e) {
// all server supported versions by Quests fulfill this format,
// so we assume that some future version can possibly break it,
// and we want to load the latest and not the oldest handler
version = Integer.MAX_VALUE;

this.questsLogger.warning("Failed to resolve server version - some features may not work! (" + e.getMessage() + ")");
}

// (titles)
this.setTitleHandle();

Expand All @@ -357,22 +335,23 @@ public void onEnable() {
// (skulls)
this.setSkullGetter();

// (version specific handler)
if (version <= 8) {
this.versionSpecificHandler = new VersionSpecificHandler8();
} else {
this.versionSpecificHandler = switch (version) {
case 9, 10 -> new VersionSpecificHandler9();
case 11 -> new VersionSpecificHandler11();
case 12, 13 -> new VersionSpecificHandler12();
case 14, 15 -> new VersionSpecificHandler14();
case 16 -> new VersionSpecificHandler16();
case 17, 18, 19 -> new VersionSpecificHandler17();
case 20 -> new VersionSpecificHandler20();
default -> new VersionSpecificHandler21();
};
// Resolve server version
Version serverVersion;
try {
serverVersion = Version.fromString(Bukkit.getBukkitVersion());
this.questsLogger.info("Your server is running version " + serverVersion);
} catch (final IllegalArgumentException e) {
// all server versions supported by Quests fulfill this format,
// so we assume that some future version can possibly break it,
// and we want to load the latest and not the oldest handler
serverVersion = Version.UNKNOWN;
this.questsLogger.warning("Failed to resolve server version - some features may not work! (" + e.getMessage() + ")");
}

// Set the latest supported version specific handler
this.versionSpecificHandler = VersionSpecificHandler.getImplementation(serverVersion);
this.questsLogger.info("Using " + this.versionSpecificHandler.getClass().getSimpleName() + " for version compatibility!");

// Instantiate Projectile to ItemStack cache
this.projectile2ItemCache = new Projectile2ItemCache();
this.projectile2ItemCache.registerEvents(this);
Expand Down Expand Up @@ -574,28 +553,6 @@ public void onEnable() {
});
}

/**
* Gets the server minor version.
*
* @return the server minor version
* @throws IllegalArgumentException with message set to the bukkit version if it could not be parsed successfully.
*/
private int getServerVersion() throws IllegalArgumentException {
final String bukkitVersion = this.getServer().getBukkitVersion();

final String[] bukkitVersionParts = bukkitVersion.split("\\.", 3);
if (bukkitVersionParts.length < 2) {
throw new IllegalArgumentException(bukkitVersion, new ArrayIndexOutOfBoundsException(bukkitVersionParts.length));
}

final String minorVersionPart = bukkitVersionParts[1].split("-")[0];
try {
return Integer.parseInt(minorVersionPart);
} catch (final NumberFormatException e) {
throw new IllegalArgumentException(bukkitVersion, e);
}
}

/**
* Gets the tasks registration message.
*
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.leonardobishop.quests.bukkit.hook.versionspecific;

import com.leonardobishop.quests.common.versioning.Version;
import org.bukkit.Keyed;
import org.bukkit.Material;
import org.bukkit.Tag;
Expand All @@ -9,6 +10,7 @@
import org.bukkit.damage.DamageSource;
import org.bukkit.entity.AbstractHorse;
import org.bukkit.entity.Camel;
import org.bukkit.entity.CamelHusk;
import org.bukkit.entity.Donkey;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Goat;
Expand All @@ -34,19 +36,60 @@
import org.bukkit.inventory.SmithingInventory;
import org.bukkit.inventory.SmithingTransformRecipe;
import org.bukkit.inventory.SmithingTrimRecipe;
import org.jspecify.annotations.NullMarked;
import org.jspecify.annotations.Nullable;

import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.NavigableSet;
import java.util.Objects;
import java.util.TreeSet;

/**
* Interface used for implementing version-specific features.
* All information about changes in the API should be documented HERE in the method docs.
*/
@SuppressWarnings({"deprecation", "BooleanMethodIsAlwaysInverted"})
@NullMarked
public interface VersionSpecificHandler {

NavigableSet<Version> IMPLEMENTATIONS = Collections.unmodifiableNavigableSet(new TreeSet<>() {{
this.add(Version.V1_8);
this.add(Version.V1_9);
this.add(Version.V1_11);
this.add(Version.V1_11_2);
this.add(Version.V1_14);
this.add(Version.V1_15_2);
this.add(Version.V1_16);
this.add(Version.V1_17);
this.add(Version.V1_19_2);
this.add(Version.V1_20);
this.add(Version.V1_20_4);
this.add(Version.V1_21_6);
this.add(Version.V1_21_11);
}});

static VersionSpecificHandler getImplementation(final Version serverVersion) {
final Version matchedVersion = Objects.requireNonNullElseGet(
IMPLEMENTATIONS.floor(serverVersion),
IMPLEMENTATIONS::first
);

final String clazzName = String.format("%s_%s",
VersionSpecificHandler.class.getCanonicalName(),
matchedVersion.toClassNameString()
);

try {
return (VersionSpecificHandler) Class.forName(clazzName).getConstructor().newInstance();
} catch (final ReflectiveOperationException e) {
throw new IllegalStateException("Failed to construct version specific handler", e);
}
}

@SuppressWarnings("unused")
int getMinecraftVersion();
Version getMinecraftVersion();

/**
* Elytra were introduced in {@code 1.9}.
Expand All @@ -62,6 +105,13 @@ public interface VersionSpecificHandler {
*/
boolean isPlayerOnCamel(Player player);

/**
* Camel Husks were introduced in {@code 1.21.11}.
*
* @see CamelHusk
*/
boolean isPlayerOnCamelHusk(Player player);

/**
* Donkeys were introduced in {@code 1.6.1}.
*
Expand All @@ -72,6 +122,7 @@ public interface VersionSpecificHandler {
* in modern versions is {@link Donkey}.
* </p>
*/
@SuppressWarnings("removal")
boolean isPlayerOnDonkey(Player player);

/**
Expand All @@ -91,6 +142,7 @@ public interface VersionSpecificHandler {
* in modern versions is {@link Horse}.
* </p>
*/
@SuppressWarnings("removal")
boolean isPlayerOnHorse(Player player);

/**
Expand All @@ -110,6 +162,7 @@ public interface VersionSpecificHandler {
* in modern versions is {@link Mule}.
* </p>
*/
@SuppressWarnings("removal")
boolean isPlayerOnMule(Player player);

/**
Expand All @@ -129,6 +182,7 @@ public interface VersionSpecificHandler {
* interface in modern versions is {@link SkeletonHorse}.
* </p>
*/
@SuppressWarnings("removal")
boolean isPlayerOnSkeletonHorse(Player player);

/**
Expand All @@ -148,6 +202,7 @@ public interface VersionSpecificHandler {
* interface in modern versions is {@link ZombieHorse}.
* </p>
*/
@SuppressWarnings("removal")
boolean isPlayerOnZombieHorse(Player player);

/**
Expand All @@ -162,6 +217,36 @@ public interface VersionSpecificHandler {
*/
boolean isOffHandEmpty(Player player);

/**
* Initially, the proper method to get an inventory contents except armor and other extra slots
* (not allowing player to store results of crafting actions) was {@link PlayerInventory#getContents()}.
* In {@code 1.9} {@link PlayerInventory#getStorageContents()} method was introduced superseding the old
* one. In newer versions {@link PlayerInventory#getContents()} method returns all the items including
* the extra slots of player inventories.
*
* @apiNote This method is intended to be used as a check for item crafting related task types.
* @see VersionSpecificHandler#getStorageContents(PlayerInventory)
*/
default int getAvailableSpace(Player player, ItemStack item) {
PlayerInventory inventory = player.getInventory();
HashMap<Integer, ? extends ItemStack> itemsOfType = inventory.all(item.getType());
int availableSpace = 0;

for (ItemStack existingItem : itemsOfType.values()) {
if (item.isSimilar(existingItem)) {
availableSpace += (item.getMaxStackSize() - existingItem.getAmount());
}
}

for (ItemStack existingItem : this.getStorageContents(inventory)) {
if (existingItem == null) {
availableSpace += item.getMaxStackSize();
}
}

return availableSpace;
}

/**
* Initially, the proper method to get an inventory contents except armor and other extra slots
* (not allowing player to store results of crafting actions) was {@link PlayerInventory#getContents()}.
Expand All @@ -171,7 +256,7 @@ public interface VersionSpecificHandler {
*
* @apiNote This method is intended to be used as a check for item crafting related task types.
*/
int getAvailableSpace(Player player, ItemStack newItemStack);
@Nullable ItemStack[] getStorageContents(PlayerInventory inventory);

/**
* Initially, clicking with a number key on a crafting result made the item go to the selected slot.
Expand Down Expand Up @@ -200,7 +285,7 @@ public interface VersionSpecificHandler {
* to get specified equipment slot item still hasn't existed. In {@code 1.15.2} the method was finally introduced
* {@link PlayerInventory#getItem(EquipmentSlot)} making us able to no longer maintain this one.
*/
ItemStack getItemInEquipmentSlot(PlayerInventory inventory, EquipmentSlot slot);
@Nullable ItemStack getItemInEquipmentSlot(PlayerInventory inventory, EquipmentSlot slot);

/**
* Dual-wielding system was introduced in {@code 1.9}.
Expand All @@ -212,7 +297,7 @@ public interface VersionSpecificHandler {
/**
* Dual-wielding system was introduced in {@code 1.9}.
*/
EquipmentSlot getHand(PlayerInteractEvent event);
@Nullable EquipmentSlot getHand(PlayerInteractEvent event);

/**
* Dual-wielding system was introduced in {@code 1.9}.
Expand All @@ -224,14 +309,14 @@ public interface VersionSpecificHandler {
* and {@link SmithingInventory#getInputMineral()}. In {@code 1.20} the feature was extended to support templates.
* Due to the following reason, new method was added: {@link SmithingInventory#getInputTemplate()}.
*/
ItemStack[] getSmithItems(SmithItemEvent event);
@Nullable ItemStack[] getSmithItems(SmithItemEvent event);

/**
* Items smithing system was introduced in {@code 1.16} with {@link SmithingTransformRecipe}.
* In {@code 1.20} the feature was extended to support templates. Due to the following reason,
* new class has been added {@link SmithingTrimRecipe}.
*/
String getSmithMode(SmithItemEvent event);
@Nullable String getSmithMode(SmithItemEvent event);

/**
* Goats were introduced in {@code 1.17}.
Expand Down

This file was deleted.

This file was deleted.

Loading