Mirror von
https://github.com/ViaVersion/ViaVersion.git
synchronisiert 2024-11-20 06:50:08 +01:00
More handled structures
Dieser Commit ist enthalten in:
Ursprung
329abcac7d
Commit
7a66bb8e1c
@ -22,21 +22,29 @@
|
|||||||
*/
|
*/
|
||||||
package com.viaversion.viaversion.api.minecraft;
|
package com.viaversion.viaversion.api.minecraft;
|
||||||
|
|
||||||
import com.google.common.base.Preconditions;
|
public interface Holder<T> {
|
||||||
|
|
||||||
public final class Holder<T> {
|
/**
|
||||||
|
* Returns an indirect id holder.
|
||||||
private final T value;
|
*
|
||||||
private final int id;
|
* @param id the id
|
||||||
|
* @param <T> the type of the value
|
||||||
public Holder(final int id) {
|
* @return a new holder with the given id
|
||||||
this.value = null;
|
* @throws IllegalArgumentException if the id is negative
|
||||||
this.id = id;
|
*/
|
||||||
|
static <T> Holder<T> of(final int id) {
|
||||||
|
return new HolderImpl<>(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Holder(final T value) {
|
/**
|
||||||
this.value = value;
|
* Returns a direct value holder.
|
||||||
this.id = -1;
|
*
|
||||||
|
* @param value the value
|
||||||
|
* @param <T> the type of the value
|
||||||
|
* @return a new direct holder
|
||||||
|
*/
|
||||||
|
static <T> Holder<T> of(final T value) {
|
||||||
|
return new HolderImpl<>(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -45,9 +53,7 @@ public final class Holder<T> {
|
|||||||
* @return true if the holder is direct
|
* @return true if the holder is direct
|
||||||
* @see #hasId()
|
* @see #hasId()
|
||||||
*/
|
*/
|
||||||
public boolean isDirect() {
|
boolean isDirect();
|
||||||
return id == -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns true if this holder has an id.
|
* Returns true if this holder has an id.
|
||||||
@ -55,16 +61,22 @@ public final class Holder<T> {
|
|||||||
* @return true if this holder has an id
|
* @return true if this holder has an id
|
||||||
* @see #isDirect()
|
* @see #isDirect()
|
||||||
*/
|
*/
|
||||||
public boolean hasId() {
|
boolean hasId();
|
||||||
return id != -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
public T value() {
|
/**
|
||||||
Preconditions.checkArgument(isDirect(), "Holder is not direct");
|
* Returns the value of this holder.
|
||||||
return value;
|
*
|
||||||
}
|
* @return the value of this holder
|
||||||
|
* @throws IllegalArgumentException if this holder is not direct
|
||||||
|
* @see #isDirect()
|
||||||
|
*/
|
||||||
|
T value();
|
||||||
|
|
||||||
public int id() {
|
/**
|
||||||
return id;
|
* Returns the id of this holder, or -1 if this holder is direct.
|
||||||
}
|
*
|
||||||
|
* @return the id of this holder, or -1 if this holder is direct
|
||||||
|
* @see #hasId()
|
||||||
|
*/
|
||||||
|
int id();
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,63 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
|
||||||
|
* Copyright (C) 2016-2024 ViaVersion and contributors
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
* SOFTWARE.
|
||||||
|
*/
|
||||||
|
package com.viaversion.viaversion.api.minecraft;
|
||||||
|
|
||||||
|
import com.google.common.base.Preconditions;
|
||||||
|
|
||||||
|
final class HolderImpl<T> implements Holder<T> {
|
||||||
|
|
||||||
|
private final T value;
|
||||||
|
private final int id;
|
||||||
|
|
||||||
|
HolderImpl(final int id) {
|
||||||
|
Preconditions.checkArgument(id >= 0, "id cannot be negative");
|
||||||
|
this.value = null;
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
HolderImpl(final T value) {
|
||||||
|
this.value = value;
|
||||||
|
this.id = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isDirect() {
|
||||||
|
return id == -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean hasId() {
|
||||||
|
return id != -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public T value() {
|
||||||
|
Preconditions.checkArgument(isDirect(), "Holder is not direct");
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int id() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
}
|
@ -36,9 +36,9 @@ public abstract class HolderType<T> extends Type<Holder<T>> {
|
|||||||
public Holder<T> read(final ByteBuf buffer) throws Exception {
|
public Holder<T> read(final ByteBuf buffer) throws Exception {
|
||||||
final int id = Type.VAR_INT.readPrimitive(buffer) - 1; // Normalize id
|
final int id = Type.VAR_INT.readPrimitive(buffer) - 1; // Normalize id
|
||||||
if (id == -1) {
|
if (id == -1) {
|
||||||
return new Holder<>(readDirect(buffer));
|
return Holder.of(readDirect(buffer));
|
||||||
}
|
}
|
||||||
return new Holder<>(id);
|
return Holder.of(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -245,7 +245,7 @@ public class InventoryPackets extends ItemRewriter<ClientboundPackets1_13, Serve
|
|||||||
if (display != null) {
|
if (display != null) {
|
||||||
ListTag<StringTag> lore = display.getListTag("Lore", StringTag.class);
|
ListTag<StringTag> lore = display.getListTag("Lore", StringTag.class);
|
||||||
if (lore != null) {
|
if (lore != null) {
|
||||||
display.put(nbtTagName("Lore"), new ListTag<>(lore.copy().getValue())); // Save old lore
|
display.put(nbtTagName("Lore"), lore.copy()); // Save old lore
|
||||||
for (StringTag loreEntry : lore) {
|
for (StringTag loreEntry : lore) {
|
||||||
String jsonText = ComponentUtil.legacyToJsonString(loreEntry.getValue(), true);
|
String jsonText = ComponentUtil.legacyToJsonString(loreEntry.getValue(), true);
|
||||||
loreEntry.setValue(jsonText);
|
loreEntry.setValue(jsonText);
|
||||||
@ -269,7 +269,7 @@ public class InventoryPackets extends ItemRewriter<ClientboundPackets1_13, Serve
|
|||||||
if (lore != null) {
|
if (lore != null) {
|
||||||
Tag savedLore = display.remove(nbtTagName("Lore"));
|
Tag savedLore = display.remove(nbtTagName("Lore"));
|
||||||
if (savedLore instanceof ListTag) {
|
if (savedLore instanceof ListTag) {
|
||||||
display.put("Lore", new ListTag<>(((ListTag<?>) savedLore).getValue()));
|
display.put("Lore", savedLore.copy());
|
||||||
} else {
|
} else {
|
||||||
for (StringTag loreEntry : lore) {
|
for (StringTag loreEntry : lore) {
|
||||||
loreEntry.setValue(ComponentUtil.jsonToLegacy(loreEntry.getValue()));
|
loreEntry.setValue(ComponentUtil.jsonToLegacy(loreEntry.getValue()));
|
||||||
|
@ -96,13 +96,13 @@ public final class Protocol1_19_3To1_19_1 extends AbstractProtocol<ClientboundPa
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
wrapper.write(Type.SOUND_EVENT, new Holder<>(soundId));
|
wrapper.write(Type.SOUND_EVENT, Holder.of(soundId));
|
||||||
};
|
};
|
||||||
registerClientbound(ClientboundPackets1_19_1.ENTITY_SOUND, soundHandler);
|
registerClientbound(ClientboundPackets1_19_1.ENTITY_SOUND, soundHandler);
|
||||||
registerClientbound(ClientboundPackets1_19_1.SOUND, soundHandler);
|
registerClientbound(ClientboundPackets1_19_1.SOUND, soundHandler);
|
||||||
registerClientbound(ClientboundPackets1_19_1.NAMED_SOUND, ClientboundPackets1_19_3.SOUND, wrapper -> {
|
registerClientbound(ClientboundPackets1_19_1.NAMED_SOUND, ClientboundPackets1_19_3.SOUND, wrapper -> {
|
||||||
final String soundIdentifier = wrapper.read(Type.STRING);
|
final String soundIdentifier = wrapper.read(Type.STRING);
|
||||||
wrapper.write(Type.SOUND_EVENT, new Holder<>(new SoundEvent(soundIdentifier, null)));
|
wrapper.write(Type.SOUND_EVENT, Holder.of(new SoundEvent(soundIdentifier, null)));
|
||||||
});
|
});
|
||||||
|
|
||||||
new StatisticsRewriter<>(this).register(ClientboundPackets1_19_1.STATISTICS);
|
new StatisticsRewriter<>(this).register(ClientboundPackets1_19_1.STATISTICS);
|
||||||
|
@ -17,8 +17,7 @@
|
|||||||
*/
|
*/
|
||||||
package com.viaversion.viaversion.protocols.protocol1_20_5to1_20_3.data;
|
package com.viaversion.viaversion.protocols.protocol1_20_5to1_20_3.data;
|
||||||
|
|
||||||
import it.unimi.dsi.fastutil.objects.Object2IntMap;
|
import com.viaversion.viaversion.util.KeyMappings;
|
||||||
import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap;
|
|
||||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -26,7 +25,7 @@ import org.checkerframework.checker.nullness.qual.Nullable;
|
|||||||
*/
|
*/
|
||||||
public final class AttributeMappings {
|
public final class AttributeMappings {
|
||||||
|
|
||||||
private static final String[] ATTRIBUTES = {
|
private static final KeyMappings ATTRIBUTES = new KeyMappings(
|
||||||
"generic.armor",
|
"generic.armor",
|
||||||
"generic.armor_toughness",
|
"generic.armor_toughness",
|
||||||
"generic.attack_damage",
|
"generic.attack_damage",
|
||||||
@ -41,20 +40,13 @@ public final class AttributeMappings {
|
|||||||
"generic.max_health",
|
"generic.max_health",
|
||||||
"generic.movement_speed",
|
"generic.movement_speed",
|
||||||
"zombie.spawn_reinforcements"
|
"zombie.spawn_reinforcements"
|
||||||
};
|
);
|
||||||
private static final Object2IntMap<String> STRING_TO_ID = new Object2IntOpenHashMap<>();
|
|
||||||
|
|
||||||
static {
|
|
||||||
for (int i = 0; i < ATTRIBUTES.length; i++) {
|
|
||||||
STRING_TO_ID.put(ATTRIBUTES[i], i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static @Nullable String attribute(final int id) {
|
public static @Nullable String attribute(final int id) {
|
||||||
return id >= 0 && id < ATTRIBUTES.length ? ATTRIBUTES[id] : null;
|
return ATTRIBUTES.idToKey(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int id(final String attribute) {
|
public static int id(final String attribute) {
|
||||||
return STRING_TO_ID.getOrDefault(attribute, -1);
|
return ATTRIBUTES.keyToId(attribute);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -17,14 +17,12 @@
|
|||||||
*/
|
*/
|
||||||
package com.viaversion.viaversion.protocols.protocol1_20_5to1_20_3.data;
|
package com.viaversion.viaversion.protocols.protocol1_20_5to1_20_3.data;
|
||||||
|
|
||||||
import com.viaversion.viaversion.util.Key;
|
import com.viaversion.viaversion.util.KeyMappings;
|
||||||
import it.unimi.dsi.fastutil.objects.Object2IntMap;
|
|
||||||
import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap;
|
|
||||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||||
|
|
||||||
public final class EnchantmentMappings {
|
public final class EnchantmentMappings {
|
||||||
|
|
||||||
public static final String[] ENCHANTMENTS = {
|
public static final KeyMappings ENCHANTMENTS = new KeyMappings(
|
||||||
"protection",
|
"protection",
|
||||||
"fire_protection",
|
"fire_protection",
|
||||||
"feather_falling",
|
"feather_falling",
|
||||||
@ -64,20 +62,13 @@ public final class EnchantmentMappings {
|
|||||||
"piercing",
|
"piercing",
|
||||||
"mending",
|
"mending",
|
||||||
"vanishing_curse"
|
"vanishing_curse"
|
||||||
};
|
);
|
||||||
private static final Object2IntMap<String> STRING_TO_ID = new Object2IntOpenHashMap<>();
|
|
||||||
|
|
||||||
static {
|
|
||||||
for (int i = 0; i < ENCHANTMENTS.length; i++) {
|
|
||||||
STRING_TO_ID.put(ENCHANTMENTS[i], i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static @Nullable String enchantment(final int id) {
|
public static @Nullable String enchantment(final int id) {
|
||||||
return id >= 0 && id < ENCHANTMENTS.length ? ENCHANTMENTS[id] : null;
|
return ENCHANTMENTS.idToKey(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int id(final String attribute) {
|
public static int id(final String attribute) {
|
||||||
return STRING_TO_ID.getOrDefault(Key.stripMinecraftNamespace(attribute), -1);
|
return ENCHANTMENTS.keyToId(attribute);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,43 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
|
||||||
|
* Copyright (C) 2016-2024 ViaVersion and contributors
|
||||||
|
*
|
||||||
|
* 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, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* 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.viaversion.viaversion.protocols.protocol1_20_5to1_20_3.data;
|
||||||
|
|
||||||
|
import com.viaversion.viaversion.util.KeyMappings;
|
||||||
|
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||||
|
|
||||||
|
public final class InstrumentMappings {
|
||||||
|
|
||||||
|
private static final KeyMappings MAPPINGS = new KeyMappings(
|
||||||
|
"ponder_goat_horn",
|
||||||
|
"sing_goat_horn",
|
||||||
|
"seek_goat_horn",
|
||||||
|
"feel_goat_horn",
|
||||||
|
"admire_goat_horn",
|
||||||
|
"call_goat_horn",
|
||||||
|
"yearn_goat_horn",
|
||||||
|
"dream_goat_horn"
|
||||||
|
);
|
||||||
|
|
||||||
|
public static @Nullable String idToKey(final int id) {
|
||||||
|
return MAPPINGS.idToKey(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int keyToId(final String name) {
|
||||||
|
return MAPPINGS.keyToId(name);
|
||||||
|
}
|
||||||
|
}
|
@ -17,9 +17,11 @@
|
|||||||
*/
|
*/
|
||||||
package com.viaversion.viaversion.protocols.protocol1_20_5to1_20_3.data;
|
package com.viaversion.viaversion.protocols.protocol1_20_5to1_20_3.data;
|
||||||
|
|
||||||
|
import com.viaversion.viaversion.util.KeyMappings;
|
||||||
|
|
||||||
public final class MapDecorationMappings {
|
public final class MapDecorationMappings {
|
||||||
|
|
||||||
private static final String[] MAP_DECORATIONS = {
|
private static final KeyMappings MAP_DECORATIONS = new KeyMappings(
|
||||||
"player",
|
"player",
|
||||||
"frame",
|
"frame",
|
||||||
"red_marker",
|
"red_marker",
|
||||||
@ -54,9 +56,9 @@ public final class MapDecorationMappings {
|
|||||||
"village_taiga",
|
"village_taiga",
|
||||||
"jungle_temple",
|
"jungle_temple",
|
||||||
"swamp_hut"
|
"swamp_hut"
|
||||||
};
|
);
|
||||||
|
|
||||||
public static String mapDecoration(final int index) {
|
public static String mapDecoration(final int index) {
|
||||||
return index < 0 || index >= MAP_DECORATIONS.length ? "player" : MAP_DECORATIONS[index];
|
return index < 0 || index >= MAP_DECORATIONS.size() ? "player" : MAP_DECORATIONS.idToKey(index);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -26,6 +26,7 @@ import com.github.steveice10.opennbt.tag.builtin.Tag;
|
|||||||
import com.viaversion.viaversion.api.data.ParticleMappings;
|
import com.viaversion.viaversion.api.data.ParticleMappings;
|
||||||
import com.viaversion.viaversion.api.minecraft.GameProfile;
|
import com.viaversion.viaversion.api.minecraft.GameProfile;
|
||||||
import com.viaversion.viaversion.api.minecraft.GlobalPosition;
|
import com.viaversion.viaversion.api.minecraft.GlobalPosition;
|
||||||
|
import com.viaversion.viaversion.api.minecraft.Holder;
|
||||||
import com.viaversion.viaversion.api.minecraft.Particle;
|
import com.viaversion.viaversion.api.minecraft.Particle;
|
||||||
import com.viaversion.viaversion.api.minecraft.data.StructuredData;
|
import com.viaversion.viaversion.api.minecraft.data.StructuredData;
|
||||||
import com.viaversion.viaversion.api.minecraft.data.StructuredDataContainer;
|
import com.viaversion.viaversion.api.minecraft.data.StructuredDataContainer;
|
||||||
@ -39,17 +40,21 @@ import com.viaversion.viaversion.api.minecraft.item.data.Enchantments;
|
|||||||
import com.viaversion.viaversion.api.minecraft.item.data.FilterableComponent;
|
import com.viaversion.viaversion.api.minecraft.item.data.FilterableComponent;
|
||||||
import com.viaversion.viaversion.api.minecraft.item.data.FilterableString;
|
import com.viaversion.viaversion.api.minecraft.item.data.FilterableString;
|
||||||
import com.viaversion.viaversion.api.minecraft.item.data.FireworkExplosion;
|
import com.viaversion.viaversion.api.minecraft.item.data.FireworkExplosion;
|
||||||
|
import com.viaversion.viaversion.api.minecraft.item.data.Fireworks;
|
||||||
import com.viaversion.viaversion.api.minecraft.item.data.LodestoneTracker;
|
import com.viaversion.viaversion.api.minecraft.item.data.LodestoneTracker;
|
||||||
|
import com.viaversion.viaversion.api.minecraft.item.data.SuspiciousStewEffect;
|
||||||
import com.viaversion.viaversion.api.minecraft.item.data.WrittenBook;
|
import com.viaversion.viaversion.api.minecraft.item.data.WrittenBook;
|
||||||
import com.viaversion.viaversion.api.type.Type;
|
import com.viaversion.viaversion.api.type.Type;
|
||||||
import com.viaversion.viaversion.api.type.types.chunk.ChunkType1_20_2;
|
import com.viaversion.viaversion.api.type.types.chunk.ChunkType1_20_2;
|
||||||
import com.viaversion.viaversion.api.type.types.version.Types1_20_3;
|
import com.viaversion.viaversion.api.type.types.version.Types1_20_3;
|
||||||
import com.viaversion.viaversion.api.type.types.version.Types1_20_5;
|
import com.viaversion.viaversion.api.type.types.version.Types1_20_5;
|
||||||
|
import com.viaversion.viaversion.protocols.protocol1_20_2to1_20.util.PotionEffects;
|
||||||
import com.viaversion.viaversion.protocols.protocol1_20_3to1_20_2.packet.ClientboundPacket1_20_3;
|
import com.viaversion.viaversion.protocols.protocol1_20_3to1_20_2.packet.ClientboundPacket1_20_3;
|
||||||
import com.viaversion.viaversion.protocols.protocol1_20_3to1_20_2.packet.ClientboundPackets1_20_3;
|
import com.viaversion.viaversion.protocols.protocol1_20_3to1_20_2.packet.ClientboundPackets1_20_3;
|
||||||
import com.viaversion.viaversion.protocols.protocol1_20_3to1_20_2.rewriter.RecipeRewriter1_20_3;
|
import com.viaversion.viaversion.protocols.protocol1_20_3to1_20_2.rewriter.RecipeRewriter1_20_3;
|
||||||
import com.viaversion.viaversion.protocols.protocol1_20_5to1_20_3.Protocol1_20_5To1_20_3;
|
import com.viaversion.viaversion.protocols.protocol1_20_5to1_20_3.Protocol1_20_5To1_20_3;
|
||||||
import com.viaversion.viaversion.protocols.protocol1_20_5to1_20_3.data.EnchantmentMappings;
|
import com.viaversion.viaversion.protocols.protocol1_20_5to1_20_3.data.EnchantmentMappings;
|
||||||
|
import com.viaversion.viaversion.protocols.protocol1_20_5to1_20_3.data.InstrumentMappings;
|
||||||
import com.viaversion.viaversion.protocols.protocol1_20_5to1_20_3.data.MapDecorationMappings;
|
import com.viaversion.viaversion.protocols.protocol1_20_5to1_20_3.data.MapDecorationMappings;
|
||||||
import com.viaversion.viaversion.protocols.protocol1_20_5to1_20_3.packet.ServerboundPacket1_20_5;
|
import com.viaversion.viaversion.protocols.protocol1_20_5to1_20_3.packet.ServerboundPacket1_20_5;
|
||||||
import com.viaversion.viaversion.protocols.protocol1_20_5to1_20_3.packet.ServerboundPackets1_20_5;
|
import com.viaversion.viaversion.protocols.protocol1_20_5to1_20_3.packet.ServerboundPackets1_20_5;
|
||||||
@ -202,7 +207,6 @@ public final class BlockItemPacketRewriter1_20_5 extends ItemRewriter<Clientboun
|
|||||||
return toOldItem(item);
|
return toOldItem(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO Block entity changes
|
|
||||||
public Item toOldItem(final Item item) {
|
public Item toOldItem(final Item item) {
|
||||||
// Start out with custom data and add the rest on top, or short-curcuit with the original item
|
// Start out with custom data and add the rest on top, or short-curcuit with the original item
|
||||||
final StructuredDataContainer data = item.structuredData();
|
final StructuredDataContainer data = item.structuredData();
|
||||||
@ -220,11 +224,13 @@ public final class BlockItemPacketRewriter1_20_5 extends ItemRewriter<Clientboun
|
|||||||
return dataItem;
|
return dataItem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO Block entity changes
|
||||||
public Item toStructuredItem(final Item old, final boolean addMarker) {
|
public Item toStructuredItem(final Item old, final boolean addMarker) {
|
||||||
final CompoundTag tag = old.tag();
|
final CompoundTag tag = old.tag();
|
||||||
final StructuredItem item = new StructuredItem(old.identifier(), (byte) old.amount(), new StructuredDataContainer());
|
final StructuredItem item = new StructuredItem(old.identifier(), (byte) old.amount(), new StructuredDataContainer());
|
||||||
final StructuredDataContainer data = item.structuredData();
|
final StructuredDataContainer data = item.structuredData();
|
||||||
data.setIdLookup(protocol, true);
|
data.setIdLookup(protocol, true);
|
||||||
|
// TODO add default data :>
|
||||||
if (tag == null) {
|
if (tag == null) {
|
||||||
return item;
|
return item;
|
||||||
}
|
}
|
||||||
@ -255,14 +261,7 @@ public final class BlockItemPacketRewriter1_20_5 extends ItemRewriter<Clientboun
|
|||||||
|
|
||||||
final CompoundTag blockState = tag.getCompoundTag("BlockStateTag");
|
final CompoundTag blockState = tag.getCompoundTag("BlockStateTag");
|
||||||
if (blockState != null) {
|
if (blockState != null) {
|
||||||
final Map<String, String> properties = new HashMap<>();
|
updateBlockState(blockState, data);
|
||||||
for (final Map.Entry<String, Tag> entry : blockState.entrySet()) {
|
|
||||||
if (entry.getValue() instanceof StringTag) {
|
|
||||||
properties.put(entry.getKey(), ((StringTag) entry.getValue()).getValue());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// TODO block state changes
|
|
||||||
data.set(StructuredDataKey.BLOCK_STATE, new BlockStateProperties(properties));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
final CompoundTag entityTag = tag.getCompoundTag("EntityTag");
|
final CompoundTag entityTag = tag.getCompoundTag("EntityTag");
|
||||||
@ -299,19 +298,7 @@ public final class BlockItemPacketRewriter1_20_5 extends ItemRewriter<Clientboun
|
|||||||
|
|
||||||
final CompoundTag explosionTag = tag.getCompoundTag("Explosion");
|
final CompoundTag explosionTag = tag.getCompoundTag("Explosion");
|
||||||
if (explosionTag != null) {
|
if (explosionTag != null) {
|
||||||
final NumberTag shape = explosionTag.getNumberTag("Type");
|
data.set(StructuredDataKey.FIREWORK_EXPLOSION, readExplosion(explosionTag));
|
||||||
final IntArrayTag colors = explosionTag.getIntArrayTag("Colors");
|
|
||||||
final IntArrayTag fadeColors = explosionTag.getIntArrayTag("FadeColors");
|
|
||||||
final NumberTag trail = explosionTag.getNumberTag("Trail");
|
|
||||||
final NumberTag flicker = explosionTag.getNumberTag("Flicker");
|
|
||||||
final FireworkExplosion explosion = new FireworkExplosion(
|
|
||||||
shape != null ? shape.asInt() : 0,
|
|
||||||
colors != null ? colors.getValue() : new int[0],
|
|
||||||
fadeColors != null ? fadeColors.getValue() : new int[0],
|
|
||||||
trail != null && trail.asBoolean(),
|
|
||||||
flicker != null && flicker.asBoolean()
|
|
||||||
);
|
|
||||||
data.set(StructuredDataKey.FIREWORK_EXPLOSION, explosion);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
final ListTag<StringTag> recipesTag = tag.getListTag("Recipes", StringTag.class);
|
final ListTag<StringTag> recipesTag = tag.getListTag("Recipes", StringTag.class);
|
||||||
@ -322,17 +309,28 @@ public final class BlockItemPacketRewriter1_20_5 extends ItemRewriter<Clientboun
|
|||||||
final CompoundTag lodestonePosTag = tag.getCompoundTag("LodestonePos");
|
final CompoundTag lodestonePosTag = tag.getCompoundTag("LodestonePos");
|
||||||
final StringTag lodestoneDimensionTag = tag.getStringTag("LodestoneDimension");
|
final StringTag lodestoneDimensionTag = tag.getStringTag("LodestoneDimension");
|
||||||
if (lodestonePosTag != null && lodestoneDimensionTag != null) {
|
if (lodestonePosTag != null && lodestoneDimensionTag != null) {
|
||||||
final NumberTag trackedTag = tag.getNumberTag("LodestoneTracked");
|
updateLodestoneTracker(tag, lodestonePosTag, lodestoneDimensionTag, data);
|
||||||
final NumberTag xTag = lodestonePosTag.getNumberTag("X");
|
}
|
||||||
final NumberTag yTag = lodestonePosTag.getNumberTag("Y");
|
|
||||||
final NumberTag zTag = lodestonePosTag.getNumberTag("Z");
|
final ListTag<CompoundTag> effectsTag = tag.getListTag("effects", CompoundTag.class);
|
||||||
final GlobalPosition position = new GlobalPosition(
|
if (effectsTag != null) {
|
||||||
lodestoneDimensionTag.getValue(),
|
updateEffects(effectsTag, data);
|
||||||
xTag != null ? xTag.asInt() : 0,
|
}
|
||||||
yTag != null ? yTag.asInt() : 0,
|
|
||||||
zTag != null ? zTag.asInt() : 0
|
final StringTag instrumentTag = tag.getStringTag("instrument");
|
||||||
);
|
if (instrumentTag != null) {
|
||||||
data.set(StructuredDataKey.LODESTONE_TRACKER, new LodestoneTracker(position, trackedTag != null && trackedTag.asBoolean()));
|
final int id = InstrumentMappings.keyToId(instrumentTag.getValue());
|
||||||
|
if (id != -1) {
|
||||||
|
data.set(StructuredDataKey.INSTRUMENT, Holder.of(id));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
final CompoundTag fireworksTag = tag.getCompoundTag("Fireworks");
|
||||||
|
if (fireworksTag != null) {
|
||||||
|
final ListTag<CompoundTag> explosionsTag = fireworksTag.getListTag("Explosions", CompoundTag.class);
|
||||||
|
if (explosionsTag != null) {
|
||||||
|
updateFireworks(fireworksTag, explosionsTag, data);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (old.identifier() == 1085) {
|
if (old.identifier() == 1085) {
|
||||||
@ -347,12 +345,15 @@ public final class BlockItemPacketRewriter1_20_5 extends ItemRewriter<Clientboun
|
|||||||
updateEnchantments(data, tag, "Enchantments", StructuredDataKey.ENCHANTMENTS, (hideFlagsValue & 0x01) == 0);
|
updateEnchantments(data, tag, "Enchantments", StructuredDataKey.ENCHANTMENTS, (hideFlagsValue & 0x01) == 0);
|
||||||
updateEnchantments(data, tag, "StoredEnchantments", StructuredDataKey.STORED_ENCHANTMENTS, (hideFlagsValue & 0x20) == 0);
|
updateEnchantments(data, tag, "StoredEnchantments", StructuredDataKey.STORED_ENCHANTMENTS, (hideFlagsValue & 0x20) == 0);
|
||||||
|
|
||||||
final NumberTag map = tag.getNumberTag("map");
|
final NumberTag mapId = tag.getNumberTag("map");
|
||||||
if (map != null) {
|
if (mapId != null) {
|
||||||
data.set(StructuredDataKey.MAP_ID, map.asInt());
|
data.set(StructuredDataKey.MAP_ID, mapId.asInt());
|
||||||
}
|
}
|
||||||
|
|
||||||
updateMapDecorations(data, tag.getListTag("Decorations", CompoundTag.class));
|
final ListTag<CompoundTag> decorationsTag = tag.getListTag("Decorations", CompoundTag.class);
|
||||||
|
if (decorationsTag != null) {
|
||||||
|
updateMapDecorations(data, decorationsTag);
|
||||||
|
}
|
||||||
|
|
||||||
// MAP_POST_PROCESSING is only used internally
|
// MAP_POST_PROCESSING is only used internally
|
||||||
|
|
||||||
@ -365,12 +366,9 @@ public final class BlockItemPacketRewriter1_20_5 extends ItemRewriter<Clientboun
|
|||||||
// StructuredDataKey.CREATIVE_SLOT_LOCK
|
// StructuredDataKey.CREATIVE_SLOT_LOCK
|
||||||
// StructuredDataKey.INTANGIBLE_PROJECTILE
|
// StructuredDataKey.INTANGIBLE_PROJECTILE
|
||||||
// StructuredDataKey.POTION_CONTENTS
|
// StructuredDataKey.POTION_CONTENTS
|
||||||
// StructuredDataKey.SUSPICIOUS_STEW_EFFECTS
|
|
||||||
// StructuredDataKey.TRIM
|
// StructuredDataKey.TRIM
|
||||||
// StructuredDataKey.BUCKET_ENTITY_DATA
|
// StructuredDataKey.BUCKET_ENTITY_DATA
|
||||||
// StructuredDataKey.BLOCK_ENTITY_DATA
|
// StructuredDataKey.BLOCK_ENTITY_DATA
|
||||||
// StructuredDataKey.INSTRUMENT
|
|
||||||
// StructuredDataKey.FIREWORKS
|
|
||||||
// StructuredDataKey.NOTE_BLOCK_SOUND
|
// StructuredDataKey.NOTE_BLOCK_SOUND
|
||||||
// StructuredDataKey.BANNER_PATTERNS
|
// StructuredDataKey.BANNER_PATTERNS
|
||||||
// StructuredDataKey.BASE_COLOR
|
// StructuredDataKey.BASE_COLOR
|
||||||
@ -388,6 +386,74 @@ public final class BlockItemPacketRewriter1_20_5 extends ItemRewriter<Clientboun
|
|||||||
return item;
|
return item;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void updateBlockState(final CompoundTag blockState, final StructuredDataContainer data) {
|
||||||
|
final Map<String, String> properties = new HashMap<>();
|
||||||
|
for (final Map.Entry<String, Tag> entry : blockState.entrySet()) {
|
||||||
|
// It's all strings now because ???
|
||||||
|
final Tag value = entry.getValue();
|
||||||
|
if (value instanceof StringTag) {
|
||||||
|
properties.put(entry.getKey(), ((StringTag) value).getValue());
|
||||||
|
} else if (value instanceof NumberTag) {
|
||||||
|
// TODO Boolean values
|
||||||
|
properties.put(entry.getKey(), Integer.toString(((NumberTag) value).asInt()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
data.set(StructuredDataKey.BLOCK_STATE, new BlockStateProperties(properties));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void updateFireworks(final CompoundTag fireworksTag, final ListTag<CompoundTag> explosionsTag, final StructuredDataContainer data) {
|
||||||
|
final NumberTag flightDuration = fireworksTag.getNumberTag("Flight");
|
||||||
|
final Fireworks fireworks = new Fireworks(
|
||||||
|
flightDuration != null ? flightDuration.asInt() : 0,
|
||||||
|
explosionsTag.stream().map(BlockItemPacketRewriter1_20_5::readExplosion).toArray(FireworkExplosion[]::new)
|
||||||
|
);
|
||||||
|
data.set(StructuredDataKey.FIREWORKS, fireworks);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void updateEffects(final ListTag<CompoundTag> effects, final StructuredDataContainer data) {
|
||||||
|
final SuspiciousStewEffect[] suspiciousStewEffects = new SuspiciousStewEffect[effects.size()];
|
||||||
|
for (int i = 0; i < effects.size(); i++) {
|
||||||
|
final CompoundTag effect = effects.get(i);
|
||||||
|
final StringTag effectId = effect.getStringTag("id");
|
||||||
|
final NumberTag duration = effect.getNumberTag("duration");
|
||||||
|
final SuspiciousStewEffect stewEffect = new SuspiciousStewEffect(
|
||||||
|
PotionEffects.keyToId(effectId != null ? effectId.getValue() : "luck") - 1,
|
||||||
|
duration != null ? duration.asInt() : 0
|
||||||
|
);
|
||||||
|
suspiciousStewEffects[i] = stewEffect;
|
||||||
|
}
|
||||||
|
data.set(StructuredDataKey.SUSPICIOUS_STEW_EFFECTS, suspiciousStewEffects);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void updateLodestoneTracker(final CompoundTag tag, final CompoundTag lodestonePosTag, final StringTag lodestoneDimensionTag, final StructuredDataContainer data) {
|
||||||
|
final NumberTag trackedTag = tag.getNumberTag("LodestoneTracked");
|
||||||
|
final NumberTag xTag = lodestonePosTag.getNumberTag("X");
|
||||||
|
final NumberTag yTag = lodestonePosTag.getNumberTag("Y");
|
||||||
|
final NumberTag zTag = lodestonePosTag.getNumberTag("Z");
|
||||||
|
final GlobalPosition position = new GlobalPosition(
|
||||||
|
lodestoneDimensionTag.getValue(),
|
||||||
|
xTag != null ? xTag.asInt() : 0,
|
||||||
|
yTag != null ? yTag.asInt() : 0,
|
||||||
|
zTag != null ? zTag.asInt() : 0
|
||||||
|
);
|
||||||
|
data.set(StructuredDataKey.LODESTONE_TRACKER, new LodestoneTracker(position, trackedTag != null && trackedTag.asBoolean()));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static FireworkExplosion readExplosion(final CompoundTag tag) {
|
||||||
|
final NumberTag shape = tag.getNumberTag("Type");
|
||||||
|
final IntArrayTag colors = tag.getIntArrayTag("Colors");
|
||||||
|
final IntArrayTag fadeColors = tag.getIntArrayTag("FadeColors");
|
||||||
|
final NumberTag trail = tag.getNumberTag("Trail");
|
||||||
|
final NumberTag flicker = tag.getNumberTag("Flicker");
|
||||||
|
return new FireworkExplosion(
|
||||||
|
shape != null ? shape.asInt() : 0,
|
||||||
|
colors != null ? colors.getValue() : new int[0],
|
||||||
|
fadeColors != null ? fadeColors.getValue() : new int[0],
|
||||||
|
trail != null && trail.asBoolean(),
|
||||||
|
flicker != null && flicker.asBoolean()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
private void updateWritableBookPages(final StructuredDataContainer data, final CompoundTag tag) {
|
private void updateWritableBookPages(final StructuredDataContainer data, final CompoundTag tag) {
|
||||||
final ListTag<StringTag> pagesTag = tag.getListTag("pages", StringTag.class);
|
final ListTag<StringTag> pagesTag = tag.getListTag("pages", StringTag.class);
|
||||||
final CompoundTag filteredPagesTag = tag.getCompoundTag("filtered_pages");
|
final CompoundTag filteredPagesTag = tag.getCompoundTag("filtered_pages");
|
||||||
@ -454,11 +520,8 @@ public final class BlockItemPacketRewriter1_20_5 extends ItemRewriter<Clientboun
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
final List<Item> items = new ArrayList<>();
|
final Item[] items = chargedProjectiles.stream().map(this::itemFromTag).toArray(Item[]::new);
|
||||||
for (final CompoundTag item : chargedProjectiles) {
|
data.set(dataKey, items);
|
||||||
items.add(itemFromTag(item));
|
|
||||||
}
|
|
||||||
data.set(dataKey, items.toArray(new Item[0]));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private Item itemFromTag(final CompoundTag item) {
|
private Item itemFromTag(final CompoundTag item) {
|
||||||
@ -502,7 +565,6 @@ public final class BlockItemPacketRewriter1_20_5 extends ItemRewriter<Clientboun
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void updateProfile(final StructuredDataContainer data, final Tag skullOwnerTag) {
|
private void updateProfile(final StructuredDataContainer data, final Tag skullOwnerTag) {
|
||||||
final List<GameProfile.Property> properties = new ArrayList<>(1);
|
|
||||||
if (skullOwnerTag instanceof StringTag) {
|
if (skullOwnerTag instanceof StringTag) {
|
||||||
final String name = ((StringTag) skullOwnerTag).getValue();
|
final String name = ((StringTag) skullOwnerTag).getValue();
|
||||||
data.set(StructuredDataKey.PROFILE, new GameProfile(name, null, EMPTY_PROPERTIES));
|
data.set(StructuredDataKey.PROFILE, new GameProfile(name, null, EMPTY_PROPERTIES));
|
||||||
@ -517,6 +579,7 @@ public final class BlockItemPacketRewriter1_20_5 extends ItemRewriter<Clientboun
|
|||||||
uuid = UUIDUtil.fromIntArray(idTag.getValue());
|
uuid = UUIDUtil.fromIntArray(idTag.getValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
final List<GameProfile.Property> properties = new ArrayList<>(1);
|
||||||
final CompoundTag propertiesTag = skullOwner.getCompoundTag("Properties");
|
final CompoundTag propertiesTag = skullOwner.getCompoundTag("Properties");
|
||||||
if (propertiesTag != null) {
|
if (propertiesTag != null) {
|
||||||
updateProperties(propertiesTag, properties);
|
updateProperties(propertiesTag, properties);
|
||||||
@ -549,10 +612,6 @@ public final class BlockItemPacketRewriter1_20_5 extends ItemRewriter<Clientboun
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void updateMapDecorations(final StructuredDataContainer data, final ListTag<CompoundTag> decorationsTag) {
|
private void updateMapDecorations(final StructuredDataContainer data, final ListTag<CompoundTag> decorationsTag) {
|
||||||
if (decorationsTag == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
final CompoundTag updatedDecorationsTag = new CompoundTag();
|
final CompoundTag updatedDecorationsTag = new CompoundTag();
|
||||||
for (final CompoundTag decorationTag : decorationsTag) {
|
for (final CompoundTag decorationTag : decorationsTag) {
|
||||||
final StringTag idTag = decorationTag.getStringTag("id");
|
final StringTag idTag = decorationTag.getStringTag("id");
|
||||||
@ -591,11 +650,7 @@ public final class BlockItemPacketRewriter1_20_5 extends ItemRewriter<Clientboun
|
|||||||
|
|
||||||
final ListTag<StringTag> loreTag = displayTag.getListTag("Lore", StringTag.class);
|
final ListTag<StringTag> loreTag = displayTag.getListTag("Lore", StringTag.class);
|
||||||
if (loreTag != null) {
|
if (loreTag != null) {
|
||||||
final List<Tag> updatedLore = new ArrayList<>();
|
data.set(StructuredDataKey.LORE, loreTag.stream().map(t -> ComponentUtil.jsonStringToTag(t.getValue())).toArray(Tag[]::new));
|
||||||
for (final StringTag loreEntry : loreTag) {
|
|
||||||
updatedLore.add(ComponentUtil.jsonStringToTag((loreEntry.getValue())));
|
|
||||||
}
|
|
||||||
data.set(StructuredDataKey.LORE, updatedLore.toArray(new Tag[0]));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
final NumberTag colorTag = displayTag.getNumberTag("color");
|
final NumberTag colorTag = displayTag.getNumberTag("color");
|
||||||
|
@ -69,7 +69,7 @@ public class SoundRewriter<C extends ClientboundPacketType> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (mappedId != soundEventHolder.id()) {
|
if (mappedId != soundEventHolder.id()) {
|
||||||
soundEventHolder = new Holder<>(mappedId);
|
soundEventHolder = Holder.of(mappedId);
|
||||||
}
|
}
|
||||||
|
|
||||||
wrapper.write(Type.SOUND_EVENT, soundEventHolder);
|
wrapper.write(Type.SOUND_EVENT, soundEventHolder);
|
||||||
|
51
common/src/main/java/com/viaversion/viaversion/util/KeyMappings.java
Normale Datei
51
common/src/main/java/com/viaversion/viaversion/util/KeyMappings.java
Normale Datei
@ -0,0 +1,51 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
|
||||||
|
* Copyright (C) 2016-2024 ViaVersion and contributors
|
||||||
|
*
|
||||||
|
* 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, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* 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.viaversion.viaversion.util;
|
||||||
|
|
||||||
|
import it.unimi.dsi.fastutil.objects.Object2IntMap;
|
||||||
|
import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap;
|
||||||
|
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||||
|
|
||||||
|
public final class KeyMappings {
|
||||||
|
|
||||||
|
private final Object2IntMap<String> keyToId;
|
||||||
|
private final String[] keys;
|
||||||
|
|
||||||
|
public KeyMappings(final String... keys) {
|
||||||
|
this.keys = keys;
|
||||||
|
keyToId = new Object2IntOpenHashMap<>(keys.length);
|
||||||
|
for (int i = 0; i < keys.length; i++) {
|
||||||
|
keyToId.put(keys[i], i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public @Nullable String idToKey(final int id) {
|
||||||
|
if (id < 0 || id >= keys.length) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return keys[id];
|
||||||
|
}
|
||||||
|
|
||||||
|
public int keyToId(final String identifier) {
|
||||||
|
return keyToId.getInt(Key.stripMinecraftNamespace(identifier));
|
||||||
|
}
|
||||||
|
|
||||||
|
public int size() {
|
||||||
|
return keys.length;
|
||||||
|
}
|
||||||
|
}
|
Laden…
In neuem Issue referenzieren
Einen Benutzer sperren