Skip to content

Commit

Permalink
Finish migrating Dimension to DimensionType
Browse files Browse the repository at this point in the history
  • Loading branch information
booky10 committed Jul 1, 2024
1 parent b01db5c commit 699fd9a
Show file tree
Hide file tree
Showing 26 changed files with 673 additions and 280 deletions.
2 changes: 2 additions & 0 deletions api/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,8 @@ mappingCompression {
compress("entity/legacy_entity_type_mappings.json")

compress("item/item_type_mappings.json")

compress("world/dimension_type_mappings.json")
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
import com.github.retrooper.packetevents.protocol.ConnectionState;
import com.github.retrooper.packetevents.protocol.item.banner.BannerPattern;
import com.github.retrooper.packetevents.protocol.item.banner.BannerPatterns;
import com.github.retrooper.packetevents.protocol.mapper.CopyableEntity;
import com.github.retrooper.packetevents.protocol.mapper.MappedEntity;
import com.github.retrooper.packetevents.protocol.nbt.NBT;
import com.github.retrooper.packetevents.protocol.nbt.NBTCompound;
Expand All @@ -41,31 +42,29 @@
import com.github.retrooper.packetevents.resources.ResourceLocation;
import com.github.retrooper.packetevents.util.mappings.IRegistry;
import com.github.retrooper.packetevents.util.mappings.SimpleRegistry;
import com.github.retrooper.packetevents.util.mappings.SimpleTypesBuilderData;
import com.github.retrooper.packetevents.util.mappings.TypesBuilderData;
import com.github.retrooper.packetevents.wrapper.configuration.server.WrapperConfigServerRegistryData;
import com.github.retrooper.packetevents.wrapper.configuration.server.WrapperConfigServerRegistryData.RegistryElement;
import com.github.retrooper.packetevents.wrapper.handshaking.client.WrapperHandshakingClientHandshake;
import com.github.retrooper.packetevents.wrapper.login.server.WrapperLoginServerLoginSuccess;
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerJoinGame;
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerRespawn;
import org.jetbrains.annotations.Nullable;

import java.net.InetSocketAddress;
import java.util.List;
import java.util.Map;
import java.util.function.BiFunction;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;

public class InternalPacketListener extends PacketListenerAbstract {

private static final Map<ResourceLocation, RegistryEntry<?>> REGISTRY_KEYS = Stream.of(
new RegistryEntry<>(BannerPatterns.getRegistry(),
BannerPattern::decode, BannerPattern::encode),
new RegistryEntry<>(DimensionTypes.getRegistry(),
DimensionType::decode, DimensionType::encode)
).collect(Collectors.toMap(
entry -> entry.baseRegistry.getRegistryKey(),
Function.identity()));
new RegistryEntry<>(BannerPatterns.getRegistry(), BannerPattern::decode),
new RegistryEntry<>(DimensionTypes.getRegistry(), DimensionType::decode)
).collect(Collectors.toMap(RegistryEntry::getRegistryKey, Function.identity()));

public InternalPacketListener() {
this(PacketListenerPriority.LOWEST);
Expand All @@ -75,15 +74,22 @@ public InternalPacketListener(PacketListenerPriority priority) {
super(priority);
}

private void handleRegistry(User user, ResourceLocation registryName, List<RegistryElement> elements) {
private void handleRegistry(
User user, ClientVersion version,
ResourceLocation registryName,
List<RegistryElement> elements
) {
RegistryEntry<?> registry = REGISTRY_KEYS.get(registryName);
if (registry != null) {
IRegistry<?> syncedRegistry = registry.createFromElements(elements);
user.putSynchronizedRegistry(syncedRegistry);
IRegistry<?> syncedRegistry = registry.createFromElements(elements, version);
user.putUserRegistry(syncedRegistry);
}
}

private void handleLegacyRegistries(User user, NBTCompound registryData) {
private void handleLegacyRegistries(
User user, ClientVersion version,
NBTCompound registryData
) {
for (NBT tag : registryData.getTags().values()) {
NBTCompound compound = (NBTCompound) tag;
// extract registry name
Expand All @@ -93,7 +99,7 @@ private void handleLegacyRegistries(User user, NBTCompound registryData) {
NBTList<NBTCompound> nbtElements =
compound.getCompoundListTagOrThrow("value");
// store registry elements
this.handleRegistry(user, registryName,
this.handleRegistry(user, version, registryName,
RegistryElement.convertNbt(nbtElements));
}
}
Expand Down Expand Up @@ -136,40 +142,34 @@ else if (event.getPacketType() == PacketType.Configuration.Server.REGISTRY_DATA)
WrapperConfigServerRegistryData packet = new WrapperConfigServerRegistryData(event);

if (packet.getElements() != null) { // 1.20.2 to 1.20.5
this.handleRegistry(user, packet.getRegistryKey(), packet.getElements());
this.handleRegistry(user, packet.getServerVersion().toClientVersion(),
packet.getRegistryKey(), packet.getElements());
}
if (packet.getRegistryData() != null) { // since 1.20.5
this.handleLegacyRegistries(user, packet.getRegistryData());
this.handleLegacyRegistries(user, packet.getServerVersion()
.toClientVersion(), packet.getRegistryData());
}
}

// The server sends registry info in login packet for 1.17 to 1.20.1
// The server sends registry info in login packet for 1.16 to 1.20.1
else if (event.getPacketType() == PacketType.Play.Server.JOIN_GAME) {
WrapperPlayServerJoinGame joinGame = new WrapperPlayServerJoinGame(event);
user.setEntityId(joinGame.getEntityId());
user.setDimension(joinGame.getDimension());

if (event.getServerVersion().isOlderThanOrEquals(ServerVersion.V_1_16_5)) {
return; // Fixed world height, no tags are sent to the client
}

if (joinGame.getDimensionCodec() != null) { // 1.16 to 1.20.1
this.handleLegacyRegistries(user, joinGame.getDimensionCodec());
this.handleLegacyRegistries(user, joinGame.getServerVersion().toClientVersion(),
joinGame.getDimensionCodec());
}

// Update world height
user.switchDimensionType(joinGame.getServerVersion(), joinGame.getDimension());
// FIXME registries need to be used WHILE decoding this packet
user.setDimensionType(joinGame.getDimensionType());
}

// Respawn is used to switch dimensions
else if (event.getPacketType() == PacketType.Play.Server.RESPAWN) {
WrapperPlayServerRespawn respawn = new WrapperPlayServerRespawn(event);
user.setDimension(respawn.getDimension());
if (event.getServerVersion().isOlderThanOrEquals(ServerVersion.V_1_16_5)) {
return; // Fixed world height, no tags are sent to the client
}

user.switchDimensionType(respawn.getServerVersion(), respawn.getDimension());
WrapperPlayServerRespawn packet = new WrapperPlayServerRespawn(event);
// FIXME registries need to be used WHILE decoding this packet
user.setDimensionType(packet.getDimensionType());
} else if (event.getPacketType() == PacketType.Play.Server.CONFIGURATION_START) {
user.setEncoderState(ConnectionState.CONFIGURATION);
} else if (event.getPacketType() == PacketType.Configuration.Server.CONFIGURATION_END) {
Expand Down Expand Up @@ -200,30 +200,34 @@ public void onPacketReceive(PacketReceiveEvent event) {
}
}

private static final class RegistryEntry<T extends MappedEntity> {
@FunctionalInterface
private interface NbtEntryDecoder<T> {

T decode(NBT nbt, ClientVersion version, @Nullable TypesBuilderData data);
}

private static final class RegistryEntry<T extends MappedEntity & CopyableEntity<T>> {

private final IRegistry<T> baseRegistry;
private final BiFunction<NBT, ClientVersion, T> decoder;
private final BiFunction<T, ClientVersion, NBT> encoder;
private final NbtEntryDecoder<T> decoder;

public RegistryEntry(
IRegistry<T> baseRegistry,
BiFunction<NBT, ClientVersion, T> decoder,
BiFunction<T, ClientVersion, NBT> encoder
NbtEntryDecoder<T> decoder
) {
this.baseRegistry = baseRegistry;
this.decoder = decoder;
this.encoder = encoder;
}

private void handleElement(
SimpleRegistry<T> registry,
RegistryElement element,
int id, ClientVersion version
) {
TypesBuilderData data = new SimpleTypesBuilderData(element.getId(), id);
if (element.getData() != null) {
// data was provided, use registry element sent over network
T value = this.decoder.apply(element.getData(), version);
T value = this.decoder.decode(element.getData(), version, data);
registry.define(element.getId(), id, value);
return;
}
Expand All @@ -242,23 +246,27 @@ private void handleElement(
ResourceLocation elementName = element.getId();
T baseEntry = this.baseRegistry.getByName(elementName);
if (baseEntry != null) {
registry.define(elementName, id, baseEntry);
registry.define(elementName, id, baseEntry.copy(data));
return;
}

// can't find this element anywhere
// TODO dummy values make at least simple stuff work?
// TODO dummy values to make at least simple stuff work?
PacketEvents.getAPI().getLogger().warning("Unknown registry entry "
+ elementName + " for " + this.baseRegistry.getRegistryKey());
+ elementName + " for " + this.getRegistryKey());
}

public IRegistry<T> createFromElements(List<RegistryElement> elements, ClientVersion version) {
SimpleRegistry<T> registry = new SimpleRegistry<>(this.baseRegistry.getRegistryKey());
SimpleRegistry<T> registry = new SimpleRegistry<>(this.getRegistryKey());
for (int id = 0; id < elements.size(); id++) {
RegistryElement element = elements.get(id);
this.handleElement(registry, element, id, version);
}
return registry;
}

public ResourceLocation getRegistryKey() {
return this.baseRegistry.getRegistryKey();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,18 @@

package com.github.retrooper.packetevents.protocol.item.banner;

import com.github.retrooper.packetevents.protocol.mapper.CopyableEntity;
import com.github.retrooper.packetevents.protocol.mapper.MappedEntity;
import com.github.retrooper.packetevents.protocol.nbt.NBT;
import com.github.retrooper.packetevents.protocol.nbt.NBTCompound;
import com.github.retrooper.packetevents.protocol.nbt.NBTString;
import com.github.retrooper.packetevents.protocol.player.ClientVersion;
import com.github.retrooper.packetevents.resources.ResourceLocation;
import com.github.retrooper.packetevents.util.mappings.TypesBuilderData;
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
import org.jetbrains.annotations.Nullable;

public interface BannerPattern extends MappedEntity {
public interface BannerPattern extends MappedEntity, CopyableEntity<BannerPattern> {

ResourceLocation getAssetId();

Expand All @@ -38,4 +45,18 @@ static void writeDirect(PacketWrapper<?> wrapper, BannerPattern pattern) {
wrapper.writeIdentifier(pattern.getAssetId());
wrapper.writeString(pattern.getTranslationKey());
}

static BannerPattern decode(NBT nbt, ClientVersion version, @Nullable TypesBuilderData data) {
NBTCompound compound = (NBTCompound) nbt;
ResourceLocation assetId = new ResourceLocation(compound.getStringTagValueOrThrow("asset_id"));
String translationKey = compound.getStringTagValueOrThrow("translation_key");
return new StaticBannerPattern(data, assetId, translationKey);
}

static NBT encode(BannerPattern bannerPattern, ClientVersion version) {
NBTCompound compound = new NBTCompound();
compound.setTag("asset_id", new NBTString(bannerPattern.getAssetId().toString()));
compound.setTag("translation_key", new NBTString(bannerPattern.getTranslationKey()));
return compound;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,11 @@ public StaticBannerPattern(@Nullable TypesBuilderData data, ResourceLocation ass
this.translationKey = translationKey;
}

@Override
public BannerPattern copy(@Nullable TypesBuilderData newData) {
return new StaticBannerPattern(newData, this.assetId, this.translationKey);
}

@Override
public ResourceLocation getAssetId() {
return this.assetId;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2024 retrooper 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.github.retrooper.packetevents.protocol.mapper;

import com.github.retrooper.packetevents.util.mappings.TypesBuilderData;
import org.jetbrains.annotations.Nullable;

public interface CopyableEntity<T extends MappedEntity> {

T copy(@Nullable TypesBuilderData newData);
}
Loading

0 comments on commit 699fd9a

Please sign in to comment.