reset chunks allow to refresh chunk client side + report.
This commit is contained in:
1 parent
c66ed96a98
commit
9806af6ff9
3 files changed
+61
-24
No files matched your search
@@ -3,8 +3,9 @@ package carpet.fakes;
|
|||||||
import net.minecraft.util.math.ChunkPos;
|
import net.minecraft.util.math.ChunkPos;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
public interface ThreadedAnvilChunkStorageInterface
|
public interface ThreadedAnvilChunkStorageInterface
|
||||||
{
|
{
|
||||||
void regenerateChunkRegion(List<ChunkPos> requestedChunks);
|
Map<String, Integer> regenerateChunkRegion(List<ChunkPos> requestedChunks);
|
||||||
}
|
}
|
||||||
+47
-21
@@ -18,6 +18,7 @@ import net.minecraft.util.thread.ThreadExecutor;
|
|||||||
import net.minecraft.world.chunk.Chunk;
|
import net.minecraft.world.chunk.Chunk;
|
||||||
import net.minecraft.world.chunk.ChunkStatus;
|
import net.minecraft.world.chunk.ChunkStatus;
|
||||||
import net.minecraft.world.chunk.WorldChunk;
|
import net.minecraft.world.chunk.WorldChunk;
|
||||||
|
import net.minecraft.world.storage.RegionFile;
|
||||||
import org.spongepowered.asm.mixin.Final;
|
import org.spongepowered.asm.mixin.Final;
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
import org.spongepowered.asm.mixin.Shadow;
|
import org.spongepowered.asm.mixin.Shadow;
|
||||||
@@ -25,6 +26,9 @@ import org.spongepowered.asm.mixin.injection.At;
|
|||||||
import org.spongepowered.asm.mixin.injection.Inject;
|
import org.spongepowered.asm.mixin.injection.Inject;
|
||||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.nio.file.Path;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
@@ -84,10 +88,40 @@ public abstract class ThreadedAnvilChunkStorage_scarpetChunkCreationMixin implem
|
|||||||
world.getServer().execute( () -> CHUNK_GENERATED.onChunkGenerated(world, chunk) );
|
world.getServer().execute( () -> CHUNK_GENERATED.onChunkGenerated(world, chunk) );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
private boolean chunkExists(ChunkPos chpos, Map<String, RegionFile> regionCache)
|
||||||
public void regenerateChunkRegion(List<ChunkPos> requestedChunks)
|
|
||||||
{
|
{
|
||||||
|
String currentRegionName = "r." + chpos.getRegionX() + "." + chpos.getRegionZ() + ".mca";
|
||||||
|
if (regionCache != null && regionCache.containsKey(currentRegionName))
|
||||||
|
{
|
||||||
|
RegionFile region = regionCache.get(currentRegionName);
|
||||||
|
if (region == null) return false;
|
||||||
|
return region.hasChunk(chpos);
|
||||||
|
}
|
||||||
|
Path regionPath = world.getDimension().getType().getSaveDirectory(
|
||||||
|
world.getSaveHandler().getWorldDir()
|
||||||
|
).toPath().resolve("region");
|
||||||
|
Path regionFilePath = regionPath.resolve(currentRegionName);
|
||||||
|
File regionFile = regionFilePath.toFile();
|
||||||
|
if (!regionFile.exists())
|
||||||
|
{
|
||||||
|
if (regionCache != null) regionCache.put(currentRegionName, null);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
try
|
||||||
|
{
|
||||||
|
RegionFile region = new RegionFile(regionFile, regionPath.toFile());
|
||||||
|
if (regionCache != null) regionCache.put(currentRegionName, region);
|
||||||
|
return region.hasChunk(chpos);
|
||||||
|
}
|
||||||
|
catch (IOException ignored) { }
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Map<String, Integer> regenerateChunkRegion(List<ChunkPos> requestedChunks)
|
||||||
|
{
|
||||||
|
Map<String, Integer> report = new HashMap<>();
|
||||||
|
report.put("requested_chunks",requestedChunks.size());
|
||||||
//flushning all tasks on the thread executor so all futures are ready - we don't want any deadlocks
|
//flushning all tasks on the thread executor so all futures are ready - we don't want any deadlocks
|
||||||
mainThreadExecutor.runTasks(() -> mainThreadExecutor.getTaskCount() == 0);
|
mainThreadExecutor.runTasks(() -> mainThreadExecutor.getTaskCount() == 0);
|
||||||
// save all pending chunks
|
// save all pending chunks
|
||||||
@@ -104,20 +138,21 @@ public abstract class ThreadedAnvilChunkStorage_scarpetChunkCreationMixin implem
|
|||||||
if (chunk != null && chunk.getStatus() != ChunkStatus.EMPTY)
|
if (chunk != null && chunk.getStatus() != ChunkStatus.EMPTY)
|
||||||
loadedChunks.add(pos);
|
loadedChunks.add(pos);
|
||||||
}
|
}
|
||||||
CarpetSettings.LOG.error("Area has "+requestedChunks.size()+" chunks");
|
report.put("loaded_chunks", loadedChunks.size());
|
||||||
CarpetSettings.LOG.error("Area has "+loadedChunks.size()+" loaded chunks");
|
|
||||||
|
|
||||||
Map<ChunkPos,ChunkStatus> targetStatus = new HashMap<>();
|
Map<ChunkPos,ChunkStatus> targetStatus = new HashMap<>();
|
||||||
|
Map<String, RegionFile> regionCache = new HashMap<>();
|
||||||
for (ChunkPos pos: requestedChunks)
|
for (ChunkPos pos: requestedChunks)
|
||||||
{
|
{
|
||||||
|
if (!chunkExists(pos, regionCache)) continue;
|
||||||
Chunk chunk = world.getChunk(pos.x, pos.z, ChunkStatus.EMPTY, true);
|
Chunk chunk = world.getChunk(pos.x, pos.z, ChunkStatus.EMPTY, true);
|
||||||
if (chunk == null || chunk.getStatus() == ChunkStatus.EMPTY)
|
if (chunk == null || chunk.getStatus() == ChunkStatus.EMPTY)
|
||||||
continue;
|
continue;
|
||||||
//unloaded areas can have unknown skirt chunk area
|
//unloaded areas can have unknown skirt chunk area
|
||||||
targetStatus.put(pos, loadedChunks.contains(pos)?chunk.getStatus():ChunkStatus.STRUCTURE_STARTS);
|
targetStatus.put(pos, loadedChunks.contains(pos)?chunk.getStatus():ChunkStatus.STRUCTURE_STARTS);
|
||||||
}
|
}
|
||||||
CarpetSettings.LOG.error("Area has "+targetStatus.size()+" chunks for removal");
|
regionCache.clear();
|
||||||
|
report.put("affected_chunks", targetStatus.size());
|
||||||
|
|
||||||
|
|
||||||
for (ChunkPos chpos : targetStatus.keySet())
|
for (ChunkPos chpos : targetStatus.keySet())
|
||||||
@@ -128,8 +163,7 @@ public abstract class ThreadedAnvilChunkStorage_scarpetChunkCreationMixin implem
|
|||||||
int currentLevel = ThreadedAnvilChunkStorage.MAX_LEVEL;
|
int currentLevel = ThreadedAnvilChunkStorage.MAX_LEVEL;
|
||||||
if (chunkHolder != null)
|
if (chunkHolder != null)
|
||||||
{
|
{
|
||||||
//CarpetSettings.LOG.error("current_level: "+chunkHolder.getLevel());
|
currentLevel = chunkHolder.getLevel()-1;
|
||||||
currentLevel = chunkHolder.getLevel();
|
|
||||||
//method_20458(id, chunkHolder); // saving chunk // skipping entities etc
|
//method_20458(id, chunkHolder); // saving chunk // skipping entities etc
|
||||||
Chunk chunk = null;
|
Chunk chunk = null;
|
||||||
try
|
try
|
||||||
@@ -184,34 +218,25 @@ public abstract class ThreadedAnvilChunkStorage_scarpetChunkCreationMixin implem
|
|||||||
|
|
||||||
for (ChunkStatus status : ChunkStatus.createOrderedList())
|
for (ChunkStatus status : ChunkStatus.createOrderedList())
|
||||||
{
|
{
|
||||||
CarpetSettings.LOG.error("Creating layer: " + status.getId() + " for "+targetStatus.size()+" chunks");
|
report.put("layer_count_"+status.getId(),targetStatus.size());
|
||||||
|
long start = System.currentTimeMillis();
|
||||||
if (status == ChunkStatus.LIGHT)
|
if (status == ChunkStatus.LIGHT)
|
||||||
{
|
{
|
||||||
//break;
|
|
||||||
serverLightingProvider.setTaskBatchSize(targetStatus.size() + 20);
|
serverLightingProvider.setTaskBatchSize(targetStatus.size() + 20);
|
||||||
}
|
}
|
||||||
for (ChunkPos chpos : new ArrayList<>(targetStatus.keySet()))
|
for (ChunkPos chpos : new ArrayList<>(targetStatus.keySet()))
|
||||||
{
|
{
|
||||||
if (targetStatus.get(chpos) == status)
|
if (targetStatus.get(chpos) == status)
|
||||||
targetStatus.remove(chpos);
|
targetStatus.remove(chpos);
|
||||||
//if (status==ChunkStatus.LIGHT)
|
|
||||||
//{
|
|
||||||
// serverLightingProvider.tick();
|
|
||||||
//}
|
|
||||||
//CarpetSettings.LOG.error("Creating layer: " + status.getId());
|
|
||||||
world.getChunk(chpos.x, chpos.z, status);
|
world.getChunk(chpos.x, chpos.z, status);
|
||||||
if (status == ChunkStatus.FULL)
|
if (status == ChunkStatus.FULL)
|
||||||
convertToFullChunk(currentChunkHolders.get(chpos.toLong()));
|
convertToFullChunk(currentChunkHolders.get(chpos.toLong()));
|
||||||
//CarpetSettings.LOG.error(" .. done");
|
|
||||||
//if (status==ChunkStatus.LIGHT)
|
|
||||||
//{
|
|
||||||
// serverLightingProvider.tick();
|
|
||||||
//}
|
|
||||||
}
|
}
|
||||||
if (status == ChunkStatus.LIGHT)
|
if (status == ChunkStatus.LIGHT)
|
||||||
{
|
{ // default task batch size after initial generation is done
|
||||||
serverLightingProvider.setTaskBatchSize(5);
|
serverLightingProvider.setTaskBatchSize(5);
|
||||||
}
|
}
|
||||||
|
report.put("layer_time_"+status.getId(), (int) (System.currentTimeMillis()-start));
|
||||||
}
|
}
|
||||||
|
|
||||||
mainThreadExecutor.runTasks(() -> mainThreadExecutor.getTaskCount() == 0);
|
mainThreadExecutor.runTasks(() -> mainThreadExecutor.getTaskCount() == 0);
|
||||||
@@ -222,5 +247,6 @@ public abstract class ThreadedAnvilChunkStorage_scarpetChunkCreationMixin implem
|
|||||||
{
|
{
|
||||||
runnable.run();
|
runnable.run();
|
||||||
}
|
}
|
||||||
|
return report;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1249,14 +1249,24 @@ public class CarpetExpression
|
|||||||
|
|
||||||
ServerWorld world = cc.s.getWorld();
|
ServerWorld world = cc.s.getWorld();
|
||||||
|
|
||||||
|
Value [] result = new Value[]{Value.NULL};
|
||||||
|
|
||||||
((CarpetContext)c).s.getMinecraftServer().submitAndJoin( () ->
|
((CarpetContext)c).s.getMinecraftServer().submitAndJoin( () ->
|
||||||
{
|
{
|
||||||
((ThreadedAnvilChunkStorageInterface) world.getChunkManager().threadedAnvilChunkStorage).regenerateChunkRegion(requestedChunks);
|
Map<String, Integer> report = ((ThreadedAnvilChunkStorageInterface) world.getChunkManager().threadedAnvilChunkStorage).regenerateChunkRegion(requestedChunks);
|
||||||
for (ChunkPos chpos: requestedChunks)
|
for (ChunkPos chpos: requestedChunks)
|
||||||
|
{
|
||||||
if (world.getChunk(chpos.x, chpos.z, ChunkStatus.FULL, false) != null)
|
if (world.getChunk(chpos.x, chpos.z, ChunkStatus.FULL, false) != null)
|
||||||
|
{
|
||||||
this.forceChunkUpdate(chpos.getCenterBlockPos(), world);
|
this.forceChunkUpdate(chpos.getCenterBlockPos(), world);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
result[0] = MapValue.wrap(report.entrySet().stream().collect(Collectors.toMap(
|
||||||
|
e -> new StringValue((String)((Map.Entry) e).getKey()),
|
||||||
|
e -> new NumericValue((Integer)((Map.Entry) e).getValue())
|
||||||
|
)));
|
||||||
});
|
});
|
||||||
return LazyValue.NULL;
|
return (_c, _t) -> result[0];
|
||||||
});
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in new issue
Block a user