返回提交历史
Modified
build.gradle
+1
-1
Modified
gradle.properties
+1
-1
Modified
src/main/java/com/xfestudio/mydimension/item/RiftItem.java
+51
-62
Modified
src/main/java/com/xfestudio/mydimension/world/MindInstances.java
+2
-2
Modified
src/main/resources/assets/mydimension/lang/en_us.json
+1
-1
Modified
src/main/resources/assets/mydimension/lang/zh_cn.json
+1
-1
XFEstudio/MyDimension
优化复制逻辑
1dc3ba1
代码差异
6 个文件
+57
-68
@@ -122,7 +122,7 @@ tasks.register('generatePlayerMindDimensions') {
122
122
]
123
123
]
124
124
125
(0..<128).each { slot ->
125
(0..<64).each { slot ->
126
126
dimensions.each { name, json ->
127
127
def file = new File(dimensionDir, "slot_${slot}/${name}.json")
128
128
file.parentFile.mkdirs()
@@ -11,7 +11,7 @@ loader_version_range=[47,)
11
11
mod_id=mydimension
12
12
mod_name=\u6211\u7684\u7ef4\u5ea6
13
13
mod_license=CC0-1.0
14
mod_version=2.0.0
14
mod_version=2.0.2
15
15
mod_group_id=com.xfestudio.mydimension
16
16
maven_group=com.xfestudio
17
17
archives_base_name=mydimension
@@ -9,7 +9,6 @@ import net.minecraft.nbt.CompoundTag;
9
9
import net.minecraft.network.chat.Component;
10
10
import net.minecraft.resources.ResourceKey;
11
11
import net.minecraft.resources.ResourceLocation;
12
import net.minecraft.server.MinecraftServer;
13
12
import net.minecraft.server.level.ServerLevel;
14
13
import net.minecraft.server.level.ServerPlayer;
15
14
import net.minecraft.sounds.SoundEvents;
@@ -24,10 +23,9 @@ import net.minecraft.world.entity.projectile.ProjectileUtil;
24
23
import net.minecraft.world.item.Item;
25
24
import net.minecraft.world.item.ItemStack;
26
25
import net.minecraft.world.level.Level;
27
import net.minecraft.world.level.dimension.DimensionType;
26
import net.minecraft.world.level.block.entity.BlockEntity;
28
27
import net.minecraft.world.level.levelgen.Heightmap;
29
28
import net.minecraft.world.level.portal.PortalInfo;
30
import net.minecraft.world.level.storage.LevelResource;
31
29
import net.minecraft.world.phys.AABB;
32
30
import net.minecraft.world.phys.EntityHitResult;
33
31
import net.minecraft.world.phys.Vec3;
@@ -35,17 +33,12 @@ import net.minecraftforge.api.distmarker.Dist;
35
33
import net.minecraftforge.common.util.ITeleporter;
36
34
import net.minecraftforge.fml.DistExecutor;
37
35
38
import java.io.IOException;
39
import java.nio.file.FileVisitResult;
40
import java.nio.file.Files;
41
import java.nio.file.Path;
42
import java.nio.file.SimpleFileVisitor;
43
import java.nio.file.attribute.BasicFileAttributes;
44
36
import java.util.function.Function;
45
37
46
38
public class RiftItem extends Item {
47
39
public static final double ETHEREAL_SURFACE_Y = 66.0D;
48
40
public static final String IMPORTED_TO_ETHEREAL_MIND = "mydimension_imported_to_ethereal_mind";
41
private static final int COPY_CHUNK_RADIUS = 1;
49
42
private static final String SELECTED_ACTION_TAG = "SelectedAction";
50
43
private static final String RETURN_POINT_TAG = "ReturnPoint";
51
44
private static final String MIND_POINTS_TAG = "MindPoints";
@@ -272,72 +265,68 @@ public class RiftItem extends Item {
272
265
return;
273
266
}
274
267
275
MinecraftServer server = player.getServer();
276
if (server == null || server.getLevel(sourceDimension) == null || server.getLevel(targetDimension) == null) {
268
ServerLevel sourceLevel = player.getServer().getLevel(sourceDimension);
269
ServerLevel targetLevel = player.getServer().getLevel(targetDimension);
270
if (sourceLevel == null || targetLevel == null) {
277
271
player.displayClientMessage(Component.translatable("message.mydimension.missing_dimension"), true);
278
272
return;
279
273
}
280
274
281
try {
282
server.saveEverything(false, true, false);
283
Path worldRoot = server.getWorldPath(LevelResource.ROOT).normalize();
284
Path source = DimensionType.getStorageFolder(sourceDimension, worldRoot).normalize();
285
Path target = DimensionType.getStorageFolder(targetDimension, worldRoot).normalize();
286
if (!source.startsWith(worldRoot) || !target.startsWith(worldRoot) || source.equals(target)) {
287
player.displayClientMessage(Component.translatable("message.mydimension.copy_failed"), true);
288
return;
289
}
275
int copiedBlocks = copyNearbyBlocks(sourceLevel, targetLevel, player.blockPosition());
276
player.displayClientMessage(Component.translatable("message.mydimension.copy_done", copiedBlocks), true);
277
}
290
278
291
if (!Files.exists(source)) {
292
player.displayClientMessage(Component.translatable("message.mydimension.copy_missing_shared"), true);
293
return;
279
private static int copyNearbyBlocks(ServerLevel sourceLevel, ServerLevel targetLevel, BlockPos center) {
280
int centerChunkX = center.getX() >> 4;
281
int centerChunkZ = center.getZ() >> 4;
282
int minY = Math.max(sourceLevel.getMinBuildHeight(), targetLevel.getMinBuildHeight());
283
int maxY = Math.min(sourceLevel.getMaxBuildHeight(), targetLevel.getMaxBuildHeight());
284
BlockPos.MutableBlockPos sourcePos = new BlockPos.MutableBlockPos();
285
BlockPos.MutableBlockPos targetPos = new BlockPos.MutableBlockPos();
286
int copied = 0;
287
288
for (int chunkX = centerChunkX - COPY_CHUNK_RADIUS; chunkX <= centerChunkX + COPY_CHUNK_RADIUS; chunkX++) {
289
for (int chunkZ = centerChunkZ - COPY_CHUNK_RADIUS; chunkZ <= centerChunkZ + COPY_CHUNK_RADIUS; chunkZ++) {
290
sourceLevel.getChunk(chunkX, chunkZ);
291
targetLevel.getChunk(chunkX, chunkZ);
292
293
int minX = chunkX << 4;
294
int minZ = chunkZ << 4;
295
for (int x = minX; x < minX + 16; x++) {
296
for (int z = minZ; z < minZ + 16; z++) {
297
for (int y = minY; y < maxY; y++) {
298
sourcePos.set(x, y, z);
299
targetPos.set(x, y, z);
300
var state = sourceLevel.getBlockState(sourcePos);
301
targetLevel.setBlock(targetPos, state, 2);
302
copyBlockEntity(sourceLevel, targetLevel, sourcePos, targetPos);
303
copied++;
304
}
305
}
306
}
294
307
}
295
296
deleteDirectory(target);
297
copyDirectory(source, target);
298
player.displayClientMessage(Component.translatable("message.mydimension.copy_done"), true);
299
} catch (IOException exception) {
300
player.displayClientMessage(Component.translatable("message.mydimension.copy_failed"), true);
301
308
}
309
310
return copied;
302
311
}
303
312
304
private static void deleteDirectory(Path path) throws IOException {
305
if (!Files.exists(path)) {
313
private static void copyBlockEntity(ServerLevel sourceLevel, ServerLevel targetLevel, BlockPos sourcePos, BlockPos targetPos) {
314
BlockEntity sourceBlockEntity = sourceLevel.getBlockEntity(sourcePos);
315
if (sourceBlockEntity == null) {
306
316
return;
307
317
}
308
318
309
Files.walkFileTree(path, new SimpleFileVisitor<>() {
310
@Override
311
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
312
Files.delete(file);
313
return FileVisitResult.CONTINUE;
314
}
315
316
@Override
317
public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException {
318
if (exc != null) {
319
throw exc;
320
}
321
Files.delete(dir);
322
return FileVisitResult.CONTINUE;
323
}
324
});
325
}
326
327
private static void copyDirectory(Path source, Path target) throws IOException {
328
Files.walkFileTree(source, new SimpleFileVisitor<>() {
329
@Override
330
public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException {
331
Files.createDirectories(target.resolve(source.relativize(dir)));
332
return FileVisitResult.CONTINUE;
333
}
319
BlockEntity targetBlockEntity = targetLevel.getBlockEntity(targetPos);
320
if (targetBlockEntity == null) {
321
return;
322
}
334
323
335
@Override
336
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
337
Files.copy(file, target.resolve(source.relativize(file)));
338
return FileVisitResult.CONTINUE;
339
}
340
});
324
CompoundTag tag = sourceBlockEntity.saveWithFullMetadata();
325
tag.putInt("x", targetPos.getX());
326
tag.putInt("y", targetPos.getY());
327
tag.putInt("z", targetPos.getZ());
328
targetBlockEntity.load(tag);
329
targetBlockEntity.setChanged();
341
330
}
342
331
343
332
private static LivingEntity findLookedAtLivingEntity(ServerPlayer player) {
@@ -12,14 +12,14 @@ import java.util.Map;
12
12
import java.util.UUID;
13
13
14
14
public class MindInstances {
15
public static final int MAX_PLAYER_SLOTS = 128;
15
public static final int MAX_PLAYER_SLOTS = 64;
16
16
private static final String DATA_NAME = "mydimension_mind_instances";
17
17
private static final String NEXT_SLOT_TAG = "NextSlot";
18
18
private static final String SLOTS_TAG = "Slots";
19
19
20
20
public static ResourceKey<Level> dimensionFor(ServerPlayer player, ResourceKey<Level> baseDimension) {
21
21
int slot = slotFor(player);
22
return slot < 0 ? baseDimension : ModDimensions.playerDimension(baseDimension, slot);
22
return slot < 0 || slot >= MAX_PLAYER_SLOTS ? baseDimension : ModDimensions.playerDimension(baseDimension, slot);
23
23
}
24
24
25
25
public static int slotFor(ServerPlayer player) {
@@ -46,6 +46,6 @@
46
46
"message.mydimension.copy_creative_only": "Only creative players can copy shared mind saves",
47
47
"message.mydimension.copy_private_unavailable": "No private mind slot is available, so the shared save cannot be copied",
48
48
"message.mydimension.copy_missing_shared": "The shared mind has no saved world data to copy yet",
49
"message.mydimension.copy_done": "Copied the shared mind save to your private mind",
49
"message.mydimension.copy_done": "Copied nearby shared mind blocks to your private mind: %s blocks",
50
50
"message.mydimension.copy_failed": "Failed to copy shared mind save"
51
51
}
@@ -46,7 +46,7 @@
46
46
"message.mydimension.copy_creative_only": "只有创造模式玩家可以复制公共心境存档",
47
47
"message.mydimension.copy_private_unavailable": "私有心境槽位不足,无法复制公共存档",
48
48
"message.mydimension.copy_missing_shared": "公共心境尚未生成存档,无法复制",
49
"message.mydimension.copy_done": "已复制公共心境存档到你的私有心境",
49
"message.mydimension.copy_done": "已复制公共心境附近方块到你的私有心境:%s 个方块",
50
50
"message.mydimension.copy_failed": "复制公共心境存档失败",
51
51
"itemGroup.mydimension": "我的维度"
52
52
}