├── .gitignore ├── .idea ├── compiler.xml ├── encodings.xml ├── jarRepositories.xml ├── misc.xml ├── uiDesigner.xml └── vcs.xml ├── LICENSE.md ├── branch_1_14 ├── pom.xml └── src │ └── main │ └── java │ └── xuan │ └── cat │ └── fartherviewdistance │ ├── api │ └── branch │ │ ├── BranchChunk.java │ │ ├── BranchChunkLight.java │ │ ├── BranchMinecraft.java │ │ ├── BranchNBT.java │ │ ├── BranchPacket.java │ │ └── packet │ │ ├── PacketEvent.java │ │ ├── PacketKeepAliveEvent.java │ │ ├── PacketMapChunkEvent.java │ │ ├── PacketUnloadChunkEvent.java │ │ └── PacketViewDistanceEvent.java │ └── code │ └── branch │ └── v14 │ ├── Branch_14_Chunk.java │ ├── Branch_14_ChunkLight.java │ ├── Branch_14_ChunkRegionLoader.java │ ├── Branch_14_Minecraft.java │ ├── Branch_14_NBT.java │ ├── Branch_14_Packet.java │ ├── Branch_14_PacketHandleChunk.java │ ├── Branch_14_PacketHandleLightUpdate.java │ └── Branch_14_ProxyPlayerConnection.java ├── branch_1_15 ├── pom.xml └── src │ └── main │ └── java │ └── xuan │ └── cat │ └── fartherviewdistance │ ├── api │ └── branch │ │ ├── BranchChunk.java │ │ ├── BranchChunkLight.java │ │ ├── BranchMinecraft.java │ │ ├── BranchNBT.java │ │ ├── BranchPacket.java │ │ └── packet │ │ ├── PacketEvent.java │ │ ├── PacketKeepAliveEvent.java │ │ ├── PacketMapChunkEvent.java │ │ ├── PacketUnloadChunkEvent.java │ │ └── PacketViewDistanceEvent.java │ └── code │ └── branch │ └── v15 │ ├── Branch_15_Chunk.java │ ├── Branch_15_ChunkLight.java │ ├── Branch_15_ChunkRegionLoader.java │ ├── Branch_15_Minecraft.java │ ├── Branch_15_NBT.java │ ├── Branch_15_Packet.java │ ├── Branch_15_PacketHandleChunk.java │ ├── Branch_15_PacketHandleLightUpdate.java │ └── Branch_15_ProxyPlayerConnection.java ├── branch_1_16 ├── pom.xml └── src │ └── main │ └── java │ └── xuan │ └── cat │ └── fartherviewdistance │ ├── api │ └── branch │ │ ├── BranchChunk.java │ │ ├── BranchChunkLight.java │ │ ├── BranchMinecraft.java │ │ ├── BranchNBT.java │ │ ├── BranchPacket.java │ │ └── packet │ │ ├── PacketEvent.java │ │ ├── PacketKeepAliveEvent.java │ │ ├── PacketMapChunkEvent.java │ │ ├── PacketUnloadChunkEvent.java │ │ └── PacketViewDistanceEvent.java │ └── code │ └── branch │ └── v16 │ ├── Branch_16_Chunk.java │ ├── Branch_16_ChunkLight.java │ ├── Branch_16_ChunkRegionLoader.java │ ├── Branch_16_Minecraft.java │ ├── Branch_16_NBT.java │ ├── Branch_16_Packet.java │ ├── Branch_16_PacketHandleChunk.java │ ├── Branch_16_PacketHandleLightUpdate.java │ └── Branch_16_ProxyPlayerConnection.java ├── branch_1_17 ├── pom.xml └── src │ └── main │ └── java │ └── xuan │ └── cat │ └── fartherviewdistance │ ├── api │ └── branch │ │ ├── BranchChunk.java │ │ ├── BranchChunkLight.java │ │ ├── BranchMinecraft.java │ │ ├── BranchNBT.java │ │ ├── BranchPacket.java │ │ └── packet │ │ ├── PacketEvent.java │ │ ├── PacketKeepAliveEvent.java │ │ ├── PacketMapChunkEvent.java │ │ ├── PacketUnloadChunkEvent.java │ │ └── PacketViewDistanceEvent.java │ └── code │ └── branch │ └── v17 │ ├── Branch_17_Chunk.java │ ├── Branch_17_ChunkLight.java │ ├── Branch_17_ChunkRegionLoader.java │ ├── Branch_17_Minecraft.java │ ├── Branch_17_NBT.java │ ├── Branch_17_Packet.java │ ├── Branch_17_PacketHandleChunk.java │ ├── Branch_17_PacketHandleLightUpdate.java │ └── Branch_17_ProxyPlayerConnection.java ├── branch_1_18 ├── pom.xml └── src │ └── main │ └── java │ └── xuan │ └── cat │ └── fartherviewdistance │ ├── api │ └── branch │ │ ├── BranchChunk.java │ │ ├── BranchChunkLight.java │ │ ├── BranchMinecraft.java │ │ ├── BranchNBT.java │ │ ├── BranchPacket.java │ │ └── packet │ │ ├── PacketEvent.java │ │ ├── PacketKeepAliveEvent.java │ │ ├── PacketMapChunkEvent.java │ │ ├── PacketUnloadChunkEvent.java │ │ └── PacketViewDistanceEvent.java │ └── code │ └── branch │ └── v18 │ ├── Branch_18_Chunk.java │ ├── Branch_18_ChunkLight.java │ ├── Branch_18_ChunkRegionLoader.java │ ├── Branch_18_Minecraft.java │ ├── Branch_18_NBT.java │ ├── Branch_18_Packet.java │ ├── Branch_18_PacketHandleChunk.java │ ├── Branch_18_PacketHandleLightUpdate.java │ └── Branch_18_ProxyPlayerConnection.java ├── branch_1_19 ├── pom.xml └── src │ └── main │ └── java │ └── xuan │ └── cat │ └── fartherviewdistance │ ├── api │ └── branch │ │ ├── BranchChunk.java │ │ ├── BranchChunkLight.java │ │ ├── BranchMinecraft.java │ │ ├── BranchNBT.java │ │ ├── BranchPacket.java │ │ └── packet │ │ ├── PacketEvent.java │ │ ├── PacketKeepAliveEvent.java │ │ ├── PacketMapChunkEvent.java │ │ ├── PacketUnloadChunkEvent.java │ │ └── PacketViewDistanceEvent.java │ └── code │ └── branch │ └── v19 │ ├── Branch_19_Chunk.java │ ├── Branch_19_ChunkLight.java │ ├── Branch_19_ChunkRegionLoader.java │ ├── Branch_19_Minecraft.java │ ├── Branch_19_NBT.java │ ├── Branch_19_Packet.java │ ├── Branch_19_PacketHandleChunk.java │ ├── Branch_19_PacketHandleLightUpdate.java │ └── Branch_19_ProxyPlayerConnection.java ├── pack.bat ├── pom.xml └── src └── main ├── java └── xuan │ └── cat │ └── fartherviewdistance │ ├── api │ ├── ViewDistance.java │ ├── branch │ │ ├── BranchChunk.java │ │ ├── BranchChunkLight.java │ │ ├── BranchMinecraft.java │ │ ├── BranchNBT.java │ │ ├── BranchPacket.java │ │ └── packet │ │ │ ├── PacketEvent.java │ │ │ ├── PacketKeepAliveEvent.java │ │ │ ├── PacketMapChunkEvent.java │ │ │ ├── PacketUnloadChunkEvent.java │ │ │ └── PacketViewDistanceEvent.java │ ├── data │ │ └── PlayerView.java │ └── event │ │ ├── ExtendChunkEvent.java │ │ ├── PlayerCheckViewDistanceEvent.java │ │ ├── PlayerInitViewEvent.java │ │ ├── PlayerSendExtendChunkEvent.java │ │ ├── PlayerSendUnloadChunkEvent.java │ │ ├── PlayerSendViewDistanceEvent.java │ │ ├── PlayerViewMarkSendChunkEvent.java │ │ └── PlayerViewMarkWaitChunkEvent.java │ └── code │ ├── ChunkEvent.java │ ├── ChunkIndex.java │ ├── ChunkPacketEvent.java │ ├── ChunkPlaceholder.java │ ├── ChunkServer.java │ ├── branch │ ├── v14 │ │ ├── Branch_14_Minecraft.java │ │ └── Branch_14_Packet.java │ ├── v15 │ │ ├── Branch_15_Minecraft.java │ │ └── Branch_15_Packet.java │ ├── v16 │ │ ├── Branch_16_Minecraft.java │ │ └── Branch_16_Packet.java │ ├── v17 │ │ ├── Branch_17_Minecraft.java │ │ └── Branch_17_Packet.java │ ├── v18 │ │ ├── Branch_18_Minecraft.java │ │ └── Branch_18_Packet.java │ └── v19 │ │ ├── Branch_19_Minecraft.java │ │ └── Branch_19_Packet.java │ ├── command │ ├── Command.java │ └── CommandSuggest.java │ └── data │ ├── ConfigData.java │ ├── CumulativeReport.java │ ├── LangFiles.java │ ├── NetworkSpeed.java │ ├── NetworkTraffic.java │ ├── PlayerChunkView.java │ └── viewmap │ ├── IntX15ViewMap.java │ ├── LongX31ViewMap.java │ ├── LongXInfinitelyViewMap.java │ ├── ViewMap.java │ ├── ViewMapMode.java │ └── ViewShape.java └── resources ├── config.yml ├── lang ├── cs_cz.json ├── de_de.json ├── en.json ├── es_es.json ├── fr_fr.json ├── it_it.json ├── ja_jp.json ├── pl_pl.json ├── ru_ru.json ├── uk_ua.json ├── zh_cn.json └── zh_tw.json └── plugin.yml /.gitignore: -------------------------------------------------------------------------------- 1 | # Project exclude paths 2 | /target/ 3 | # 项目排除路径 4 | /branch_1_14/target/ 5 | /branch_1_15/target/ 6 | /branch_1_16/target/ 7 | /branch_1_17/target/ 8 | /branch_1_18/target/ 9 | /branch_1_19/target/ 10 | /.idea/ 11 | -------------------------------------------------------------------------------- /.idea/compiler.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /.idea/encodings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /.idea/jarRepositories.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 9 | 10 | 14 | 15 | 19 | 20 | 24 | 25 | 29 | 30 | -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /branch_1_14/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | FartherViewDistance 8 | branch_1_14 9 | r1 10 | 11 | 12 | 1.8 13 | UTF-8 14 | 15 | 16 | 17 | clean package 18 | 19 | 20 | org.apache.maven.plugins 21 | maven-compiler-plugin 22 | 3.8.1 23 | 24 | 1.8 25 | 1.8 26 | 27 | 28 | 29 | 30 | 31 | src/main/resources 32 | true 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | dmulloy2-repo 41 | https://repo.dmulloy2.net/repository/public/ 42 | 43 | 44 | 45 | minecraft_environment 46 | https://xuancat.app:8443/repository/minecraft_environment/ 47 | 48 | 49 | 50 | 51 | 52 | 53 | paper 54 | 1.14.4 55 | 243 56 | 57 | 58 | paper 59 | 1.14.4 60 | 243 61 | patched 62 | 63 | 64 | -------------------------------------------------------------------------------- /branch_1_14/src/main/java/xuan/cat/fartherviewdistance/api/branch/BranchChunk.java: -------------------------------------------------------------------------------- 1 | package xuan.cat.fartherviewdistance.api.branch; 2 | 3 | import org.bukkit.Chunk; 4 | import org.bukkit.Material; 5 | import org.bukkit.World; 6 | import org.bukkit.block.Biome; 7 | import org.bukkit.block.data.BlockData; 8 | import org.bukkit.util.Vector; 9 | 10 | import java.util.List; 11 | import java.util.Map; 12 | 13 | public interface BranchChunk { 14 | BranchNBT toNBT(BranchChunkLight light, List asyncRunnable); 15 | 16 | Chunk getChunk(); 17 | 18 | World getWorld(); 19 | 20 | boolean equalsBlockData(int x, int y, int z, BlockData blockData); 21 | BlockData getBlockData(int x, int y, int z); 22 | void setBlockData(int x, int y, int z, BlockData blockData); 23 | Map getBlockDataMap(); 24 | 25 | Material getMaterial(int x, int y, int z); 26 | void setMaterial(int x, int y, int z, Material material); 27 | 28 | int getX(); 29 | int getZ(); 30 | 31 | Status getStatus(); 32 | 33 | void replaceAllMaterial(BlockData[] target, BlockData to); 34 | 35 | @Deprecated 36 | Biome getBiome(int x, int z); 37 | Biome getBiome(int x, int y, int z); 38 | @Deprecated 39 | void setBiome(int x, int z, Biome biome); 40 | void setBiome(int x, int y, int z, Biome biome); 41 | 42 | boolean hasFluid(int x, int y, int z); 43 | boolean isAir(int x, int y, int z); 44 | 45 | int getHighestY(int x, int z); 46 | 47 | /** 48 | * 區塊狀態 49 | */ 50 | enum Status { 51 | EMPTY (0), 52 | STRUCTURE_STARTS (1), 53 | STRUCTURE_REFERENCES(2), 54 | BIOMES (3), 55 | NOISE (4), 56 | SURFACE (5), 57 | CARVERS (6), 58 | LIQUID_CARVERS (7), 59 | FEATURES (8), 60 | LIGHT (9), 61 | SPAWN (10), 62 | HEIGHTMAPS (11), 63 | FULL (12); 64 | 65 | private final int sequence; 66 | Status(int sequence) { 67 | this.sequence = sequence; 68 | } 69 | 70 | public boolean isAbove(Status status) { 71 | return this.sequence >= status.sequence; 72 | } 73 | public boolean isUnder(Status status) { 74 | return this.sequence <= status.sequence; 75 | } 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /branch_1_14/src/main/java/xuan/cat/fartherviewdistance/api/branch/BranchChunkLight.java: -------------------------------------------------------------------------------- 1 | package xuan.cat.fartherviewdistance.api.branch; 2 | 3 | public interface BranchChunkLight { 4 | } 5 | -------------------------------------------------------------------------------- /branch_1_14/src/main/java/xuan/cat/fartherviewdistance/api/branch/BranchMinecraft.java: -------------------------------------------------------------------------------- 1 | package xuan.cat.fartherviewdistance.api.branch; 2 | 3 | import org.bukkit.Chunk; 4 | import org.bukkit.World; 5 | import org.bukkit.entity.Player; 6 | 7 | import java.io.IOException; 8 | 9 | public interface BranchMinecraft { 10 | BranchNBT getChunkNBTFromDisk(World world, int chunkX, int chunkZ) throws IOException; 11 | 12 | BranchChunk getChunkFromMemoryCache(World world, int chunkX, int chunkZ); 13 | 14 | BranchChunk fromChunk(World world, int chunkX, int chunkZ, BranchNBT nbt, boolean integralHeightmap); 15 | 16 | BranchChunkLight fromLight(World world, BranchNBT nbt); 17 | 18 | BranchChunkLight fromLight(World world); 19 | 20 | BranchChunk fromChunk(World world, Chunk chunk); 21 | 22 | BranchChunk.Status fromStatus(BranchNBT nbt); 23 | 24 | void injectPlayer(Player player); 25 | } 26 | -------------------------------------------------------------------------------- /branch_1_14/src/main/java/xuan/cat/fartherviewdistance/api/branch/BranchNBT.java: -------------------------------------------------------------------------------- 1 | package xuan.cat.fartherviewdistance.api.branch; 2 | 3 | public interface BranchNBT { 4 | } 5 | -------------------------------------------------------------------------------- /branch_1_14/src/main/java/xuan/cat/fartherviewdistance/api/branch/BranchPacket.java: -------------------------------------------------------------------------------- 1 | package xuan.cat.fartherviewdistance.api.branch; 2 | 3 | import org.bukkit.entity.Player; 4 | 5 | import java.util.function.Consumer; 6 | 7 | public interface BranchPacket { 8 | void sendViewDistance(Player player, int viewDistance); 9 | 10 | void sendUnloadChunk(Player player, int chunkX, int chunkZ); 11 | 12 | Consumer sendChunkAndLight(BranchChunk chunk, BranchChunkLight light, boolean needTile, Consumer consumeTraffic); 13 | 14 | void sendKeepAlive(Player player, long id); 15 | } 16 | -------------------------------------------------------------------------------- /branch_1_14/src/main/java/xuan/cat/fartherviewdistance/api/branch/packet/PacketEvent.java: -------------------------------------------------------------------------------- 1 | package xuan.cat.fartherviewdistance.api.branch.packet; 2 | 3 | import org.bukkit.Bukkit; 4 | import org.bukkit.entity.Player; 5 | import org.bukkit.event.Cancellable; 6 | import org.bukkit.event.Event; 7 | 8 | public abstract class PacketEvent extends Event implements Cancellable { 9 | private final Player player; 10 | private boolean cancel = false; 11 | 12 | public PacketEvent(Player player) { 13 | super(!Bukkit.isPrimaryThread()); 14 | this.player = player; 15 | } 16 | 17 | public final boolean isCancelled() { 18 | return cancel; 19 | } 20 | public final void setCancelled(boolean cancel) { 21 | this.cancel = cancel; 22 | } 23 | 24 | public final Player getPlayer() { 25 | return player; 26 | } 27 | } -------------------------------------------------------------------------------- /branch_1_14/src/main/java/xuan/cat/fartherviewdistance/api/branch/packet/PacketKeepAliveEvent.java: -------------------------------------------------------------------------------- 1 | package xuan.cat.fartherviewdistance.api.branch.packet; 2 | 3 | import org.bukkit.entity.Player; 4 | import org.bukkit.event.HandlerList; 5 | 6 | public final class PacketKeepAliveEvent extends PacketEvent { 7 | private static final HandlerList handlers = new HandlerList(); 8 | public HandlerList getHandlers() { 9 | return handlers; 10 | } 11 | public static HandlerList getHandlerList() { 12 | return handlers; 13 | } 14 | 15 | private final long id; 16 | 17 | public PacketKeepAliveEvent(Player player, long id) { 18 | super(player); 19 | this.id = id; 20 | } 21 | 22 | public long getId() { 23 | return id; 24 | } 25 | } -------------------------------------------------------------------------------- /branch_1_14/src/main/java/xuan/cat/fartherviewdistance/api/branch/packet/PacketMapChunkEvent.java: -------------------------------------------------------------------------------- 1 | package xuan.cat.fartherviewdistance.api.branch.packet; 2 | 3 | import org.bukkit.entity.Player; 4 | import org.bukkit.event.HandlerList; 5 | 6 | public final class PacketMapChunkEvent extends PacketEvent { 7 | private static final HandlerList handlers = new HandlerList(); 8 | public HandlerList getHandlers() { 9 | return handlers; 10 | } 11 | public static HandlerList getHandlerList() { 12 | return handlers; 13 | } 14 | 15 | private final int chunkX; 16 | private final int chunkZ; 17 | 18 | public PacketMapChunkEvent(Player player, int chunkX, int chunkZ) { 19 | super(player); 20 | this.chunkX = chunkX; 21 | this.chunkZ = chunkZ; 22 | } 23 | 24 | public int getChunkX() { 25 | return chunkX; 26 | } 27 | public int getChunkZ() { 28 | return chunkZ; 29 | } 30 | } -------------------------------------------------------------------------------- /branch_1_14/src/main/java/xuan/cat/fartherviewdistance/api/branch/packet/PacketUnloadChunkEvent.java: -------------------------------------------------------------------------------- 1 | package xuan.cat.fartherviewdistance.api.branch.packet; 2 | 3 | import org.bukkit.entity.Player; 4 | import org.bukkit.event.HandlerList; 5 | 6 | public final class PacketUnloadChunkEvent extends PacketEvent { 7 | private static final HandlerList handlers = new HandlerList(); 8 | public HandlerList getHandlers() { 9 | return handlers; 10 | } 11 | public static HandlerList getHandlerList() { 12 | return handlers; 13 | } 14 | 15 | private final int chunkX; 16 | private final int chunkZ; 17 | 18 | public PacketUnloadChunkEvent(Player player, int chunkX, int chunkZ) { 19 | super(player); 20 | this.chunkX = chunkX; 21 | this.chunkZ = chunkZ; 22 | } 23 | 24 | public int getChunkX() { 25 | return chunkX; 26 | } 27 | public int getChunkZ() { 28 | return chunkZ; 29 | } 30 | } -------------------------------------------------------------------------------- /branch_1_14/src/main/java/xuan/cat/fartherviewdistance/api/branch/packet/PacketViewDistanceEvent.java: -------------------------------------------------------------------------------- 1 | package xuan.cat.fartherviewdistance.api.branch.packet; 2 | 3 | import org.bukkit.entity.Player; 4 | import org.bukkit.event.HandlerList; 5 | 6 | public final class PacketViewDistanceEvent extends PacketEvent { 7 | private static final HandlerList handlers = new HandlerList(); 8 | public HandlerList getHandlers() { 9 | return handlers; 10 | } 11 | public static HandlerList getHandlerList() { 12 | return handlers; 13 | } 14 | 15 | private final int viewDistance; 16 | 17 | public PacketViewDistanceEvent(Player player, int viewDistance) { 18 | super(player); 19 | this.viewDistance = viewDistance; 20 | } 21 | 22 | public int getViewDistance() { 23 | return viewDistance; 24 | } 25 | 26 | } -------------------------------------------------------------------------------- /branch_1_14/src/main/java/xuan/cat/fartherviewdistance/code/branch/v14/Branch_14_ChunkLight.java: -------------------------------------------------------------------------------- 1 | package xuan.cat.fartherviewdistance.code.branch.v14; 2 | 3 | import net.minecraft.server.v1_14_R1.WorldServer; 4 | import org.bukkit.World; 5 | import org.bukkit.craftbukkit.v1_14_R1.CraftWorld; 6 | import xuan.cat.fartherviewdistance.api.branch.BranchChunkLight; 7 | 8 | import java.util.Arrays; 9 | 10 | public final class Branch_14_ChunkLight implements BranchChunkLight { 11 | public static final byte[] EMPTY = new byte[0]; 12 | 13 | private final WorldServer worldServer; 14 | private final byte[][] blockLights; 15 | private final byte[][] skyLights; 16 | 17 | public Branch_14_ChunkLight(World world) { 18 | this(((CraftWorld) world).getHandle()); 19 | } 20 | public Branch_14_ChunkLight(WorldServer worldServer) { 21 | this(worldServer, new byte[18][], new byte[18][]); 22 | } 23 | public Branch_14_ChunkLight(WorldServer worldServer, byte[][] blockLights, byte[][] skyLights) { 24 | this.worldServer = worldServer; 25 | this.blockLights = blockLights; 26 | this.skyLights = skyLights; 27 | Arrays.fill(blockLights, EMPTY); 28 | Arrays.fill(skyLights, EMPTY); 29 | } 30 | 31 | public WorldServer getWorldServer() { 32 | return worldServer; 33 | } 34 | 35 | public int getArrayLength() { 36 | return blockLights.length; 37 | } 38 | 39 | public static int indexFromSectionY(WorldServer worldServer, int sectionY) { 40 | return sectionY + 1; 41 | } 42 | 43 | public void setBlockLight(int sectionY, byte[] blockLight) { 44 | blockLights[indexFromSectionY(worldServer, sectionY)] = blockLight; 45 | } 46 | public void setSkyLight(int sectionY, byte[] skyLight) { 47 | skyLights[indexFromSectionY(worldServer, sectionY)] = skyLight; 48 | } 49 | 50 | public byte[] getBlockLight(int sectionY) { 51 | return blockLights[indexFromSectionY(worldServer, sectionY)]; 52 | } 53 | public byte[] getSkyLight(int sectionY) { 54 | return skyLights[indexFromSectionY(worldServer, sectionY)]; 55 | } 56 | 57 | public byte[][] getBlockLights() { 58 | return blockLights; 59 | } 60 | public byte[][] getSkyLights() { 61 | return skyLights; 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /branch_1_14/src/main/java/xuan/cat/fartherviewdistance/code/branch/v14/Branch_14_Minecraft.java: -------------------------------------------------------------------------------- 1 | package xuan.cat.fartherviewdistance.code.branch.v14; 2 | 3 | import io.netty.channel.*; 4 | import net.minecraft.server.v1_14_R1.*; 5 | import org.bukkit.World; 6 | import org.bukkit.craftbukkit.v1_14_R1.CraftChunk; 7 | import org.bukkit.craftbukkit.v1_14_R1.CraftWorld; 8 | import org.bukkit.craftbukkit.v1_14_R1.entity.CraftPlayer; 9 | import org.bukkit.entity.Player; 10 | import xuan.cat.fartherviewdistance.api.branch.BranchChunk; 11 | import xuan.cat.fartherviewdistance.api.branch.BranchChunkLight; 12 | import xuan.cat.fartherviewdistance.api.branch.BranchMinecraft; 13 | import xuan.cat.fartherviewdistance.api.branch.BranchNBT; 14 | 15 | import java.io.IOException; 16 | 17 | public final class Branch_14_Minecraft implements BranchMinecraft { 18 | public BranchNBT getChunkNBTFromDisk(World world, int chunkX, int chunkZ) throws IOException { 19 | WorldServer worldServer = ((CraftWorld) world).getHandle(); 20 | ChunkProviderServer providerServer = worldServer.getChunkProvider(); 21 | PlayerChunkMap playerChunkMap = providerServer.playerChunkMap; 22 | NBTTagCompound nbtTagCompound = playerChunkMap.read(new ChunkCoordIntPair(chunkX, chunkZ)); 23 | return nbtTagCompound != null ? new Branch_14_NBT(nbtTagCompound) : null; 24 | } 25 | 26 | /** 27 | * @deprecated 由於 NMS 沒有實作異步, 所以不使用 28 | */ 29 | @Deprecated 30 | public BranchChunk getChunkFromMemoryCache(World world, int chunkX, int chunkZ) { 31 | return null; 32 | } 33 | 34 | public BranchChunk fromChunk(World world, int chunkX, int chunkZ, BranchNBT nbt, boolean integralHeightmap) { 35 | return Branch_14_ChunkRegionLoader.loadChunk(((CraftWorld) world).getHandle(), new ChunkCoordIntPair(chunkX, chunkZ), ((Branch_14_NBT) nbt).getNMSTag(), integralHeightmap); 36 | } 37 | 38 | public BranchChunkLight fromLight(World world, BranchNBT nbt) { 39 | return Branch_14_ChunkRegionLoader.loadLight(((CraftWorld) world).getHandle(), ((Branch_14_NBT) nbt).getNMSTag()); 40 | } 41 | public BranchChunkLight fromLight(World world) { 42 | return new Branch_14_ChunkLight(((CraftWorld) world).getHandle()); 43 | } 44 | 45 | public BranchChunk.Status fromStatus(BranchNBT nbt) { 46 | return Branch_14_ChunkRegionLoader.loadStatus(((Branch_14_NBT) nbt).getNMSTag()); 47 | } 48 | 49 | public BranchChunk fromChunk(World world, org.bukkit.Chunk chunk) { 50 | return new Branch_14_Chunk(((CraftChunk) chunk).getCraftWorld().getHandle(), ((CraftChunk) chunk).getHandle()); 51 | } 52 | 53 | public int getPlayerPing(Player player) { 54 | return ((CraftPlayer) player).getHandle().ping; 55 | } 56 | 57 | public void injectPlayer(Player player) { 58 | EntityPlayer entityPlayer = ((CraftPlayer) player).getHandle(); 59 | PlayerConnection connection = entityPlayer.playerConnection; 60 | NetworkManager networkManager = connection.networkManager; 61 | Channel channel = networkManager.channel; 62 | ChannelPipeline pipeline = channel.pipeline(); 63 | pipeline.addAfter("packet_handler", "farther_view_distance_write", new ChannelDuplexHandler() { 64 | @Override 65 | public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception { 66 | if (msg instanceof Packet) { 67 | if (!Branch_14_ProxyPlayerConnection.write(player, (Packet) msg)) 68 | return; 69 | } 70 | super.write(ctx, msg, promise); 71 | } 72 | }); 73 | pipeline.addAfter("encoder", "farther_view_distance_read", new ChannelInboundHandlerAdapter() { 74 | @Override 75 | public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { 76 | if (msg instanceof Packet) { 77 | if (!Branch_14_ProxyPlayerConnection.read(player, (Packet) msg)) 78 | return; 79 | } 80 | super.channelRead(ctx, msg); 81 | } 82 | }); 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /branch_1_14/src/main/java/xuan/cat/fartherviewdistance/code/branch/v14/Branch_14_NBT.java: -------------------------------------------------------------------------------- 1 | package xuan.cat.fartherviewdistance.code.branch.v14; 2 | 3 | import net.minecraft.server.v1_14_R1.NBTTagCompound; 4 | import xuan.cat.fartherviewdistance.api.branch.BranchNBT; 5 | 6 | public final class Branch_14_NBT implements BranchNBT { 7 | 8 | protected NBTTagCompound tag; 9 | 10 | public Branch_14_NBT() { 11 | this.tag = new NBTTagCompound(); 12 | } 13 | 14 | public Branch_14_NBT(NBTTagCompound tag) { 15 | this.tag = tag; 16 | } 17 | 18 | 19 | public NBTTagCompound getNMSTag() { 20 | return tag; 21 | } 22 | 23 | @Override 24 | public String toString() { 25 | return tag.toString(); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /branch_1_14/src/main/java/xuan/cat/fartherviewdistance/code/branch/v14/Branch_14_Packet.java: -------------------------------------------------------------------------------- 1 | package xuan.cat.fartherviewdistance.code.branch.v14; 2 | 3 | import io.netty.buffer.Unpooled; 4 | import net.minecraft.server.v1_14_R1.*; 5 | import org.bukkit.craftbukkit.v1_14_R1.entity.CraftPlayer; 6 | import org.bukkit.entity.Player; 7 | import xuan.cat.fartherviewdistance.api.branch.BranchChunk; 8 | import xuan.cat.fartherviewdistance.api.branch.BranchChunkLight; 9 | import xuan.cat.fartherviewdistance.api.branch.BranchPacket; 10 | 11 | import java.util.function.Consumer; 12 | 13 | public final class Branch_14_Packet implements BranchPacket { 14 | private final Branch_14_PacketHandleChunk handleChunk = new Branch_14_PacketHandleChunk(); 15 | private final Branch_14_PacketHandleLightUpdate handleLightUpdate = new Branch_14_PacketHandleLightUpdate(); 16 | 17 | public void sendPacket(Player player, Packet packet) { 18 | try { 19 | PlayerConnection container = ((CraftPlayer) player).getHandle().playerConnection; 20 | container.sendPacket(packet); 21 | } catch (IllegalArgumentException ignored) { 22 | } 23 | } 24 | 25 | public void sendViewDistance(Player player, int viewDistance) { 26 | sendPacket(player, new PacketPlayOutViewDistance(viewDistance)); 27 | } 28 | 29 | public void sendUnloadChunk(Player player, int chunkX, int chunkZ) { 30 | sendPacket(player, new PacketPlayOutUnloadChunk(chunkX, chunkZ)); 31 | } 32 | 33 | public Consumer sendChunkAndLight(BranchChunk chunk, BranchChunkLight light, boolean needTile, Consumer consumeTraffic) { 34 | PacketPlayOutMapChunk packetChunk = handleChunk.createMapChunkPacket(chunk.getChunk(), 65535, needTile); 35 | PacketPlayOutLightUpdate packetLight = handleLightUpdate.createLightUpdatePacket(chunk.getX(), chunk.getZ(), ((Branch_14_ChunkLight) light)); 36 | try { 37 | // 適用於 paper 38 | packetChunk.setReady(true); 39 | } catch (NoSuchMethodError noSuchMethodError) { 40 | // 適用於 spigot (不推薦) 41 | } 42 | calculateConsume(packetChunk, consumeTraffic); 43 | calculateConsume(packetLight, consumeTraffic); 44 | return (player) -> { 45 | sendPacket(player, packetLight); 46 | sendPacket(player, packetChunk); 47 | }; 48 | } 49 | 50 | public void sendKeepAlive(Player player, long id) { 51 | sendPacket(player, new PacketPlayOutKeepAlive(id)); 52 | } 53 | 54 | private void calculateConsume(Packet packet, Consumer consumeTraffic) { 55 | PacketDataSerializer serializer = new PacketDataSerializer(Unpooled.buffer().writerIndex(0)); 56 | try { 57 | packet.b(serializer); 58 | } catch (Exception ignored) { 59 | } 60 | consumeTraffic.accept(serializer.readableBytes()); 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /branch_1_14/src/main/java/xuan/cat/fartherviewdistance/code/branch/v14/Branch_14_ProxyPlayerConnection.java: -------------------------------------------------------------------------------- 1 | package xuan.cat.fartherviewdistance.code.branch.v14; 2 | 3 | import net.minecraft.server.v1_14_R1.*; 4 | import org.bukkit.Bukkit; 5 | import org.bukkit.entity.Player; 6 | import xuan.cat.fartherviewdistance.api.branch.packet.PacketKeepAliveEvent; 7 | import xuan.cat.fartherviewdistance.api.branch.packet.PacketMapChunkEvent; 8 | import xuan.cat.fartherviewdistance.api.branch.packet.PacketUnloadChunkEvent; 9 | import xuan.cat.fartherviewdistance.api.branch.packet.PacketViewDistanceEvent; 10 | 11 | import java.lang.reflect.Field; 12 | 13 | public final class Branch_14_ProxyPlayerConnection { 14 | public static boolean read(Player player, Packet packet) { 15 | if (packet instanceof PacketPlayInKeepAlive) { 16 | PacketKeepAliveEvent event = new PacketKeepAliveEvent(player, ((PacketPlayInKeepAlive) packet).b()); 17 | Bukkit.getPluginManager().callEvent(event); 18 | return !event.isCancelled(); 19 | } else { 20 | return true; 21 | } 22 | } 23 | 24 | 25 | private static Field field_PacketPlayOutUnloadChunk_chunkX; 26 | private static Field field_PacketPlayOutUnloadChunk_chunkZ; 27 | private static Field field_PacketPlayOutViewDistance_distance; 28 | private static Field field_PacketPlayOutMapChunk_chunkX; 29 | private static Field field_PacketPlayOutMapChunk_chunkZ; 30 | static { 31 | try { 32 | field_PacketPlayOutUnloadChunk_chunkX = PacketPlayOutUnloadChunk.class.getDeclaredField("a"); 33 | field_PacketPlayOutUnloadChunk_chunkZ = PacketPlayOutUnloadChunk.class.getDeclaredField("b"); 34 | field_PacketPlayOutViewDistance_distance = PacketPlayOutViewDistance.class.getDeclaredField("a"); 35 | field_PacketPlayOutMapChunk_chunkX = PacketPlayOutMapChunk.class.getDeclaredField("a"); 36 | field_PacketPlayOutMapChunk_chunkZ = PacketPlayOutMapChunk.class.getDeclaredField("b"); 37 | field_PacketPlayOutUnloadChunk_chunkX.setAccessible(true); 38 | field_PacketPlayOutUnloadChunk_chunkZ.setAccessible(true); 39 | field_PacketPlayOutViewDistance_distance.setAccessible(true); 40 | field_PacketPlayOutMapChunk_chunkX.setAccessible(true); 41 | field_PacketPlayOutMapChunk_chunkZ.setAccessible(true); 42 | } catch (Exception ex) { 43 | ex.printStackTrace(); 44 | } 45 | } 46 | public static boolean write(Player player, Packet packet) { 47 | try { 48 | if (packet instanceof PacketPlayOutUnloadChunk) { 49 | PacketUnloadChunkEvent event = new PacketUnloadChunkEvent(player, field_PacketPlayOutUnloadChunk_chunkX.getInt(packet), field_PacketPlayOutUnloadChunk_chunkZ.getInt(packet)); 50 | Bukkit.getPluginManager().callEvent(event); 51 | return !event.isCancelled(); 52 | } else if (packet instanceof PacketPlayOutViewDistance) { 53 | PacketViewDistanceEvent event = new PacketViewDistanceEvent(player, field_PacketPlayOutViewDistance_distance.getInt(packet)); 54 | Bukkit.getPluginManager().callEvent(event); 55 | return !event.isCancelled(); 56 | } else if (packet instanceof PacketPlayOutMapChunk) { 57 | PacketMapChunkEvent event = new PacketMapChunkEvent(player, field_PacketPlayOutMapChunk_chunkX.getInt(packet), field_PacketPlayOutMapChunk_chunkZ.getInt(packet)); 58 | Bukkit.getPluginManager().callEvent(event); 59 | return !event.isCancelled(); 60 | } else { 61 | return true; 62 | } 63 | } catch (Exception ex) { 64 | ex.printStackTrace(); 65 | return true; 66 | } 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /branch_1_15/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | FartherViewDistance 8 | branch_1_15 9 | r1 10 | 11 | 12 | 1.8 13 | UTF-8 14 | 15 | 16 | 17 | clean package 18 | 19 | 20 | org.apache.maven.plugins 21 | maven-compiler-plugin 22 | 3.8.1 23 | 24 | 1.8 25 | 1.8 26 | 27 | 28 | 29 | 30 | 31 | src/main/resources 32 | true 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | dmulloy2-repo 41 | https://repo.dmulloy2.net/repository/public/ 42 | 43 | 44 | 45 | minecraft_environment 46 | https://xuancat.app:8443/repository/minecraft_environment/ 47 | 48 | 49 | 50 | 51 | 52 | 53 | paper 54 | 1.15.2 55 | 391 56 | 57 | 58 | paper 59 | 1.15.2 60 | 391 61 | patched 62 | 63 | 64 | -------------------------------------------------------------------------------- /branch_1_15/src/main/java/xuan/cat/fartherviewdistance/api/branch/BranchChunk.java: -------------------------------------------------------------------------------- 1 | package xuan.cat.fartherviewdistance.api.branch; 2 | 3 | import org.bukkit.Chunk; 4 | import org.bukkit.Material; 5 | import org.bukkit.World; 6 | import org.bukkit.block.Biome; 7 | import org.bukkit.block.data.BlockData; 8 | import org.bukkit.util.Vector; 9 | 10 | import java.util.List; 11 | import java.util.Map; 12 | 13 | public interface BranchChunk { 14 | BranchNBT toNBT(BranchChunkLight light, List asyncRunnable); 15 | 16 | Chunk getChunk(); 17 | 18 | World getWorld(); 19 | 20 | boolean equalsBlockData(int x, int y, int z, BlockData blockData); 21 | BlockData getBlockData(int x, int y, int z); 22 | void setBlockData(int x, int y, int z, BlockData blockData); 23 | Map getBlockDataMap(); 24 | 25 | Material getMaterial(int x, int y, int z); 26 | void setMaterial(int x, int y, int z, Material material); 27 | 28 | int getX(); 29 | int getZ(); 30 | 31 | Status getStatus(); 32 | 33 | void replaceAllMaterial(BlockData[] target, BlockData to); 34 | 35 | @Deprecated 36 | Biome getBiome(int x, int z); 37 | Biome getBiome(int x, int y, int z); 38 | @Deprecated 39 | void setBiome(int x, int z, Biome biome); 40 | void setBiome(int x, int y, int z, Biome biome); 41 | 42 | boolean hasFluid(int x, int y, int z); 43 | boolean isAir(int x, int y, int z); 44 | 45 | int getHighestY(int x, int z); 46 | 47 | /** 48 | * 區塊狀態 49 | */ 50 | enum Status { 51 | EMPTY (0), 52 | STRUCTURE_STARTS (1), 53 | STRUCTURE_REFERENCES(2), 54 | BIOMES (3), 55 | NOISE (4), 56 | SURFACE (5), 57 | CARVERS (6), 58 | LIQUID_CARVERS (7), 59 | FEATURES (8), 60 | LIGHT (9), 61 | SPAWN (10), 62 | HEIGHTMAPS (11), 63 | FULL (12); 64 | 65 | private final int sequence; 66 | Status(int sequence) { 67 | this.sequence = sequence; 68 | } 69 | 70 | public boolean isAbove(Status status) { 71 | return this.sequence >= status.sequence; 72 | } 73 | public boolean isUnder(Status status) { 74 | return this.sequence <= status.sequence; 75 | } 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /branch_1_15/src/main/java/xuan/cat/fartherviewdistance/api/branch/BranchChunkLight.java: -------------------------------------------------------------------------------- 1 | package xuan.cat.fartherviewdistance.api.branch; 2 | 3 | public interface BranchChunkLight { 4 | } 5 | -------------------------------------------------------------------------------- /branch_1_15/src/main/java/xuan/cat/fartherviewdistance/api/branch/BranchMinecraft.java: -------------------------------------------------------------------------------- 1 | package xuan.cat.fartherviewdistance.api.branch; 2 | 3 | import org.bukkit.Chunk; 4 | import org.bukkit.World; 5 | import org.bukkit.entity.Player; 6 | 7 | import java.io.IOException; 8 | 9 | public interface BranchMinecraft { 10 | BranchNBT getChunkNBTFromDisk(World world, int chunkX, int chunkZ) throws IOException; 11 | 12 | BranchChunk getChunkFromMemoryCache(World world, int chunkX, int chunkZ); 13 | 14 | BranchChunk fromChunk(World world, int chunkX, int chunkZ, BranchNBT nbt, boolean integralHeightmap); 15 | 16 | BranchChunkLight fromLight(World world, BranchNBT nbt); 17 | 18 | BranchChunkLight fromLight(World world); 19 | 20 | BranchChunk fromChunk(World world, Chunk chunk); 21 | 22 | BranchChunk.Status fromStatus(BranchNBT nbt); 23 | 24 | void injectPlayer(Player player); 25 | } 26 | -------------------------------------------------------------------------------- /branch_1_15/src/main/java/xuan/cat/fartherviewdistance/api/branch/BranchNBT.java: -------------------------------------------------------------------------------- 1 | package xuan.cat.fartherviewdistance.api.branch; 2 | 3 | public interface BranchNBT { 4 | } 5 | -------------------------------------------------------------------------------- /branch_1_15/src/main/java/xuan/cat/fartherviewdistance/api/branch/BranchPacket.java: -------------------------------------------------------------------------------- 1 | package xuan.cat.fartherviewdistance.api.branch; 2 | 3 | import org.bukkit.entity.Player; 4 | 5 | import java.util.function.Consumer; 6 | 7 | public interface BranchPacket { 8 | void sendViewDistance(Player player, int viewDistance); 9 | 10 | void sendUnloadChunk(Player player, int chunkX, int chunkZ); 11 | 12 | Consumer sendChunkAndLight(BranchChunk chunk, BranchChunkLight light, boolean needTile, Consumer consumeTraffic); 13 | 14 | void sendKeepAlive(Player player, long id); 15 | } 16 | -------------------------------------------------------------------------------- /branch_1_15/src/main/java/xuan/cat/fartherviewdistance/api/branch/packet/PacketEvent.java: -------------------------------------------------------------------------------- 1 | package xuan.cat.fartherviewdistance.api.branch.packet; 2 | 3 | import org.bukkit.Bukkit; 4 | import org.bukkit.entity.Player; 5 | import org.bukkit.event.Cancellable; 6 | import org.bukkit.event.Event; 7 | 8 | public abstract class PacketEvent extends Event implements Cancellable { 9 | private final Player player; 10 | private boolean cancel = false; 11 | 12 | public PacketEvent(Player player) { 13 | super(!Bukkit.isPrimaryThread()); 14 | this.player = player; 15 | } 16 | 17 | public final boolean isCancelled() { 18 | return cancel; 19 | } 20 | public final void setCancelled(boolean cancel) { 21 | this.cancel = cancel; 22 | } 23 | 24 | public final Player getPlayer() { 25 | return player; 26 | } 27 | } -------------------------------------------------------------------------------- /branch_1_15/src/main/java/xuan/cat/fartherviewdistance/api/branch/packet/PacketKeepAliveEvent.java: -------------------------------------------------------------------------------- 1 | package xuan.cat.fartherviewdistance.api.branch.packet; 2 | 3 | import org.bukkit.entity.Player; 4 | import org.bukkit.event.HandlerList; 5 | 6 | public final class PacketKeepAliveEvent extends PacketEvent { 7 | private static final HandlerList handlers = new HandlerList(); 8 | public HandlerList getHandlers() { 9 | return handlers; 10 | } 11 | public static HandlerList getHandlerList() { 12 | return handlers; 13 | } 14 | 15 | private final long id; 16 | 17 | public PacketKeepAliveEvent(Player player, long id) { 18 | super(player); 19 | this.id = id; 20 | } 21 | 22 | public long getId() { 23 | return id; 24 | } 25 | } -------------------------------------------------------------------------------- /branch_1_15/src/main/java/xuan/cat/fartherviewdistance/api/branch/packet/PacketMapChunkEvent.java: -------------------------------------------------------------------------------- 1 | package xuan.cat.fartherviewdistance.api.branch.packet; 2 | 3 | import org.bukkit.entity.Player; 4 | import org.bukkit.event.HandlerList; 5 | 6 | public final class PacketMapChunkEvent extends PacketEvent { 7 | private static final HandlerList handlers = new HandlerList(); 8 | public HandlerList getHandlers() { 9 | return handlers; 10 | } 11 | public static HandlerList getHandlerList() { 12 | return handlers; 13 | } 14 | 15 | private final int chunkX; 16 | private final int chunkZ; 17 | 18 | public PacketMapChunkEvent(Player player, int chunkX, int chunkZ) { 19 | super(player); 20 | this.chunkX = chunkX; 21 | this.chunkZ = chunkZ; 22 | } 23 | 24 | public int getChunkX() { 25 | return chunkX; 26 | } 27 | public int getChunkZ() { 28 | return chunkZ; 29 | } 30 | } -------------------------------------------------------------------------------- /branch_1_15/src/main/java/xuan/cat/fartherviewdistance/api/branch/packet/PacketUnloadChunkEvent.java: -------------------------------------------------------------------------------- 1 | package xuan.cat.fartherviewdistance.api.branch.packet; 2 | 3 | import org.bukkit.entity.Player; 4 | import org.bukkit.event.HandlerList; 5 | 6 | public final class PacketUnloadChunkEvent extends PacketEvent { 7 | private static final HandlerList handlers = new HandlerList(); 8 | public HandlerList getHandlers() { 9 | return handlers; 10 | } 11 | public static HandlerList getHandlerList() { 12 | return handlers; 13 | } 14 | 15 | private final int chunkX; 16 | private final int chunkZ; 17 | 18 | public PacketUnloadChunkEvent(Player player, int chunkX, int chunkZ) { 19 | super(player); 20 | this.chunkX = chunkX; 21 | this.chunkZ = chunkZ; 22 | } 23 | 24 | public int getChunkX() { 25 | return chunkX; 26 | } 27 | public int getChunkZ() { 28 | return chunkZ; 29 | } 30 | } -------------------------------------------------------------------------------- /branch_1_15/src/main/java/xuan/cat/fartherviewdistance/api/branch/packet/PacketViewDistanceEvent.java: -------------------------------------------------------------------------------- 1 | package xuan.cat.fartherviewdistance.api.branch.packet; 2 | 3 | import org.bukkit.entity.Player; 4 | import org.bukkit.event.HandlerList; 5 | 6 | public final class PacketViewDistanceEvent extends PacketEvent { 7 | private static final HandlerList handlers = new HandlerList(); 8 | public HandlerList getHandlers() { 9 | return handlers; 10 | } 11 | public static HandlerList getHandlerList() { 12 | return handlers; 13 | } 14 | 15 | private final int viewDistance; 16 | 17 | public PacketViewDistanceEvent(Player player, int viewDistance) { 18 | super(player); 19 | this.viewDistance = viewDistance; 20 | } 21 | 22 | public int getViewDistance() { 23 | return viewDistance; 24 | } 25 | 26 | } -------------------------------------------------------------------------------- /branch_1_15/src/main/java/xuan/cat/fartherviewdistance/code/branch/v15/Branch_15_ChunkLight.java: -------------------------------------------------------------------------------- 1 | package xuan.cat.fartherviewdistance.code.branch.v15; 2 | 3 | import net.minecraft.server.v1_15_R1.WorldServer; 4 | import org.bukkit.World; 5 | import org.bukkit.craftbukkit.v1_15_R1.CraftWorld; 6 | import xuan.cat.fartherviewdistance.api.branch.BranchChunkLight; 7 | 8 | import java.util.Arrays; 9 | 10 | public final class Branch_15_ChunkLight implements BranchChunkLight { 11 | public static final byte[] EMPTY = new byte[0]; 12 | 13 | private final WorldServer worldServer; 14 | private final byte[][] blockLights; 15 | private final byte[][] skyLights; 16 | 17 | public Branch_15_ChunkLight(World world) { 18 | this(((CraftWorld) world).getHandle()); 19 | } 20 | public Branch_15_ChunkLight(WorldServer worldServer) { 21 | this(worldServer, new byte[18][], new byte[18][]); 22 | } 23 | public Branch_15_ChunkLight(WorldServer worldServer, byte[][] blockLights, byte[][] skyLights) { 24 | this.worldServer = worldServer; 25 | this.blockLights = blockLights; 26 | this.skyLights = skyLights; 27 | Arrays.fill(blockLights, EMPTY); 28 | Arrays.fill(skyLights, EMPTY); 29 | } 30 | 31 | public WorldServer getWorldServer() { 32 | return worldServer; 33 | } 34 | 35 | public int getArrayLength() { 36 | return blockLights.length; 37 | } 38 | 39 | public static int indexFromSectionY(WorldServer worldServer, int sectionY) { 40 | return sectionY + 1; 41 | } 42 | 43 | public void setBlockLight(int sectionY, byte[] blockLight) { 44 | blockLights[indexFromSectionY(worldServer, sectionY)] = blockLight; 45 | } 46 | public void setSkyLight(int sectionY, byte[] skyLight) { 47 | skyLights[indexFromSectionY(worldServer, sectionY)] = skyLight; 48 | } 49 | 50 | public byte[] getBlockLight(int sectionY) { 51 | return blockLights[indexFromSectionY(worldServer, sectionY)]; 52 | } 53 | public byte[] getSkyLight(int sectionY) { 54 | return skyLights[indexFromSectionY(worldServer, sectionY)]; 55 | } 56 | 57 | public byte[][] getBlockLights() { 58 | return blockLights; 59 | } 60 | public byte[][] getSkyLights() { 61 | return skyLights; 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /branch_1_15/src/main/java/xuan/cat/fartherviewdistance/code/branch/v15/Branch_15_NBT.java: -------------------------------------------------------------------------------- 1 | package xuan.cat.fartherviewdistance.code.branch.v15; 2 | 3 | import net.minecraft.server.v1_15_R1.NBTTagCompound; 4 | import xuan.cat.fartherviewdistance.api.branch.BranchNBT; 5 | 6 | public final class Branch_15_NBT implements BranchNBT { 7 | 8 | protected NBTTagCompound tag; 9 | 10 | public Branch_15_NBT() { 11 | this.tag = new NBTTagCompound(); 12 | } 13 | 14 | public Branch_15_NBT(NBTTagCompound tag) { 15 | this.tag = tag; 16 | } 17 | 18 | 19 | public NBTTagCompound getNMSTag() { 20 | return tag; 21 | } 22 | 23 | @Override 24 | public String toString() { 25 | return tag.toString(); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /branch_1_15/src/main/java/xuan/cat/fartherviewdistance/code/branch/v15/Branch_15_Packet.java: -------------------------------------------------------------------------------- 1 | package xuan.cat.fartherviewdistance.code.branch.v15; 2 | 3 | import io.netty.buffer.Unpooled; 4 | import net.minecraft.server.v1_15_R1.*; 5 | import org.bukkit.craftbukkit.v1_15_R1.entity.CraftPlayer; 6 | import org.bukkit.entity.Player; 7 | import xuan.cat.fartherviewdistance.api.branch.BranchChunk; 8 | import xuan.cat.fartherviewdistance.api.branch.BranchChunkLight; 9 | import xuan.cat.fartherviewdistance.api.branch.BranchPacket; 10 | 11 | import java.util.function.Consumer; 12 | 13 | public final class Branch_15_Packet implements BranchPacket { 14 | private final Branch_15_PacketHandleChunk handleChunk = new Branch_15_PacketHandleChunk(); 15 | private final Branch_15_PacketHandleLightUpdate handleLightUpdate = new Branch_15_PacketHandleLightUpdate(); 16 | 17 | public void sendPacket(Player player, Packet packet) { 18 | try { 19 | PlayerConnection container = ((CraftPlayer) player).getHandle().playerConnection; 20 | container.sendPacket(packet); 21 | } catch (IllegalArgumentException ignored) { 22 | } 23 | } 24 | 25 | public void sendViewDistance(Player player, int viewDistance) { 26 | sendPacket(player, new PacketPlayOutViewDistance(viewDistance)); 27 | } 28 | 29 | public void sendUnloadChunk(Player player, int chunkX, int chunkZ) { 30 | sendPacket(player, new PacketPlayOutUnloadChunk(chunkX, chunkZ)); 31 | } 32 | 33 | public Consumer sendChunkAndLight(BranchChunk chunk, BranchChunkLight light, boolean needTile, Consumer consumeTraffic) { 34 | PacketPlayOutMapChunk packetChunk = handleChunk.createMapChunkPacket(chunk.getChunk(), 65535, needTile); 35 | PacketPlayOutLightUpdate packetLight = handleLightUpdate.createLightUpdatePacket(chunk.getX(), chunk.getZ(), ((Branch_15_ChunkLight) light)); 36 | try { 37 | // 適用於 paper 38 | packetChunk.setReady(true); 39 | } catch (NoSuchMethodError noSuchMethodError) { 40 | // 適用於 spigot (不推薦) 41 | } 42 | calculateConsume(packetChunk, consumeTraffic); 43 | calculateConsume(packetLight, consumeTraffic); 44 | return (player) -> { 45 | sendPacket(player, packetLight); 46 | sendPacket(player, packetChunk); 47 | }; 48 | } 49 | 50 | public void sendKeepAlive(Player player, long id) { 51 | sendPacket(player, new PacketPlayOutKeepAlive(id)); 52 | } 53 | 54 | private void calculateConsume(Packet packet, Consumer consumeTraffic) { 55 | PacketDataSerializer serializer = new PacketDataSerializer(Unpooled.buffer().writerIndex(0)); 56 | try { 57 | packet.b(serializer); 58 | } catch (Exception ignored) { 59 | } 60 | consumeTraffic.accept(serializer.readableBytes()); 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /branch_1_15/src/main/java/xuan/cat/fartherviewdistance/code/branch/v15/Branch_15_ProxyPlayerConnection.java: -------------------------------------------------------------------------------- 1 | package xuan.cat.fartherviewdistance.code.branch.v15; 2 | 3 | import net.minecraft.server.v1_15_R1.*; 4 | import org.bukkit.Bukkit; 5 | import org.bukkit.entity.Player; 6 | import xuan.cat.fartherviewdistance.api.branch.packet.PacketKeepAliveEvent; 7 | import xuan.cat.fartherviewdistance.api.branch.packet.PacketMapChunkEvent; 8 | import xuan.cat.fartherviewdistance.api.branch.packet.PacketUnloadChunkEvent; 9 | import xuan.cat.fartherviewdistance.api.branch.packet.PacketViewDistanceEvent; 10 | 11 | import java.lang.reflect.Field; 12 | 13 | public final class Branch_15_ProxyPlayerConnection { 14 | public static boolean read(Player player, Packet packet) { 15 | if (packet instanceof PacketPlayInKeepAlive) { 16 | PacketKeepAliveEvent event = new PacketKeepAliveEvent(player, ((PacketPlayInKeepAlive) packet).b()); 17 | Bukkit.getPluginManager().callEvent(event); 18 | return !event.isCancelled(); 19 | } else { 20 | return true; 21 | } 22 | } 23 | 24 | 25 | private static Field field_PacketPlayOutUnloadChunk_chunkX; 26 | private static Field field_PacketPlayOutUnloadChunk_chunkZ; 27 | private static Field field_PacketPlayOutViewDistance_distance; 28 | private static Field field_PacketPlayOutMapChunk_chunkX; 29 | private static Field field_PacketPlayOutMapChunk_chunkZ; 30 | static { 31 | try { 32 | field_PacketPlayOutUnloadChunk_chunkX = PacketPlayOutUnloadChunk.class.getDeclaredField("a"); 33 | field_PacketPlayOutUnloadChunk_chunkZ = PacketPlayOutUnloadChunk.class.getDeclaredField("b"); 34 | field_PacketPlayOutViewDistance_distance = PacketPlayOutViewDistance.class.getDeclaredField("a"); 35 | field_PacketPlayOutMapChunk_chunkX = PacketPlayOutMapChunk.class.getDeclaredField("a"); 36 | field_PacketPlayOutMapChunk_chunkZ = PacketPlayOutMapChunk.class.getDeclaredField("b"); 37 | field_PacketPlayOutUnloadChunk_chunkX.setAccessible(true); 38 | field_PacketPlayOutUnloadChunk_chunkZ.setAccessible(true); 39 | field_PacketPlayOutViewDistance_distance.setAccessible(true); 40 | field_PacketPlayOutMapChunk_chunkX.setAccessible(true); 41 | field_PacketPlayOutMapChunk_chunkZ.setAccessible(true); 42 | } catch (Exception ex) { 43 | ex.printStackTrace(); 44 | } 45 | } 46 | public static boolean write(Player player, Packet packet) { 47 | try { 48 | if (packet instanceof PacketPlayOutUnloadChunk) { 49 | PacketUnloadChunkEvent event = new PacketUnloadChunkEvent(player, field_PacketPlayOutUnloadChunk_chunkX.getInt(packet), field_PacketPlayOutUnloadChunk_chunkZ.getInt(packet)); 50 | Bukkit.getPluginManager().callEvent(event); 51 | return !event.isCancelled(); 52 | } else if (packet instanceof PacketPlayOutViewDistance) { 53 | PacketViewDistanceEvent event = new PacketViewDistanceEvent(player, field_PacketPlayOutViewDistance_distance.getInt(packet)); 54 | Bukkit.getPluginManager().callEvent(event); 55 | return !event.isCancelled(); 56 | } else if (packet instanceof PacketPlayOutMapChunk) { 57 | PacketMapChunkEvent event = new PacketMapChunkEvent(player, field_PacketPlayOutMapChunk_chunkX.getInt(packet), field_PacketPlayOutMapChunk_chunkZ.getInt(packet)); 58 | Bukkit.getPluginManager().callEvent(event); 59 | return !event.isCancelled(); 60 | } else { 61 | return true; 62 | } 63 | } catch (Exception ex) { 64 | ex.printStackTrace(); 65 | return true; 66 | } 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /branch_1_16/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | FartherViewDistance 8 | branch_1_16 9 | r3 10 | 11 | 12 | 1.8 13 | UTF-8 14 | 15 | 16 | 17 | clean package 18 | 19 | 20 | org.apache.maven.plugins 21 | maven-compiler-plugin 22 | 3.8.1 23 | 24 | 1.8 25 | 1.8 26 | 27 | 28 | 29 | 30 | 31 | src/main/resources 32 | true 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | dmulloy2-repo 41 | https://repo.dmulloy2.net/repository/public/ 42 | 43 | 44 | 45 | minecraft_environment 46 | https://xuancat.app:8443/repository/minecraft_environment/ 47 | 48 | 49 | 50 | 51 | 52 | 53 | paper 54 | 1.16.5 55 | 794 56 | 57 | 58 | paper 59 | 1.16.5 60 | 794 61 | patched 62 | 63 | 64 | -------------------------------------------------------------------------------- /branch_1_16/src/main/java/xuan/cat/fartherviewdistance/api/branch/BranchChunk.java: -------------------------------------------------------------------------------- 1 | package xuan.cat.fartherviewdistance.api.branch; 2 | 3 | import org.bukkit.Chunk; 4 | import org.bukkit.Material; 5 | import org.bukkit.World; 6 | import org.bukkit.block.Biome; 7 | import org.bukkit.block.data.BlockData; 8 | import org.bukkit.util.Vector; 9 | 10 | import java.util.List; 11 | import java.util.Map; 12 | 13 | public interface BranchChunk { 14 | BranchNBT toNBT(BranchChunkLight light, List asyncRunnable); 15 | 16 | Chunk getChunk(); 17 | 18 | World getWorld(); 19 | 20 | boolean equalsBlockData(int x, int y, int z, BlockData blockData); 21 | BlockData getBlockData(int x, int y, int z); 22 | void setBlockData(int x, int y, int z, BlockData blockData); 23 | Map getBlockDataMap(); 24 | 25 | Material getMaterial(int x, int y, int z); 26 | void setMaterial(int x, int y, int z, Material material); 27 | 28 | int getX(); 29 | int getZ(); 30 | 31 | Status getStatus(); 32 | 33 | void replaceAllMaterial(BlockData[] target, BlockData to); 34 | 35 | @Deprecated 36 | Biome getBiome(int x, int z); 37 | Biome getBiome(int x, int y, int z); 38 | @Deprecated 39 | void setBiome(int x, int z, Biome biome); 40 | void setBiome(int x, int y, int z, Biome biome); 41 | 42 | boolean hasFluid(int x, int y, int z); 43 | boolean isAir(int x, int y, int z); 44 | 45 | int getHighestY(int x, int z); 46 | 47 | /** 48 | * 區塊狀態 49 | */ 50 | enum Status { 51 | EMPTY (0), 52 | STRUCTURE_STARTS (1), 53 | STRUCTURE_REFERENCES(2), 54 | BIOMES (3), 55 | NOISE (4), 56 | SURFACE (5), 57 | CARVERS (6), 58 | LIQUID_CARVERS (7), 59 | FEATURES (8), 60 | LIGHT (9), 61 | SPAWN (10), 62 | HEIGHTMAPS (11), 63 | FULL (12); 64 | 65 | private final int sequence; 66 | Status(int sequence) { 67 | this.sequence = sequence; 68 | } 69 | 70 | public boolean isAbove(Status status) { 71 | return this.sequence >= status.sequence; 72 | } 73 | public boolean isUnder(Status status) { 74 | return this.sequence <= status.sequence; 75 | } 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /branch_1_16/src/main/java/xuan/cat/fartherviewdistance/api/branch/BranchChunkLight.java: -------------------------------------------------------------------------------- 1 | package xuan.cat.fartherviewdistance.api.branch; 2 | 3 | public interface BranchChunkLight { 4 | } 5 | -------------------------------------------------------------------------------- /branch_1_16/src/main/java/xuan/cat/fartherviewdistance/api/branch/BranchMinecraft.java: -------------------------------------------------------------------------------- 1 | package xuan.cat.fartherviewdistance.api.branch; 2 | 3 | import org.bukkit.Chunk; 4 | import org.bukkit.World; 5 | import org.bukkit.entity.Player; 6 | 7 | import java.io.IOException; 8 | 9 | public interface BranchMinecraft { 10 | BranchNBT getChunkNBTFromDisk(World world, int chunkX, int chunkZ) throws IOException; 11 | 12 | BranchChunk getChunkFromMemoryCache(World world, int chunkX, int chunkZ); 13 | 14 | BranchChunk fromChunk(World world, int chunkX, int chunkZ, BranchNBT nbt, boolean integralHeightmap); 15 | 16 | BranchChunkLight fromLight(World world, BranchNBT nbt); 17 | 18 | BranchChunkLight fromLight(World world); 19 | 20 | BranchChunk fromChunk(World world, Chunk chunk); 21 | 22 | BranchChunk.Status fromStatus(BranchNBT nbt); 23 | 24 | void injectPlayer(Player player); 25 | } 26 | -------------------------------------------------------------------------------- /branch_1_16/src/main/java/xuan/cat/fartherviewdistance/api/branch/BranchNBT.java: -------------------------------------------------------------------------------- 1 | package xuan.cat.fartherviewdistance.api.branch; 2 | 3 | public interface BranchNBT { 4 | } 5 | -------------------------------------------------------------------------------- /branch_1_16/src/main/java/xuan/cat/fartherviewdistance/api/branch/BranchPacket.java: -------------------------------------------------------------------------------- 1 | package xuan.cat.fartherviewdistance.api.branch; 2 | 3 | import org.bukkit.entity.Player; 4 | 5 | import java.util.function.Consumer; 6 | 7 | public interface BranchPacket { 8 | void sendViewDistance(Player player, int viewDistance); 9 | 10 | void sendUnloadChunk(Player player, int chunkX, int chunkZ); 11 | 12 | Consumer sendChunkAndLight(BranchChunk chunk, BranchChunkLight light, boolean needTile, Consumer consumeTraffic); 13 | 14 | void sendKeepAlive(Player player, long id); 15 | } 16 | -------------------------------------------------------------------------------- /branch_1_16/src/main/java/xuan/cat/fartherviewdistance/api/branch/packet/PacketEvent.java: -------------------------------------------------------------------------------- 1 | package xuan.cat.fartherviewdistance.api.branch.packet; 2 | 3 | import org.bukkit.Bukkit; 4 | import org.bukkit.entity.Player; 5 | import org.bukkit.event.Cancellable; 6 | import org.bukkit.event.Event; 7 | 8 | public abstract class PacketEvent extends Event implements Cancellable { 9 | private final Player player; 10 | private boolean cancel = false; 11 | 12 | public PacketEvent(Player player) { 13 | super(!Bukkit.isPrimaryThread()); 14 | this.player = player; 15 | } 16 | 17 | public final boolean isCancelled() { 18 | return cancel; 19 | } 20 | public final void setCancelled(boolean cancel) { 21 | this.cancel = cancel; 22 | } 23 | 24 | public final Player getPlayer() { 25 | return player; 26 | } 27 | } -------------------------------------------------------------------------------- /branch_1_16/src/main/java/xuan/cat/fartherviewdistance/api/branch/packet/PacketKeepAliveEvent.java: -------------------------------------------------------------------------------- 1 | package xuan.cat.fartherviewdistance.api.branch.packet; 2 | 3 | import org.bukkit.entity.Player; 4 | import org.bukkit.event.HandlerList; 5 | 6 | public final class PacketKeepAliveEvent extends PacketEvent { 7 | private static final HandlerList handlers = new HandlerList(); 8 | public HandlerList getHandlers() { 9 | return handlers; 10 | } 11 | public static HandlerList getHandlerList() { 12 | return handlers; 13 | } 14 | 15 | private final long id; 16 | 17 | public PacketKeepAliveEvent(Player player, long id) { 18 | super(player); 19 | this.id = id; 20 | } 21 | 22 | public long getId() { 23 | return id; 24 | } 25 | } -------------------------------------------------------------------------------- /branch_1_16/src/main/java/xuan/cat/fartherviewdistance/api/branch/packet/PacketMapChunkEvent.java: -------------------------------------------------------------------------------- 1 | package xuan.cat.fartherviewdistance.api.branch.packet; 2 | 3 | import org.bukkit.entity.Player; 4 | import org.bukkit.event.HandlerList; 5 | 6 | public final class PacketMapChunkEvent extends PacketEvent { 7 | private static final HandlerList handlers = new HandlerList(); 8 | public HandlerList getHandlers() { 9 | return handlers; 10 | } 11 | public static HandlerList getHandlerList() { 12 | return handlers; 13 | } 14 | 15 | private final int chunkX; 16 | private final int chunkZ; 17 | 18 | public PacketMapChunkEvent(Player player, int chunkX, int chunkZ) { 19 | super(player); 20 | this.chunkX = chunkX; 21 | this.chunkZ = chunkZ; 22 | } 23 | 24 | public int getChunkX() { 25 | return chunkX; 26 | } 27 | public int getChunkZ() { 28 | return chunkZ; 29 | } 30 | } -------------------------------------------------------------------------------- /branch_1_16/src/main/java/xuan/cat/fartherviewdistance/api/branch/packet/PacketUnloadChunkEvent.java: -------------------------------------------------------------------------------- 1 | package xuan.cat.fartherviewdistance.api.branch.packet; 2 | 3 | import org.bukkit.entity.Player; 4 | import org.bukkit.event.HandlerList; 5 | 6 | public final class PacketUnloadChunkEvent extends PacketEvent { 7 | private static final HandlerList handlers = new HandlerList(); 8 | public HandlerList getHandlers() { 9 | return handlers; 10 | } 11 | public static HandlerList getHandlerList() { 12 | return handlers; 13 | } 14 | 15 | private final int chunkX; 16 | private final int chunkZ; 17 | 18 | public PacketUnloadChunkEvent(Player player, int chunkX, int chunkZ) { 19 | super(player); 20 | this.chunkX = chunkX; 21 | this.chunkZ = chunkZ; 22 | } 23 | 24 | public int getChunkX() { 25 | return chunkX; 26 | } 27 | public int getChunkZ() { 28 | return chunkZ; 29 | } 30 | } -------------------------------------------------------------------------------- /branch_1_16/src/main/java/xuan/cat/fartherviewdistance/api/branch/packet/PacketViewDistanceEvent.java: -------------------------------------------------------------------------------- 1 | package xuan.cat.fartherviewdistance.api.branch.packet; 2 | 3 | import org.bukkit.entity.Player; 4 | import org.bukkit.event.HandlerList; 5 | 6 | public final class PacketViewDistanceEvent extends PacketEvent { 7 | private static final HandlerList handlers = new HandlerList(); 8 | public HandlerList getHandlers() { 9 | return handlers; 10 | } 11 | public static HandlerList getHandlerList() { 12 | return handlers; 13 | } 14 | 15 | private final int viewDistance; 16 | 17 | public PacketViewDistanceEvent(Player player, int viewDistance) { 18 | super(player); 19 | this.viewDistance = viewDistance; 20 | } 21 | 22 | public int getViewDistance() { 23 | return viewDistance; 24 | } 25 | 26 | } -------------------------------------------------------------------------------- /branch_1_16/src/main/java/xuan/cat/fartherviewdistance/code/branch/v16/Branch_16_ChunkLight.java: -------------------------------------------------------------------------------- 1 | package xuan.cat.fartherviewdistance.code.branch.v16; 2 | 3 | import net.minecraft.server.v1_16_R3.WorldServer; 4 | import org.bukkit.World; 5 | import org.bukkit.craftbukkit.v1_16_R3.CraftWorld; 6 | import xuan.cat.fartherviewdistance.api.branch.BranchChunkLight; 7 | 8 | import java.util.Arrays; 9 | 10 | public final class Branch_16_ChunkLight implements BranchChunkLight { 11 | public static final byte[] EMPTY = new byte[0]; 12 | 13 | private final WorldServer worldServer; 14 | private final byte[][] blockLights; 15 | private final byte[][] skyLights; 16 | 17 | public Branch_16_ChunkLight(World world) { 18 | this(((CraftWorld) world).getHandle()); 19 | } 20 | public Branch_16_ChunkLight(WorldServer worldServer) { 21 | this(worldServer, new byte[18][], new byte[18][]); 22 | } 23 | public Branch_16_ChunkLight(WorldServer worldServer, byte[][] blockLights, byte[][] skyLights) { 24 | this.worldServer = worldServer; 25 | this.blockLights = blockLights; 26 | this.skyLights = skyLights; 27 | Arrays.fill(blockLights, EMPTY); 28 | Arrays.fill(skyLights, EMPTY); 29 | } 30 | 31 | public WorldServer getWorldServer() { 32 | return worldServer; 33 | } 34 | 35 | public int getArrayLength() { 36 | return blockLights.length; 37 | } 38 | 39 | public static int indexFromSectionY(WorldServer worldServer, int sectionY) { 40 | return sectionY + 1; 41 | } 42 | 43 | public void setBlockLight(int sectionY, byte[] blockLight) { 44 | blockLights[indexFromSectionY(worldServer, sectionY)] = blockLight; 45 | } 46 | public void setSkyLight(int sectionY, byte[] skyLight) { 47 | skyLights[indexFromSectionY(worldServer, sectionY)] = skyLight; 48 | } 49 | 50 | public byte[] getBlockLight(int sectionY) { 51 | return blockLights[indexFromSectionY(worldServer, sectionY)]; 52 | } 53 | public byte[] getSkyLight(int sectionY) { 54 | return skyLights[indexFromSectionY(worldServer, sectionY)]; 55 | } 56 | 57 | public byte[][] getBlockLights() { 58 | return blockLights; 59 | } 60 | public byte[][] getSkyLights() { 61 | return skyLights; 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /branch_1_16/src/main/java/xuan/cat/fartherviewdistance/code/branch/v16/Branch_16_NBT.java: -------------------------------------------------------------------------------- 1 | package xuan.cat.fartherviewdistance.code.branch.v16; 2 | 3 | import net.minecraft.server.v1_16_R3.NBTTagCompound; 4 | import xuan.cat.fartherviewdistance.api.branch.BranchNBT; 5 | 6 | public final class Branch_16_NBT implements BranchNBT { 7 | protected NBTTagCompound tag; 8 | 9 | 10 | public Branch_16_NBT() { 11 | this.tag = new NBTTagCompound(); 12 | } 13 | 14 | public Branch_16_NBT(NBTTagCompound tag) { 15 | this.tag = tag; 16 | } 17 | 18 | 19 | public NBTTagCompound getNMSTag() { 20 | return tag; 21 | } 22 | 23 | @Override 24 | public String toString() { 25 | return tag.toString(); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /branch_1_16/src/main/java/xuan/cat/fartherviewdistance/code/branch/v16/Branch_16_Packet.java: -------------------------------------------------------------------------------- 1 | package xuan.cat.fartherviewdistance.code.branch.v16; 2 | 3 | import io.netty.buffer.Unpooled; 4 | import net.minecraft.server.v1_16_R3.*; 5 | import org.bukkit.craftbukkit.v1_16_R3.entity.CraftPlayer; 6 | import org.bukkit.entity.Player; 7 | import xuan.cat.fartherviewdistance.api.branch.BranchChunk; 8 | import xuan.cat.fartherviewdistance.api.branch.BranchChunkLight; 9 | import xuan.cat.fartherviewdistance.api.branch.BranchPacket; 10 | 11 | import java.util.function.Consumer; 12 | 13 | public final class Branch_16_Packet implements BranchPacket { 14 | private final Branch_16_PacketHandleChunk handleChunk = new Branch_16_PacketHandleChunk(); 15 | private final Branch_16_PacketHandleLightUpdate handleLightUpdate = new Branch_16_PacketHandleLightUpdate(); 16 | 17 | public void sendPacket(Player player, Packet packet) { 18 | try { 19 | PlayerConnection container = ((CraftPlayer) player).getHandle().playerConnection; 20 | container.sendPacket(packet); 21 | } catch (IllegalArgumentException ignored) { 22 | } 23 | } 24 | 25 | public void sendViewDistance(Player player, int viewDistance) { 26 | sendPacket(player, new PacketPlayOutViewDistance(viewDistance)); 27 | } 28 | 29 | public void sendUnloadChunk(Player player, int chunkX, int chunkZ) { 30 | sendPacket(player, new PacketPlayOutUnloadChunk(chunkX, chunkZ)); 31 | } 32 | 33 | public Consumer sendChunkAndLight(BranchChunk chunk, BranchChunkLight light, boolean needTile, Consumer consumeTraffic) { 34 | PacketPlayOutMapChunk packetChunk = handleChunk.createMapChunkPacket(chunk.getChunk(), 65535, needTile); 35 | PacketPlayOutLightUpdate packetLight = handleLightUpdate.createLightUpdatePacket(chunk.getX(), chunk.getZ(), (Branch_16_ChunkLight) light); 36 | try { 37 | // 適用於 paper 38 | packetChunk.setReady(true); 39 | } catch (NoSuchMethodError noSuchMethodError) { 40 | // 適用於 spigot (不推薦) 41 | } 42 | calculateConsume(packetChunk, consumeTraffic); 43 | calculateConsume(packetLight, consumeTraffic); 44 | return (player) -> { 45 | sendPacket(player, packetLight); 46 | sendPacket(player, packetChunk); 47 | }; 48 | } 49 | 50 | public void sendKeepAlive(Player player, long id) { 51 | sendPacket(player, new PacketPlayOutKeepAlive(id)); 52 | } 53 | 54 | private void calculateConsume(Packet packet, Consumer consumeTraffic) { 55 | PacketDataSerializer serializer = new PacketDataSerializer(Unpooled.buffer().writerIndex(0)); 56 | try { 57 | packet.b(serializer); 58 | } catch (Exception ignored) { 59 | } 60 | consumeTraffic.accept(serializer.readableBytes()); 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /branch_1_16/src/main/java/xuan/cat/fartherviewdistance/code/branch/v16/Branch_16_ProxyPlayerConnection.java: -------------------------------------------------------------------------------- 1 | package xuan.cat.fartherviewdistance.code.branch.v16; 2 | 3 | import net.minecraft.server.v1_16_R3.*; 4 | import org.bukkit.Bukkit; 5 | import org.bukkit.entity.Player; 6 | import xuan.cat.fartherviewdistance.api.branch.packet.PacketKeepAliveEvent; 7 | import xuan.cat.fartherviewdistance.api.branch.packet.PacketMapChunkEvent; 8 | import xuan.cat.fartherviewdistance.api.branch.packet.PacketUnloadChunkEvent; 9 | import xuan.cat.fartherviewdistance.api.branch.packet.PacketViewDistanceEvent; 10 | 11 | import java.lang.reflect.Field; 12 | 13 | public final class Branch_16_ProxyPlayerConnection { 14 | public static boolean read(Player player, Packet packet) { 15 | if (packet instanceof PacketPlayInKeepAlive) { 16 | PacketKeepAliveEvent event = new PacketKeepAliveEvent(player, ((PacketPlayInKeepAlive) packet).b()); 17 | Bukkit.getPluginManager().callEvent(event); 18 | return !event.isCancelled(); 19 | } else { 20 | return true; 21 | } 22 | } 23 | 24 | 25 | private static Field field_PacketPlayOutUnloadChunk_chunkX; 26 | private static Field field_PacketPlayOutUnloadChunk_chunkZ; 27 | private static Field field_PacketPlayOutViewDistance_distance; 28 | private static Field field_PacketPlayOutMapChunk_chunkX; 29 | private static Field field_PacketPlayOutMapChunk_chunkZ; 30 | static { 31 | try { 32 | field_PacketPlayOutUnloadChunk_chunkX = PacketPlayOutUnloadChunk.class.getDeclaredField("a"); 33 | field_PacketPlayOutUnloadChunk_chunkZ = PacketPlayOutUnloadChunk.class.getDeclaredField("b"); 34 | field_PacketPlayOutViewDistance_distance = PacketPlayOutViewDistance.class.getDeclaredField("a"); 35 | field_PacketPlayOutMapChunk_chunkX = PacketPlayOutMapChunk.class.getDeclaredField("a"); 36 | field_PacketPlayOutMapChunk_chunkZ = PacketPlayOutMapChunk.class.getDeclaredField("b"); 37 | field_PacketPlayOutUnloadChunk_chunkX.setAccessible(true); 38 | field_PacketPlayOutUnloadChunk_chunkZ.setAccessible(true); 39 | field_PacketPlayOutViewDistance_distance.setAccessible(true); 40 | field_PacketPlayOutMapChunk_chunkX.setAccessible(true); 41 | field_PacketPlayOutMapChunk_chunkZ.setAccessible(true); 42 | } catch (Exception ex) { 43 | ex.printStackTrace(); 44 | } 45 | } 46 | public static boolean write(Player player, Packet packet) { 47 | try { 48 | if (packet instanceof PacketPlayOutUnloadChunk) { 49 | PacketUnloadChunkEvent event = new PacketUnloadChunkEvent(player, field_PacketPlayOutUnloadChunk_chunkX.getInt(packet), field_PacketPlayOutUnloadChunk_chunkZ.getInt(packet)); 50 | Bukkit.getPluginManager().callEvent(event); 51 | return !event.isCancelled(); 52 | } else if (packet instanceof PacketPlayOutViewDistance) { 53 | PacketViewDistanceEvent event = new PacketViewDistanceEvent(player, field_PacketPlayOutViewDistance_distance.getInt(packet)); 54 | Bukkit.getPluginManager().callEvent(event); 55 | return !event.isCancelled(); 56 | } else if (packet instanceof PacketPlayOutMapChunk) { 57 | PacketMapChunkEvent event = new PacketMapChunkEvent(player, field_PacketPlayOutMapChunk_chunkX.getInt(packet), field_PacketPlayOutMapChunk_chunkZ.getInt(packet)); 58 | Bukkit.getPluginManager().callEvent(event); 59 | return !event.isCancelled(); 60 | } else { 61 | return true; 62 | } 63 | } catch (Exception ex) { 64 | ex.printStackTrace(); 65 | return true; 66 | } 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /branch_1_17/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | FartherViewDistance 8 | branch_1_17 9 | r1 10 | 11 | 12 | 1.8 13 | UTF-8 14 | 15 | 16 | 17 | clean package 18 | 19 | 20 | org.apache.maven.plugins 21 | maven-compiler-plugin 22 | 3.8.1 23 | 24 | 1.8 25 | 1.8 26 | 27 | 28 | 29 | 30 | 31 | src/main/resources 32 | true 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | dmulloy2-repo 41 | https://repo.dmulloy2.net/repository/public/ 42 | 43 | 44 | 45 | minecraft_environment 46 | https://xuancat.app:8443/repository/minecraft_environment/ 47 | 48 | 49 | 50 | 51 | 52 | 53 | paper 54 | 1.17.1 55 | 368 56 | 57 | 58 | paper 59 | 1.17.1 60 | 368 61 | patched 62 | 63 | 64 | -------------------------------------------------------------------------------- /branch_1_17/src/main/java/xuan/cat/fartherviewdistance/api/branch/BranchChunk.java: -------------------------------------------------------------------------------- 1 | package xuan.cat.fartherviewdistance.api.branch; 2 | 3 | import org.bukkit.Chunk; 4 | import org.bukkit.Material; 5 | import org.bukkit.World; 6 | import org.bukkit.block.Biome; 7 | import org.bukkit.block.data.BlockData; 8 | import org.bukkit.util.Vector; 9 | 10 | import java.util.List; 11 | import java.util.Map; 12 | 13 | public interface BranchChunk { 14 | BranchNBT toNBT(BranchChunkLight light, List asyncRunnable); 15 | 16 | Chunk getChunk(); 17 | 18 | World getWorld(); 19 | 20 | boolean equalsBlockData(int x, int y, int z, BlockData blockData); 21 | BlockData getBlockData(int x, int y, int z); 22 | void setBlockData(int x, int y, int z, BlockData blockData); 23 | Map getBlockDataMap(); 24 | 25 | Material getMaterial(int x, int y, int z); 26 | void setMaterial(int x, int y, int z, Material material); 27 | 28 | int getX(); 29 | int getZ(); 30 | 31 | Status getStatus(); 32 | 33 | void replaceAllMaterial(BlockData[] target, BlockData to); 34 | 35 | @Deprecated 36 | Biome getBiome(int x, int z); 37 | Biome getBiome(int x, int y, int z); 38 | @Deprecated 39 | void setBiome(int x, int z, Biome biome); 40 | void setBiome(int x, int y, int z, Biome biome); 41 | 42 | boolean hasFluid(int x, int y, int z); 43 | boolean isAir(int x, int y, int z); 44 | 45 | int getHighestY(int x, int z); 46 | 47 | /** 48 | * 區塊狀態 49 | */ 50 | enum Status { 51 | EMPTY (0), 52 | STRUCTURE_STARTS (1), 53 | STRUCTURE_REFERENCES(2), 54 | BIOMES (3), 55 | NOISE (4), 56 | SURFACE (5), 57 | CARVERS (6), 58 | LIQUID_CARVERS (7), 59 | FEATURES (8), 60 | LIGHT (9), 61 | SPAWN (10), 62 | HEIGHTMAPS (11), 63 | FULL (12); 64 | 65 | private final int sequence; 66 | Status(int sequence) { 67 | this.sequence = sequence; 68 | } 69 | 70 | public boolean isAbove(Status status) { 71 | return this.sequence >= status.sequence; 72 | } 73 | public boolean isUnder(Status status) { 74 | return this.sequence <= status.sequence; 75 | } 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /branch_1_17/src/main/java/xuan/cat/fartherviewdistance/api/branch/BranchChunkLight.java: -------------------------------------------------------------------------------- 1 | package xuan.cat.fartherviewdistance.api.branch; 2 | 3 | public interface BranchChunkLight { 4 | } 5 | -------------------------------------------------------------------------------- /branch_1_17/src/main/java/xuan/cat/fartherviewdistance/api/branch/BranchMinecraft.java: -------------------------------------------------------------------------------- 1 | package xuan.cat.fartherviewdistance.api.branch; 2 | 3 | import org.bukkit.Chunk; 4 | import org.bukkit.World; 5 | import org.bukkit.entity.Player; 6 | 7 | import java.io.IOException; 8 | 9 | public interface BranchMinecraft { 10 | BranchNBT getChunkNBTFromDisk(World world, int chunkX, int chunkZ) throws IOException; 11 | 12 | BranchChunk getChunkFromMemoryCache(World world, int chunkX, int chunkZ); 13 | 14 | BranchChunk fromChunk(World world, int chunkX, int chunkZ, BranchNBT nbt, boolean integralHeightmap); 15 | 16 | BranchChunkLight fromLight(World world, BranchNBT nbt); 17 | 18 | BranchChunkLight fromLight(World world); 19 | 20 | BranchChunk fromChunk(World world, Chunk chunk); 21 | 22 | BranchChunk.Status fromStatus(BranchNBT nbt); 23 | 24 | void injectPlayer(Player player); 25 | } 26 | -------------------------------------------------------------------------------- /branch_1_17/src/main/java/xuan/cat/fartherviewdistance/api/branch/BranchNBT.java: -------------------------------------------------------------------------------- 1 | package xuan.cat.fartherviewdistance.api.branch; 2 | 3 | public interface BranchNBT { 4 | } 5 | -------------------------------------------------------------------------------- /branch_1_17/src/main/java/xuan/cat/fartherviewdistance/api/branch/BranchPacket.java: -------------------------------------------------------------------------------- 1 | package xuan.cat.fartherviewdistance.api.branch; 2 | 3 | import org.bukkit.entity.Player; 4 | 5 | import java.util.function.Consumer; 6 | 7 | public interface BranchPacket { 8 | void sendViewDistance(Player player, int viewDistance); 9 | 10 | void sendUnloadChunk(Player player, int chunkX, int chunkZ); 11 | 12 | Consumer sendChunkAndLight(BranchChunk chunk, BranchChunkLight light, boolean needTile, Consumer consumeTraffic); 13 | 14 | void sendKeepAlive(Player player, long id); 15 | } 16 | -------------------------------------------------------------------------------- /branch_1_17/src/main/java/xuan/cat/fartherviewdistance/api/branch/packet/PacketEvent.java: -------------------------------------------------------------------------------- 1 | package xuan.cat.fartherviewdistance.api.branch.packet; 2 | 3 | import org.bukkit.Bukkit; 4 | import org.bukkit.entity.Player; 5 | import org.bukkit.event.Cancellable; 6 | import org.bukkit.event.Event; 7 | 8 | public abstract class PacketEvent extends Event implements Cancellable { 9 | private final Player player; 10 | private boolean cancel = false; 11 | 12 | public PacketEvent(Player player) { 13 | super(!Bukkit.isPrimaryThread()); 14 | this.player = player; 15 | } 16 | 17 | public final boolean isCancelled() { 18 | return cancel; 19 | } 20 | public final void setCancelled(boolean cancel) { 21 | this.cancel = cancel; 22 | } 23 | 24 | public final Player getPlayer() { 25 | return player; 26 | } 27 | } -------------------------------------------------------------------------------- /branch_1_17/src/main/java/xuan/cat/fartherviewdistance/api/branch/packet/PacketKeepAliveEvent.java: -------------------------------------------------------------------------------- 1 | package xuan.cat.fartherviewdistance.api.branch.packet; 2 | 3 | import org.bukkit.entity.Player; 4 | import org.bukkit.event.HandlerList; 5 | 6 | public final class PacketKeepAliveEvent extends PacketEvent { 7 | private static final HandlerList handlers = new HandlerList(); 8 | public HandlerList getHandlers() { 9 | return handlers; 10 | } 11 | public static HandlerList getHandlerList() { 12 | return handlers; 13 | } 14 | 15 | private final long id; 16 | 17 | public PacketKeepAliveEvent(Player player, long id) { 18 | super(player); 19 | this.id = id; 20 | } 21 | 22 | public long getId() { 23 | return id; 24 | } 25 | } -------------------------------------------------------------------------------- /branch_1_17/src/main/java/xuan/cat/fartherviewdistance/api/branch/packet/PacketMapChunkEvent.java: -------------------------------------------------------------------------------- 1 | package xuan.cat.fartherviewdistance.api.branch.packet; 2 | 3 | import org.bukkit.entity.Player; 4 | import org.bukkit.event.HandlerList; 5 | 6 | public final class PacketMapChunkEvent extends PacketEvent { 7 | private static final HandlerList handlers = new HandlerList(); 8 | public HandlerList getHandlers() { 9 | return handlers; 10 | } 11 | public static HandlerList getHandlerList() { 12 | return handlers; 13 | } 14 | 15 | private final int chunkX; 16 | private final int chunkZ; 17 | 18 | public PacketMapChunkEvent(Player player, int chunkX, int chunkZ) { 19 | super(player); 20 | this.chunkX = chunkX; 21 | this.chunkZ = chunkZ; 22 | } 23 | 24 | public int getChunkX() { 25 | return chunkX; 26 | } 27 | public int getChunkZ() { 28 | return chunkZ; 29 | } 30 | } -------------------------------------------------------------------------------- /branch_1_17/src/main/java/xuan/cat/fartherviewdistance/api/branch/packet/PacketUnloadChunkEvent.java: -------------------------------------------------------------------------------- 1 | package xuan.cat.fartherviewdistance.api.branch.packet; 2 | 3 | import org.bukkit.entity.Player; 4 | import org.bukkit.event.HandlerList; 5 | 6 | public final class PacketUnloadChunkEvent extends PacketEvent { 7 | private static final HandlerList handlers = new HandlerList(); 8 | public HandlerList getHandlers() { 9 | return handlers; 10 | } 11 | public static HandlerList getHandlerList() { 12 | return handlers; 13 | } 14 | 15 | private final int chunkX; 16 | private final int chunkZ; 17 | 18 | public PacketUnloadChunkEvent(Player player, int chunkX, int chunkZ) { 19 | super(player); 20 | this.chunkX = chunkX; 21 | this.chunkZ = chunkZ; 22 | } 23 | 24 | public int getChunkX() { 25 | return chunkX; 26 | } 27 | public int getChunkZ() { 28 | return chunkZ; 29 | } 30 | } -------------------------------------------------------------------------------- /branch_1_17/src/main/java/xuan/cat/fartherviewdistance/api/branch/packet/PacketViewDistanceEvent.java: -------------------------------------------------------------------------------- 1 | package xuan.cat.fartherviewdistance.api.branch.packet; 2 | 3 | import org.bukkit.entity.Player; 4 | import org.bukkit.event.HandlerList; 5 | 6 | public final class PacketViewDistanceEvent extends PacketEvent { 7 | private static final HandlerList handlers = new HandlerList(); 8 | public HandlerList getHandlers() { 9 | return handlers; 10 | } 11 | public static HandlerList getHandlerList() { 12 | return handlers; 13 | } 14 | 15 | private final int viewDistance; 16 | 17 | public PacketViewDistanceEvent(Player player, int viewDistance) { 18 | super(player); 19 | this.viewDistance = viewDistance; 20 | } 21 | 22 | public int getViewDistance() { 23 | return viewDistance; 24 | } 25 | 26 | } -------------------------------------------------------------------------------- /branch_1_17/src/main/java/xuan/cat/fartherviewdistance/code/branch/v17/Branch_17_ChunkLight.java: -------------------------------------------------------------------------------- 1 | package xuan.cat.fartherviewdistance.code.branch.v17; 2 | 3 | import net.minecraft.server.level.WorldServer; 4 | import org.bukkit.World; 5 | import org.bukkit.craftbukkit.v1_17_R1.CraftWorld; 6 | import xuan.cat.fartherviewdistance.api.branch.BranchChunkLight; 7 | 8 | import java.util.Arrays; 9 | 10 | public final class Branch_17_ChunkLight implements BranchChunkLight { 11 | public static final byte[] EMPTY = new byte[0]; 12 | 13 | private final WorldServer worldServer; 14 | private final byte[][] blockLights; 15 | private final byte[][] skyLights; 16 | 17 | public Branch_17_ChunkLight(World world) { 18 | this(((CraftWorld) world).getHandle()); 19 | } 20 | public Branch_17_ChunkLight(WorldServer worldServer) { 21 | this(worldServer, new byte[worldServer.getSectionsCount() + 2][], new byte[worldServer.getSectionsCount() + 2][]); 22 | } 23 | public Branch_17_ChunkLight(WorldServer worldServer, byte[][] blockLights, byte[][] skyLights) { 24 | this.worldServer = worldServer; 25 | this.blockLights = blockLights; 26 | this.skyLights = skyLights; 27 | Arrays.fill(blockLights, EMPTY); 28 | Arrays.fill(skyLights, EMPTY); 29 | } 30 | 31 | public WorldServer getWorldServer() { 32 | return worldServer; 33 | } 34 | 35 | public int getArrayLength() { 36 | return blockLights.length; 37 | } 38 | 39 | public static int indexFromSectionY(WorldServer worldServer, int sectionY) { 40 | return sectionY - worldServer.getMinSection() + 1; 41 | } 42 | 43 | public void setBlockLight(int sectionY, byte[] blockLight) { 44 | blockLights[indexFromSectionY(worldServer, sectionY)] = blockLight; 45 | } 46 | public void setSkyLight(int sectionY, byte[] skyLight) { 47 | skyLights[indexFromSectionY(worldServer, sectionY)] = skyLight; 48 | } 49 | 50 | public byte[] getBlockLight(int sectionY) { 51 | return blockLights[indexFromSectionY(worldServer, sectionY)]; 52 | } 53 | public byte[] getSkyLight(int sectionY) { 54 | return skyLights[indexFromSectionY(worldServer, sectionY)]; 55 | } 56 | 57 | public byte[][] getBlockLights() { 58 | return blockLights; 59 | } 60 | public byte[][] getSkyLights() { 61 | return skyLights; 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /branch_1_17/src/main/java/xuan/cat/fartherviewdistance/code/branch/v17/Branch_17_NBT.java: -------------------------------------------------------------------------------- 1 | package xuan.cat.fartherviewdistance.code.branch.v17; 2 | 3 | import net.minecraft.nbt.NBTTagCompound; 4 | import xuan.cat.fartherviewdistance.api.branch.BranchNBT; 5 | 6 | public final class Branch_17_NBT implements BranchNBT { 7 | 8 | protected NBTTagCompound tag; 9 | 10 | public Branch_17_NBT() { 11 | this.tag = new NBTTagCompound(); 12 | } 13 | 14 | public Branch_17_NBT(NBTTagCompound tag) { 15 | this.tag = tag; 16 | } 17 | 18 | 19 | public NBTTagCompound getNMSTag() { 20 | return tag; 21 | } 22 | 23 | @Override 24 | public String toString() { 25 | return tag.toString(); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /branch_1_17/src/main/java/xuan/cat/fartherviewdistance/code/branch/v17/Branch_17_Packet.java: -------------------------------------------------------------------------------- 1 | package xuan.cat.fartherviewdistance.code.branch.v17; 2 | 3 | import net.minecraft.network.protocol.Packet; 4 | import net.minecraft.network.protocol.game.*; 5 | import net.minecraft.server.network.PlayerConnection; 6 | import org.bukkit.craftbukkit.v1_17_R1.entity.CraftPlayer; 7 | import org.bukkit.entity.Player; 8 | import xuan.cat.fartherviewdistance.api.branch.BranchChunk; 9 | import xuan.cat.fartherviewdistance.api.branch.BranchChunkLight; 10 | import xuan.cat.fartherviewdistance.api.branch.BranchPacket; 11 | 12 | import java.util.function.Consumer; 13 | 14 | public final class Branch_17_Packet implements BranchPacket { 15 | private final Branch_17_PacketHandleChunk handleChunk = new Branch_17_PacketHandleChunk(); 16 | private final Branch_17_PacketHandleLightUpdate handleLightUpdate = new Branch_17_PacketHandleLightUpdate(); 17 | 18 | public void sendPacket(Player player, Packet packet) { 19 | try { 20 | PlayerConnection container = ((CraftPlayer) player).getHandle().b; 21 | container.sendPacket(packet); 22 | } catch (IllegalArgumentException ignored) { 23 | } 24 | } 25 | 26 | public void sendViewDistance(Player player, int viewDistance) { 27 | sendPacket(player, new PacketPlayOutViewDistance(viewDistance)); 28 | } 29 | 30 | public void sendUnloadChunk(Player player, int chunkX, int chunkZ) { 31 | sendPacket(player, new PacketPlayOutUnloadChunk(chunkX, chunkZ)); 32 | } 33 | 34 | public Consumer sendChunkAndLight(BranchChunk chunk, BranchChunkLight light, boolean needTile, Consumer consumeTraffic) { 35 | PacketPlayOutMapChunk packetChunk = handleChunk.createMapChunkPacket(chunk.getChunk(), needTile, consumeTraffic); 36 | PacketPlayOutLightUpdate packetLight = handleLightUpdate.createLightUpdatePacket(chunk.getX(), chunk.getZ(), (Branch_17_ChunkLight) light, true, consumeTraffic); 37 | try { 38 | // 適用於 paper 39 | packetChunk.setReady(true); 40 | } catch (NoSuchMethodError noSuchMethodError) { 41 | // 適用於 spigot (不推薦) 42 | } 43 | return (player) -> { 44 | sendPacket(player, packetLight); 45 | sendPacket(player, packetChunk); 46 | }; 47 | } 48 | 49 | public void sendKeepAlive(Player player, long id) { 50 | sendPacket(player, new PacketPlayOutKeepAlive(id)); 51 | } 52 | 53 | } 54 | -------------------------------------------------------------------------------- /branch_1_17/src/main/java/xuan/cat/fartherviewdistance/code/branch/v17/Branch_17_PacketHandleLightUpdate.java: -------------------------------------------------------------------------------- 1 | package xuan.cat.fartherviewdistance.code.branch.v17; 2 | 3 | import io.netty.buffer.Unpooled; 4 | import net.minecraft.network.PacketDataSerializer; 5 | import net.minecraft.network.protocol.game.PacketPlayOutLightUpdate; 6 | 7 | import java.lang.reflect.Field; 8 | import java.util.ArrayList; 9 | import java.util.BitSet; 10 | import java.util.List; 11 | import java.util.function.Consumer; 12 | 13 | public final class Branch_17_PacketHandleLightUpdate { 14 | private Field field_cleaner1 = null; 15 | private Field field_cleaner2 = null; 16 | 17 | 18 | public Branch_17_PacketHandleLightUpdate() { 19 | Class atClass = PacketPlayOutLightUpdate.class; 20 | 21 | try { 22 | field_cleaner1 = atClass.getDeclaredField("cleaner1"); 23 | field_cleaner2 = atClass.getDeclaredField("cleaner2"); 24 | 25 | field_cleaner1 .setAccessible(true); 26 | field_cleaner2 .setAccessible(true); 27 | } catch (Exception ignored) { 28 | } 29 | } 30 | 31 | 32 | public PacketPlayOutLightUpdate createLightUpdatePacket(int chunkX, int chunkZ, Branch_17_ChunkLight light, boolean trustEdges, Consumer consumeTraffic) { 33 | PacketDataSerializer serializer = new PacketDataSerializer(Unpooled.buffer().writerIndex(0)); 34 | 35 | List dataSky = new ArrayList<>(); 36 | List dataBlock = new ArrayList<>(); 37 | BitSet notSkyEmpty = new BitSet(); 38 | BitSet notBlockEmpty = new BitSet(); 39 | BitSet isSkyEmpty = new BitSet(); 40 | BitSet isBlockEmpty = new BitSet(); 41 | 42 | for(int index = 0; index < light.getArrayLength() ; ++index) { 43 | saveBitSet(light.getSkyLights(), index, notSkyEmpty, isSkyEmpty, dataSky); 44 | saveBitSet(light.getBlockLights(), index, notBlockEmpty, isBlockEmpty, dataBlock); 45 | } 46 | 47 | serializer.d(chunkX); 48 | serializer.d(chunkZ); 49 | serializer.writeBoolean(trustEdges); 50 | serializer.a(notSkyEmpty); 51 | serializer.a(notBlockEmpty); 52 | serializer.a(isSkyEmpty); 53 | serializer.a(isBlockEmpty); 54 | serializer.a(dataSky, PacketDataSerializer::a); 55 | serializer.a(dataBlock, PacketDataSerializer::a); 56 | 57 | consumeTraffic.accept(serializer.readableBytes()); 58 | 59 | PacketPlayOutLightUpdate packet = new PacketPlayOutLightUpdate(serializer); 60 | 61 | try { 62 | if (field_cleaner1 != null) 63 | field_cleaner1.set(packet, (Runnable) () -> { }); 64 | if (field_cleaner2 != null) 65 | field_cleaner2.set(packet, (Runnable) () -> { }); 66 | } catch (Exception exception) { 67 | exception.printStackTrace(); 68 | } 69 | 70 | return packet; 71 | } 72 | 73 | 74 | private static void saveBitSet(byte[][] nibbleArrays, int index, BitSet notEmpty, BitSet isEmpty, List list) { 75 | byte[] nibbleArray = nibbleArrays[index]; 76 | if (nibbleArray != Branch_17_ChunkLight.EMPTY) { 77 | if (nibbleArray == null) { 78 | isEmpty.set(index); 79 | } else { 80 | notEmpty.set(index); 81 | list.add(nibbleArray); 82 | } 83 | } 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /branch_1_17/src/main/java/xuan/cat/fartherviewdistance/code/branch/v17/Branch_17_ProxyPlayerConnection.java: -------------------------------------------------------------------------------- 1 | package xuan.cat.fartherviewdistance.code.branch.v17; 2 | 3 | import net.minecraft.network.protocol.Packet; 4 | import net.minecraft.network.protocol.game.PacketPlayInKeepAlive; 5 | import net.minecraft.network.protocol.game.PacketPlayOutMapChunk; 6 | import net.minecraft.network.protocol.game.PacketPlayOutUnloadChunk; 7 | import net.minecraft.network.protocol.game.PacketPlayOutViewDistance; 8 | import org.bukkit.Bukkit; 9 | import org.bukkit.entity.Player; 10 | import xuan.cat.fartherviewdistance.api.branch.packet.PacketKeepAliveEvent; 11 | import xuan.cat.fartherviewdistance.api.branch.packet.PacketMapChunkEvent; 12 | import xuan.cat.fartherviewdistance.api.branch.packet.PacketUnloadChunkEvent; 13 | import xuan.cat.fartherviewdistance.api.branch.packet.PacketViewDistanceEvent; 14 | 15 | import java.lang.reflect.Field; 16 | 17 | public final class Branch_17_ProxyPlayerConnection { 18 | public static boolean read(Player player, Packet packet) { 19 | if (packet instanceof PacketPlayInKeepAlive) { 20 | PacketKeepAliveEvent event = new PacketKeepAliveEvent(player, ((PacketPlayInKeepAlive) packet).b()); 21 | Bukkit.getPluginManager().callEvent(event); 22 | return !event.isCancelled(); 23 | } else { 24 | return true; 25 | } 26 | } 27 | 28 | 29 | private static Field field_PacketPlayOutUnloadChunk_chunkX; 30 | private static Field field_PacketPlayOutUnloadChunk_chunkZ; 31 | private static Field field_PacketPlayOutViewDistance_distance; 32 | private static Field field_PacketPlayOutMapChunk_chunkX; 33 | private static Field field_PacketPlayOutMapChunk_chunkZ; 34 | static { 35 | try { 36 | field_PacketPlayOutUnloadChunk_chunkX = PacketPlayOutUnloadChunk.class.getDeclaredField("a"); 37 | field_PacketPlayOutUnloadChunk_chunkZ = PacketPlayOutUnloadChunk.class.getDeclaredField("b"); 38 | field_PacketPlayOutViewDistance_distance = PacketPlayOutViewDistance.class.getDeclaredField("a"); 39 | field_PacketPlayOutMapChunk_chunkX = PacketPlayOutMapChunk.class.getDeclaredField("a"); 40 | field_PacketPlayOutMapChunk_chunkZ = PacketPlayOutMapChunk.class.getDeclaredField("b"); 41 | field_PacketPlayOutUnloadChunk_chunkX.setAccessible(true); 42 | field_PacketPlayOutUnloadChunk_chunkZ.setAccessible(true); 43 | field_PacketPlayOutViewDistance_distance.setAccessible(true); 44 | field_PacketPlayOutMapChunk_chunkX.setAccessible(true); 45 | field_PacketPlayOutMapChunk_chunkZ.setAccessible(true); 46 | } catch (Exception ex) { 47 | ex.printStackTrace(); 48 | } 49 | } 50 | public static boolean write(Player player, Packet packet) { 51 | try { 52 | if (packet instanceof PacketPlayOutUnloadChunk) { 53 | PacketUnloadChunkEvent event = new PacketUnloadChunkEvent(player, field_PacketPlayOutUnloadChunk_chunkX.getInt(packet), field_PacketPlayOutUnloadChunk_chunkZ.getInt(packet)); 54 | Bukkit.getPluginManager().callEvent(event); 55 | return !event.isCancelled(); 56 | } else if (packet instanceof PacketPlayOutViewDistance) { 57 | PacketViewDistanceEvent event = new PacketViewDistanceEvent(player, field_PacketPlayOutViewDistance_distance.getInt(packet)); 58 | Bukkit.getPluginManager().callEvent(event); 59 | return !event.isCancelled(); 60 | } else if (packet instanceof PacketPlayOutMapChunk) { 61 | PacketMapChunkEvent event = new PacketMapChunkEvent(player, field_PacketPlayOutMapChunk_chunkX.getInt(packet), field_PacketPlayOutMapChunk_chunkZ.getInt(packet)); 62 | Bukkit.getPluginManager().callEvent(event); 63 | return !event.isCancelled(); 64 | } else { 65 | return true; 66 | } 67 | } catch (Exception ex) { 68 | ex.printStackTrace(); 69 | return true; 70 | } 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /branch_1_18/src/main/java/xuan/cat/fartherviewdistance/api/branch/BranchChunk.java: -------------------------------------------------------------------------------- 1 | package xuan.cat.fartherviewdistance.api.branch; 2 | 3 | import org.bukkit.Chunk; 4 | import org.bukkit.Material; 5 | import org.bukkit.World; 6 | import org.bukkit.block.Biome; 7 | import org.bukkit.block.data.BlockData; 8 | import org.bukkit.util.Vector; 9 | 10 | import java.util.List; 11 | import java.util.Map; 12 | 13 | public interface BranchChunk { 14 | BranchNBT toNBT(BranchChunkLight light, List asyncRunnable); 15 | 16 | Chunk getChunk(); 17 | 18 | World getWorld(); 19 | 20 | boolean equalsBlockData(int x, int y, int z, BlockData blockData); 21 | BlockData getBlockData(int x, int y, int z); 22 | void setBlockData(int x, int y, int z, BlockData blockData); 23 | Map getBlockDataMap(); 24 | 25 | Material getMaterial(int x, int y, int z); 26 | void setMaterial(int x, int y, int z, Material material); 27 | 28 | int getX(); 29 | int getZ(); 30 | 31 | Status getStatus(); 32 | 33 | void replaceAllMaterial(BlockData[] target, BlockData to); 34 | 35 | @Deprecated 36 | Biome getBiome(int x, int z); 37 | Biome getBiome(int x, int y, int z); 38 | @Deprecated 39 | void setBiome(int x, int z, Biome biome); 40 | void setBiome(int x, int y, int z, Biome biome); 41 | 42 | boolean hasFluid(int x, int y, int z); 43 | boolean isAir(int x, int y, int z); 44 | 45 | int getHighestY(int x, int z); 46 | 47 | /** 48 | * 區塊狀態 49 | */ 50 | enum Status { 51 | EMPTY (0), 52 | STRUCTURE_STARTS (1), 53 | STRUCTURE_REFERENCES(2), 54 | BIOMES (3), 55 | NOISE (4), 56 | SURFACE (5), 57 | CARVERS (6), 58 | LIQUID_CARVERS (7), 59 | FEATURES (8), 60 | LIGHT (9), 61 | SPAWN (10), 62 | HEIGHTMAPS (11), 63 | FULL (12); 64 | 65 | private final int sequence; 66 | Status(int sequence) { 67 | this.sequence = sequence; 68 | } 69 | 70 | public boolean isAbove(Status status) { 71 | return this.sequence >= status.sequence; 72 | } 73 | public boolean isUnder(Status status) { 74 | return this.sequence <= status.sequence; 75 | } 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /branch_1_18/src/main/java/xuan/cat/fartherviewdistance/api/branch/BranchChunkLight.java: -------------------------------------------------------------------------------- 1 | package xuan.cat.fartherviewdistance.api.branch; 2 | 3 | public interface BranchChunkLight { 4 | } 5 | -------------------------------------------------------------------------------- /branch_1_18/src/main/java/xuan/cat/fartherviewdistance/api/branch/BranchMinecraft.java: -------------------------------------------------------------------------------- 1 | package xuan.cat.fartherviewdistance.api.branch; 2 | 3 | import org.bukkit.Chunk; 4 | import org.bukkit.World; 5 | import org.bukkit.entity.Player; 6 | 7 | import java.io.IOException; 8 | 9 | public interface BranchMinecraft { 10 | BranchNBT getChunkNBTFromDisk(World world, int chunkX, int chunkZ) throws IOException; 11 | 12 | BranchChunk getChunkFromMemoryCache(World world, int chunkX, int chunkZ); 13 | 14 | BranchChunk fromChunk(World world, int chunkX, int chunkZ, BranchNBT nbt, boolean integralHeightmap); 15 | 16 | BranchChunkLight fromLight(World world, BranchNBT nbt); 17 | 18 | BranchChunkLight fromLight(World world); 19 | 20 | BranchChunk fromChunk(World world, Chunk chunk); 21 | 22 | BranchChunk.Status fromStatus(BranchNBT nbt); 23 | 24 | void injectPlayer(Player player); 25 | } 26 | -------------------------------------------------------------------------------- /branch_1_18/src/main/java/xuan/cat/fartherviewdistance/api/branch/BranchNBT.java: -------------------------------------------------------------------------------- 1 | package xuan.cat.fartherviewdistance.api.branch; 2 | 3 | public interface BranchNBT { 4 | } 5 | -------------------------------------------------------------------------------- /branch_1_18/src/main/java/xuan/cat/fartherviewdistance/api/branch/BranchPacket.java: -------------------------------------------------------------------------------- 1 | package xuan.cat.fartherviewdistance.api.branch; 2 | 3 | import org.bukkit.entity.Player; 4 | 5 | import java.util.function.Consumer; 6 | 7 | public interface BranchPacket { 8 | void sendViewDistance(Player player, int viewDistance); 9 | 10 | void sendUnloadChunk(Player player, int chunkX, int chunkZ); 11 | 12 | Consumer sendChunkAndLight(BranchChunk chunk, BranchChunkLight light, boolean needTile, Consumer consumeTraffic); 13 | 14 | void sendKeepAlive(Player player, long id); 15 | } 16 | -------------------------------------------------------------------------------- /branch_1_18/src/main/java/xuan/cat/fartherviewdistance/api/branch/packet/PacketEvent.java: -------------------------------------------------------------------------------- 1 | package xuan.cat.fartherviewdistance.api.branch.packet; 2 | 3 | import org.bukkit.Bukkit; 4 | import org.bukkit.entity.Player; 5 | import org.bukkit.event.Cancellable; 6 | import org.bukkit.event.Event; 7 | 8 | public abstract class PacketEvent extends Event implements Cancellable { 9 | private final Player player; 10 | private boolean cancel = false; 11 | 12 | public PacketEvent(Player player) { 13 | super(!Bukkit.isPrimaryThread()); 14 | this.player = player; 15 | } 16 | 17 | public final boolean isCancelled() { 18 | return cancel; 19 | } 20 | public final void setCancelled(boolean cancel) { 21 | this.cancel = cancel; 22 | } 23 | 24 | public final Player getPlayer() { 25 | return player; 26 | } 27 | } -------------------------------------------------------------------------------- /branch_1_18/src/main/java/xuan/cat/fartherviewdistance/api/branch/packet/PacketKeepAliveEvent.java: -------------------------------------------------------------------------------- 1 | package xuan.cat.fartherviewdistance.api.branch.packet; 2 | 3 | import org.bukkit.entity.Player; 4 | import org.bukkit.event.HandlerList; 5 | 6 | public final class PacketKeepAliveEvent extends PacketEvent { 7 | private static final HandlerList handlers = new HandlerList(); 8 | public HandlerList getHandlers() { 9 | return handlers; 10 | } 11 | public static HandlerList getHandlerList() { 12 | return handlers; 13 | } 14 | 15 | private final long id; 16 | 17 | public PacketKeepAliveEvent(Player player, long id) { 18 | super(player); 19 | this.id = id; 20 | } 21 | 22 | public long getId() { 23 | return id; 24 | } 25 | } -------------------------------------------------------------------------------- /branch_1_18/src/main/java/xuan/cat/fartherviewdistance/api/branch/packet/PacketMapChunkEvent.java: -------------------------------------------------------------------------------- 1 | package xuan.cat.fartherviewdistance.api.branch.packet; 2 | 3 | import org.bukkit.entity.Player; 4 | import org.bukkit.event.HandlerList; 5 | 6 | public final class PacketMapChunkEvent extends PacketEvent { 7 | private static final HandlerList handlers = new HandlerList(); 8 | public HandlerList getHandlers() { 9 | return handlers; 10 | } 11 | public static HandlerList getHandlerList() { 12 | return handlers; 13 | } 14 | 15 | private final int chunkX; 16 | private final int chunkZ; 17 | 18 | public PacketMapChunkEvent(Player player, int chunkX, int chunkZ) { 19 | super(player); 20 | this.chunkX = chunkX; 21 | this.chunkZ = chunkZ; 22 | } 23 | 24 | public int getChunkX() { 25 | return chunkX; 26 | } 27 | public int getChunkZ() { 28 | return chunkZ; 29 | } 30 | } -------------------------------------------------------------------------------- /branch_1_18/src/main/java/xuan/cat/fartherviewdistance/api/branch/packet/PacketUnloadChunkEvent.java: -------------------------------------------------------------------------------- 1 | package xuan.cat.fartherviewdistance.api.branch.packet; 2 | 3 | import org.bukkit.entity.Player; 4 | import org.bukkit.event.HandlerList; 5 | 6 | public final class PacketUnloadChunkEvent extends PacketEvent { 7 | private static final HandlerList handlers = new HandlerList(); 8 | public HandlerList getHandlers() { 9 | return handlers; 10 | } 11 | public static HandlerList getHandlerList() { 12 | return handlers; 13 | } 14 | 15 | private final int chunkX; 16 | private final int chunkZ; 17 | 18 | public PacketUnloadChunkEvent(Player player, int chunkX, int chunkZ) { 19 | super(player); 20 | this.chunkX = chunkX; 21 | this.chunkZ = chunkZ; 22 | } 23 | 24 | public int getChunkX() { 25 | return chunkX; 26 | } 27 | public int getChunkZ() { 28 | return chunkZ; 29 | } 30 | } -------------------------------------------------------------------------------- /branch_1_18/src/main/java/xuan/cat/fartherviewdistance/api/branch/packet/PacketViewDistanceEvent.java: -------------------------------------------------------------------------------- 1 | package xuan.cat.fartherviewdistance.api.branch.packet; 2 | 3 | import org.bukkit.entity.Player; 4 | import org.bukkit.event.HandlerList; 5 | 6 | public final class PacketViewDistanceEvent extends PacketEvent { 7 | private static final HandlerList handlers = new HandlerList(); 8 | public HandlerList getHandlers() { 9 | return handlers; 10 | } 11 | public static HandlerList getHandlerList() { 12 | return handlers; 13 | } 14 | 15 | private final int viewDistance; 16 | 17 | public PacketViewDistanceEvent(Player player, int viewDistance) { 18 | super(player); 19 | this.viewDistance = viewDistance; 20 | } 21 | 22 | public int getViewDistance() { 23 | return viewDistance; 24 | } 25 | 26 | } -------------------------------------------------------------------------------- /branch_1_18/src/main/java/xuan/cat/fartherviewdistance/code/branch/v18/Branch_18_ChunkLight.java: -------------------------------------------------------------------------------- 1 | package xuan.cat.fartherviewdistance.code.branch.v18; 2 | 3 | import net.minecraft.server.level.ServerLevel; 4 | import org.bukkit.World; 5 | import org.bukkit.craftbukkit.v1_18_R2.CraftWorld; 6 | import xuan.cat.fartherviewdistance.api.branch.BranchChunkLight; 7 | 8 | import java.util.Arrays; 9 | 10 | public final class Branch_18_ChunkLight implements BranchChunkLight { 11 | public static final byte[] EMPTY = new byte[0]; 12 | 13 | private final ServerLevel worldServer; 14 | private final byte[][] blockLights; 15 | private final byte[][] skyLights; 16 | 17 | public Branch_18_ChunkLight(World world) { 18 | this(((CraftWorld) world).getHandle()); 19 | } 20 | public Branch_18_ChunkLight(ServerLevel worldServer) { 21 | this(worldServer, new byte[worldServer.getSectionsCount() + 2][], new byte[worldServer.getSectionsCount() + 2][]); 22 | } 23 | public Branch_18_ChunkLight(ServerLevel worldServer, byte[][] blockLights, byte[][] skyLights) { 24 | this.worldServer = worldServer; 25 | this.blockLights = blockLights; 26 | this.skyLights = skyLights; 27 | Arrays.fill(blockLights, EMPTY); 28 | Arrays.fill(skyLights, EMPTY); 29 | } 30 | 31 | public ServerLevel getWorldServer() { 32 | return worldServer; 33 | } 34 | 35 | public int getArrayLength() { 36 | return blockLights.length; 37 | } 38 | 39 | public static int indexFromSectionY(ServerLevel worldServer, int sectionY) { 40 | return sectionY - worldServer.getMinSection() + 1; 41 | } 42 | 43 | public void setBlockLight(int sectionY, byte[] blockLight) { 44 | blockLights[indexFromSectionY(worldServer, sectionY)] = blockLight; 45 | } 46 | public void setSkyLight(int sectionY, byte[] skyLight) { 47 | skyLights[indexFromSectionY(worldServer, sectionY)] = skyLight; 48 | } 49 | 50 | public byte[] getBlockLight(int sectionY) { 51 | return blockLights[indexFromSectionY(worldServer, sectionY)]; 52 | } 53 | public byte[] getSkyLight(int sectionY) { 54 | return skyLights[indexFromSectionY(worldServer, sectionY)]; 55 | } 56 | 57 | public byte[][] getBlockLights() { 58 | return blockLights; 59 | } 60 | public byte[][] getSkyLights() { 61 | return skyLights; 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /branch_1_18/src/main/java/xuan/cat/fartherviewdistance/code/branch/v18/Branch_18_NBT.java: -------------------------------------------------------------------------------- 1 | package xuan.cat.fartherviewdistance.code.branch.v18; 2 | 3 | import net.minecraft.nbt.CompoundTag; 4 | import xuan.cat.fartherviewdistance.api.branch.BranchNBT; 5 | 6 | public final class Branch_18_NBT implements BranchNBT { 7 | 8 | protected CompoundTag tag; 9 | 10 | public Branch_18_NBT() { 11 | this.tag = new CompoundTag(); 12 | } 13 | 14 | public Branch_18_NBT(CompoundTag tag) { 15 | this.tag = tag; 16 | } 17 | 18 | 19 | public CompoundTag getNMSTag() { 20 | return tag; 21 | } 22 | 23 | @Override 24 | public String toString() { 25 | return tag.toString(); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /branch_1_18/src/main/java/xuan/cat/fartherviewdistance/code/branch/v18/Branch_18_Packet.java: -------------------------------------------------------------------------------- 1 | package xuan.cat.fartherviewdistance.code.branch.v18; 2 | 3 | import io.netty.buffer.Unpooled; 4 | import net.minecraft.network.Connection; 5 | import net.minecraft.network.FriendlyByteBuf; 6 | import net.minecraft.network.protocol.Packet; 7 | import net.minecraft.network.protocol.game.ClientboundForgetLevelChunkPacket; 8 | import net.minecraft.network.protocol.game.ClientboundKeepAlivePacket; 9 | import net.minecraft.network.protocol.game.ClientboundLevelChunkWithLightPacket; 10 | import net.minecraft.network.protocol.game.ClientboundSetChunkCacheRadiusPacket; 11 | import org.bukkit.craftbukkit.v1_18_R2.entity.CraftPlayer; 12 | import org.bukkit.entity.Player; 13 | import xuan.cat.fartherviewdistance.api.branch.BranchChunk; 14 | import xuan.cat.fartherviewdistance.api.branch.BranchChunkLight; 15 | import xuan.cat.fartherviewdistance.api.branch.BranchPacket; 16 | 17 | import java.util.function.Consumer; 18 | 19 | public final class Branch_18_Packet implements BranchPacket { 20 | private final Branch_18_PacketHandleChunk handleChunk = new Branch_18_PacketHandleChunk(); 21 | private final Branch_18_PacketHandleLightUpdate handleLightUpdate = new Branch_18_PacketHandleLightUpdate(); 22 | 23 | public void sendPacket(Player player, Packet packet) { 24 | try { 25 | Connection container = ((CraftPlayer) player).getHandle().connection.connection; 26 | container.send(packet); 27 | } catch (IllegalArgumentException ignored) { 28 | } 29 | } 30 | 31 | public void sendViewDistance(Player player, int viewDistance) { 32 | sendPacket(player, new ClientboundSetChunkCacheRadiusPacket(viewDistance)); 33 | } 34 | 35 | public void sendUnloadChunk(Player player, int chunkX, int chunkZ) { 36 | sendPacket(player, new ClientboundForgetLevelChunkPacket(chunkX, chunkZ)); 37 | } 38 | 39 | public Consumer sendChunkAndLight(BranchChunk chunk, BranchChunkLight light, boolean needTile, Consumer consumeTraffic) { 40 | FriendlyByteBuf serializer = new FriendlyByteBuf(Unpooled.buffer().writerIndex(0)); 41 | serializer.writeInt(chunk.getX()); 42 | serializer.writeInt(chunk.getZ()); 43 | this.handleChunk.write(serializer, chunk.getChunk(), needTile); 44 | this.handleLightUpdate.write(serializer, (Branch_18_ChunkLight) light, true); 45 | consumeTraffic.accept(serializer.readableBytes()); 46 | ClientboundLevelChunkWithLightPacket packet = new ClientboundLevelChunkWithLightPacket(serializer); 47 | try { 48 | // 適用於 paper 49 | packet.setReady(true); 50 | } catch (NoSuchMethodError noSuchMethodError) { 51 | // 適用於 spigot (不推薦) 52 | } 53 | return (player) -> sendPacket(player, packet); 54 | } 55 | 56 | public void sendKeepAlive(Player player, long id) { 57 | sendPacket(player, new ClientboundKeepAlivePacket(id)); 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /branch_1_18/src/main/java/xuan/cat/fartherviewdistance/code/branch/v18/Branch_18_PacketHandleChunk.java: -------------------------------------------------------------------------------- 1 | package xuan.cat.fartherviewdistance.code.branch.v18; 2 | 3 | import io.netty.buffer.Unpooled; 4 | import net.minecraft.core.BlockPos; 5 | import net.minecraft.core.Registry; 6 | import net.minecraft.core.SectionPos; 7 | import net.minecraft.nbt.CompoundTag; 8 | import net.minecraft.nbt.LongArrayTag; 9 | import net.minecraft.network.FriendlyByteBuf; 10 | import net.minecraft.world.level.block.entity.BlockEntity; 11 | import net.minecraft.world.level.chunk.LevelChunk; 12 | import net.minecraft.world.level.chunk.LevelChunkSection; 13 | import net.minecraft.world.level.levelgen.Heightmap; 14 | import org.bukkit.Chunk; 15 | import org.bukkit.craftbukkit.v1_18_R2.CraftChunk; 16 | 17 | import java.util.HashMap; 18 | import java.util.Map; 19 | 20 | public final class Branch_18_PacketHandleChunk { 21 | public Branch_18_PacketHandleChunk() { 22 | } 23 | 24 | public void write(FriendlyByteBuf serializer, Chunk chunk, boolean needTile) { 25 | this.write(serializer, ((CraftChunk) chunk).getHandle(), needTile); 26 | } 27 | 28 | public void write(FriendlyByteBuf serializer, LevelChunk chunk, boolean needTile) { 29 | CompoundTag heightmapsNBT = new CompoundTag(); 30 | for (Map.Entry entry : chunk.getHeightmaps()) { 31 | Heightmap.Types heightType = entry.getKey(); 32 | Heightmap heightMap = entry.getValue(); 33 | if (heightType.sendToClient()) 34 | heightmapsNBT.put(heightType.getSerializationKey(), new LongArrayTag(heightMap.getRawData())); 35 | } 36 | 37 | int chunkSize = 0; 38 | for(LevelChunkSection section : chunk.getSections()) { 39 | chunkSize += section.getSerializedSize(); 40 | } 41 | byte[] bufferBytes = new byte[chunkSize]; 42 | FriendlyByteBuf bufferByteBuf = new FriendlyByteBuf(Unpooled.wrappedBuffer(bufferBytes)); 43 | bufferByteBuf.writerIndex(0); 44 | for(LevelChunkSection section : chunk.getSections()) { 45 | section.write(bufferByteBuf); 46 | } 47 | 48 | serializer.writeNbt(heightmapsNBT); 49 | serializer.writeVarInt(bufferBytes.length); 50 | serializer.writeBytes(bufferBytes); 51 | 52 | Map blockEntityMap = !needTile ? new HashMap<>(0) : chunk.getBlockEntities(); 53 | serializer.writeCollection(blockEntityMap.entrySet(), (buf, entry) -> { 54 | BlockEntity blockEntity = entry.getValue(); 55 | CompoundTag entityNBT = blockEntity.getUpdateTag(); 56 | BlockPos blockPos = blockEntity.getBlockPos(); 57 | buf.writeByte(SectionPos.sectionRelative(blockPos.getX()) << 4 | SectionPos.sectionRelative(blockPos.getZ())); 58 | buf.writeShort(blockPos.getY()); 59 | buf.writeVarInt(Registry.BLOCK_ENTITY_TYPE.getId(blockEntity.getType())); 60 | buf.writeNbt(entityNBT.isEmpty() ? null : entityNBT); 61 | }); 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /branch_1_18/src/main/java/xuan/cat/fartherviewdistance/code/branch/v18/Branch_18_PacketHandleLightUpdate.java: -------------------------------------------------------------------------------- 1 | package xuan.cat.fartherviewdistance.code.branch.v18; 2 | 3 | import net.minecraft.network.FriendlyByteBuf; 4 | 5 | import java.util.ArrayList; 6 | import java.util.BitSet; 7 | import java.util.List; 8 | 9 | public final class Branch_18_PacketHandleLightUpdate { 10 | public Branch_18_PacketHandleLightUpdate() { 11 | } 12 | 13 | public void write(FriendlyByteBuf serializer, Branch_18_ChunkLight light, boolean trustEdges) { 14 | List dataSky = new ArrayList<>(); 15 | List dataBlock = new ArrayList<>(); 16 | BitSet notSkyEmpty = new BitSet(); 17 | BitSet notBlockEmpty = new BitSet(); 18 | BitSet isSkyEmpty = new BitSet(); 19 | BitSet isBlockEmpty = new BitSet(); 20 | 21 | for (int index = 0; index < light.getArrayLength(); ++index) { 22 | saveBitSet(light.getSkyLights(), index, notSkyEmpty, isSkyEmpty, dataSky); 23 | saveBitSet(light.getBlockLights(), index, notBlockEmpty, isBlockEmpty, dataBlock); 24 | } 25 | 26 | serializer.writeBoolean(trustEdges); 27 | serializer.writeBitSet(notSkyEmpty); 28 | serializer.writeBitSet(notBlockEmpty); 29 | serializer.writeBitSet(isSkyEmpty); 30 | serializer.writeBitSet(isBlockEmpty); 31 | serializer.writeCollection(dataSky, FriendlyByteBuf::writeByteArray); 32 | serializer.writeCollection(dataBlock, FriendlyByteBuf::writeByteArray); 33 | } 34 | 35 | private static void saveBitSet(byte[][] nibbleArrays, int index, BitSet notEmpty, BitSet isEmpty, List list) { 36 | byte[] nibbleArray = nibbleArrays[index]; 37 | if (nibbleArray != Branch_18_ChunkLight.EMPTY) { 38 | if (nibbleArray == null) { 39 | isEmpty.set(index); 40 | } else { 41 | notEmpty.set(index); 42 | list.add(nibbleArray); 43 | } 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /branch_1_18/src/main/java/xuan/cat/fartherviewdistance/code/branch/v18/Branch_18_ProxyPlayerConnection.java: -------------------------------------------------------------------------------- 1 | package xuan.cat.fartherviewdistance.code.branch.v18; 2 | 3 | import net.minecraft.network.protocol.Packet; 4 | import net.minecraft.network.protocol.game.ClientboundForgetLevelChunkPacket; 5 | import net.minecraft.network.protocol.game.ClientboundLevelChunkWithLightPacket; 6 | import net.minecraft.network.protocol.game.ClientboundSetChunkCacheRadiusPacket; 7 | import net.minecraft.network.protocol.game.ServerboundKeepAlivePacket; 8 | import org.bukkit.Bukkit; 9 | import org.bukkit.entity.Player; 10 | import xuan.cat.fartherviewdistance.api.branch.packet.PacketKeepAliveEvent; 11 | import xuan.cat.fartherviewdistance.api.branch.packet.PacketMapChunkEvent; 12 | import xuan.cat.fartherviewdistance.api.branch.packet.PacketUnloadChunkEvent; 13 | import xuan.cat.fartherviewdistance.api.branch.packet.PacketViewDistanceEvent; 14 | 15 | import java.lang.reflect.Field; 16 | 17 | public final class Branch_18_ProxyPlayerConnection { 18 | public static boolean read(Player player, Packet packet) { 19 | if (packet instanceof ServerboundKeepAlivePacket) { 20 | PacketKeepAliveEvent event = new PacketKeepAliveEvent(player, ((ServerboundKeepAlivePacket) packet).getId()); 21 | Bukkit.getPluginManager().callEvent(event); 22 | return !event.isCancelled(); 23 | } else { 24 | return true; 25 | } 26 | } 27 | 28 | 29 | private static Field field_PacketPlayOutUnloadChunk_chunkX; 30 | private static Field field_PacketPlayOutUnloadChunk_chunkZ; 31 | private static Field field_PacketPlayOutViewDistance_distance; 32 | private static Field field_ClientboundLevelChunkWithLightPacket_chunkX; 33 | private static Field field_ClientboundLevelChunkWithLightPacket_chunkZ; 34 | static { 35 | try { 36 | field_PacketPlayOutUnloadChunk_chunkX = ClientboundForgetLevelChunkPacket.class.getDeclaredField("a"); 37 | field_PacketPlayOutUnloadChunk_chunkZ = ClientboundForgetLevelChunkPacket.class.getDeclaredField("b"); 38 | field_PacketPlayOutViewDistance_distance = ClientboundSetChunkCacheRadiusPacket.class.getDeclaredField("a"); 39 | field_ClientboundLevelChunkWithLightPacket_chunkX = ClientboundLevelChunkWithLightPacket.class.getDeclaredField("a"); 40 | field_ClientboundLevelChunkWithLightPacket_chunkZ = ClientboundLevelChunkWithLightPacket.class.getDeclaredField("b"); 41 | field_PacketPlayOutUnloadChunk_chunkX.setAccessible(true); 42 | field_PacketPlayOutUnloadChunk_chunkZ.setAccessible(true); 43 | field_PacketPlayOutViewDistance_distance.setAccessible(true); 44 | field_ClientboundLevelChunkWithLightPacket_chunkX.setAccessible(true); 45 | field_ClientboundLevelChunkWithLightPacket_chunkZ.setAccessible(true); 46 | } catch (Exception ex) { 47 | ex.printStackTrace(); 48 | } 49 | } 50 | public static boolean write(Player player, Packet packet) { 51 | try { 52 | if (packet instanceof ClientboundForgetLevelChunkPacket) { 53 | PacketUnloadChunkEvent event = new PacketUnloadChunkEvent(player, field_PacketPlayOutUnloadChunk_chunkX.getInt(packet), field_PacketPlayOutUnloadChunk_chunkZ.getInt(packet)); 54 | Bukkit.getPluginManager().callEvent(event); 55 | return !event.isCancelled(); 56 | } else if (packet instanceof ClientboundSetChunkCacheRadiusPacket) { 57 | PacketViewDistanceEvent event = new PacketViewDistanceEvent(player, field_PacketPlayOutViewDistance_distance.getInt(packet)); 58 | Bukkit.getPluginManager().callEvent(event); 59 | return !event.isCancelled(); 60 | } else if (packet instanceof ClientboundLevelChunkWithLightPacket) { 61 | PacketMapChunkEvent event = new PacketMapChunkEvent(player, field_ClientboundLevelChunkWithLightPacket_chunkX.getInt(packet), field_ClientboundLevelChunkWithLightPacket_chunkZ.getInt(packet)); 62 | Bukkit.getPluginManager().callEvent(event); 63 | return !event.isCancelled(); 64 | } else { 65 | return true; 66 | } 67 | } catch (Exception ex) { 68 | ex.printStackTrace(); 69 | return true; 70 | } 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /branch_1_19/src/main/java/xuan/cat/fartherviewdistance/api/branch/BranchChunk.java: -------------------------------------------------------------------------------- 1 | package xuan.cat.fartherviewdistance.api.branch; 2 | 3 | import org.bukkit.Chunk; 4 | import org.bukkit.Material; 5 | import org.bukkit.World; 6 | import org.bukkit.block.Biome; 7 | import org.bukkit.block.data.BlockData; 8 | import org.bukkit.util.Vector; 9 | 10 | import java.util.List; 11 | import java.util.Map; 12 | 13 | public interface BranchChunk { 14 | BranchNBT toNBT(BranchChunkLight light, List asyncRunnable); 15 | 16 | Chunk getChunk(); 17 | 18 | World getWorld(); 19 | 20 | boolean equalsBlockData(int x, int y, int z, BlockData blockData); 21 | BlockData getBlockData(int x, int y, int z); 22 | void setBlockData(int x, int y, int z, BlockData blockData); 23 | Map getBlockDataMap(); 24 | 25 | Material getMaterial(int x, int y, int z); 26 | void setMaterial(int x, int y, int z, Material material); 27 | 28 | int getX(); 29 | int getZ(); 30 | 31 | Status getStatus(); 32 | 33 | void replaceAllMaterial(BlockData[] target, BlockData to); 34 | 35 | @Deprecated 36 | Biome getBiome(int x, int z); 37 | Biome getBiome(int x, int y, int z); 38 | @Deprecated 39 | void setBiome(int x, int z, Biome biome); 40 | void setBiome(int x, int y, int z, Biome biome); 41 | 42 | boolean hasFluid(int x, int y, int z); 43 | boolean isAir(int x, int y, int z); 44 | 45 | int getHighestY(int x, int z); 46 | 47 | /** 48 | * 區塊狀態 49 | */ 50 | enum Status { 51 | EMPTY (0), 52 | STRUCTURE_STARTS (1), 53 | STRUCTURE_REFERENCES(2), 54 | BIOMES (3), 55 | NOISE (4), 56 | SURFACE (5), 57 | CARVERS (6), 58 | LIQUID_CARVERS (7), 59 | FEATURES (8), 60 | LIGHT (9), 61 | SPAWN (10), 62 | HEIGHTMAPS (11), 63 | FULL (12); 64 | 65 | private final int sequence; 66 | Status(int sequence) { 67 | this.sequence = sequence; 68 | } 69 | 70 | public boolean isAbove(Status status) { 71 | return this.sequence >= status.sequence; 72 | } 73 | public boolean isUnder(Status status) { 74 | return this.sequence <= status.sequence; 75 | } 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /branch_1_19/src/main/java/xuan/cat/fartherviewdistance/api/branch/BranchChunkLight.java: -------------------------------------------------------------------------------- 1 | package xuan.cat.fartherviewdistance.api.branch; 2 | 3 | public interface BranchChunkLight { 4 | } 5 | -------------------------------------------------------------------------------- /branch_1_19/src/main/java/xuan/cat/fartherviewdistance/api/branch/BranchMinecraft.java: -------------------------------------------------------------------------------- 1 | package xuan.cat.fartherviewdistance.api.branch; 2 | 3 | import org.bukkit.Chunk; 4 | import org.bukkit.World; 5 | import org.bukkit.entity.Player; 6 | 7 | import java.io.IOException; 8 | 9 | public interface BranchMinecraft { 10 | BranchNBT getChunkNBTFromDisk(World world, int chunkX, int chunkZ) throws IOException; 11 | 12 | BranchChunk getChunkFromMemoryCache(World world, int chunkX, int chunkZ); 13 | 14 | BranchChunk fromChunk(World world, int chunkX, int chunkZ, BranchNBT nbt, boolean integralHeightmap); 15 | 16 | BranchChunkLight fromLight(World world, BranchNBT nbt); 17 | 18 | BranchChunkLight fromLight(World world); 19 | 20 | BranchChunk fromChunk(World world, Chunk chunk); 21 | 22 | BranchChunk.Status fromStatus(BranchNBT nbt); 23 | 24 | void injectPlayer(Player player); 25 | } 26 | -------------------------------------------------------------------------------- /branch_1_19/src/main/java/xuan/cat/fartherviewdistance/api/branch/BranchNBT.java: -------------------------------------------------------------------------------- 1 | package xuan.cat.fartherviewdistance.api.branch; 2 | 3 | public interface BranchNBT { 4 | } 5 | -------------------------------------------------------------------------------- /branch_1_19/src/main/java/xuan/cat/fartherviewdistance/api/branch/BranchPacket.java: -------------------------------------------------------------------------------- 1 | package xuan.cat.fartherviewdistance.api.branch; 2 | 3 | import org.bukkit.entity.Player; 4 | 5 | import java.util.function.Consumer; 6 | 7 | public interface BranchPacket { 8 | void sendViewDistance(Player player, int viewDistance); 9 | 10 | void sendUnloadChunk(Player player, int chunkX, int chunkZ); 11 | 12 | Consumer sendChunkAndLight(BranchChunk chunk, BranchChunkLight light, boolean needTile, Consumer consumeTraffic); 13 | 14 | void sendKeepAlive(Player player, long id); 15 | } 16 | -------------------------------------------------------------------------------- /branch_1_19/src/main/java/xuan/cat/fartherviewdistance/api/branch/packet/PacketEvent.java: -------------------------------------------------------------------------------- 1 | package xuan.cat.fartherviewdistance.api.branch.packet; 2 | 3 | import org.bukkit.Bukkit; 4 | import org.bukkit.entity.Player; 5 | import org.bukkit.event.Cancellable; 6 | import org.bukkit.event.Event; 7 | 8 | public abstract class PacketEvent extends Event implements Cancellable { 9 | private final Player player; 10 | private boolean cancel = false; 11 | 12 | public PacketEvent(Player player) { 13 | super(!Bukkit.isPrimaryThread()); 14 | this.player = player; 15 | } 16 | 17 | public final boolean isCancelled() { 18 | return cancel; 19 | } 20 | public final void setCancelled(boolean cancel) { 21 | this.cancel = cancel; 22 | } 23 | 24 | public final Player getPlayer() { 25 | return player; 26 | } 27 | } -------------------------------------------------------------------------------- /branch_1_19/src/main/java/xuan/cat/fartherviewdistance/api/branch/packet/PacketKeepAliveEvent.java: -------------------------------------------------------------------------------- 1 | package xuan.cat.fartherviewdistance.api.branch.packet; 2 | 3 | import org.bukkit.entity.Player; 4 | import org.bukkit.event.HandlerList; 5 | 6 | public final class PacketKeepAliveEvent extends PacketEvent { 7 | private static final HandlerList handlers = new HandlerList(); 8 | public HandlerList getHandlers() { 9 | return handlers; 10 | } 11 | public static HandlerList getHandlerList() { 12 | return handlers; 13 | } 14 | 15 | private final long id; 16 | 17 | public PacketKeepAliveEvent(Player player, long id) { 18 | super(player); 19 | this.id = id; 20 | } 21 | 22 | public long getId() { 23 | return id; 24 | } 25 | } -------------------------------------------------------------------------------- /branch_1_19/src/main/java/xuan/cat/fartherviewdistance/api/branch/packet/PacketMapChunkEvent.java: -------------------------------------------------------------------------------- 1 | package xuan.cat.fartherviewdistance.api.branch.packet; 2 | 3 | import org.bukkit.entity.Player; 4 | import org.bukkit.event.HandlerList; 5 | 6 | public final class PacketMapChunkEvent extends PacketEvent { 7 | private static final HandlerList handlers = new HandlerList(); 8 | public HandlerList getHandlers() { 9 | return handlers; 10 | } 11 | public static HandlerList getHandlerList() { 12 | return handlers; 13 | } 14 | 15 | private final int chunkX; 16 | private final int chunkZ; 17 | 18 | public PacketMapChunkEvent(Player player, int chunkX, int chunkZ) { 19 | super(player); 20 | this.chunkX = chunkX; 21 | this.chunkZ = chunkZ; 22 | } 23 | 24 | public int getChunkX() { 25 | return chunkX; 26 | } 27 | public int getChunkZ() { 28 | return chunkZ; 29 | } 30 | } -------------------------------------------------------------------------------- /branch_1_19/src/main/java/xuan/cat/fartherviewdistance/api/branch/packet/PacketUnloadChunkEvent.java: -------------------------------------------------------------------------------- 1 | package xuan.cat.fartherviewdistance.api.branch.packet; 2 | 3 | import org.bukkit.entity.Player; 4 | import org.bukkit.event.HandlerList; 5 | 6 | public final class PacketUnloadChunkEvent extends PacketEvent { 7 | private static final HandlerList handlers = new HandlerList(); 8 | public HandlerList getHandlers() { 9 | return handlers; 10 | } 11 | public static HandlerList getHandlerList() { 12 | return handlers; 13 | } 14 | 15 | private final int chunkX; 16 | private final int chunkZ; 17 | 18 | public PacketUnloadChunkEvent(Player player, int chunkX, int chunkZ) { 19 | super(player); 20 | this.chunkX = chunkX; 21 | this.chunkZ = chunkZ; 22 | } 23 | 24 | public int getChunkX() { 25 | return chunkX; 26 | } 27 | public int getChunkZ() { 28 | return chunkZ; 29 | } 30 | } -------------------------------------------------------------------------------- /branch_1_19/src/main/java/xuan/cat/fartherviewdistance/api/branch/packet/PacketViewDistanceEvent.java: -------------------------------------------------------------------------------- 1 | package xuan.cat.fartherviewdistance.api.branch.packet; 2 | 3 | import org.bukkit.entity.Player; 4 | import org.bukkit.event.HandlerList; 5 | 6 | public final class PacketViewDistanceEvent extends PacketEvent { 7 | private static final HandlerList handlers = new HandlerList(); 8 | public HandlerList getHandlers() { 9 | return handlers; 10 | } 11 | public static HandlerList getHandlerList() { 12 | return handlers; 13 | } 14 | 15 | private final int viewDistance; 16 | 17 | public PacketViewDistanceEvent(Player player, int viewDistance) { 18 | super(player); 19 | this.viewDistance = viewDistance; 20 | } 21 | 22 | public int getViewDistance() { 23 | return viewDistance; 24 | } 25 | 26 | } -------------------------------------------------------------------------------- /branch_1_19/src/main/java/xuan/cat/fartherviewdistance/code/branch/v19/Branch_19_ChunkLight.java: -------------------------------------------------------------------------------- 1 | package xuan.cat.fartherviewdistance.code.branch.v19; 2 | 3 | import net.minecraft.server.level.ServerLevel; 4 | import org.bukkit.World; 5 | import org.bukkit.craftbukkit.v1_19_R3.CraftWorld; 6 | import xuan.cat.fartherviewdistance.api.branch.BranchChunkLight; 7 | 8 | import java.util.Arrays; 9 | 10 | public final class Branch_19_ChunkLight implements BranchChunkLight { 11 | public static final byte[] EMPTY = new byte[0]; 12 | 13 | private final ServerLevel worldServer; 14 | private final byte[][] blockLights; 15 | private final byte[][] skyLights; 16 | 17 | public Branch_19_ChunkLight(World world) { 18 | this(((CraftWorld) world).getHandle()); 19 | } 20 | public Branch_19_ChunkLight(ServerLevel worldServer) { 21 | this(worldServer, new byte[worldServer.getSectionsCount() + 2][], new byte[worldServer.getSectionsCount() + 2][]); 22 | } 23 | public Branch_19_ChunkLight(ServerLevel worldServer, byte[][] blockLights, byte[][] skyLights) { 24 | this.worldServer = worldServer; 25 | this.blockLights = blockLights; 26 | this.skyLights = skyLights; 27 | Arrays.fill(blockLights, EMPTY); 28 | Arrays.fill(skyLights, EMPTY); 29 | } 30 | 31 | public ServerLevel getWorldServer() { 32 | return worldServer; 33 | } 34 | 35 | public int getArrayLength() { 36 | return blockLights.length; 37 | } 38 | 39 | public static int indexFromSectionY(ServerLevel worldServer, int sectionY) { 40 | return sectionY - worldServer.getMinSection() + 1; 41 | } 42 | 43 | public void setBlockLight(int sectionY, byte[] blockLight) { 44 | blockLights[indexFromSectionY(worldServer, sectionY)] = blockLight; 45 | } 46 | public void setSkyLight(int sectionY, byte[] skyLight) { 47 | skyLights[indexFromSectionY(worldServer, sectionY)] = skyLight; 48 | } 49 | 50 | public byte[] getBlockLight(int sectionY) { 51 | return blockLights[indexFromSectionY(worldServer, sectionY)]; 52 | } 53 | public byte[] getSkyLight(int sectionY) { 54 | return skyLights[indexFromSectionY(worldServer, sectionY)]; 55 | } 56 | 57 | public byte[][] getBlockLights() { 58 | return blockLights; 59 | } 60 | public byte[][] getSkyLights() { 61 | return skyLights; 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /branch_1_19/src/main/java/xuan/cat/fartherviewdistance/code/branch/v19/Branch_19_NBT.java: -------------------------------------------------------------------------------- 1 | package xuan.cat.fartherviewdistance.code.branch.v19; 2 | 3 | import net.minecraft.nbt.CompoundTag; 4 | import xuan.cat.fartherviewdistance.api.branch.BranchNBT; 5 | 6 | public final class Branch_19_NBT implements BranchNBT { 7 | 8 | protected CompoundTag tag; 9 | 10 | public Branch_19_NBT() { 11 | this.tag = new CompoundTag(); 12 | } 13 | 14 | public Branch_19_NBT(CompoundTag tag) { 15 | this.tag = tag; 16 | } 17 | 18 | 19 | public CompoundTag getNMSTag() { 20 | return tag; 21 | } 22 | 23 | @Override 24 | public String toString() { 25 | return tag.toString(); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /branch_1_19/src/main/java/xuan/cat/fartherviewdistance/code/branch/v19/Branch_19_Packet.java: -------------------------------------------------------------------------------- 1 | package xuan.cat.fartherviewdistance.code.branch.v19; 2 | 3 | import io.netty.buffer.Unpooled; 4 | import net.minecraft.network.Connection; 5 | import net.minecraft.network.FriendlyByteBuf; 6 | import net.minecraft.network.protocol.Packet; 7 | import net.minecraft.network.protocol.game.ClientboundForgetLevelChunkPacket; 8 | import net.minecraft.network.protocol.game.ClientboundKeepAlivePacket; 9 | import net.minecraft.network.protocol.game.ClientboundLevelChunkWithLightPacket; 10 | import net.minecraft.network.protocol.game.ClientboundSetChunkCacheRadiusPacket; 11 | import org.bukkit.craftbukkit.v1_19_R3.entity.CraftPlayer; 12 | import org.bukkit.entity.Player; 13 | import xuan.cat.fartherviewdistance.api.branch.BranchChunk; 14 | import xuan.cat.fartherviewdistance.api.branch.BranchChunkLight; 15 | import xuan.cat.fartherviewdistance.api.branch.BranchPacket; 16 | 17 | import java.util.function.Consumer; 18 | 19 | public final class Branch_19_Packet implements BranchPacket { 20 | private final Branch_19_PacketHandleChunk handleChunk = new Branch_19_PacketHandleChunk(); 21 | private final Branch_19_PacketHandleLightUpdate handleLightUpdate = new Branch_19_PacketHandleLightUpdate(); 22 | 23 | public void sendPacket(Player player, Packet packet) { 24 | try { 25 | Connection container = ((CraftPlayer) player).getHandle().connection.connection; 26 | container.send(packet); 27 | } catch (IllegalArgumentException ignored) { 28 | } 29 | } 30 | 31 | public void sendViewDistance(Player player, int viewDistance) { 32 | sendPacket(player, new ClientboundSetChunkCacheRadiusPacket(viewDistance)); 33 | } 34 | 35 | public void sendUnloadChunk(Player player, int chunkX, int chunkZ) { 36 | sendPacket(player, new ClientboundForgetLevelChunkPacket(chunkX, chunkZ)); 37 | } 38 | 39 | public Consumer sendChunkAndLight(BranchChunk chunk, BranchChunkLight light, boolean needTile, Consumer consumeTraffic) { 40 | FriendlyByteBuf serializer = new FriendlyByteBuf(Unpooled.buffer().writerIndex(0)); 41 | serializer.writeInt(chunk.getX()); 42 | serializer.writeInt(chunk.getZ()); 43 | this.handleChunk.write(serializer, ((Branch_19_Chunk) chunk).getLevelChunk(), needTile); 44 | this.handleLightUpdate.write(serializer, (Branch_19_ChunkLight) light, true); 45 | consumeTraffic.accept(serializer.readableBytes()); 46 | ClientboundLevelChunkWithLightPacket packet = new ClientboundLevelChunkWithLightPacket(serializer); 47 | try { 48 | // 適用於 paper 49 | packet.setReady(true); 50 | } catch (NoSuchMethodError noSuchMethodError) { 51 | // 適用於 spigot (不推薦) 52 | } 53 | return (player) -> sendPacket(player, packet); 54 | } 55 | 56 | public void sendKeepAlive(Player player, long id) { 57 | sendPacket(player, new ClientboundKeepAlivePacket(id)); 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /branch_1_19/src/main/java/xuan/cat/fartherviewdistance/code/branch/v19/Branch_19_PacketHandleChunk.java: -------------------------------------------------------------------------------- 1 | package xuan.cat.fartherviewdistance.code.branch.v19; 2 | 3 | import io.netty.buffer.Unpooled; 4 | import net.minecraft.core.BlockPos; 5 | import net.minecraft.core.SectionPos; 6 | import net.minecraft.core.registries.BuiltInRegistries; 7 | import net.minecraft.nbt.CompoundTag; 8 | import net.minecraft.nbt.LongArrayTag; 9 | import net.minecraft.network.FriendlyByteBuf; 10 | import net.minecraft.world.level.block.entity.BlockEntity; 11 | import net.minecraft.world.level.chunk.LevelChunk; 12 | import net.minecraft.world.level.chunk.LevelChunkSection; 13 | import net.minecraft.world.level.levelgen.Heightmap; 14 | 15 | import java.util.HashMap; 16 | import java.util.Map; 17 | 18 | public final class Branch_19_PacketHandleChunk { 19 | public Branch_19_PacketHandleChunk() { 20 | } 21 | 22 | public void write(FriendlyByteBuf serializer, LevelChunk chunk, boolean needTile) { 23 | CompoundTag heightmapsNBT = new CompoundTag(); 24 | for (Map.Entry entry : chunk.getHeightmaps()) { 25 | Heightmap.Types heightType = entry.getKey(); 26 | Heightmap heightMap = entry.getValue(); 27 | if (heightType.sendToClient()) 28 | heightmapsNBT.put(heightType.getSerializationKey(), new LongArrayTag(heightMap.getRawData())); 29 | } 30 | 31 | int chunkSize = 0; 32 | for(LevelChunkSection section : chunk.getSections()) { 33 | chunkSize += section.getSerializedSize(); 34 | } 35 | byte[] bufferBytes = new byte[chunkSize]; 36 | FriendlyByteBuf bufferByteBuf = new FriendlyByteBuf(Unpooled.wrappedBuffer(bufferBytes)); 37 | bufferByteBuf.writerIndex(0); 38 | for(LevelChunkSection section : chunk.getSections()) { 39 | section.write(bufferByteBuf); 40 | } 41 | 42 | serializer.writeNbt(heightmapsNBT); 43 | serializer.writeVarInt(bufferBytes.length); 44 | serializer.writeBytes(bufferBytes); 45 | 46 | Map blockEntityMap = !needTile ? new HashMap<>(0) : chunk.getBlockEntities(); 47 | serializer.writeCollection(blockEntityMap.entrySet(), (buf, entry) -> { 48 | BlockEntity blockEntity = entry.getValue(); 49 | CompoundTag entityNBT = blockEntity.getUpdateTag(); 50 | BlockPos blockPos = blockEntity.getBlockPos(); 51 | buf.writeByte(SectionPos.sectionRelative(blockPos.getX()) << 4 | SectionPos.sectionRelative(blockPos.getZ())); 52 | buf.writeShort(blockPos.getY()); 53 | buf.writeVarInt(BuiltInRegistries.BLOCK_ENTITY_TYPE.getId(blockEntity.getType())); 54 | buf.writeNbt(entityNBT.isEmpty() ? null : entityNBT); 55 | }); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /branch_1_19/src/main/java/xuan/cat/fartherviewdistance/code/branch/v19/Branch_19_PacketHandleLightUpdate.java: -------------------------------------------------------------------------------- 1 | package xuan.cat.fartherviewdistance.code.branch.v19; 2 | 3 | import net.minecraft.network.FriendlyByteBuf; 4 | 5 | import java.util.ArrayList; 6 | import java.util.BitSet; 7 | import java.util.List; 8 | 9 | public final class Branch_19_PacketHandleLightUpdate { 10 | public Branch_19_PacketHandleLightUpdate() { 11 | } 12 | 13 | public void write(FriendlyByteBuf serializer, Branch_19_ChunkLight light, boolean trustEdges) { 14 | List dataSky = new ArrayList<>(); 15 | List dataBlock = new ArrayList<>(); 16 | BitSet notSkyEmpty = new BitSet(); 17 | BitSet notBlockEmpty = new BitSet(); 18 | BitSet isSkyEmpty = new BitSet(); 19 | BitSet isBlockEmpty = new BitSet(); 20 | 21 | for (int index = 0; index < light.getArrayLength(); ++index) { 22 | saveBitSet(light.getSkyLights(), index, notSkyEmpty, isSkyEmpty, dataSky); 23 | saveBitSet(light.getBlockLights(), index, notBlockEmpty, isBlockEmpty, dataBlock); 24 | } 25 | 26 | serializer.writeBoolean(trustEdges); 27 | serializer.writeBitSet(notSkyEmpty); 28 | serializer.writeBitSet(notBlockEmpty); 29 | serializer.writeBitSet(isSkyEmpty); 30 | serializer.writeBitSet(isBlockEmpty); 31 | serializer.writeCollection(dataSky, FriendlyByteBuf::writeByteArray); 32 | serializer.writeCollection(dataBlock, FriendlyByteBuf::writeByteArray); 33 | } 34 | 35 | private static void saveBitSet(byte[][] nibbleArrays, int index, BitSet notEmpty, BitSet isEmpty, List list) { 36 | byte[] nibbleArray = nibbleArrays[index]; 37 | if (nibbleArray != Branch_19_ChunkLight.EMPTY) { 38 | if (nibbleArray == null) { 39 | isEmpty.set(index); 40 | } else { 41 | notEmpty.set(index); 42 | list.add(nibbleArray); 43 | } 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /pack.bat: -------------------------------------------------------------------------------- 1 | rmdir /s /q temporary 2 | mkdir temporary 3 | del pack.jar 4 | "C:\Program Files\7-Zip\7z.exe" x .\target\*.jar -o.\temporary\ 5 | 6 | "C:\Program Files\7-Zip\7z.exe" x .\branch_1_14\target\branch_1_14-r1.jar -o.\temporary\ -y 7 | "C:\Program Files\7-Zip\7z.exe" x .\branch_1_15\target\branch_1_15-r1.jar -o.\temporary\ -y 8 | "C:\Program Files\7-Zip\7z.exe" x .\branch_1_16\target\branch_1_16-r3.jar -o.\temporary\ -y 9 | "C:\Program Files\7-Zip\7z.exe" x .\branch_1_17\target\branch_1_17-r1.jar -o.\temporary\ -y 10 | "C:\Program Files\7-Zip\7z.exe" x .\branch_1_18\target\branch_1_18-r1.jar -o.\temporary\ -y 11 | "C:\Program Files\7-Zip\7z.exe" x .\branch_1_19\target\branch_1_19-r1.jar -o.\temporary\ -y 12 | 13 | "C:\Program Files\7-Zip\7z.exe" a -aou pack.jar .\temporary\* 14 | rmdir /s /q temporary -------------------------------------------------------------------------------- /src/main/java/xuan/cat/fartherviewdistance/api/ViewDistance.java: -------------------------------------------------------------------------------- 1 | package xuan.cat.fartherviewdistance.api; 2 | 3 | import org.bukkit.entity.Player; 4 | import xuan.cat.fartherviewdistance.api.data.PlayerView; 5 | import xuan.cat.fartherviewdistance.code.ChunkIndex; 6 | import xuan.cat.fartherviewdistance.code.data.PlayerChunkView; 7 | 8 | public final class ViewDistance { 9 | private ViewDistance() { 10 | } 11 | 12 | 13 | public static PlayerView getPlayerView(Player player) { 14 | PlayerChunkView view = ChunkIndex.getChunkServer().getView(player); 15 | return view != null ? view.viewAPI : null; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/main/java/xuan/cat/fartherviewdistance/api/branch/BranchChunk.java: -------------------------------------------------------------------------------- 1 | package xuan.cat.fartherviewdistance.api.branch; 2 | 3 | import org.bukkit.Chunk; 4 | import org.bukkit.Material; 5 | import org.bukkit.World; 6 | import org.bukkit.block.Biome; 7 | import org.bukkit.block.data.BlockData; 8 | import org.bukkit.util.Vector; 9 | 10 | import java.util.List; 11 | import java.util.Map; 12 | 13 | public interface BranchChunk { 14 | BranchNBT toNBT(BranchChunkLight light, List asyncRunnable); 15 | 16 | Chunk getChunk(); 17 | 18 | World getWorld(); 19 | 20 | boolean equalsBlockData(int x, int y, int z, BlockData blockData); 21 | BlockData getBlockData(int x, int y, int z); 22 | void setBlockData(int x, int y, int z, BlockData blockData); 23 | Map getBlockDataMap(); 24 | 25 | Material getMaterial(int x, int y, int z); 26 | void setMaterial(int x, int y, int z, Material material); 27 | 28 | int getX(); 29 | int getZ(); 30 | 31 | Status getStatus(); 32 | 33 | void replaceAllMaterial(BlockData[] target, BlockData to); 34 | 35 | @Deprecated 36 | Biome getBiome(int x, int z); 37 | Biome getBiome(int x, int y, int z); 38 | @Deprecated 39 | void setBiome(int x, int z, Biome biome); 40 | void setBiome(int x, int y, int z, Biome biome); 41 | 42 | boolean hasFluid(int x, int y, int z); 43 | boolean isAir(int x, int y, int z); 44 | 45 | int getHighestY(int x, int z); 46 | 47 | /** 48 | * 區塊狀態 49 | */ 50 | enum Status { 51 | EMPTY (0), 52 | STRUCTURE_STARTS (1), 53 | STRUCTURE_REFERENCES(2), 54 | BIOMES (3), 55 | NOISE (4), 56 | SURFACE (5), 57 | CARVERS (6), 58 | LIQUID_CARVERS (7), 59 | FEATURES (8), 60 | LIGHT (9), 61 | SPAWN (10), 62 | HEIGHTMAPS (11), 63 | FULL (12); 64 | 65 | private final int sequence; 66 | Status(int sequence) { 67 | this.sequence = sequence; 68 | } 69 | 70 | public boolean isAbove(Status status) { 71 | return this.sequence >= status.sequence; 72 | } 73 | public boolean isUnder(Status status) { 74 | return this.sequence <= status.sequence; 75 | } 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /src/main/java/xuan/cat/fartherviewdistance/api/branch/BranchChunkLight.java: -------------------------------------------------------------------------------- 1 | package xuan.cat.fartherviewdistance.api.branch; 2 | 3 | public interface BranchChunkLight { 4 | } 5 | -------------------------------------------------------------------------------- /src/main/java/xuan/cat/fartherviewdistance/api/branch/BranchMinecraft.java: -------------------------------------------------------------------------------- 1 | package xuan.cat.fartherviewdistance.api.branch; 2 | 3 | import org.bukkit.Chunk; 4 | import org.bukkit.World; 5 | import org.bukkit.entity.Player; 6 | 7 | import java.io.IOException; 8 | 9 | public interface BranchMinecraft { 10 | BranchNBT getChunkNBTFromDisk(World world, int chunkX, int chunkZ) throws IOException; 11 | 12 | BranchChunk getChunkFromMemoryCache(World world, int chunkX, int chunkZ); 13 | 14 | BranchChunk fromChunk(World world, int chunkX, int chunkZ, BranchNBT nbt, boolean integralHeightmap); 15 | 16 | BranchChunkLight fromLight(World world, BranchNBT nbt); 17 | 18 | BranchChunkLight fromLight(World world); 19 | 20 | BranchChunk fromChunk(World world, Chunk chunk); 21 | 22 | BranchChunk.Status fromStatus(BranchNBT nbt); 23 | 24 | void injectPlayer(Player player); 25 | } 26 | -------------------------------------------------------------------------------- /src/main/java/xuan/cat/fartherviewdistance/api/branch/BranchNBT.java: -------------------------------------------------------------------------------- 1 | package xuan.cat.fartherviewdistance.api.branch; 2 | 3 | public interface BranchNBT { 4 | } 5 | -------------------------------------------------------------------------------- /src/main/java/xuan/cat/fartherviewdistance/api/branch/BranchPacket.java: -------------------------------------------------------------------------------- 1 | package xuan.cat.fartherviewdistance.api.branch; 2 | 3 | import org.bukkit.entity.Player; 4 | 5 | import java.util.function.Consumer; 6 | 7 | public interface BranchPacket { 8 | void sendViewDistance(Player player, int viewDistance); 9 | 10 | void sendUnloadChunk(Player player, int chunkX, int chunkZ); 11 | 12 | Consumer sendChunkAndLight(BranchChunk chunk, BranchChunkLight light, boolean needTile, Consumer consumeTraffic); 13 | 14 | void sendKeepAlive(Player player, long id); 15 | } 16 | -------------------------------------------------------------------------------- /src/main/java/xuan/cat/fartherviewdistance/api/branch/packet/PacketEvent.java: -------------------------------------------------------------------------------- 1 | package xuan.cat.fartherviewdistance.api.branch.packet; 2 | 3 | import org.bukkit.Bukkit; 4 | import org.bukkit.entity.Player; 5 | import org.bukkit.event.Cancellable; 6 | import org.bukkit.event.Event; 7 | 8 | public abstract class PacketEvent extends Event implements Cancellable { 9 | private final Player player; 10 | private boolean cancel = false; 11 | 12 | public PacketEvent(Player player) { 13 | super(!Bukkit.isPrimaryThread()); 14 | this.player = player; 15 | } 16 | 17 | public final boolean isCancelled() { 18 | return cancel; 19 | } 20 | public final void setCancelled(boolean cancel) { 21 | this.cancel = cancel; 22 | } 23 | 24 | public final Player getPlayer() { 25 | return player; 26 | } 27 | } -------------------------------------------------------------------------------- /src/main/java/xuan/cat/fartherviewdistance/api/branch/packet/PacketKeepAliveEvent.java: -------------------------------------------------------------------------------- 1 | package xuan.cat.fartherviewdistance.api.branch.packet; 2 | 3 | import org.bukkit.entity.Player; 4 | import org.bukkit.event.HandlerList; 5 | 6 | public final class PacketKeepAliveEvent extends PacketEvent { 7 | private static final HandlerList handlers = new HandlerList(); 8 | public HandlerList getHandlers() { 9 | return handlers; 10 | } 11 | public static HandlerList getHandlerList() { 12 | return handlers; 13 | } 14 | 15 | private final long id; 16 | 17 | public PacketKeepAliveEvent(Player player, long id) { 18 | super(player); 19 | this.id = id; 20 | } 21 | 22 | public long getId() { 23 | return id; 24 | } 25 | } -------------------------------------------------------------------------------- /src/main/java/xuan/cat/fartherviewdistance/api/branch/packet/PacketMapChunkEvent.java: -------------------------------------------------------------------------------- 1 | package xuan.cat.fartherviewdistance.api.branch.packet; 2 | 3 | import org.bukkit.entity.Player; 4 | import org.bukkit.event.HandlerList; 5 | 6 | public final class PacketMapChunkEvent extends PacketEvent { 7 | private static final HandlerList handlers = new HandlerList(); 8 | public HandlerList getHandlers() { 9 | return handlers; 10 | } 11 | public static HandlerList getHandlerList() { 12 | return handlers; 13 | } 14 | 15 | private final int chunkX; 16 | private final int chunkZ; 17 | 18 | public PacketMapChunkEvent(Player player, int chunkX, int chunkZ) { 19 | super(player); 20 | this.chunkX = chunkX; 21 | this.chunkZ = chunkZ; 22 | } 23 | 24 | public int getChunkX() { 25 | return chunkX; 26 | } 27 | public int getChunkZ() { 28 | return chunkZ; 29 | } 30 | } -------------------------------------------------------------------------------- /src/main/java/xuan/cat/fartherviewdistance/api/branch/packet/PacketUnloadChunkEvent.java: -------------------------------------------------------------------------------- 1 | package xuan.cat.fartherviewdistance.api.branch.packet; 2 | 3 | import org.bukkit.entity.Player; 4 | import org.bukkit.event.HandlerList; 5 | 6 | public final class PacketUnloadChunkEvent extends PacketEvent { 7 | private static final HandlerList handlers = new HandlerList(); 8 | public HandlerList getHandlers() { 9 | return handlers; 10 | } 11 | public static HandlerList getHandlerList() { 12 | return handlers; 13 | } 14 | 15 | private final int chunkX; 16 | private final int chunkZ; 17 | 18 | public PacketUnloadChunkEvent(Player player, int chunkX, int chunkZ) { 19 | super(player); 20 | this.chunkX = chunkX; 21 | this.chunkZ = chunkZ; 22 | } 23 | 24 | public int getChunkX() { 25 | return chunkX; 26 | } 27 | public int getChunkZ() { 28 | return chunkZ; 29 | } 30 | } -------------------------------------------------------------------------------- /src/main/java/xuan/cat/fartherviewdistance/api/branch/packet/PacketViewDistanceEvent.java: -------------------------------------------------------------------------------- 1 | package xuan.cat.fartherviewdistance.api.branch.packet; 2 | 3 | import org.bukkit.entity.Player; 4 | import org.bukkit.event.HandlerList; 5 | 6 | public final class PacketViewDistanceEvent extends PacketEvent { 7 | private static final HandlerList handlers = new HandlerList(); 8 | public HandlerList getHandlers() { 9 | return handlers; 10 | } 11 | public static HandlerList getHandlerList() { 12 | return handlers; 13 | } 14 | 15 | private final int viewDistance; 16 | 17 | public PacketViewDistanceEvent(Player player, int viewDistance) { 18 | super(player); 19 | this.viewDistance = viewDistance; 20 | } 21 | 22 | public int getViewDistance() { 23 | return viewDistance; 24 | } 25 | 26 | } -------------------------------------------------------------------------------- /src/main/java/xuan/cat/fartherviewdistance/api/event/ExtendChunkEvent.java: -------------------------------------------------------------------------------- 1 | package xuan.cat.fartherviewdistance.api.event; 2 | 3 | import org.bukkit.Bukkit; 4 | import org.bukkit.event.Event; 5 | import xuan.cat.fartherviewdistance.api.data.PlayerView; 6 | 7 | public abstract class ExtendChunkEvent extends Event { 8 | private final PlayerView view; 9 | 10 | 11 | public ExtendChunkEvent(PlayerView view) { 12 | super(!Bukkit.isPrimaryThread()); 13 | this.view = view; 14 | } 15 | 16 | 17 | public PlayerView getView() { 18 | return view; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/main/java/xuan/cat/fartherviewdistance/api/event/PlayerCheckViewDistanceEvent.java: -------------------------------------------------------------------------------- 1 | package xuan.cat.fartherviewdistance.api.event; 2 | 3 | import org.bukkit.event.HandlerList; 4 | import xuan.cat.fartherviewdistance.api.data.PlayerView; 5 | 6 | public final class PlayerCheckViewDistanceEvent extends ExtendChunkEvent { 7 | private static final HandlerList handlers = new HandlerList(); 8 | 9 | private final int serverDistance; 10 | private final int clientDistance; 11 | private final int maxDistance; 12 | private Integer forciblyDistance; 13 | 14 | 15 | public PlayerCheckViewDistanceEvent(PlayerView view, int serverDistance, int clientDistance, int maxDistance) { 16 | super(view); 17 | this.serverDistance = serverDistance; 18 | this.clientDistance = clientDistance; 19 | this.maxDistance = maxDistance; 20 | } 21 | 22 | 23 | public int getClientDistance() { 24 | return clientDistance; 25 | } 26 | 27 | public int getMaxDistance() { 28 | return maxDistance; 29 | } 30 | 31 | public int getServerDistance() { 32 | return serverDistance; 33 | } 34 | 35 | public Integer getForciblyDistance() { 36 | return forciblyDistance; 37 | } 38 | 39 | public void setForciblyDistance(Integer forciblyDistance) { 40 | this.forciblyDistance = forciblyDistance; 41 | } 42 | 43 | 44 | public HandlerList getHandlers() { 45 | return handlers; 46 | } 47 | 48 | public static HandlerList getHandlerList() { 49 | return handlers; 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /src/main/java/xuan/cat/fartherviewdistance/api/event/PlayerInitViewEvent.java: -------------------------------------------------------------------------------- 1 | package xuan.cat.fartherviewdistance.api.event; 2 | 3 | import org.bukkit.event.HandlerList; 4 | import xuan.cat.fartherviewdistance.api.data.PlayerView; 5 | 6 | public final class PlayerInitViewEvent extends ExtendChunkEvent { 7 | private static final HandlerList handlers = new HandlerList(); 8 | 9 | 10 | public PlayerInitViewEvent(PlayerView view) { 11 | super(view); 12 | } 13 | 14 | 15 | public HandlerList getHandlers() { 16 | return handlers; 17 | } 18 | 19 | public static HandlerList getHandlerList() { 20 | return handlers; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/main/java/xuan/cat/fartherviewdistance/api/event/PlayerSendExtendChunkEvent.java: -------------------------------------------------------------------------------- 1 | package xuan.cat.fartherviewdistance.api.event; 2 | 3 | import org.bukkit.World; 4 | import org.bukkit.event.Cancellable; 5 | import org.bukkit.event.HandlerList; 6 | import xuan.cat.fartherviewdistance.api.branch.BranchChunk; 7 | import xuan.cat.fartherviewdistance.api.data.PlayerView; 8 | 9 | /** 10 | * 發送延伸的區塊給玩家時 11 | */ 12 | public final class PlayerSendExtendChunkEvent extends ExtendChunkEvent implements Cancellable { 13 | private static final HandlerList handlers = new HandlerList(); 14 | 15 | private boolean cancel = false; 16 | private final BranchChunk chunk; 17 | private final World world; 18 | 19 | 20 | public PlayerSendExtendChunkEvent(PlayerView view, BranchChunk chunk, World world) { 21 | super(view); 22 | this.chunk = chunk; 23 | this.world = world; 24 | } 25 | 26 | 27 | public BranchChunk getChunk() { 28 | return chunk; 29 | } 30 | 31 | public World getWorld() { 32 | return world; 33 | } 34 | 35 | public boolean isCancelled() { 36 | return cancel; 37 | } 38 | 39 | public void setCancelled(boolean cancel) { 40 | this.cancel = cancel; 41 | } 42 | 43 | 44 | public HandlerList getHandlers() { 45 | return handlers; 46 | } 47 | 48 | public static HandlerList getHandlerList() { 49 | return handlers; 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /src/main/java/xuan/cat/fartherviewdistance/api/event/PlayerSendUnloadChunkEvent.java: -------------------------------------------------------------------------------- 1 | package xuan.cat.fartherviewdistance.api.event; 2 | 3 | import org.bukkit.event.Cancellable; 4 | import org.bukkit.event.HandlerList; 5 | import xuan.cat.fartherviewdistance.api.data.PlayerView; 6 | 7 | /** 8 | * 發送區塊卸除給玩家時 9 | */ 10 | public final class PlayerSendUnloadChunkEvent extends ExtendChunkEvent implements Cancellable { 11 | private static final HandlerList handlers = new HandlerList(); 12 | 13 | private boolean cancel = false; 14 | private final int chunkX; 15 | private final int chunkZ; 16 | 17 | 18 | public PlayerSendUnloadChunkEvent(PlayerView view, int chunkX, int chunkZ) { 19 | super(view); 20 | this.chunkX = chunkX; 21 | this.chunkZ = chunkZ; 22 | } 23 | 24 | 25 | public int getChunkX() { 26 | return chunkX; 27 | } 28 | 29 | public int getChunkZ() { 30 | return chunkZ; 31 | } 32 | 33 | public boolean isCancelled() { 34 | return cancel; 35 | } 36 | 37 | public void setCancelled(boolean cancel) { 38 | this.cancel = cancel; 39 | } 40 | 41 | 42 | public HandlerList getHandlers() { 43 | return handlers; 44 | } 45 | 46 | public static HandlerList getHandlerList() { 47 | return handlers; 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/main/java/xuan/cat/fartherviewdistance/api/event/PlayerSendViewDistanceEvent.java: -------------------------------------------------------------------------------- 1 | package xuan.cat.fartherviewdistance.api.event; 2 | 3 | import org.bukkit.event.Cancellable; 4 | import org.bukkit.event.HandlerList; 5 | import xuan.cat.fartherviewdistance.api.data.PlayerView; 6 | 7 | public final class PlayerSendViewDistanceEvent extends ExtendChunkEvent implements Cancellable { 8 | private static final HandlerList handlers = new HandlerList(); 9 | 10 | private boolean cancel = false; 11 | private int distance; 12 | 13 | 14 | public PlayerSendViewDistanceEvent(PlayerView view, int distance) { 15 | super(view); 16 | this.distance = distance; 17 | } 18 | 19 | 20 | public int getDistance() { 21 | return distance; 22 | } 23 | 24 | public void setDistance(int distance) { 25 | this.distance = distance; 26 | } 27 | 28 | public boolean isCancelled() { 29 | return cancel; 30 | } 31 | 32 | public void setCancelled(boolean cancel) { 33 | this.cancel = cancel; 34 | } 35 | 36 | 37 | public HandlerList getHandlers() { 38 | return handlers; 39 | } 40 | 41 | public static HandlerList getHandlerList() { 42 | return handlers; 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/main/java/xuan/cat/fartherviewdistance/api/event/PlayerViewMarkSendChunkEvent.java: -------------------------------------------------------------------------------- 1 | package xuan.cat.fartherviewdistance.api.event; 2 | 3 | import org.bukkit.event.Cancellable; 4 | import org.bukkit.event.HandlerList; 5 | import xuan.cat.fartherviewdistance.api.data.PlayerView; 6 | 7 | public final class PlayerViewMarkSendChunkEvent extends ExtendChunkEvent implements Cancellable { 8 | private static final HandlerList handlers = new HandlerList(); 9 | 10 | private boolean cancel = false; 11 | private final int chunkX; 12 | private final int chunkZ; 13 | 14 | 15 | public PlayerViewMarkSendChunkEvent(PlayerView view, int chunkX, int chunkZ) { 16 | super(view); 17 | this.chunkX = chunkX; 18 | this.chunkZ = chunkZ; 19 | } 20 | 21 | 22 | public int getChunkX() { 23 | return chunkX; 24 | } 25 | 26 | public int getChunkZ() { 27 | return chunkZ; 28 | } 29 | 30 | public boolean isCancelled() { 31 | return cancel; 32 | } 33 | 34 | public void setCancelled(boolean cancel) { 35 | this.cancel = cancel; 36 | } 37 | 38 | 39 | public HandlerList getHandlers() { 40 | return handlers; 41 | } 42 | 43 | public static HandlerList getHandlerList() { 44 | return handlers; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/main/java/xuan/cat/fartherviewdistance/api/event/PlayerViewMarkWaitChunkEvent.java: -------------------------------------------------------------------------------- 1 | package xuan.cat.fartherviewdistance.api.event; 2 | 3 | import org.bukkit.event.Cancellable; 4 | import org.bukkit.event.HandlerList; 5 | import xuan.cat.fartherviewdistance.api.data.PlayerView; 6 | 7 | public final class PlayerViewMarkWaitChunkEvent extends ExtendChunkEvent implements Cancellable { 8 | private static final HandlerList handlers = new HandlerList(); 9 | 10 | private boolean cancel = false; 11 | private final int chunkX; 12 | private final int chunkZ; 13 | 14 | 15 | public PlayerViewMarkWaitChunkEvent(PlayerView view, int chunkX, int chunkZ) { 16 | super(view); 17 | this.chunkX = chunkX; 18 | this.chunkZ = chunkZ; 19 | } 20 | 21 | 22 | public int getChunkX() { 23 | return chunkX; 24 | } 25 | 26 | public int getChunkZ() { 27 | return chunkZ; 28 | } 29 | 30 | public boolean isCancelled() { 31 | return cancel; 32 | } 33 | 34 | public void setCancelled(boolean cancel) { 35 | this.cancel = cancel; 36 | } 37 | 38 | 39 | public HandlerList getHandlers() { 40 | return handlers; 41 | } 42 | 43 | public static HandlerList getHandlerList() { 44 | return handlers; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/main/java/xuan/cat/fartherviewdistance/code/ChunkPlaceholder.java: -------------------------------------------------------------------------------- 1 | package xuan.cat.fartherviewdistance.code; 2 | 3 | import me.clip.placeholderapi.expansion.PlaceholderExpansion; 4 | import org.bukkit.OfflinePlayer; 5 | import org.bukkit.entity.Player; 6 | import xuan.cat.fartherviewdistance.api.ViewDistance; 7 | import xuan.cat.fartherviewdistance.api.data.PlayerView; 8 | 9 | import java.util.Locale; 10 | 11 | public final class ChunkPlaceholder extends PlaceholderExpansion { 12 | private static ChunkPlaceholder imp; 13 | public static void registerPlaceholder() { 14 | imp = new ChunkPlaceholder(); 15 | imp.register(); 16 | } 17 | public static void unregisterPlaceholder() { 18 | if (imp != null) { 19 | imp.unregister(); 20 | } 21 | } 22 | 23 | @Override 24 | public boolean persist() { 25 | return true; 26 | } 27 | 28 | @Override 29 | public boolean canRegister() { 30 | return true; 31 | } 32 | 33 | @Override 34 | public String getIdentifier() { 35 | return "viewdistance"; 36 | } 37 | 38 | @Override 39 | public String getAuthor() { 40 | return "xuancat0208"; 41 | } 42 | 43 | @Override 44 | public String getVersion() { 45 | return "FartherViewDistancePlaceholder 0.0.1"; 46 | } 47 | 48 | @Override 49 | public String onRequest(OfflinePlayer offlinePlayer, String params) { 50 | if (!(offlinePlayer instanceof Player)) 51 | return "-"; 52 | Player player = (Player) offlinePlayer; 53 | PlayerView playerView = ViewDistance.getPlayerView(player); 54 | if (playerView == null) 55 | return "-"; 56 | switch (params.toLowerCase(Locale.ROOT)) { 57 | case "delay": 58 | return String.valueOf(playerView.getDelay()); 59 | case "forcibly_max_distance": 60 | return String.valueOf(playerView.getForciblyMaxDistance()); 61 | case "max_extend_view_distance": 62 | return String.valueOf(playerView.getMaxExtendViewDistance()); 63 | case "now_extend_view_distance": 64 | return String.valueOf(playerView.getNowExtendViewDistance()); 65 | case "now_server_view_distance": 66 | return String.valueOf(playerView.getNowServerViewDistance()); 67 | case "forcibly_send_second_max_bytes": 68 | return String.valueOf(playerView.getForciblySendSecondMaxBytes()); 69 | case "network_speed_avg": 70 | return String.valueOf(playerView.getNetworkSpeedAVG()); 71 | case "network_report_load_fast_5s": 72 | return String.valueOf(playerView.getNetworkReportLoadFast5s()); 73 | case "network_report_load_fast_1m": 74 | return String.valueOf(playerView.getNetworkReportLoadFast1m()); 75 | case "network_report_load_fast_5m": 76 | return String.valueOf(playerView.getNetworkReportLoadFast5m()); 77 | case "network_report_load_slow_5s": 78 | return String.valueOf(playerView.getNetworkReportLoadSlow5s()); 79 | case "network_report_load_slow_1m": 80 | return String.valueOf(playerView.getNetworkReportLoadSlow1m()); 81 | case "network_report_load_slow_5m": 82 | return String.valueOf(playerView.getNetworkReportLoadSlow5m()); 83 | case "network_report_consume_5s": 84 | return String.valueOf(playerView.getNetworkReportConsume5s()); 85 | case "network_report_consume_1m": 86 | return String.valueOf(playerView.getNetworkReportConsume1m()); 87 | case "network_report_consume_5m": 88 | return String.valueOf(playerView.getNetworkReportConsume5m()); 89 | default: 90 | return null; 91 | } 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /src/main/java/xuan/cat/fartherviewdistance/code/branch/v14/Branch_14_Minecraft.java: -------------------------------------------------------------------------------- 1 | package xuan.cat.fartherviewdistance.code.branch.v14; 2 | 3 | import org.bukkit.Chunk; 4 | import org.bukkit.World; 5 | import org.bukkit.entity.Player; 6 | import xuan.cat.fartherviewdistance.api.branch.BranchChunk; 7 | import xuan.cat.fartherviewdistance.api.branch.BranchChunkLight; 8 | import xuan.cat.fartherviewdistance.api.branch.BranchMinecraft; 9 | import xuan.cat.fartherviewdistance.api.branch.BranchNBT; 10 | 11 | import java.io.IOException; 12 | 13 | public final class Branch_14_Minecraft implements BranchMinecraft { 14 | @Override 15 | public BranchNBT getChunkNBTFromDisk(World world, int chunkX, int chunkZ) throws IOException { 16 | throw new UnsupportedOperationException(); 17 | } 18 | 19 | @Override 20 | public BranchChunk getChunkFromMemoryCache(World world, int chunkX, int chunkZ) { 21 | throw new UnsupportedOperationException(); 22 | } 23 | 24 | @Override 25 | public BranchChunk fromChunk(World world, int chunkX, int chunkZ, BranchNBT nbt, boolean integralHeightmap) { 26 | throw new UnsupportedOperationException(); 27 | } 28 | 29 | @Override 30 | public BranchChunkLight fromLight(World world, BranchNBT nbt) { 31 | throw new UnsupportedOperationException(); 32 | } 33 | 34 | @Override 35 | public BranchChunkLight fromLight(World world) { 36 | throw new UnsupportedOperationException(); 37 | } 38 | 39 | @Override 40 | public BranchChunk fromChunk(World world, Chunk chunk) { 41 | throw new UnsupportedOperationException(); 42 | } 43 | 44 | @Override 45 | public BranchChunk.Status fromStatus(BranchNBT nbt) { 46 | throw new UnsupportedOperationException(); 47 | } 48 | 49 | @Override 50 | public void injectPlayer(Player player) { 51 | throw new UnsupportedOperationException(); 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/main/java/xuan/cat/fartherviewdistance/code/branch/v14/Branch_14_Packet.java: -------------------------------------------------------------------------------- 1 | package xuan.cat.fartherviewdistance.code.branch.v14; 2 | 3 | import org.bukkit.entity.Player; 4 | import xuan.cat.fartherviewdistance.api.branch.BranchChunk; 5 | import xuan.cat.fartherviewdistance.api.branch.BranchChunkLight; 6 | import xuan.cat.fartherviewdistance.api.branch.BranchPacket; 7 | 8 | import java.util.function.Consumer; 9 | 10 | public final class Branch_14_Packet implements BranchPacket { 11 | @Override 12 | public void sendViewDistance(Player player, int viewDistance) { 13 | throw new UnsupportedOperationException(); 14 | } 15 | 16 | @Override 17 | public void sendUnloadChunk(Player player, int chunkX, int chunkZ) { 18 | throw new UnsupportedOperationException(); 19 | } 20 | 21 | @Override 22 | public Consumer sendChunkAndLight(BranchChunk chunk, BranchChunkLight light, boolean needTile, Consumer consumeTraffic) { 23 | throw new UnsupportedOperationException(); 24 | } 25 | 26 | @Override 27 | public void sendKeepAlive(Player player, long id) { 28 | throw new UnsupportedOperationException(); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/main/java/xuan/cat/fartherviewdistance/code/branch/v15/Branch_15_Minecraft.java: -------------------------------------------------------------------------------- 1 | package xuan.cat.fartherviewdistance.code.branch.v15; 2 | 3 | import org.bukkit.Chunk; 4 | import org.bukkit.World; 5 | import org.bukkit.entity.Player; 6 | import xuan.cat.fartherviewdistance.api.branch.BranchChunk; 7 | import xuan.cat.fartherviewdistance.api.branch.BranchChunkLight; 8 | import xuan.cat.fartherviewdistance.api.branch.BranchMinecraft; 9 | import xuan.cat.fartherviewdistance.api.branch.BranchNBT; 10 | 11 | import java.io.IOException; 12 | 13 | public final class Branch_15_Minecraft implements BranchMinecraft { 14 | @Override 15 | public BranchNBT getChunkNBTFromDisk(World world, int chunkX, int chunkZ) throws IOException { 16 | throw new UnsupportedOperationException(); 17 | } 18 | 19 | @Override 20 | public BranchChunk getChunkFromMemoryCache(World world, int chunkX, int chunkZ) { 21 | throw new UnsupportedOperationException(); 22 | } 23 | 24 | @Override 25 | public BranchChunk fromChunk(World world, int chunkX, int chunkZ, BranchNBT nbt, boolean integralHeightmap) { 26 | throw new UnsupportedOperationException(); 27 | } 28 | 29 | @Override 30 | public BranchChunkLight fromLight(World world, BranchNBT nbt) { 31 | throw new UnsupportedOperationException(); 32 | } 33 | 34 | @Override 35 | public BranchChunkLight fromLight(World world) { 36 | throw new UnsupportedOperationException(); 37 | } 38 | 39 | @Override 40 | public BranchChunk fromChunk(World world, Chunk chunk) { 41 | throw new UnsupportedOperationException(); 42 | } 43 | 44 | @Override 45 | public BranchChunk.Status fromStatus(BranchNBT nbt) { 46 | throw new UnsupportedOperationException(); 47 | } 48 | 49 | @Override 50 | public void injectPlayer(Player player) { 51 | throw new UnsupportedOperationException(); 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/main/java/xuan/cat/fartherviewdistance/code/branch/v15/Branch_15_Packet.java: -------------------------------------------------------------------------------- 1 | package xuan.cat.fartherviewdistance.code.branch.v15; 2 | 3 | import org.bukkit.entity.Player; 4 | import xuan.cat.fartherviewdistance.api.branch.BranchChunk; 5 | import xuan.cat.fartherviewdistance.api.branch.BranchChunkLight; 6 | import xuan.cat.fartherviewdistance.api.branch.BranchPacket; 7 | 8 | import java.util.function.Consumer; 9 | 10 | public final class Branch_15_Packet implements BranchPacket { 11 | @Override 12 | public void sendViewDistance(Player player, int viewDistance) { 13 | throw new UnsupportedOperationException(); 14 | } 15 | 16 | @Override 17 | public void sendUnloadChunk(Player player, int chunkX, int chunkZ) { 18 | throw new UnsupportedOperationException(); 19 | } 20 | 21 | @Override 22 | public Consumer sendChunkAndLight(BranchChunk chunk, BranchChunkLight light, boolean needTile, Consumer consumeTraffic) { 23 | throw new UnsupportedOperationException(); 24 | } 25 | 26 | @Override 27 | public void sendKeepAlive(Player player, long id) { 28 | throw new UnsupportedOperationException(); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/main/java/xuan/cat/fartherviewdistance/code/branch/v16/Branch_16_Minecraft.java: -------------------------------------------------------------------------------- 1 | package xuan.cat.fartherviewdistance.code.branch.v16; 2 | 3 | import org.bukkit.Chunk; 4 | import org.bukkit.World; 5 | import org.bukkit.entity.Player; 6 | import xuan.cat.fartherviewdistance.api.branch.BranchChunk; 7 | import xuan.cat.fartherviewdistance.api.branch.BranchChunkLight; 8 | import xuan.cat.fartherviewdistance.api.branch.BranchMinecraft; 9 | import xuan.cat.fartherviewdistance.api.branch.BranchNBT; 10 | 11 | import java.io.IOException; 12 | 13 | public final class Branch_16_Minecraft implements BranchMinecraft { 14 | @Override 15 | public BranchNBT getChunkNBTFromDisk(World world, int chunkX, int chunkZ) throws IOException { 16 | throw new UnsupportedOperationException(); 17 | } 18 | 19 | @Override 20 | public BranchChunk getChunkFromMemoryCache(World world, int chunkX, int chunkZ) { 21 | throw new UnsupportedOperationException(); 22 | } 23 | 24 | @Override 25 | public BranchChunk fromChunk(World world, int chunkX, int chunkZ, BranchNBT nbt, boolean integralHeightmap) { 26 | throw new UnsupportedOperationException(); 27 | } 28 | 29 | @Override 30 | public BranchChunkLight fromLight(World world, BranchNBT nbt) { 31 | throw new UnsupportedOperationException(); 32 | } 33 | 34 | @Override 35 | public BranchChunkLight fromLight(World world) { 36 | throw new UnsupportedOperationException(); 37 | } 38 | 39 | @Override 40 | public BranchChunk fromChunk(World world, Chunk chunk) { 41 | throw new UnsupportedOperationException(); 42 | } 43 | 44 | @Override 45 | public BranchChunk.Status fromStatus(BranchNBT nbt) { 46 | throw new UnsupportedOperationException(); 47 | } 48 | 49 | @Override 50 | public void injectPlayer(Player player) { 51 | throw new UnsupportedOperationException(); 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/main/java/xuan/cat/fartherviewdistance/code/branch/v16/Branch_16_Packet.java: -------------------------------------------------------------------------------- 1 | package xuan.cat.fartherviewdistance.code.branch.v16; 2 | 3 | import org.bukkit.entity.Player; 4 | import xuan.cat.fartherviewdistance.api.branch.BranchChunk; 5 | import xuan.cat.fartherviewdistance.api.branch.BranchChunkLight; 6 | import xuan.cat.fartherviewdistance.api.branch.BranchPacket; 7 | 8 | import java.util.function.Consumer; 9 | 10 | public final class Branch_16_Packet implements BranchPacket { 11 | @Override 12 | public void sendViewDistance(Player player, int viewDistance) { 13 | throw new UnsupportedOperationException(); 14 | } 15 | 16 | @Override 17 | public void sendUnloadChunk(Player player, int chunkX, int chunkZ) { 18 | throw new UnsupportedOperationException(); 19 | } 20 | 21 | @Override 22 | public Consumer sendChunkAndLight(BranchChunk chunk, BranchChunkLight light, boolean needTile, Consumer consumeTraffic) { 23 | throw new UnsupportedOperationException(); 24 | } 25 | 26 | @Override 27 | public void sendKeepAlive(Player player, long id) { 28 | throw new UnsupportedOperationException(); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/main/java/xuan/cat/fartherviewdistance/code/branch/v17/Branch_17_Minecraft.java: -------------------------------------------------------------------------------- 1 | package xuan.cat.fartherviewdistance.code.branch.v17; 2 | 3 | import org.bukkit.Chunk; 4 | import org.bukkit.World; 5 | import org.bukkit.entity.Player; 6 | import xuan.cat.fartherviewdistance.api.branch.BranchChunk; 7 | import xuan.cat.fartherviewdistance.api.branch.BranchChunkLight; 8 | import xuan.cat.fartherviewdistance.api.branch.BranchMinecraft; 9 | import xuan.cat.fartherviewdistance.api.branch.BranchNBT; 10 | 11 | import java.io.IOException; 12 | 13 | public final class Branch_17_Minecraft implements BranchMinecraft { 14 | @Override 15 | public BranchNBT getChunkNBTFromDisk(World world, int chunkX, int chunkZ) throws IOException { 16 | throw new UnsupportedOperationException(); 17 | } 18 | 19 | @Override 20 | public BranchChunk getChunkFromMemoryCache(World world, int chunkX, int chunkZ) { 21 | throw new UnsupportedOperationException(); 22 | } 23 | 24 | @Override 25 | public BranchChunk fromChunk(World world, int chunkX, int chunkZ, BranchNBT nbt, boolean integralHeightmap) { 26 | throw new UnsupportedOperationException(); 27 | } 28 | 29 | @Override 30 | public BranchChunkLight fromLight(World world, BranchNBT nbt) { 31 | throw new UnsupportedOperationException(); 32 | } 33 | 34 | @Override 35 | public BranchChunkLight fromLight(World world) { 36 | throw new UnsupportedOperationException(); 37 | } 38 | 39 | @Override 40 | public BranchChunk fromChunk(World world, Chunk chunk) { 41 | throw new UnsupportedOperationException(); 42 | } 43 | 44 | @Override 45 | public BranchChunk.Status fromStatus(BranchNBT nbt) { 46 | throw new UnsupportedOperationException(); 47 | } 48 | 49 | @Override 50 | public void injectPlayer(Player player) { 51 | throw new UnsupportedOperationException(); 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/main/java/xuan/cat/fartherviewdistance/code/branch/v17/Branch_17_Packet.java: -------------------------------------------------------------------------------- 1 | package xuan.cat.fartherviewdistance.code.branch.v17; 2 | 3 | import org.bukkit.entity.Player; 4 | import xuan.cat.fartherviewdistance.api.branch.BranchChunk; 5 | import xuan.cat.fartherviewdistance.api.branch.BranchChunkLight; 6 | import xuan.cat.fartherviewdistance.api.branch.BranchPacket; 7 | 8 | import java.util.function.Consumer; 9 | 10 | public final class Branch_17_Packet implements BranchPacket { 11 | @Override 12 | public void sendViewDistance(Player player, int viewDistance) { 13 | throw new UnsupportedOperationException(); 14 | } 15 | 16 | @Override 17 | public void sendUnloadChunk(Player player, int chunkX, int chunkZ) { 18 | throw new UnsupportedOperationException(); 19 | } 20 | 21 | @Override 22 | public Consumer sendChunkAndLight(BranchChunk chunk, BranchChunkLight light, boolean needTile, Consumer consumeTraffic) { 23 | throw new UnsupportedOperationException(); 24 | } 25 | 26 | @Override 27 | public void sendKeepAlive(Player player, long id) { 28 | throw new UnsupportedOperationException(); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/main/java/xuan/cat/fartherviewdistance/code/branch/v18/Branch_18_Minecraft.java: -------------------------------------------------------------------------------- 1 | package xuan.cat.fartherviewdistance.code.branch.v18; 2 | 3 | import org.bukkit.Chunk; 4 | import org.bukkit.World; 5 | import org.bukkit.entity.Player; 6 | import xuan.cat.fartherviewdistance.api.branch.BranchChunk; 7 | import xuan.cat.fartherviewdistance.api.branch.BranchChunkLight; 8 | import xuan.cat.fartherviewdistance.api.branch.BranchMinecraft; 9 | import xuan.cat.fartherviewdistance.api.branch.BranchNBT; 10 | 11 | import java.io.IOException; 12 | 13 | public final class Branch_18_Minecraft implements BranchMinecraft { 14 | @Override 15 | public BranchNBT getChunkNBTFromDisk(World world, int chunkX, int chunkZ) throws IOException { 16 | throw new UnsupportedOperationException(); 17 | } 18 | 19 | @Override 20 | public BranchChunk getChunkFromMemoryCache(World world, int chunkX, int chunkZ) { 21 | throw new UnsupportedOperationException(); 22 | } 23 | 24 | @Override 25 | public BranchChunk fromChunk(World world, int chunkX, int chunkZ, BranchNBT nbt, boolean integralHeightmap) { 26 | throw new UnsupportedOperationException(); 27 | } 28 | 29 | @Override 30 | public BranchChunkLight fromLight(World world, BranchNBT nbt) { 31 | throw new UnsupportedOperationException(); 32 | } 33 | 34 | @Override 35 | public BranchChunkLight fromLight(World world) { 36 | throw new UnsupportedOperationException(); 37 | } 38 | 39 | @Override 40 | public BranchChunk fromChunk(World world, Chunk chunk) { 41 | throw new UnsupportedOperationException(); 42 | } 43 | 44 | @Override 45 | public BranchChunk.Status fromStatus(BranchNBT nbt) { 46 | throw new UnsupportedOperationException(); 47 | } 48 | 49 | @Override 50 | public void injectPlayer(Player player) { 51 | throw new UnsupportedOperationException(); 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/main/java/xuan/cat/fartherviewdistance/code/branch/v18/Branch_18_Packet.java: -------------------------------------------------------------------------------- 1 | package xuan.cat.fartherviewdistance.code.branch.v18; 2 | 3 | import org.bukkit.entity.Player; 4 | import xuan.cat.fartherviewdistance.api.branch.BranchChunk; 5 | import xuan.cat.fartherviewdistance.api.branch.BranchChunkLight; 6 | import xuan.cat.fartherviewdistance.api.branch.BranchPacket; 7 | 8 | import java.util.function.Consumer; 9 | 10 | public final class Branch_18_Packet implements BranchPacket { 11 | @Override 12 | public void sendViewDistance(Player player, int viewDistance) { 13 | throw new UnsupportedOperationException(); 14 | } 15 | 16 | @Override 17 | public void sendUnloadChunk(Player player, int chunkX, int chunkZ) { 18 | throw new UnsupportedOperationException(); 19 | } 20 | 21 | @Override 22 | public Consumer sendChunkAndLight(BranchChunk chunk, BranchChunkLight light, boolean needTile, Consumer consumeTraffic) { 23 | throw new UnsupportedOperationException(); 24 | } 25 | 26 | @Override 27 | public void sendKeepAlive(Player player, long id) { 28 | throw new UnsupportedOperationException(); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/main/java/xuan/cat/fartherviewdistance/code/branch/v19/Branch_19_Minecraft.java: -------------------------------------------------------------------------------- 1 | package xuan.cat.fartherviewdistance.code.branch.v19; 2 | 3 | import org.bukkit.Chunk; 4 | import org.bukkit.World; 5 | import org.bukkit.entity.Player; 6 | import xuan.cat.fartherviewdistance.api.branch.BranchChunk; 7 | import xuan.cat.fartherviewdistance.api.branch.BranchChunkLight; 8 | import xuan.cat.fartherviewdistance.api.branch.BranchMinecraft; 9 | import xuan.cat.fartherviewdistance.api.branch.BranchNBT; 10 | 11 | import java.io.IOException; 12 | 13 | public final class Branch_19_Minecraft implements BranchMinecraft { 14 | @Override 15 | public BranchNBT getChunkNBTFromDisk(World world, int chunkX, int chunkZ) throws IOException { 16 | throw new UnsupportedOperationException(); 17 | } 18 | 19 | @Override 20 | public BranchChunk getChunkFromMemoryCache(World world, int chunkX, int chunkZ) { 21 | throw new UnsupportedOperationException(); 22 | } 23 | 24 | @Override 25 | public BranchChunk fromChunk(World world, int chunkX, int chunkZ, BranchNBT nbt, boolean integralHeightmap) { 26 | throw new UnsupportedOperationException(); 27 | } 28 | 29 | @Override 30 | public BranchChunkLight fromLight(World world, BranchNBT nbt) { 31 | throw new UnsupportedOperationException(); 32 | } 33 | 34 | @Override 35 | public BranchChunkLight fromLight(World world) { 36 | throw new UnsupportedOperationException(); 37 | } 38 | 39 | @Override 40 | public BranchChunk fromChunk(World world, Chunk chunk) { 41 | throw new UnsupportedOperationException(); 42 | } 43 | 44 | @Override 45 | public BranchChunk.Status fromStatus(BranchNBT nbt) { 46 | throw new UnsupportedOperationException(); 47 | } 48 | 49 | @Override 50 | public void injectPlayer(Player player) { 51 | throw new UnsupportedOperationException(); 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/main/java/xuan/cat/fartherviewdistance/code/branch/v19/Branch_19_Packet.java: -------------------------------------------------------------------------------- 1 | package xuan.cat.fartherviewdistance.code.branch.v19; 2 | 3 | import org.bukkit.entity.Player; 4 | import xuan.cat.fartherviewdistance.api.branch.BranchChunk; 5 | import xuan.cat.fartherviewdistance.api.branch.BranchChunkLight; 6 | import xuan.cat.fartherviewdistance.api.branch.BranchPacket; 7 | 8 | import java.util.function.Consumer; 9 | 10 | public final class Branch_19_Packet implements BranchPacket { 11 | @Override 12 | public void sendViewDistance(Player player, int viewDistance) { 13 | throw new UnsupportedOperationException(); 14 | } 15 | 16 | @Override 17 | public void sendUnloadChunk(Player player, int chunkX, int chunkZ) { 18 | throw new UnsupportedOperationException(); 19 | } 20 | 21 | @Override 22 | public Consumer sendChunkAndLight(BranchChunk chunk, BranchChunkLight light, boolean needTile, Consumer consumeTraffic) { 23 | throw new UnsupportedOperationException(); 24 | } 25 | 26 | @Override 27 | public void sendKeepAlive(Player player, long id) { 28 | throw new UnsupportedOperationException(); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/main/java/xuan/cat/fartherviewdistance/code/command/CommandSuggest.java: -------------------------------------------------------------------------------- 1 | package xuan.cat.fartherviewdistance.code.command; 2 | 3 | import org.bukkit.Bukkit; 4 | import org.bukkit.command.Command; 5 | import org.bukkit.command.CommandSender; 6 | import org.bukkit.command.TabCompleter; 7 | import xuan.cat.fartherviewdistance.code.ChunkServer; 8 | import xuan.cat.fartherviewdistance.code.data.ConfigData; 9 | 10 | import java.util.ArrayList; 11 | import java.util.List; 12 | 13 | public final class CommandSuggest implements TabCompleter { 14 | 15 | private final ChunkServer chunkServer; 16 | private final ConfigData configData; 17 | 18 | public CommandSuggest(ChunkServer chunkServer, ConfigData configData) { 19 | this.chunkServer = chunkServer; 20 | this.configData = configData; 21 | } 22 | 23 | public List onTabComplete(CommandSender sender, Command command, String s, String[] parameters) { 24 | if (!sender.hasPermission("command.viewdistance")) { 25 | return new ArrayList<>(); 26 | } 27 | 28 | List list = new ArrayList<>(); 29 | 30 | if (parameters.length == 1) { 31 | list.add("start"); 32 | list.add("stop"); 33 | list.add("reload"); 34 | list.add("report"); 35 | list.add("permissionCheck"); 36 | list.add("debug"); 37 | } else if (parameters.length == 2) { 38 | switch (parameters[0]) { 39 | case "report": 40 | list.add("server"); 41 | list.add("thread"); 42 | list.add("world"); 43 | list.add("player"); 44 | break; 45 | case "permissionCheck": 46 | Bukkit.getOnlinePlayers().forEach(player -> list.add(player.getName())); 47 | break; 48 | case "debug": 49 | list.add("view"); 50 | break; 51 | } 52 | } else if (parameters.length == 3) { 53 | switch (parameters[0]) { 54 | case "report": 55 | break; 56 | case "permissionCheck": 57 | break; 58 | case "debug": 59 | switch (parameters[1]) { 60 | case "view": 61 | Bukkit.getOnlinePlayers().forEach(player -> list.add(player.getName())); 62 | break; 63 | } 64 | break; 65 | } 66 | } 67 | 68 | return list; 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /src/main/java/xuan/cat/fartherviewdistance/code/data/CumulativeReport.java: -------------------------------------------------------------------------------- 1 | package xuan.cat.fartherviewdistance.code.data; 2 | 3 | /** 4 | * 累計處裡報告 5 | */ 6 | public final class CumulativeReport { 7 | /** 高速讀取 */ 8 | private volatile int[] loadFast = new int[300]; 9 | /** 慢速讀取 */ 10 | private volatile int[] loadSlow = new int[300]; 11 | /** 消耗 */ 12 | private volatile int[] consume = new int[300]; 13 | 14 | 15 | public void next() { 16 | try { 17 | // 累計用向後推移1個 18 | int[] loadFastClone = new int[300]; 19 | int[] loadSlowClone = new int[300]; 20 | int[] consumeClone = new int[300]; 21 | System.arraycopy(loadFast, 0, loadFastClone, 1, loadFast.length - 1); 22 | System.arraycopy(loadSlow, 0, loadSlowClone, 1, loadSlow.length - 1); 23 | System.arraycopy(consume, 0, consumeClone, 1, consume.length - 1); 24 | loadFast = loadFastClone; 25 | loadSlow = loadSlowClone; 26 | consume = consumeClone; 27 | } catch (Exception e) { 28 | e.printStackTrace(); 29 | } 30 | } 31 | 32 | 33 | public void increaseLoadFast() { 34 | loadFast[0]++; 35 | } 36 | public void increaseLoadSlow() { 37 | loadSlow[0]++; 38 | } 39 | public void addConsume(int value) { 40 | consume[0] += value; 41 | } 42 | 43 | 44 | public int reportLoadFast5s() { 45 | int total = 0; 46 | for (int i = 0 ; i < 5 ; ++i) 47 | total += loadFast[i]; 48 | return total; 49 | } 50 | public int reportLoadFast1m() { 51 | int total = 0; 52 | for (int i = 0 ; i < 60 ; ++i) 53 | total += loadFast[i]; 54 | return total; 55 | } 56 | public int reportLoadFast5m() { 57 | int total = 0; 58 | for (int i = 0 ; i < 300 ; ++i) 59 | total += loadFast[i]; 60 | return total; 61 | } 62 | 63 | 64 | public int reportLoadSlow5s() { 65 | int total = 0; 66 | for (int i = 0 ; i < 5 ; ++i) 67 | total += loadSlow[i]; 68 | return total; 69 | } 70 | public int reportLoadSlow1m() { 71 | int total = 0; 72 | for (int i = 0 ; i < 60 ; ++i) 73 | total += loadSlow[i]; 74 | return total; 75 | } 76 | public int reportLoadSlow5m() { 77 | int total = 0; 78 | for (int i = 0 ; i < 300 ; ++i) 79 | total += loadSlow[i]; 80 | return total; 81 | } 82 | 83 | 84 | public long reportConsume5s() { 85 | long total = 0; 86 | for (int i = 0 ; i < 5 ; ++i) 87 | total += consume[i]; 88 | return total; 89 | } 90 | public long reportConsume1m() { 91 | long total = 0; 92 | for (int i = 0 ; i < 60 ; ++i) 93 | total += consume[i]; 94 | return total; 95 | } 96 | public long reportConsume5m() { 97 | long total = 0; 98 | for (int i = 0 ; i < 300 ; ++i) 99 | total += consume[i]; 100 | return total; 101 | } 102 | } 103 | -------------------------------------------------------------------------------- /src/main/java/xuan/cat/fartherviewdistance/code/data/LangFiles.java: -------------------------------------------------------------------------------- 1 | package xuan.cat.fartherviewdistance.code.data; 2 | 3 | import com.google.gson.Gson; 4 | import com.google.gson.JsonElement; 5 | import com.google.gson.JsonObject; 6 | import org.bukkit.command.CommandSender; 7 | import org.bukkit.entity.Player; 8 | 9 | import java.io.IOException; 10 | import java.io.InputStreamReader; 11 | import java.net.URL; 12 | import java.net.URLConnection; 13 | import java.nio.charset.StandardCharsets; 14 | import java.util.Locale; 15 | import java.util.Map; 16 | import java.util.concurrent.ConcurrentHashMap; 17 | 18 | /** 語言文件 */ 19 | public final class LangFiles { 20 | /** 全部語言文件 */ 21 | private final Map fileMap = new ConcurrentHashMap<>(); 22 | /** 預設語言文件 */ 23 | private final JsonObject defaultMap = loadLang(Locale.ENGLISH); 24 | 25 | 26 | /** 27 | * @param sender 執行人 28 | * @param key 條目鑰匙 29 | * @return 語言條目 30 | */ 31 | public String get(CommandSender sender, String key) { 32 | if (sender instanceof Player) { 33 | try { 34 | // 1.16 以上 35 | return get(((Player) sender).locale(), key); 36 | } catch (NoSuchMethodError noSuchMethodError) { 37 | return get(parseLocale(((Player) sender).getLocale()), key); 38 | } 39 | } else { 40 | return get(Locale.ENGLISH, key); 41 | } 42 | } 43 | private static Locale parseLocale(String string) { 44 | String[] segments = string.split("_", 3); 45 | int length = segments.length; 46 | switch (length) { 47 | case 1: 48 | return new Locale(string); 49 | case 2: 50 | return new Locale(segments[0], segments[1]); 51 | case 3: 52 | return new Locale(segments[0], segments[1], segments[2]); 53 | default: 54 | return null; 55 | } 56 | } 57 | /** 58 | * @param locale 語言類型 59 | * @param key 條目鑰匙 60 | * @return 語言條目 61 | */ 62 | public String get(Locale locale, String key) { 63 | JsonObject lang = fileMap.computeIfAbsent(locale, v -> loadLang(locale)); 64 | JsonElement element = lang.get(key); 65 | if (element != null && !element.isJsonNull()) { 66 | return element.getAsString(); 67 | } else { 68 | return defaultMap.get(key).getAsString(); 69 | } 70 | } 71 | /** 72 | * @param locale 語言類型 73 | * @return 讀取語言文件 74 | */ 75 | private JsonObject loadLang(Locale locale) { 76 | URL url = getClass().getClassLoader().getResource("lang/" + locale.toString().toLowerCase(Locale.ROOT) + ".json"); 77 | if (url == null) 78 | return new JsonObject(); 79 | try { 80 | URLConnection connection = url.openConnection(); 81 | connection.setUseCaches(true); 82 | return new Gson().fromJson(new InputStreamReader(connection.getInputStream(), StandardCharsets.UTF_8), JsonObject.class); 83 | } catch (IOException exception) { 84 | return new JsonObject(); 85 | } 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /src/main/java/xuan/cat/fartherviewdistance/code/data/NetworkSpeed.java: -------------------------------------------------------------------------------- 1 | package xuan.cat.fartherviewdistance.code.data; 2 | 3 | import java.util.concurrent.atomic.AtomicInteger; 4 | 5 | /** 6 | * 網路速度監聽器 7 | */ 8 | public final class NetworkSpeed { 9 | /** 測速用時間戳 */ 10 | public volatile long speedTimestamp = 0; 11 | /** 測速用數據量 */ 12 | public volatile int speedConsume = 0; 13 | /** 測速用 ID */ 14 | public volatile Long speedID = null; 15 | 16 | /** 延遲用時間戳 */ 17 | public volatile long pingTimestamp = 0; 18 | /** 延遲用 ID */ 19 | public volatile Long pingID = null; 20 | /** 最後一次的延遲 */ 21 | public volatile int lastPing = 0; 22 | 23 | /** 寫入紀錄 */ 24 | private volatile int[] writeArray = new int[50]; 25 | /** 延遲紀錄 */ 26 | private volatile int[] consumeArray = new int[50]; 27 | /** 寫入累計 */ 28 | private final AtomicInteger writeTotal = new AtomicInteger(0); 29 | /** 寫入累計 */ 30 | private final AtomicInteger consumeTotal = new AtomicInteger(0); 31 | 32 | 33 | /** 34 | * 加入 35 | */ 36 | public void add(int ping, int length) { 37 | synchronized (writeTotal) { 38 | writeTotal.addAndGet(length); 39 | consumeTotal.addAndGet(ping); 40 | writeArray[0] += length; 41 | consumeArray[0] += ping; 42 | } 43 | } 44 | 45 | 46 | /** 47 | * @return 平均速度 48 | */ 49 | public int avg() { 50 | synchronized (writeTotal) { 51 | int writeGet = writeTotal.get(); 52 | int consumeGet = Math.max(1, consumeTotal.get()); 53 | if (writeGet == 0) { 54 | return 0; 55 | } else { 56 | return writeGet / consumeGet; 57 | } 58 | } 59 | } 60 | 61 | 62 | /** 63 | * 下一個 tick 64 | */ 65 | public void next() { 66 | synchronized (writeTotal) { 67 | writeTotal.addAndGet(-writeArray[writeArray.length - 1]); 68 | consumeTotal.addAndGet(-consumeArray[consumeArray.length - 1]); 69 | int[] writeArrayClone = new int[writeArray.length]; 70 | int[] consumeArrayClone = new int[consumeArray.length]; 71 | System.arraycopy(writeArray, 0, writeArrayClone, 1, writeArray.length - 1); 72 | System.arraycopy(consumeArray, 0, consumeArrayClone, 1, consumeArray.length - 1); 73 | writeArray = writeArrayClone; 74 | consumeArray = consumeArrayClone; 75 | } 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /src/main/java/xuan/cat/fartherviewdistance/code/data/NetworkTraffic.java: -------------------------------------------------------------------------------- 1 | package xuan.cat.fartherviewdistance.code.data; 2 | 3 | /** 4 | * 網路流量 5 | */ 6 | public final class NetworkTraffic { 7 | // /** 寫入紀錄 */ 8 | // private volatile int[] writeArray = new int[20]; 9 | // /** 寫入累計 */ 10 | // private final AtomicInteger writeTotal = new AtomicInteger(0); 11 | private volatile int value = 0; 12 | 13 | 14 | /** 15 | * 已使用 16 | * @param length 位元組數量 17 | */ 18 | public synchronized void use(int length) { 19 | value += length; 20 | // synchronized (writeTotal) { 21 | // writeArray[0] += length; 22 | // writeTotal.addAndGet(length); 23 | // } 24 | } 25 | 26 | /** 27 | * @return 當前的狀態 28 | */ 29 | public synchronized int get() { 30 | return value; 31 | // synchronized (writeTotal) { 32 | // return writeTotal.get(); 33 | // } 34 | } 35 | 36 | /** 37 | * @param length 位元組數量 38 | * @return 是否低於使用量 39 | */ 40 | public synchronized boolean exceed(int length) { 41 | return value >= length; 42 | // synchronized (writeTotal) { 43 | // return writeTotal.get() >= length; 44 | // } 45 | } 46 | 47 | /** 48 | * 下一個 tick 49 | */ 50 | public void next() { 51 | value = 0; 52 | // synchronized (writeTotal) { 53 | // writeTotal.addAndGet(-writeArray[writeArray.length - 1]); 54 | // int[] writeArrayClone = new int[writeArray.length]; 55 | // System.arraycopy(writeArray, 0, writeArrayClone, 1, writeArray.length - 1); 56 | // writeArray = writeArrayClone; 57 | // } 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /src/main/java/xuan/cat/fartherviewdistance/code/data/viewmap/ViewMap.java: -------------------------------------------------------------------------------- 1 | package xuan.cat.fartherviewdistance.code.data.viewmap; 2 | 3 | import org.bukkit.Location; 4 | import org.bukkit.command.CommandSender; 5 | 6 | import java.util.List; 7 | import java.util.concurrent.atomic.AtomicInteger; 8 | 9 | public abstract class ViewMap { 10 | public final ViewShape viewShape; 11 | public int extendDistance = 1; 12 | public int serverDistance = 1; 13 | /** 已完成距離 */ 14 | public final AtomicInteger completedDistance = new AtomicInteger(-1); 15 | protected int centerX = 0; 16 | protected int centerZ = 0; 17 | 18 | protected ViewMap(ViewShape viewShape) { 19 | this.viewShape = viewShape; 20 | } 21 | 22 | 23 | public abstract List movePosition(Location location); 24 | /** 25 | * 移動到區塊位置 (中心點) 26 | * @param moveX 區塊座標X 27 | * @param moveZ 區塊座標Z 28 | * @return 如果有區塊被移除, 則會集中回傳在這 29 | */ 30 | public abstract List movePosition(int moveX, int moveZ); 31 | 32 | 33 | /** 34 | * 取得下一個應該要處裡的區塊 35 | * @return positionKey, 若沒有需要處裡的區塊, 則回傳 null 36 | */ 37 | public abstract Long get(); 38 | 39 | public int getCenterX() { 40 | return centerX; 41 | } 42 | public int getCenterZ() { 43 | return centerZ; 44 | } 45 | 46 | public final void setCenter(Location location) { 47 | setCenter(location.getBlockX() >> 4, location.getBlockZ() >> 4); 48 | } 49 | public final void setCenter(int positionX, int positionZ) { 50 | setCenterX(positionX); 51 | setCenterZ(positionZ); 52 | } 53 | public void setCenterX(int centerX) { 54 | this.centerX = centerX; 55 | } 56 | public void setCenterZ(int centerZ) { 57 | this.centerZ = centerZ; 58 | } 59 | 60 | 61 | public static int getX(long positionKey) { 62 | return (int) (positionKey); 63 | } 64 | public static int getZ(long positionKey) { 65 | return (int) (positionKey >> 32); 66 | } 67 | public static long getPositionKey(int x, int z) { 68 | return ((long) z << 32) & 0b1111111111111111111111111111111100000000000000000000000000000000L | x & 0b0000000000000000000000000000000011111111111111111111111111111111L; 69 | } 70 | 71 | 72 | public abstract boolean inPosition(int positionX, int positionZ); 73 | 74 | 75 | public abstract boolean isWaitPosition(long positionKey); 76 | public abstract boolean isWaitPosition(int positionX, int positionZ); 77 | 78 | 79 | public abstract boolean isSendPosition(long positionKey); 80 | public abstract boolean isSendPosition(int positionX, int positionZ); 81 | 82 | 83 | public abstract void markWaitPosition(long positionKey); 84 | public abstract void markWaitPosition(int positionX, int positionZ); 85 | 86 | 87 | public abstract void markSendPosition(long positionKey); 88 | public abstract void markSendPosition(int positionX, int positionZ); 89 | 90 | 91 | /** 92 | * @param range 範圍外的區塊標記為等待中 93 | */ 94 | public abstract void markOutsideWait(int range); 95 | /** 96 | * @param range 範圍外的區塊標記為以發送 97 | */ 98 | public abstract void markOutsideSend(int range); 99 | 100 | 101 | /** 102 | * @param range 範圍內的區塊標記為等待中 103 | */ 104 | public abstract void markInsideWait(int range); 105 | /** 106 | * @param range 範圍內的區塊標記為以發送 107 | */ 108 | public abstract void markInsideSend(int range); 109 | 110 | 111 | public abstract List getAll(); 112 | public abstract List getAllNotServer(); 113 | 114 | 115 | public abstract boolean isWaitSafe(int pointerX, int pointerZ); 116 | public abstract boolean isSendSafe(int pointerX, int pointerZ); 117 | 118 | 119 | public abstract boolean markWaitSafe(int pointerX, int pointerZ); 120 | public abstract void markSendSafe(int pointerX, int pointerZ); 121 | 122 | 123 | public abstract void clear(); 124 | 125 | 126 | public abstract void debug(CommandSender sender); 127 | } 128 | -------------------------------------------------------------------------------- /src/main/java/xuan/cat/fartherviewdistance/code/data/viewmap/ViewMapMode.java: -------------------------------------------------------------------------------- 1 | package xuan.cat.fartherviewdistance.code.data.viewmap; 2 | 3 | import java.util.function.Function; 4 | 5 | public enum ViewMapMode { 6 | X15(IntX15ViewMap::new, 15), 7 | X31(LongX31ViewMap::new, 31), 8 | X63((viewShape) -> new LongXInfinitelyViewMap(viewShape, 2), 63), 9 | X127((viewShape) -> new LongXInfinitelyViewMap(viewShape, 4), 127), 10 | X383((viewShape) -> new LongXInfinitelyViewMap(viewShape, 6), 383), 11 | ; 12 | 13 | private final int extend; 14 | private final Function create; 15 | 16 | ViewMapMode(Function create, int extend) { 17 | this.extend = extend; 18 | this.create = create; 19 | } 20 | 21 | public ViewMap createMap(ViewShape viewShape) { 22 | return create.apply(viewShape); 23 | } 24 | 25 | public int getExtend() { 26 | return extend; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/main/java/xuan/cat/fartherviewdistance/code/data/viewmap/ViewShape.java: -------------------------------------------------------------------------------- 1 | package xuan.cat.fartherviewdistance.code.data.viewmap; 2 | 3 | /** 4 | * 視圖形狀 5 | */ 6 | public enum ViewShape { 7 | /** 方形 */ 8 | SQUARE((int aX, int aZ, int bX, int bZ, int viewDistance) -> { 9 | int minX = bX - viewDistance; 10 | int minZ = bZ - viewDistance; 11 | int maxX = bX + viewDistance; 12 | int maxZ = bZ + viewDistance; 13 | return aX >= minX && aZ >= minZ && aX <= maxX && aZ <= maxZ; 14 | }), 15 | /** 圓形 */ 16 | ROUND((int aX, int aZ, int bX, int bZ, int viewDistance) -> { 17 | int viewDiameter = viewDistance * viewDistance + viewDistance; 18 | int distanceX = aX - bX; 19 | int distanceZ = aZ - bZ; 20 | int distance = distanceX * distanceX + distanceZ * distanceZ; 21 | return distance <= viewDiameter; 22 | }, (int aX, int aZ, int bX, int bZ, int viewDistance) -> { 23 | JudgeInside inside = (int _aX, int _aZ, int _bX, int _bZ, int viewDiameter) -> { 24 | int distanceX = _aX - _bX; 25 | int distanceZ = _aZ - _bZ; 26 | int distance = distanceX * distanceX + distanceZ * distanceZ; 27 | return distance <= viewDiameter; 28 | }; 29 | int viewDiameter = viewDistance * viewDistance + viewDistance; 30 | return inside.test(aX, aZ, bX, bZ, viewDiameter) && !(!inside.test(aX + 1, aZ, bX, bZ, viewDiameter) || !inside.test(aX - 1, aZ, bX, bZ, viewDiameter) || !inside.test(aX, aZ + 1, bX, bZ, viewDiameter) || !inside.test(aX, aZ - 1, bX, bZ, viewDiameter)); 31 | }), 32 | ; 33 | 34 | /** 35 | * 許可計算 36 | */ 37 | interface JudgeInside { 38 | boolean test(int aX, int aZ, int bX, int bZ, int viewDistance); 39 | } 40 | private final JudgeInside judgeInside; 41 | private final JudgeInside judgeInsideEdge; 42 | 43 | ViewShape(JudgeInside judgeInside) { 44 | this(judgeInside, judgeInside); 45 | } 46 | ViewShape(JudgeInside judgeInside, JudgeInside judgeInsideEdge) { 47 | this.judgeInside = judgeInside; 48 | this.judgeInsideEdge = judgeInsideEdge; 49 | } 50 | 51 | public boolean isInside(int aX, int aZ, int bX, int bZ, int viewDistance) { 52 | return judgeInside.test(aX, aZ, bX, bZ, viewDistance); 53 | } 54 | public boolean isInsideEdge(int aX, int aZ, int bX, int bZ, int viewDistance) { 55 | return judgeInsideEdge.test(aX, aZ, bX, bZ, viewDistance); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /src/main/resources/lang/cs_cz.json: -------------------------------------------------------------------------------- 1 | { 2 | "command.no_permission": "Nemáte dostatečná oprávnění", 3 | "command.missing_parameters": "Chybí parametry", 4 | "command.reread_configuration_successfully": "Konfigurace byla úspěšně znovu načtena", 5 | "command.reread_configuration_error": "Konfigurace byla znovu načtena, ale došlo k chybě", 6 | "command.unknown_parameter_type": "Neznámý typ parametru", 7 | "command.report.source": "ZDROJ", 8 | "command.report.fast": "RYCHLÝ", 9 | "command.report.slow": "POMALÝ", 10 | "command.report.flow": "TOK", 11 | "command.report.5s": "5S", 12 | "command.report.1m": "1M", 13 | "command.report.5m": "5M", 14 | "command.continue_execution": "Pokračovat ve vykonávání", 15 | "command.suspension_execution": "Pozastavit provádění", 16 | "command.players_do_not_exist": "Players do not exist", 17 | "command.rechecked_player_permissions": "Rechecked player permissions" 18 | } -------------------------------------------------------------------------------- /src/main/resources/lang/de_de.json: -------------------------------------------------------------------------------- 1 | { 2 | "command.no_permission": "Keine Erlaubnis", 3 | "command.missing_parameters": "Fehlende Parameter", 4 | "command.reread_configuration_successfully": "Konfiguration erfolgreich neu eingelesen", 5 | "command.reread_configuration_error": "Fehler beim neu einlesen der Konfiguration", 6 | "command.unknown_parameter_type": "Unbekannter Parametertyp", 7 | "command.report.source": "QUELLE", 8 | "command.report.fast": "SCHNELL", 9 | "command.report.slow": "LANGSAM", 10 | "command.report.flow": "FLIESSEN", 11 | "command.report.5s": "5S", 12 | "command.report.1m": "1M", 13 | "command.report.5m": "5M", 14 | "command.continue_execution": "Ausführung fortsetzen", 15 | "command.suspension_execution": "Ausführung suspendieren", 16 | "command.players_do_not_exist": "Players do not exist", 17 | "command.rechecked_player_permissions": "Rechecked player permissions" 18 | } -------------------------------------------------------------------------------- /src/main/resources/lang/en.json: -------------------------------------------------------------------------------- 1 | { 2 | "command.no_permission": "No permission", 3 | "command.missing_parameters": "Missing parameters", 4 | "command.reread_configuration_successfully": "Reread configuration successfully", 5 | "command.reread_configuration_error": "Reread configuration an error occurred", 6 | "command.unknown_parameter_type": "Unknown parameter type", 7 | "command.report.source": "SOURCE", 8 | "command.report.fast": "FAST", 9 | "command.report.slow": "SLOW", 10 | "command.report.flow": "FLOW", 11 | "command.report.5s": "5S", 12 | "command.report.1m": "1M", 13 | "command.report.5m": "5M", 14 | "command.continue_execution": "Continue execution", 15 | "command.suspension_execution": "Suspension execution", 16 | "command.players_do_not_exist": "Players do not exist", 17 | "command.rechecked_player_permissions": "Rechecked player permissions" 18 | } -------------------------------------------------------------------------------- /src/main/resources/lang/es_es.json: -------------------------------------------------------------------------------- 1 | { 2 | "command.no_permission": "No tienes permisos", 3 | "command.missing_parameters": "Faltan parámetros", 4 | "command.reread_configuration_successfully": "Configuración releída exitosamente", 5 | "command.reread_configuration_error": "Ha ocurrido un error releyendo la configuración", 6 | "command.unknown_parameter_type": "Tipo de parámetro desconocido", 7 | "command.report.source": "FUENTE", 8 | "command.report.fast": "RÁPIDO", 9 | "command.report.slow": "LENTO", 10 | "command.report.flow": "FLUÍDO", 11 | "command.report.5s": "5S", 12 | "command.report.1m": "1M", 13 | "command.report.5m": "5M", 14 | "command.continue_execution": "Continuar ejecución", 15 | "command.suspension_execution": "Suspender ejecución", 16 | "command.players_do_not_exist": "Players do not exist", 17 | "command.rechecked_player_permissions": "Rechecked player permissions" 18 | } -------------------------------------------------------------------------------- /src/main/resources/lang/fr_fr.json: -------------------------------------------------------------------------------- 1 | { 2 | "command.no_permission": "Permission manquante", 3 | "command.missing_parameters": "Paramètres manquants", 4 | "command.reread_configuration_successfully": "La configuration a été rechargée avec succès", 5 | "command.reread_configuration_error": "La configuration a été rechargée mais des erreurs ont survenu", 6 | "command.unknown_parameter_type": "Type de paramètre inconnu", 7 | "command.report.source": "SOURCE", 8 | "command.report.fast": "RAPIDE", 9 | "command.report.slow": "LENT", 10 | "command.report.flow": "FLOW", 11 | "command.report.5s": "5S", 12 | "command.report.1m": "1M", 13 | "command.report.5m": "5M", 14 | "command.continue_execution": "Continuer l'exécution", 15 | "command.suspension_execution": "Suspendre l'exécution", 16 | "command.players_do_not_exist": "Players do not exist", 17 | "command.rechecked_player_permissions": "Rechecked player permissions" 18 | } -------------------------------------------------------------------------------- /src/main/resources/lang/it_it.json: -------------------------------------------------------------------------------- 1 | { 2 | "command.no_permission": "Non hai il permesso", 3 | "command.missing_parameters": "Mancano alcuni parametri", 4 | "command.reread_configuration_successfully": "Config ricaricato", 5 | "command.reread_configuration_error": "C'è stato un errore durante il ricaricamento del config", 6 | "command.unknown_parameter_type": "Parametro di tipo sconosciuto", 7 | "command.report.source": "FONTE", 8 | "command.report.fast": "VELOCE", 9 | "command.report.slow": "LENTA", 10 | "command.report.flow": "FLUSSO", 11 | "command.report.5s": "5S", 12 | "command.report.1m": "1M", 13 | "command.report.5m": "5M", 14 | "command.continue_execution": "Riprendi Esecuzione", 15 | "command.suspension_execution": "Sospendi esecuzione", 16 | "command.players_do_not_exist": "Players do not exist", 17 | "command.rechecked_player_permissions": "Rechecked player permissions" 18 | } -------------------------------------------------------------------------------- /src/main/resources/lang/ja_jp.json: -------------------------------------------------------------------------------- 1 | { 2 | "command.no_permission": "許可なし", 3 | "command.missing_parameters": "欠落したパラメータ", 4 | "command.reread_configuration_successfully": "構成の再読み込みに成功", 5 | "command.reread_configuration_error": "構成の再読み込みに失敗", 6 | "command.unknown_parameter_type": "不明なパラメータ種類", 7 | "command.report.source": "出典", 8 | "command.report.fast": "速い", 9 | "command.report.slow": "遅い", 10 | "command.report.flow": "流れ", 11 | "command.report.5s": "5S", 12 | "command.report.1m": "1M", 13 | "command.report.5m": "5M", 14 | "command.continue_execution": "実行を続ける", 15 | "command.suspension_execution": "実行を中止", 16 | "command.players_do_not_exist": "Players do not exist", 17 | "command.rechecked_player_permissions": "Rechecked player permissions" 18 | } -------------------------------------------------------------------------------- /src/main/resources/lang/pl_pl.json: -------------------------------------------------------------------------------- 1 | { 2 | "command.no_permission": "Brak uprawnień", 3 | "command.missing_parameters": "Brakujące argumenty", 4 | "command.reread_configuration_successfully": "Przeczytaj plik konfiguracyjny ponownie", 5 | "command.reread_configuration_error": "Przeczytaj plik konfiguracyjny ponownie, wystąpił błąd", 6 | "command.unknown_parameter_type": "Nieznany parametr", 7 | "command.report.source": "ŹRÓDŁO", 8 | "command.report.fast": "SZYBKO", 9 | "command.report.slow": "WOLNO", 10 | "command.report.flow": "PRZEPŁYW", 11 | "command.report.5s": "5S", 12 | "command.report.1m": "1M", 13 | "command.report.5m": "5M", 14 | "command.continue_execution": "Kontynuuj wykonanie", 15 | "command.suspension_execution": "Zawieszenie wykonania", 16 | "command.players_do_not_exist": "Players do not exist", 17 | "command.rechecked_player_permissions": "Rechecked player permissions" 18 | } -------------------------------------------------------------------------------- /src/main/resources/lang/ru_ru.json: -------------------------------------------------------------------------------- 1 | { 2 | "command.no_permission": "Недостаточно прав", 3 | "command.missing_parameters": "Недостаточно параметров", 4 | "command.reread_configuration_successfully": "Конфигурация плагина успешно перезагружена", 5 | "command.reread_configuration_error": "Произошла ошибка при перезагрузке конфигурации плагина", 6 | "command.unknown_parameter_type": "Неизвестный тип параметра", 7 | "command.report.source": "ИСТОЧНИК", 8 | "command.report.fast": "БЫСТРО", 9 | "command.report.slow": "МЕДЛЕННО", 10 | "command.report.flow": "ПОТОК", 11 | "command.report.5s": "5с", 12 | "command.report.1m": "1м", 13 | "command.report.5m": "5м", 14 | "command.continue_execution": "Ошибка продолжения", 15 | "command.suspension_execution": "Ошибка приостановки", 16 | "command.players_do_not_exist": "Players do not exist", 17 | "command.rechecked_player_permissions": "Rechecked player permissions" 18 | } -------------------------------------------------------------------------------- /src/main/resources/lang/uk_ua.json: -------------------------------------------------------------------------------- 1 | { 2 | "command.no_permission": "Недостатньо прав", 3 | "command.missing_parameters": "Недостатньо параметрів", 4 | "command.reread_configuration_successfully": "Конфігурація плагіна успішно перезавантажена", 5 | "command.reread_configuration_error": "Сталася помилка під час перезавантаження конфігурації плагіна", 6 | "command.unknown_parameter_type": "Невідомий тип параметра", 7 | "command.report.source": "ДЖЕРЕЛО", 8 | "command.report.fast": "ШВИДКО", 9 | "command.report.slow": "ПОВІЛЬНО", 10 | "command.report.flow": "ПОТІК", 11 | "command.report.5s": "5с", 12 | "command.report.1m": "1хв", 13 | "command.report.5m": "5хв", 14 | "command.continue_execution": "Помилка продовження", 15 | "command.suspension_execution": "Помилка припинення", 16 | "command.players_do_not_exist": "Players do not exist", 17 | "command.rechecked_player_permissions": "Rechecked player permissions" 18 | } -------------------------------------------------------------------------------- /src/main/resources/lang/zh_cn.json: -------------------------------------------------------------------------------- 1 | { 2 | "command.no_permission": "无此权限", 3 | "command.missing_parameters": "缺少参数", 4 | "command.reread_configuration_successfully": "已重新读取设定", 5 | "command.reread_configuration_error": "重新读取设定时发生错误", 6 | "command.unknown_parameter_type": "未知的参数类型", 7 | "command.report.source": "来源", 8 | "command.report.fast": "快速", 9 | "command.report.slow": "慢速", 10 | "command.report.flow": "流量", 11 | "command.report.5s": "5S", 12 | "command.report.1m": "1M", 13 | "command.report.5m": "5M", 14 | "command.continue_execution": "继续运行", 15 | "command.suspension_execution": "暂停运行", 16 | "command.players_do_not_exist": "玩家不存在", 17 | "command.rechecked_player_permissions": "已重新检查玩家权限" 18 | } -------------------------------------------------------------------------------- /src/main/resources/lang/zh_tw.json: -------------------------------------------------------------------------------- 1 | { 2 | "command.no_permission": "無此權限", 3 | "command.missing_parameters": "缺少參數", 4 | "command.reread_configuration_successfully": "已重新讀取設定", 5 | "command.reread_configuration_error": "重新讀取設定時發生錯誤", 6 | "command.unknown_parameter_type": "未知的參數類型", 7 | "command.report.source": "來源", 8 | "command.report.fast": "快速", 9 | "command.report.slow": "慢速", 10 | "command.report.flow": "流量", 11 | "command.report.5s": "5S", 12 | "command.report.1m": "1M", 13 | "command.report.5m": "5M", 14 | "command.continue_execution": "繼續運行", 15 | "command.suspension_execution": "暫停運行", 16 | "command.players_do_not_exist": "玩家不存在", 17 | "command.rechecked_player_permissions": "已重新檢查玩家權限" 18 | } -------------------------------------------------------------------------------- /src/main/resources/plugin.yml: -------------------------------------------------------------------------------- 1 | name: FartherViewDistance 2 | version: ${project.version} 3 | main: xuan.cat.fartherviewdistance.code.ChunkIndex 4 | api-version: 1.13 5 | softdepend: [PlaceholderAPI] 6 | authors: [xuancat0208] 7 | commands: 8 | viewdistance: 9 | usage: op 10 | --------------------------------------------------------------------------------