Compare commits

..
52 Commits
Author SHA1 Message Date
Myles e9bccda259 4.3.1 Release - Fix set display preview being sent prematurely #2918 2022-06-07 23:11:21 +01:00
Nassim Jahnke 9a34ff2a51 4.3.0 Release 2022-06-05 11:31:07 +02:00
trickypr f01d9408de 1.19-rc2 (#2910) 2022-06-04 11:08:04 +02:00
Nassim Jahnke 15ff7b4c9d 1.19-rc1 2022-06-02 17:49:25 +02:00
Nassim Jahnke d47765ce45 1.19-pre5 2022-06-01 15:16:47 +02:00
Gero b82b067745 Actually make every message a system message (#2903) 2022-05-25 21:24:26 +02:00
Nassim Jahnke b7005f2400 1.19-pre3 2022-05-25 14:33:39 +02:00
roro1506HD 312fe3a851 Fixed wrong packet in MovementTransmitter when not using NMS player ticking (#2900) 2022-05-23 20:29:21 +02:00
Nassim Jahnke 69d50fa992 Join game fixes 2022-05-23 19:38:38 +02:00
Nassim Jahnke 1308dcb8dd No need to queue messages anymore
The client now uses the main registry instead of the level registry
2022-05-23 18:24:32 +02:00
Nassim Jahnke b4ecba8382 1.19-pre2 2022-05-23 18:03:18 +02:00
Nassim Jahnke 3529d6a229 Sanity check for queued messages 2022-05-21 11:00:55 +02:00
Nassim Jahnke 4213c4cce5 Queue up messages before the chat type registry has been sent
Fixes #2898
2022-05-20 15:32:10 +02:00
Nassim Jahnke 3d3e09977c Fix big fat dumb 2022-05-20 14:16:31 +02:00
Nassim Jahnke 90feac8c83 Update DebugHandler 2022-05-20 14:10:23 +02:00
Nassim Jahnke 80a807e366 Fix head yaw and pitch being swapped for mob spawns 2022-05-20 10:00:31 +02:00
Nassim Jahnke 3eba8ba922 More consistent client entity tracking 2022-05-20 09:53:39 +02:00
Nassim Jahnke 71a68bf36e Fix the client entity being untracked on world changes
Fixes #2894 and probably other things
2022-05-19 23:04:18 +02:00
Nassim Jahnke e67501cde3 Fix painting id being used too early
Fixes #2893
2022-05-19 19:54:27 +02:00
Nassim Jahnke 9aa7f5e879 Fix data stored on join being lost on Bungee
Bungee doesn't resend a join game for old servers, so we will have to keep data stored there across server switches
This likely fixes other issues with chunk data writing after server switches on legacy servers as well
2022-05-19 12:37:04 +02:00
Nassim Jahnke 854ecf0b47 1.19-pre1 2022-05-18 21:29:18 +02:00
Nassim Jahnke f538f25d63 Update OpenNBT 2022-05-16 13:33:41 +02:00
Nassim Jahnke 48a7fdc1d1 Fix command rewriter npe 2022-05-15 18:11:36 +02:00
Nassim Jahnke 1d5ae0e3e0 Use mappings instead of hardcoding entity ids 2022-05-14 11:58:45 +02:00
Nassim Jahnke f0462085d3 Add id->string methods to FullMappingData 2022-05-13 13:23:57 +02:00
Nassim Jahnke 7dc7b62cc9 22w19a (and a varying mix of removed and added dread) 2022-05-12 23:49:15 +02:00
Nassim Jahnke b9f80754e0 22w18a 2022-05-04 19:15:23 +02:00
Nassim Jahnke 5b9f775743 Use normal uuid type in gameprofile packet 2022-04-27 21:49:37 +02:00
Nassim Jahnke 0e66228a96 22w17a (and a lot of dread) 2022-04-27 21:06:34 +02:00
Nassim Jahnke 8df48bc378 StoredEntityData#remove 2022-04-20 20:16:08 +02:00
Nassim Jahnke d36d5d6def 22w16b 2022-04-20 20:00:46 +02:00
Nassim Jahnke 8b51430555 22w16a (except you have off-centered paintings) 2022-04-20 19:42:43 +02:00
Nassim Jahnke f71288e299 22w15a 2022-04-13 18:36:26 +02:00
Nassim Jahnke c0fc8195ce ?????????????????????????????????????????????????????
Also add removeTags and renameTag method to TagRewriter
2022-04-06 22:50:59 +02:00
Nassim Jahnke dd189411e6 New meta types (oh no) 2022-04-06 20:16:00 +02:00
Nassim Jahnke 4693b95bea 22w14a 2022-04-06 19:07:16 +02:00
Nassim Jahnke 596a42e312 22w13a 2022-03-31 18:46:35 +02:00
Nassim Jahnke 71944be482 Minor improvement to var int writing 2022-03-26 18:12:12 +01:00
Nassim Jahnke d1699fbb8d Merge remote-tracking branch 'origin/master' into dev 2022-03-24 19:07:28 +01:00
Nassim Jahnke bd880b608f 22w12a 2022-03-24 18:52:38 +01:00
Nassim Jahnke 3386431749 Comment out entity effect transformer 2022-03-21 10:40:52 +01:00
Nassim Jahnke c3fc8b5f18 Actually fix particles
Fixes #2850
2022-03-19 16:04:13 +01:00
Nassim Jahnke ec740476da Check world in BukkitBlockConnectionProvider
ignoring all of that still being unsafe
2022-03-19 09:37:34 +01:00
Nassim Jahnke a536ad1d10 Fix particles 2022-03-16 22:51:18 +01:00
Nassim Jahnke a1ae7818a2 Add namespace to argument type mappings 2022-03-16 20:25:00 +01:00
Nassim Jahnke 365b3a8a38 22w11a 2022-03-16 19:48:17 +01:00
RK_01 823eb1f392 Fix inventory acknowledgements being dropped sometimes (#2848) 2022-03-16 18:35:58 +01:00
Nassim Jahnke a12dfa405f 1.19 Experimental Snapshot 1 2022-03-16 18:21:41 +01:00
Nassim Jahnke 9798ec296a Update gradle wrapper to 7.4.1 2022-03-09 18:48:56 +01:00
Nassim Jahnke c1b993c01b Hotfix ProtocolLib 5.0.0 compatibility 2022-03-09 17:41:36 +01:00
Nassim Jahnke f55696a605 Bump version to 4.2.2-SNAPSHOT 2022-03-09 17:28:57 +01:00
Nassim Jahnke f361bd66ea 4.2.1 Release
Fix 1.18.2 client respawn on legacy servers
2022-02-28 16:01:41 +01:00
94 changed files with 28568 additions and 407 deletions

No files matched your search

@@ -83,6 +83,7 @@ public class ProtocolVersion {
public static final ProtocolVersion v1_17_1 = register(756, "1.17.1");
public static final ProtocolVersion v1_18 = register(757, "1.18/1.18.1", new VersionRange("1.18", 0, 1));
public static final ProtocolVersion v1_18_2 = register(758, "1.18.2");
public static final ProtocolVersion v1_19 = register(759, "1.19");
public static final ProtocolVersion unknown = register(-1, "UNKNOWN");
public static ProtocolVersion register(int version, String name) {
@@ -64,7 +64,7 @@ public interface ViaAPI<T> {
* @return API version incremented with meaningful API changes
*/
default int apiVersion() {
return 10;
return 12;
}
/**
@@ -29,4 +29,13 @@ package com.viaversion.viaversion.api.connection;
* @see UserConnection#put(StorableObject)
*/
public interface StorableObject {
/**
* Returns whether the object should be uncached on a server switch.
*
* @return whether the object should be uncached on a server switch
*/
default boolean clearOnServerSwitch() {
return true;
}
}
@@ -58,6 +58,15 @@ public interface UserConnection {
*/
boolean has(Class<? extends StorableObject> objectClass);
/**
* Removes and returns an object from the storage.
*
* @param objectClass class of the object to get
* @param <T> type of the class you want to get
* @return removed storable object if present
*/
@Nullable <T extends StorableObject> T remove(Class<T> objectClass);
/**
* Put an object into the stored objects based on class.
*
@@ -83,6 +92,7 @@ public interface UserConnection {
/**
* Adds an entity tracker to the user connection.
* Does not override existing entity trackers.
*
* @param protocolClass protocol class
* @param tracker entity tracker
@@ -91,9 +101,18 @@ public interface UserConnection {
/**
* Clear stored objects and entity trackers.
* Used for Bungee when switching servers.
*/
void clearStoredObjects();
default void clearStoredObjects() {
clearStoredObjects(false);
}
/**
* Clear stored objects and entity trackers.
* If cleared for a proxy server switch, some stored objects and tracker data will be retained.
*
* @param isServerSwitch whether the clear is due to a server switch
*/
void clearStoredObjects(boolean isServerSwitch);
/**
* Sends a raw packet to the connection on the current thread.
@@ -0,0 +1,73 @@
/*
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
* Copyright (C) 2016-2022 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.data;
import org.checkerframework.checker.nullness.qual.Nullable;
/**
* Mappings containing the full string identifier mappings.
*/
public interface FullMappings {
Mappings mappings();
/**
* Returns the unmapped integer id for the given identifier, or -1 if not found.
*
* @param identifier unmapped string identifier
* @return unmapped int id, or -1 if not found
*/
int id(String identifier);
/**
* Returns the mapped integer id for the given mapped identifier, or -1 if not found.
*
* @param mappedIdentifier mapped string identifier
* @return mapped int id, or -1 if not found
*/
int mappedId(String mappedIdentifier);
/**
* Returns the unmapped string identifier for the given mapped id.
*
* @param id unmapped id
* @return unmapped string identifier
*/
String identifier(int id);
/**
* Returns the mapped string identifier for the given mapped id.
*
* @param mappedId mapped id
* @return mapped string identifier
*/
String mappedIdentifier(int mappedId);
/**
* Returns the mapped string identifier for the given unmapped identifier.
*
* @param identifier unmapped identifier
* @return mapped string identifier, or null if not found
*/
@Nullable String mappedIdentifier(String identifier);
}
@@ -0,0 +1,89 @@
/*
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
* Copyright (C) 2016-2022 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.data;
import com.google.gson.JsonArray;
import it.unimi.dsi.fastutil.objects.Object2IntMap;
import org.checkerframework.checker.nullness.qual.Nullable;
public class FullMappingsBase implements FullMappings {
private final Object2IntMap<String> stringToId;
private final Object2IntMap<String> mappedStringToId;
private final String[] idToString;
private final String[] mappedIdToString;
private final Mappings mappings;
public FullMappingsBase(final JsonArray oldMappings, final JsonArray newMappings, final Mappings mappings) {
this.mappings = mappings;
stringToId = MappingDataLoader.arrayToMap(oldMappings);
mappedStringToId = MappingDataLoader.arrayToMap(newMappings);
stringToId.defaultReturnValue(-1);
mappedStringToId.defaultReturnValue(-1);
idToString = new String[oldMappings.size()];
for (int i = 0; i < oldMappings.size(); i++) {
idToString[i] = oldMappings.get(i).getAsString();
}
mappedIdToString = new String[newMappings.size()];
for (int i = 0; i < newMappings.size(); i++) {
mappedIdToString[i] = newMappings.get(i).getAsString();
}
}
@Override
public Mappings mappings() {
return mappings;
}
@Override
public int id(final String identifier) {
return stringToId.getInt(identifier);
}
@Override
public int mappedId(final String mappedIdentifier) {
return mappedStringToId.getInt(mappedIdentifier);
}
@Override
public String identifier(final int id) {
return idToString[id];
}
@Override
public String mappedIdentifier(final int mappedId) {
return mappedIdToString[mappedId];
}
@Override
public @Nullable String mappedIdentifier(final String identifier) {
final int id = id(identifier);
if (id == -1) {
return null;
}
final int mappedId = mappings.getNewId(id);
return mappedId != -1 ? mappedIdentifier(mappedId) : null;
}
}
@@ -0,0 +1,66 @@
/*
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
* Copyright (C) 2016-2022 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.data;
import it.unimi.dsi.fastutil.ints.Int2IntMap;
import it.unimi.dsi.fastutil.ints.Int2IntOpenHashMap;
public class Int2IntMapMappings implements Mappings {
private final Int2IntMap mappings;
private final int mappedIds;
protected Int2IntMapMappings(final Int2IntMap mappings, final int mappedIds) {
this.mappings = mappings;
this.mappedIds = mappedIds;
mappings.defaultReturnValue(-1);
}
public static Int2IntMapMappings of(final Int2IntMap mappings, final int mappedIds) {
return new Int2IntMapMappings(mappings, mappedIds);
}
public static Int2IntMapMappings of() {
return new Int2IntMapMappings(new Int2IntOpenHashMap(), -1);
}
@Override
public int getNewId(final int id) {
return mappings.get(id);
}
@Override
public void setNewId(final int id, final int newId) {
mappings.put(id, newId);
}
@Override
public int size() {
return mappings.size();
}
@Override
public int mappedSize() {
return mappedIds;
}
}
@@ -102,4 +102,12 @@ public interface MappingData {
@Nullable Mappings getSoundMappings();
@Nullable Mappings getStatisticsMappings();
@Nullable Mappings getEnchantmentMappings();
@Nullable FullMappings getEntityMappings();
@Nullable FullMappings getArgumentTypeMappings();
@Nullable Mappings getPaintingMappings();
}
@@ -44,12 +44,16 @@ public class MappingDataBase implements MappingData {
protected final String newVersion;
protected final boolean hasDiffFile;
protected Int2IntBiMap itemMappings;
protected FullMappings argumentTypeMappings;
protected FullMappings entityMappings;
protected ParticleMappings particleMappings;
protected Mappings blockMappings;
protected Mappings blockStateMappings;
protected Mappings blockEntityMappings;
protected Mappings soundMappings;
protected Mappings statisticsMappings;
protected Mappings enchantmentMappings;
protected Mappings paintingMappings;
protected Map<RegistryType, List<TagData>> tags;
protected boolean loadItems = true;
@@ -75,6 +79,11 @@ public class MappingDataBase implements MappingData {
blockEntityMappings = loadFromArray(oldMappings, newMappings, diffmapping, "blockentities");
soundMappings = loadFromArray(oldMappings, newMappings, diffmapping, "sounds");
statisticsMappings = loadFromArray(oldMappings, newMappings, diffmapping, "statistics");
enchantmentMappings = loadFromArray(oldMappings, newMappings, diffmapping, "enchantments");
paintingMappings = loadFromArray(oldMappings, newMappings, diffmapping, "paintings");
entityMappings = loadFullMappings(oldMappings, newMappings, diffmapping, "entities");
argumentTypeMappings = loadFullMappings(oldMappings, newMappings, diffmapping, "argumenttypes");
Mappings particles = loadFromArray(oldMappings, newMappings, diffmapping, "particles");
if (particles != null) {
@@ -102,6 +111,11 @@ public class MappingDataBase implements MappingData {
loadExtras(oldMappings, newMappings, diffmapping);
}
protected FullMappings loadFullMappings(JsonObject oldMappings, JsonObject newMappings, @Nullable JsonObject diffMappings, String key) {
Mappings mappings = loadFromArray(oldMappings, newMappings, diffMappings, key);
return mappings != null ? new FullMappingsBase(oldMappings.getAsJsonArray(key), newMappings.getAsJsonArray(key), mappings) : null;
}
private void loadTags(RegistryType type, JsonObject object, Object2IntMap<String> typeMapping) {
JsonObject tags = object.getAsJsonObject(type.resourceLocation());
List<TagData> tagsList = new ArrayList<>(tags.size());
@@ -148,7 +162,7 @@ public class MappingDataBase implements MappingData {
@Override
public int getNewParticleId(int id) {
return checkValidity(id, particleMappings.getMappings().getNewId(id), "particles");
return checkValidity(id, particleMappings.mappings().getNewId(id), "particles");
}
@Override
@@ -191,6 +205,26 @@ public class MappingDataBase implements MappingData {
return statisticsMappings;
}
@Override
public @Nullable Mappings getEnchantmentMappings() {
return enchantmentMappings;
}
@Override
public @Nullable FullMappings getEntityMappings() {
return entityMappings;
}
@Override
public @Nullable FullMappings getArgumentTypeMappings() {
return argumentTypeMappings;
}
@Override
public @Nullable Mappings getPaintingMappings() {
return paintingMappings;
}
protected @Nullable Mappings loadFromArray(JsonObject oldMappings, JsonObject newMappings, @Nullable JsonObject diffMappings, String key) {
if (!oldMappings.has(key) || !newMappings.has(key)) return null;
@@ -164,7 +164,7 @@ public class MappingDataLoader {
mapIdentifiers(output, oldIdentifiers, newIdentifiers, diffIdentifiers, true);
}
private static int mapIdentifierEntry(Map.Entry<String, JsonElement> entry, Object2IntMap newIdentifierMap, @Nullable JsonObject diffIdentifiers, boolean warnOnMissing) {
private static int mapIdentifierEntry(Map.Entry<String, JsonElement> entry, Object2IntMap<String> newIdentifierMap, @Nullable JsonObject diffIdentifiers, boolean warnOnMissing) {
int value = newIdentifierMap.getInt(entry.getValue().getAsString());
if (value == -1) {
// Search in diff mappings
@@ -38,6 +38,28 @@ public interface Mappings {
*/
int getNewId(int id);
/**
* Returns the mapped id from the given id, or the given default if unmapped/invalid.
*
* @param id unmapped id
* @param def fallback return value
* @return mapped id, or -1 if invalid/out of bounds
*/
default int getNewIdOrDefault(int id, int def) {
final int mappedId = getNewId(id);
return mappedId != -1 ? mappedId : def;
}
/**
* Returns whether the id has a mapping.
*
* @param id unmapped id
* @return whether the id has a mapped id
*/
default boolean contains(int id) {
return getNewId(id) != -1;
}
/**
* Manually maps a specific id.
*
@@ -25,51 +25,19 @@ package com.viaversion.viaversion.api.data;
import com.google.gson.JsonArray;
import it.unimi.dsi.fastutil.ints.IntArrayList;
import it.unimi.dsi.fastutil.ints.IntList;
import it.unimi.dsi.fastutil.objects.Object2IntMap;
public class ParticleMappings {
private final Object2IntMap<String> stringToId;
private final Object2IntMap<String> mappedStringToId;
private final Mappings mappings;
public class ParticleMappings extends FullMappingsBase {
private final IntList itemParticleIds = new IntArrayList(2);
private final IntList blockParticleIds = new IntArrayList(4);
public ParticleMappings(JsonArray oldMappings, JsonArray newMappings, Mappings mappings) {
this.mappings = mappings;
stringToId = MappingDataLoader.arrayToMap(oldMappings);
mappedStringToId = MappingDataLoader.arrayToMap(newMappings);
stringToId.defaultReturnValue(-1);
mappedStringToId.defaultReturnValue(-1);
super(oldMappings, newMappings, mappings);
addBlockParticle("block");
addBlockParticle("falling_dust");
addBlockParticle("block_marker");
addItemParticle("item");
}
/**
* Returns the unmapped integer id for the given identifier, or -1 if not found.
*
* @param identifier unmapped string identifier
* @return unmapped int id, or -1 if not found
*/
public int id(String identifier) {
return stringToId.getInt(identifier);
}
/**
* Returns the mapped integer id for the given mapped identifier, or -1 if not found.
*
* @param mappedIdentifier mapped string identifier
* @return mapped int id, or -1 if not found
*/
public int mappedId(String mappedIdentifier) {
return mappedStringToId.getInt(mappedIdentifier);
}
public Mappings getMappings() {
return mappings;
}
public boolean addItemParticle(final String identifier) {
final int id = id(identifier);
return id != -1 && itemParticleIds.add(id);
@@ -0,0 +1,30 @@
/*
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
* Copyright (C) 2016-2022 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.data.entity;
public interface DimensionData {
int minY();
int height();
}
@@ -26,6 +26,8 @@ import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.api.minecraft.entities.EntityType;
import org.checkerframework.checker.nullness.qual.Nullable;
import java.util.Map;
public interface EntityTracker {
/**
@@ -151,4 +153,18 @@ public interface EntityTracker {
int biomesSent();
void setBiomesSent(int biomesSent);
EntityType playerType();
@Nullable DimensionData dimensionData(String dimension);
void setDimensions(Map<String, DimensionData> dimensions);
/**
* Adds the client player entity to the tracker.
* If the client entity has not been set yet, this will return false.
*
* @return whether the client has been tracked
*/
boolean trackClientEntity();
}
@@ -51,6 +51,15 @@ public interface StoredEntityData {
*/
@Nullable <T> T get(Class<T> objectClass);
/**
* Removes and returns an object from the storage if present.
*
* @param objectClass class of the object to remove
* @param <T> object type
* @return removed object if present
*/
@Nullable <T> T remove(Class<T> objectClass);
/**
* Stores an object based on its class.
*
@@ -22,8 +22,12 @@
*/
package com.viaversion.viaversion.api.debug;
import com.google.common.annotations.Beta;
import com.viaversion.viaversion.api.protocol.packet.Direction;
import com.viaversion.viaversion.api.protocol.packet.PacketType;
import com.viaversion.viaversion.api.protocol.packet.PacketWrapper;
@Beta
public interface DebugHandler {
/**
@@ -47,6 +51,14 @@ public interface DebugHandler {
*/
void addPacketTypeNameToLog(String packetTypeName);
/**
* Adds a packet id to the list of packet types to log.
* Packets will be checked on each protocol transformer, so this is best used on single protocol pipes.
*
* @param packetType packet type
*/
void addPacketTypeToLog(PacketType packetType);
/**
* Removes a packet type name from the list of packet types to log.
*
@@ -78,8 +90,16 @@ public interface DebugHandler {
* Returns whether the given packet should be logged.
* If no specific packet type has been added, all packet types will be logged.
*
* @param wrapper packet wrapper
* @param wrapper packet wrapper
* @param direction packet direction
* @return whether the packet should be logged
*/
boolean shouldLog(PacketWrapper wrapper);
boolean shouldLog(PacketWrapper wrapper, Direction direction);
default void enableAndLogIds(final PacketType... packetTypes) {
setEnabled(true);
for (final PacketType packetType : packetTypes) {
addPacketTypeToLog(packetType);
}
}
}
@@ -0,0 +1,66 @@
/*
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
* Copyright (C) 2016-2022 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;
public final class GlobalPosition extends Position {
private final String dimension;
public GlobalPosition(final String dimension, final int x, final int y, final int z) {
super(x, y, z);
this.dimension = dimension;
}
public String dimension() {
return dimension;
}
@Override
public boolean equals(final Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
final GlobalPosition position = (GlobalPosition) o;
if (x != position.x) return false;
if (y != position.y) return false;
if (z != position.z) return false;
return dimension.equals(position.dimension);
}
@Override
public int hashCode() {
int result = dimension.hashCode();
result = 31 * result + x;
result = 31 * result + y;
result = 31 * result + z;
return result;
}
@Override
public String toString() {
return "GlobalPosition{" +
"dimension='" + dimension + '\'' +
", x=" + x +
", y=" + y +
", z=" + z +
'}';
}
}
@@ -23,9 +23,9 @@
package com.viaversion.viaversion.api.minecraft;
public class Position {
private final int x;
private final int y;
private final int z;
protected final int x;
protected final int y;
protected final int z;
public Position(int x, int y, int z) {
this.x = x;
@@ -59,6 +59,10 @@ public class Position {
return z;
}
public GlobalPosition withDimension(String dimension) {
return new GlobalPosition(dimension, x, y, z);
}
@Deprecated/*(forRemoval=true)*/
public int getX() {
return x;
@@ -0,0 +1,47 @@
/*
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
* Copyright (C) 2016-2022 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;
public class Position3d {
private final double x;
private final double y;
private final double z;
public Position3d(final double x, final double y, final double z) {
this.x = x;
this.y = y;
this.z = z;
}
public double x() {
return x;
}
public double y() {
return y;
}
public double z() {
return z;
}
}
@@ -170,6 +170,16 @@ public class Entity1_10Types {
public EntityType getParent() {
return parent;
}
@Override
public String identifier() {
throw new UnsupportedOperationException();
}
@Override
public boolean isAbstractType() {
return id != -1;
}
}
public enum ObjectType implements com.viaversion.viaversion.api.minecraft.entities.ObjectType {
@@ -187,6 +187,16 @@ public class Entity1_11Types {
return parent;
}
@Override
public String identifier() {
throw new UnsupportedOperationException();
}
@Override
public boolean isAbstractType() {
return id != -1;
}
static {
for (EntityType type : EntityType.values()) {
TYPES.put(type.id, type);
@@ -191,6 +191,16 @@ public class Entity1_12Types {
return parent;
}
@Override
public String identifier() {
throw new UnsupportedOperationException();
}
@Override
public boolean isAbstractType() {
return id != -1;
}
static {
for (EntityType type : EntityType.values()) {
TYPES.put(type.id, type);
@@ -240,6 +240,16 @@ public class Entity1_13Types {
return parent;
}
@Override
public String identifier() {
throw new UnsupportedOperationException();
}
@Override
public boolean isAbstractType() {
return id != -1;
}
static {
for (EntityType type : EntityType.values()) {
TYPES.put(type.id, type);
@@ -224,6 +224,16 @@ public enum Entity1_14Types implements EntityType {
return parent;
}
@Override
public String identifier() {
throw new UnsupportedOperationException();
}
@Override
public boolean isAbstractType() {
return id != -1;
}
static {
TYPES = EntityTypeUtil.toOrderedArray(values());
}
@@ -226,6 +226,16 @@ public enum Entity1_15Types implements EntityType {
return parent;
}
@Override
public String identifier() {
throw new UnsupportedOperationException();
}
@Override
public boolean isAbstractType() {
return id != -1;
}
static {
TYPES = EntityTypeUtil.toOrderedArray(values());
}
@@ -231,6 +231,16 @@ public enum Entity1_16Types implements EntityType {
return parent;
}
@Override
public String identifier() {
throw new UnsupportedOperationException();
}
@Override
public boolean isAbstractType() {
return id != -1;
}
static {
TYPES = EntityTypeUtil.toOrderedArray(values());
}
@@ -235,6 +235,16 @@ public enum Entity1_16_2Types implements EntityType {
return parent;
}
@Override
public String identifier() {
throw new UnsupportedOperationException();
}
@Override
public boolean isAbstractType() {
return id != -1;
}
static {
TYPES = EntityTypeUtil.toOrderedArray(values());
}
@@ -240,6 +240,16 @@ public enum Entity1_17Types implements EntityType {
return parent;
}
@Override
public String identifier() {
throw new UnsupportedOperationException();
}
@Override
public boolean isAbstractType() {
return id != -1;
}
static {
TYPES = EntityTypeUtil.toOrderedArray(values());
}
@@ -0,0 +1,283 @@
/*
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
* Copyright (C) 2016-2022 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.entities;
import com.google.common.base.Preconditions;
import com.viaversion.viaversion.api.protocol.Protocol;
import com.viaversion.viaversion.util.EntityTypeUtil;
import org.checkerframework.checker.nullness.qual.Nullable;
import java.util.Locale;
public enum Entity1_19Types implements EntityType {
ENTITY(null, null),
AREA_EFFECT_CLOUD(ENTITY),
END_CRYSTAL(ENTITY),
EVOKER_FANGS(ENTITY),
EXPERIENCE_ORB(ENTITY),
EYE_OF_ENDER(ENTITY),
FALLING_BLOCK(ENTITY),
FIREWORK_ROCKET(ENTITY),
ITEM(ENTITY),
LLAMA_SPIT(ENTITY),
TNT(ENTITY),
SHULKER_BULLET(ENTITY),
FISHING_BOBBER(ENTITY),
LIVINGENTITY(ENTITY, null),
ARMOR_STAND(LIVINGENTITY),
MARKER(ENTITY),
PLAYER(LIVINGENTITY),
ABSTRACT_INSENTIENT(LIVINGENTITY, null),
ENDER_DRAGON(ABSTRACT_INSENTIENT),
BEE(ABSTRACT_INSENTIENT),
ABSTRACT_CREATURE(ABSTRACT_INSENTIENT, null),
ABSTRACT_AGEABLE(ABSTRACT_CREATURE, null),
VILLAGER(ABSTRACT_AGEABLE),
WANDERING_TRADER(ABSTRACT_AGEABLE),
// Animals
ABSTRACT_ANIMAL(ABSTRACT_AGEABLE, null),
AXOLOTL(ABSTRACT_ANIMAL),
DOLPHIN(ABSTRACT_INSENTIENT),
CHICKEN(ABSTRACT_ANIMAL),
COW(ABSTRACT_ANIMAL),
MOOSHROOM(COW),
PANDA(ABSTRACT_INSENTIENT),
PIG(ABSTRACT_ANIMAL),
POLAR_BEAR(ABSTRACT_ANIMAL),
RABBIT(ABSTRACT_ANIMAL),
SHEEP(ABSTRACT_ANIMAL),
TURTLE(ABSTRACT_ANIMAL),
FOX(ABSTRACT_ANIMAL),
FROG(ABSTRACT_ANIMAL),
GOAT(ABSTRACT_ANIMAL),
ABSTRACT_TAMEABLE_ANIMAL(ABSTRACT_ANIMAL, null),
CAT(ABSTRACT_TAMEABLE_ANIMAL),
OCELOT(ABSTRACT_TAMEABLE_ANIMAL),
WOLF(ABSTRACT_TAMEABLE_ANIMAL),
ABSTRACT_PARROT(ABSTRACT_TAMEABLE_ANIMAL, null),
PARROT(ABSTRACT_PARROT),
// Horses
ABSTRACT_HORSE(ABSTRACT_ANIMAL, null),
CHESTED_HORSE(ABSTRACT_HORSE, null),
DONKEY(CHESTED_HORSE),
MULE(CHESTED_HORSE),
LLAMA(CHESTED_HORSE),
TRADER_LLAMA(CHESTED_HORSE),
HORSE(ABSTRACT_HORSE),
SKELETON_HORSE(ABSTRACT_HORSE),
ZOMBIE_HORSE(ABSTRACT_HORSE),
// Golem
ABSTRACT_GOLEM(ABSTRACT_CREATURE, null),
SNOW_GOLEM(ABSTRACT_GOLEM),
IRON_GOLEM(ABSTRACT_GOLEM),
SHULKER(ABSTRACT_GOLEM),
// Fish
ABSTRACT_FISHES(ABSTRACT_CREATURE, null),
COD(ABSTRACT_FISHES),
PUFFERFISH(ABSTRACT_FISHES),
SALMON(ABSTRACT_FISHES),
TROPICAL_FISH(ABSTRACT_FISHES),
// Monsters
ABSTRACT_MONSTER(ABSTRACT_CREATURE, null),
BLAZE(ABSTRACT_MONSTER),
CREEPER(ABSTRACT_MONSTER),
ENDERMITE(ABSTRACT_MONSTER),
ENDERMAN(ABSTRACT_MONSTER),
GIANT(ABSTRACT_MONSTER),
SILVERFISH(ABSTRACT_MONSTER),
VEX(ABSTRACT_MONSTER),
WITCH(ABSTRACT_MONSTER),
WITHER(ABSTRACT_MONSTER),
RAVAGER(ABSTRACT_MONSTER),
ABSTRACT_PIGLIN(ABSTRACT_MONSTER, null),
PIGLIN(ABSTRACT_PIGLIN),
PIGLIN_BRUTE(ABSTRACT_PIGLIN),
HOGLIN(ABSTRACT_ANIMAL),
STRIDER(ABSTRACT_ANIMAL),
TADPOLE(ABSTRACT_FISHES),
ZOGLIN(ABSTRACT_MONSTER),
WARDEN(ABSTRACT_MONSTER),
// Illagers
ABSTRACT_ILLAGER_BASE(ABSTRACT_MONSTER, null),
ABSTRACT_EVO_ILLU_ILLAGER(ABSTRACT_ILLAGER_BASE, null),
EVOKER(ABSTRACT_EVO_ILLU_ILLAGER),
ILLUSIONER(ABSTRACT_EVO_ILLU_ILLAGER),
VINDICATOR(ABSTRACT_ILLAGER_BASE),
PILLAGER(ABSTRACT_ILLAGER_BASE),
// Skeletons
ABSTRACT_SKELETON(ABSTRACT_MONSTER, null),
SKELETON(ABSTRACT_SKELETON),
STRAY(ABSTRACT_SKELETON),
WITHER_SKELETON(ABSTRACT_SKELETON),
// Guardians
GUARDIAN(ABSTRACT_MONSTER),
ELDER_GUARDIAN(GUARDIAN),
// Spiders
SPIDER(ABSTRACT_MONSTER),
CAVE_SPIDER(SPIDER),
// Zombies
ZOMBIE(ABSTRACT_MONSTER),
DROWNED(ZOMBIE),
HUSK(ZOMBIE),
ZOMBIFIED_PIGLIN(ZOMBIE),
ZOMBIE_VILLAGER(ZOMBIE),
// Flying entities
ABSTRACT_FLYING(ABSTRACT_INSENTIENT, null),
GHAST(ABSTRACT_FLYING),
PHANTOM(ABSTRACT_FLYING),
ABSTRACT_AMBIENT(ABSTRACT_INSENTIENT, null),
BAT(ABSTRACT_AMBIENT),
ALLAY(ABSTRACT_CREATURE),
ABSTRACT_WATERMOB(ABSTRACT_INSENTIENT, null),
SQUID(ABSTRACT_WATERMOB),
GLOW_SQUID(SQUID),
// Slimes
SLIME(ABSTRACT_INSENTIENT),
MAGMA_CUBE(SLIME),
// Hangable objects
ABSTRACT_HANGING(ENTITY, null),
LEASH_KNOT(ABSTRACT_HANGING),
ITEM_FRAME(ABSTRACT_HANGING),
GLOW_ITEM_FRAME(ITEM_FRAME),
PAINTING(ABSTRACT_HANGING),
ABSTRACT_LIGHTNING(ENTITY, null),
LIGHTNING_BOLT(ABSTRACT_LIGHTNING),
// Arrows
ABSTRACT_ARROW(ENTITY, null),
ARROW(ABSTRACT_ARROW),
SPECTRAL_ARROW(ABSTRACT_ARROW),
TRIDENT(ABSTRACT_ARROW),
// Fireballs
ABSTRACT_FIREBALL(ENTITY, null),
DRAGON_FIREBALL(ABSTRACT_FIREBALL),
FIREBALL(ABSTRACT_FIREBALL),
SMALL_FIREBALL(ABSTRACT_FIREBALL),
WITHER_SKULL(ABSTRACT_FIREBALL),
// Projectiles
PROJECTILE_ABSTRACT(ENTITY, null),
SNOWBALL(PROJECTILE_ABSTRACT),
ENDER_PEARL(PROJECTILE_ABSTRACT),
EGG(PROJECTILE_ABSTRACT),
POTION(PROJECTILE_ABSTRACT),
EXPERIENCE_BOTTLE(PROJECTILE_ABSTRACT),
// Vehicles
MINECART_ABSTRACT(ENTITY, null),
CHESTED_MINECART_ABSTRACT(MINECART_ABSTRACT, null),
CHEST_MINECART(CHESTED_MINECART_ABSTRACT),
HOPPER_MINECART(CHESTED_MINECART_ABSTRACT),
MINECART(MINECART_ABSTRACT),
FURNACE_MINECART(MINECART_ABSTRACT),
COMMAND_BLOCK_MINECART(MINECART_ABSTRACT),
TNT_MINECART(MINECART_ABSTRACT),
SPAWNER_MINECART(MINECART_ABSTRACT),
BOAT(ENTITY),
CHEST_BOAT(BOAT);
private static final EntityType[] TYPES = EntityTypeUtil.createSizedArray(values());
private final EntityType parent;
private final String identifier;
private int id = -1;
Entity1_19Types(final EntityType parent) {
this.parent = parent;
this.identifier = "minecraft:" + name().toLowerCase(Locale.ROOT);
}
Entity1_19Types(final EntityType parent, @Nullable final String identifier) {
this.parent = parent;
this.identifier = identifier;
}
@Override
public int getId() {
if (id == -1) {
throw new IllegalStateException("Ids have not been initialized yet (type " + name() + ")");
}
return id;
}
@Override
public String identifier() {
Preconditions.checkArgument(identifier != null, "Called identifier method on abstract type");
return identifier;
}
@Override
public @Nullable EntityType getParent() {
return parent;
}
@Override
public boolean isAbstractType() {
return identifier == null;
}
public static EntityType getTypeFromId(final int typeId) {
return EntityTypeUtil.getTypeFromId(TYPES, typeId, ENTITY);
}
public static void initialize(final Protocol<?, ?, ?, ?> protocol) {
for (final Entity1_19Types type : values()) {
if (type.isAbstractType()) {
continue;
}
final int id = protocol.getMappingData().getEntityMappings().mappedId(type.identifier());
Preconditions.checkArgument(id != -1, "Entity type %s has no id", type.identifier());
type.id = id;
}
EntityTypeUtil.fill(values(), TYPES);
}
}
@@ -30,6 +30,7 @@ public interface EntityType {
* Returns the entity id.
*
* @return entity id
* @throws IllegalStateException if ids have not been loaded yet
*/
int getId();
@@ -47,6 +48,22 @@ public interface EntityType {
*/
String name();
/**
* Returns the entity's Vanilla identifier.
*
* @return entity identifier
* @throws IllegalArgumentException if {@link #isAbstractType()} returns true
*/
String identifier();
/**
* Returns whether the type does not represent an actual entity, e.g. animal or monster.
*
* @return whether the type does not represent an actual entity
*/
boolean isAbstractType();
@Deprecated/*(forRemoval = true)*/
default boolean is(EntityType... types) {
for (EntityType type : types) {
if (this == type) {
@@ -0,0 +1,59 @@
/*
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
* Copyright (C) 2016-2022 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.metadata.types;
import com.viaversion.viaversion.api.minecraft.metadata.MetaType;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.api.type.types.minecraft.ParticleType;
public final class MetaTypes1_19 extends AbstractMetaTypes {
public final MetaType byteType = add(0, Type.BYTE);
public final MetaType varIntType = add(1, Type.VAR_INT);
public final MetaType floatType = add(2, Type.FLOAT);
public final MetaType stringType = add(3, Type.STRING);
public final MetaType componentType = add(4, Type.COMPONENT);
public final MetaType optionalComponentType = add(5, Type.OPTIONAL_COMPONENT);
public final MetaType itemType = add(6, Type.FLAT_VAR_INT_ITEM);
public final MetaType booleanType = add(7, Type.BOOLEAN);
public final MetaType rotationType = add(8, Type.ROTATION);
public final MetaType positionType = add(9, Type.POSITION1_14);
public final MetaType optionalPositionType = add(10, Type.OPTIONAL_POSITION_1_14);
public final MetaType directionType = add(11, Type.VAR_INT);
public final MetaType optionalUUIDType = add(12, Type.OPTIONAL_UUID);
public final MetaType blockStateType = add(13, Type.VAR_INT);
public final MetaType nbtType = add(14, Type.NBT);
public final MetaType particleType;
public final MetaType villagerDatatType = add(16, Type.VILLAGER_DATA);
public final MetaType optionalVarIntType = add(17, Type.OPTIONAL_VAR_INT);
public final MetaType poseType = add(18, Type.VAR_INT);
public final MetaType catVariantType = add(19, Type.VAR_INT);
public final MetaType frogVariantType = add(20, Type.VAR_INT);
public final MetaType optionalGlobalPosition = add(21, Type.OPTIONAL_GLOBAL_POSITION);
public final MetaType paintingVariantType = add(22, Type.VAR_INT);
public MetaTypes1_19(final ParticleType particleType) {
super(23);
this.particleType = add(15, particleType);
}
}
@@ -351,7 +351,7 @@ public abstract class AbstractProtocol<C1 extends ClientboundPacketType, C2 exte
throw e;
}
private String toNiceHex(int id) {
public static String toNiceHex(int id) {
String hex = Integer.toHexString(id).toUpperCase();
return (hex.length() == 1 ? "0x0" : "0x") + hex;
}
@@ -80,6 +80,7 @@ public class ProtocolVersion {
public static final ProtocolVersion v1_17_1 = register(756, "1.17.1");
public static final ProtocolVersion v1_18 = register(757, "1.18/1.18.1", new VersionRange("1.18", 0, 1));
public static final ProtocolVersion v1_18_2 = register(758, "1.18.2");
public static final ProtocolVersion v1_19 = register(759, "1.19");
public static final ProtocolVersion unknown = register(-1, "UNKNOWN");
public static ProtocolVersion register(int version, String name) {
@@ -49,6 +49,9 @@ public abstract class RewriterBase<T extends Protocol> implements Rewriter<T> {
protected void registerRewrites() {
}
public void onMappingDataLoaded() {
}
@Override
public T protocol() {
return protocol;
@@ -27,6 +27,7 @@ import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
import com.google.gson.JsonElement;
import com.viaversion.viaversion.api.minecraft.BlockChangeRecord;
import com.viaversion.viaversion.api.minecraft.EulerAngle;
import com.viaversion.viaversion.api.minecraft.GlobalPosition;
import com.viaversion.viaversion.api.minecraft.Position;
import com.viaversion.viaversion.api.minecraft.Vector;
import com.viaversion.viaversion.api.minecraft.VillagerData;
@@ -66,6 +67,7 @@ import com.viaversion.viaversion.api.type.types.minecraft.OptPosition1_14Type;
import com.viaversion.viaversion.api.type.types.minecraft.OptPositionType;
import com.viaversion.viaversion.api.type.types.minecraft.OptUUIDType;
import com.viaversion.viaversion.api.type.types.minecraft.OptionalComponentType;
import com.viaversion.viaversion.api.type.types.minecraft.OptionalGlobalPositionType;
import com.viaversion.viaversion.api.type.types.minecraft.OptionalVarIntType;
import com.viaversion.viaversion.api.type.types.minecraft.Position1_14Type;
import com.viaversion.viaversion.api.type.types.minecraft.PositionType;
@@ -154,6 +156,7 @@ public abstract class Type<T> implements ByteBufReader<T>, ByteBufWriter<T> {
public static final Type<Position> OPTIONAL_POSITION = new OptPositionType();
public static final Type<Position> OPTIONAL_POSITION_1_14 = new OptPosition1_14Type();
public static final Type<GlobalPosition> OPTIONAL_GLOBAL_POSITION = new OptionalGlobalPositionType();
public static final Type<BlockChangeRecord> BLOCK_CHANGE_RECORD = new BlockChangeRecordType();
public static final Type<BlockChangeRecord[]> BLOCK_CHANGE_RECORD_ARRAY = new ArrayType<>(Type.BLOCK_CHANGE_RECORD);
@@ -28,40 +28,37 @@ import io.netty.buffer.ByteBuf;
public class VarIntType extends Type<Integer> implements TypeConverter<Integer> {
private static final int CONTINUE_BIT = 0x80;
private static final int VALUE_BITS = 0x7F;
private static final int MULTI_BYTE_BITS = ~VALUE_BITS;
private static final int MAX_BYTES = 5;
public VarIntType() {
super("VarInt", Integer.class);
}
public int readPrimitive(ByteBuf buffer) {
int out = 0;
int value = 0;
int bytes = 0;
byte in;
do {
in = buffer.readByte();
out |= (in & 0x7F) << (bytes++ * 7);
if (bytes > 5) { // 5 is maxBytes
value |= (in & VALUE_BITS) << (bytes++ * 7);
if (bytes > MAX_BYTES) {
throw new RuntimeException("VarInt too big");
}
} while ((in & 0x80) == 0x80);
return out;
} while ((in & CONTINUE_BIT) == CONTINUE_BIT);
return value;
}
public void writePrimitive(ByteBuf buffer, int object) {
int part;
do {
part = object & 0x7F;
public void writePrimitive(ByteBuf buffer, int value) {
while ((value & MULTI_BYTE_BITS) != 0) {
buffer.writeByte((value & VALUE_BITS) | CONTINUE_BIT);
value >>>= 7;
}
object >>>= 7;
if (object != 0) {
part |= 0x80;
}
buffer.writeByte(part);
} while (object != 0);
buffer.writeByte(value);
}
/**
@@ -0,0 +1,52 @@
/*
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
* Copyright (C) 2016-2022 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.type.types.minecraft;
import com.viaversion.viaversion.api.minecraft.GlobalPosition;
import com.viaversion.viaversion.api.type.Type;
import io.netty.buffer.ByteBuf;
public class OptionalGlobalPositionType extends Type<GlobalPosition> {
public OptionalGlobalPositionType() {
super(GlobalPosition.class);
}
@Override
public GlobalPosition read(ByteBuf buffer) throws Exception {
if (buffer.readBoolean()) {
final String dimension = Type.STRING.read(buffer);
return Type.POSITION1_14.read(buffer).withDimension(dimension);
}
return null;
}
@Override
public void write(ByteBuf buffer, GlobalPosition object) throws Exception {
buffer.writeBoolean(object != null);
if (object != null) {
Type.STRING.write(buffer, object.dimension());
Type.POSITION1_14.write(buffer, object);
}
}
}
@@ -117,6 +117,12 @@ public class ParticleType extends Type<Particle> {
}
particle.add(Type.VAR_INT, Type.VAR_INT.readPrimitive(buf)); // Arrival in ticks
};
public static final ParticleReader SCULK_CHARGE = (buf, particle) -> {
particle.add(Type.FLOAT, Type.FLOAT.readPrimitive(buf)); // Roll
};
public static final ParticleReader SHRIEK = (buf, particle) -> {
particle.add(Type.VAR_INT, Type.VAR_INT.readPrimitive(buf)); // Delay
};
}
public final class ParticleTypeFiller {
@@ -0,0 +1,39 @@
/*
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
* Copyright (C) 2016-2022 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.type.types.version;
import com.viaversion.viaversion.api.minecraft.metadata.Metadata;
import com.viaversion.viaversion.api.minecraft.metadata.types.MetaTypes1_19;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.api.type.types.minecraft.MetaListType;
import com.viaversion.viaversion.api.type.types.minecraft.ParticleType;
import java.util.List;
public final class Types1_19 {
public static final ParticleType PARTICLE = new ParticleType(); // Only safe to use after protocol loading
public static final MetaTypes1_19 META_TYPES = new MetaTypes1_19(PARTICLE);
public static final Type<Metadata> METADATA = new MetadataType(META_TYPES);
public static final Type<List<Metadata>> METADATA_LIST = new MetaListType(METADATA);
}
@@ -37,9 +37,9 @@ public class EntityTypeUtil {
* @param values entity types
* @return ordered array with each index representing the actual entity id
*/
public static EntityType[] toOrderedArray(EntityType[] values) {
List<EntityType> types = new ArrayList<>();
for (EntityType type : values) {
public static EntityType[] toOrderedArray(final EntityType[] values) {
final List<EntityType> types = new ArrayList<>();
for (final EntityType type : values) {
if (type.getId() != -1) {
types.add(type);
}
@@ -49,6 +49,24 @@ public class EntityTypeUtil {
return types.toArray(new EntityType[0]);
}
public static EntityType[] createSizedArray(final EntityType[] values) {
int count = 0;
for (final EntityType type : values) {
if (!type.isAbstractType()) {
count++;
}
}
return new EntityType[(int) count];
}
public static void fill(final EntityType[] values, final EntityType[] toFill) {
for (final EntityType type : values) {
if (!type.isAbstractType()) {
toFill[type.getId()] = type;
}
}
}
/**
* Returns the entity type from id, or the given fallback if out of bounds.
*
@@ -57,8 +75,8 @@ public class EntityTypeUtil {
* @param fallback fallback/base entity type
* @return entity type from id
*/
public static EntityType getTypeFromId(EntityType[] values, int typeId, EntityType fallback) {
EntityType type;
public static EntityType getTypeFromId(final EntityType[] values, final int typeId, final EntityType fallback) {
final EntityType type;
if (typeId < 0 || typeId >= values.length || (type = values[typeId]) == null) {
Via.getPlatform().getLogger().severe("Could not find " + fallback.getClass().getSimpleName() + " type id " + typeId);
return fallback;
@@ -17,13 +17,13 @@
*/
package com.viaversion.viaversion.bukkit.providers;
import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.protocols.protocol1_13to1_12_2.blockconnections.providers.BlockConnectionProvider;
import org.bukkit.Bukkit;
import org.bukkit.Chunk;
import org.bukkit.World;
import org.bukkit.block.Block;
import org.bukkit.entity.Player;
import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.protocols.protocol1_13to1_12_2.blockconnections.providers.BlockConnectionProvider;
import java.util.UUID;
@@ -48,7 +48,7 @@ public class BukkitBlockConnectionProvider extends BlockConnectionProvider {
}
public Chunk getChunk(World world, int x, int z) {
if (lastChunk != null && lastChunk.getX() == x && lastChunk.getZ() == z) {
if (lastChunk != null && lastChunk.getWorld().equals(world) && lastChunk.getX() == x && lastChunk.getZ() == z) {
return lastChunk;
}
return lastChunk = world.getChunkAt(x, z);
@@ -89,8 +89,8 @@ public class ViaVersionPlugin extends JavaPlugin implements ViaPlatform<Player>
@Override
public void onLoad() {
// Via should load before PL, so we can't check for it in the constructor
boolean hasProtocolLib = Bukkit.getPluginManager().getPlugin("ProtocolLib") != null;
((BukkitViaInjector) Via.getManager().getInjector()).setProtocolLib(hasProtocolLib);
Plugin protocolLib = Bukkit.getPluginManager().getPlugin("ProtocolLib");
ProtocolLibEnableListener.checkCompat(protocolLib);
// Spigot detector
try {
@@ -23,6 +23,8 @@ import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.server.PluginDisableEvent;
import org.bukkit.event.server.PluginEnableEvent;
import org.bukkit.plugin.Plugin;
import org.jetbrains.annotations.Nullable;
public class ProtocolLibEnableListener implements Listener {
@@ -30,7 +32,7 @@ public class ProtocolLibEnableListener implements Listener {
public void onPluginEnable(PluginEnableEvent e) {
// Will likely never happen, but try to account for hacky plugin loading systems anyways
if (e.getPlugin().getName().equals("ProtocolLib")) {
((BukkitViaInjector) Via.getManager().getInjector()).setProtocolLib(true);
checkCompat(e.getPlugin());
}
}
@@ -40,4 +42,21 @@ public class ProtocolLibEnableListener implements Listener {
((BukkitViaInjector) Via.getManager().getInjector()).setProtocolLib(false);
}
}
public static void checkCompat(@Nullable Plugin protocolLib) {
if (protocolLib != null) {
String version = protocolLib.getDescription().getVersion();
String majorVersion = version.split("\\.", 2)[0];
try {
// Only need the compat check for version < 5
if (Integer.parseInt(majorVersion) < 5) {
((BukkitViaInjector) Via.getManager().getInjector()).setProtocolLib(true);
return;
}
} catch (NumberFormatException ignored) {
Via.getPlatform().getLogger().warning("ProtocolLib version check failed for version " + version);
}
}
((BukkitViaInjector) Via.getManager().getInjector()).setProtocolLib(false);
}
}
@@ -84,14 +84,14 @@ public class BukkitViaMovementTransmitter extends MovementTransmitterProvider {
public Object getFlyingPacket() {
if (idlePacket == null)
throw new NullPointerException("Could not locate flying packet");
return idlePacket2;
return idlePacket;
}
@Override
public Object getGroundPacket() {
if (idlePacket == null)
throw new NullPointerException("Could not locate flying packet");
return idlePacket;
return idlePacket2;
}
@Override
@@ -48,9 +48,12 @@ import net.md_5.bungee.protocol.packet.PluginMessage;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.nio.charset.StandardCharsets;
import java.util.*;
import java.util.stream.Collectors;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.UUID;
public class BungeeServerHandler implements Listener {
private static Method getHandshake;
@@ -184,7 +187,7 @@ public class BungeeServerHandler implements Listener {
// Refresh the pipes
List<ProtocolPathEntry> protocolPath = Via.getManager().getProtocolManager().getProtocolPath(info.getProtocolVersion(), protocolId);
ProtocolPipeline pipeline = user.getProtocolInfo().getPipeline();
user.clearStoredObjects();
user.clearStoredObjects(true);
pipeline.cleanPipes();
if (protocolPath == null) {
// TODO Check Bungee Supported Protocols? *shrugs*
@@ -93,6 +93,11 @@ public class UserConnectionImpl implements UserConnection {
return storedObjects.containsKey(objectClass);
}
@Override
public <T extends StorableObject> @Nullable T remove(Class<T> objectClass) {
return (T) storedObjects.remove(objectClass);
}
@Override
public void put(StorableObject object) {
storedObjects.put(object.getClass(), object);
@@ -110,13 +115,23 @@ public class UserConnectionImpl implements UserConnection {
@Override
public void addEntityTracker(Class<? extends Protocol> protocolClass, EntityTracker tracker) {
entityTrackers.put(protocolClass, tracker);
if (!entityTrackers.containsKey(protocolClass)) {
entityTrackers.put(protocolClass, tracker);
}
}
@Override
public void clearStoredObjects() {
storedObjects.clear();
entityTrackers.clear();
public void clearStoredObjects(boolean isServerSwitch) {
if (isServerSwitch) {
storedObjects.values().removeIf(StorableObject::clearOnServerSwitch);
for (EntityTracker tracker : entityTrackers.values()) {
tracker.clearEntities();
tracker.trackClientEntity();
}
} else {
storedObjects.clear();
entityTrackers.clear();
}
}
@Override
@@ -0,0 +1,69 @@
/*
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
* Copyright (C) 2016-2022 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.data.entity;
import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
import com.github.steveice10.opennbt.tag.builtin.IntTag;
import com.github.steveice10.opennbt.tag.builtin.NumberTag;
import com.github.steveice10.opennbt.tag.builtin.Tag;
import com.viaversion.viaversion.api.data.entity.DimensionData;
public final class DimensionDataImpl implements DimensionData {
private final int minY;
private final int height;
public DimensionDataImpl(final int minY, final int height) {
this.minY = minY;
this.height = height;
}
public DimensionDataImpl(final CompoundTag dimensionData) {
final Tag height = dimensionData.get("height");
if (height instanceof IntTag) {
this.height = ((NumberTag) height).asInt();
} else {
throw new IllegalArgumentException("height missing in dimension data: " + dimensionData);
}
final Tag minY = dimensionData.get("min_y");
if (minY instanceof IntTag) {
this.minY = ((NumberTag) minY).asInt();
} else {
throw new IllegalArgumentException("min_y missing in dimension data: " + dimensionData);
}
}
@Override
public int minY() {
return minY;
}
@Override
public int height() {
return height;
}
@Override
public String toString() {
return "DimensionData{" +
"minY=" + minY +
", height=" + height +
'}';
}
}
@@ -21,6 +21,7 @@ package com.viaversion.viaversion.data.entity;
import com.google.common.base.Preconditions;
import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.api.data.entity.ClientEntityIdChangeListener;
import com.viaversion.viaversion.api.data.entity.DimensionData;
import com.viaversion.viaversion.api.data.entity.EntityTracker;
import com.viaversion.viaversion.api.data.entity.StoredEntityData;
import com.viaversion.viaversion.api.minecraft.entities.EntityType;
@@ -28,6 +29,9 @@ import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
import org.checkerframework.checker.nullness.qual.Nullable;
import space.vectrix.flare.fastutil.Int2ObjectSyncMap;
import java.util.Collections;
import java.util.Map;
public class EntityTrackerBase implements EntityTracker, ClientEntityIdChangeListener {
private final Int2ObjectMap<EntityType> entityTypes = Int2ObjectSyncMap.hashmap();
private final Int2ObjectMap<StoredEntityData> entityData;
@@ -38,6 +42,7 @@ public class EntityTrackerBase implements EntityTracker, ClientEntityIdChangeLis
private int currentMinY;
private String currentWorld;
private int biomesSent = -1;
private Map<String, DimensionData> dimensions = Collections.emptyMap();
public EntityTrackerBase(UserConnection connection, @Nullable EntityType playerType) {
this(connection, playerType, false);
@@ -118,6 +123,15 @@ public class EntityTrackerBase implements EntityTracker, ClientEntityIdChangeLis
this.clientEntityId = clientEntityId;
}
@Override
public boolean trackClientEntity() {
if (clientEntityId != -1) {
entityTypes.put(clientEntityId, playerType);
return true;
}
return false;
}
@Override
public int currentWorldSectionHeight() {
return currentWorldSectionHeight;
@@ -157,4 +171,19 @@ public class EntityTrackerBase implements EntityTracker, ClientEntityIdChangeLis
public void setBiomesSent(int biomesSent) {
this.biomesSent = biomesSent;
}
@Override
public EntityType playerType() {
return playerType;
}
@Override
public @Nullable DimensionData dimensionData(String dimension) {
return dimensions.get(dimension);
}
@Override
public void setDimensions(Map<String, DimensionData> dimensions) {
this.dimensions = dimensions;
}
}
@@ -42,6 +42,11 @@ public final class StoredEntityImpl implements StoredEntityData {
return (T) storedObjects.get(objectClass);
}
@Override
public <T> @Nullable T remove(Class<T> objectClass) {
return (T) storedObjects.remove(objectClass);
}
@Override
public boolean has(Class<?> objectClass) {
return storedObjects.containsKey(objectClass);
@@ -18,7 +18,11 @@
package com.viaversion.viaversion.debug;
import com.viaversion.viaversion.api.debug.DebugHandler;
import com.viaversion.viaversion.api.protocol.packet.Direction;
import com.viaversion.viaversion.api.protocol.packet.PacketType;
import com.viaversion.viaversion.api.protocol.packet.PacketWrapper;
import it.unimi.dsi.fastutil.ints.IntOpenHashSet;
import it.unimi.dsi.fastutil.ints.IntSet;
import java.util.HashSet;
import java.util.Set;
@@ -26,7 +30,9 @@ import java.util.Set;
public final class DebugHandlerImpl implements DebugHandler {
private final Set<String> packetTypesToLog = new HashSet<>();
private boolean logPostPacketTransform = true;
private final IntSet clientboundPacketIdsToLog = new IntOpenHashSet();
private final IntSet serverboundPacketIdsToLog = new IntOpenHashSet();
private boolean logPostPacketTransform;
private boolean enabled;
@Override
@@ -44,6 +50,11 @@ public final class DebugHandlerImpl implements DebugHandler {
packetTypesToLog.add(packetTypeName);
}
@Override
public void addPacketTypeToLog(PacketType packetType) {
(packetType.direction() == Direction.SERVERBOUND ? serverboundPacketIdsToLog : clientboundPacketIdsToLog).add(packetType.getId());
}
@Override
public boolean removePacketTypeNameToLog(final String packetTypeName) {
return packetTypesToLog.remove(packetTypeName);
@@ -65,7 +76,9 @@ public final class DebugHandlerImpl implements DebugHandler {
}
@Override
public boolean shouldLog(final PacketWrapper wrapper) {
return packetTypesToLog.isEmpty() || (wrapper.getPacketType() != null && packetTypesToLog.contains(wrapper.getPacketType().getName()));
public boolean shouldLog(final PacketWrapper wrapper, final Direction direction) {
return packetTypesToLog.isEmpty() && serverboundPacketIdsToLog.isEmpty() && clientboundPacketIdsToLog.isEmpty()
|| (wrapper.getPacketType() != null && packetTypesToLog.contains(wrapper.getPacketType().getName()))
|| (direction == Direction.SERVERBOUND ? serverboundPacketIdsToLog : clientboundPacketIdsToLog).contains(wrapper.getId());
}
}
@@ -66,6 +66,7 @@ import com.viaversion.viaversion.protocols.protocol1_17_1to1_17.Protocol1_17_1To
import com.viaversion.viaversion.protocols.protocol1_17to1_16_4.Protocol1_17To1_16_4;
import com.viaversion.viaversion.protocols.protocol1_18_2to1_18.Protocol1_18_2To1_18;
import com.viaversion.viaversion.protocols.protocol1_18to1_17_1.Protocol1_18To1_17_1;
import com.viaversion.viaversion.protocols.protocol1_19to1_18_2.Protocol1_19To1_18_2;
import com.viaversion.viaversion.protocols.protocol1_9_1_2to1_9_3_4.Protocol1_9_1_2To1_9_3_4;
import com.viaversion.viaversion.protocols.protocol1_9_1to1_9.Protocol1_9_1To1_9;
import com.viaversion.viaversion.protocols.protocol1_9_3to1_9_1_2.Protocol1_9_3To1_9_1_2;
@@ -171,6 +172,8 @@ public class ProtocolManagerImpl implements ProtocolManager {
registerProtocol(new Protocol1_17_1To1_17(), ProtocolVersion.v1_17_1, ProtocolVersion.v1_17);
registerProtocol(new Protocol1_18To1_17_1(), ProtocolVersion.v1_18, ProtocolVersion.v1_17_1);
registerProtocol(new Protocol1_18_2To1_18(), ProtocolVersion.v1_18_2, ProtocolVersion.v1_18);
registerProtocol(new Protocol1_19To1_18_2(), ProtocolVersion.v1_19, ProtocolVersion.v1_18_2);
}
@Override
@@ -114,12 +114,16 @@ public class ProtocolPipelineImpl extends AbstractSimpleProtocol implements Prot
public void transform(Direction direction, State state, PacketWrapper packetWrapper) throws Exception {
int originalID = packetWrapper.getId();
DebugHandler debugHandler = Via.getManager().debugHandler();
if (debugHandler.enabled() && !debugHandler.logPostPacketTransform() && debugHandler.shouldLog(packetWrapper, direction)) {
logPacket(direction, state, packetWrapper, originalID);
}
// Apply protocols
packetWrapper.apply(direction, state, 0, protocolList, direction == Direction.CLIENTBOUND);
super.transform(direction, state, packetWrapper);
DebugHandler debugHandler = Via.getManager().debugHandler();
if (debugHandler.enabled() && debugHandler.logPostPacketTransform() && debugHandler.shouldLog(packetWrapper)) {
if (debugHandler.enabled() && debugHandler.logPostPacketTransform() && debugHandler.shouldLog(packetWrapper, direction)) {
logPacket(direction, state, packetWrapper, originalID);
}
}
@@ -127,20 +131,20 @@ public class ProtocolPipelineImpl extends AbstractSimpleProtocol implements Prot
private void logPacket(Direction direction, State state, PacketWrapper packetWrapper, int originalID) {
// Debug packet
int clientProtocol = userConnection.getProtocolInfo().getProtocolVersion();
ViaPlatform platform = Via.getPlatform();
ViaPlatform<?> platform = Via.getPlatform();
String actualUsername = packetWrapper.user().getProtocolInfo().getUsername();
String username = actualUsername != null ? actualUsername + " " : "";
platform.getLogger().log(Level.INFO, "{0}{1} {2}: {3} (0x{4}) -> {5} (0x{6}) [{7}] {8}",
platform.getLogger().log(Level.INFO, "{0}{1} {2}: {3} ({4}) -> {5} ({6}) [{7}] {8}",
new Object[]{
username,
direction,
state,
originalID,
Integer.toHexString(originalID),
AbstractSimpleProtocol.toNiceHex(originalID),
packetWrapper.getId(),
Integer.toHexString(packetWrapper.getId()),
AbstractSimpleProtocol.toNiceHex(packetWrapper.getId()),
Integer.toString(clientProtocol),
packetWrapper
});
@@ -488,10 +488,10 @@ public class PacketWrapperImpl implements PacketWrapper {
@Override
public String toString() {
return "PacketWrapper{" +
"packetValues=" + packetValues +
", readableObjects=" + readableObjects +
"packetType=" + packetType +
", id=" + id +
", packetType=" + packetType +
", packetValues=" + packetValues +
", readableObjects=" + readableObjects +
'}';
}
}
@@ -26,6 +26,6 @@ public class BaseProtocol1_16 extends BaseProtocol1_7 {
@Override
protected UUID passthroughLoginUUID(final PacketWrapper wrapper) throws Exception {
return wrapper.passthrough(Type.UUID_INT_ARRAY);
return wrapper.passthrough(Type.UUID);
}
}
@@ -69,7 +69,7 @@ public class MetadataRewriter1_11To1_10 extends EntityRewriter<Protocol1_11To1_1
}
if (type.isOrHasParent(EntityType.ZOMBIE)) { // Zombie | Zombie Villager | Husk
if (type.is(EntityType.ZOMBIE, EntityType.HUSK) && metadata.id() == 14) {
if ((type == EntityType.ZOMBIE || type == EntityType.HUSK) && metadata.id() == 14) {
metadatas.remove(metadata);
} else {
if (metadata.id() == 15) {
@@ -104,7 +104,7 @@ public class MetadataRewriter1_11To1_10 extends EntityRewriter<Protocol1_11To1_1
metadatas.remove(metadata);
}
}
if (type.is(EntityType.DONKEY, EntityType.MULE)) {
if (type == EntityType.DONKEY || type == EntityType.MULE) {
// Chested Horse
if (metadata.id() == 13) {
if ((((byte) metadata.getValue()) & 0x08) == 0x08) {
@@ -118,7 +118,7 @@ public class Protocol1_13To1_12_2 extends AbstractProtocol<ClientboundPackets1_1
wrapper.write(Type.INT, position.z());
};
private static final PacketHandler SEND_DECLARE_COMMANDS_AND_TAGS =
public static final PacketHandler SEND_DECLARE_COMMANDS_AND_TAGS =
w -> {
// Send fake declare commands
w.create(ClientboundPackets1_13.DECLARE_COMMANDS, wrapper -> {
@@ -388,30 +388,6 @@ public class Protocol1_13To1_12_2 extends AbstractProtocol<ClientboundPackets1_1
}
});
registerClientbound(ClientboundPackets1_12_1.JOIN_GAME, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.INT); // 0 - Entity ID
map(Type.UNSIGNED_BYTE); // 1 - Gamemode
map(Type.INT); // 2 - Dimension
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
// Store the player
int entityId = wrapper.get(Type.INT, 0);
wrapper.user().getEntityTracker(Protocol1_13To1_12_2.class).addEntity(entityId, Entity1_13Types.EntityType.PLAYER);
ClientWorld clientChunks = wrapper.user().get(ClientWorld.class);
int dimensionId = wrapper.get(Type.INT, 1);
clientChunks.setEnvironment(dimensionId);
}
});
handler(SEND_DECLARE_COMMANDS_AND_TAGS);
}
});
registerClientbound(ClientboundPackets1_12_1.CRAFT_RECIPE_RESPONSE, new PacketRemapper() {
@Override
public void registerMap() {
@@ -47,7 +47,6 @@ public class MappingData extends MappingDataBase {
private final Map<String, String> translateMapping = new HashMap<>();
private final Map<String, String> mojangTranslation = new HashMap<>();
private final BiMap<String, String> channelMappings = HashBiMap.create(); // 1.12->1.13
private Mappings enchantmentMappings;
public MappingData() {
super("1.12", "1.13");
@@ -59,9 +58,9 @@ public class MappingData extends MappingDataBase {
loadTags(itemTags, newMappings.getAsJsonObject("item_tags"));
loadTags(fluidTags, newMappings.getAsJsonObject("fluid_tags"));
loadEnchantments(oldEnchantmentsIds, oldMappings.getAsJsonObject("enchantments"));
loadEnchantments(oldEnchantmentsIds, oldMappings.getAsJsonObject("legacy_enchantments"));
enchantmentMappings = IntArrayMappings.builder().customEntrySize(72)
.unmapped(oldMappings.getAsJsonObject("enchantments")).mapped(newMappings.getAsJsonObject("enchantments")).build();
.unmapped(oldMappings.getAsJsonObject("legacy_enchantments")).mapped(newMappings.getAsJsonArray("enchantments")).build();
// Map minecraft:snow[layers=1] of 1.12 to minecraft:snow[layers=2] in 1.13
if (Via.getConfig().isSnowCollisionFix()) {
@@ -196,8 +195,4 @@ public class MappingData extends MappingDataBase {
public BiMap<String, String> getChannelMappings() {
return channelMappings;
}
public Mappings getEnchantmentMappings() {
return enchantmentMappings;
}
}
@@ -27,6 +27,7 @@ import com.viaversion.viaversion.api.type.types.version.Types1_13;
import com.viaversion.viaversion.protocols.protocol1_12_1to1_12.ClientboundPackets1_12_1;
import com.viaversion.viaversion.protocols.protocol1_13to1_12_2.Protocol1_13To1_12_2;
import com.viaversion.viaversion.protocols.protocol1_13to1_12_2.metadata.MetadataRewriter1_13To1_12_2;
import com.viaversion.viaversion.protocols.protocol1_9_3to1_9_1_2.storage.ClientWorld;
public class EntityPackets {
@@ -128,6 +129,23 @@ public class EntityPackets {
}
});
protocol.registerClientbound(ClientboundPackets1_12_1.JOIN_GAME, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.INT); // 0 - Entity ID
map(Type.UNSIGNED_BYTE); // 1 - Gamemode
map(Type.INT); // 2 - Dimension
handler(wrapper -> {
ClientWorld clientChunks = wrapper.user().get(ClientWorld.class);
int dimensionId = wrapper.get(Type.INT, 1);
clientChunks.setEnvironment(dimensionId);
});
handler(metadataRewriter.playerTrackerHandler());
handler(Protocol1_13To1_12_2.SEND_DECLARE_COMMANDS_AND_TAGS);
}
});
metadataRewriter.registerRemoveEntities(ClientboundPackets1_12_1.DESTROY_ENTITIES);
metadataRewriter.registerMetadataRewriter(ClientboundPackets1_12_1.ENTITY_METADATA, Types1_12.METADATA_LIST, Types1_13.METADATA_LIST);
}
@@ -28,7 +28,7 @@ public class CommandRewriter1_14 extends CommandRewriter {
}
@Override
protected @Nullable String handleArgumentType(String argumentType) {
public @Nullable String handleArgumentType(String argumentType) {
if (argumentType.equals("minecraft:nbt")) {
return "minecraft:nbt_compound_tag";
}
@@ -33,6 +33,7 @@ import com.viaversion.viaversion.protocols.protocol1_14to1_13_2.ClientboundPacke
import com.viaversion.viaversion.protocols.protocol1_14to1_13_2.Protocol1_14To1_13_2;
import com.viaversion.viaversion.protocols.protocol1_14to1_13_2.metadata.MetadataRewriter1_14To1_13_2;
import com.viaversion.viaversion.protocols.protocol1_14to1_13_2.storage.EntityTracker1_14;
import com.viaversion.viaversion.protocols.protocol1_9_3to1_9_1_2.storage.ClientWorld;
import java.util.LinkedList;
import java.util.List;
@@ -195,6 +196,42 @@ public class EntityPackets {
}
});
protocol.registerClientbound(ClientboundPackets1_13.JOIN_GAME, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.INT); // 0 - Entity ID
map(Type.UNSIGNED_BYTE); // 1 - Gamemode
map(Type.INT); // 2 - Dimension
handler(wrapper -> {
// Store the player
ClientWorld clientChunks = wrapper.user().get(ClientWorld.class);
int dimensionId = wrapper.get(Type.INT, 1);
clientChunks.setEnvironment(dimensionId);
});
handler(metadataRewriter.playerTrackerHandler());
handler(wrapper -> {
short difficulty = wrapper.read(Type.UNSIGNED_BYTE); // 19w11a removed difficulty from join game
PacketWrapper difficultyPacket = wrapper.create(ClientboundPackets1_14.SERVER_DIFFICULTY);
difficultyPacket.write(Type.UNSIGNED_BYTE, difficulty);
difficultyPacket.write(Type.BOOLEAN, false); // Unknown value added in 19w11a
difficultyPacket.scheduleSend(protocol.getClass());
wrapper.passthrough(Type.UNSIGNED_BYTE); // Max Players
wrapper.passthrough(Type.STRING); // Level Type
wrapper.write(Type.VAR_INT, WorldPackets.SERVERSIDE_VIEW_DISTANCE); // Serverside view distance, added in 19w13a
});
handler(wrapper -> {
// Manually send the packet
wrapper.send(Protocol1_14To1_13_2.class);
wrapper.cancel();
// View distance has to be sent after the join packet
WorldPackets.sendViewDistancePacket(wrapper.user());
});
}
});
protocol.registerClientbound(ClientboundPackets1_13.USE_BED, ClientboundPackets1_14.ENTITY_METADATA, new PacketRemapper() {
@Override
public void registerMap() {
@@ -25,7 +25,6 @@ import com.viaversion.viaversion.api.minecraft.BlockFace;
import com.viaversion.viaversion.api.minecraft.chunks.Chunk;
import com.viaversion.viaversion.api.minecraft.chunks.ChunkSection;
import com.viaversion.viaversion.api.minecraft.chunks.NibbleArray;
import com.viaversion.viaversion.api.minecraft.entities.Entity1_14Types;
import com.viaversion.viaversion.api.protocol.packet.PacketWrapper;
import com.viaversion.viaversion.api.protocol.remapper.PacketHandler;
import com.viaversion.viaversion.api.protocol.remapper.PacketRemapper;
@@ -288,55 +287,6 @@ public class WorldPackets {
}
});
protocol.registerClientbound(ClientboundPackets1_13.JOIN_GAME, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.INT); // 0 - Entity ID
map(Type.UNSIGNED_BYTE); // 1 - Gamemode
map(Type.INT); // 2 - Dimension
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
// Store the player
ClientWorld clientChunks = wrapper.user().get(ClientWorld.class);
int dimensionId = wrapper.get(Type.INT, 1);
clientChunks.setEnvironment(dimensionId);
int entityId = wrapper.get(Type.INT, 0);
Entity1_14Types entType = Entity1_14Types.PLAYER;
// Register Type ID
EntityTracker1_14 tracker = wrapper.user().getEntityTracker(Protocol1_14To1_13_2.class);
tracker.addEntity(entityId, entType);
tracker.setClientEntityId(entityId);
}
});
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
short difficulty = wrapper.read(Type.UNSIGNED_BYTE); // 19w11a removed difficulty from join game
PacketWrapper difficultyPacket = wrapper.create(ClientboundPackets1_14.SERVER_DIFFICULTY);
difficultyPacket.write(Type.UNSIGNED_BYTE, difficulty);
difficultyPacket.write(Type.BOOLEAN, false); // Unknown value added in 19w11a
difficultyPacket.scheduleSend(protocol.getClass());
wrapper.passthrough(Type.UNSIGNED_BYTE); // Max Players
wrapper.passthrough(Type.STRING); // Level Type
wrapper.write(Type.VAR_INT, SERVERSIDE_VIEW_DISTANCE); // Serverside view distance, added in 19w13a
}
});
handler(wrapper -> {
// Manually send the packet
wrapper.send(Protocol1_14To1_13_2.class);
wrapper.cancel();
// View distance has to be sent after the join packet
sendViewDistancePacket(wrapper.user());
});
}
});
protocol.registerClientbound(ClientboundPackets1_13.MAP_DATA, new PacketRemapper() {
@Override
public void registerMap() {
@@ -394,7 +344,7 @@ public class WorldPackets {
});
}
private static void sendViewDistancePacket(UserConnection connection) throws Exception {
static void sendViewDistancePacket(UserConnection connection) throws Exception {
PacketWrapper setViewDistance = PacketWrapper.create(ClientboundPackets1_14.UPDATE_VIEW_DISTANCE, null, connection);
setViewDistance.write(Type.VAR_INT, WorldPackets.SERVERSIDE_VIEW_DISTANCE);
setViewDistance.send(Protocol1_14To1_13_2.class);
@@ -18,6 +18,7 @@
package com.viaversion.viaversion.protocols.protocol1_15to1_14_4;
import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.api.minecraft.RegistryType;
import com.viaversion.viaversion.api.minecraft.entities.Entity1_15Types;
import com.viaversion.viaversion.api.protocol.AbstractProtocol;
import com.viaversion.viaversion.api.protocol.remapper.PacketRemapper;
@@ -31,9 +32,7 @@ import com.viaversion.viaversion.protocols.protocol1_15to1_14_4.data.MappingData
import com.viaversion.viaversion.protocols.protocol1_15to1_14_4.metadata.MetadataRewriter1_15To1_14_4;
import com.viaversion.viaversion.protocols.protocol1_15to1_14_4.packets.EntityPackets;
import com.viaversion.viaversion.protocols.protocol1_15to1_14_4.packets.InventoryPackets;
import com.viaversion.viaversion.protocols.protocol1_15to1_14_4.packets.PlayerPackets;
import com.viaversion.viaversion.protocols.protocol1_15to1_14_4.packets.WorldPackets;
import com.viaversion.viaversion.api.minecraft.RegistryType;
import com.viaversion.viaversion.rewriter.SoundRewriter;
import com.viaversion.viaversion.rewriter.StatisticsRewriter;
import com.viaversion.viaversion.rewriter.TagRewriter;
@@ -55,7 +54,6 @@ public class Protocol1_15To1_14_4 extends AbstractProtocol<ClientboundPackets1_1
itemRewriter.register();
EntityPackets.register(this);
PlayerPackets.register(this);
WorldPackets.register(this);
SoundRewriter soundRewriter = new SoundRewriter(this);
@@ -17,6 +17,7 @@
*/
package com.viaversion.viaversion.protocols.protocol1_15to1_14_4.packets;
import com.viaversion.viaversion.api.Via;
import com.viaversion.viaversion.api.minecraft.entities.Entity1_15Types;
import com.viaversion.viaversion.api.minecraft.metadata.Metadata;
import com.viaversion.viaversion.api.protocol.packet.PacketWrapper;
@@ -79,6 +80,32 @@ public class EntityPackets {
}
});
protocol.registerClientbound(ClientboundPackets1_14.RESPAWN, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.INT);
handler(wrapper -> wrapper.write(Type.LONG, 0L)); // Level Seed
}
});
protocol.registerClientbound(ClientboundPackets1_14.JOIN_GAME, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.INT); // 0 - Entity ID
map(Type.UNSIGNED_BYTE); // 1 - Gamemode
map(Type.INT); // 2 - Dimension
handler(metadataRewriter.playerTrackerHandler());
handler(wrapper -> wrapper.write(Type.LONG, 0L)); // Level Seed
map(Type.UNSIGNED_BYTE); // 3 - Max Players
map(Type.STRING); // 4 - Level Type
map(Type.VAR_INT); // 5 - View Distance
map(Type.BOOLEAN); // 6 - Reduce Debug Info
handler(wrapper -> wrapper.write(Type.BOOLEAN, !Via.getConfig().is1_15InstantRespawn())); // Show Death Screen
}
});
metadataRewriter.registerMetadataRewriter(ClientboundPackets1_14.ENTITY_METADATA, Types1_14.METADATA_LIST);
metadataRewriter.registerRemoveEntities(ClientboundPackets1_14.DESTROY_ENTITIES);
}
@@ -1,64 +0,0 @@
/*
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
* Copyright (C) 2016-2022 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_15to1_14_4.packets;
import com.viaversion.viaversion.api.Via;
import com.viaversion.viaversion.api.data.entity.EntityTracker;
import com.viaversion.viaversion.api.minecraft.entities.Entity1_15Types;
import com.viaversion.viaversion.api.protocol.Protocol;
import com.viaversion.viaversion.api.protocol.remapper.PacketRemapper;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.protocols.protocol1_14to1_13_2.ClientboundPackets1_14;
import com.viaversion.viaversion.protocols.protocol1_15to1_14_4.Protocol1_15To1_14_4;
public class PlayerPackets {
public static void register(Protocol protocol) {
protocol.registerClientbound(ClientboundPackets1_14.RESPAWN, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.INT);
handler(wrapper -> wrapper.write(Type.LONG, 0L)); // Level Seed
}
});
protocol.registerClientbound(ClientboundPackets1_14.JOIN_GAME, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.INT); // 0 - Entity ID
map(Type.UNSIGNED_BYTE); // 1 - Gamemode
map(Type.INT); // 2 - Dimension
handler(wrapper -> {
// Register Type ID
EntityTracker tracker = wrapper.user().getEntityTracker(Protocol1_15To1_14_4.class);
int entityId = wrapper.get(Type.INT, 0);
tracker.addEntity(entityId, Entity1_15Types.PLAYER);
});
handler(wrapper -> wrapper.write(Type.LONG, 0L)); // Level Seed
map(Type.UNSIGNED_BYTE); // 3 - Max Players
map(Type.STRING); // 4 - Level Type
map(Type.VAR_INT); // 5 - View Distance
map(Type.BOOLEAN); // 6 - Reduce Debug Info
handler(wrapper -> wrapper.write(Type.BOOLEAN, !Via.getConfig().is1_15InstantRespawn())); // Show Death Screen
}
});
}
}
@@ -63,9 +63,7 @@ public class EntityPackets {
map(Type.LONG); // Seed
map(Type.UNSIGNED_BYTE, Type.VAR_INT); // Max players
// ...
handler(wrapper -> {
wrapper.user().getEntityTracker(Protocol1_16_2To1_16_1.class).addEntity(wrapper.get(Type.INT, 0), Entity1_16_2Types.PLAYER);
});
handler(metadataRewriter.playerTrackerHandler());
}
});
@@ -86,6 +84,6 @@ public class EntityPackets {
Via.getPlatform().getLogger().severe("Could not get dimension data of " + dimensionType);
throw new NullPointerException("Dimension data for " + dimensionType + " is null!");
}
return tag;
return tag.clone();
}
}
@@ -84,9 +84,9 @@ public class Protocol1_16To1_15_2 extends AbstractProtocol<ClientboundPackets1_1
@Override
public void registerMap() {
handler(wrapper -> {
// Transform string to int array
// Transform string to a uuid
UUID uuid = UUID.fromString(wrapper.read(Type.STRING));
wrapper.write(Type.UUID_INT_ARRAY, uuid);
wrapper.write(Type.UUID, uuid);
});
}
});
@@ -17,6 +17,10 @@
*/
package com.viaversion.viaversion.protocols.protocol1_17to1_16_4.packets;
import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
import com.github.steveice10.opennbt.tag.builtin.IntTag;
import com.github.steveice10.opennbt.tag.builtin.ListTag;
import com.github.steveice10.opennbt.tag.builtin.Tag;
import com.viaversion.viaversion.api.data.entity.EntityTracker;
import com.viaversion.viaversion.api.minecraft.entities.Entity1_16_2Types;
import com.viaversion.viaversion.api.minecraft.entities.Entity1_17Types;
@@ -66,6 +70,42 @@ public final class EntityPackets extends EntityRewriter<Protocol1_17To1_16_4> {
}
});
protocol.registerClientbound(ClientboundPackets1_16_2.JOIN_GAME, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.INT); // Entity ID
map(Type.BOOLEAN); // Hardcore
map(Type.UNSIGNED_BYTE); // Gamemode
map(Type.BYTE); // Previous Gamemode
map(Type.STRING_ARRAY); // World List
map(Type.NBT); // Registry
map(Type.NBT); // Current dimension
handler(wrapper -> {
// Add new dimension fields
CompoundTag dimensionRegistry = wrapper.get(Type.NBT, 0).get("minecraft:dimension_type");
ListTag dimensions = dimensionRegistry.get("value");
for (Tag dimension : dimensions) {
CompoundTag dimensionCompound = ((CompoundTag) dimension).get("element");
addNewDimensionData(dimensionCompound);
}
CompoundTag currentDimensionTag = wrapper.get(Type.NBT, 1);
addNewDimensionData(currentDimensionTag);
});
handler(playerTrackerHandler());
}
});
protocol.registerClientbound(ClientboundPackets1_16_2.RESPAWN, new PacketRemapper() {
@Override
public void registerMap() {
handler(wrapper -> {
CompoundTag dimensionData = wrapper.passthrough(Type.NBT);
addNewDimensionData(dimensionData);
});
}
});
protocol.registerClientbound(ClientboundPackets1_16_2.ENTITY_PROPERTIES, new PacketRemapper() {
@Override
public void registerMap() {
@@ -156,4 +196,9 @@ public final class EntityPackets extends EntityRewriter<Protocol1_17To1_16_4> {
public EntityType typeFromId(int type) {
return Entity1_17Types.getTypeFromId(type);
}
private static void addNewDimensionData(CompoundTag tag) {
tag.put("min_y", new IntTag(0));
tag.put("height", new IntTag(256));
}
}
@@ -17,16 +17,10 @@
*/
package com.viaversion.viaversion.protocols.protocol1_17to1_16_4.packets;
import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
import com.github.steveice10.opennbt.tag.builtin.IntTag;
import com.github.steveice10.opennbt.tag.builtin.ListTag;
import com.github.steveice10.opennbt.tag.builtin.Tag;
import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.api.minecraft.BlockChangeRecord;
import com.viaversion.viaversion.api.minecraft.BlockChangeRecord1_16_2;
import com.viaversion.viaversion.api.minecraft.chunks.Chunk;
import com.viaversion.viaversion.api.minecraft.chunks.ChunkSection;
import com.viaversion.viaversion.api.minecraft.entities.Entity1_17Types;
import com.viaversion.viaversion.api.protocol.packet.ClientboundPacketType;
import com.viaversion.viaversion.api.protocol.packet.PacketWrapper;
import com.viaversion.viaversion.api.protocol.remapper.PacketRemapper;
@@ -164,44 +158,6 @@ public final class WorldPackets {
}
});
protocol.registerClientbound(ClientboundPackets1_16_2.JOIN_GAME, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.INT); // Entity ID
map(Type.BOOLEAN); // Hardcore
map(Type.UNSIGNED_BYTE); // Gamemode
map(Type.BYTE); // Previous Gamemode
map(Type.STRING_ARRAY); // World List
map(Type.NBT); // Registry
map(Type.NBT); // Current dimension
handler(wrapper -> {
// Add new dimension fields
CompoundTag dimensionRegistry = wrapper.get(Type.NBT, 0).get("minecraft:dimension_type");
ListTag dimensions = dimensionRegistry.get("value");
for (Tag dimension : dimensions) {
CompoundTag dimensionCompound = ((CompoundTag) dimension).get("element");
addNewDimensionData(dimensionCompound);
}
CompoundTag currentDimensionTag = wrapper.get(Type.NBT, 1);
addNewDimensionData(currentDimensionTag);
UserConnection user = wrapper.user();
user.getEntityTracker(Protocol1_17To1_16_4.class).addEntity(wrapper.get(Type.INT, 0), Entity1_17Types.PLAYER);
});
}
});
protocol.registerClientbound(ClientboundPackets1_16_2.RESPAWN, new PacketRemapper() {
@Override
public void registerMap() {
handler(wrapper -> {
CompoundTag dimensionData = wrapper.passthrough(Type.NBT);
addNewDimensionData(dimensionData);
});
}
});
blockRewriter.registerEffect(ClientboundPackets1_16_2.EFFECT, 1010, 2001);
}
@@ -234,9 +190,4 @@ public final class WorldPackets {
blockChangePacket.send(Protocol1_17To1_16_4.class);
}
}
private static void addNewDimensionData(CompoundTag tag) {
tag.put("min_y", new IntTag(0));
tag.put("height", new IntTag(256));
}
}
@@ -18,17 +18,17 @@
package com.viaversion.viaversion.protocols.protocol1_17to1_16_4.storage;
import com.viaversion.viaversion.api.connection.StorableObject;
import it.unimi.dsi.fastutil.ints.IntOpenHashSet;
import it.unimi.dsi.fastutil.ints.IntSet;
import it.unimi.dsi.fastutil.ints.IntArrayList;
import it.unimi.dsi.fastutil.ints.IntList;
public final class InventoryAcknowledgements implements StorableObject {
private final IntSet ids = new IntOpenHashSet();
private final IntList ids = new IntArrayList();
public void addId(int id) {
ids.add(id);
}
public boolean removeId(int id) {
return ids.remove(id);
return ids.rem(id);
}
}
@@ -58,9 +58,9 @@ public final class Chunk1_18Type extends Type<Chunk> {
sections[i] = sectionType.read(sectionsBuf);
}
} finally {
if (sectionsBuf.readableBytes() > 0 && Via.getManager().isDebug()) {
/*if (sectionsBuf.readableBytes() > 0 && Via.getManager().isDebug()) {
Via.getPlatform().getLogger().warning("Found " + sectionsBuf.readableBytes() + " more bytes than expected while reading the chunk: " + chunkX + "/" + chunkZ);
}
}*/
sectionsBuf.release();
}
@@ -0,0 +1,139 @@
/*
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
* Copyright (C) 2016-2022 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_19to1_18_2;
import com.viaversion.viaversion.api.protocol.packet.ClientboundPacketType;
public enum ClientboundPackets1_19 implements ClientboundPacketType {
SPAWN_ENTITY, // 0x00
SPAWN_EXPERIENCE_ORB, // 0x01
SPAWN_PLAYER, // 0x02
ENTITY_ANIMATION, // 0x03
STATISTICS, // 0x04
BLOCK_CHANGED_ACK, // 0x05
BLOCK_BREAK_ANIMATION, // 0x06
BLOCK_ENTITY_DATA, // 0x07
BLOCK_ACTION, // 0x08
BLOCK_CHANGE, // 0x09
BOSSBAR, // 0x0A
SERVER_DIFFICULTY, // 0x0B
CHAT_PREVIEW, // 0x0C
CLEAR_TITLES, // 0x0D
TAB_COMPLETE, // 0x0E
DECLARE_COMMANDS, // 0x0F
CLOSE_WINDOW, // 0x10
WINDOW_ITEMS, // 0x11
WINDOW_PROPERTY, // 0x12
SET_SLOT, // 0x13
COOLDOWN, // 0x14
PLUGIN_MESSAGE, // 0x15
NAMED_SOUND, // 0x16
DISCONNECT, // 0x17
ENTITY_STATUS, // 0x18
EXPLOSION, // 0x19
UNLOAD_CHUNK, // 0x1A
GAME_EVENT, // 0x1B
OPEN_HORSE_WINDOW, // 0x1C
WORLD_BORDER_INIT, // 0x1D
KEEP_ALIVE, // 0x1E
CHUNK_DATA, // 0x1F
EFFECT, // 0x20
SPAWN_PARTICLE, // 0x21
UPDATE_LIGHT, // 0x22
JOIN_GAME, // 0x23
MAP_DATA, // 0x24
TRADE_LIST, // 0x25
ENTITY_POSITION, // 0x26
ENTITY_POSITION_AND_ROTATION, // 0x27
ENTITY_ROTATION, // 0x28
VEHICLE_MOVE, // 0x29
OPEN_BOOK, // 0x2A
OPEN_WINDOW, // 0x2B
OPEN_SIGN_EDITOR, // 0x2C
PING, // 0x2D
CRAFT_RECIPE_RESPONSE, // 0x2E
PLAYER_ABILITIES, // 0x2F
PLAYER_CHAT, // 0x30
COMBAT_END, // 0x31
COMBAT_ENTER, // 0x32
COMBAT_KILL, // 0x33
PLAYER_INFO, // 0x34
FACE_PLAYER, // 0x35
PLAYER_POSITION, // 0x36
UNLOCK_RECIPES, // 0x37
REMOVE_ENTITIES, // 0x38
REMOVE_ENTITY_EFFECT, // 0x39
RESOURCE_PACK, // 0x3A
RESPAWN, // 0x3B
ENTITY_HEAD_LOOK, // 0x3C
MULTI_BLOCK_CHANGE, // 0x3D
SELECT_ADVANCEMENTS_TAB, // 0x3E
SERVER_DATA, // 0x3F
ACTIONBAR, // 0x40
WORLD_BORDER_CENTER, // 0x41
WORLD_BORDER_LERP_SIZE, // 0x42
WORLD_BORDER_SIZE, // 0x43
WORLD_BORDER_WARNING_DELAY, // 0x44
WORLD_BORDER_WARNING_DISTANCE, // 0x45
CAMERA, // 0x46
HELD_ITEM_CHANGE, // 0x47
UPDATE_VIEW_POSITION, // 0x48
UPDATE_VIEW_DISTANCE, // 0x49
SPAWN_POSITION, // 0x4A
SET_DISPLAY_CHAT_PREVIEW, // 0x4B
DISPLAY_SCOREBOARD, // 0x4C
ENTITY_METADATA, // 0x4D
ATTACH_ENTITY, // 0x4E
ENTITY_VELOCITY, // 0x4F
ENTITY_EQUIPMENT, // 0x50
SET_EXPERIENCE, // 0x51
UPDATE_HEALTH, // 0x52
SCOREBOARD_OBJECTIVE, // 0x53
SET_PASSENGERS, // 0x54
TEAMS, // 0x55
UPDATE_SCORE, // 0x56
SET_SIMULATION_DISTANCE, // 0x57
TITLE_SUBTITLE, // 0x58
TIME_UPDATE, // 0x59
TITLE_TEXT, // 0x5A
TITLE_TIMES, // 0x5B
ENTITY_SOUND, // 0x5C
SOUND, // 0x5D
STOP_SOUND, // 0x5E
SYSTEM_CHAT, // 0x5F
TAB_LIST, // 0x60
NBT_QUERY, // 0x61
COLLECT_ITEM, // 0x62
ENTITY_TELEPORT, // 0x63
ADVANCEMENTS, // 0x64
ENTITY_PROPERTIES, // 0x65
ENTITY_EFFECT, // 0x66
DECLARE_RECIPES, // 0x67
TAGS; // 0x68
@Override
public int getId() {
return ordinal();
}
@Override
public String getName() {
return name();
}
}
@@ -0,0 +1,311 @@
/*
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
* Copyright (C) 2016-2022 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_19to1_18_2;
import com.viaversion.viaversion.api.Via;
import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.api.data.MappingData;
import com.viaversion.viaversion.api.data.MappingDataBase;
import com.viaversion.viaversion.api.minecraft.entities.Entity1_19Types;
import com.viaversion.viaversion.api.protocol.AbstractProtocol;
import com.viaversion.viaversion.api.protocol.packet.State;
import com.viaversion.viaversion.api.protocol.remapper.PacketRemapper;
import com.viaversion.viaversion.api.rewriter.EntityRewriter;
import com.viaversion.viaversion.api.rewriter.ItemRewriter;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.api.type.types.minecraft.ParticleType;
import com.viaversion.viaversion.api.type.types.version.Types1_19;
import com.viaversion.viaversion.data.entity.EntityTrackerBase;
import com.viaversion.viaversion.protocols.base.ClientboundLoginPackets;
import com.viaversion.viaversion.protocols.base.ServerboundLoginPackets;
import com.viaversion.viaversion.protocols.protocol1_17to1_16_4.ServerboundPackets1_17;
import com.viaversion.viaversion.protocols.protocol1_18to1_17_1.ClientboundPackets1_18;
import com.viaversion.viaversion.protocols.protocol1_19to1_18_2.packets.EntityPackets;
import com.viaversion.viaversion.protocols.protocol1_19to1_18_2.packets.InventoryPackets;
import com.viaversion.viaversion.protocols.protocol1_19to1_18_2.packets.WorldPackets;
import com.viaversion.viaversion.protocols.protocol1_19to1_18_2.storage.DimensionRegistryStorage;
import com.viaversion.viaversion.protocols.protocol1_19to1_18_2.storage.NonceStorage;
import com.viaversion.viaversion.rewriter.CommandRewriter;
import com.viaversion.viaversion.rewriter.SoundRewriter;
import com.viaversion.viaversion.rewriter.TagRewriter;
import javax.crypto.Cipher;
import java.security.KeyFactory;
import java.security.NoSuchAlgorithmException;
import java.security.PublicKey;
import java.security.spec.EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
public final class Protocol1_19To1_18_2 extends AbstractProtocol<ClientboundPackets1_18, ClientboundPackets1_19, ServerboundPackets1_17, ServerboundPackets1_19> {
public static final MappingData MAPPINGS = new MappingDataBase("1.18", "1.19", true);
private static final KeyFactory RSA_FACTORY;
static {
try {
RSA_FACTORY = KeyFactory.getInstance("RSA");
} catch (final NoSuchAlgorithmException e) {
throw new RuntimeException(e);
}
}
private final EntityPackets entityRewriter = new EntityPackets(this);
private final InventoryPackets itemRewriter = new InventoryPackets(this);
public Protocol1_19To1_18_2() {
super(ClientboundPackets1_18.class, ClientboundPackets1_19.class, ServerboundPackets1_17.class, ServerboundPackets1_19.class);
}
@Override
protected void registerPackets() {
final TagRewriter tagRewriter = new TagRewriter(this);
tagRewriter.registerGeneric(ClientboundPackets1_18.TAGS);
entityRewriter.register();
itemRewriter.register();
WorldPackets.register(this);
cancelClientbound(ClientboundPackets1_18.ADD_VIBRATION_SIGNAL);
final SoundRewriter soundRewriter = new SoundRewriter(this);
registerClientbound(ClientboundPackets1_18.SOUND, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.VAR_INT); // Sound id
map(Type.VAR_INT); // Source
map(Type.INT); // X
map(Type.INT); // Y
map(Type.INT); // Z
map(Type.FLOAT); // Volume
map(Type.FLOAT); // Pitch
create(Type.LONG, 0L); // Seed
handler(soundRewriter.getSoundHandler());
}
});
registerClientbound(ClientboundPackets1_18.ENTITY_SOUND, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.VAR_INT); // Sound id
map(Type.VAR_INT); // Source
map(Type.VAR_INT); // Entity id
map(Type.FLOAT); // Volume
map(Type.FLOAT); // Pitch
create(Type.LONG, 0L); // Seed
handler(soundRewriter.getSoundHandler());
}
});
registerClientbound(ClientboundPackets1_18.NAMED_SOUND, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.STRING); // Sound name
map(Type.VAR_INT); // Source
map(Type.INT); // X
map(Type.INT); // Y
map(Type.INT); // Z
map(Type.FLOAT); // Volume
map(Type.FLOAT); // Pitch
create(Type.LONG, 0L); // Seed
}
});
final CommandRewriter commandRewriter = new CommandRewriter(this);
registerClientbound(ClientboundPackets1_18.DECLARE_COMMANDS, new PacketRemapper() {
@Override
public void registerMap() {
handler(wrapper -> {
final int size = wrapper.passthrough(Type.VAR_INT);
for (int i = 0; i < size; i++) {
final byte flags = wrapper.passthrough(Type.BYTE);
wrapper.passthrough(Type.VAR_INT_ARRAY_PRIMITIVE); // Children indices
if ((flags & 0x08) != 0) {
wrapper.passthrough(Type.VAR_INT); // Redirect node index
}
final int nodeType = flags & 0x03;
if (nodeType == 1 || nodeType == 2) { // Literal/argument node
wrapper.passthrough(Type.STRING); // Name
}
if (nodeType == 2) { // Argument node
final String argumentType = wrapper.read(Type.STRING);
final int argumentTypeId = MAPPINGS.getArgumentTypeMappings().mappedId(argumentType);
if (argumentTypeId == -1) {
Via.getPlatform().getLogger().warning("Unknown command argument type: " + argumentType);
}
wrapper.write(Type.VAR_INT, argumentTypeId);
commandRewriter.handleArgument(wrapper, argumentType);
if ((flags & 0x10) != 0) {
wrapper.passthrough(Type.STRING); // Suggestion type
}
}
}
wrapper.passthrough(Type.VAR_INT); // Root node index
});
}
});
// Make every message a system message, including player ones; we don't want to analyze and remove player names from the original component
registerClientbound(ClientboundPackets1_18.CHAT_MESSAGE, ClientboundPackets1_19.SYSTEM_CHAT, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.COMPONENT); // Message
handler(wrapper -> {
int type = wrapper.read(Type.BYTE);
wrapper.write(Type.VAR_INT, type == 2 ? 1 : 0);
});
read(Type.UUID); // Sender
}
});
registerServerbound(ServerboundPackets1_19.CHAT_MESSAGE, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.STRING); // Message
read(Type.LONG); // Timestamp
read(Type.LONG); // Salt
read(Type.BYTE_ARRAY_PRIMITIVE); // Signature
read(Type.BOOLEAN); // Signed preview
}
});
registerServerbound(ServerboundPackets1_19.CHAT_COMMAND, ServerboundPackets1_17.CHAT_MESSAGE, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.STRING); // Command
read(Type.LONG); // Timestamp
read(Type.LONG); // Salt
handler(wrapper -> {
final String command = wrapper.get(Type.STRING, 0);
wrapper.set(Type.STRING, 0, "/" + command);
final int signatures = wrapper.read(Type.VAR_INT);
for (int i = 0; i < signatures; i++) {
wrapper.read(Type.STRING); // Argument name
wrapper.read(Type.BYTE_ARRAY_PRIMITIVE); // Signature
}
});
read(Type.BOOLEAN); // Signed preview
}
});
cancelServerbound(ServerboundPackets1_19.CHAT_PREVIEW);
// Login changes
registerClientbound(State.LOGIN, ClientboundLoginPackets.GAME_PROFILE.getId(), ClientboundLoginPackets.GAME_PROFILE.getId(), new PacketRemapper() {
@Override
public void registerMap() {
map(Type.UUID); // UUID
map(Type.STRING); // Name
create(Type.VAR_INT, 0); // No properties
}
});
registerClientbound(State.LOGIN, ClientboundLoginPackets.HELLO.getId(), ClientboundLoginPackets.HELLO.getId(), new PacketRemapper() {
@Override
public void registerMap() {
map(Type.STRING); // Server id
handler(wrapper -> {
final byte[] pubKey = wrapper.passthrough(Type.BYTE_ARRAY_PRIMITIVE);
final byte[] nonce = wrapper.passthrough(Type.BYTE_ARRAY_PRIMITIVE);
final EncodedKeySpec keySpec = new X509EncodedKeySpec(pubKey);
final PublicKey key = RSA_FACTORY.generatePublic(keySpec);
final Cipher cipher = Cipher.getInstance(key.getAlgorithm());
cipher.init(Cipher.ENCRYPT_MODE, key);
wrapper.user().put(new NonceStorage(cipher.doFinal(nonce)));
});
}
});
registerServerbound(State.LOGIN, ServerboundLoginPackets.HELLO.getId(), ServerboundLoginPackets.HELLO.getId(), new PacketRemapper() {
@Override
public void registerMap() {
map(Type.STRING); // Name
handler(wrapper -> {
if (wrapper.read(Type.BOOLEAN)) {
wrapper.read(Type.LONG); // Timestamp
wrapper.read(Type.BYTE_ARRAY_PRIMITIVE); // Key
wrapper.read(Type.BYTE_ARRAY_PRIMITIVE); // Signature
}
});
}
});
registerServerbound(State.LOGIN, ServerboundLoginPackets.ENCRYPTION_KEY.getId(), ServerboundLoginPackets.ENCRYPTION_KEY.getId(), new PacketRemapper() {
@Override
public void registerMap() {
map(Type.BYTE_ARRAY_PRIMITIVE); // Keys
handler(wrapper -> {
if (wrapper.read(Type.BOOLEAN)) {
// Nonce, just pass it through
wrapper.passthrough(Type.BYTE_ARRAY_PRIMITIVE);
} else {
// 🧂
final NonceStorage nonceStorage = wrapper.user().remove(NonceStorage.class);
if (nonceStorage == null) {
throw new IllegalArgumentException("Server sent nonce is missing");
}
wrapper.read(Type.LONG); // Salt
wrapper.read(Type.BYTE_ARRAY_PRIMITIVE); // Signature
wrapper.write(Type.BYTE_ARRAY_PRIMITIVE, nonceStorage.nonce());
}
});
}
});
}
@Override
protected void onMappingDataLoaded() {
Types1_19.PARTICLE.filler(this)
.reader("block", ParticleType.Readers.BLOCK)
.reader("block_marker", ParticleType.Readers.BLOCK)
.reader("dust", ParticleType.Readers.DUST)
.reader("falling_dust", ParticleType.Readers.BLOCK)
.reader("dust_color_transition", ParticleType.Readers.DUST_TRANSITION)
.reader("item", ParticleType.Readers.VAR_INT_ITEM)
.reader("vibration", ParticleType.Readers.VIBRATION)
.reader("sculk_charge", ParticleType.Readers.SCULK_CHARGE)
.reader("shriek", ParticleType.Readers.SHRIEK);
Entity1_19Types.initialize(this);
entityRewriter.onMappingDataLoaded();
}
@Override
public void init(final UserConnection user) {
if (!user.has(DimensionRegistryStorage.class)) {
user.put(new DimensionRegistryStorage());
}
addEntityTracker(user, new EntityTrackerBase(user, Entity1_19Types.PLAYER));
}
@Override
public MappingData getMappingData() {
return MAPPINGS;
}
@Override
public EntityRewriter getEntityRewriter() {
return entityRewriter;
}
@Override
public ItemRewriter getItemRewriter() {
return itemRewriter;
}
}
@@ -0,0 +1,84 @@
/*
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
* Copyright (C) 2016-2022 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_19to1_18_2;
import com.viaversion.viaversion.api.protocol.packet.ServerboundPacketType;
public enum ServerboundPackets1_19 implements ServerboundPacketType {
TELEPORT_CONFIRM, // 0x00
QUERY_BLOCK_NBT, // 0x01
SET_DIFFICULTY, // 0x02
CHAT_COMMAND, // 0x03
CHAT_MESSAGE, // 0x04
CHAT_PREVIEW, // 0x05
CLIENT_STATUS, // 0x06
CLIENT_SETTINGS, // 0x07
TAB_COMPLETE, // 0x08
CLICK_WINDOW_BUTTON, // 0x09
CLICK_WINDOW, // 0x0A
CLOSE_WINDOW, // 0x0B
PLUGIN_MESSAGE, // 0x0C
EDIT_BOOK, // 0x0D
ENTITY_NBT_REQUEST, // 0x0E
INTERACT_ENTITY, // 0x0F
GENERATE_JIGSAW, // 0x10
KEEP_ALIVE, // 0x11
LOCK_DIFFICULTY, // 0x12
PLAYER_POSITION, // 0x13
PLAYER_POSITION_AND_ROTATION, // 0x14
PLAYER_ROTATION, // 0x15
PLAYER_MOVEMENT, // 0x16
VEHICLE_MOVE, // 0x17
STEER_BOAT, // 0x18
PICK_ITEM, // 0x19
CRAFT_RECIPE_REQUEST, // 0x1A
PLAYER_ABILITIES, // 0x1B
PLAYER_DIGGING, // 0x1C
ENTITY_ACTION, // 0x1D
STEER_VEHICLE, // 0x1E
PONG, // 0x1F
RECIPE_BOOK_DATA, // 0x20
SEEN_RECIPE, // 0x21
RENAME_ITEM, // 0x22
RESOURCE_PACK_STATUS, // 0x23
ADVANCEMENT_TAB, // 0x24
SELECT_TRADE, // 0x25
SET_BEACON_EFFECT, // 0x26
HELD_ITEM_CHANGE, // 0x27
UPDATE_COMMAND_BLOCK, // 0x28
UPDATE_COMMAND_BLOCK_MINECART, // 0x29
CREATIVE_INVENTORY_ACTION, // 0x2A
UPDATE_JIGSAW_BLOCK, // 0x2B
UPDATE_STRUCTURE_BLOCK, // 0x2C
UPDATE_SIGN, // 0x2D
ANIMATION, // 0x2E
SPECTATE, // 0x2F
PLAYER_BLOCK_PLACEMENT, // 0x30
USE_ITEM; // 0x31
@Override
public int getId() {
return ordinal();
}
@Override
public String getName() {
return name();
}
}
@@ -0,0 +1,371 @@
/*
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
* Copyright (C) 2016-2022 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_19to1_18_2.packets;
import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
import com.github.steveice10.opennbt.tag.builtin.IntTag;
import com.github.steveice10.opennbt.tag.builtin.ListTag;
import com.github.steveice10.opennbt.tag.builtin.Tag;
import com.viaversion.viaversion.api.Via;
import com.viaversion.viaversion.api.data.entity.DimensionData;
import com.viaversion.viaversion.api.minecraft.Position;
import com.viaversion.viaversion.api.minecraft.entities.Entity1_19Types;
import com.viaversion.viaversion.api.minecraft.entities.EntityType;
import com.viaversion.viaversion.api.minecraft.metadata.Metadata;
import com.viaversion.viaversion.api.minecraft.nbt.BinaryTagIO;
import com.viaversion.viaversion.api.protocol.packet.PacketWrapper;
import com.viaversion.viaversion.api.protocol.remapper.PacketRemapper;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.api.type.types.version.Types1_18;
import com.viaversion.viaversion.api.type.types.version.Types1_19;
import com.viaversion.viaversion.data.entity.DimensionDataImpl;
import com.viaversion.viaversion.protocols.protocol1_18to1_17_1.ClientboundPackets1_18;
import com.viaversion.viaversion.protocols.protocol1_19to1_18_2.ClientboundPackets1_19;
import com.viaversion.viaversion.protocols.protocol1_19to1_18_2.Protocol1_19To1_18_2;
import com.viaversion.viaversion.protocols.protocol1_19to1_18_2.storage.DimensionRegistryStorage;
import com.viaversion.viaversion.rewriter.EntityRewriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public final class EntityPackets extends EntityRewriter<Protocol1_19To1_18_2> {
//TODO move to compressed nbt file
private static final String CHAT_REGISTRY_SNBT = "{\n" +
" \"minecraft:chat_type\": {\n" +
" \"type\": \"minecraft:chat_type\",\n" +
" \"value\": [\n" +
" {\n" +
" \"name\": \"minecraft:system\",\n" +
" \"id\": 0,\n" +
" \"element\": {\n" +
" \"chat\": {},\n" +
" \"narration\": {\n" +
" \"priority\": \"system\"\n" +
" }\n" +
" }\n" +
" },\n" +
" {\n" +
" \"name\": \"minecraft:game_info\",\n" +
" \"id\": 1,\n" +
" \"element\": {\n" +
" \"overlay\": {}\n" +
" }\n" +
" }\n" +
" ]\n" +
" }\n" +
"}";
private static final CompoundTag CHAT_REGISTRY;
static {
try {
CHAT_REGISTRY = BinaryTagIO.readString(CHAT_REGISTRY_SNBT).get("minecraft:chat_type");
} catch (final IOException e) {
throw new RuntimeException(e);
}
}
public EntityPackets(final Protocol1_19To1_18_2 protocol) {
super(protocol);
}
@Override
public void registerPackets() {
registerTracker(ClientboundPackets1_18.SPAWN_PLAYER, Entity1_19Types.PLAYER);
registerMetadataRewriter(ClientboundPackets1_18.ENTITY_METADATA, Types1_18.METADATA_LIST, Types1_19.METADATA_LIST);
registerRemoveEntities(ClientboundPackets1_18.REMOVE_ENTITIES);
protocol.registerClientbound(ClientboundPackets1_18.SPAWN_ENTITY, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.VAR_INT); // Entity id
map(Type.UUID); // Entity UUID
map(Type.VAR_INT); // Entity type
map(Type.DOUBLE); // X
map(Type.DOUBLE); // Y
map(Type.DOUBLE); // Z
map(Type.BYTE); // Pitch
map(Type.BYTE); // Yaw
handler(wrapper -> {
final byte yaw = wrapper.get(Type.BYTE, 1);
wrapper.write(Type.BYTE, yaw); // Head yaw
});
map(Type.INT, Type.VAR_INT); // Data
handler(trackerHandler());
handler(wrapper -> {
final int entityId = wrapper.get(Type.VAR_INT, 0);
final EntityType entityType = tracker(wrapper.user()).entityType(entityId);
if (entityType == Entity1_19Types.FALLING_BLOCK) {
wrapper.set(Type.VAR_INT, 2, protocol.getMappingData().getNewBlockStateId(wrapper.get(Type.VAR_INT, 2)));
}
});
}
});
protocol.registerClientbound(ClientboundPackets1_18.SPAWN_PAINTING, ClientboundPackets1_19.SPAWN_ENTITY, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.VAR_INT); // Entity id
map(Type.UUID); // Entity UUID
handler(wrapper -> {
wrapper.write(Type.VAR_INT, Entity1_19Types.PAINTING.getId());
final int motive = wrapper.read(Type.VAR_INT);
final Position blockPosition = wrapper.read(Type.POSITION1_14);
final byte direction = wrapper.read(Type.BYTE);
wrapper.write(Type.DOUBLE, blockPosition.x() + 0.5d);
wrapper.write(Type.DOUBLE, blockPosition.y() + 0.5d);
wrapper.write(Type.DOUBLE, blockPosition.z() + 0.5d);
wrapper.write(Type.BYTE, (byte) 0); // Pitch
wrapper.write(Type.BYTE, (byte) 0); // Yaw
wrapper.write(Type.BYTE, (byte) 0); // Head yaw
wrapper.write(Type.VAR_INT, to3dId(direction)); // Data
wrapper.write(Type.SHORT, (short) 0); // Velocity x
wrapper.write(Type.SHORT, (short) 0); // Velocity y
wrapper.write(Type.SHORT, (short) 0); // Velocity z
wrapper.send(Protocol1_19To1_18_2.class);
wrapper.cancel();
// Send motive in metadata
final PacketWrapper metaPacket = wrapper.create(ClientboundPackets1_19.ENTITY_METADATA);
metaPacket.write(Type.VAR_INT, wrapper.get(Type.VAR_INT, 0)); // Entity id
final List<Metadata> metadata = new ArrayList<>();
metadata.add(new Metadata(8, Types1_19.META_TYPES.paintingVariantType, protocol.getMappingData().getPaintingMappings().getNewId(motive)));
metaPacket.write(Types1_19.METADATA_LIST, metadata);
metaPacket.send(Protocol1_19To1_18_2.class);
});
}
});
protocol.registerClientbound(ClientboundPackets1_18.SPAWN_MOB, ClientboundPackets1_19.SPAWN_ENTITY, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.VAR_INT); // Entity ID
map(Type.UUID); // Entity UUID
map(Type.VAR_INT); // Entity Type
map(Type.DOUBLE); // X
map(Type.DOUBLE); // Y
map(Type.DOUBLE); // Z
handler(wrapper -> {
// Change order
final byte yaw = wrapper.read(Type.BYTE);
final byte pitch = wrapper.read(Type.BYTE);
wrapper.write(Type.BYTE, pitch);
wrapper.write(Type.BYTE, yaw);
});
map(Type.BYTE); // Head yaw
create(Type.VAR_INT, 0); // Data
map(Type.SHORT); // Velocity x
map(Type.SHORT); // Velocity y
map(Type.SHORT); // Velocity z
handler(trackerHandler());
}
});
protocol.registerClientbound(ClientboundPackets1_18.ENTITY_EFFECT, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.VAR_INT); // Entity id
map(Type.VAR_INT); // Effect id
map(Type.BYTE); // Amplifier
map(Type.VAR_INT); // Duration
map(Type.BYTE); // Flags
create(Type.BOOLEAN, false); // No factor data
}
});
protocol.registerClientbound(ClientboundPackets1_18.JOIN_GAME, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.INT); // Entity ID
map(Type.BOOLEAN); // Hardcore
map(Type.UNSIGNED_BYTE); // Gamemode
map(Type.BYTE); // Previous Gamemode
map(Type.STRING_ARRAY); // World List
map(Type.NBT); // Registry
handler(wrapper -> {
final CompoundTag tag = wrapper.get(Type.NBT, 0);
// Add necessary chat types
tag.put("minecraft:chat_type", CHAT_REGISTRY.clone());
// Cache a whole lot of data
final ListTag dimensions = ((CompoundTag) tag.get("minecraft:dimension_type")).get("value");
final Map<String, DimensionData> dimensionDataMap = new HashMap<>(dimensions.size());
final Map<CompoundTag, String> dimensionsMap = new HashMap<>(dimensions.size());
for (final Tag dimension : dimensions) {
final CompoundTag dimensionCompound = (CompoundTag) dimension;
final CompoundTag element = dimensionCompound.get("element");
final String name = (String) dimensionCompound.get("name").getValue();
dimensionDataMap.put(name, new DimensionDataImpl(element));
dimensionsMap.put(element.clone(), name);
addMonsterSpawnData(element);
}
tracker(wrapper.user()).setDimensions(dimensionDataMap);
final DimensionRegistryStorage registryStorage = wrapper.user().get(DimensionRegistryStorage.class);
registryStorage.setDimensions(dimensionsMap);
writeDimensionKey(wrapper, registryStorage);
});
map(Type.STRING); // World
map(Type.LONG); // Seed
map(Type.VAR_INT); // Max players
map(Type.VAR_INT); // Chunk radius
map(Type.VAR_INT); // Simulation distance
map(Type.BOOLEAN); // Reduced debug info
map(Type.BOOLEAN); // Show death screen
map(Type.BOOLEAN); // Debug
map(Type.BOOLEAN); // Flat
create(Type.OPTIONAL_GLOBAL_POSITION, null); // Last death location
handler(playerTrackerHandler());
handler(worldDataTrackerHandlerByKey());
handler(biomeSizeTracker());
handler(wrapper -> {
// Disable the chat preview
final PacketWrapper displayPreviewPacket = wrapper.create(ClientboundPackets1_19.SET_DISPLAY_CHAT_PREVIEW);
displayPreviewPacket.write(Type.BOOLEAN, false);
displayPreviewPacket.scheduleSend(Protocol1_19To1_18_2.class);
});
}
});
protocol.registerClientbound(ClientboundPackets1_18.RESPAWN, new PacketRemapper() {
@Override
public void registerMap() {
handler(wrapper -> writeDimensionKey(wrapper, wrapper.user().get(DimensionRegistryStorage.class)));
map(Type.STRING); // World
map(Type.LONG); // Seed
map(Type.UNSIGNED_BYTE); // Gamemode
map(Type.BYTE); // Previous gamemode
map(Type.BOOLEAN); // Debug
map(Type.BOOLEAN); // Flat
map(Type.BOOLEAN); // Keep player data
create(Type.OPTIONAL_GLOBAL_POSITION, null); // Last death location
handler(worldDataTrackerHandlerByKey());
}
});
protocol.registerClientbound(ClientboundPackets1_18.PLAYER_INFO, new PacketRemapper() {
@Override
public void registerMap() {
handler(wrapper -> {
final int action = wrapper.passthrough(Type.VAR_INT);
final int entries = wrapper.passthrough(Type.VAR_INT);
for (int i = 0; i < entries; i++) {
wrapper.passthrough(Type.UUID); // UUID
if (action == 0) { // Add player
wrapper.passthrough(Type.STRING); // Player Name
final int properties = wrapper.passthrough(Type.VAR_INT);
for (int j = 0; j < properties; j++) {
wrapper.passthrough(Type.STRING); // Name
wrapper.passthrough(Type.STRING); // Value
if (wrapper.passthrough(Type.BOOLEAN)) {
wrapper.passthrough(Type.STRING); // Signature
}
}
wrapper.passthrough(Type.VAR_INT); // Gamemode
wrapper.passthrough(Type.VAR_INT); // Ping
if (wrapper.passthrough(Type.BOOLEAN)) {
wrapper.passthrough(Type.COMPONENT); // Display name
}
// No public profile signature
wrapper.write(Type.BOOLEAN, false);
} else if (action == 1 || action == 2) { // Update gamemode/update latency
wrapper.passthrough(Type.VAR_INT);
} else if (action == 3) { // Update display name
if (wrapper.passthrough(Type.BOOLEAN)) {
wrapper.passthrough(Type.COMPONENT);
}
}
}
});
}
});
}
private static void writeDimensionKey(final PacketWrapper wrapper, final DimensionRegistryStorage registryStorage) throws Exception {
// Find dimension key by data
final CompoundTag currentDimension = wrapper.read(Type.NBT);
final String dimensionKey = registryStorage.dimensionKey(currentDimension);
if (dimensionKey == null) {
Via.getPlatform().getLogger().severe("The server tried to send dimension data from a dimension the client wasn't told about on join. " +
"Plugins and mods have to make sure they are not creating new dimension types while players are online, and proxies need to make sure they don't scramble dimension data." +
" Known dimensions:");
for (final Map.Entry<CompoundTag, String> entry : registryStorage.dimensions().entrySet()) {
Via.getPlatform().getLogger().severe(entry.getValue() + ": " + entry.getKey());
}
throw new IllegalArgumentException("Dimension not found in registry data from join packet: " + currentDimension);
}
wrapper.write(Type.STRING, dimensionKey);
}
private static int to3dId(final int id) {
switch (id) {
case -1: // Both up and down
return 1; // Up
case 2: // North
return 2;
case 0: // South
return 3;
case 1: // West
return 4;
case 3: // East
return 5;
}
throw new IllegalArgumentException("Unknown 2d id: " + id);
}
private static void addMonsterSpawnData(final CompoundTag dimension) {
// The actual values here don't matter
dimension.put("monster_spawn_block_light_limit", new IntTag(0));
dimension.put("monster_spawn_light_level", new IntTag(11));
}
@Override
protected void registerRewrites() {
filter().handler((event, meta) -> meta.setMetaType(Types1_19.META_TYPES.byId(meta.metaType().typeId())));
registerMetaTypeHandler(Types1_19.META_TYPES.itemType, Types1_19.META_TYPES.blockStateType, Types1_19.META_TYPES.particleType);
filter().filterFamily(Entity1_19Types.MINECART_ABSTRACT).index(11).handler((event, meta) -> {
// Convert to new block id
final int data = (int) meta.getValue();
meta.setValue(protocol.getMappingData().getNewBlockStateId(data));
});
filter().type(Entity1_19Types.CAT).index(19).handler((event, meta) -> meta.setMetaType(Types1_19.META_TYPES.catVariantType));
}
@Override
public void onMappingDataLoaded() {
mapTypes();
}
@Override
public EntityType typeFromId(final int type) {
return Entity1_19Types.getTypeFromId(type);
}
}
@@ -0,0 +1,112 @@
/*
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
* Copyright (C) 2016-2022 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_19to1_18_2.packets;
import com.viaversion.viaversion.api.protocol.packet.PacketWrapper;
import com.viaversion.viaversion.api.protocol.remapper.PacketHandler;
import com.viaversion.viaversion.api.protocol.remapper.PacketRemapper;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.protocols.protocol1_16to1_15_2.data.RecipeRewriter1_16;
import com.viaversion.viaversion.protocols.protocol1_18to1_17_1.ClientboundPackets1_18;
import com.viaversion.viaversion.protocols.protocol1_19to1_18_2.ClientboundPackets1_19;
import com.viaversion.viaversion.protocols.protocol1_19to1_18_2.Protocol1_19To1_18_2;
import com.viaversion.viaversion.protocols.protocol1_19to1_18_2.ServerboundPackets1_19;
import com.viaversion.viaversion.rewriter.ItemRewriter;
public final class InventoryPackets extends ItemRewriter<Protocol1_19To1_18_2> {
public InventoryPackets(Protocol1_19To1_18_2 protocol) {
super(protocol);
}
@Override
public void registerPackets() {
registerSetCooldown(ClientboundPackets1_18.COOLDOWN);
registerWindowItems1_17_1(ClientboundPackets1_18.WINDOW_ITEMS, Type.FLAT_VAR_INT_ITEM_ARRAY_VAR_INT, Type.FLAT_VAR_INT_ITEM);
registerTradeList(ClientboundPackets1_18.TRADE_LIST, Type.FLAT_VAR_INT_ITEM);
registerSetSlot1_17_1(ClientboundPackets1_18.SET_SLOT, Type.FLAT_VAR_INT_ITEM);
registerAdvancements(ClientboundPackets1_18.ADVANCEMENTS, Type.FLAT_VAR_INT_ITEM);
registerEntityEquipmentArray(ClientboundPackets1_18.ENTITY_EQUIPMENT, Type.FLAT_VAR_INT_ITEM);
protocol.registerClientbound(ClientboundPackets1_18.SPAWN_PARTICLE, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.INT, Type.VAR_INT); // 0 - Particle ID
map(Type.BOOLEAN); // 1 - Long Distance
map(Type.DOUBLE); // 2 - X
map(Type.DOUBLE); // 3 - Y
map(Type.DOUBLE); // 4 - Z
map(Type.FLOAT); // 5 - Offset X
map(Type.FLOAT); // 6 - Offset Y
map(Type.FLOAT); // 7 - Offset Z
map(Type.FLOAT); // 8 - Particle Data
map(Type.INT); // 9 - Particle Count
handler(getSpawnParticleHandler(Type.VAR_INT, Type.FLAT_VAR_INT_ITEM));
}
});
registerClickWindow1_17_1(ServerboundPackets1_19.CLICK_WINDOW, Type.FLAT_VAR_INT_ITEM);
registerCreativeInvAction(ServerboundPackets1_19.CREATIVE_INVENTORY_ACTION, Type.FLAT_VAR_INT_ITEM);
registerWindowPropertyEnchantmentHandler(ClientboundPackets1_18.WINDOW_PROPERTY);
protocol.registerServerbound(ServerboundPackets1_19.PLAYER_DIGGING, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.VAR_INT); // Action
map(Type.POSITION1_14); // Block position
map(Type.UNSIGNED_BYTE); // Direction
handler(sequenceHandler());
}
});
protocol.registerServerbound(ServerboundPackets1_19.PLAYER_BLOCK_PLACEMENT, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.VAR_INT); // Hand
map(Type.POSITION1_14); // Block position
map(Type.VAR_INT); // Direction
map(Type.FLOAT); // X
map(Type.FLOAT); // Y
map(Type.FLOAT); // Z
map(Type.BOOLEAN); // Inside
handler(sequenceHandler());
}
});
protocol.registerServerbound(ServerboundPackets1_19.USE_ITEM, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.VAR_INT); // Hand
handler(sequenceHandler());
}
});
new RecipeRewriter1_16(protocol).registerDefaultHandler(ClientboundPackets1_18.DECLARE_RECIPES);
}
private PacketHandler sequenceHandler() {
return wrapper -> {
// Manually send and follow up with an acknowledgement
final int sequence = wrapper.read(Type.VAR_INT);
wrapper.sendToServer(Protocol1_19To1_18_2.class);
wrapper.cancel();
final PacketWrapper ackPacket = wrapper.create(ClientboundPackets1_19.BLOCK_CHANGED_ACK);
ackPacket.write(Type.VAR_INT, sequence);
ackPacket.scheduleSend(Protocol1_19To1_18_2.class);
};
}
}
@@ -0,0 +1,89 @@
/*
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
* Copyright (C) 2016-2022 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_19to1_18_2.packets;
import com.google.common.base.Preconditions;
import com.viaversion.viaversion.api.data.entity.EntityTracker;
import com.viaversion.viaversion.api.minecraft.chunks.Chunk;
import com.viaversion.viaversion.api.minecraft.chunks.ChunkSection;
import com.viaversion.viaversion.api.minecraft.chunks.DataPalette;
import com.viaversion.viaversion.api.minecraft.chunks.PaletteType;
import com.viaversion.viaversion.api.protocol.remapper.PacketRemapper;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.protocols.protocol1_18to1_17_1.ClientboundPackets1_18;
import com.viaversion.viaversion.protocols.protocol1_18to1_17_1.types.Chunk1_18Type;
import com.viaversion.viaversion.protocols.protocol1_19to1_18_2.Protocol1_19To1_18_2;
import com.viaversion.viaversion.protocols.protocol1_19to1_18_2.ServerboundPackets1_19;
import com.viaversion.viaversion.rewriter.BlockRewriter;
import com.viaversion.viaversion.util.MathUtil;
public final class WorldPackets {
public static void register(final Protocol1_19To1_18_2 protocol) {
final BlockRewriter blockRewriter = new BlockRewriter(protocol, Type.POSITION1_14);
blockRewriter.registerBlockAction(ClientboundPackets1_18.BLOCK_ACTION);
blockRewriter.registerBlockChange(ClientboundPackets1_18.BLOCK_CHANGE);
blockRewriter.registerVarLongMultiBlockChange(ClientboundPackets1_18.MULTI_BLOCK_CHANGE);
blockRewriter.registerEffect(ClientboundPackets1_18.EFFECT, 1010, 2001);
protocol.cancelClientbound(ClientboundPackets1_18.ACKNOWLEDGE_PLAYER_DIGGING);
protocol.registerClientbound(ClientboundPackets1_18.CHUNK_DATA, new PacketRemapper() {
@Override
public void registerMap() {
handler(wrapper -> {
final EntityTracker tracker = protocol.getEntityRewriter().tracker(wrapper.user());
Preconditions.checkArgument(tracker.biomesSent() != 0, "Biome count not set");
Preconditions.checkArgument(tracker.currentWorldSectionHeight() != 0, "Section height not set");
final Chunk1_18Type chunkType = new Chunk1_18Type(tracker.currentWorldSectionHeight(),
MathUtil.ceilLog2(protocol.getMappingData().getBlockStateMappings().mappedSize()),
MathUtil.ceilLog2(tracker.biomesSent()));
final Chunk chunk = wrapper.passthrough(chunkType);
for (final ChunkSection section : chunk.getSections()) {
final DataPalette blockPalette = section.palette(PaletteType.BLOCKS);
for (int i = 0; i < blockPalette.size(); i++) {
final int id = blockPalette.idByIndex(i);
blockPalette.setIdByIndex(i, protocol.getMappingData().getNewBlockStateId(id));
}
}
});
}
});
protocol.registerServerbound(ServerboundPackets1_19.SET_BEACON_EFFECT, new PacketRemapper() {
@Override
public void registerMap() {
handler(wrapper -> {
// Primary effect
if (wrapper.read(Type.BOOLEAN)) {
wrapper.passthrough(Type.VAR_INT);
} else {
wrapper.write(Type.VAR_INT, -1);
}
// Secondary effect
if (wrapper.read(Type.BOOLEAN)) {
wrapper.passthrough(Type.VAR_INT);
} else {
wrapper.write(Type.VAR_INT, -1);
}
});
}
});
}
}
@@ -0,0 +1,46 @@
/*
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
* Copyright (C) 2016-2022 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_19to1_18_2.storage;
import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
import com.viaversion.viaversion.api.connection.StorableObject;
import org.checkerframework.checker.nullness.qual.Nullable;
import java.util.Map;
public final class DimensionRegistryStorage implements StorableObject {
private Map<CompoundTag, String> dimensions;
public @Nullable String dimensionKey(final CompoundTag dimensionData) {
return dimensions.get(dimensionData); // HMMMMMMMMMMM
}
public void setDimensions(final Map<CompoundTag, String> dimensions) {
this.dimensions = dimensions;
}
public Map<CompoundTag, String> dimensions() {
return dimensions;
}
@Override
public boolean clearOnServerSwitch() {
return false;
}
}
@@ -0,0 +1,33 @@
/*
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
* Copyright (C) 2016-2022 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_19to1_18_2.storage;
import com.viaversion.viaversion.api.connection.StorableObject;
public final class NonceStorage implements StorableObject {
private final byte[] nonce;
public NonceStorage(final byte[] nonce) {
this.nonce = nonce;
}
public byte[] nonce() {
return nonce;
}
}
@@ -30,11 +30,11 @@ import java.util.Map;
/**
* Abstract rewriter for the declare commands packet to handle argument type name and content changes.
*/
public abstract class CommandRewriter {
public class CommandRewriter {
protected final Protocol protocol;
protected final Map<String, CommandArgumentConsumer> parserHandlers = new HashMap<>();
protected CommandRewriter(Protocol protocol) {
public CommandRewriter(Protocol protocol) {
this.protocol = protocol;
// Register default parsers
@@ -122,13 +122,57 @@ public abstract class CommandRewriter {
});
}
public void registerDeclareCommands1_19(ClientboundPacketType packetType) {
protocol.registerClientbound(packetType, new PacketRemapper() {
@Override
public void registerMap() {
handler(wrapper -> {
int size = wrapper.passthrough(Type.VAR_INT);
for (int i = 0; i < size; i++) {
byte flags = wrapper.passthrough(Type.BYTE);
wrapper.passthrough(Type.VAR_INT_ARRAY_PRIMITIVE); // Children indices
if ((flags & 0x08) != 0) {
wrapper.passthrough(Type.VAR_INT); // Redirect node index
}
byte nodeType = (byte) (flags & 0x03);
if (nodeType == 1 || nodeType == 2) { // Literal/argument node
wrapper.passthrough(Type.STRING); // Name
}
if (nodeType == 2) { // Argument node
int argumentTypeId = wrapper.read(Type.VAR_INT);
String argumentType = protocol.getMappingData().getArgumentTypeMappings().identifier(argumentTypeId);
String newArgumentType = handleArgumentType(argumentType);
if (newArgumentType != null) {
wrapper.write(Type.VAR_INT, protocol.getMappingData().getArgumentTypeMappings().mappedId(newArgumentType));
}
// Always call the handler using the previous name
handleArgument(wrapper, argumentType);
}
if ((flags & 0x10) != 0) {
wrapper.passthrough(Type.STRING); // Suggestion type
}
}
wrapper.passthrough(Type.VAR_INT); // Root node index
});
}
});
}
/**
* Can be overridden if needed.
*
* @param argumentType argument type
* @return new argument type, or null if it should be removed
*/
protected @Nullable String handleArgumentType(String argumentType) {
public @Nullable String handleArgumentType(String argumentType) {
if (protocol.getMappingData() != null && protocol.getMappingData().getArgumentTypeMappings() != null) {
return protocol.getMappingData().getArgumentTypeMappings().mappedIdentifier(argumentType);
}
return argumentType;
}
@@ -24,7 +24,10 @@ import com.github.steveice10.opennbt.tag.builtin.Tag;
import com.google.common.base.Preconditions;
import com.viaversion.viaversion.api.Via;
import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.api.data.Int2IntMapMappings;
import com.viaversion.viaversion.api.data.Mappings;
import com.viaversion.viaversion.api.data.ParticleMappings;
import com.viaversion.viaversion.api.data.entity.DimensionData;
import com.viaversion.viaversion.api.data.entity.EntityTracker;
import com.viaversion.viaversion.api.minecraft.entities.EntityType;
import com.viaversion.viaversion.api.minecraft.item.Item;
@@ -40,8 +43,6 @@ import com.viaversion.viaversion.api.type.types.Particle;
import com.viaversion.viaversion.rewriter.meta.MetaFilter;
import com.viaversion.viaversion.rewriter.meta.MetaHandlerEvent;
import com.viaversion.viaversion.rewriter.meta.MetaHandlerEventImpl;
import it.unimi.dsi.fastutil.ints.Int2IntMap;
import it.unimi.dsi.fastutil.ints.Int2IntOpenHashMap;
import org.checkerframework.checker.nullness.qual.Nullable;
import java.util.ArrayList;
@@ -54,7 +55,7 @@ public abstract class EntityRewriter<T extends Protocol> extends RewriterBase<T>
private static final Metadata[] EMPTY_ARRAY = new Metadata[0];
protected final List<MetaFilter> metadataFilters = new ArrayList<>();
protected final boolean trackMappedType;
protected Int2IntMap typeMappings;
protected Mappings typeMappings;
protected EntityRewriter(T protocol) {
this(protocol, true);
@@ -166,7 +167,7 @@ public abstract class EntityRewriter<T extends Protocol> extends RewriterBase<T>
@Override
public int newEntityId(int id) {
return typeMappings != null ? typeMappings.getOrDefault(id, id) : id;
return typeMappings != null ? typeMappings.getNewIdOrDefault(id, id) : id;
}
/**
@@ -183,10 +184,9 @@ public abstract class EntityRewriter<T extends Protocol> extends RewriterBase<T>
protected void mapEntityType(int id, int mappedId) {
if (typeMappings == null) {
typeMappings = new Int2IntOpenHashMap();
typeMappings.defaultReturnValue(-1);
typeMappings = Int2IntMapMappings.of();
}
typeMappings.put(id, mappedId);
typeMappings.setNewId(id, mappedId);
}
/**
@@ -198,15 +198,14 @@ public abstract class EntityRewriter<T extends Protocol> extends RewriterBase<T>
*/
public <E extends Enum<E> & EntityType> void mapTypes(EntityType[] oldTypes, Class<E> newTypeClass) {
if (typeMappings == null) {
typeMappings = new Int2IntOpenHashMap(oldTypes.length, .99F);
typeMappings.defaultReturnValue(-1);
typeMappings = Int2IntMapMappings.of();
}
for (EntityType oldType : oldTypes) {
try {
E newType = Enum.valueOf(newTypeClass, oldType.name());
typeMappings.put(oldType.getId(), newType.getId());
typeMappings.setNewId(oldType.getId(), newType.getId());
} catch (IllegalArgumentException notFound) {
if (!typeMappings.containsKey(oldType.getId())) {
if (!typeMappings.contains(oldType.getId())) {
Via.getPlatform().getLogger().warning("Could not find new entity type for " + oldType + "! " +
"Old type: " + oldType.getClass().getEnclosingClass().getSimpleName() + ", new type: " + newTypeClass.getEnclosingClass().getSimpleName());
}
@@ -214,6 +213,15 @@ public abstract class EntityRewriter<T extends Protocol> extends RewriterBase<T>
}
}
/**
* Maps entity ids based on the protocol's mapping data.
*/
public void mapTypes() {
Preconditions.checkArgument(typeMappings == null, "Type mappings have already been set - manual type mappings should be set *after* this");
Preconditions.checkNotNull(protocol.getMappingData().getEntityMappings(), "Protocol does not have entity mappings");
typeMappings = protocol.getMappingData().getEntityMappings().mappings();
}
/**
* Registers a metadata handler to rewrite, item, block, and particle ids stored in metadata.
*
@@ -271,6 +279,32 @@ public abstract class EntityRewriter<T extends Protocol> extends RewriterBase<T>
});
}
public void registerTrackerWithData1_19(ClientboundPacketType packetType, EntityType fallingBlockType) {
protocol.registerClientbound(packetType, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.VAR_INT); // Entity id
map(Type.UUID); // Entity UUID
map(Type.VAR_INT); // Entity type
map(Type.DOUBLE); // X
map(Type.DOUBLE); // Y
map(Type.DOUBLE); // Z
map(Type.BYTE); // Pitch
map(Type.BYTE); // Yaw
map(Type.BYTE); // Head yaw
map(Type.VAR_INT); // Data
handler(trackerHandler());
handler(wrapper -> {
int entityId = wrapper.get(Type.VAR_INT, 0);
EntityType entityType = tracker(wrapper.user()).entityType(entityId);
if (entityType == fallingBlockType) {
wrapper.set(Type.VAR_INT, 2, protocol.getMappingData().getNewBlockStateId(wrapper.get(Type.VAR_INT, 2)));
}
});
}
});
}
/**
* Registers an entity tracker for the extra spawn packets like player, painting, or xp orb spawns.
*
@@ -364,6 +398,15 @@ public abstract class EntityRewriter<T extends Protocol> extends RewriterBase<T>
return trackerAndRewriterHandler(null);
}
public PacketHandler playerTrackerHandler() {
return wrapper -> {
final EntityTracker tracker = tracker(wrapper.user());
final int entityId = wrapper.get(Type.INT, 0);
tracker.setClientEntityId(entityId);
tracker.addEntity(entityId, tracker.playerType());
};
}
/**
* Returns a packet handler storing height, min_y, and name of the current world.
* If the client changes to a new world, the stored entity data will be cleared.
@@ -394,6 +437,30 @@ public abstract class EntityRewriter<T extends Protocol> extends RewriterBase<T>
String world = wrapper.get(Type.STRING, 0);
if (tracker.currentWorld() != null && !tracker.currentWorld().equals(world)) {
tracker.clearEntities();
tracker.trackClientEntity();
}
tracker.setCurrentWorld(world);
};
}
public PacketHandler worldDataTrackerHandlerByKey() {
return wrapper -> {
EntityTracker tracker = tracker(wrapper.user());
String key = wrapper.get(Type.STRING, 0);
DimensionData dimensionData = tracker.dimensionData(key);
if (dimensionData == null) {
Via.getPlatform().getLogger().severe("Dimension data missing for dimension: " + key + ", falling back to overworld");
dimensionData = tracker.dimensionData("minecraft:overworld");
Preconditions.checkNotNull(dimensionData, "Overworld data missing");
}
tracker.setCurrentWorldSectionHeight(dimensionData.height() >> 4);
tracker.setCurrentMinY(dimensionData.minY());
String world = wrapper.get(Type.STRING, 0);
if (tracker.currentWorld() != null && !tracker.currentWorld().equals(world)) {
tracker.clearEntities();
tracker.trackClientEntity();
}
tracker.setCurrentWorld(world);
};
@@ -17,6 +17,7 @@
*/
package com.viaversion.viaversion.rewriter;
import com.viaversion.viaversion.api.data.Mappings;
import com.viaversion.viaversion.api.data.ParticleMappings;
import com.viaversion.viaversion.api.minecraft.item.Item;
import com.viaversion.viaversion.api.protocol.Protocol;
@@ -171,30 +172,6 @@ public abstract class ItemRewriter<T extends Protocol> extends RewriterBase<T> i
});
}
public void registerClickWindow1_17(ServerboundPacketType packetType, Type<Item> type) {
protocol.registerServerbound(packetType, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.UNSIGNED_BYTE); // Window Id
map(Type.SHORT); // Slot
map(Type.BYTE); // Button
map(Type.VAR_INT); // Mode
handler(wrapper -> {
// Affected items
int length = wrapper.passthrough(Type.VAR_INT);
for (int i = 0; i < length; i++) {
wrapper.passthrough(Type.SHORT); // Slot
handleItemToServer(wrapper.passthrough(type));
}
// Carried item
handleItemToServer(wrapper.passthrough(type));
});
}
});
}
public void registerClickWindow1_17_1(ServerboundPacketType packetType, Type<Item> type) {
protocol.registerServerbound(packetType, new PacketRemapper() {
@Override
@@ -303,6 +280,23 @@ public abstract class ItemRewriter<T extends Protocol> extends RewriterBase<T> i
});
}
public void registerWindowPropertyEnchantmentHandler(ClientboundPacketType packetType) {
protocol.registerClientbound(packetType, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.UNSIGNED_BYTE); // Container id
handler(wrapper -> {
short property = wrapper.passthrough(Type.SHORT);
if (property >= 4 && property <= 6) { // Enchantment id
Mappings mappings = protocol.getMappingData().getEnchantmentMappings();
short enchantmentId = (short) mappings.getNewId(wrapper.read(Type.SHORT));
wrapper.write(Type.SHORT, enchantmentId);
}
});
}
});
}
// Not the very best place for this, but has to stay here until *everything* is abstracted
public void registerSpawnParticle(ClientboundPacketType packetType, Type<Item> itemType, Type<?> coordType) {
protocol.registerClientbound(packetType, new PacketRemapper() {
@@ -323,22 +317,45 @@ public abstract class ItemRewriter<T extends Protocol> extends RewriterBase<T> i
});
}
public void registerSpawnParticle1_19(ClientboundPacketType packetType, Type<Item> itemType, Type<?> coordType) {
protocol.registerClientbound(packetType, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.VAR_INT); // 0 - Particle ID
map(Type.BOOLEAN); // 1 - Long Distance
map(coordType); // 2 - X
map(coordType); // 3 - Y
map(coordType); // 4 - Z
map(Type.FLOAT); // 5 - Offset X
map(Type.FLOAT); // 6 - Offset Y
map(Type.FLOAT); // 7 - Offset Z
map(Type.FLOAT); // 8 - Particle Data
map(Type.INT); // 9 - Particle Count
handler(getSpawnParticleHandler(Type.VAR_INT, itemType));
}
});
}
public PacketHandler getSpawnParticleHandler(Type<Item> itemType) {
return getSpawnParticleHandler(Type.INT, itemType);
}
public PacketHandler getSpawnParticleHandler(Type<Integer> idType, Type<Item> itemType) {
return wrapper -> {
int id = wrapper.get(Type.INT, 0);
int id = wrapper.get(idType, 0);
if (id == -1) return;
ParticleMappings mappings = protocol.getMappingData().getParticleMappings();
if (mappings.isBlockParticle(id)) {
int data = wrapper.passthrough(Type.VAR_INT);
wrapper.set(Type.VAR_INT, 0, protocol.getMappingData().getNewBlockStateId(data));
int data = wrapper.read(Type.VAR_INT);
wrapper.write(Type.VAR_INT, protocol.getMappingData().getNewBlockStateId(data));
} else if (mappings.isItemParticle(id)) {
handleItemToClient(wrapper.passthrough(itemType));
}
int newId = protocol.getMappingData().getNewParticleId(id);
if (newId != id) {
wrapper.set(Type.INT, 0, newId);
wrapper.set(idType, 0, newId);
}
};
}
@@ -33,13 +33,18 @@ import org.checkerframework.checker.nullness.qual.Nullable;
import java.util.ArrayList;
import java.util.EnumMap;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
public class TagRewriter {
private static final int[] EMPTY_ARRAY = {};
private final Protocol protocol;
private final Map<RegistryType, List<TagData>> newTags = new EnumMap<>(RegistryType.class);
private final Map<RegistryType, Map<String, String>> toRename = new EnumMap<>(RegistryType.class);
private final Set<String> toRemove = new HashSet<>();
public TagRewriter(Protocol protocol) {
this.protocol = protocol;
@@ -57,6 +62,14 @@ public class TagRewriter {
}
}
public void removeTags(final String registryKey) {
toRemove.add(registryKey);
}
public void renameTag(final RegistryType type, final String registryKey, final String renameTo) {
toRename.computeIfAbsent(type, t -> new HashMap<>()).put(registryKey, renameTo);
}
/**
* Adds an empty tag (since the client crashes if a checked tag is not registered).
*
@@ -77,7 +90,7 @@ public class TagRewriter {
/**
* Adds an entity tag type to be filled with the given entity type ids.
*
* @param tagId registry tag type
* @param tagId registry tag type
* @param entities mapped entity types
*/
public void addEntityTag(String tagId, EntityType... entities) {
@@ -148,7 +161,7 @@ public class TagRewriter {
public PacketHandler getHandler(@Nullable RegistryType readUntilType) {
return wrapper -> {
for (RegistryType type : RegistryType.getValues()) {
handle(wrapper, getRewriter(type), getNewTags(type));
handle(wrapper, getRewriter(type), getNewTags(type), toRename.get(type));
// Stop iterating
if (type == readUntilType) {
@@ -160,29 +173,53 @@ public class TagRewriter {
public PacketHandler getGenericHandler() {
return wrapper -> {
int length = wrapper.passthrough(Type.VAR_INT);
final int length = wrapper.passthrough(Type.VAR_INT);
int editedLength = length;
for (int i = 0; i < length; i++) {
String registryKey = wrapper.passthrough(Type.STRING);
String registryKey = wrapper.read(Type.STRING);
if (toRemove.contains(registryKey)) {
wrapper.set(Type.VAR_INT, 0, --editedLength);
int tagsSize = wrapper.read(Type.VAR_INT);
for (int j = 0; j < tagsSize; j++) {
wrapper.read(Type.STRING);
wrapper.read(Type.VAR_INT_ARRAY_PRIMITIVE);
}
continue;
}
wrapper.write(Type.STRING, registryKey);
if (registryKey.startsWith("minecraft:")) {
registryKey = registryKey.substring(10);
}
RegistryType type = RegistryType.getByKey(registryKey);
if (type != null) {
handle(wrapper, getRewriter(type), getNewTags(type));
handle(wrapper, getRewriter(type), getNewTags(type), toRename.get(type));
} else {
handle(wrapper, null, null);
handle(wrapper, null, null, null);
}
}
};
}
public void handle(PacketWrapper wrapper, @Nullable IdRewriteFunction rewriteFunction, @Nullable List<TagData> newTags) throws Exception {
handle(wrapper, rewriteFunction, newTags, null);
}
public void handle(PacketWrapper wrapper, @Nullable IdRewriteFunction rewriteFunction, @Nullable List<TagData> newTags, @Nullable Map<String, String> tagsToRename) throws Exception {
int tagsSize = wrapper.read(Type.VAR_INT);
wrapper.write(Type.VAR_INT, newTags != null ? tagsSize + newTags.size() : tagsSize); // add new tags count
for (int i = 0; i < tagsSize; i++) {
wrapper.passthrough(Type.STRING);
String key = wrapper.read(Type.STRING);
if (tagsToRename != null) {
String renamedKey = tagsToRename.get(key);
if (renamedKey != null) {
key = renamedKey;
}
}
wrapper.write(Type.STRING, key);
int[] ids = wrapper.read(Type.VAR_INT_ARRAY_PRIMITIVE);
if (rewriteFunction != null) {
// Map ids and filter out new blocks
@@ -2378,7 +2378,7 @@
"25100329": "minecraft:zombie_pigman_spawn_egg",
"25100330": "minecraft:zombie_villager_spawn_egg"
},
"enchantments": {
"legacy_enchantments": {
"0": "minecraft:protection",
"1": "minecraft:fire_protection",
"2": "minecraft:feather_falling",
@@ -11301,42 +11301,42 @@
"weather.rain",
"weather.rain.above"
],
"enchantments": {
"0": "minecraft:protection",
"1": "minecraft:fire_protection",
"2": "minecraft:feather_falling",
"3": "minecraft:blast_protection",
"4": "minecraft:projectile_protection",
"5": "minecraft:respiration",
"6": "minecraft:aqua_affinity",
"7": "minecraft:thorns",
"8": "minecraft:depth_strider",
"9": "minecraft:frost_walker",
"10": "minecraft:binding_curse",
"11": "minecraft:sharpness",
"12": "minecraft:smite",
"13": "minecraft:bane_of_arthropods",
"14": "minecraft:knockback",
"15": "minecraft:fire_aspect",
"16": "minecraft:looting",
"17": "minecraft:sweeping",
"18": "minecraft:efficiency",
"19": "minecraft:silk_touch",
"20": "minecraft:unbreaking",
"21": "minecraft:fortune",
"22": "minecraft:power",
"23": "minecraft:punch",
"24": "minecraft:flame",
"25": "minecraft:infinity",
"26": "minecraft:luck_of_the_sea",
"27": "minecraft:lure",
"28": "minecraft:loyalty",
"29": "minecraft:impaling",
"30": "minecraft:riptide",
"31": "minecraft:channeling",
"32": "minecraft:mending",
"33": "minecraft:vanishing_curse"
},
"enchantments": [
"minecraft:protection",
"minecraft:fire_protection",
"minecraft:feather_falling",
"minecraft:blast_protection",
"minecraft:projectile_protection",
"minecraft:respiration",
"minecraft:aqua_affinity",
"minecraft:thorns",
"minecraft:depth_strider",
"minecraft:frost_walker",
"minecraft:binding_curse",
"minecraft:sharpness",
"minecraft:smite",
"minecraft:bane_of_arthropods",
"minecraft:knockback",
"minecraft:fire_aspect",
"minecraft:looting",
"minecraft:sweeping",
"minecraft:efficiency",
"minecraft:silk_touch",
"minecraft:unbreaking",
"minecraft:fortune",
"minecraft:power",
"minecraft:punch",
"minecraft:flame",
"minecraft:infinity",
"minecraft:luck_of_the_sea",
"minecraft:lure",
"minecraft:loyalty",
"minecraft:impaling",
"minecraft:riptide",
"minecraft:channeling",
"minecraft:mending",
"minecraft:vanishing_curse"
],
"statistics": [
"minecraft.leave_game",
"minecraft.play_one_minute",
@@ -23676,5 +23676,236 @@
"campfire",
"beehive",
"sculk_sensor"
],
"argumenttypes": [
"brigadier:bool",
"brigadier:float",
"brigadier:double",
"brigadier:integer",
"brigadier:long",
"brigadier:string",
"minecraft:entity",
"minecraft:game_profile",
"minecraft:block_pos",
"minecraft:column_pos",
"minecraft:vec3",
"minecraft:vec2",
"minecraft:block_state",
"minecraft:block_predicate",
"minecraft:item_stack",
"minecraft:item_predicate",
"minecraft:color",
"minecraft:component",
"minecraft:message",
"minecraft:nbt_compound_tag",
"minecraft:nbt_tag",
"minecraft:nbt_path",
"minecraft:objective",
"minecraft:objective_criteria",
"minecraft:operation",
"minecraft:particle",
"minecraft:angle",
"minecraft:rotation",
"minecraft:scoreboard_slot",
"minecraft:score_holder",
"minecraft:swizzle",
"minecraft:team",
"minecraft:item_slot",
"minecraft:resource_location",
"minecraft:mob_effect",
"minecraft:function",
"minecraft:entity_anchor",
"minecraft:int_range",
"minecraft:float_range",
"minecraft:item_enchantment",
"minecraft:entity_summon",
"minecraft:dimension",
"minecraft:time",
"minecraft:uuid",
"minecraft:resource",
"minecraft:resource_or_tag"
],
"enchantments": [
"minecraft:protection",
"minecraft:fire_protection",
"minecraft:feather_falling",
"minecraft:blast_protection",
"minecraft:projectile_protection",
"minecraft:respiration",
"minecraft:aqua_affinity",
"minecraft:thorns",
"minecraft:depth_strider",
"minecraft:frost_walker",
"minecraft:binding_curse",
"minecraft:soul_speed",
"minecraft:sharpness",
"minecraft:smite",
"minecraft:bane_of_arthropods",
"minecraft:knockback",
"minecraft:fire_aspect",
"minecraft:looting",
"minecraft:sweeping",
"minecraft:efficiency",
"minecraft:silk_touch",
"minecraft:unbreaking",
"minecraft:fortune",
"minecraft:power",
"minecraft:punch",
"minecraft:flame",
"minecraft:infinity",
"minecraft:luck_of_the_sea",
"minecraft:lure",
"minecraft:loyalty",
"minecraft:impaling",
"minecraft:riptide",
"minecraft:channeling",
"minecraft:multishot",
"minecraft:quick_charge",
"minecraft:piercing",
"minecraft:mending",
"minecraft:vanishing_curse"
],
"entities": [
"minecraft:area_effect_cloud",
"minecraft:armor_stand",
"minecraft:arrow",
"minecraft:axolotl",
"minecraft:bat",
"minecraft:bee",
"minecraft:blaze",
"minecraft:boat",
"minecraft:cat",
"minecraft:cave_spider",
"minecraft:chicken",
"minecraft:cod",
"minecraft:cow",
"minecraft:creeper",
"minecraft:dolphin",
"minecraft:donkey",
"minecraft:dragon_fireball",
"minecraft:drowned",
"minecraft:elder_guardian",
"minecraft:end_crystal",
"minecraft:ender_dragon",
"minecraft:enderman",
"minecraft:endermite",
"minecraft:evoker",
"minecraft:evoker_fangs",
"minecraft:experience_orb",
"minecraft:eye_of_ender",
"minecraft:falling_block",
"minecraft:firework_rocket",
"minecraft:fox",
"minecraft:ghast",
"minecraft:giant",
"minecraft:glow_item_frame",
"minecraft:glow_squid",
"minecraft:goat",
"minecraft:guardian",
"minecraft:hoglin",
"minecraft:horse",
"minecraft:husk",
"minecraft:illusioner",
"minecraft:iron_golem",
"minecraft:item",
"minecraft:item_frame",
"minecraft:fireball",
"minecraft:leash_knot",
"minecraft:lightning_bolt",
"minecraft:llama",
"minecraft:llama_spit",
"minecraft:magma_cube",
"minecraft:marker",
"minecraft:minecart",
"minecraft:chest_minecart",
"minecraft:command_block_minecart",
"minecraft:furnace_minecart",
"minecraft:hopper_minecart",
"minecraft:spawner_minecart",
"minecraft:tnt_minecart",
"minecraft:mule",
"minecraft:mooshroom",
"minecraft:ocelot",
"minecraft:painting",
"minecraft:panda",
"minecraft:parrot",
"minecraft:phantom",
"minecraft:pig",
"minecraft:piglin",
"minecraft:piglin_brute",
"minecraft:pillager",
"minecraft:polar_bear",
"minecraft:tnt",
"minecraft:pufferfish",
"minecraft:rabbit",
"minecraft:ravager",
"minecraft:salmon",
"minecraft:sheep",
"minecraft:shulker",
"minecraft:shulker_bullet",
"minecraft:silverfish",
"minecraft:skeleton",
"minecraft:skeleton_horse",
"minecraft:slime",
"minecraft:small_fireball",
"minecraft:snow_golem",
"minecraft:snowball",
"minecraft:spectral_arrow",
"minecraft:spider",
"minecraft:squid",
"minecraft:stray",
"minecraft:strider",
"minecraft:egg",
"minecraft:ender_pearl",
"minecraft:experience_bottle",
"minecraft:potion",
"minecraft:trident",
"minecraft:trader_llama",
"minecraft:tropical_fish",
"minecraft:turtle",
"minecraft:vex",
"minecraft:villager",
"minecraft:vindicator",
"minecraft:wandering_trader",
"minecraft:witch",
"minecraft:wither",
"minecraft:wither_skeleton",
"minecraft:wither_skull",
"minecraft:wolf",
"minecraft:zoglin",
"minecraft:zombie",
"minecraft:zombie_horse",
"minecraft:zombie_villager",
"minecraft:zombified_piglin",
"minecraft:player",
"minecraft:fishing_bobber"
],
"paintings": [
"minecraft:kebab",
"minecraft:aztec",
"minecraft:alban",
"minecraft:aztec2",
"minecraft:bomb",
"minecraft:plant",
"minecraft:wasteland",
"minecraft:pool",
"minecraft:courbet",
"minecraft:sea",
"minecraft:sunset",
"minecraft:creebet",
"minecraft:wanderer",
"minecraft:graham",
"minecraft:match",
"minecraft:bust",
"minecraft:stage",
"minecraft:void",
"minecraft:skull_and_roses",
"minecraft:wither",
"minecraft:fighters",
"minecraft:pointer",
"minecraft:pigscene",
"minecraft:burning_skull",
"minecraft:skeleton",
"minecraft:donkey_kong"
]
}
File diff suppressed because it is too large. Load diff
@@ -0,0 +1,200 @@
{
"blockstates": {
"148": "minecraft:oak_leaves[distance=1,persistent=true,waterlogged=false]",
"149": "minecraft:oak_leaves[distance=1,persistent=false,waterlogged=false]",
"150": "minecraft:oak_leaves[distance=2,persistent=true,waterlogged=false]",
"151": "minecraft:oak_leaves[distance=2,persistent=false,waterlogged=false]",
"152": "minecraft:oak_leaves[distance=3,persistent=true,waterlogged=false]",
"153": "minecraft:oak_leaves[distance=3,persistent=false,waterlogged=false]",
"154": "minecraft:oak_leaves[distance=4,persistent=true,waterlogged=false]",
"155": "minecraft:oak_leaves[distance=4,persistent=false,waterlogged=false]",
"156": "minecraft:oak_leaves[distance=5,persistent=true,waterlogged=false]",
"157": "minecraft:oak_leaves[distance=5,persistent=false,waterlogged=false]",
"158": "minecraft:oak_leaves[distance=6,persistent=true,waterlogged=false]",
"159": "minecraft:oak_leaves[distance=6,persistent=false,waterlogged=false]",
"160": "minecraft:oak_leaves[distance=7,persistent=true,waterlogged=false]",
"161": "minecraft:oak_leaves[distance=7,persistent=false,waterlogged=false]",
"162": "minecraft:spruce_leaves[distance=1,persistent=true,waterlogged=false]",
"163": "minecraft:spruce_leaves[distance=1,persistent=false,waterlogged=false]",
"164": "minecraft:spruce_leaves[distance=2,persistent=true,waterlogged=false]",
"165": "minecraft:spruce_leaves[distance=2,persistent=false,waterlogged=false]",
"166": "minecraft:spruce_leaves[distance=3,persistent=true,waterlogged=false]",
"167": "minecraft:spruce_leaves[distance=3,persistent=false,waterlogged=false]",
"168": "minecraft:spruce_leaves[distance=4,persistent=true,waterlogged=false]",
"169": "minecraft:spruce_leaves[distance=4,persistent=false,waterlogged=false]",
"170": "minecraft:spruce_leaves[distance=5,persistent=true,waterlogged=false]",
"171": "minecraft:spruce_leaves[distance=5,persistent=false,waterlogged=false]",
"172": "minecraft:spruce_leaves[distance=6,persistent=true,waterlogged=false]",
"173": "minecraft:spruce_leaves[distance=6,persistent=false,waterlogged=false]",
"174": "minecraft:spruce_leaves[distance=7,persistent=true,waterlogged=false]",
"175": "minecraft:spruce_leaves[distance=7,persistent=false,waterlogged=false]",
"176": "minecraft:birch_leaves[distance=1,persistent=true,waterlogged=false]",
"177": "minecraft:birch_leaves[distance=1,persistent=false,waterlogged=false]",
"178": "minecraft:birch_leaves[distance=2,persistent=true,waterlogged=false]",
"179": "minecraft:birch_leaves[distance=2,persistent=false,waterlogged=false]",
"180": "minecraft:birch_leaves[distance=3,persistent=true,waterlogged=false]",
"181": "minecraft:birch_leaves[distance=3,persistent=false,waterlogged=false]",
"182": "minecraft:birch_leaves[distance=4,persistent=true,waterlogged=false]",
"183": "minecraft:birch_leaves[distance=4,persistent=false,waterlogged=false]",
"184": "minecraft:birch_leaves[distance=5,persistent=true,waterlogged=false]",
"185": "minecraft:birch_leaves[distance=5,persistent=false,waterlogged=false]",
"186": "minecraft:birch_leaves[distance=6,persistent=true,waterlogged=false]",
"187": "minecraft:birch_leaves[distance=6,persistent=false,waterlogged=false]",
"188": "minecraft:birch_leaves[distance=7,persistent=true,waterlogged=false]",
"189": "minecraft:birch_leaves[distance=7,persistent=false,waterlogged=false]",
"190": "minecraft:jungle_leaves[distance=1,persistent=true,waterlogged=false]",
"191": "minecraft:jungle_leaves[distance=1,persistent=false,waterlogged=false]",
"192": "minecraft:jungle_leaves[distance=2,persistent=true,waterlogged=false]",
"193": "minecraft:jungle_leaves[distance=2,persistent=false,waterlogged=false]",
"194": "minecraft:jungle_leaves[distance=3,persistent=true,waterlogged=false]",
"195": "minecraft:jungle_leaves[distance=3,persistent=false,waterlogged=false]",
"196": "minecraft:jungle_leaves[distance=4,persistent=true,waterlogged=false]",
"197": "minecraft:jungle_leaves[distance=4,persistent=false,waterlogged=false]",
"198": "minecraft:jungle_leaves[distance=5,persistent=true,waterlogged=false]",
"199": "minecraft:jungle_leaves[distance=5,persistent=false,waterlogged=false]",
"200": "minecraft:jungle_leaves[distance=6,persistent=true,waterlogged=false]",
"201": "minecraft:jungle_leaves[distance=6,persistent=false,waterlogged=false]",
"202": "minecraft:jungle_leaves[distance=7,persistent=true,waterlogged=false]",
"203": "minecraft:jungle_leaves[distance=7,persistent=false,waterlogged=false]",
"204": "minecraft:acacia_leaves[distance=1,persistent=true,waterlogged=false]",
"205": "minecraft:acacia_leaves[distance=1,persistent=false,waterlogged=false]",
"206": "minecraft:acacia_leaves[distance=2,persistent=true,waterlogged=false]",
"207": "minecraft:acacia_leaves[distance=2,persistent=false,waterlogged=false]",
"208": "minecraft:acacia_leaves[distance=3,persistent=true,waterlogged=false]",
"209": "minecraft:acacia_leaves[distance=3,persistent=false,waterlogged=false]",
"210": "minecraft:acacia_leaves[distance=4,persistent=true,waterlogged=false]",
"211": "minecraft:acacia_leaves[distance=4,persistent=false,waterlogged=false]",
"212": "minecraft:acacia_leaves[distance=5,persistent=true,waterlogged=false]",
"213": "minecraft:acacia_leaves[distance=5,persistent=false,waterlogged=false]",
"214": "minecraft:acacia_leaves[distance=6,persistent=true,waterlogged=false]",
"215": "minecraft:acacia_leaves[distance=6,persistent=false,waterlogged=false]",
"216": "minecraft:acacia_leaves[distance=7,persistent=true,waterlogged=false]",
"217": "minecraft:acacia_leaves[distance=7,persistent=false,waterlogged=false]",
"218": "minecraft:dark_oak_leaves[distance=1,persistent=true,waterlogged=false]",
"219": "minecraft:dark_oak_leaves[distance=1,persistent=false,waterlogged=false]",
"220": "minecraft:dark_oak_leaves[distance=2,persistent=true,waterlogged=false]",
"221": "minecraft:dark_oak_leaves[distance=2,persistent=false,waterlogged=false]",
"222": "minecraft:dark_oak_leaves[distance=3,persistent=true,waterlogged=false]",
"223": "minecraft:dark_oak_leaves[distance=3,persistent=false,waterlogged=false]",
"224": "minecraft:dark_oak_leaves[distance=4,persistent=true,waterlogged=false]",
"225": "minecraft:dark_oak_leaves[distance=4,persistent=false,waterlogged=false]",
"226": "minecraft:dark_oak_leaves[distance=5,persistent=true,waterlogged=false]",
"227": "minecraft:dark_oak_leaves[distance=5,persistent=false,waterlogged=false]",
"228": "minecraft:dark_oak_leaves[distance=6,persistent=true,waterlogged=false]",
"229": "minecraft:dark_oak_leaves[distance=6,persistent=false,waterlogged=false]",
"230": "minecraft:dark_oak_leaves[distance=7,persistent=true,waterlogged=false]",
"231": "minecraft:dark_oak_leaves[distance=7,persistent=false,waterlogged=false]",
"232": "minecraft:azalea_leaves[distance=1,persistent=true,waterlogged=false]",
"233": "minecraft:azalea_leaves[distance=1,persistent=false,waterlogged=false]",
"234": "minecraft:azalea_leaves[distance=2,persistent=true,waterlogged=false]",
"235": "minecraft:azalea_leaves[distance=2,persistent=false,waterlogged=false]",
"236": "minecraft:azalea_leaves[distance=3,persistent=true,waterlogged=false]",
"237": "minecraft:azalea_leaves[distance=3,persistent=false,waterlogged=false]",
"238": "minecraft:azalea_leaves[distance=4,persistent=true,waterlogged=false]",
"239": "minecraft:azalea_leaves[distance=4,persistent=false,waterlogged=false]",
"240": "minecraft:azalea_leaves[distance=5,persistent=true,waterlogged=false]",
"241": "minecraft:azalea_leaves[distance=5,persistent=false,waterlogged=false]",
"242": "minecraft:azalea_leaves[distance=6,persistent=true,waterlogged=false]",
"243": "minecraft:azalea_leaves[distance=6,persistent=false,waterlogged=false]",
"244": "minecraft:azalea_leaves[distance=7,persistent=true,waterlogged=false]",
"245": "minecraft:azalea_leaves[distance=7,persistent=false,waterlogged=false]",
"246": "minecraft:flowering_azalea_leaves[distance=1,persistent=true,waterlogged=false]",
"247": "minecraft:flowering_azalea_leaves[distance=1,persistent=false,waterlogged=false]",
"248": "minecraft:flowering_azalea_leaves[distance=2,persistent=true,waterlogged=false]",
"249": "minecraft:flowering_azalea_leaves[distance=2,persistent=false,waterlogged=false]",
"250": "minecraft:flowering_azalea_leaves[distance=3,persistent=true,waterlogged=false]",
"251": "minecraft:flowering_azalea_leaves[distance=3,persistent=false,waterlogged=false]",
"252": "minecraft:flowering_azalea_leaves[distance=4,persistent=true,waterlogged=false]",
"253": "minecraft:flowering_azalea_leaves[distance=4,persistent=false,waterlogged=false]",
"254": "minecraft:flowering_azalea_leaves[distance=5,persistent=true,waterlogged=false]",
"255": "minecraft:flowering_azalea_leaves[distance=5,persistent=false,waterlogged=false]",
"256": "minecraft:flowering_azalea_leaves[distance=6,persistent=true,waterlogged=false]",
"257": "minecraft:flowering_azalea_leaves[distance=6,persistent=false,waterlogged=false]",
"258": "minecraft:flowering_azalea_leaves[distance=7,persistent=true,waterlogged=false]",
"259": "minecraft:flowering_azalea_leaves[distance=7,persistent=false,waterlogged=false]",
"1416": "minecraft:piston_head[type=normal,facing=north,short=true]",
"1417": "minecraft:piston_head[type=sticky,facing=north,short=true]",
"1418": "minecraft:piston_head[type=normal,facing=north,short=false]",
"1419": "minecraft:piston_head[type=sticky,facing=north,short=false]",
"1420": "minecraft:piston_head[type=normal,facing=east,short=true]",
"1421": "minecraft:piston_head[type=sticky,facing=east,short=true]",
"1422": "minecraft:piston_head[type=normal,facing=east,short=false]",
"1423": "minecraft:piston_head[type=sticky,facing=east,short=false]",
"1424": "minecraft:piston_head[type=normal,facing=south,short=true]",
"1425": "minecraft:piston_head[type=sticky,facing=south,short=true]",
"1426": "minecraft:piston_head[type=normal,facing=south,short=false]",
"1427": "minecraft:piston_head[type=sticky,facing=south,short=false]",
"1428": "minecraft:piston_head[type=normal,facing=west,short=true]",
"1429": "minecraft:piston_head[type=sticky,facing=west,short=true]",
"1430": "minecraft:piston_head[type=normal,facing=west,short=false]",
"1431": "minecraft:piston_head[type=sticky,facing=west,short=false]",
"1432": "minecraft:piston_head[type=normal,facing=up,short=true]",
"1433": "minecraft:piston_head[type=sticky,facing=up,short=true]",
"1434": "minecraft:piston_head[type=normal,facing=up,short=false]",
"1435": "minecraft:piston_head[type=sticky,facing=up,short=false]",
"1436": "minecraft:piston_head[type=normal,facing=down,short=true]",
"1437": "minecraft:piston_head[type=sticky,facing=down,short=true]",
"1438": "minecraft:piston_head[type=normal,facing=down,short=false]",
"1439": "minecraft:piston_head[type=sticky,facing=down,short=false]",
"1456": "minecraft:moving_piston[type=normal,facing=north]",
"1457": "minecraft:moving_piston[type=sticky,facing=north]",
"1458": "minecraft:moving_piston[type=normal,facing=east]",
"1459": "minecraft:moving_piston[type=sticky,facing=east]",
"1460": "minecraft:moving_piston[type=normal,facing=south]",
"1461": "minecraft:moving_piston[type=sticky,facing=south]",
"1462": "minecraft:moving_piston[type=normal,facing=west]",
"1463": "minecraft:moving_piston[type=sticky,facing=west]",
"1464": "minecraft:moving_piston[type=normal,facing=up]",
"1465": "minecraft:moving_piston[type=sticky,facing=up]",
"1466": "minecraft:moving_piston[type=normal,facing=down]",
"1467": "minecraft:moving_piston[type=sticky,facing=down]",
"2090": "minecraft:chest[type=single,facing=north,waterlogged=true]",
"2091": "minecraft:chest[type=single,facing=north,waterlogged=false]",
"2092": "minecraft:chest[type=left,facing=north,waterlogged=true]",
"2093": "minecraft:chest[type=left,facing=north,waterlogged=false]",
"2094": "minecraft:chest[type=right,facing=north,waterlogged=true]",
"2095": "minecraft:chest[type=right,facing=north,waterlogged=false]",
"2096": "minecraft:chest[type=single,facing=south,waterlogged=true]",
"2097": "minecraft:chest[type=single,facing=south,waterlogged=false]",
"2098": "minecraft:chest[type=left,facing=south,waterlogged=true]",
"2099": "minecraft:chest[type=left,facing=south,waterlogged=false]",
"2100": "minecraft:chest[type=right,facing=south,waterlogged=true]",
"2101": "minecraft:chest[type=right,facing=south,waterlogged=false]",
"2102": "minecraft:chest[type=single,facing=west,waterlogged=true]",
"2103": "minecraft:chest[type=single,facing=west,waterlogged=false]",
"2104": "minecraft:chest[type=left,facing=west,waterlogged=true]",
"2105": "minecraft:chest[type=left,facing=west,waterlogged=false]",
"2106": "minecraft:chest[type=right,facing=west,waterlogged=true]",
"2107": "minecraft:chest[type=right,facing=west,waterlogged=false]",
"2108": "minecraft:chest[type=single,facing=east,waterlogged=true]",
"2109": "minecraft:chest[type=single,facing=east,waterlogged=false]",
"2110": "minecraft:chest[type=left,facing=east,waterlogged=true]",
"2111": "minecraft:chest[type=left,facing=east,waterlogged=false]",
"2112": "minecraft:chest[type=right,facing=east,waterlogged=true]",
"2113": "minecraft:chest[type=right,facing=east,waterlogged=false]",
"6828": "minecraft:trapped_chest[type=single,facing=north,waterlogged=true]",
"6829": "minecraft:trapped_chest[type=single,facing=north,waterlogged=false]",
"6830": "minecraft:trapped_chest[type=left,facing=north,waterlogged=true]",
"6831": "minecraft:trapped_chest[type=left,facing=north,waterlogged=false]",
"6832": "minecraft:trapped_chest[type=right,facing=north,waterlogged=true]",
"6833": "minecraft:trapped_chest[type=right,facing=north,waterlogged=false]",
"6834": "minecraft:trapped_chest[type=single,facing=south,waterlogged=true]",
"6835": "minecraft:trapped_chest[type=single,facing=south,waterlogged=false]",
"6836": "minecraft:trapped_chest[type=left,facing=south,waterlogged=true]",
"6837": "minecraft:trapped_chest[type=left,facing=south,waterlogged=false]",
"6838": "minecraft:trapped_chest[type=right,facing=south,waterlogged=true]",
"6839": "minecraft:trapped_chest[type=right,facing=south,waterlogged=false]",
"6840": "minecraft:trapped_chest[type=single,facing=west,waterlogged=true]",
"6841": "minecraft:trapped_chest[type=single,facing=west,waterlogged=false]",
"6842": "minecraft:trapped_chest[type=left,facing=west,waterlogged=true]",
"6843": "minecraft:trapped_chest[type=left,facing=west,waterlogged=false]",
"6844": "minecraft:trapped_chest[type=right,facing=west,waterlogged=true]",
"6845": "minecraft:trapped_chest[type=right,facing=west,waterlogged=false]",
"6846": "minecraft:trapped_chest[type=single,facing=east,waterlogged=true]",
"6847": "minecraft:trapped_chest[type=single,facing=east,waterlogged=false]",
"6848": "minecraft:trapped_chest[type=left,facing=east,waterlogged=true]",
"6849": "minecraft:trapped_chest[type=left,facing=east,waterlogged=false]",
"6850": "minecraft:trapped_chest[type=right,facing=east,waterlogged=true]",
"6851": "minecraft:trapped_chest[type=right,facing=east,waterlogged=false]"
}
}
@@ -40,6 +40,7 @@ public class EntityTypesTest {
testArrayOrder(Entity1_16Types.values(), Entity1_16Types::getTypeFromId);
testArrayOrder(Entity1_16_2Types.values(), Entity1_16_2Types::getTypeFromId);
testArrayOrder(Entity1_17Types.values(), Entity1_17Types::getTypeFromId);
// Newer type enums are automatically filled using mappings
}
private void testArrayOrder(EntityType[] types, Function<Integer, EntityType> returnFunction) {
+1 -1
View File
@@ -1,5 +1,5 @@
# Project properties - we put these here so they can be modified without causing a recompile of the build scripts
projectVersion=4.2.0
projectVersion=4.3.1
# Gradle properties
org.gradle.daemon=true
+1 -1
View File
@@ -6,7 +6,7 @@ adventure = "4.9.3"
gson = "2.8.8"
fastutil = "8.5.6"
flare = "2.0.0"
openNBT = "2.0-SNAPSHOT"
openNBT = "2.0"
javassist = "3.28.0-GA"
# Common provided
Binary file not shown.
+1 -1
View File
@@ -1,5 +1,5 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.3.3-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-7.4.2-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
Vendored
+5 -5
View File
@@ -1,7 +1,7 @@
#!/bin/sh
#
# Copyright © 2015-2021 the original authors.
# Copyright © 2015-2021 the original authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -32,10 +32,10 @@
# Busybox and similar reduced shells will NOT work, because this script
# requires all of these POSIX shell features:
# * functions;
# * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,
# «${var#prefix}», «${var%suffix}», and «$( cmd )»;
# * compound commands having a testable exit status, especially «case»;
# * various built-in commands including «command», «set», and «ulimit».
# * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,
# «${var#prefix}», «${var%suffix}», and «$( cmd )»;
# * compound commands having a testable exit status, especially «case»;
# * various built-in commands including «command», «set», and «ulimit».
#
# Important for patching:
#
-1
View File
@@ -1,5 +1,4 @@
enableFeaturePreview("TYPESAFE_PROJECT_ACCESSORS")
enableFeaturePreview("VERSION_CATALOGS")
dependencyResolutionManagement {
// configures repositories for all projects