Skip to content

Commit

Permalink
v1.0.8 超軽量化 & ブロックの光源が歪になる問題の修正
Browse files Browse the repository at this point in the history
  • Loading branch information
bea4dev committed Jul 31, 2021
1 parent 2905da8 commit 0c242a4
Show file tree
Hide file tree
Showing 15 changed files with 530 additions and 85 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
<dependency>
<groupId>com.github.Be4rJP</groupId>
<artifactId>Parallel</artifactId>
<version>v1.0.7</version>
<version>v1.0.8</version>
</dependency>
```

Expand Down
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

<groupId>be4rjp</groupId>
<artifactId>Parallel</artifactId>
<version>1.0.7</version>
<version>1.0.8</version>
<packaging>jar</packaging>

<name>Parallel</name>
Expand Down
147 changes: 119 additions & 28 deletions src/main/java/be4rjp/parallel/ParallelWorld.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,8 @@
import be4rjp.parallel.enums.UpdatePacketType;
import be4rjp.parallel.nms.NMSUtil;
import be4rjp.parallel.nms.manager.MultiBlockChangePacketManager;
import be4rjp.parallel.util.BlockLocation;
import be4rjp.parallel.util.BlockPosition3i;
import be4rjp.parallel.util.ChunkLocation;
import org.bukkit.Bukkit;
import org.bukkit.Chunk;
import org.bukkit.Location;
import org.bukkit.Material;
import be4rjp.parallel.util.*;
import org.bukkit.*;
import org.bukkit.block.Block;
import org.bukkit.block.data.BlockData;
import org.bukkit.entity.Player;
Expand Down Expand Up @@ -50,17 +45,31 @@ public static synchronized void removeParallelWorld(String uuid){


private final String uuid;
private final Map<ChunkLocation, Map<BlockLocation, BlockData>> chunkBlockMap;
private final Map<ChunkPosition, Map<BlockLocation, PBlockData>> chunkBlockMap;
private final Map<ChunkLocation, Object> editedPacketForChunkMap;
private final Map<ChunkLocation, Object> editedPacketForLightMap;

private ParallelWorld(String uuid){
this.uuid = uuid;
this.chunkBlockMap = new ConcurrentHashMap<>();
this.editedPacketForChunkMap = new ConcurrentHashMap<>();
this.editedPacketForLightMap = new ConcurrentHashMap<>();

removeParallelWorld(uuid);
worldMap.put(uuid, this);
}




private void addEditedChunk(ChunkPosition chunkPosition, World world){
ChunkLocation chunkLocation = new ChunkLocation(world, chunkPosition.x << 4, chunkPosition.z << 4);
this.editedPacketForChunkMap.remove(chunkLocation);
this.editedPacketForLightMap.remove(chunkLocation);
}

public Map<ChunkLocation, Object> getEditedPacketForChunkMap() {return editedPacketForChunkMap;}

public Map<ChunkLocation, Object> getEditedPacketForLightMap() {return editedPacketForLightMap;}

/**
* ブロックを設置します
* @param block 設置したいブロック
Expand All @@ -79,14 +88,16 @@ public void setBlock(Block block, Material material, boolean blockUpdate){
* @param blockUpdate ブロックの変更をプレイヤーに通知するかどうか
*/
public void setBlock(Block block, BlockData blockData, boolean blockUpdate){
ChunkLocation chunkLocation = new ChunkLocation(block.getX(), block.getZ());
ChunkPosition chunkPosition = new ChunkPosition(block.getX(), block.getZ());
this.addEditedChunk(chunkPosition, block.getWorld());

Map<BlockLocation, BlockData> blockMap = chunkBlockMap.get(chunkLocation);
Map<BlockLocation, PBlockData> blockMap = chunkBlockMap.get(chunkPosition);
if(blockMap == null){
blockMap = new ConcurrentHashMap<>();
chunkBlockMap.put(chunkLocation, blockMap);
chunkBlockMap.put(chunkPosition, blockMap);
}
blockMap.put(BlockLocation.createBlockLocation(block), blockData);
PBlockData pBlockData = blockMap.computeIfAbsent(BlockLocation.createBlockLocation(block), k -> new PBlockData());
pBlockData.setBlockData(blockData);

if(block.getChunk().isLoaded() && blockUpdate) {
for(Player player : Bukkit.getServer().getOnlinePlayers()) {
Expand All @@ -99,6 +110,25 @@ public void setBlock(Block block, BlockData blockData, boolean blockUpdate){
}


/**
* ブロックのライトレベルを設定します
* @param block 設定したいブロック
* @param level 設定したいライトレベル
*/
public void setLightLevel(Block block, int level){
ChunkPosition chunkPosition = new ChunkPosition(block.getX(), block.getZ());
this.addEditedChunk(chunkPosition, block.getWorld());

Map<BlockLocation, PBlockData> blockMap = chunkBlockMap.get(chunkPosition);
if(blockMap == null){
blockMap = new ConcurrentHashMap<>();
chunkBlockMap.put(chunkPosition, blockMap);
}
PBlockData pBlockData = blockMap.computeIfAbsent(BlockLocation.createBlockLocation(block), k -> new PBlockData());
pBlockData.setBlockLightLevel(Math.max(level, 15));
}


/**
* 一気に大量のブロックを設置します。
* @param blockDataMap 置き換えるブロックとブロックデータのマップ
Expand All @@ -115,14 +145,16 @@ public void setBlocks(Map<Block, BlockData> blockDataMap, @Nullable UpdatePacket
BlockData data = entry.getValue();

Location location = block.getLocation();
ChunkLocation chunkLocation = new ChunkLocation(location.getBlockX(), location.getBlockZ());
ChunkPosition chunkPosition = new ChunkPosition(location.getBlockX(), location.getBlockZ());
this.addEditedChunk(chunkPosition, block.getWorld());

Map<BlockLocation, BlockData> blockMap = chunkBlockMap.get(chunkLocation);
Map<BlockLocation, PBlockData> blockMap = chunkBlockMap.get(chunkPosition);
if(blockMap == null){
blockMap = new ConcurrentHashMap<>();
chunkBlockMap.put(chunkLocation, blockMap);
chunkBlockMap.put(chunkPosition, blockMap);
}
blockMap.put(BlockLocation.createBlockLocation(block), data);
PBlockData pBlockData = blockMap.computeIfAbsent(BlockLocation.createBlockLocation(block), k -> new PBlockData());
pBlockData.setBlockData(data);

Set<Block> blocks = updateMap.computeIfAbsent(block.getChunk(), k -> new HashSet<>());
blocks.add(block);
Expand Down Expand Up @@ -160,7 +192,7 @@ public void setBlocks(Map<Block, BlockData> blockDataMap, @Nullable UpdatePacket
short[] locations = new short[65535];
int index = 0;
for(Block block : blocks){
short loc = (short) ((block.getX() & 15) << 12 | (block.getZ() & 15) << 8 | block.getY());
short loc = (short) ((block.getX() & 0xF) << 12 | (block.getZ() & 0xF) << 8 | block.getY());
locations[index] = loc;
index++;
}
Expand Down Expand Up @@ -217,7 +249,7 @@ public void setBlocks(Map<Block, BlockData> blockDataMap, @Nullable UpdatePacket
* 設置した全てのブロックデータを消去します
*/
public void removeAll(){
worldMap.clear();
chunkBlockMap.clear();
}


Expand All @@ -235,14 +267,16 @@ public void setBlocks(Map<Block, BlockData> blockDataMap, boolean chunkUpdate){
BlockData data = entry.getValue();

BlockLocation location = BlockLocation.createBlockLocation(block);
ChunkLocation chunkLocation = new ChunkLocation(location.getX(), location.getZ());
ChunkPosition chunkPosition = new ChunkPosition(location.getX(), location.getZ());
this.addEditedChunk(chunkPosition, block.getWorld());

Map<BlockLocation, BlockData> blockMap = chunkBlockMap.get(chunkLocation);
Map<BlockLocation, PBlockData> blockMap = chunkBlockMap.get(chunkPosition);
if(blockMap == null){
blockMap = new ConcurrentHashMap<>();
chunkBlockMap.put(chunkLocation, blockMap);
chunkBlockMap.put(chunkPosition, blockMap);
}
blockMap.put(location, data);
PBlockData pBlockData = blockMap.computeIfAbsent(BlockLocation.createBlockLocation(block), k -> new PBlockData());
pBlockData.setBlockData(data);

chunkSet.add(block.getChunk());
}
Expand All @@ -265,6 +299,32 @@ public void setBlocks(Map<Block, BlockData> blockDataMap, boolean chunkUpdate){
}


/**
* 一気に大量のブロックのライトレベルを設定します。
* @param lightLevelMap 置き換えるブロックとブロックデータのマップ
*/
public void setLightLevels(Map<Block, Integer> lightLevelMap){
Set<Chunk> chunkSet = new HashSet<>();

for(Map.Entry<Block, Integer> entry : lightLevelMap.entrySet()){
Block block = entry.getKey();
int level = Math.max(entry.getValue(), 15);

BlockLocation location = BlockLocation.createBlockLocation(block);
ChunkPosition chunkPosition = new ChunkPosition(location.getX(), location.getZ());
this.addEditedChunk(chunkPosition, block.getWorld());

Map<BlockLocation, PBlockData> blockMap = chunkBlockMap.get(chunkPosition);
if(blockMap == null){
blockMap = new ConcurrentHashMap<>();
chunkBlockMap.put(chunkPosition, blockMap);
}
PBlockData pBlockData = blockMap.computeIfAbsent(BlockLocation.createBlockLocation(block), k -> new PBlockData());
pBlockData.setBlockLightLevel(level);

chunkSet.add(block.getChunk());
}
}



Expand All @@ -274,19 +334,50 @@ public void setBlocks(Map<Block, BlockData> blockDataMap, boolean chunkUpdate){
*/
public void removeBlock(Block block){
BlockLocation location = BlockLocation.createBlockLocation(block);
ChunkLocation chunkLocation = new ChunkLocation(location.getX(), location.getZ());
ChunkPosition chunkPosition = new ChunkPosition(location.getX(), location.getZ());
this.addEditedChunk(chunkPosition, block.getWorld());

Map<BlockLocation, BlockData> blockMap = chunkBlockMap.get(chunkLocation);
Map<BlockLocation, PBlockData> blockMap = chunkBlockMap.get(chunkPosition);
if(blockMap == null) return;
blockMap.remove(location);
}


/**
* ブロックデータを取得します
* @param block 取得したいブロック
* @return BlockData 見つからない場合は null を返します
*/
public @Nullable BlockData getBlockData(Block block){
BlockLocation location = BlockLocation.createBlockLocation(block);
ChunkPosition chunkPosition = new ChunkPosition(location.getX(), location.getZ());

Map<BlockLocation, PBlockData> blockMap = chunkBlockMap.get(chunkPosition);
if(blockMap == null) return null;
return blockMap.get(location).getBlockData();
}


/**
* ライトレベルを取得します
* @param block ライトレベルを取得したいブロック
* @return int(0 ~ 15) 見つからない場合は -1 を返します
*/
public int getBlockLightLevel(Block block){
BlockLocation location = BlockLocation.createBlockLocation(block);
ChunkPosition chunkPosition = new ChunkPosition(location.getX(), location.getZ());

Map<BlockLocation, PBlockData> blockMap = chunkBlockMap.get(chunkPosition);
if(blockMap == null) return -1;
return blockMap.get(location).getBlockLightLevel();
}


/**
* ブロックの編集を行いたい場合は必ずほかのメソッドを使用してください
* @return Map<ChunkLocation, Map<BlockLocation, BlockData>>
* @return Map<ChunkLocation, Map<BlockLocation, PBlockData>>
*/
public Map<ChunkLocation, Map<BlockLocation, BlockData>> getChunkBlockMap() {
public Map<ChunkPosition, Map<BlockLocation, PBlockData>> getChunkBlockMap() {
return new ConcurrentHashMap<>(chunkBlockMap);
}
}
6 changes: 3 additions & 3 deletions src/main/java/be4rjp/parallel/nms/NMSUtil.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package be4rjp.parallel.nms;

import be4rjp.parallel.util.BlockPosition3i;
import be4rjp.parallel.util.ChunkLocation;
import be4rjp.parallel.util.ChunkPosition;
import io.netty.channel.Channel;
import org.bukkit.Bukkit;
import org.bukkit.Chunk;
Expand Down Expand Up @@ -215,14 +215,14 @@ public static Object createSectionPosition(int x, int y, int z)
}


public static ChunkLocation getChunkLocation(Object chunkCoordIntPair)
public static ChunkPosition getChunkLocation(Object chunkCoordIntPair)
throws ClassNotFoundException, SecurityException, NoSuchMethodException, NoSuchFieldException,
IllegalArgumentException, IllegalAccessException, InvocationTargetException, InstantiationException {

Class<?> ChunkCoordIntPair = NMSUtil.getNMSClass("ChunkCoordIntPair");
int x = ChunkCoordIntPair.getField("x").getInt(chunkCoordIntPair);
int z = ChunkCoordIntPair.getField("z").getInt(chunkCoordIntPair);
return new ChunkLocation(x << 4, z << 4);
return new ChunkPosition(x << 4, z << 4);
}


Expand Down
11 changes: 7 additions & 4 deletions src/main/java/be4rjp/parallel/nms/PacketHandler.java
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
package be4rjp.parallel.nms;
import be4rjp.parallel.Parallel;
import be4rjp.parallel.nms.manager.BlockChangePacketManager;
import be4rjp.parallel.nms.manager.ChunkPacketManager;
import be4rjp.parallel.nms.manager.FlyingPacketManager;
import be4rjp.parallel.nms.manager.MultiBlockChangePacketManager;
import be4rjp.parallel.nms.manager.*;
import io.netty.channel.*;
import org.bukkit.entity.Player;

Expand Down Expand Up @@ -37,6 +34,12 @@ public void write(ChannelHandlerContext channelHandlerContext, Object packet, Ch
manager.runTaskAsynchronously(Parallel.getPlugin());
return;
}

if(packet.getClass().getSimpleName().equalsIgnoreCase("PacketPlayOutLightUpdate")){
LightUpdatePacketManager manager = new LightUpdatePacketManager(channelHandlerContext, packet, channelPromise, this, player);
manager.runTaskAsynchronously(Parallel.getPlugin());
return;
}

if(packet.getClass().getSimpleName().equalsIgnoreCase("PacketPlayOutBlockChange")){
BlockChangePacketManager manager = new BlockChangePacketManager(channelHandlerContext, packet, channelPromise, this, player);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@
import be4rjp.parallel.nms.PacketHandler;
import be4rjp.parallel.util.BlockLocation;
import be4rjp.parallel.util.BlockPosition3i;
import be4rjp.parallel.util.ChunkLocation;
import be4rjp.parallel.util.ChunkPosition;
import be4rjp.parallel.util.PBlockData;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelPromise;
import org.bukkit.block.data.BlockData;
Expand Down Expand Up @@ -55,16 +56,16 @@ public void run() {
BlockPosition3i position3i = NMSUtil.getBlockPosition3i(blockPosition);

ParallelWorld parallelWorld = ParallelWorld.getParallelWorld(player);
ChunkLocation chunkLocation = new ChunkLocation(position3i.getX(), position3i.getZ());
Map<BlockLocation, BlockData> dataMap = parallelWorld.getChunkBlockMap().get(chunkLocation);
ChunkPosition chunkPosition = new ChunkPosition(position3i.getX(), position3i.getZ());
Map<BlockLocation, PBlockData> dataMap = parallelWorld.getChunkBlockMap().get(chunkPosition);
if(dataMap == null){
packetHandler.doWrite(channelHandlerContext, packet, channelPromise);
return;
}
for (Map.Entry<BlockLocation, BlockData> entry : dataMap.entrySet()) {
for (Map.Entry<BlockLocation, PBlockData> entry : dataMap.entrySet()) {
BlockLocation location = entry.getKey();
BlockData blockData = entry.getValue();

BlockData blockData = entry.getValue().getBlockData();
if(blockData == null) continue;
if(player.getWorld() != location.getWorld()) continue;

if(position3i.getX() == location.getX() && position3i.getY() == location.getY() && position3i.getZ() == location.getZ()){
Expand Down
Loading

0 comments on commit 0c242a4

Please sign in to comment.