package com.xfestudio.mydimension.world;
import com.xfestudio.mydimension.MyDimension;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.resources.ResourceKey;
import net.minecraft.server.MinecraftServer;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.saveddata.SavedData;
import net.minecraft.world.level.storage.LevelResource;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
public class MindInstances {
public static final int MAX_PLAYER_SLOTS = 64;
public static final int BUILT_IN_PLAYER_SLOTS = 2;
private static final String DATA_NAME = "mydimension_mind_instances";
private static final String NEXT_SLOT_TAG = "NextSlot";
private static final String REQUESTED_SLOTS_TAG = "RequestedSlots";
private static final String SLOTS_TAG = "Slots";
private static final String GENERATED_DATAPACK_NAME = "mydimension_dynamic_player_minds";
public static ResourceKey<Level> dimensionFor(ServerPlayer player, ResourceKey<Level> baseDimension) {
if (!PrivateMindFeature.isEnabled()) {
return baseDimension;
}
int slot = slotFor(player);
if (slot < 0 || slot >= MAX_PLAYER_SLOTS) {
return baseDimension;
}
MinecraftServer server = player.getServer();
ResourceKey<Level> privateDimension = ModDimensions.playerDimension(baseDimension, slot);
if (server.getLevel(privateDimension) != null) {
return privateDimension;
}
data(server).requestSlots(server, slot + 1);
return baseDimension;
}
public static ResourceKey<Level> dimensionForOwner(MinecraftServer server, UUID owner, ResourceKey<Level> baseDimension) {
if (!PrivateMindFeature.isEnabled()) {
return baseDimension;
}
int slot = slotFor(server, owner);
if (slot < 0 || slot >= MAX_PLAYER_SLOTS) {
return null;
}
return ModDimensions.playerDimension(baseDimension, slot);
}
public static int slotFor(ServerPlayer player) {
if (!PrivateMindFeature.isEnabled()) {
return -1;
}
return slotFor(player.getServer(), player.getUUID());
}
public static int slotFor(MinecraftServer server, UUID owner) {
if (!PrivateMindFeature.isEnabled()) {
return -1;
}
MindInstanceData data = data(server);
int slot = data.slotFor(owner);
if (slot >= BUILT_IN_PLAYER_SLOTS) {
data.requestSlots(server, slot + 1);
}
return slot;
}
private static MindInstanceData data(MinecraftServer server) {
return server.overworld().getDataStorage().computeIfAbsent(MindInstanceData::load, MindInstanceData::new, DATA_NAME);
}
public static class MindInstanceData extends SavedData {
private final Map<UUID, Integer> slots = new HashMap<>();
private int nextSlot;
private int requestedSlots = BUILT_IN_PLAYER_SLOTS;
public static MindInstanceData load(CompoundTag tag) {
MindInstanceData data = new MindInstanceData();
data.nextSlot = tag.getInt(NEXT_SLOT_TAG);
data.requestedSlots = Math.max(BUILT_IN_PLAYER_SLOTS, tag.contains(REQUESTED_SLOTS_TAG) ? tag.getInt(REQUESTED_SLOTS_TAG) : data.nextSlot);
CompoundTag slotsTag = tag.getCompound(SLOTS_TAG);
for (String key : slotsTag.getAllKeys()) {
try {
data.slots.put(UUID.fromString(key), slotsTag.getInt(key));
} catch (IllegalArgumentException ignored) {
}
}
return data;
}
@Override
public CompoundTag save(CompoundTag tag) {
tag.putInt(NEXT_SLOT_TAG, nextSlot);
tag.putInt(REQUESTED_SLOTS_TAG, requestedSlots);
CompoundTag slotsTag = new CompoundTag();
for (Map.Entry<UUID, Integer> entry : slots.entrySet()) {
slotsTag.putInt(entry.getKey().toString(), entry.getValue());
}
tag.put(SLOTS_TAG, slotsTag);
return tag;
}
private int slotFor(UUID owner) {
Integer existing = slots.get(owner);
if (existing != null) {
return existing;
}
if (nextSlot >= MAX_PLAYER_SLOTS) {
return -1;
}
int slot = nextSlot++;
slots.put(owner, slot);
setDirty();
return slot;
}
private void requestSlots(MinecraftServer server, int slotsNeeded) {
int clampedSlots = Math.min(Math.max(slotsNeeded, BUILT_IN_PLAYER_SLOTS), MAX_PLAYER_SLOTS);
if (clampedSlots > requestedSlots) {
requestedSlots = clampedSlots;
setDirty();
}
if (clampedSlots > BUILT_IN_PLAYER_SLOTS) {
writeGeneratedDatapack(server, clampedSlots);
}
}
}
private static void writeGeneratedDatapack(MinecraftServer server, int slotsNeeded) {
Path datapackRoot = server.getWorldPath(LevelResource.DATAPACK_DIR).resolve(GENERATED_DATAPACK_NAME);
Path dimensionDir = datapackRoot.resolve("data").resolve(MyDimension.MOD_ID).resolve("dimension");
try {
deleteDirectory(dimensionDir);
Files.createDirectories(dimensionDir);
Files.writeString(datapackRoot.resolve("pack.mcmeta"), """
{
"pack": {
"description": "My Dimension dynamic private mind dimensions",
"pack_format": 15
}
}
""", StandardCharsets.UTF_8);
for (int slot = BUILT_IN_PLAYER_SLOTS; slot < slotsNeeded; slot++) {
writeSlotDimensions(dimensionDir, slot);
}
} catch (IOException exception) {
MyDimension.LOGGER.warn("Failed to write dynamic player mind dimension datapack", exception);
}
}
private static void writeSlotDimensions(Path dimensionDir, int slot) throws IOException {
Files.createDirectories(dimensionDir);
Files.writeString(dimensionDir.resolve("p" + slot + "e.json"), etherealMindJson(), StandardCharsets.UTF_8);
Files.writeString(dimensionDir.resolve("p" + slot + "m.json"), mirrorMindJson(), StandardCharsets.UTF_8);
Files.writeString(dimensionDir.resolve("p" + slot + "w.json"), waterMindJson(), StandardCharsets.UTF_8);
Files.writeString(dimensionDir.resolve("p" + slot + "n.json"), natureMindJson(), StandardCharsets.UTF_8);
Files.writeString(dimensionDir.resolve("p" + slot + "s.json"), soaringMindJson(), StandardCharsets.UTF_8);
}
private static void deleteDirectory(Path directory) throws IOException {
if (!Files.exists(directory)) {
return;
}
try (var paths = Files.walk(directory)) {
for (Path path : paths.sorted(Comparator.reverseOrder()).toList()) {
Files.deleteIfExists(path);
}
}
}
private static String etherealMindJson() {
return """
{
"type": "mydimension:ethereal_mind",
"generator": {
"type": "minecraft:flat",
"settings": {
"biome": "mydimension:ethereal_mind",
"features": false,
"lakes": false,
"layers": [
{ "block": "minecraft:stone", "height": 60 },
{ "block": "minecraft:dirt", "height": 3 },
{ "block": "minecraft:quartz_block", "height": 3 }
],
"structure_overrides": []
}
}
}
""";
}
private static String mirrorMindJson() {
return """
{
"type": "mydimension:mirror_mind",
"generator": {
"type": "mydimension:no_structure_noise",
"biome_source": {
"type": "minecraft:multi_noise",
"preset": "minecraft:overworld"
},
"settings": "minecraft:overworld"
}
}
""";
}
private static String waterMindJson() {
return """
{
"type": "mydimension:water_mind",
"generator": {
"type": "minecraft:flat",
"settings": {
"biome": "mydimension:water_mind",
"features": false,
"lakes": false,
"layers": [
{ "block": "minecraft:stone", "height": 20 },
{ "block": "minecraft:gravel", "height": 5 },
{ "block": "minecraft:water", "height": 50 }
],
"structure_overrides": []
}
}
}
""";
}
private static String natureMindJson() {
return """
{
"type": "mydimension:nature_mind",
"generator": {
"type": "minecraft:flat",
"settings": {
"biome": "mydimension:nature_mind",
"features": true,
"lakes": false,
"layers": [
{ "block": "minecraft:stone", "height": 50 },
{ "block": "minecraft:dirt", "height": 9 },
{ "block": "minecraft:grass_block", "height": 1 }
],
"structure_overrides": []
}
}
}
""";
}
private static String soaringMindJson() {
return """
{
"type": "mydimension:soaring_mind",
"generator": {
"type": "mydimension:soaring_islands",
"biome_source": {
"type": "minecraft:checkerboard",
"biomes": [
"minecraft:plains",
"minecraft:forest",
"minecraft:flower_forest",
"minecraft:birch_forest",
"minecraft:meadow",
"minecraft:cherry_grove",
"minecraft:snowy_plains",
"minecraft:grove",
"minecraft:desert",
"minecraft:savanna",
"minecraft:jungle",
"minecraft:windswept_hills"
],
"scale": 3
}
}
}
""";
}
}
package com.xfestudio.mydimension.world;
import com.xfestudio.mydimension.MyDimension;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.resources.ResourceKey;
import net.minecraft.server.MinecraftServer;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.saveddata.SavedData;
import net.minecraft.world.level.storage.LevelResource;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
public class MindInstances {
public static final int MAX_PLAYER_SLOTS = 64;
public static final int BUILT_IN_PLAYER_SLOTS = 2;
private static final String DATA_NAME = "mydimension_mind_instances";
private static final String NEXT_SLOT_TAG = "NextSlot";
private static final String REQUESTED_SLOTS_TAG = "RequestedSlots";
private static final String SLOTS_TAG = "Slots";
private static final String GENERATED_DATAPACK_NAME = "mydimension_dynamic_player_minds";
public static ResourceKey<Level> dimensionFor(ServerPlayer player, ResourceKey<Level> baseDimension) {
if (!PrivateMindFeature.isEnabled()) {
return baseDimension;
}
int slot = slotFor(player);
if (slot < 0 || slot >= MAX_PLAYER_SLOTS) {
return baseDimension;
}
MinecraftServer server = player.getServer();
ResourceKey<Level> privateDimension = ModDimensions.playerDimension(baseDimension, slot);
if (server.getLevel(privateDimension) != null) {
return privateDimension;
}
data(server).requestSlots(server, slot + 1);
return baseDimension;
}
public static ResourceKey<Level> dimensionForOwner(MinecraftServer server, UUID owner, ResourceKey<Level> baseDimension) {
if (!PrivateMindFeature.isEnabled()) {
return baseDimension;
}
int slot = slotFor(server, owner);
if (slot < 0 || slot >= MAX_PLAYER_SLOTS) {
return null;
}
return ModDimensions.playerDimension(baseDimension, slot);
}
public static int slotFor(ServerPlayer player) {
if (!PrivateMindFeature.isEnabled()) {
return -1;
}
return slotFor(player.getServer(), player.getUUID());
}
public static int slotFor(MinecraftServer server, UUID owner) {
if (!PrivateMindFeature.isEnabled()) {
return -1;
}
MindInstanceData data = data(server);
int slot = data.slotFor(owner);
if (slot >= BUILT_IN_PLAYER_SLOTS) {
data.requestSlots(server, slot + 1);
}
return slot;
}
private static MindInstanceData data(MinecraftServer server) {
return server.overworld().getDataStorage().computeIfAbsent(MindInstanceData::load, MindInstanceData::new, DATA_NAME);
}
public static class MindInstanceData extends SavedData {
private final Map<UUID, Integer> slots = new HashMap<>();
private int nextSlot;
private int requestedSlots = BUILT_IN_PLAYER_SLOTS;
public static MindInstanceData load(CompoundTag tag) {
MindInstanceData data = new MindInstanceData();
data.nextSlot = tag.getInt(NEXT_SLOT_TAG);
data.requestedSlots = Math.max(BUILT_IN_PLAYER_SLOTS, tag.contains(REQUESTED_SLOTS_TAG) ? tag.getInt(REQUESTED_SLOTS_TAG) : data.nextSlot);
CompoundTag slotsTag = tag.getCompound(SLOTS_TAG);
for (String key : slotsTag.getAllKeys()) {
try {
data.slots.put(UUID.fromString(key), slotsTag.getInt(key));
} catch (IllegalArgumentException ignored) {
}
}
return data;
}
@Override
public CompoundTag save(CompoundTag tag) {
tag.putInt(NEXT_SLOT_TAG, nextSlot);
tag.putInt(REQUESTED_SLOTS_TAG, requestedSlots);
CompoundTag slotsTag = new CompoundTag();
for (Map.Entry<UUID, Integer> entry : slots.entrySet()) {
slotsTag.putInt(entry.getKey().toString(), entry.getValue());
}
tag.put(SLOTS_TAG, slotsTag);
return tag;
}
private int slotFor(UUID owner) {
Integer existing = slots.get(owner);
if (existing != null) {
return existing;
}
if (nextSlot >= MAX_PLAYER_SLOTS) {
return -1;
}
int slot = nextSlot++;
slots.put(owner, slot);
setDirty();
return slot;
}
private void requestSlots(MinecraftServer server, int slotsNeeded) {
int clampedSlots = Math.min(Math.max(slotsNeeded, BUILT_IN_PLAYER_SLOTS), MAX_PLAYER_SLOTS);
if (clampedSlots > requestedSlots) {
requestedSlots = clampedSlots;
setDirty();
}
if (clampedSlots > BUILT_IN_PLAYER_SLOTS) {
writeGeneratedDatapack(server, clampedSlots);
}
}
}
private static void writeGeneratedDatapack(MinecraftServer server, int slotsNeeded) {
Path datapackRoot = server.getWorldPath(LevelResource.DATAPACK_DIR).resolve(GENERATED_DATAPACK_NAME);
Path dimensionDir = datapackRoot.resolve("data").resolve(MyDimension.MOD_ID).resolve("dimension");
try {
deleteDirectory(dimensionDir);
Files.createDirectories(dimensionDir);
Files.writeString(datapackRoot.resolve("pack.mcmeta"), """
{
"pack": {
"description": "My Dimension dynamic private mind dimensions",
"pack_format": 15
}
}
""", StandardCharsets.UTF_8);
for (int slot = BUILT_IN_PLAYER_SLOTS; slot < slotsNeeded; slot++) {
writeSlotDimensions(dimensionDir, slot);
}
} catch (IOException exception) {
MyDimension.LOGGER.warn("Failed to write dynamic player mind dimension datapack", exception);
}
}
private static void writeSlotDimensions(Path dimensionDir, int slot) throws IOException {
Files.createDirectories(dimensionDir);
Files.writeString(dimensionDir.resolve("p" + slot + "e.json"), etherealMindJson(), StandardCharsets.UTF_8);
Files.writeString(dimensionDir.resolve("p" + slot + "m.json"), mirrorMindJson(), StandardCharsets.UTF_8);
Files.writeString(dimensionDir.resolve("p" + slot + "w.json"), waterMindJson(), StandardCharsets.UTF_8);
Files.writeString(dimensionDir.resolve("p" + slot + "n.json"), natureMindJson(), StandardCharsets.UTF_8);
Files.writeString(dimensionDir.resolve("p" + slot + "s.json"), soaringMindJson(), StandardCharsets.UTF_8);
}
private static void deleteDirectory(Path directory) throws IOException {
if (!Files.exists(directory)) {
return;
}
try (var paths = Files.walk(directory)) {
for (Path path : paths.sorted(Comparator.reverseOrder()).toList()) {
Files.deleteIfExists(path);
}
}
}
private static String etherealMindJson() {
return """
{
"type": "mydimension:ethereal_mind",
"generator": {
"type": "minecraft:flat",
"settings": {
"biome": "mydimension:ethereal_mind",
"features": false,
"lakes": false,
"layers": [
{ "block": "minecraft:stone", "height": 60 },
{ "block": "minecraft:dirt", "height": 3 },
{ "block": "minecraft:quartz_block", "height": 3 }
],
"structure_overrides": []
}
}
}
""";
}
private static String mirrorMindJson() {
return """
{
"type": "mydimension:mirror_mind",
"generator": {
"type": "mydimension:no_structure_noise",
"biome_source": {
"type": "minecraft:multi_noise",
"preset": "minecraft:overworld"
},
"settings": "minecraft:overworld"
}
}
""";
}
private static String waterMindJson() {
return """
{
"type": "mydimension:water_mind",
"generator": {
"type": "minecraft:flat",
"settings": {
"biome": "mydimension:water_mind",
"features": false,
"lakes": false,
"layers": [
{ "block": "minecraft:stone", "height": 20 },
{ "block": "minecraft:gravel", "height": 5 },
{ "block": "minecraft:water", "height": 50 }
],
"structure_overrides": []
}
}
}
""";
}
private static String natureMindJson() {
return """
{
"type": "mydimension:nature_mind",
"generator": {
"type": "minecraft:flat",
"settings": {
"biome": "mydimension:nature_mind",
"features": true,
"lakes": false,
"layers": [
{ "block": "minecraft:stone", "height": 50 },
{ "block": "minecraft:dirt", "height": 9 },
{ "block": "minecraft:grass_block", "height": 1 }
],
"structure_overrides": []
}
}
}
""";
}
private static String soaringMindJson() {
return """
{
"type": "mydimension:soaring_mind",
"generator": {
"type": "mydimension:soaring_islands",
"biome_source": {
"type": "minecraft:checkerboard",
"biomes": [
"minecraft:plains",
"minecraft:forest",
"minecraft:flower_forest",
"minecraft:birch_forest",
"minecraft:meadow",
"minecraft:cherry_grove",
"minecraft:snowy_plains",
"minecraft:grove",
"minecraft:desert",
"minecraft:savanna",
"minecraft:jungle",
"minecraft:windswept_hills"
],
"scale": 3
}
}
}
""";
}
}