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 net.minecraft.core.BlockPos;
|
||||
import net.minecraft.network.FriendlyByteBuf;
|
||||
import net.minecraft.server.level.ServerChunkCache;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.network.protocol.Packet;
|
||||
import net.minecraft.server.level.*;
|
||||
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.chunk.LevelChunk;
|
||||
import org.bukkit.Bukkit;
|
||||
@ -19,6 +20,7 @@ import org.bukkit.event.Listener;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
@ -66,6 +68,23 @@ public class AxiomPaper extends JavaPlugin implements Listener {
|
||||
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
|
||||
public void onEnable() {
|
||||
instance = this;
|
||||
|
@ -127,6 +127,12 @@ public class Reflection {
|
||||
|
||||
|
||||
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) {
|
||||
if(name.startsWith("org.bukkit.craftbukkit"))
|
||||
name = ORG_BUKKIT_CRAFTBUKKIT + name.substring(22);
|
||||
|
@ -49,7 +49,7 @@ public class ViaVersionTranslator implements VersionTranslator {
|
||||
|
||||
@Override
|
||||
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;
|
||||
try {
|
||||
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.Reflection;
|
||||
import com.moulberry.axiom.version.VersionWrapper;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.SectionPos;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.server.level.ServerChunkCache;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.server.level.ThreadedLevelLightEngine;
|
||||
import net.minecraft.world.level.BlockGetter;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
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.LevelChunkSection;
|
||||
import net.minecraft.world.level.levelgen.Heightmap;
|
||||
import net.minecraft.world.level.lighting.LightEngine;
|
||||
import net.minecraft.world.level.lighting.LightEventListener;
|
||||
import org.bukkit.World;
|
||||
|
||||
@ -42,7 +41,6 @@ public class ChunkSectionModifier {
|
||||
private final Heightmap[] heightmaps;
|
||||
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<LevelChunkSection, Boolean> hasOnlyAir = Reflection.getTypedMethod(LevelChunkSection.class, boolean.class, 1);
|
||||
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);
|
||||
chunkSource = AxiomPaper.getChunkSource(level);
|
||||
lightEngine = getLightEngine.invoke(chunkSource);
|
||||
lightEngine = AxiomPaper.getLightEngine(chunkSource);
|
||||
chunk = AxiomPaper.getChunk(level, cx, cz);
|
||||
|
||||
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<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<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);
|
||||
public void setState(int sx, int sy, int sz, BlockState state) {
|
||||
BlockState old = setBlockState.invoke(section, sx, sy, sz, state, false);
|
||||
@ -88,7 +85,7 @@ public class ChunkSectionModifier {
|
||||
|
||||
blockChanged.invoke(chunkSource, pos);
|
||||
|
||||
if (hasDifferentLightProperties.invoke(null, chunk, pos, old, state)) {
|
||||
if (VersionWrapper.impl.hasDifferentLightProperties(chunk, pos, old, state)) {
|
||||
checkBlock.invoke(lightEngine, pos);
|
||||
}
|
||||
}
|
||||
|
@ -2,30 +2,22 @@ package com.moulberry.axiom.packet;
|
||||
|
||||
import com.moulberry.axiom.AxiomConstants;
|
||||
import com.moulberry.axiom.AxiomPaper;
|
||||
import com.moulberry.axiom.Reflection;
|
||||
import com.moulberry.axiom.buffer.BiomeBuffer;
|
||||
import com.moulberry.axiom.buffer.CompressedBlockEntity;
|
||||
import com.moulberry.axiom.buffer.MojBuf;
|
||||
import com.moulberry.axiom.event.AxiomModifyWorldEvent;
|
||||
import com.moulberry.axiom.integration.RegionProtection;
|
||||
import com.moulberry.axiom.integration.VersionTranslator;
|
||||
import com.moulberry.axiom.version.VersionWrapper;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
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.Chunk;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
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) {
|
||||
Set<Chunk> changedChunks = new HashSet<>();
|
||||
biomeBuffer.forEachEntry((x, y, z, biome) -> {
|
||||
@ -93,17 +81,7 @@ public class SetBlockBufferPacketListener implements AxiomPacketListener {
|
||||
changedChunks.add(world.getChunkAt(cx, cz));
|
||||
});
|
||||
|
||||
ServerLevel level = AxiomPaper.convert(world);
|
||||
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)));
|
||||
VersionWrapper.impl.publishBiomeChange(AxiomPaper.convert(world), changedChunks);
|
||||
}
|
||||
|
||||
}
|
||||
|
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