geforkt von Mirrors/AxiomPaperPlugin
Dieser Commit ist enthalten in:
Ursprung
6f5617ded3
Commit
162bfc8fe2
@ -6,10 +6,11 @@ import io.netty.buffer.ByteBuf;
|
|||||||
import io.netty.buffer.Unpooled;
|
import io.netty.buffer.Unpooled;
|
||||||
import net.minecraft.core.BlockPos;
|
import net.minecraft.core.BlockPos;
|
||||||
import net.minecraft.network.FriendlyByteBuf;
|
import net.minecraft.network.FriendlyByteBuf;
|
||||||
import net.minecraft.server.level.ServerChunkCache;
|
import net.minecraft.network.protocol.Packet;
|
||||||
import net.minecraft.server.level.ServerLevel;
|
import net.minecraft.server.level.*;
|
||||||
import net.minecraft.server.level.ServerPlayer;
|
|
||||||
import net.minecraft.server.network.ServerGamePacketListenerImpl;
|
import net.minecraft.server.network.ServerGamePacketListenerImpl;
|
||||||
|
import net.minecraft.server.network.ServerPlayerConnection;
|
||||||
|
import net.minecraft.world.level.ChunkPos;
|
||||||
import net.minecraft.world.level.Level;
|
import net.minecraft.world.level.Level;
|
||||||
import net.minecraft.world.level.chunk.LevelChunk;
|
import net.minecraft.world.level.chunk.LevelChunk;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
@ -19,6 +20,7 @@ import org.bukkit.event.Listener;
|
|||||||
import org.bukkit.plugin.Plugin;
|
import org.bukkit.plugin.Plugin;
|
||||||
import org.bukkit.plugin.java.JavaPlugin;
|
import org.bukkit.plugin.java.JavaPlugin;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
@ -66,6 +68,23 @@ public class AxiomPaper extends JavaPlugin implements Listener {
|
|||||||
return getChunkSource.invoke(level);
|
return getChunkSource.invoke(level);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static final Reflection.Method<ServerChunkCache, ThreadedLevelLightEngine> getLightEngine = Reflection.getTypedMethod(ServerChunkCache.class, ThreadedLevelLightEngine.class);
|
||||||
|
public static ThreadedLevelLightEngine getLightEngine(ServerChunkCache chunkSource) {
|
||||||
|
return getLightEngine.invoke(chunkSource);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final Reflection.Method<ServerPlayerConnection, Void> send = Reflection.getMethod(ServerPlayerConnection.class, Packet.class);
|
||||||
|
public static void sendPacket(ServerPlayer player, Packet<?> packet) {
|
||||||
|
send.invoke(AxiomPaper.getConnection(player), packet);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final Reflection.Field<ServerChunkCache, ChunkMap> chunkMap = Reflection.getField(ServerChunkCache.class, ChunkMap.class);
|
||||||
|
private static final Reflection.Method<ChunkMap, List> getPlayers = Reflection.getTypedMethod(ChunkMap.class, List.class, ChunkPos.class, boolean.class);
|
||||||
|
public static List<ServerPlayer> getPlayersSeeingChunk(ServerLevel level, ChunkPos pos) {
|
||||||
|
ChunkMap map = chunkMap.get(AxiomPaper.getChunkSource(level));
|
||||||
|
return (List<ServerPlayer>)getPlayers.invoke(map, pos, false);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onEnable() {
|
public void onEnable() {
|
||||||
instance = this;
|
instance = this;
|
||||||
|
@ -127,6 +127,12 @@ public class Reflection {
|
|||||||
|
|
||||||
|
|
||||||
private static final String ORG_BUKKIT_CRAFTBUKKIT = Bukkit.getServer().getClass().getPackage().getName();
|
private static final String ORG_BUKKIT_CRAFTBUKKIT = Bukkit.getServer().getClass().getPackage().getName();
|
||||||
|
public static final int VERSION; // Format: 2 digit minor version, 2 digit CraftBukkit revision: eg. 2001 for v1_20_R1
|
||||||
|
static {
|
||||||
|
String[] version = ORG_BUKKIT_CRAFTBUKKIT.substring(ORG_BUKKIT_CRAFTBUKKIT.lastIndexOf('.')).split("_");
|
||||||
|
VERSION = Integer.parseInt(version[1]) * 100 + Integer.parseInt(version[2].substring(1));
|
||||||
|
}
|
||||||
|
|
||||||
public static <T> Class<T> getClass(String name) {
|
public static <T> Class<T> getClass(String name) {
|
||||||
if(name.startsWith("org.bukkit.craftbukkit"))
|
if(name.startsWith("org.bukkit.craftbukkit"))
|
||||||
name = ORG_BUKKIT_CRAFTBUKKIT + name.substring(22);
|
name = ORG_BUKKIT_CRAFTBUKKIT + name.substring(22);
|
||||||
|
@ -49,7 +49,7 @@ public class ViaVersionTranslator implements VersionTranslator {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void readPalettedContainer(Player player, ByteBuf buf, PositionConsumer<BlockState> consumer) {
|
public void readPalettedContainer(Player player, ByteBuf buf, PositionConsumer<BlockState> consumer) {
|
||||||
//TODO GlobalPaletteBits depend on player version
|
//TODO GlobalPaletteBits depend on player version (currently only 1.20.1, depending on Axiom version)
|
||||||
DataPalette container;
|
DataPalette container;
|
||||||
try {
|
try {
|
||||||
container = new PaletteType1_18(PaletteType.BLOCKS, 15).read(buf);
|
container = new PaletteType1_18(PaletteType.BLOCKS, 15).read(buf);
|
||||||
|
@ -2,12 +2,12 @@ package com.moulberry.axiom.packet;
|
|||||||
|
|
||||||
import com.moulberry.axiom.AxiomPaper;
|
import com.moulberry.axiom.AxiomPaper;
|
||||||
import com.moulberry.axiom.Reflection;
|
import com.moulberry.axiom.Reflection;
|
||||||
|
import com.moulberry.axiom.version.VersionWrapper;
|
||||||
import net.minecraft.core.BlockPos;
|
import net.minecraft.core.BlockPos;
|
||||||
import net.minecraft.core.SectionPos;
|
import net.minecraft.core.SectionPos;
|
||||||
import net.minecraft.nbt.CompoundTag;
|
import net.minecraft.nbt.CompoundTag;
|
||||||
import net.minecraft.server.level.ServerChunkCache;
|
import net.minecraft.server.level.ServerChunkCache;
|
||||||
import net.minecraft.server.level.ServerLevel;
|
import net.minecraft.server.level.ServerLevel;
|
||||||
import net.minecraft.server.level.ThreadedLevelLightEngine;
|
|
||||||
import net.minecraft.world.level.BlockGetter;
|
import net.minecraft.world.level.BlockGetter;
|
||||||
import net.minecraft.world.level.block.Block;
|
import net.minecraft.world.level.block.Block;
|
||||||
import net.minecraft.world.level.block.EntityBlock;
|
import net.minecraft.world.level.block.EntityBlock;
|
||||||
@ -18,7 +18,6 @@ import net.minecraft.world.level.chunk.ChunkAccess;
|
|||||||
import net.minecraft.world.level.chunk.LevelChunk;
|
import net.minecraft.world.level.chunk.LevelChunk;
|
||||||
import net.minecraft.world.level.chunk.LevelChunkSection;
|
import net.minecraft.world.level.chunk.LevelChunkSection;
|
||||||
import net.minecraft.world.level.levelgen.Heightmap;
|
import net.minecraft.world.level.levelgen.Heightmap;
|
||||||
import net.minecraft.world.level.lighting.LightEngine;
|
|
||||||
import net.minecraft.world.level.lighting.LightEventListener;
|
import net.minecraft.world.level.lighting.LightEventListener;
|
||||||
import org.bukkit.World;
|
import org.bukkit.World;
|
||||||
|
|
||||||
@ -42,7 +41,6 @@ public class ChunkSectionModifier {
|
|||||||
private final Heightmap[] heightmaps;
|
private final Heightmap[] heightmaps;
|
||||||
private final boolean hadOnlyAir;
|
private final boolean hadOnlyAir;
|
||||||
|
|
||||||
private static final Reflection.Method<ServerChunkCache, ThreadedLevelLightEngine> getLightEngine = Reflection.getTypedMethod(ServerChunkCache.class, ThreadedLevelLightEngine.class);
|
|
||||||
private static final Reflection.Method<ChunkAccess, LevelChunkSection> getSection = Reflection.getTypedMethod(ChunkAccess.class, LevelChunkSection.class, int.class);
|
private static final Reflection.Method<ChunkAccess, LevelChunkSection> getSection = Reflection.getTypedMethod(ChunkAccess.class, LevelChunkSection.class, int.class);
|
||||||
private static final Reflection.Method<LevelChunkSection, Boolean> hasOnlyAir = Reflection.getTypedMethod(LevelChunkSection.class, boolean.class, 1);
|
private static final Reflection.Method<LevelChunkSection, Boolean> hasOnlyAir = Reflection.getTypedMethod(LevelChunkSection.class, boolean.class, 1);
|
||||||
private static final Reflection.Field<ChunkAccess, Map> chunkHeightmaps = Reflection.getField(ChunkAccess.class, Map.class);
|
private static final Reflection.Field<ChunkAccess, Map> chunkHeightmaps = Reflection.getField(ChunkAccess.class, Map.class);
|
||||||
@ -53,7 +51,7 @@ public class ChunkSectionModifier {
|
|||||||
|
|
||||||
ServerLevel level = AxiomPaper.convert(world);
|
ServerLevel level = AxiomPaper.convert(world);
|
||||||
chunkSource = AxiomPaper.getChunkSource(level);
|
chunkSource = AxiomPaper.getChunkSource(level);
|
||||||
lightEngine = getLightEngine.invoke(chunkSource);
|
lightEngine = AxiomPaper.getLightEngine(chunkSource);
|
||||||
chunk = AxiomPaper.getChunk(level, cx, cz);
|
chunk = AxiomPaper.getChunk(level, cx, cz);
|
||||||
|
|
||||||
section = getSection.invoke(chunk, cy - world.getMinHeight() / 16);
|
section = getSection.invoke(chunk, cy - world.getMinHeight() / 16);
|
||||||
@ -67,7 +65,6 @@ public class ChunkSectionModifier {
|
|||||||
private static final Reflection.Method<BlockState, Block> getBlock = Reflection.getTypedMethod(BlockState.class, Block.class);
|
private static final Reflection.Method<BlockState, Block> getBlock = Reflection.getTypedMethod(BlockState.class, Block.class);
|
||||||
private static final Reflection.Method<ChunkAccess, Void> removeBlockEntity = Reflection.getMethod(ChunkAccess.class, BlockPos.class);
|
private static final Reflection.Method<ChunkAccess, Void> removeBlockEntity = Reflection.getMethod(ChunkAccess.class, BlockPos.class);
|
||||||
private static final Reflection.Method<ServerChunkCache, Void> blockChanged = Reflection.getMethod(ServerChunkCache.class, BlockPos.class);
|
private static final Reflection.Method<ServerChunkCache, Void> blockChanged = Reflection.getMethod(ServerChunkCache.class, BlockPos.class);
|
||||||
private static final Reflection.Method<LightEngine, Boolean> hasDifferentLightProperties = Reflection.getTypedMethod(LightEngine.class, boolean.class, BlockGetter.class, BlockPos.class, BlockState.class, BlockState.class);
|
|
||||||
private static final Reflection.Method<LightEventListener, Void> checkBlock = Reflection.getMethod(LightEventListener.class, BlockPos.class);
|
private static final Reflection.Method<LightEventListener, Void> checkBlock = Reflection.getMethod(LightEventListener.class, BlockPos.class);
|
||||||
public void setState(int sx, int sy, int sz, BlockState state) {
|
public void setState(int sx, int sy, int sz, BlockState state) {
|
||||||
BlockState old = setBlockState.invoke(section, sx, sy, sz, state, false);
|
BlockState old = setBlockState.invoke(section, sx, sy, sz, state, false);
|
||||||
@ -88,7 +85,7 @@ public class ChunkSectionModifier {
|
|||||||
|
|
||||||
blockChanged.invoke(chunkSource, pos);
|
blockChanged.invoke(chunkSource, pos);
|
||||||
|
|
||||||
if (hasDifferentLightProperties.invoke(null, chunk, pos, old, state)) {
|
if (VersionWrapper.impl.hasDifferentLightProperties(chunk, pos, old, state)) {
|
||||||
checkBlock.invoke(lightEngine, pos);
|
checkBlock.invoke(lightEngine, pos);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,30 +2,22 @@ package com.moulberry.axiom.packet;
|
|||||||
|
|
||||||
import com.moulberry.axiom.AxiomConstants;
|
import com.moulberry.axiom.AxiomConstants;
|
||||||
import com.moulberry.axiom.AxiomPaper;
|
import com.moulberry.axiom.AxiomPaper;
|
||||||
import com.moulberry.axiom.Reflection;
|
|
||||||
import com.moulberry.axiom.buffer.BiomeBuffer;
|
import com.moulberry.axiom.buffer.BiomeBuffer;
|
||||||
import com.moulberry.axiom.buffer.CompressedBlockEntity;
|
import com.moulberry.axiom.buffer.CompressedBlockEntity;
|
||||||
import com.moulberry.axiom.buffer.MojBuf;
|
import com.moulberry.axiom.buffer.MojBuf;
|
||||||
import com.moulberry.axiom.event.AxiomModifyWorldEvent;
|
import com.moulberry.axiom.event.AxiomModifyWorldEvent;
|
||||||
import com.moulberry.axiom.integration.RegionProtection;
|
import com.moulberry.axiom.integration.RegionProtection;
|
||||||
import com.moulberry.axiom.integration.VersionTranslator;
|
import com.moulberry.axiom.integration.VersionTranslator;
|
||||||
|
import com.moulberry.axiom.version.VersionWrapper;
|
||||||
import io.netty.buffer.ByteBuf;
|
import io.netty.buffer.ByteBuf;
|
||||||
import net.minecraft.core.BlockPos;
|
import net.minecraft.core.BlockPos;
|
||||||
import net.minecraft.network.protocol.Packet;
|
|
||||||
import net.minecraft.network.protocol.game.ClientboundChunksBiomesPacket;
|
|
||||||
import net.minecraft.server.level.ChunkMap;
|
|
||||||
import net.minecraft.server.level.ServerChunkCache;
|
|
||||||
import net.minecraft.server.level.ServerLevel;
|
|
||||||
import net.minecraft.server.level.ServerPlayer;
|
|
||||||
import net.minecraft.server.network.ServerPlayerConnection;
|
|
||||||
import net.minecraft.world.level.ChunkPos;
|
|
||||||
import net.minecraft.world.level.chunk.LevelChunk;
|
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.Chunk;
|
import org.bukkit.Chunk;
|
||||||
import org.bukkit.World;
|
import org.bukkit.World;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.HashSet;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
public class SetBlockBufferPacketListener implements AxiomPacketListener {
|
public class SetBlockBufferPacketListener implements AxiomPacketListener {
|
||||||
|
|
||||||
@ -80,10 +72,6 @@ public class SetBlockBufferPacketListener implements AxiomPacketListener {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final Reflection.Field<ServerChunkCache, ChunkMap> chunkMap = Reflection.getField(ServerChunkCache.class, ChunkMap.class);
|
|
||||||
private static final Reflection.Method<ChunkMap, List> getPlayers = Reflection.getTypedMethod(ChunkMap.class, List.class, ChunkPos.class, boolean.class);
|
|
||||||
private static final Reflection.Method<ServerPlayerConnection, Void> send = Reflection.getMethod(ServerPlayerConnection.class, Packet.class);
|
|
||||||
private static final Reflection.Method<ClientboundChunksBiomesPacket, ClientboundChunksBiomesPacket> forChunks = Reflection.getTypedMethod(ClientboundChunksBiomesPacket.class, ClientboundChunksBiomesPacket.class, List.class);
|
|
||||||
private void applyBiomeBuffer(World world, BiomeBuffer biomeBuffer) {
|
private void applyBiomeBuffer(World world, BiomeBuffer biomeBuffer) {
|
||||||
Set<Chunk> changedChunks = new HashSet<>();
|
Set<Chunk> changedChunks = new HashSet<>();
|
||||||
biomeBuffer.forEachEntry((x, y, z, biome) -> {
|
biomeBuffer.forEachEntry((x, y, z, biome) -> {
|
||||||
@ -93,17 +81,7 @@ public class SetBlockBufferPacketListener implements AxiomPacketListener {
|
|||||||
changedChunks.add(world.getChunkAt(cx, cz));
|
changedChunks.add(world.getChunkAt(cx, cz));
|
||||||
});
|
});
|
||||||
|
|
||||||
ServerLevel level = AxiomPaper.convert(world);
|
VersionWrapper.impl.publishBiomeChange(AxiomPaper.convert(world), changedChunks);
|
||||||
ChunkMap map = chunkMap.get(AxiomPaper.getChunkSource(level));
|
|
||||||
HashMap<ServerPlayer, List<LevelChunk>> playerChunks = new HashMap<>();
|
|
||||||
for (Chunk chunk : changedChunks) {
|
|
||||||
ChunkPos chunkPos = new ChunkPos(chunk.getX(), chunk.getZ());
|
|
||||||
LevelChunk nativeChunk = AxiomPaper.getChunk(level, chunk.getX(), chunk.getZ());
|
|
||||||
for (ServerPlayer player : (List<ServerPlayer>)getPlayers.invoke(map, chunkPos, false)) {
|
|
||||||
playerChunks.computeIfAbsent(player, p -> new ArrayList<>()).add(nativeChunk);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
playerChunks.forEach((serverPlayer, list) -> send.invoke(AxiomPaper.getConnection(serverPlayer), forChunks.invoke(null, list)));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
41
src/main/java/com/moulberry/axiom/version/Version19R2.java
Normale Datei
41
src/main/java/com/moulberry/axiom/version/Version19R2.java
Normale Datei
@ -0,0 +1,41 @@
|
|||||||
|
package com.moulberry.axiom.version;
|
||||||
|
|
||||||
|
import com.moulberry.axiom.AxiomPaper;
|
||||||
|
import com.moulberry.axiom.Reflection;
|
||||||
|
import net.minecraft.core.BlockPos;
|
||||||
|
import net.minecraft.network.protocol.game.ClientboundLevelChunkWithLightPacket;
|
||||||
|
import net.minecraft.server.level.ServerLevel;
|
||||||
|
import net.minecraft.server.level.ServerPlayer;
|
||||||
|
import net.minecraft.server.level.ThreadedLevelLightEngine;
|
||||||
|
import net.minecraft.world.level.BlockGetter;
|
||||||
|
import net.minecraft.world.level.ChunkPos;
|
||||||
|
import net.minecraft.world.level.block.state.BlockState;
|
||||||
|
import net.minecraft.world.level.chunk.LevelChunk;
|
||||||
|
import org.bukkit.Chunk;
|
||||||
|
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
public class Version19R2 implements VersionWrapper {
|
||||||
|
|
||||||
|
private static final Reflection.Method<BlockState, Integer> getLightBlock = Reflection.getTypedMethod(BlockState.class, int.class, BlockGetter.class, BlockPos.class);
|
||||||
|
private static final Reflection.Field<BlockState, Integer> lightEmission = Reflection.getField(BlockState.class, int.class);
|
||||||
|
private static final Reflection.Field<BlockState, Boolean> useShapeForLightOcclusion = Reflection.getField(BlockState.class, boolean.class);
|
||||||
|
@Override
|
||||||
|
public boolean hasDifferentLightProperties(BlockGetter chunk, BlockPos pos, BlockState old, BlockState state) {
|
||||||
|
return getLightBlock.invoke(old, chunk, pos) != getLightBlock.invoke(state, chunk, pos) || lightEmission.get(old) != lightEmission.get(state) || useShapeForLightOcclusion.get(old) || useShapeForLightOcclusion.get(state);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void publishBiomeChange(ServerLevel level, Set<Chunk> chunks) {
|
||||||
|
ThreadedLevelLightEngine lightEngine = AxiomPaper.getLightEngine(AxiomPaper.getChunkSource(level));
|
||||||
|
|
||||||
|
for (Chunk chunk : chunks) {
|
||||||
|
ChunkPos chunkPos = new ChunkPos(chunk.getX(), chunk.getZ());
|
||||||
|
LevelChunk nativeChunk = AxiomPaper.getChunk(level, chunk.getX(), chunk.getZ());
|
||||||
|
ClientboundLevelChunkWithLightPacket packet = new ClientboundLevelChunkWithLightPacket(nativeChunk, lightEngine, null, null, true);
|
||||||
|
for (ServerPlayer player : AxiomPaper.getPlayersSeeingChunk(level, chunkPos)) {
|
||||||
|
AxiomPaper.sendPacket(player, packet);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
42
src/main/java/com/moulberry/axiom/version/Version20R1.java
Normale Datei
42
src/main/java/com/moulberry/axiom/version/Version20R1.java
Normale Datei
@ -0,0 +1,42 @@
|
|||||||
|
package com.moulberry.axiom.version;
|
||||||
|
|
||||||
|
import com.moulberry.axiom.AxiomPaper;
|
||||||
|
import com.moulberry.axiom.Reflection;
|
||||||
|
import net.minecraft.core.BlockPos;
|
||||||
|
import net.minecraft.network.protocol.game.ClientboundChunksBiomesPacket;
|
||||||
|
import net.minecraft.server.level.ServerLevel;
|
||||||
|
import net.minecraft.server.level.ServerPlayer;
|
||||||
|
import net.minecraft.world.level.BlockGetter;
|
||||||
|
import net.minecraft.world.level.ChunkPos;
|
||||||
|
import net.minecraft.world.level.block.state.BlockState;
|
||||||
|
import net.minecraft.world.level.chunk.LevelChunk;
|
||||||
|
import net.minecraft.world.level.lighting.LightEngine;
|
||||||
|
import org.bukkit.Chunk;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
public class Version20R1 implements VersionWrapper {
|
||||||
|
|
||||||
|
private static final Reflection.Method<LightEngine, Boolean> hasDifferentLightProperties = Reflection.getTypedMethod(LightEngine.class, boolean.class, BlockGetter.class, BlockPos.class, BlockState.class, BlockState.class);
|
||||||
|
@Override
|
||||||
|
public boolean hasDifferentLightProperties(BlockGetter chunk, BlockPos pos, BlockState old, BlockState state) {
|
||||||
|
return hasDifferentLightProperties.invoke(null, chunk, pos, old, state);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final Reflection.Method<ClientboundChunksBiomesPacket, ClientboundChunksBiomesPacket> forChunks = Reflection.getTypedMethod(ClientboundChunksBiomesPacket.class, ClientboundChunksBiomesPacket.class, List.class);
|
||||||
|
@Override
|
||||||
|
public void publishBiomeChange(ServerLevel level, Set<Chunk> chunks) {
|
||||||
|
HashMap<ServerPlayer, List<LevelChunk>> playerChunks = new HashMap<>();
|
||||||
|
for (Chunk chunk : chunks) {
|
||||||
|
ChunkPos chunkPos = new ChunkPos(chunk.getX(), chunk.getZ());
|
||||||
|
LevelChunk nativeChunk = AxiomPaper.getChunk(level, chunk.getX(), chunk.getZ());
|
||||||
|
for (ServerPlayer player : AxiomPaper.getPlayersSeeingChunk(level, chunkPos)) {
|
||||||
|
playerChunks.computeIfAbsent(player, p -> new ArrayList<>()).add(nativeChunk);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
playerChunks.forEach((serverPlayer, list) -> AxiomPaper.sendPacket(serverPlayer, forChunks.invoke(null, list)));
|
||||||
|
}
|
||||||
|
}
|
18
src/main/java/com/moulberry/axiom/version/VersionWrapper.java
Normale Datei
18
src/main/java/com/moulberry/axiom/version/VersionWrapper.java
Normale Datei
@ -0,0 +1,18 @@
|
|||||||
|
package com.moulberry.axiom.version;
|
||||||
|
|
||||||
|
import com.moulberry.axiom.Reflection;
|
||||||
|
import net.minecraft.core.BlockPos;
|
||||||
|
import net.minecraft.server.level.ServerLevel;
|
||||||
|
import net.minecraft.world.level.BlockGetter;
|
||||||
|
import net.minecraft.world.level.block.state.BlockState;
|
||||||
|
import org.bukkit.Chunk;
|
||||||
|
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
public interface VersionWrapper {
|
||||||
|
VersionWrapper impl = Reflection.VERSION > 1902 ? new Version20R1() : new Version19R2();
|
||||||
|
|
||||||
|
boolean hasDifferentLightProperties(BlockGetter chunk, BlockPos pos, BlockState old, BlockState state);
|
||||||
|
void publishBiomeChange(ServerLevel level, Set<Chunk> chunks);
|
||||||
|
|
||||||
|
}
|
Laden…
In neuem Issue referenzieren
Einen Benutzer sperren