Mirror von
https://github.com/GeyserMC/Geyser.git
synchronisiert 2024-11-19 22:40:18 +01:00
Merge 'upstream/master' into feature/blocky
Signed-off-by: Joshua Castle <26531652+Kas-tle@users.noreply.github.com>
Dieser Commit ist enthalten in:
Commit
ac9ea6ff9b
@ -147,7 +147,7 @@ public final class Registries {
|
|||||||
/**
|
/**
|
||||||
* A registry holding all the potion mixes.
|
* A registry holding all the potion mixes.
|
||||||
*/
|
*/
|
||||||
public static final SimpleRegistry<Set<PotionMixData>> POTION_MIXES;
|
public static final VersionedRegistry<Set<PotionMixData>> POTION_MIXES;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A versioned registry holding all the recipes, with the net ID being the key, and {@link GeyserRecipe} as the value.
|
* A versioned registry holding all the recipes, with the net ID being the key, and {@link GeyserRecipe} as the value.
|
||||||
@ -185,7 +185,7 @@ public final class Registries {
|
|||||||
RecipeRegistryPopulator.populate();
|
RecipeRegistryPopulator.populate();
|
||||||
|
|
||||||
// Create registries that require other registries to load first
|
// Create registries that require other registries to load first
|
||||||
POTION_MIXES = SimpleRegistry.create(PotionMixRegistryLoader::new);
|
POTION_MIXES = VersionedRegistry.create(PotionMixRegistryLoader::new);
|
||||||
ENCHANTMENTS = SimpleMappedRegistry.create("mappings/enchantments.json", EnchantmentRegistryLoader::new);
|
ENCHANTMENTS = SimpleMappedRegistry.create("mappings/enchantments.json", EnchantmentRegistryLoader::new);
|
||||||
|
|
||||||
// Remove unneeded client generation data from NbtMapBuilder
|
// Remove unneeded client generation data from NbtMapBuilder
|
||||||
|
@ -26,17 +26,18 @@
|
|||||||
package org.geysermc.geyser.registry.loader;
|
package org.geysermc.geyser.registry.loader;
|
||||||
|
|
||||||
import com.nukkitx.protocol.bedrock.data.inventory.PotionMixData;
|
import com.nukkitx.protocol.bedrock.data.inventory.PotionMixData;
|
||||||
|
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
|
||||||
|
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
|
||||||
import org.geysermc.geyser.inventory.item.Potion;
|
import org.geysermc.geyser.inventory.item.Potion;
|
||||||
import org.geysermc.geyser.network.GameProtocol;
|
|
||||||
import org.geysermc.geyser.registry.Registries;
|
import org.geysermc.geyser.registry.Registries;
|
||||||
import org.geysermc.geyser.registry.type.ItemMapping;
|
import org.geysermc.geyser.registry.type.ItemMapping;
|
||||||
|
import org.geysermc.geyser.registry.type.ItemMappings;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
//TODO this needs to be versioned, but the runtime item states between 1.17 and 1.17.10 are identical except for new blocks so this works for both
|
|
||||||
/**
|
/**
|
||||||
* Generates a collection of {@link PotionMixData} that enables the
|
* Generates a collection of {@link PotionMixData} that enables the
|
||||||
* Bedrock client to place brewing items into the brewing stand.
|
* Bedrock client to place brewing items into the brewing stand.
|
||||||
@ -46,64 +47,72 @@ import java.util.Set;
|
|||||||
* (Ex: Bedrock cannot normally place glass bottles or fully upgraded
|
* (Ex: Bedrock cannot normally place glass bottles or fully upgraded
|
||||||
* potions into the brewing stand, but Java can.)
|
* potions into the brewing stand, but Java can.)
|
||||||
*/
|
*/
|
||||||
public class PotionMixRegistryLoader implements RegistryLoader<Object, Set<PotionMixData>> {
|
public class PotionMixRegistryLoader implements RegistryLoader<Object, Int2ObjectMap<Set<PotionMixData>>> {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Set<PotionMixData> load(Object input) {
|
public Int2ObjectMap<Set<PotionMixData>> load(Object input) {
|
||||||
List<ItemMapping> ingredients = new ArrayList<>();
|
var allPotionMixes = new Int2ObjectOpenHashMap<Set<PotionMixData>>(Registries.ITEMS.get().size());
|
||||||
ingredients.add(getNonNull("minecraft:nether_wart"));
|
for (var entry : Registries.ITEMS.get().int2ObjectEntrySet()) {
|
||||||
ingredients.add(getNonNull("minecraft:redstone"));
|
ItemMappings mappings = entry.getValue();
|
||||||
ingredients.add(getNonNull("minecraft:glowstone_dust"));
|
List<ItemMapping> ingredients = new ArrayList<>();
|
||||||
ingredients.add(getNonNull("minecraft:fermented_spider_eye"));
|
ingredients.add(getNonNull(mappings, "minecraft:nether_wart"));
|
||||||
ingredients.add(getNonNull("minecraft:gunpowder"));
|
ingredients.add(getNonNull(mappings, "minecraft:redstone"));
|
||||||
ingredients.add(getNonNull("minecraft:dragon_breath"));
|
ingredients.add(getNonNull(mappings, "minecraft:glowstone_dust"));
|
||||||
ingredients.add(getNonNull("minecraft:sugar"));
|
ingredients.add(getNonNull(mappings, "minecraft:fermented_spider_eye"));
|
||||||
ingredients.add(getNonNull("minecraft:rabbit_foot"));
|
ingredients.add(getNonNull(mappings, "minecraft:gunpowder"));
|
||||||
ingredients.add(getNonNull("minecraft:glistering_melon_slice"));
|
ingredients.add(getNonNull(mappings, "minecraft:dragon_breath"));
|
||||||
ingredients.add(getNonNull("minecraft:spider_eye"));
|
ingredients.add(getNonNull(mappings, "minecraft:sugar"));
|
||||||
ingredients.add(getNonNull("minecraft:pufferfish"));
|
ingredients.add(getNonNull(mappings, "minecraft:rabbit_foot"));
|
||||||
ingredients.add(getNonNull("minecraft:magma_cream"));
|
ingredients.add(getNonNull(mappings, "minecraft:glistering_melon_slice"));
|
||||||
ingredients.add(getNonNull("minecraft:golden_carrot"));
|
ingredients.add(getNonNull(mappings, "minecraft:spider_eye"));
|
||||||
ingredients.add(getNonNull("minecraft:blaze_powder"));
|
ingredients.add(getNonNull(mappings, "minecraft:pufferfish"));
|
||||||
ingredients.add(getNonNull("minecraft:ghast_tear"));
|
ingredients.add(getNonNull(mappings, "minecraft:magma_cream"));
|
||||||
ingredients.add(getNonNull("minecraft:turtle_helmet"));
|
ingredients.add(getNonNull(mappings, "minecraft:golden_carrot"));
|
||||||
ingredients.add(getNonNull("minecraft:phantom_membrane"));
|
ingredients.add(getNonNull(mappings, "minecraft:blaze_powder"));
|
||||||
|
ingredients.add(getNonNull(mappings, "minecraft:ghast_tear"));
|
||||||
|
ingredients.add(getNonNull(mappings, "minecraft:turtle_helmet"));
|
||||||
|
ingredients.add(getNonNull(mappings, "minecraft:phantom_membrane"));
|
||||||
|
|
||||||
List<ItemMapping> inputs = new ArrayList<>();
|
List<ItemMapping> inputs = List.of(
|
||||||
inputs.add(getNonNull("minecraft:potion"));
|
getNonNull(mappings, "minecraft:potion"),
|
||||||
inputs.add(getNonNull("minecraft:splash_potion"));
|
getNonNull(mappings, "minecraft:splash_potion"),
|
||||||
inputs.add(getNonNull("minecraft:lingering_potion"));
|
getNonNull(mappings, "minecraft:lingering_potion")
|
||||||
|
);
|
||||||
|
|
||||||
ItemMapping glassBottle = getNonNull("minecraft:glass_bottle");
|
ItemMapping glassBottle = getNonNull(mappings, "minecraft:glass_bottle");
|
||||||
|
|
||||||
Set<PotionMixData> potionMixes = new HashSet<>();
|
Set<PotionMixData> potionMixes = new HashSet<>();
|
||||||
|
|
||||||
// Add all types of potions as inputs
|
// Add all types of potions as inputs
|
||||||
ItemMapping fillerIngredient = ingredients.get(0);
|
ItemMapping fillerIngredient = ingredients.get(0);
|
||||||
for (ItemMapping entryInput : inputs) {
|
for (ItemMapping entryInput : inputs) {
|
||||||
for (Potion potion : Potion.values()) {
|
for (Potion potion : Potion.VALUES) {
|
||||||
|
potionMixes.add(new PotionMixData(
|
||||||
|
entryInput.getBedrockId(), potion.getBedrockId(),
|
||||||
|
fillerIngredient.getBedrockId(), fillerIngredient.getBedrockData(),
|
||||||
|
glassBottle.getBedrockId(), glassBottle.getBedrockData())
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add all brewing ingredients
|
||||||
|
// Also adds glass bottle as input
|
||||||
|
for (ItemMapping ingredient : ingredients) {
|
||||||
potionMixes.add(new PotionMixData(
|
potionMixes.add(new PotionMixData(
|
||||||
entryInput.getBedrockId(), potion.getBedrockId(),
|
glassBottle.getBedrockId(), glassBottle.getBedrockData(),
|
||||||
fillerIngredient.getBedrockId(), fillerIngredient.getBedrockData(),
|
ingredient.getBedrockId(), ingredient.getBedrockData(),
|
||||||
glassBottle.getBedrockId(), glassBottle.getBedrockData())
|
glassBottle.getBedrockId(), glassBottle.getBedrockData())
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// Add all brewing ingredients
|
allPotionMixes.put(entry.getIntKey(), potionMixes);
|
||||||
// Also adds glass bottle as input
|
|
||||||
for (ItemMapping ingredient : ingredients) {
|
|
||||||
potionMixes.add(new PotionMixData(
|
|
||||||
glassBottle.getBedrockId(), glassBottle.getBedrockData(),
|
|
||||||
ingredient.getBedrockId(), ingredient.getBedrockData(),
|
|
||||||
glassBottle.getBedrockId(), glassBottle.getBedrockData())
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
return potionMixes;
|
allPotionMixes.trim();
|
||||||
|
return allPotionMixes;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static ItemMapping getNonNull(String javaIdentifier) {
|
private static ItemMapping getNonNull(ItemMappings mappings, String javaIdentifier) {
|
||||||
ItemMapping itemMapping = Registries.ITEMS.forVersion(GameProtocol.DEFAULT_BEDROCK_CODEC.getProtocolVersion()).getMapping(javaIdentifier);
|
ItemMapping itemMapping = mappings.getMapping(javaIdentifier);
|
||||||
if (itemMapping == null)
|
if (itemMapping == null)
|
||||||
throw new NullPointerException("No item entry exists for java identifier: " + javaIdentifier);
|
throw new NullPointerException("No item entry exists for java identifier: " + javaIdentifier);
|
||||||
|
|
||||||
|
@ -33,9 +33,9 @@ import lombok.Getter;
|
|||||||
import lombok.Setter;
|
import lombok.Setter;
|
||||||
import lombok.experimental.Accessors;
|
import lombok.experimental.Accessors;
|
||||||
|
|
||||||
|
import javax.annotation.Nonnull;
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Objects;
|
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
@Getter
|
@Getter
|
||||||
@ -46,7 +46,7 @@ public final class Team {
|
|||||||
|
|
||||||
@Getter(AccessLevel.PACKAGE)
|
@Getter(AccessLevel.PACKAGE)
|
||||||
private final Set<String> entities;
|
private final Set<String> entities;
|
||||||
@Setter @Nullable private NameTagVisibility nameTagVisibility;
|
@Nonnull private NameTagVisibility nameTagVisibility = NameTagVisibility.ALWAYS;
|
||||||
@Setter private TeamColor color;
|
@Setter private TeamColor color;
|
||||||
|
|
||||||
private final TeamData currentData;
|
private final TeamData currentData;
|
||||||
@ -189,11 +189,6 @@ public final class Team {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public boolean isVisibleFor(String entity) {
|
public boolean isVisibleFor(String entity) {
|
||||||
if (nameTagVisibility == null) {
|
|
||||||
// Null - normal behavior
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return switch (nameTagVisibility) {
|
return switch (nameTagVisibility) {
|
||||||
case HIDE_FOR_OTHER_TEAMS -> {
|
case HIDE_FOR_OTHER_TEAMS -> {
|
||||||
// Player must be in a team in order for HIDE_FOR_OTHER_TEAMS to be triggered
|
// Player must be in a team in order for HIDE_FOR_OTHER_TEAMS to be triggered
|
||||||
@ -206,8 +201,12 @@ public final class Team {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public NameTagVisibility getNameTagVisibility() {
|
public Team setNameTagVisibility(@Nullable NameTagVisibility nameTagVisibility) {
|
||||||
return Objects.requireNonNullElse(this.nameTagVisibility, NameTagVisibility.ALWAYS);
|
if (nameTagVisibility != null) {
|
||||||
|
// Null check like this (and this.nameTagVisibility defaults to ALWAYS) as of Java 1.19.4
|
||||||
|
this.nameTagVisibility = nameTagVisibility;
|
||||||
|
}
|
||||||
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -646,7 +646,7 @@ public class GeyserSession implements GeyserConnection, GeyserCommandSource {
|
|||||||
// Potion mixes are registered by default, as they are needed to be able to put ingredients into the brewing stand.
|
// Potion mixes are registered by default, as they are needed to be able to put ingredients into the brewing stand.
|
||||||
CraftingDataPacket craftingDataPacket = new CraftingDataPacket();
|
CraftingDataPacket craftingDataPacket = new CraftingDataPacket();
|
||||||
craftingDataPacket.setCleanRecipes(true);
|
craftingDataPacket.setCleanRecipes(true);
|
||||||
craftingDataPacket.getPotionMixData().addAll(Registries.POTION_MIXES.get());
|
craftingDataPacket.getPotionMixData().addAll(Registries.POTION_MIXES.forVersion(this.upstream.getProtocolVersion()));
|
||||||
upstream.sendPacket(craftingDataPacket);
|
upstream.sendPacket(craftingDataPacket);
|
||||||
|
|
||||||
PlayStatusPacket playStatusPacket = new PlayStatusPacket();
|
PlayStatusPacket playStatusPacket = new PlayStatusPacket();
|
||||||
@ -1704,6 +1704,8 @@ public class GeyserSession implements GeyserConnection, GeyserCommandSource {
|
|||||||
abilities.add(Ability.MINE);
|
abilities.add(Ability.MINE);
|
||||||
// Needed so you can drop items
|
// Needed so you can drop items
|
||||||
abilities.add(Ability.DOORS_AND_SWITCHES);
|
abilities.add(Ability.DOORS_AND_SWITCHES);
|
||||||
|
// Required for lecterns to work (likely started around 1.19.10; confirmed on 1.19.70)
|
||||||
|
abilities.add(Ability.OPEN_CONTAINERS);
|
||||||
if (gameMode == GameMode.CREATIVE) {
|
if (gameMode == GameMode.CREATIVE) {
|
||||||
// Needed so the client doesn't attempt to take away items
|
// Needed so the client doesn't attempt to take away items
|
||||||
abilities.add(Ability.INSTABUILD);
|
abilities.add(Ability.INSTABUILD);
|
||||||
|
@ -88,7 +88,7 @@ public abstract class InventoryTranslator {
|
|||||||
put(ContainerType.LOOM, new LoomInventoryTranslator());
|
put(ContainerType.LOOM, new LoomInventoryTranslator());
|
||||||
put(ContainerType.MERCHANT, new MerchantInventoryTranslator());
|
put(ContainerType.MERCHANT, new MerchantInventoryTranslator());
|
||||||
put(ContainerType.SHULKER_BOX, new ShulkerInventoryTranslator());
|
put(ContainerType.SHULKER_BOX, new ShulkerInventoryTranslator());
|
||||||
put(ContainerType.SMITHING, new SmithingInventoryTranslator());
|
put(ContainerType.LEGACY_SMITHING, new SmithingInventoryTranslator());
|
||||||
put(ContainerType.STONECUTTER, new StonecutterInventoryTranslator());
|
put(ContainerType.STONECUTTER, new StonecutterInventoryTranslator());
|
||||||
|
|
||||||
/* Lectern */
|
/* Lectern */
|
||||||
|
@ -43,25 +43,21 @@ public class BedrockRequestAbilityTranslator extends PacketTranslator<RequestAbi
|
|||||||
@Override
|
@Override
|
||||||
public void translate(GeyserSession session, RequestAbilityPacket packet) {
|
public void translate(GeyserSession session, RequestAbilityPacket packet) {
|
||||||
if (packet.getAbility() == Ability.FLYING) {
|
if (packet.getAbility() == Ability.FLYING) {
|
||||||
handle(session, packet.isBoolValue());
|
boolean isFlying = packet.isBoolValue();
|
||||||
}
|
if (!isFlying && session.getGameMode() == GameMode.SPECTATOR) {
|
||||||
}
|
// We should always be flying in spectator mode
|
||||||
|
session.sendAdventureSettings();
|
||||||
|
return;
|
||||||
|
} else if (isFlying && session.getPlayerEntity().getFlag(EntityFlag.SWIMMING) && session.getCollisionManager().isPlayerInWater()) {
|
||||||
|
// As of 1.18.1, Java Edition cannot fly while in water, but it can fly while crawling
|
||||||
|
// If this isn't present, swimming on a 1.13.2 server and then attempting to fly will put you into a flying/swimming state that is invalid on JE
|
||||||
|
session.sendAdventureSettings();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
//FIXME remove after pre-1.19.30 support is dropped and merge into main method
|
session.setFlying(isFlying);
|
||||||
static void handle(GeyserSession session, boolean isFlying) {
|
ServerboundPlayerAbilitiesPacket abilitiesPacket = new ServerboundPlayerAbilitiesPacket(isFlying);
|
||||||
if (!isFlying && session.getGameMode() == GameMode.SPECTATOR) {
|
session.sendDownstreamPacket(abilitiesPacket);
|
||||||
// We should always be flying in spectator mode
|
|
||||||
session.sendAdventureSettings();
|
|
||||||
return;
|
|
||||||
} else if (isFlying && session.getPlayerEntity().getFlag(EntityFlag.SWIMMING) && session.getCollisionManager().isPlayerInWater()) {
|
|
||||||
// As of 1.18.1, Java Edition cannot fly while in water, but it can fly while crawling
|
|
||||||
// If this isn't present, swimming on a 1.13.2 server and then attempting to fly will put you into a flying/swimming state that is invalid on JE
|
|
||||||
session.sendAdventureSettings();
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
session.setFlying(isFlying);
|
|
||||||
ServerboundPlayerAbilitiesPacket abilitiesPacket = new ServerboundPlayerAbilitiesPacket(isFlying);
|
|
||||||
session.sendDownstreamPacket(abilitiesPacket);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -47,4 +47,9 @@ public class JavaKeepAliveTranslator extends PacketTranslator<ClientboundKeepAli
|
|||||||
latencyPacket.setTimestamp(packet.getPingId() * 1000);
|
latencyPacket.setTimestamp(packet.getPingId() * 1000);
|
||||||
session.sendUpstreamPacket(latencyPacket);
|
session.sendUpstreamPacket(latencyPacket);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean shouldExecuteInEventLoop() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -30,8 +30,6 @@ import com.github.steveice10.mc.protocol.packet.ingame.serverbound.ServerboundCu
|
|||||||
import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
|
import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
|
||||||
import com.github.steveice10.opennbt.tag.builtin.IntTag;
|
import com.github.steveice10.opennbt.tag.builtin.IntTag;
|
||||||
import com.nukkitx.protocol.bedrock.data.GameRuleData;
|
import com.nukkitx.protocol.bedrock.data.GameRuleData;
|
||||||
import com.nukkitx.protocol.bedrock.data.PlayerPermission;
|
|
||||||
import com.nukkitx.protocol.bedrock.packet.AdventureSettingsPacket;
|
|
||||||
import com.nukkitx.protocol.bedrock.packet.GameRulesChangedPacket;
|
import com.nukkitx.protocol.bedrock.packet.GameRulesChangedPacket;
|
||||||
import com.nukkitx.protocol.bedrock.packet.SetPlayerGameTypePacket;
|
import com.nukkitx.protocol.bedrock.packet.SetPlayerGameTypePacket;
|
||||||
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
|
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
|
||||||
@ -107,11 +105,6 @@ public class JavaLoginTranslator extends PacketTranslator<ClientboundLoginPacket
|
|||||||
session.getUpstream().sendPostStartGamePackets();
|
session.getUpstream().sendPostStartGamePackets();
|
||||||
}
|
}
|
||||||
|
|
||||||
AdventureSettingsPacket bedrockPacket = new AdventureSettingsPacket();
|
|
||||||
bedrockPacket.setUniqueEntityId(session.getPlayerEntity().getGeyserId());
|
|
||||||
bedrockPacket.setPlayerPermission(PlayerPermission.MEMBER);
|
|
||||||
session.sendUpstreamPacket(bedrockPacket);
|
|
||||||
|
|
||||||
if (!needsSpawnPacket) {
|
if (!needsSpawnPacket) {
|
||||||
SetPlayerGameTypePacket playerGameTypePacket = new SetPlayerGameTypePacket();
|
SetPlayerGameTypePacket playerGameTypePacket = new SetPlayerGameTypePacket();
|
||||||
playerGameTypePacket.setGamemode(packet.getGameMode().ordinal());
|
playerGameTypePacket.setGamemode(packet.getGameMode().ordinal());
|
||||||
|
@ -167,7 +167,7 @@ public class JavaUpdateRecipesTranslator extends PacketTranslator<ClientboundUpd
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
craftingDataPacket.getCraftingData().addAll(CARTOGRAPHY_RECIPES);
|
craftingDataPacket.getCraftingData().addAll(CARTOGRAPHY_RECIPES);
|
||||||
craftingDataPacket.getPotionMixData().addAll(Registries.POTION_MIXES.get());
|
craftingDataPacket.getPotionMixData().addAll(Registries.POTION_MIXES.forVersion(session.getUpstream().getProtocolVersion()));
|
||||||
|
|
||||||
Int2ObjectMap<GeyserStonecutterData> stonecutterRecipeMap = new Int2ObjectOpenHashMap<>();
|
Int2ObjectMap<GeyserStonecutterData> stonecutterRecipeMap = new Int2ObjectOpenHashMap<>();
|
||||||
for (Int2ObjectMap.Entry<List<StoneCuttingRecipeData>> data : unsortedStonecutterData.int2ObjectEntrySet()) {
|
for (Int2ObjectMap.Entry<List<StoneCuttingRecipeData>> data : unsortedStonecutterData.int2ObjectEntrySet()) {
|
||||||
|
@ -11,7 +11,7 @@ websocket = "1.5.1"
|
|||||||
protocol = "2.9.17-20230217.002312-1"
|
protocol = "2.9.17-20230217.002312-1"
|
||||||
raknet = "1.6.28-20220125.214016-6"
|
raknet = "1.6.28-20220125.214016-6"
|
||||||
mcauthlib = "d9d773e"
|
mcauthlib = "d9d773e"
|
||||||
mcprotocollib = "1.19.4-20230314.173921-2"
|
mcprotocollib = "1.19.4-20230317.173631-4"
|
||||||
adventure = "4.12.0-20220629.025215-9"
|
adventure = "4.12.0-20220629.025215-9"
|
||||||
adventure-platform = "4.1.2"
|
adventure-platform = "4.1.2"
|
||||||
junit = "5.9.2"
|
junit = "5.9.2"
|
||||||
|
Laden…
In neuem Issue referenzieren
Einen Benutzer sperren