WIP 21w37a

This commit is contained in:
Nassim Jahnke 2021-09-14 17:38:52 +02:00
parent d67269c9fe
commit b4301adb3b
No known key found for this signature in database
GPG Key ID: 6BE3B555EBC5982B
23 changed files with 25071 additions and 204 deletions

View File

@ -0,0 +1,45 @@
/*
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
* Copyright (C) 2016-2021 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.blockentity;
import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
import org.checkerframework.checker.nullness.qual.Nullable;
public interface BlockEntity {
default byte relX() {
return -1; //TODO
}
default byte relZ() {
return -1; //TODO
}
byte packedXZ();
short y();
int typeId();
@Nullable CompoundTag tag();
}

View File

@ -0,0 +1,59 @@
/*
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
* Copyright (C) 2016-2021 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.blockentity;
import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
public final class BlockEntityImpl implements BlockEntity {
private final byte packedXZ;
private final short y;
private final int typeId;
private final CompoundTag tag;
public BlockEntityImpl(final byte packedXZ, final short y, final int typeId, final CompoundTag tag) {
this.packedXZ = packedXZ;
this.y = y;
this.typeId = typeId;
this.tag = tag;
}
@Override
public byte packedXZ() {
return packedXZ;
}
@Override
public short y() {
return y;
}
@Override
public int typeId() {
return typeId;
}
@Override
public CompoundTag tag() {
return tag;
}
}

View File

@ -23,6 +23,7 @@
package com.viaversion.viaversion.api.minecraft.chunks;
import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
import com.viaversion.viaversion.api.minecraft.blockentity.BlockEntity;
import org.checkerframework.checker.nullness.qual.Nullable;
import java.util.BitSet;
@ -147,4 +148,9 @@ public class BaseChunk implements Chunk {
public List<CompoundTag> getBlockEntities() {
return blockEntities;
}
@Override
public List<BlockEntity> blockEntities() {
throw new UnsupportedOperationException();
}
}

View File

@ -23,6 +23,7 @@
package com.viaversion.viaversion.api.minecraft.chunks;
import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
import com.viaversion.viaversion.api.minecraft.blockentity.BlockEntity;
import org.checkerframework.checker.nullness.qual.Nullable;
import java.util.BitSet;
@ -115,4 +116,11 @@ public interface Chunk {
* @return list of block entities
*/
List<CompoundTag> getBlockEntities();
/**
* Returns a list of block entities.
*
* @return list of block entities
*/
List<BlockEntity> blockEntities();
}

View File

@ -0,0 +1,136 @@
/*
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
* Copyright (C) 2016-2021 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.chunks;
import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
import com.viaversion.viaversion.api.minecraft.blockentity.BlockEntity;
import org.checkerframework.checker.nullness.qual.Nullable;
import java.util.BitSet;
import java.util.List;
public class Chunk1_18 implements Chunk {
protected final int x;
protected final int z;
protected ChunkSection[] sections;
protected CompoundTag heightMap;
protected final List<BlockEntity> blockEntities;
public Chunk1_18(int x, int z, ChunkSection[] sections, CompoundTag heightMap, List<BlockEntity> blockEntities) {
this.x = x;
this.z = z;
this.sections = sections;
this.heightMap = heightMap;
this.blockEntities = blockEntities;
}
@Override
public boolean isBiomeData() {
return false;
}
@Override
public int getX() {
return x;
}
@Override
public int getZ() {
return z;
}
@Override
public boolean isFullChunk() {
return true;
}
@Override
public boolean isIgnoreOldLightData() {
return false;
}
@Override
public void setIgnoreOldLightData(boolean ignoreOldLightData) {
throw new UnsupportedOperationException();
}
@Override
public int getBitmask() {
return -1;
}
@Override
public void setBitmask(int bitmask) {
throw new UnsupportedOperationException();
}
@Override
public @Nullable BitSet getChunkMask() {
return null;
}
@Override
public void setChunkMask(BitSet chunkSectionMask) {
throw new UnsupportedOperationException();
}
@Override
public ChunkSection[] getSections() {
return sections;
}
@Override
public void setSections(ChunkSection[] sections) {
this.sections = sections;
}
@Override
public int @Nullable [] getBiomeData() {
return null;
}
@Override
public void setBiomeData(int @Nullable [] biomeData) {
throw new UnsupportedOperationException();
}
@Override
public @Nullable CompoundTag getHeightMap() {
return heightMap;
}
@Override
public void setHeightMap(final CompoundTag heightMap) {
this.heightMap = heightMap;
}
@Override
public List<CompoundTag> getBlockEntities() {
throw new UnsupportedOperationException();
}
@Override
public List<BlockEntity> blockEntities() {
return blockEntities;
}
}

View File

@ -31,144 +31,89 @@ public interface ChunkSection {
*/
int SIZE = 16 * 16 * 16; // width * depth * height
/**
* Returns the block index of the given coordinates within a section.
*
* @param x section x
* @param y section y
* @param z section z
* @return section block index
*/
static int index(int x, int y, int z) {
return y << 8 | z << 4 | x;
}
/**
* Returns the block state of the given index.
*
* @param idx block index within the section
* @return block state of the given index
*/
int getFlatBlock(int idx);
@Deprecated/*(forRemoval = true)*/
default int getFlatBlock(int idx) {
return palette(PaletteType.BLOCKS).value(idx);
}
/**
* Returns the block state of the section coordinate.
*
* @param x section x
* @param y section y
* @param z section z
* @return block state of the given section coordinate
*/
@Deprecated/*(forRemoval = true)*/
default int getFlatBlock(int x, int y, int z) {
return getFlatBlock(index(x, y, z));
}
/**
* Set a block state in the chunk section.
* This method will not update non-air blocks count.
*
* @param idx block index within the section
* @param id raw or flat id of the block state
*/
void setFlatBlock(int idx, int id);
@Deprecated/*(forRemoval = true)*/
default void setFlatBlock(int idx, int id) {
palette(PaletteType.BLOCKS).setValue(idx, id);
}
/**
* Set a block state in the chunk section.
* This method will not update non-air blocks count.
*
* @param x section x
* @param y section y
* @param z section z
* @param id raw or flat id of the block state
*/
@Deprecated/*(forRemoval = true)*/
default void setFlatBlock(int x, int y, int z, int id) {
setFlatBlock(index(x, y, z), id);
}
@Deprecated/*(forRemoval = true)*/
default int getBlockWithoutData(int x, int y, int z) {
return getFlatBlock(x, y, z) >> 4;
}
@Deprecated/*(forRemoval = true)*/
default int getBlockData(int x, int y, int z) {
return getFlatBlock(x, y, z) & 0xF;
}
/**
* Set a block in the chunks.
* This method will not update non-air blocks count.
*
* @param x Block X
* @param y Block Y
* @param z Block Z
* @param type The type of the block
* @param data The data value of the block
*/
@Deprecated/*(forRemoval = true)*/
default void setBlockWithData(int x, int y, int z, int type, int data) {
setFlatBlock(index(x, y, z), type << 4 | (data & 0xF));
}
@Deprecated/*(forRemoval = true)*/
default void setBlockWithData(int idx, int type, int data) {
setFlatBlock(idx, type << 4 | (data & 0xF));
}
/**
* Sets a block to the given palette index.
*
* @param idx block index
* @param index palette index
*/
void setPaletteIndex(int idx, int index);
@Deprecated/*(forRemoval = true)*/
default void setPaletteIndex(int idx, int index) {
palette(PaletteType.BLOCKS).setIndex(idx, index);
}
/**
* Returns the palette index of the given block index.
*
* @param idx block index
* @return palette index of the given block index
*/
int getPaletteIndex(int idx);
@Deprecated/*(forRemoval = true)*/
default int getPaletteIndex(int idx) {
return palette(PaletteType.BLOCKS).index(idx);
}
/**
* Returns the size of the palette.
*
* @return palette size
*/
int getPaletteSize();
@Deprecated/*(forRemoval = true)*/
default int getPaletteSize() {
return palette(PaletteType.BLOCKS).size();
}
/**
* Returns the block state assigned to the given palette index.
*
* @param index palette index
* @return block state assigned to the given palette index
*/
int getPaletteEntry(int index);
@Deprecated/*(forRemoval = true)*/
default int getPaletteEntry(int index) {
return palette(PaletteType.BLOCKS).entry(index);
}
/**
* Assigns a block state assigned to the given palette index.
*
* @param index palette index
* @param id block state
*/
void setPaletteEntry(int index, int id);
@Deprecated/*(forRemoval = true)*/
default void setPaletteEntry(int index, int id) {
palette(PaletteType.BLOCKS).setEntry(index, id);
}
/**
* Replaces a block state in the palette.
*
* @param oldId old block state
* @param newId new block state
*/
void replacePaletteEntry(int oldId, int newId);
@Deprecated/*(forRemoval = true)*/
default void replacePaletteEntry(int oldId, int newId) {
palette(PaletteType.BLOCKS).replaceEntry(oldId, newId);
}
/**
* Adds a new block state to the palette.
*
* @param id block state
*/
void addPaletteEntry(int id);
@Deprecated/*(forRemoval = true)*/
default void addPaletteEntry(int id) {
palette(PaletteType.BLOCKS).addEntry(id);
}
/**
* Clears the palette.
*/
void clearPalette();
@Deprecated/*(forRemoval = true)*/
default void clearPalette() {
palette(PaletteType.BLOCKS).clear();
}
/**
* Returns the number of non-air blocks in this section.
@ -198,4 +143,16 @@ public interface ChunkSection {
@Nullable ChunkSectionLight getLight();
void setLight(@Nullable ChunkSectionLight light);
/**
* Returns the palette of the given type if present.
*
* @param type type of the palette
* @return palette
*/
@Nullable DataPalette palette(PaletteType type);
void addPalette(DataPalette blockPalette);
void removePalette(PaletteType type);
}

View File

@ -22,120 +22,31 @@
*/
package com.viaversion.viaversion.api.minecraft.chunks;
import it.unimi.dsi.fastutil.ints.Int2IntMap;
import it.unimi.dsi.fastutil.ints.Int2IntOpenHashMap;
import it.unimi.dsi.fastutil.ints.IntArrayList;
import it.unimi.dsi.fastutil.ints.IntList;
import org.checkerframework.checker.nullness.qual.Nullable;
import java.util.EnumMap;
public class ChunkSectionImpl implements ChunkSection {
private final IntList palette;
private final Int2IntMap inversePalette;
private final int[] blocks;
private final EnumMap<PaletteType, DataPalette> palettes = new EnumMap<>(PaletteType.class);
private ChunkSectionLight light;
private int nonAirBlocksCount;
public ChunkSectionImpl(boolean holdsLight) {
this.blocks = new int[SIZE];
palette = new IntArrayList();
inversePalette = new Int2IntOpenHashMap();
inversePalette.defaultReturnValue(-1);
public ChunkSectionImpl() {
}
public ChunkSectionImpl(final boolean holdsLight) {
addPalette(new DataPaletteImpl(PaletteType.BLOCKS));
if (holdsLight) {
this.light = new ChunkSectionLightImpl();
}
}
public ChunkSectionImpl(boolean holdsLight, int expectedPaletteLength) {
this.blocks = new int[SIZE];
public ChunkSectionImpl(final boolean holdsLight, final int expectedPaletteLength) {
addPalette(new DataPaletteImpl(PaletteType.BLOCKS, expectedPaletteLength));
if (holdsLight) {
this.light = new ChunkSectionLightImpl();
}
// Pre-size the palette array/map
palette = new IntArrayList(expectedPaletteLength);
inversePalette = new Int2IntOpenHashMap(expectedPaletteLength);
inversePalette.defaultReturnValue(-1);
}
@Override
public int getFlatBlock(int idx) {
int index = blocks[idx];
return palette.getInt(index);
}
@Override
public void setFlatBlock(int idx, int id) {
int index = inversePalette.get(id);
if (index == -1) {
index = palette.size();
palette.add(id);
inversePalette.put(id, index);
}
blocks[idx] = index;
}
@Override
public int getPaletteIndex(int idx) {
return blocks[idx];
}
@Override
public void setPaletteIndex(int idx, int index) {
blocks[idx] = index;
}
@Override
public int getPaletteSize() {
return palette.size();
}
@Override
public int getPaletteEntry(int index) {
return palette.getInt(index);
}
@Override
public void setPaletteEntry(int index, int id) {
int oldId = palette.set(index, id);
if (oldId == id) return;
inversePalette.put(id, index);
if (inversePalette.get(oldId) == index) {
inversePalette.remove(oldId);
for (int i = 0; i < palette.size(); i++) {
if (palette.getInt(i) == oldId) {
inversePalette.put(oldId, i);
break;
}
}
}
}
@Override
public void replacePaletteEntry(int oldId, int newId) {
int index = inversePalette.remove(oldId);
if (index == -1) return;
inversePalette.put(newId, index);
for (int i = 0; i < palette.size(); i++) {
if (palette.getInt(i) == oldId) {
palette.set(i, newId);
}
}
}
@Override
public void addPaletteEntry(int id) {
inversePalette.put(id, palette.size());
palette.add(id);
}
@Override
public void clearPalette() {
palette.clear();
inversePalette.clear();
}
@Override
@ -144,7 +55,7 @@ public class ChunkSectionImpl implements ChunkSection {
}
@Override
public void setNonAirBlocksCount(int nonAirBlocksCount) {
public void setNonAirBlocksCount(final int nonAirBlocksCount) {
this.nonAirBlocksCount = nonAirBlocksCount;
}
@ -154,7 +65,22 @@ public class ChunkSectionImpl implements ChunkSection {
}
@Override
public void setLight(@Nullable ChunkSectionLight light) {
public void setLight(@Nullable final ChunkSectionLight light) {
this.light = light;
}
@Override
public DataPalette palette(final PaletteType type) {
return palettes.get(type);
}
@Override
public void addPalette(final DataPalette palette) {
palettes.put(palette.type(), palette);
}
@Override
public void removePalette(final PaletteType type) {
palettes.remove(type);
}
}

View File

@ -0,0 +1,154 @@
/*
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
* Copyright (C) 2016-2021 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.chunks;
public interface DataPalette {
/**
* Returns the block state of the given index.
*
* @param idx block index within the section
* @return block state of the given index
*/
int value(int idx);
/**
* Returns the block state of the section coordinate.
*
* @param x section x
* @param y section y
* @param z section z
* @return block state of the given section coordinate
*/
default int value(final int x, final int y, final int z) {
return value(ChunkSection.index(x, y, z));
}
/**
* Set a block state in the chunk section.
* This method will not update non-air blocks count.
*
* @param idx block index within the section
* @param id raw or flat id of the block state
*/
void setValue(int idx, int id);
/**
* Set a block state in the chunk section.
* This method will not update non-air blocks count.
*
* @param x section x
* @param y section y
* @param z section z
* @param id raw or flat id of the block state
*/
default void setValue(final int x, final int y, final int z, final int id) {
setValue(ChunkSection.index(x, y, z), id);
}
// ----------------------------------------------------------------------------
default int rawDataBlock(final int x, final int y, final int z) {
return value(x, y, z) >> 4;
}
default int dataBlock(final int x, final int y, final int z) {
return value(x, y, z) & 0xF;
}
default void setDataBlock(final int x, final int y, final int z, final int type, final int data) {
setValue(ChunkSection.index(x, y, z), type << 4 | (data & 0xF));
}
default void setDataBlock(final int idx, final int type, final int data) {
setValue(idx, type << 4 | (data & 0xF));
}
// ----------------------------------------------------------------------------
/**
* Sets a block to the given palette index.
*
* @param idx block index
* @param index palette index
*/
void setIndex(int idx, int index);
/**
* Returns the palette index of the given block index.
*
* @param idx block index
* @return palette index of the given block index
*/
int index(int idx);
/**
* Returns the size of the palette.
*
* @return palette size
*/
int size();
/**
* Returns the block state assigned to the given palette index.
*
* @param index palette index
* @return block state assigned to the given palette index
*/
int entry(int index);
/**
* Assigns a block state assigned to the given palette index.
*
* @param index palette index
* @param id block state
*/
void setEntry(int index, int id);
/**
* Replaces a block state in the palette.
*
* @param oldId old block state
* @param newId new block state
*/
void replaceEntry(int oldId, int newId);
/**
* Adds a new block state to the palette.
*
* @param id block state
*/
void addEntry(int id);
/**
* Clears the palette.
*/
void clear();
/**
* Returns the type of data this palette holds.
*
* @return type of data this palette holds
*/
PaletteType type();
}

View File

@ -0,0 +1,138 @@
/*
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
* Copyright (C) 2016-2021 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.chunks;
import it.unimi.dsi.fastutil.ints.Int2IntMap;
import it.unimi.dsi.fastutil.ints.Int2IntOpenHashMap;
import it.unimi.dsi.fastutil.ints.IntArrayList;
import it.unimi.dsi.fastutil.ints.IntList;
public final class DataPaletteImpl implements DataPalette {
private final IntList palette;
private final Int2IntMap inversePalette;
private final int[] values;
private final PaletteType type;
public DataPaletteImpl(final PaletteType type) {
this.type = type;
this.values = new int[ChunkSection.SIZE];
palette = new IntArrayList();
inversePalette = new Int2IntOpenHashMap();
inversePalette.defaultReturnValue(-1);
}
public DataPaletteImpl(final PaletteType type, final int expectedPaletteLength) {
this.type = type;
this.values = new int[ChunkSection.SIZE];
// Pre-size the palette array/map
palette = new IntArrayList(expectedPaletteLength);
inversePalette = new Int2IntOpenHashMap(expectedPaletteLength);
inversePalette.defaultReturnValue(-1);
}
@Override
public int value(final int idx) {
final int index = values[idx];
return palette.getInt(index);
}
@Override
public void setValue(final int idx, final int id) {
int index = inversePalette.get(id);
if (index == -1) {
index = palette.size();
palette.add(id);
inversePalette.put(id, index);
}
values[idx] = index;
}
@Override
public int index(final int idx) {
return values[idx];
}
@Override
public void setIndex(final int idx, final int index) {
values[idx] = index;
}
@Override
public int size() {
return palette.size();
}
@Override
public int entry(final int index) {
return palette.getInt(index);
}
@Override
public void setEntry(final int index, final int id) {
final int oldId = palette.set(index, id);
if (oldId == id) return;
inversePalette.put(id, index);
if (inversePalette.get(oldId) == index) {
inversePalette.remove(oldId);
for (int i = 0; i < palette.size(); i++) {
if (palette.getInt(i) == oldId) {
inversePalette.put(oldId, i);
break;
}
}
}
}
@Override
public void replaceEntry(final int oldId, final int newId) {
final int index = inversePalette.remove(oldId);
if (index == -1) return;
inversePalette.put(newId, index);
for (int i = 0; i < palette.size(); i++) {
if (palette.getInt(i) == oldId) {
palette.set(i, newId);
}
}
}
@Override
public void addEntry(final int id) {
inversePalette.put(id, palette.size());
palette.add(id);
}
@Override
public void clear() {
palette.clear();
inversePalette.clear();
}
@Override
public PaletteType type() {
return type;
}
}

View File

@ -0,0 +1,38 @@
/*
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
* Copyright (C) 2016-2021 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.chunks;
public enum PaletteType {
BLOCKS(8),
BIOMES(2);
private final int highestBitsPerValue;
PaletteType(final int highestBitsPerValue) {
this.highestBitsPerValue = highestBitsPerValue;
}
public int highestBitsPerValue() {
return highestBitsPerValue;
}
}

View File

@ -78,6 +78,7 @@ public class ProtocolVersion {
public static final ProtocolVersion v1_16_4 = register(754, "1.16.4/5", new VersionRange("1.16", 4, 5));
public static final ProtocolVersion v1_17 = register(755, "1.17");
public static final ProtocolVersion v1_17_1 = register(756, "1.17.1");
public static final ProtocolVersion v1_18 = register(757, 48, "1.18");
public static final ProtocolVersion unknown = register(-1, "UNKNOWN");
public static ProtocolVersion register(int version, String name) {

View File

@ -31,17 +31,26 @@ public class ByteType extends Type<Byte> implements TypeConverter<Byte> {
super(Byte.class);
}
public byte readPrimitive(ByteBuf buffer) {
return buffer.readByte();
}
public void writePrimitive(ByteBuf buffer, byte object) {
buffer.writeByte(object);
}
@Override
@Deprecated
public Byte read(ByteBuf buffer) {
return buffer.readByte();
}
@Override
@Deprecated
public void write(ByteBuf buffer, Byte object) {
buffer.writeByte(object);
}
@Override
public Byte from(Object o) {
if (o instanceof Number) {

View File

@ -0,0 +1,53 @@
/*
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
* Copyright (C) 2016-2021 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.github.steveice10.opennbt.tag.builtin.CompoundTag;
import com.viaversion.viaversion.api.minecraft.blockentity.BlockEntity;
import com.viaversion.viaversion.api.minecraft.blockentity.BlockEntityImpl;
import com.viaversion.viaversion.api.type.Type;
import io.netty.buffer.ByteBuf;
public class BlockEntityType1_18 extends Type<BlockEntity> {
public BlockEntityType1_18() {
super(BlockEntity.class);
}
@Override
public BlockEntity read(final ByteBuf buffer) throws Exception {
final byte xz = buffer.readByte();
final short y = buffer.readShort();
final int typeId = Type.VAR_INT.readPrimitive(buffer);
final CompoundTag tag = Type.NBT.read(buffer);
return new BlockEntityImpl(xz, y, typeId, tag);
}
@Override
public void write(final ByteBuf buffer, final BlockEntity entity) throws Exception {
buffer.writeByte(entity.packedXZ());
buffer.writeShort(entity.y());
Type.VAR_INT.writePrimitive(buffer, entity.typeId());
Type.NBT.write(buffer, entity.tag());
}
}

View File

@ -0,0 +1,136 @@
/*
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
* Copyright (C) 2016-2021 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.chunks.ChunkSection;
import com.viaversion.viaversion.api.minecraft.chunks.ChunkSectionImpl;
import com.viaversion.viaversion.api.minecraft.chunks.DataPalette;
import com.viaversion.viaversion.api.minecraft.chunks.DataPaletteImpl;
import com.viaversion.viaversion.api.minecraft.chunks.PaletteType;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.util.CompactArrayUtil;
import io.netty.buffer.ByteBuf;
public class ChunkSectionType1_18 extends Type<ChunkSection> {
private static final int GLOBAL_PALETTE = 15;
public ChunkSectionType1_18() {
super("Chunk Section Type", ChunkSection.class);
}
@Override
public ChunkSection read(final ByteBuf buffer) throws Exception {
final ChunkSection chunkSection = new ChunkSectionImpl();
chunkSection.setNonAirBlocksCount(buffer.readShort());
chunkSection.addPalette(readPalette(buffer, PaletteType.BLOCKS));
chunkSection.addPalette(readPalette(buffer, PaletteType.BIOMES));
return chunkSection;
}
@Override
public void write(final ByteBuf buffer, final ChunkSection section) throws Exception {
buffer.writeShort(section.getNonAirBlocksCount());
writePalette(buffer, section.palette(PaletteType.BLOCKS));
writePalette(buffer, section.palette(PaletteType.BIOMES));
}
private DataPalette readPalette(final ByteBuf buffer, final PaletteType type) {
int bitsPerValue = buffer.readByte();
final int originalBitsPerValue = bitsPerValue;
if (bitsPerValue > type.highestBitsPerValue()) {
bitsPerValue = GLOBAL_PALETTE;
}
// Read palette
final DataPaletteImpl palette;
if (bitsPerValue == 0) {
//TODO Create proper singleton palette Object
palette = new DataPaletteImpl(type, 1);
palette.addEntry(Type.VAR_INT.readPrimitive(buffer));
Type.VAR_INT.readPrimitive(buffer); // 0 values length
return palette;
}
if (bitsPerValue != GLOBAL_PALETTE) {
final int paletteLength = Type.VAR_INT.readPrimitive(buffer);
palette = new DataPaletteImpl(type, paletteLength);
for (int i = 0; i < paletteLength; i++) {
palette.addEntry(Type.VAR_INT.readPrimitive(buffer));
}
} else {
palette = new DataPaletteImpl(type);
}
// Read values
final long[] values = new long[Type.VAR_INT.readPrimitive(buffer)];
if (values.length > 0) {
final char valuesPerLong = (char) (64 / bitsPerValue);
final int expectedLength = (ChunkSection.SIZE + valuesPerLong - 1) / valuesPerLong;
if (values.length != expectedLength) {
throw new IllegalStateException("Palette data length (" + values.length + ") does not match expected length (" + expectedLength + ")! bitsPerValue=" + bitsPerValue + ", originalBitsPerValue=" + originalBitsPerValue);
}
for (int i = 0; i < values.length; i++) {
values[i] = buffer.readLong();
}
CompactArrayUtil.iterateCompactArrayWithPadding(bitsPerValue, ChunkSection.SIZE, values,
bitsPerValue == GLOBAL_PALETTE ? palette::setValue : palette::setIndex);
}
return palette;
}
private void writePalette(final ByteBuf buffer, final DataPalette palette) {
int bitsPerValue = 0;
while (palette.size() > 1 << bitsPerValue) {
bitsPerValue += 1;
}
if (bitsPerValue > palette.type().highestBitsPerValue()) {
bitsPerValue = GLOBAL_PALETTE;
}
buffer.writeByte(bitsPerValue);
if (bitsPerValue == 0) {
// Write single value
Type.VAR_INT.writePrimitive(buffer, palette.entry(0)); //TODO right?
Type.VAR_INT.writePrimitive(buffer, 0); // Empty values length
return;
}
if (bitsPerValue != GLOBAL_PALETTE) {
// Write pallete
Type.VAR_INT.writePrimitive(buffer, palette.size());
for (int i = 0; i < palette.size(); i++) {
Type.VAR_INT.writePrimitive(buffer, palette.entry(i));
}
}
final long[] data = CompactArrayUtil.createCompactArrayWithPadding(bitsPerValue, ChunkSection.SIZE, bitsPerValue == GLOBAL_PALETTE ? palette::value : palette::index);
Type.VAR_INT.writePrimitive(buffer, data.length);
for (final long l : data) {
buffer.writeLong(l);
}
}
}

View File

@ -0,0 +1,33 @@
/*
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
* Copyright (C) 2016-2021 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.blockentity.BlockEntity;
import com.viaversion.viaversion.api.minecraft.chunks.ChunkSection;
import com.viaversion.viaversion.api.type.Type;
public final class Types1_18 {
public static final Type<ChunkSection> CHUNK_SECTION = new ChunkSectionType1_18();
public static final Type<BlockEntity> BLOCK_ENTITY = new BlockEntityType1_18();
}

View File

@ -64,6 +64,7 @@ import com.viaversion.viaversion.protocols.protocol1_16_4to1_16_3.Protocol1_16_4
import com.viaversion.viaversion.protocols.protocol1_16to1_15_2.Protocol1_16To1_15_2;
import com.viaversion.viaversion.protocols.protocol1_17_1to1_17.Protocol1_17_1To1_17;
import com.viaversion.viaversion.protocols.protocol1_17to1_16_4.Protocol1_17To1_16_4;
import com.viaversion.viaversion.protocols.protocol1_18to1_17_1.Protocol1_18To1_17_1;
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;
@ -167,6 +168,7 @@ public class ProtocolManagerImpl implements ProtocolManager {
registerProtocol(new Protocol1_17To1_16_4(), ProtocolVersion.v1_17, ProtocolVersion.v1_16_4);
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);
}
@Override

View File

@ -0,0 +1,78 @@
/*
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
* Copyright (C) 2016-2021 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_18to1_17_1;
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_17Types;
import com.viaversion.viaversion.api.protocol.AbstractProtocol;
import com.viaversion.viaversion.api.protocol.remapper.PacketRemapper;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.data.entity.EntityTrackerBase;
import com.viaversion.viaversion.protocols.protocol1_17_1to1_17.ClientboundPackets1_17_1;
import com.viaversion.viaversion.protocols.protocol1_17to1_16_4.ServerboundPackets1_17;
import com.viaversion.viaversion.protocols.protocol1_18to1_17_1.packets.EntityPackets;
import com.viaversion.viaversion.protocols.protocol1_18to1_17_1.packets.WorldPackets;
import com.viaversion.viaversion.protocols.protocol1_18to1_17_1.storage.ChunkLightStorage;
import com.viaversion.viaversion.rewriter.EntityRewriter;
import com.viaversion.viaversion.rewriter.SoundRewriter;
public final class Protocol1_18To1_17_1 extends AbstractProtocol<ClientboundPackets1_17_1, ClientboundPackets1_17_1, ServerboundPackets1_17, ServerboundPackets1_17> {
public static final MappingData MAPPINGS = new MappingDataBase("1.17", "1.18");
private final EntityRewriter<Protocol1_18To1_17_1> entityRewriter = new EntityPackets(this);
public Protocol1_18To1_17_1() {
super(ClientboundPackets1_17_1.class, ClientboundPackets1_17_1.class, ServerboundPackets1_17.class, ServerboundPackets1_17.class);
final SoundRewriter soundRewriter = new SoundRewriter(this);
soundRewriter.registerSound(ClientboundPackets1_17_1.SOUND);
soundRewriter.registerSound(ClientboundPackets1_17_1.NAMED_SOUND);
registerClientbound(ClientboundPackets1_17_1.BLOCK_ENTITY_DATA, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.POSITION1_14);
map(Type.UNSIGNED_BYTE, Type.VAR_INT);
}
});
}
@Override
protected void registerPackets() {
entityRewriter.register();
WorldPackets.register(this);
}
@Override
public MappingData getMappingData() {
return MAPPINGS;
}
@Override
public void init(final UserConnection connection) {
addEntityTracker(connection, new EntityTrackerBase(connection, Entity1_17Types.PLAYER)); //TODO Entity1_18Types
connection.put(new ChunkLightStorage());
}
@Override
public EntityRewriter<Protocol1_18To1_17_1> getEntityRewriter() {
return entityRewriter;
}
}

View File

@ -0,0 +1,93 @@
/*
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
* Copyright (C) 2016-2021 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_18to1_17_1.packets;
import com.viaversion.viaversion.api.data.entity.EntityTracker;
import com.viaversion.viaversion.api.minecraft.entities.Entity1_17Types;
import com.viaversion.viaversion.api.minecraft.entities.EntityType;
import com.viaversion.viaversion.api.protocol.remapper.PacketRemapper;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.protocols.protocol1_17_1to1_17.ClientboundPackets1_17_1;
import com.viaversion.viaversion.protocols.protocol1_18to1_17_1.Protocol1_18To1_17_1;
import com.viaversion.viaversion.protocols.protocol1_18to1_17_1.storage.ChunkLightStorage;
import com.viaversion.viaversion.rewriter.EntityRewriter;
public final class EntityPackets extends EntityRewriter<Protocol1_18To1_17_1> {
public EntityPackets(final Protocol1_18To1_17_1 protocol) {
super(protocol);
//mapTypes(Entity1_17Types.values(), Entity1_18Types.class);
}
@Override
public void registerPackets() {
/*registerTrackerWithData(ClientboundPackets1_17_1.SPAWN_ENTITY, Entity1_18Types.FALLING_BLOCK);
registerTracker(ClientboundPackets1_17_1.SPAWN_MOB);
registerTracker(ClientboundPackets1_17_1.SPAWN_PLAYER, Entity1_18Types.PLAYER);
registerMetadataRewriter(ClientboundPackets1_17_1.ENTITY_METADATA, Types1_17.METADATA_LIST);
registerRemoveEntities(ClientboundPackets1_17_1.REMOVE_ENTITIES);*/
protocol.registerClientbound(ClientboundPackets1_17_1.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 data
map(Type.STRING); // World
handler(worldDataTrackerHandler(1));
}
});
protocol.registerClientbound(ClientboundPackets1_17_1.RESPAWN, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.NBT); // Current dimension data
map(Type.STRING); // World
handler(wrapper -> {
final String world = wrapper.get(Type.STRING, 0);
final EntityTracker tracker = tracker(wrapper.user());
if (!world.equals(tracker.currentWorld())) {
wrapper.user().get(ChunkLightStorage.class).clear();
}
});
handler(worldDataTrackerHandler(0));
}
});
}
@Override
protected void registerRewrites() {
//registerMetaTypeHandler(MetaType1_17.ITEM, MetaType1_17.BLOCK_STATE, MetaType1_17.PARTICLE); //TODO with nulls if needed
/*filter().filterFamily(Entity1_17Types.MINECART_ABSTRACT).index(11).handler((event, meta) -> { //TODO check id
// Convert to new block id
int data = (int) meta.getValue();
meta.setValue(protocol.getMappingData().getNewBlockStateId(data));
});*/
}
@Override
public EntityType typeFromId(final int type) {
//TODO Entity1_18Types
return Entity1_17Types.getTypeFromId(type);
}
}

View File

@ -0,0 +1,146 @@
/*
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
* Copyright (C) 2016-2021 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_18to1_17_1.packets;
import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
import com.github.steveice10.opennbt.tag.builtin.NumberTag;
import com.viaversion.viaversion.api.Via;
import com.viaversion.viaversion.api.data.entity.EntityTracker;
import com.viaversion.viaversion.api.minecraft.blockentity.BlockEntity;
import com.viaversion.viaversion.api.minecraft.blockentity.BlockEntityImpl;
import com.viaversion.viaversion.api.minecraft.chunks.Chunk;
import com.viaversion.viaversion.api.minecraft.chunks.Chunk1_18;
import com.viaversion.viaversion.api.protocol.remapper.PacketRemapper;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.protocols.protocol1_17_1to1_17.ClientboundPackets1_17_1;
import com.viaversion.viaversion.protocols.protocol1_17to1_16_4.types.Chunk1_17Type;
import com.viaversion.viaversion.protocols.protocol1_18to1_17_1.Protocol1_18To1_17_1;
import com.viaversion.viaversion.protocols.protocol1_18to1_17_1.storage.ChunkLightStorage;
import com.viaversion.viaversion.protocols.protocol1_18to1_17_1.types.Chunk1_18Type;
import java.util.ArrayList;
import java.util.List;
public final class WorldPackets {
public static void register(final Protocol1_18To1_17_1 protocol) {
protocol.registerClientbound(ClientboundPackets1_17_1.UPDATE_LIGHT, new PacketRemapper() {
@Override
public void registerMap() {
handler(wrapper -> {
final int chunkX = wrapper.read(Type.VAR_INT);
final int chunkZ = wrapper.read(Type.VAR_INT);
if (wrapper.user().get(ChunkLightStorage.class).isLoaded(chunkX, chunkZ)) {
// Light packets updating already sent chunks are the same as before
return;
}
wrapper.cancel();
final boolean trustEdges = wrapper.read(Type.BOOLEAN);
final long[] skyLightMask = wrapper.read(Type.LONG_ARRAY_PRIMITIVE);
final long[] blockLightMask = wrapper.read(Type.LONG_ARRAY_PRIMITIVE);
final long[] emptySkyLightMask = wrapper.read(Type.LONG_ARRAY_PRIMITIVE);
final long[] emptyBlockLightMask = wrapper.read(Type.LONG_ARRAY_PRIMITIVE);
final int skyLightLenght = wrapper.read(Type.VAR_INT);
final byte[][] skyLight = new byte[skyLightLenght][];
for (int i = 0; i < skyLightLenght; i++) {
skyLight[i] = wrapper.read(Type.BYTE_ARRAY_PRIMITIVE);
}
final int blockLightLength = wrapper.read(Type.VAR_INT);
final byte[][] blockLight = new byte[blockLightLength][];
for (int i = 0; i < blockLightLength; i++) {
blockLight[i] = wrapper.read(Type.BYTE_ARRAY_PRIMITIVE);
}
final ChunkLightStorage lightStorage = wrapper.user().get(ChunkLightStorage.class);
lightStorage.storeLight(chunkX, chunkZ,
new ChunkLightStorage.ChunkLight(trustEdges, skyLightMask, blockLightMask,
emptySkyLightMask, emptyBlockLightMask, skyLight, blockLight));
});
}
});
protocol.registerClientbound(ClientboundPackets1_17_1.CHUNK_DATA, new PacketRemapper() {
@Override
public void registerMap() {
handler(wrapper -> {
final EntityTracker tracker = protocol.getEntityRewriter().tracker(wrapper.user());
Chunk chunk = wrapper.read(new Chunk1_17Type(tracker.currentWorldSectionHeight()));
/*for (int s = 0; s < chunk.getSections().length; s++) {
ChunkSection section = chunk.getSections()[s];
if (section == null) continue;
for (int i = 0; i < section.getPaletteSize(); i++) {
int old = section.getPaletteEntry(i);
section.setPaletteEntry(i, protocol.getMappingData().getNewBlockStateId(old));
}
}*/
final List<BlockEntity> blockEntities = new ArrayList<>(chunk.getBlockEntities().size());
for (final CompoundTag tag : chunk.getBlockEntities()) {
final int x = ((NumberTag) tag.get("x")).asInt();
final int z = ((NumberTag) tag.get("z")).asInt();
final short y = ((NumberTag) tag.get("y")).asShort();
final int typeId; //TODO :smolBoi:
blockEntities.add(new BlockEntityImpl((x & 15) << 4 | (z & 15), y, typeId, tag));
}
chunk = new Chunk1_18(chunk.getX(), chunk.getZ(), chunk.getSections(), chunk.getHeightMap(), blockEntities);
wrapper.write(new Chunk1_18Type(tracker.currentWorldSectionHeight()), chunk);
// Get and remove light stored, there's only full chunk packets //TODO Only get, not remove if we find out people re-send full chunk packets without re-sending light
final ChunkLightStorage lightStorage = wrapper.user().get(ChunkLightStorage.class);
final ChunkLightStorage.ChunkLight light = lightStorage.removeLight(chunk.getX(), chunk.getZ());
if (light == null) {
Via.getPlatform().getLogger().warning("No light data found for chunk at " + chunk.getX() + ", " + chunk.getZ());
wrapper.cancel();
return;
}
// Append light data to chunk packet
wrapper.write(Type.BOOLEAN, light.trustEdges());
wrapper.write(Type.LONG_ARRAY_PRIMITIVE, light.skyLightMask());
wrapper.write(Type.LONG_ARRAY_PRIMITIVE, light.blockLightMask());
wrapper.write(Type.LONG_ARRAY_PRIMITIVE, light.emptySkyLightMask());
wrapper.write(Type.LONG_ARRAY_PRIMITIVE, light.emptyBlockLightMask());
wrapper.write(Type.VAR_INT, light.skyLight().length);
for (final byte[] skyLight : light.skyLight()) {
wrapper.write(Type.BYTE_ARRAY_PRIMITIVE, skyLight);
}
wrapper.write(Type.VAR_INT, light.blockLight().length);
for (final byte[] blockLight : light.blockLight()) {
wrapper.write(Type.BYTE_ARRAY_PRIMITIVE, blockLight);
}
});
}
});
protocol.registerClientbound(ClientboundPackets1_17_1.UNLOAD_CHUNK, new PacketRemapper() {
@Override
public void registerMap() {
handler(wrapper -> {
final int chunkX = wrapper.passthrough(Type.INT);
final int chunkZ = wrapper.passthrough(Type.INT);
wrapper.user().get(ChunkLightStorage.class).clear(chunkX, chunkZ);
});
}
});
}
}

View File

@ -0,0 +1,112 @@
/*
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
* Copyright (C) 2016-2021 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_18to1_17_1.storage;
import com.viaversion.viaversion.api.connection.StorableObject;
import org.checkerframework.checker.nullness.qual.Nullable;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
public final class ChunkLightStorage implements StorableObject {
private final Map<Long, ChunkLight> lightPackets = new HashMap<>();
private final Set<Long> loadedChunks = new HashSet<>();
public void storeLight(final int x, final int z, final ChunkLight chunkLight) {
lightPackets.put(getChunkSectionIndex(x, z), chunkLight);
}
public @Nullable ChunkLight removeLight(final int x, final int z) {
return lightPackets.get(getChunkSectionIndex(x, z));
}
public void addLoadedChunk(final int x, final int z) {
loadedChunks.add(getChunkSectionIndex(x, z));
}
public boolean isLoaded(final int x, final int z) {
return loadedChunks.contains(getChunkSectionIndex(x, z));
}
public void clear(final int x, final int z) {
final long index = getChunkSectionIndex(x, z);
lightPackets.remove(index);
loadedChunks.remove(index);
}
public void clear() {
loadedChunks.clear();
lightPackets.clear();
}
private long getChunkSectionIndex(final int x, final int z) {
return ((x & 0x3FFFFFFL) << 38) | (z & 0x3FFFFFFL);
}
public static final class ChunkLight {
private final boolean trustEdges;
private final long[] skyLightMask;
private final long[] blockLightMask;
private final long[] emptySkyLightMask;
private final long[] emptyBlockLightMask;
private final byte[][] skyLight;
private final byte[][] blockLight;
public ChunkLight(final boolean trustEdges, final long[] skyLightMask, final long[] blockLightMask,
final long[] emptySkyLightMask, final long[] emptyBlockLightMask, final byte[][] skyLight, final byte[][] blockLight) {
this.trustEdges = trustEdges;
this.skyLightMask = skyLightMask;
this.emptySkyLightMask = emptySkyLightMask;
this.blockLightMask = blockLightMask;
this.emptyBlockLightMask = emptyBlockLightMask;
this.skyLight = skyLight;
this.blockLight = blockLight;
}
public boolean trustEdges() {
return trustEdges;
}
public long[] skyLightMask() {
return skyLightMask;
}
public long[] emptySkyLightMask() {
return emptySkyLightMask;
}
public long[] blockLightMask() {
return blockLightMask;
}
public long[] emptyBlockLightMask() {
return emptyBlockLightMask;
}
public byte[][] skyLight() {
return skyLight;
}
public byte[][] blockLight() {
return blockLight;
}
}
}

View File

@ -0,0 +1,103 @@
/*
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
* Copyright (C) 2016-2021 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_18to1_17_1.types;
import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
import com.google.common.base.Preconditions;
import com.viaversion.viaversion.api.Via;
import com.viaversion.viaversion.api.minecraft.blockentity.BlockEntity;
import com.viaversion.viaversion.api.minecraft.chunks.Chunk;
import com.viaversion.viaversion.api.minecraft.chunks.Chunk1_18;
import com.viaversion.viaversion.api.minecraft.chunks.ChunkSection;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.api.type.types.minecraft.BaseChunkType;
import com.viaversion.viaversion.api.type.types.version.Types1_18;
import io.netty.buffer.ByteBuf;
import java.util.ArrayList;
import java.util.List;
public final class Chunk1_18Type extends Type<Chunk> {
private final int ySectionCount;
public Chunk1_18Type(final int ySectionCount) {
super(Chunk.class);
Preconditions.checkArgument(ySectionCount > 0);
this.ySectionCount = ySectionCount;
}
@Override
public Chunk read(final ByteBuf input) throws Exception {
final int chunkX = input.readInt();
final int chunkZ = input.readInt();
final CompoundTag heightMap = Type.NBT.read(input);
Type.VAR_INT.readPrimitive(input); // Data size in bytes
// Read sections
final ChunkSection[] sections = new ChunkSection[ySectionCount];
for (int i = 0; i < ySectionCount; i++) {
sections[i] = Types1_18.CHUNK_SECTION.read(input);
}
final int blockEntitiesLength = Type.VAR_INT.readPrimitive(input);
final List<BlockEntity> blockEntities = new ArrayList<>(blockEntitiesLength);
for (int i = 0; i < blockEntitiesLength; i++) {
blockEntities.add(Types1_18.BLOCK_ENTITY.read(input));
}
// Read all the remaining bytes (workaround for #681)
if (input.readableBytes() > 0) {
final byte[] array = Type.REMAINING_BYTES.read(input);
if (Via.getManager().isDebug()) {
Via.getPlatform().getLogger().warning("Found " + array.length + " more bytes than expected while reading the chunk: " + chunkX + "/" + chunkZ);
}
}
return new Chunk1_18(chunkX, chunkZ, sections, heightMap, blockEntities);
}
@Override
public void write(final ByteBuf output, final Chunk chunk) throws Exception {
output.writeInt(chunk.getX());
output.writeInt(chunk.getZ());
Type.NBT.write(output, chunk.getHeightMap());
final ByteBuf buf = output.alloc().buffer();
try {
for (final ChunkSection section : chunk.getSections()) {
Types1_18.CHUNK_SECTION.write(buf, section);
}
buf.readerIndex(0);
Type.VAR_INT.writePrimitive(output, buf.readableBytes());
output.writeBytes(buf);
} finally {
buf.release(); // release buffer
}
for (final BlockEntity blockEntity : chunk.blockEntities()) {
Types1_18.BLOCK_ENTITY.write(output, blockEntity);
}
}
@Override
public Class<? extends Type> getBaseClass() {
return BaseChunkType.class;
}
}

File diff suppressed because it is too large Load Diff

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.0.2-SNAPSHOT
projectVersion=4.1.0-21w37a-SNAPSHOT
# Gradle properties
org.gradle.daemon=true