返回提交历史
Modified
build.gradle
+1
-1
Modified
gradle.properties
+1
-1
Modified
src/main/java/com/xfestudio/mydimension/world/MindInstances.java
+200
-2
XFEstudio/MyDimension
优化维度加载机制
a3d108a
代码差异
3 个文件
+202
-4
@@ -146,7 +146,7 @@ tasks.register('generatePlayerMindDimensions') {
146
146
]
147
147
]
148
148
149
(0..<64).each { slot ->
149
(0..<2).each { slot ->
150
150
dimensions.each { name, json ->
151
151
def file = new File(dimensionDir, "slot_${slot}/${name}.json")
152
152
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.1.1
14
mod_version=2.2.0
15
15
mod_group_id=com.xfestudio.mydimension
16
16
maven_group=com.xfestudio
17
17
archives_base_name=mydimension
@@ -1,29 +1,56 @@
1
1
package com.xfestudio.mydimension.world;
2
2
3
import com.xfestudio.mydimension.MyDimension;
3
4
import net.minecraft.nbt.CompoundTag;
4
5
import net.minecraft.resources.ResourceKey;
5
6
import net.minecraft.server.MinecraftServer;
6
7
import net.minecraft.server.level.ServerPlayer;
7
8
import net.minecraft.world.level.Level;
8
9
import net.minecraft.world.level.saveddata.SavedData;
10
import net.minecraft.world.level.storage.LevelResource;
9
11
12
import java.io.IOException;
13
import java.nio.charset.StandardCharsets;
14
import java.nio.file.Files;
15
import java.nio.file.Path;
16
import java.util.Comparator;
10
17
import java.util.HashMap;
11
18
import java.util.Map;
12
19
import java.util.UUID;
13
20
14
21
public class MindInstances {
15
22
public static final int MAX_PLAYER_SLOTS = 64;
23
public static final int BUILT_IN_PLAYER_SLOTS = 2;
16
24
private static final String DATA_NAME = "mydimension_mind_instances";
17
25
private static final String NEXT_SLOT_TAG = "NextSlot";
26
private static final String REQUESTED_SLOTS_TAG = "RequestedSlots";
18
27
private static final String SLOTS_TAG = "Slots";
28
private static final String GENERATED_DATAPACK_NAME = "mydimension_dynamic_player_minds";
19
29
20
30
public static ResourceKey<Level> dimensionFor(ServerPlayer player, ResourceKey<Level> baseDimension) {
21
31
int slot = slotFor(player);
22
return slot < 0 || slot >= MAX_PLAYER_SLOTS ? baseDimension : ModDimensions.playerDimension(baseDimension, slot);
32
if (slot < 0 || slot >= MAX_PLAYER_SLOTS) {
33
return baseDimension;
34
}
35
36
MinecraftServer server = player.getServer();
37
ResourceKey<Level> privateDimension = ModDimensions.playerDimension(baseDimension, slot);
38
if (server.getLevel(privateDimension) != null) {
39
return privateDimension;
40
}
41
42
data(server).requestSlots(server, slot + 1);
43
return baseDimension;
23
44
}
24
45
25
46
public static int slotFor(ServerPlayer player) {
26
return data(player.getServer()).slotFor(player.getUUID());
47
MinecraftServer server = player.getServer();
48
MindInstanceData data = data(server);
49
int slot = data.slotFor(player.getUUID());
50
if (slot >= BUILT_IN_PLAYER_SLOTS) {
51
data.requestSlots(server, slot + 1);
52
}
53
return slot;
27
54
}
28
55
29
56
private static MindInstanceData data(MinecraftServer server) {
@@ -33,10 +60,12 @@ public class MindInstances {
33
60
public static class MindInstanceData extends SavedData {
34
61
private final Map<UUID, Integer> slots = new HashMap<>();
35
62
private int nextSlot;
63
private int requestedSlots = BUILT_IN_PLAYER_SLOTS;
36
64
37
65
public static MindInstanceData load(CompoundTag tag) {
38
66
MindInstanceData data = new MindInstanceData();
39
67
data.nextSlot = tag.getInt(NEXT_SLOT_TAG);
68
data.requestedSlots = Math.max(BUILT_IN_PLAYER_SLOTS, tag.contains(REQUESTED_SLOTS_TAG) ? tag.getInt(REQUESTED_SLOTS_TAG) : data.nextSlot);
40
69
CompoundTag slotsTag = tag.getCompound(SLOTS_TAG);
41
70
for (String key : slotsTag.getAllKeys()) {
42
71
try {
@@ -50,6 +79,7 @@ public class MindInstances {
50
79
@Override
51
80
public CompoundTag save(CompoundTag tag) {
52
81
tag.putInt(NEXT_SLOT_TAG, nextSlot);
82
tag.putInt(REQUESTED_SLOTS_TAG, requestedSlots);
53
83
CompoundTag slotsTag = new CompoundTag();
54
84
for (Map.Entry<UUID, Integer> entry : slots.entrySet()) {
55
85
slotsTag.putInt(entry.getKey().toString(), entry.getValue());
@@ -73,5 +103,173 @@ public class MindInstances {
73
103
setDirty();
74
104
return slot;
75
105
}
106
107
private void requestSlots(MinecraftServer server, int slotsNeeded) {
108
int clampedSlots = Math.min(Math.max(slotsNeeded, BUILT_IN_PLAYER_SLOTS), MAX_PLAYER_SLOTS);
109
if (clampedSlots > requestedSlots) {
110
requestedSlots = clampedSlots;
111
setDirty();
112
}
113
114
if (clampedSlots > BUILT_IN_PLAYER_SLOTS) {
115
writeGeneratedDatapack(server, clampedSlots);
116
}
117
}
118
}
119
120
private static void writeGeneratedDatapack(MinecraftServer server, int slotsNeeded) {
121
Path datapackRoot = server.getWorldPath(LevelResource.DATAPACK_DIR).resolve(GENERATED_DATAPACK_NAME);
122
Path dimensionDir = datapackRoot.resolve("data").resolve(MyDimension.MOD_ID).resolve("dimension").resolve("player_minds");
123
try {
124
deleteDirectory(dimensionDir);
125
Files.createDirectories(dimensionDir);
126
Files.writeString(datapackRoot.resolve("pack.mcmeta"), """
127
{
128
"pack": {
129
"description": "My Dimension dynamic private mind dimensions",
130
"pack_format": 15
131
}
132
}
133
""", StandardCharsets.UTF_8);
134
135
for (int slot = BUILT_IN_PLAYER_SLOTS; slot < slotsNeeded; slot++) {
136
writeSlotDimensions(dimensionDir, slot);
137
}
138
} catch (IOException exception) {
139
MyDimension.LOGGER.warn("Failed to write dynamic player mind dimension datapack", exception);
140
}
141
}
142
143
private static void writeSlotDimensions(Path dimensionDir, int slot) throws IOException {
144
Path slotDir = dimensionDir.resolve("slot_" + slot);
145
Files.createDirectories(slotDir);
146
Files.writeString(slotDir.resolve("ethereal_mind.json"), etherealMindJson(), StandardCharsets.UTF_8);
147
Files.writeString(slotDir.resolve("mirror_mind.json"), mirrorMindJson(), StandardCharsets.UTF_8);
148
Files.writeString(slotDir.resolve("water_mind.json"), waterMindJson(), StandardCharsets.UTF_8);
149
Files.writeString(slotDir.resolve("nature_mind.json"), natureMindJson(), StandardCharsets.UTF_8);
150
Files.writeString(slotDir.resolve("soaring_mind.json"), soaringMindJson(), StandardCharsets.UTF_8);
151
}
152
153
private static void deleteDirectory(Path directory) throws IOException {
154
if (!Files.exists(directory)) {
155
return;
156
}
157
158
try (var paths = Files.walk(directory)) {
159
for (Path path : paths.sorted(Comparator.reverseOrder()).toList()) {
160
Files.deleteIfExists(path);
161
}
162
}
163
}
164
165
private static String etherealMindJson() {
166
return """
167
{
168
"type": "mydimension:ethereal_mind",
169
"generator": {
170
"type": "minecraft:flat",
171
"settings": {
172
"biome": "mydimension:ethereal_mind",
173
"features": false,
174
"lakes": false,
175
"layers": [
176
{ "block": "minecraft:stone", "height": 60 },
177
{ "block": "minecraft:dirt", "height": 3 },
178
{ "block": "minecraft:quartz_block", "height": 3 }
179
],
180
"structure_overrides": []
181
}
182
}
183
}
184
""";
185
}
186
187
private static String mirrorMindJson() {
188
return """
189
{
190
"type": "mydimension:mirror_mind",
191
"generator": {
192
"type": "mydimension:no_structure_noise",
193
"biome_source": {
194
"type": "minecraft:multi_noise",
195
"preset": "minecraft:overworld"
196
},
197
"settings": "minecraft:overworld"
198
}
199
}
200
""";
201
}
202
203
private static String waterMindJson() {
204
return """
205
{
206
"type": "mydimension:water_mind",
207
"generator": {
208
"type": "minecraft:flat",
209
"settings": {
210
"biome": "mydimension:water_mind",
211
"features": false,
212
"lakes": false,
213
"layers": [
214
{ "block": "minecraft:stone", "height": 20 },
215
{ "block": "minecraft:gravel", "height": 5 },
216
{ "block": "minecraft:water", "height": 50 }
217
],
218
"structure_overrides": []
219
}
220
}
221
}
222
""";
223
}
224
225
private static String natureMindJson() {
226
return """
227
{
228
"type": "mydimension:nature_mind",
229
"generator": {
230
"type": "minecraft:flat",
231
"settings": {
232
"biome": "mydimension:nature_mind",
233
"features": true,
234
"lakes": false,
235
"layers": [
236
{ "block": "minecraft:stone", "height": 50 },
237
{ "block": "minecraft:dirt", "height": 9 },
238
{ "block": "minecraft:grass_block", "height": 1 }
239
],
240
"structure_overrides": []
241
}
242
}
243
}
244
""";
245
}
246
247
private static String soaringMindJson() {
248
return """
249
{
250
"type": "mydimension:soaring_mind",
251
"generator": {
252
"type": "mydimension:soaring_islands",
253
"biome_source": {
254
"type": "minecraft:checkerboard",
255
"biomes": [
256
"minecraft:plains",
257
"minecraft:forest",
258
"minecraft:flower_forest",
259
"minecraft:birch_forest",
260
"minecraft:meadow",
261
"minecraft:cherry_grove",
262
"minecraft:snowy_plains",
263
"minecraft:grove",
264
"minecraft:desert",
265
"minecraft:savanna",
266
"minecraft:jungle",
267
"minecraft:windswept_hills"
268
],
269
"scale": 3
270
}
271
}
272
}
273
""";
76
274
}
77
275
}