mirror of
https://github.com/VolmitSoftware/Iris.git
synced 2026-07-23 15:20:53 +00:00
dwa
This commit is contained in:
@@ -38,6 +38,7 @@ import art.arcane.iris.core.runtime.TransientWorldCleanupSupport;
|
||||
import art.arcane.iris.core.runtime.WorldRuntimeControlService;
|
||||
import art.arcane.iris.core.lifecycle.WorldLifecycleStaging;
|
||||
import art.arcane.iris.core.link.IrisPapiExpansion;
|
||||
import art.arcane.iris.core.localization.IrisLanguage;
|
||||
import art.arcane.iris.core.link.MultiverseCoreLink;
|
||||
import art.arcane.iris.core.loader.IrisData;
|
||||
import art.arcane.iris.core.nms.INMS;
|
||||
@@ -606,6 +607,7 @@ public class Iris extends VolmitPlugin implements Listener, ReloadAware {
|
||||
|
||||
private void enable() {
|
||||
alreadyDrained.set(false);
|
||||
IrisLanguage.initialize();
|
||||
PaperLibBootstrap.install();
|
||||
SimdSupport.install();
|
||||
services = new KMap<>();
|
||||
@@ -1110,9 +1112,11 @@ public class Iris extends VolmitPlugin implements Listener, ReloadAware {
|
||||
configHotloadEngine.processFileChange(file, ignored -> {
|
||||
IrisSettings.invalidate();
|
||||
IrisSettings.get();
|
||||
IrisLanguage.reload();
|
||||
return true;
|
||||
}, ignored -> Iris.info("Hotloaded settings.json "));
|
||||
}
|
||||
IrisLanguage.update();
|
||||
}
|
||||
|
||||
private static boolean isSettingsFile(File file) {
|
||||
|
||||
+15
-12
@@ -29,42 +29,45 @@ import art.arcane.volmlib.util.director.annotations.Param;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Director(name = "datapack", aliases = {"datapacks", "dp"}, description = "Download & manage external datapack imports (Modrinth)")
|
||||
import art.arcane.iris.core.localization.IrisLanguage;
|
||||
import art.arcane.iris.core.localization.BukkitCommandMessages;
|
||||
import art.arcane.volmlib.util.localization.MessageArgument;
|
||||
@Director(name = "datapack", aliases = {"datapacks", "dp"}, description = "Download & manage external datapack imports (Modrinth)", descriptionKey = "iris.director.commanddatapack.director.download_manage_external_datapack_imports_modrinth")
|
||||
public class CommandDatapack implements DirectorExecutor {
|
||||
@Director(description = "Download/update every datapack listed in a pack dimension's 'datapackImports' and install it into the world so its structures register like vanilla", aliases = {"pull"})
|
||||
@Director(description = "Download/update every datapack listed in a pack dimension's 'datapackImports' and install it into the world so its structures register like vanilla", descriptionKey = "iris.director.commanddatapack.director.download_update_every_datapack_listed_pack_dimension_s_datapackimports_install_it_into", aliases = {"pull"})
|
||||
public void ingest(
|
||||
@Param(description = "Restart the server when new datapacks are installed (required for new structures to register and generate)", defaultValue = "false")
|
||||
@Param(description = "Restart the server when new datapacks are installed (required for new structures to register and generate)", descriptionKey = "iris.director.commanddatapack.param.restart_server_when_new_datapacks_are_installed_required_new_structures_register_generate", defaultValue = "false")
|
||||
boolean restart
|
||||
) {
|
||||
VolmitSender sender = sender();
|
||||
sender.sendMessage(C.GRAY + "Starting datapack ingest...");
|
||||
sender.sendMessage(IrisLanguage.text(BukkitCommandMessages.COMMAND_DATAPACK_STARTING_DATAPACK_INGEST));
|
||||
J.a(() -> DatapackIngestService.ingestAll(sender, restart));
|
||||
}
|
||||
|
||||
@Director(description = "List configured datapack imports and their installed versions", aliases = {"ls"})
|
||||
@Director(description = "List configured datapack imports and their installed versions", descriptionKey = "iris.director.commanddatapack.director.list_configured_datapack_imports_their_installed_versions", aliases = {"ls"})
|
||||
public void list() {
|
||||
VolmitSender sender = sender();
|
||||
KList<String> configured = DatapackIngestService.collectConfiguredImports();
|
||||
List<DatapackIngestService.Entry> installed = DatapackIngestService.installed();
|
||||
|
||||
sender.sendMessage(C.GREEN + "Configured datapack imports: " + C.WHITE + configured.size());
|
||||
sender.sendMessage(IrisLanguage.text(BukkitCommandMessages.COMMAND_DATAPACK_CONFIGURED_DATAPACK_IMPORTS, MessageArgument.untrusted("value", configured.size())));
|
||||
for (String url : configured) {
|
||||
sender.sendMessage(C.GRAY + " - " + C.WHITE + url);
|
||||
sender.sendMessage(IrisLanguage.text(BukkitCommandMessages.COMMAND_DATAPACK_MESSAGE, MessageArgument.untrusted("url", url)));
|
||||
}
|
||||
|
||||
sender.sendMessage(C.GREEN + "Installed datapacks: " + C.WHITE + installed.size());
|
||||
sender.sendMessage(IrisLanguage.text(BukkitCommandMessages.COMMAND_DATAPACK_INSTALLED_DATAPACKS, MessageArgument.untrusted("value", installed.size())));
|
||||
for (DatapackIngestService.Entry entry : installed) {
|
||||
sender.sendMessage(C.GRAY + " - " + C.WHITE + entry.id + C.GRAY + " " + (entry.versionNumber == null ? "?" : entry.versionNumber));
|
||||
sender.sendMessage(IrisLanguage.text(BukkitCommandMessages.COMMAND_DATAPACK_MESSAGE_2, MessageArgument.untrusted("value", entry.id), MessageArgument.untrusted("value2", (entry.versionNumber == null ? "?" : entry.versionNumber))));
|
||||
}
|
||||
|
||||
if (configured.isEmpty()) {
|
||||
sender.sendMessage(C.YELLOW + "Add Modrinth URLs to a dimension's 'datapackImports' list, then run /iris datapack ingest.");
|
||||
sender.sendMessage(IrisLanguage.text(BukkitCommandMessages.COMMAND_DATAPACK_ADD_MODRINTH_URLS_DIMENSION_S_DATAPACKIMPORTS_LIST_THEN_RUN_IRIS));
|
||||
}
|
||||
}
|
||||
|
||||
@Director(description = "Remove an installed datapack by id (also delete its URL from datapackImports to keep it gone)", aliases = {"rm"})
|
||||
@Director(description = "Remove an installed datapack by id (also delete its URL from datapackImports to keep it gone)", descriptionKey = "iris.director.commanddatapack.director.remove_installed_datapack_by_id_also_delete_its_url_from_datapackimports_keep", aliases = {"rm"})
|
||||
public void remove(
|
||||
@Param(description = "The datapack id (folder name) shown by /iris datapack list")
|
||||
@Param(description = "The datapack id (folder name) shown by /iris datapack list", descriptionKey = "iris.director.commanddatapack.param.datapack_id_folder_name_shown_by_iris_datapack_list")
|
||||
String id
|
||||
) {
|
||||
DatapackIngestService.remove(sender(), id);
|
||||
|
||||
+66
-75
@@ -64,15 +64,20 @@ import java.util.Enumeration;
|
||||
import java.util.Map;
|
||||
import java.util.TreeMap;
|
||||
|
||||
@Director(name = "Developer", origin = DirectorOrigin.BOTH, description = "Iris World Manager", aliases = {"dev"})
|
||||
import art.arcane.iris.core.localization.IrisLanguage;
|
||||
import art.arcane.iris.core.localization.BukkitCommandMessages;
|
||||
import art.arcane.volmlib.util.localization.MessageArgument;
|
||||
import art.arcane.iris.core.localization.BukkitCommandMessagesExtended;
|
||||
import art.arcane.iris.core.localization.BukkitRuntimeMessages;
|
||||
@Director(name = "Developer", origin = DirectorOrigin.BOTH, description = "Iris World Manager", descriptionKey = "iris.director.commanddeveloper.director.iris_world_manager", aliases = {"dev"})
|
||||
public class CommandDeveloper implements DirectorExecutor {
|
||||
@Director(description = "Get Loaded TectonicPlates Count", origin = DirectorOrigin.BOTH, sync = true)
|
||||
@Director(description = "Get Loaded TectonicPlates Count", descriptionKey = "iris.director.commanddeveloper.director.get_loaded_tectonicplates_count", origin = DirectorOrigin.BOTH, sync = true)
|
||||
public void EngineStatus() {
|
||||
Iris.service(IrisEngineSVC.class)
|
||||
.engineStatus(sender());
|
||||
}
|
||||
|
||||
@Director(description = "Send a test exception to sentry")
|
||||
@Director(description = "Send a test exception to sentry", descriptionKey = "iris.director.commanddeveloper.director.send_test_exception_sentry")
|
||||
public void Sentry() {
|
||||
Engine engine = engine();
|
||||
Exception testException = new Exception("This is a test");
|
||||
@@ -85,23 +90,23 @@ public class CommandDeveloper implements DirectorExecutor {
|
||||
}
|
||||
}
|
||||
|
||||
@Director(description = "Hash generated block output of a fixed area for determinism/identity testing", origin = DirectorOrigin.BOTH)
|
||||
@Director(description = "Hash generated block output of a fixed area for determinism/identity testing", descriptionKey = "iris.director.commanddeveloper.director.hash_generated_block_output_fixed_area_determinism_identity_testing", origin = DirectorOrigin.BOTH)
|
||||
public void genhash(
|
||||
@Param(description = "The world to hash", contextual = true)
|
||||
@Param(description = "The world to hash", descriptionKey = "iris.director.commanddeveloper.param.world_hash", contextual = true)
|
||||
World world,
|
||||
@Param(description = "Radius in chunks around the center", defaultValue = "4")
|
||||
@Param(description = "Radius in chunks around the center", descriptionKey = "iris.director.commanddeveloper.param.radius_chunks_around_center", defaultValue = "4")
|
||||
int radius,
|
||||
@Param(description = "Center chunk X", defaultValue = "0")
|
||||
@Param(description = "Center chunk X", descriptionKey = "iris.director.commanddeveloper.param.center_chunk_x", defaultValue = "0")
|
||||
int centerX,
|
||||
@Param(description = "Center chunk Z", defaultValue = "0")
|
||||
@Param(description = "Center chunk Z", descriptionKey = "iris.director.commanddeveloper.param.center_chunk_z", defaultValue = "0")
|
||||
int centerZ) {
|
||||
if (world == null) {
|
||||
sender().sendMessage(C.RED + "World is null.");
|
||||
sender().sendMessage(IrisLanguage.text(BukkitCommandMessagesExtended.COMMAND_DEVELOPER_WORLD_IS_NULL));
|
||||
return;
|
||||
}
|
||||
|
||||
VolmitSender sender = sender();
|
||||
sender.sendMessage(C.GREEN + "genhash started: " + ((radius * 2 + 1) * (radius * 2 + 1)) + " chunks...");
|
||||
sender.sendMessage(IrisLanguage.text(BukkitCommandMessages.COMMAND_DEVELOPER_GENHASH_STARTED_CHUNKS, MessageArgument.untrusted("value", ((radius * 2 + 1) * (radius * 2 + 1)))));
|
||||
J.a(() -> runGenhash(sender, world, radius, centerX, centerZ));
|
||||
}
|
||||
|
||||
@@ -122,7 +127,7 @@ public class CommandDeveloper implements DirectorExecutor {
|
||||
snapshot = loaded.getChunkSnapshot(false, false, false);
|
||||
} catch (Throwable e) {
|
||||
Iris.reportError(e);
|
||||
sender.sendMessage(C.RED + "genhash failed at chunk " + rx + "," + rz + ": " + e.getMessage());
|
||||
sender.sendMessage(IrisLanguage.text(BukkitCommandMessages.COMMAND_DEVELOPER_GENHASH_FAILED_AT_CHUNK, MessageArgument.untrusted("rx", rx), MessageArgument.untrusted("rz", rz), MessageArgument.untrusted("value", String.valueOf(e.getMessage()))));
|
||||
return;
|
||||
}
|
||||
long chunkHash = 0L;
|
||||
@@ -172,9 +177,7 @@ public class CommandDeveloper implements DirectorExecutor {
|
||||
Iris.reportError(e);
|
||||
}
|
||||
|
||||
sender.sendMessage(C.GREEN + "genhash global=" + C.GOLD + Long.toHexString(globalHash)
|
||||
+ C.GREEN + " chunks=" + (side * side) + " solid=" + solidBlocks
|
||||
+ " in " + Form.duration((long) (M.ms() - startMs), 1));
|
||||
sender.sendMessage(IrisLanguage.text(BukkitCommandMessages.COMMAND_DEVELOPER_GENHASH_GLOBAL_CHUNKS_SOLID, MessageArgument.untrusted("value", Long.toHexString(globalHash)), MessageArgument.untrusted("value2", (side * side)), MessageArgument.untrusted("solidBlocks", solidBlocks), MessageArgument.untrusted("value3", Form.duration((long) (M.ms() - startMs), 1))));
|
||||
Iris.info("genhash world=" + world.getName() + " global=" + Long.toHexString(globalHash)
|
||||
+ " chunks=" + (side * side) + " solidBlocks=" + solidBlocks + " -> " + out.getAbsolutePath());
|
||||
}
|
||||
@@ -185,29 +188,23 @@ public class CommandDeveloper implements DirectorExecutor {
|
||||
return z ^ (z >>> 31);
|
||||
}
|
||||
|
||||
@Director(description = "Update the pack of a world (UNSAFE!)", name = "update-world", aliases = "^world")
|
||||
@Director(description = "Update the pack of a world (UNSAFE!)", descriptionKey = "iris.director.commanddeveloper.director.update_pack_world_unsafe", name = "update-world", aliases = "^world")
|
||||
public void updateWorld(
|
||||
@Param(description = "The world to update", contextual = true)
|
||||
@Param(description = "The world to update", descriptionKey = "iris.director.commanddeveloper.param.world_update", contextual = true)
|
||||
World world,
|
||||
@Param(description = "The pack to install into the world", contextual = true, aliases = "dimension")
|
||||
@Param(description = "The pack to install into the world", descriptionKey = "iris.director.commanddeveloper.param.pack_install_into_world", contextual = true, aliases = "dimension")
|
||||
IrisDimension pack,
|
||||
@Param(description = "Make sure to make a backup & read the warnings first!", defaultValue = "false", aliases = "c")
|
||||
@Param(description = "Make sure to make a backup & read the warnings first!", descriptionKey = "iris.director.commanddeveloper.param.make_sure_make_backup_read_warnings_first", defaultValue = "false", aliases = "c")
|
||||
boolean confirm,
|
||||
@Param(description = "Should Iris download the pack again for you", defaultValue = "false", name = "fresh-download", aliases = {"fresh", "new"})
|
||||
@Param(description = "Should Iris download the pack again for you", descriptionKey = "iris.director.commanddeveloper.param.should_iris_download_pack_again_you", defaultValue = "false", name = "fresh-download", aliases = {"fresh", "new"})
|
||||
boolean freshDownload
|
||||
) {
|
||||
if (!confirm) {
|
||||
sender().sendMessage(new String[]{
|
||||
C.RED + "You should always make a backup before using this",
|
||||
C.YELLOW + "Issues caused by this can be, but are not limited to:",
|
||||
C.YELLOW + " - Broken chunks (cut-offs) between old and new chunks (before & after the update)",
|
||||
C.YELLOW + " - Regenerated chunks that do not fit in with the old chunks",
|
||||
C.YELLOW + " - Structures not spawning again when regenerating",
|
||||
C.YELLOW + " - Caves not lining up",
|
||||
C.YELLOW + " - Terrain layers not lining up",
|
||||
C.RED + "Now that you are aware of the risks, and have made a back-up:",
|
||||
C.RED + "/iris developer update-world " + world.getName() + " " + pack.getLoadKey() + " confirm=true"
|
||||
});
|
||||
sender().sendMessage(IrisLanguage.text(
|
||||
BukkitRuntimeMessages.COMMAND_DEVELOPER_UPDATE_WORLD_WARNING,
|
||||
MessageArgument.untrusted("world", world.getName()),
|
||||
MessageArgument.untrusted("pack", pack.getLoadKey())
|
||||
));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -221,16 +218,16 @@ public class CommandDeveloper implements DirectorExecutor {
|
||||
Iris.service(StudioSVC.class).installIntoWorld(sender(), pack, folder);
|
||||
}
|
||||
|
||||
@Director(description = "Test")
|
||||
@Director(description = "Test", descriptionKey = "iris.director.commanddeveloper.director.test")
|
||||
public void mantle(
|
||||
@Param(name = "plate", description = "Dump the whole tectonic plate instead of a single section", defaultValue = "false")
|
||||
@Param(name = "plate", description = "Dump the whole tectonic plate instead of a single section", descriptionKey = "iris.director.commanddeveloper.param.dump_whole_tectonic_plate_instead_single_section", defaultValue = "false")
|
||||
boolean plate,
|
||||
@Param(name = "name", description = "The dump file id under plugins/Iris/dump (pv.<id>.*)", defaultValue = "21474836474")
|
||||
@Param(name = "name", description = "The dump file id under plugins/Iris/dump (pv.<id>.*)", descriptionKey = "iris.director.commanddeveloper.param.dump_file_id_under_plugins_iris_dump_pv_id", defaultValue = "21474836474")
|
||||
String name
|
||||
) throws Throwable {
|
||||
Engine activeEngine = engine();
|
||||
if (activeEngine == null) {
|
||||
sender().sendMessage(C.RED + "Target an Iris world before reading a mantle dump.");
|
||||
sender().sendMessage(IrisLanguage.text(BukkitCommandMessagesExtended.COMMAND_DEVELOPER_TARGET_IRIS_WORLD_BEFORE_READING_MANTLE_DUMP));
|
||||
return;
|
||||
}
|
||||
File base = Iris.instance.getDataFile("dump", "pv." + name + ".ttp.lz4b.bin");
|
||||
@@ -252,29 +249,29 @@ public class CommandDeveloper implements DirectorExecutor {
|
||||
}
|
||||
}
|
||||
|
||||
@Director(description = "Test")
|
||||
@Director(description = "Test", descriptionKey = "iris.director.commanddeveloper.director.test_2")
|
||||
public void packBenchmark(
|
||||
@Param(description = "The pack to bench", aliases = {"pack"}, defaultValue = "overworld")
|
||||
@Param(description = "The pack to bench", descriptionKey = "iris.director.commanddeveloper.param.pack_bench", aliases = {"pack"}, defaultValue = "overworld")
|
||||
IrisDimension dimension,
|
||||
@Param(description = "Radius in regions", defaultValue = "2048")
|
||||
@Param(description = "Radius in regions", descriptionKey = "iris.director.commanddeveloper.param.radius_regions", defaultValue = "2048")
|
||||
int radius,
|
||||
@Param(description = "Open GUI while benchmarking", defaultValue = "false")
|
||||
@Param(description = "Open GUI while benchmarking", descriptionKey = "iris.director.commanddeveloper.param.open_gui_while_benchmarking", defaultValue = "false")
|
||||
boolean gui
|
||||
) {
|
||||
new IrisPackBenchmarking(dimension, radius, gui);
|
||||
}
|
||||
|
||||
@Director(description = "Upgrade to another Minecraft version")
|
||||
@Director(description = "Upgrade to another Minecraft version", descriptionKey = "iris.director.commanddeveloper.director.upgrade_another_minecraft_version")
|
||||
public void upgrade(
|
||||
@Param(description = "The version to upgrade to", defaultValue = "latest") DataVersion version) {
|
||||
sender().sendMessage(C.GREEN + "Upgrading to " + version.getVersion() + "...");
|
||||
@Param(description = "The version to upgrade to", descriptionKey = "iris.director.commanddeveloper.param.version_upgrade", defaultValue = "latest") DataVersion version) {
|
||||
sender().sendMessage(IrisLanguage.text(BukkitCommandMessagesExtended.COMMAND_DEVELOPER_UPGRADING, MessageArgument.untrusted("value", version.getVersion())));
|
||||
ServerConfigurator.installDataPacks(version.get(), false);
|
||||
sender().sendMessage(C.GREEN + "Done upgrading! You can now update your server version to " + version.getVersion());
|
||||
sender().sendMessage(IrisLanguage.text(BukkitCommandMessagesExtended.COMMAND_DEVELOPER_DONE_UPGRADING_YOU_CAN_NOW_UPDATE_YOUR_SERVER_VERSION, MessageArgument.untrusted("value", version.getVersion())));
|
||||
}
|
||||
|
||||
@Director(description = "test")
|
||||
@Director(description = "test", descriptionKey = "iris.director.commanddeveloper.director.test_3")
|
||||
public void mca (
|
||||
@Param(description = "The world folder to scan for .mca region files") String world) {
|
||||
@Param(description = "The world folder to scan for .mca region files", descriptionKey = "iris.director.commanddeveloper.param.world_folder_scan_mca_region_files") String world) {
|
||||
try {
|
||||
File[] McaFiles = new File(world, "region").listFiles((dir, name) -> name.endsWith(".mca"));
|
||||
for (File mca : McaFiles) {
|
||||
@@ -286,25 +283,25 @@ public class CommandDeveloper implements DirectorExecutor {
|
||||
|
||||
}
|
||||
|
||||
@Director(description = "Delete nearby chunk blocks for regen testing", name = "delete-chunk", aliases = {"dc"}, origin = DirectorOrigin.PLAYER, sync = true)
|
||||
@Director(description = "Delete nearby chunk blocks for regen testing", descriptionKey = "iris.director.commanddeveloper.director.delete_nearby_chunk_blocks_regen_testing", name = "delete-chunk", aliases = {"dc"}, origin = DirectorOrigin.PLAYER, sync = true)
|
||||
public void deleteChunk(
|
||||
@Param(description = "Radius in chunks around your current chunk", defaultValue = "0")
|
||||
@Param(description = "Radius in chunks around your current chunk", descriptionKey = "iris.director.commanddeveloper.param.radius_chunks_around_your_current_chunk", defaultValue = "0")
|
||||
int radius
|
||||
) {
|
||||
if (radius < 0) {
|
||||
sender().sendMessage(C.RED + "Radius must be 0 or greater.");
|
||||
sender().sendMessage(IrisLanguage.text(BukkitCommandMessagesExtended.COMMAND_DEVELOPER_RADIUS_MUST_BE_0_GREATER));
|
||||
return;
|
||||
}
|
||||
|
||||
World world = player().getWorld();
|
||||
if (!IrisToolbelt.isIrisWorld(world)) {
|
||||
sender().sendMessage(C.RED + "This is not an Iris world.");
|
||||
sender().sendMessage(IrisLanguage.text(BukkitCommandMessagesExtended.COMMAND_DEVELOPER_THIS_IS_NOT_IRIS_WORLD));
|
||||
return;
|
||||
}
|
||||
|
||||
PlatformChunkGenerator access = IrisToolbelt.access(world);
|
||||
if (access == null || access.getEngine() == null) {
|
||||
sender().sendMessage(C.RED + "The engine access for this world is null.");
|
||||
sender().sendMessage(IrisLanguage.text(BukkitCommandMessagesExtended.COMMAND_DEVELOPER_ENGINE_ACCESS_THIS_WORLD_IS_NULL));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -312,14 +309,12 @@ public class CommandDeveloper implements DirectorExecutor {
|
||||
int centerZ = player().getLocation().getBlockZ() >> 4;
|
||||
int chunks = (radius * 2 + 1) * (radius * 2 + 1);
|
||||
|
||||
sender().sendMessage(C.GREEN + "Delete started: " + C.GOLD + chunks + C.GREEN
|
||||
+ " chunk(s) around " + C.GOLD + centerX + "," + centerZ + C.GREEN
|
||||
+ ". Clearing blocks to air.");
|
||||
sender().sendMessage(IrisLanguage.text(BukkitCommandMessagesExtended.COMMAND_DEVELOPER_DELETE_STARTED_CHUNK_S_AROUND_CLEARING_BLOCKS_AIR, MessageArgument.untrusted("chunks", chunks), MessageArgument.untrusted("centerX", centerX), MessageArgument.untrusted("centerZ", centerZ)));
|
||||
|
||||
new ChunkClearer(world, access.getEngine(), sender(), centerX, centerZ, radius).start();
|
||||
}
|
||||
|
||||
@Director(description = "Test", aliases = {"ip"})
|
||||
@Director(description = "Test", descriptionKey = "iris.director.commanddeveloper.director.test_4", aliases = {"ip"})
|
||||
public void network() {
|
||||
try {
|
||||
Enumeration<NetworkInterface> networkInterfaces = NetworkInterface.getNetworkInterfaces();
|
||||
@@ -337,25 +332,25 @@ public class CommandDeveloper implements DirectorExecutor {
|
||||
|
||||
// --- Regen ---
|
||||
|
||||
@Director(name = "regen", aliases = {"rg"}, description = "Delete and regenerate nearby chunks in place using Iris generation", origin = DirectorOrigin.PLAYER, sync = true)
|
||||
@Director(name = "regen", aliases = {"rg"}, description = "Delete and regenerate nearby chunks in place using Iris generation", descriptionKey = "iris.director.commanddeveloper.director.delete_regenerate_nearby_chunks_place_using_iris_generation", origin = DirectorOrigin.PLAYER, sync = true)
|
||||
public void regen(
|
||||
@Param(name = "radius", description = "The radius of nearby chunks", defaultValue = "5")
|
||||
@Param(name = "radius", description = "The radius of nearby chunks", descriptionKey = "iris.director.commanddeveloper.param.radius_nearby_chunks", defaultValue = "5")
|
||||
int radius
|
||||
) {
|
||||
if (radius < 0) {
|
||||
sender().sendMessage(C.RED + "Radius must be 0 or greater.");
|
||||
sender().sendMessage(IrisLanguage.text(BukkitCommandMessagesExtended.COMMAND_DEVELOPER_RADIUS_MUST_BE_0_GREATER_2));
|
||||
return;
|
||||
}
|
||||
|
||||
World world = player().getWorld();
|
||||
if (!IrisToolbelt.isIrisWorld(world)) {
|
||||
sender().sendMessage(C.RED + "You must be in an Iris world to use regen.");
|
||||
sender().sendMessage(IrisLanguage.text(BukkitCommandMessagesExtended.COMMAND_DEVELOPER_YOU_MUST_BE_IRIS_WORLD_USE_REGEN));
|
||||
return;
|
||||
}
|
||||
|
||||
Engine engine = IrisToolbelt.access(world).getEngine();
|
||||
if (engine == null) {
|
||||
sender().sendMessage(C.RED + "The engine access for this world is null. Generate nearby chunks first.");
|
||||
sender().sendMessage(IrisLanguage.text(BukkitCommandMessagesExtended.COMMAND_DEVELOPER_ENGINE_ACCESS_THIS_WORLD_IS_NULL_GENERATE_NEARBY_CHUNKS_FIRST));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -363,9 +358,7 @@ public class CommandDeveloper implements DirectorExecutor {
|
||||
int centerZ = player().getLocation().getBlockZ() >> 4;
|
||||
int chunks = (radius * 2 + 1) * (radius * 2 + 1);
|
||||
|
||||
sender().sendMessage(C.GREEN + "Regen started: " + C.GOLD + chunks + C.GREEN
|
||||
+ " chunk(s) around " + C.GOLD + centerX + "," + centerZ + C.GREEN
|
||||
+ ". Deleting and regenerating in place.");
|
||||
sender().sendMessage(IrisLanguage.text(BukkitCommandMessagesExtended.COMMAND_DEVELOPER_REGEN_STARTED_CHUNK_S_AROUND_DELETING_REGENERATING_PLACE, MessageArgument.untrusted("chunks", chunks), MessageArgument.untrusted("centerX", centerX), MessageArgument.untrusted("centerZ", centerZ)));
|
||||
Iris.info("Regen run start: world=" + world.getName()
|
||||
+ " center=" + centerX + "," + centerZ
|
||||
+ " radius=" + radius
|
||||
@@ -374,43 +367,41 @@ public class CommandDeveloper implements DirectorExecutor {
|
||||
new InPlaceChunkRegenerator(world, engine, sender(), centerX, centerZ, radius).start();
|
||||
}
|
||||
|
||||
@Director(name = "goldenhash", aliases = {"gold"}, description = "Generate chunks into buffers (no world writes) and hash blocks+biomes; captures a golden file or verifies against an existing one. Resets mantle in the scanned area - use on disposable test worlds.", origin = DirectorOrigin.BOTH)
|
||||
@Director(name = "goldenhash", aliases = {"gold"}, description = "Generate chunks into buffers (no world writes) and hash blocks+biomes; captures a golden file or verifies against an existing one. Resets mantle in the scanned area - use on disposable test worlds.", descriptionKey = "iris.director.commanddeveloper.director.generate_chunks_into_buffers_no_world_writes_hash_blocks_biomes_captures_golden", origin = DirectorOrigin.BOTH)
|
||||
public void goldenhash(
|
||||
@Param(description = "The world to scan", contextual = true)
|
||||
@Param(description = "The world to scan", descriptionKey = "iris.director.commanddeveloper.param.world_scan", contextual = true)
|
||||
World world,
|
||||
@Param(name = "radius", description = "Radius in chunks around the center", defaultValue = "8")
|
||||
@Param(name = "radius", description = "Radius in chunks around the center", descriptionKey = "iris.director.commanddeveloper.param.radius_chunks_around_center_2", defaultValue = "8")
|
||||
int radius,
|
||||
@Param(name = "center-x", description = "Center chunk X", defaultValue = "0")
|
||||
@Param(name = "center-x", description = "Center chunk X", descriptionKey = "iris.director.commanddeveloper.param.center_chunk_x_2", defaultValue = "0")
|
||||
int centerX,
|
||||
@Param(name = "center-z", description = "Center chunk Z", defaultValue = "0")
|
||||
@Param(name = "center-z", description = "Center chunk Z", descriptionKey = "iris.director.commanddeveloper.param.center_chunk_z_2", defaultValue = "0")
|
||||
int centerZ,
|
||||
@Param(name = "reset-mantle", description = "Delete mantle data in the scan area first for full regeneration from scratch", defaultValue = "true")
|
||||
@Param(name = "reset-mantle", description = "Delete mantle data in the scan area first for full regeneration from scratch", descriptionKey = "iris.director.commanddeveloper.param.delete_mantle_data_scan_area_first_full_regeneration_from_scratch", defaultValue = "true")
|
||||
boolean resetMantle,
|
||||
@Param(name = "threads", description = "Concurrent chunk generations; 1 = strictly serial for order-dependence testing", defaultValue = "8")
|
||||
@Param(name = "threads", description = "Concurrent chunk generations; 1 = strictly serial for order-dependence testing", descriptionKey = "iris.director.commanddeveloper.param.concurrent_chunk_generations_1_strictly_serial_order_dependence_testing", defaultValue = "8")
|
||||
int threads,
|
||||
@Param(name = "deep", description = "Also dump full per-chunk non-air blockstates for offline diffing", defaultValue = "false")
|
||||
@Param(name = "deep", description = "Also dump full per-chunk non-air blockstates for offline diffing", descriptionKey = "iris.director.commanddeveloper.param.also_dump_full_per_chunk_non_air_blockstates_offline_diffing", defaultValue = "false")
|
||||
boolean deep
|
||||
) {
|
||||
if (radius < 0) {
|
||||
sender().sendMessage(C.RED + "Radius must be 0 or greater.");
|
||||
sender().sendMessage(IrisLanguage.text(BukkitCommandMessagesExtended.COMMAND_DEVELOPER_RADIUS_MUST_BE_0_GREATER_3));
|
||||
return;
|
||||
}
|
||||
|
||||
if (world == null || !IrisToolbelt.isIrisWorld(world)) {
|
||||
sender().sendMessage(C.RED + "Target must be an Iris world.");
|
||||
sender().sendMessage(IrisLanguage.text(BukkitCommandMessagesExtended.COMMAND_DEVELOPER_TARGET_MUST_BE_IRIS_WORLD));
|
||||
return;
|
||||
}
|
||||
|
||||
PlatformChunkGenerator access = IrisToolbelt.access(world);
|
||||
if (access == null || access.getEngine() == null) {
|
||||
sender().sendMessage(C.RED + "The engine access for this world is null.");
|
||||
sender().sendMessage(IrisLanguage.text(BukkitCommandMessagesExtended.COMMAND_DEVELOPER_ENGINE_ACCESS_THIS_WORLD_IS_NULL_2));
|
||||
return;
|
||||
}
|
||||
|
||||
int chunks = (radius * 2 + 1) * (radius * 2 + 1);
|
||||
sender().sendMessage(C.GREEN + "GoldenHash started: " + C.GOLD + chunks + C.GREEN
|
||||
+ " chunk(s) around " + C.GOLD + centerX + "," + centerZ + C.GREEN
|
||||
+ " in buffers (world untouched).");
|
||||
sender().sendMessage(IrisLanguage.text(BukkitCommandMessagesExtended.COMMAND_DEVELOPER_GOLDENHASH_STARTED_CHUNK_S_AROUND_BUFFERS_WORLD_UNTOUCHED, MessageArgument.untrusted("chunks", chunks), MessageArgument.untrusted("centerX", centerX), MessageArgument.untrusted("centerZ", centerZ)));
|
||||
Iris.info("goldenhash start: world=" + world.getName()
|
||||
+ " center=" + centerX + "," + centerZ
|
||||
+ " radius=" + radius
|
||||
|
||||
+24
-21
@@ -33,86 +33,89 @@ import java.awt.Desktop;
|
||||
import java.awt.GraphicsEnvironment;
|
||||
|
||||
|
||||
@Director(name = "edit", origin = DirectorOrigin.PLAYER, description = "Edit something")
|
||||
import art.arcane.iris.core.localization.IrisLanguage;
|
||||
import art.arcane.iris.core.localization.BukkitCommandMessagesExtended;
|
||||
import art.arcane.volmlib.util.localization.MessageArgument;
|
||||
@Director(name = "edit", origin = DirectorOrigin.PLAYER, description = "Edit something", descriptionKey = "iris.director.commandedit.director.edit_something")
|
||||
public class CommandEdit implements DirectorExecutor {
|
||||
private boolean noStudio() {
|
||||
if (!sender().isPlayer()) {
|
||||
sender().sendMessage(C.RED + "Players only!");
|
||||
sender().sendMessage(IrisLanguage.text(BukkitCommandMessagesExtended.COMMAND_EDIT_PLAYERS_ONLY));
|
||||
return true;
|
||||
}
|
||||
if (!Iris.service(StudioSVC.class).isProjectOpen()) {
|
||||
sender().sendMessage(C.RED + "No studio world is open!");
|
||||
sender().sendMessage(IrisLanguage.text(BukkitCommandMessagesExtended.COMMAND_EDIT_NO_STUDIO_WORLD_IS_OPEN));
|
||||
return true;
|
||||
}
|
||||
if (!engine().isStudio()) {
|
||||
sender().sendMessage(C.RED + "You must be in a studio world!");
|
||||
sender().sendMessage(IrisLanguage.text(BukkitCommandMessagesExtended.COMMAND_EDIT_YOU_MUST_BE_STUDIO_WORLD));
|
||||
return true;
|
||||
}
|
||||
|
||||
if (GraphicsEnvironment.isHeadless()) {
|
||||
sender().sendMessage(C.RED + "Cannot open files in headless environments!");
|
||||
sender().sendMessage(IrisLanguage.text(BukkitCommandMessagesExtended.COMMAND_EDIT_CANNOT_OPEN_FILES_HEADLESS_ENVIRONMENTS));
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!Desktop.isDesktopSupported()) {
|
||||
sender().sendMessage(C.RED + "Desktop is not supported by this environment!");
|
||||
sender().sendMessage(IrisLanguage.text(BukkitCommandMessagesExtended.COMMAND_EDIT_DESKTOP_IS_NOT_SUPPORTED_BY_THIS_ENVIRONMENT));
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@Director(description = "Edit the biome you specified", aliases = {"b"}, origin = DirectorOrigin.PLAYER)
|
||||
public void biome(@Param(contextual = false, description = "The biome to edit") IrisBiome biome) {
|
||||
@Director(description = "Edit the biome you specified", descriptionKey = "iris.director.commandedit.director.edit_biome_you_specified", aliases = {"b"}, origin = DirectorOrigin.PLAYER)
|
||||
public void biome(@Param(contextual = false, description = "The biome to edit", descriptionKey = "iris.director.commandedit.param.biome_edit") IrisBiome biome) {
|
||||
if (noStudio()) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
if (biome == null || biome.getLoadFile() == null) {
|
||||
sender().sendMessage(C.GOLD + "Cannot find the file; Perhaps it was not loaded directly from a file?");
|
||||
sender().sendMessage(IrisLanguage.text(BukkitCommandMessagesExtended.COMMAND_EDIT_CANNOT_FIND_FILE_PERHAPS_IT_WAS_NOT_LOADED_DIRECTLY_FROM));
|
||||
return;
|
||||
}
|
||||
Desktop.getDesktop().open(biome.getLoadFile());
|
||||
sender().sendMessage(C.GREEN + "Opening " + biome.getTypeName() + " " + biome.getLoadFile().getName().split("\\Q.\\E")[0] + " in VSCode! ");
|
||||
sender().sendMessage(IrisLanguage.text(BukkitCommandMessagesExtended.COMMAND_EDIT_OPENING_VSCODE, MessageArgument.untrusted("value", biome.getTypeName()), MessageArgument.untrusted("value2", biome.getLoadFile().getName().split("\\Q.\\E")[0])));
|
||||
} catch (Throwable e) {
|
||||
Iris.reportError(e);
|
||||
sender().sendMessage(C.RED + "Cant find the file. Or registrant does not exist");
|
||||
sender().sendMessage(IrisLanguage.text(BukkitCommandMessagesExtended.COMMAND_EDIT_CANT_FIND_FILE_REGISTRANT_DOES_NOT_EXIST));
|
||||
}
|
||||
}
|
||||
|
||||
@Director(description = "Edit the region you specified", aliases = {"r"}, origin = DirectorOrigin.PLAYER)
|
||||
public void region(@Param(contextual = false, description = "The region to edit") IrisRegion region) {
|
||||
@Director(description = "Edit the region you specified", descriptionKey = "iris.director.commandedit.director.edit_region_you_specified", aliases = {"r"}, origin = DirectorOrigin.PLAYER)
|
||||
public void region(@Param(contextual = false, description = "The region to edit", descriptionKey = "iris.director.commandedit.param.region_edit") IrisRegion region) {
|
||||
if (noStudio()) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
if (region == null || region.getLoadFile() == null) {
|
||||
sender().sendMessage(C.GOLD + "Cannot find the file; Perhaps it was not loaded directly from a file?");
|
||||
sender().sendMessage(IrisLanguage.text(BukkitCommandMessagesExtended.COMMAND_EDIT_CANNOT_FIND_FILE_PERHAPS_IT_WAS_NOT_LOADED_DIRECTLY_FROM_2));
|
||||
return;
|
||||
}
|
||||
Desktop.getDesktop().open(region.getLoadFile());
|
||||
sender().sendMessage(C.GREEN + "Opening " + region.getTypeName() + " " + region.getLoadFile().getName().split("\\Q.\\E")[0] + " in VSCode! ");
|
||||
sender().sendMessage(IrisLanguage.text(BukkitCommandMessagesExtended.COMMAND_EDIT_OPENING_VSCODE_2, MessageArgument.untrusted("value", region.getTypeName()), MessageArgument.untrusted("value2", region.getLoadFile().getName().split("\\Q.\\E")[0])));
|
||||
} catch (Throwable e) {
|
||||
Iris.reportError(e);
|
||||
sender().sendMessage(C.RED + "Cant find the file. Or registrant does not exist");
|
||||
sender().sendMessage(IrisLanguage.text(BukkitCommandMessagesExtended.COMMAND_EDIT_CANT_FIND_FILE_REGISTRANT_DOES_NOT_EXIST_2));
|
||||
}
|
||||
}
|
||||
|
||||
@Director(description = "Edit the dimension you specified", aliases = {"d"}, origin = DirectorOrigin.PLAYER)
|
||||
public void dimension(@Param(contextual = false, description = "The dimension to edit") IrisDimension dimension) {
|
||||
@Director(description = "Edit the dimension you specified", descriptionKey = "iris.director.commandedit.director.edit_dimension_you_specified", aliases = {"d"}, origin = DirectorOrigin.PLAYER)
|
||||
public void dimension(@Param(contextual = false, description = "The dimension to edit", descriptionKey = "iris.director.commandedit.param.dimension_edit") IrisDimension dimension) {
|
||||
if (noStudio()) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
if (dimension == null || dimension.getLoadFile() == null) {
|
||||
sender().sendMessage(C.GOLD + "Cannot find the file; Perhaps it was not loaded directly from a file?");
|
||||
sender().sendMessage(IrisLanguage.text(BukkitCommandMessagesExtended.COMMAND_EDIT_CANNOT_FIND_FILE_PERHAPS_IT_WAS_NOT_LOADED_DIRECTLY_FROM_3));
|
||||
return;
|
||||
}
|
||||
Desktop.getDesktop().open(dimension.getLoadFile());
|
||||
sender().sendMessage(C.GREEN + "Opening " + dimension.getTypeName() + " " + dimension.getLoadFile().getName().split("\\Q.\\E")[0] + " in VSCode! ");
|
||||
sender().sendMessage(IrisLanguage.text(BukkitCommandMessagesExtended.COMMAND_EDIT_OPENING_VSCODE_3, MessageArgument.untrusted("value", dimension.getTypeName()), MessageArgument.untrusted("value2", dimension.getLoadFile().getName().split("\\Q.\\E")[0])));
|
||||
} catch (Throwable e) {
|
||||
Iris.reportError(e);
|
||||
sender().sendMessage(C.RED + "Cant find the file. Or registrant does not exist");
|
||||
sender().sendMessage(IrisLanguage.text(BukkitCommandMessagesExtended.COMMAND_EDIT_CANT_FIND_FILE_REGISTRANT_DOES_NOT_EXIST_3));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+32
-29
@@ -50,61 +50,65 @@ import org.bukkit.entity.Player;
|
||||
import org.bukkit.generator.structure.Structure;
|
||||
import org.bukkit.util.StructureSearchResult;
|
||||
|
||||
@Director(name = "find", origin = DirectorOrigin.PLAYER, description = "Iris Find commands", aliases = "goto")
|
||||
import art.arcane.iris.core.localization.IrisLanguage;
|
||||
import art.arcane.iris.core.localization.BukkitCommandMessages;
|
||||
import art.arcane.volmlib.util.localization.MessageArgument;
|
||||
import art.arcane.iris.core.localization.BukkitCommandMessagesExtended;
|
||||
@Director(name = "find", origin = DirectorOrigin.PLAYER, description = "Iris Find commands", descriptionKey = "iris.director.commandfind.director.iris_find_commands", aliases = "goto")
|
||||
public class CommandFind implements DirectorExecutor {
|
||||
@Director(description = "Find a biome")
|
||||
@Director(description = "Find a biome", descriptionKey = "iris.director.commandfind.director.find_biome")
|
||||
public void biome(
|
||||
@Param(description = "The biome to look for")
|
||||
@Param(description = "The biome to look for", descriptionKey = "iris.director.commandfind.param.biome_look")
|
||||
IrisBiome biome,
|
||||
@Param(description = "Should you be teleported", defaultValue = "true")
|
||||
@Param(description = "Should you be teleported", descriptionKey = "iris.director.commandfind.param.should_you_be_teleported", defaultValue = "true")
|
||||
boolean teleport
|
||||
) {
|
||||
Engine e = engine();
|
||||
|
||||
if (e == null) {
|
||||
sender().sendMessage(C.GOLD + "Not in an Iris World!");
|
||||
sender().sendMessage(IrisLanguage.text(BukkitCommandMessagesExtended.COMMAND_FIND_NOT_IRIS_WORLD));
|
||||
return;
|
||||
}
|
||||
|
||||
EngineBukkitOps.gotoBiome(e, biome, player(), teleport);
|
||||
}
|
||||
|
||||
@Director(description = "Find a region")
|
||||
@Director(description = "Find a region", descriptionKey = "iris.director.commandfind.director.find_region")
|
||||
public void region(
|
||||
@Param(description = "The region to look for")
|
||||
@Param(description = "The region to look for", descriptionKey = "iris.director.commandfind.param.region_look")
|
||||
IrisRegion region,
|
||||
@Param(description = "Should you be teleported", defaultValue = "true")
|
||||
@Param(description = "Should you be teleported", descriptionKey = "iris.director.commandfind.param.should_you_be_teleported_2", defaultValue = "true")
|
||||
boolean teleport
|
||||
) {
|
||||
Engine e = engine();
|
||||
|
||||
if (e == null) {
|
||||
sender().sendMessage(C.GOLD + "Not in an Iris World!");
|
||||
sender().sendMessage(IrisLanguage.text(BukkitCommandMessagesExtended.COMMAND_FIND_NOT_IRIS_WORLD_2));
|
||||
return;
|
||||
}
|
||||
|
||||
EngineBukkitOps.gotoRegion(e, region, player(), teleport);
|
||||
}
|
||||
|
||||
@Director(description = "Find a point of interest.")
|
||||
@Director(description = "Find a point of interest.", descriptionKey = "iris.director.commandfind.director.find_point_interest")
|
||||
public void poi(
|
||||
@Param(description = "The type of PoI to look for.")
|
||||
@Param(description = "The type of PoI to look for.", descriptionKey = "iris.director.commandfind.param.type_poi_look")
|
||||
String type,
|
||||
@Param(description = "Should you be teleported", defaultValue = "true")
|
||||
@Param(description = "Should you be teleported", descriptionKey = "iris.director.commandfind.param.should_you_be_teleported_3", defaultValue = "true")
|
||||
boolean teleport
|
||||
) {
|
||||
Engine e = engine();
|
||||
if (e == null) {
|
||||
sender().sendMessage(C.GOLD + "Not in an Iris World!");
|
||||
sender().sendMessage(IrisLanguage.text(BukkitCommandMessagesExtended.COMMAND_FIND_NOT_IRIS_WORLD_3));
|
||||
return;
|
||||
}
|
||||
|
||||
EngineBukkitOps.gotoPOI(e, type, player(), teleport);
|
||||
}
|
||||
|
||||
@Director(description = "Find a structure (a vanilla key like minecraft:village_plains or minecraft:stronghold, or an imported iris structure key)", sync = true)
|
||||
@Director(description = "Find a structure (a vanilla key like minecraft:village_plains or minecraft:stronghold, or an imported iris structure key)", descriptionKey = "iris.director.commandfind.director.find_structure_vanilla_key_like_minecraft_village_plains_minecraft_stronghold_imported_iris", sync = true)
|
||||
public void structure(
|
||||
@Param(description = "The structure to look for (e.g. minecraft:village_plains, minecraft:stronghold, minecraft_ancient_city)", customHandler = StructureHandler.class)
|
||||
@Param(description = "The structure to look for (e.g. minecraft:village_plains, minecraft:stronghold, minecraft_ancient_city)", descriptionKey = "iris.director.commandfind.param.structure_look_e_g_minecraft_village_plains_minecraft_stronghold_minecraft_ancient_city", customHandler = StructureHandler.class)
|
||||
String structure
|
||||
) {
|
||||
VolmitSender commandSender = sender();
|
||||
@@ -116,7 +120,7 @@ public class CommandFind implements DirectorExecutor {
|
||||
Engine e = engine();
|
||||
|
||||
if (e == null) {
|
||||
commandSender.sendMessage(C.GOLD + "Not in an Iris World!");
|
||||
commandSender.sendMessage(IrisLanguage.text(BukkitCommandMessages.COMMAND_FIND_NOT_IRIS_WORLD));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -143,19 +147,19 @@ public class CommandFind implements DirectorExecutor {
|
||||
}
|
||||
|
||||
if (nativeStructure == null) {
|
||||
commandSender.sendMessage(C.RED + "Unknown structure: " + structureKey);
|
||||
commandSender.sendMessage(IrisLanguage.text(BukkitCommandMessages.COMMAND_FIND_UNKNOWN_STRUCTURE, MessageArgument.untrusted("structureKey", structureKey)));
|
||||
return;
|
||||
}
|
||||
|
||||
Player target = player();
|
||||
if (target == null) {
|
||||
commandSender.sendMessage(C.GOLD + "Run this in-game to teleport to a structure.");
|
||||
commandSender.sendMessage(IrisLanguage.text(BukkitCommandMessages.COMMAND_FIND_RUN_THIS_GAME_TELEPORT_STRUCTURE));
|
||||
return;
|
||||
}
|
||||
|
||||
World targetWorld = target.getWorld();
|
||||
Location origin = target.getLocation();
|
||||
commandSender.sendMessage(C.GRAY + "Locating " + structureKey + "...");
|
||||
commandSender.sendMessage(IrisLanguage.text(BukkitCommandMessages.COMMAND_FIND_LOCATING, MessageArgument.untrusted("structureKey", structureKey)));
|
||||
J.s(() -> {
|
||||
try {
|
||||
if (!StructureReachability.isReachable(e, structureKey)) {
|
||||
@@ -196,14 +200,14 @@ public class CommandFind implements DirectorExecutor {
|
||||
private void locateIrisStructure(Engine engine, String structure, VolmitSender commandSender) {
|
||||
Player target = player();
|
||||
if (target == null) {
|
||||
commandSender.sendMessage(C.GOLD + "Run this in-game to teleport to a structure.");
|
||||
commandSender.sendMessage(IrisLanguage.text(BukkitCommandMessages.COMMAND_FIND_RUN_THIS_GAME_TELEPORT_STRUCTURE_2));
|
||||
return;
|
||||
}
|
||||
World targetWorld = target.getWorld();
|
||||
Location origin = target.getLocation();
|
||||
int blockX = origin.getBlockX();
|
||||
int blockZ = origin.getBlockZ();
|
||||
commandSender.sendMessage(C.GRAY + "Locating " + structure + "...");
|
||||
commandSender.sendMessage(IrisLanguage.text(BukkitCommandMessages.COMMAND_FIND_LOCATING_2, MessageArgument.untrusted("structure", structure)));
|
||||
J.a(() -> {
|
||||
try {
|
||||
IrisStructureLocator.LocateResult result =
|
||||
@@ -230,17 +234,17 @@ public class CommandFind implements DirectorExecutor {
|
||||
});
|
||||
}
|
||||
|
||||
@Director(description = "Find an object")
|
||||
@Director(description = "Find an object", descriptionKey = "iris.director.commandfind.director.find_object")
|
||||
public void object(
|
||||
@Param(description = "The object to look for", customHandler = ObjectHandler.class)
|
||||
@Param(description = "The object to look for", descriptionKey = "iris.director.commandfind.param.object_look", customHandler = ObjectHandler.class)
|
||||
String object,
|
||||
@Param(description = "Should you be teleported", defaultValue = "true")
|
||||
@Param(description = "Should you be teleported", descriptionKey = "iris.director.commandfind.param.should_you_be_teleported_4", defaultValue = "true")
|
||||
boolean teleport
|
||||
) {
|
||||
Engine e = engine();
|
||||
|
||||
if (e == null) {
|
||||
sender().sendMessage(C.GOLD + "Not in an Iris World!");
|
||||
sender().sendMessage(IrisLanguage.text(BukkitCommandMessagesExtended.COMMAND_FIND_NOT_IRIS_WORLD_4));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -248,7 +252,7 @@ public class CommandFind implements DirectorExecutor {
|
||||
if (studioPlayer != null) {
|
||||
try {
|
||||
if (ObjectStudioSaveService.get().teleportTo(studioPlayer, object)) {
|
||||
sender().sendMessage(C.GREEN + "Object Studio: teleporting to " + object);
|
||||
sender().sendMessage(IrisLanguage.text(BukkitCommandMessagesExtended.COMMAND_FIND_OBJECT_STUDIO_TELEPORTING, MessageArgument.untrusted("object", object)));
|
||||
return;
|
||||
}
|
||||
} catch (Throwable t) {
|
||||
@@ -261,7 +265,7 @@ public class CommandFind implements DirectorExecutor {
|
||||
return;
|
||||
}
|
||||
|
||||
sender().sendMessage(C.RED + object + " is not configured in any region/biome object placements.");
|
||||
sender().sendMessage(IrisLanguage.text(BukkitCommandMessagesExtended.COMMAND_FIND_IS_NOT_CONFIGURED_ANY_REGION_BIOME_OBJECT_PLACEMENTS, MessageArgument.untrusted("object", object)));
|
||||
}
|
||||
|
||||
private void prepareStructureTeleport(Player target, World world, VolmitSender commandSender, String structure,
|
||||
@@ -291,8 +295,7 @@ public class CommandFind implements DirectorExecutor {
|
||||
Location destination = new Location(world, at.getBlockX() + 0.5, y, at.getBlockZ() + 0.5);
|
||||
J.runEntity(target, () -> {
|
||||
BukkitPlatform.teleportAsync(target, destination);
|
||||
commandSender.sendMessage(C.GREEN + "Teleported to " + structure + " @ "
|
||||
+ at.getBlockX() + ", " + y + ", " + at.getBlockZ());
|
||||
commandSender.sendMessage(IrisLanguage.text(BukkitCommandMessages.COMMAND_FIND_TELEPORTED, MessageArgument.untrusted("structure", structure), MessageArgument.untrusted("value", at.getBlockX()), MessageArgument.untrusted("y", y), MessageArgument.untrusted("value2", at.getBlockZ())));
|
||||
});
|
||||
} catch (Throwable t) {
|
||||
sendStructureMessage(target, commandSender, C.RED + "Could not prepare the destination for " + structure + ".");
|
||||
|
||||
+110
-89
@@ -67,7 +67,13 @@ import static art.arcane.iris.core.service.EditSVC.deletingWorld;
|
||||
import static art.arcane.iris.util.common.misc.ServerProperties.BUKKIT_YML;
|
||||
import static org.bukkit.Bukkit.getServer;
|
||||
|
||||
@Director(name = "iris", aliases = {"ir", "irs"}, description = "Basic Command")
|
||||
import art.arcane.iris.core.localization.IrisLanguage;
|
||||
import art.arcane.iris.core.localization.IrisMessages;
|
||||
import art.arcane.volmlib.util.localization.MessageArgument;
|
||||
import art.arcane.iris.core.localization.BukkitCommandMessages;
|
||||
import art.arcane.iris.core.localization.BukkitCommandMessagesExtended;
|
||||
import art.arcane.iris.core.localization.RuntimeUiMessages;
|
||||
@Director(name = "iris", aliases = {"ir", "irs"}, description = "Basic Command", descriptionKey = "iris.director.commandiris.director.basic_command")
|
||||
public class CommandIris implements DirectorExecutor {
|
||||
private CommandStudio studio;
|
||||
private CommandPregen pregen;
|
||||
@@ -85,37 +91,37 @@ public class CommandIris implements DirectorExecutor {
|
||||
String worldNameToCheck = "YourWorldName";
|
||||
VolmitSender sender = Iris.getSender();
|
||||
|
||||
@Director(description = "Create a new world", aliases = {"c"})
|
||||
@Director(description = "Create a new world", descriptionKey = "iris.director.commandiris.director.create_new_world", aliases = {"c"})
|
||||
public void create(
|
||||
@Param(aliases = "world-name", description = "The name of the world to create")
|
||||
@Param(aliases = "world-name", description = "The name of the world to create", descriptionKey = "iris.director.commandiris.param.name_world_create")
|
||||
String name,
|
||||
@Param(
|
||||
aliases = {"dimension", "pack"},
|
||||
description = "The dimension/pack to create the world with",
|
||||
description = "The dimension/pack to create the world with", descriptionKey = "iris.director.commandiris.param.dimension_pack_create_world_with",
|
||||
defaultValue = "default",
|
||||
customHandler = PackDimensionTypeHandler.class
|
||||
)
|
||||
String type,
|
||||
@Param(description = "The seed to generate the world with", defaultValue = "1337")
|
||||
@Param(description = "The seed to generate the world with", descriptionKey = "iris.director.commandiris.param.seed_generate_world_with", defaultValue = "1337")
|
||||
long seed,
|
||||
@Param(aliases = "main-world", description = "Whether or not to automatically use this world as the main world", defaultValue = "false")
|
||||
@Param(aliases = "main-world", description = "Whether or not to automatically use this world as the main world", descriptionKey = "iris.director.commandiris.param.whether_not_automatically_use_this_world_as_main_world", defaultValue = "false")
|
||||
boolean main
|
||||
) {
|
||||
String worldName = IrisWorldStorage.logicalName(IrisWorldStorage.keyFromName(name));
|
||||
if (worldName.equalsIgnoreCase("iris")) {
|
||||
sender().sendMessage(C.RED + "You cannot use the world name \"iris\" for creating worlds as Iris uses this directory for studio worlds.");
|
||||
sender().sendMessage(C.RED + "May we suggest the name \"IrisWorld\" instead?");
|
||||
sender().sendMessage(IrisLanguage.text(BukkitCommandMessagesExtended.COMMAND_IRIS_YOU_CANNOT_USE_WORLD_NAME_IRIS_CREATING_WORLDS_AS_IRIS));
|
||||
sender().sendMessage(IrisLanguage.text(BukkitCommandMessagesExtended.COMMAND_IRIS_MAY_WE_SUGGEST_NAME_IRISWORLD_INSTEAD));
|
||||
return;
|
||||
}
|
||||
|
||||
if (worldName.equalsIgnoreCase("benchmark")) {
|
||||
sender().sendMessage(C.RED + "You cannot use the world name \"benchmark\" for creating worlds as Iris uses this directory for Benchmarking Packs.");
|
||||
sender().sendMessage(C.RED + "May we suggest the name \"IrisWorld\" instead?");
|
||||
sender().sendMessage(IrisLanguage.text(BukkitCommandMessagesExtended.COMMAND_IRIS_YOU_CANNOT_USE_WORLD_NAME_BENCHMARK_CREATING_WORLDS_AS_IRIS));
|
||||
sender().sendMessage(IrisLanguage.text(BukkitCommandMessagesExtended.COMMAND_IRIS_MAY_WE_SUGGEST_NAME_IRISWORLD_INSTEAD_2));
|
||||
return;
|
||||
}
|
||||
|
||||
if (IrisWorldStorage.dimensionRoot(worldName).exists()) {
|
||||
sender().sendMessage(C.RED + "That folder already exists!");
|
||||
sender().sendMessage(IrisLanguage.text(BukkitCommandMessagesExtended.COMMAND_IRIS_THAT_FOLDER_ALREADY_EXISTS));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -125,15 +131,15 @@ public class CommandIris implements DirectorExecutor {
|
||||
|
||||
IrisDimension dimension = IrisToolbelt.getDimension(resolvedType);
|
||||
if (dimension == null) {
|
||||
sender().sendMessage(C.RED + "Could not find or download dimension \"" + resolvedType + "\".");
|
||||
sender().sendMessage(C.YELLOW + "Try one of: overworld, vanilla, flat, theend");
|
||||
sender().sendMessage(C.YELLOW + "Or download manually: /iris download " + resolvedType);
|
||||
sender().sendMessage(IrisLanguage.text(BukkitCommandMessagesExtended.COMMAND_IRIS_COULD_NOT_FIND_DOWNLOAD_DIMENSION, MessageArgument.untrusted("resolvedType", resolvedType)));
|
||||
sender().sendMessage(IrisLanguage.text(BukkitCommandMessagesExtended.COMMAND_IRIS_TRY_ONE_OVERWORLD_VANILLA_FLAT_THEEND));
|
||||
sender().sendMessage(IrisLanguage.text(BukkitCommandMessagesExtended.COMMAND_IRIS_DOWNLOAD_MANUALLY_IRIS_DOWNLOAD, MessageArgument.untrusted("resolvedType", resolvedType)));
|
||||
return;
|
||||
}
|
||||
|
||||
if (J.isFolia()) {
|
||||
if (stageFoliaWorldCreation(worldName, dimension, seed, main)) {
|
||||
sender().sendMessage(C.GREEN + "World staging completed. Restart the server to generate/load \"" + worldName + "\".");
|
||||
sender().sendMessage(IrisLanguage.text(BukkitCommandMessagesExtended.COMMAND_IRIS_WORLD_STAGING_COMPLETED_RESTART_SERVER_GENERATE_LOAD, MessageArgument.untrusted("worldName", worldName)));
|
||||
}
|
||||
return;
|
||||
}
|
||||
@@ -154,15 +160,15 @@ public class CommandIris implements DirectorExecutor {
|
||||
}));
|
||||
}
|
||||
} catch (Throwable e) {
|
||||
sender().sendMessage(C.RED + "Exception raised during creation. See the console for more details.");
|
||||
sender().sendMessage(IrisLanguage.text(BukkitCommandMessagesExtended.COMMAND_IRIS_EXCEPTION_RAISED_DURING_CREATION_SEE_CONSOLE_MORE_DETAILS));
|
||||
Iris.reportError("Exception raised during world creation for \"" + worldName + "\".", e);
|
||||
worldCreation = false;
|
||||
return;
|
||||
}
|
||||
|
||||
worldCreation = false;
|
||||
sender().sendMessage(C.GREEN + "Successfully created your world!");
|
||||
if (main) sender().sendMessage(C.GREEN + "Your world will automatically be set as the main world when the server restarts.");
|
||||
sender().sendMessage(IrisLanguage.text(BukkitCommandMessagesExtended.COMMAND_IRIS_SUCCESSFULLY_CREATED_YOUR_WORLD));
|
||||
if (main) sender().sendMessage(IrisLanguage.text(BukkitCommandMessagesExtended.COMMAND_IRIS_YOUR_WORLD_WILL_AUTOMATICALLY_BE_SET_AS_MAIN_WORLD_WHEN));
|
||||
}
|
||||
|
||||
private boolean updateMainWorld(String newName) {
|
||||
@@ -216,13 +222,13 @@ public class CommandIris implements DirectorExecutor {
|
||||
}
|
||||
|
||||
private boolean stageFoliaWorldCreation(String name, IrisDimension dimension, long seed, boolean main) {
|
||||
sender().sendMessage(C.YELLOW + "Runtime world creation is disabled on Folia.");
|
||||
sender().sendMessage(C.YELLOW + "Preparing world files and bukkit.yml for next startup...");
|
||||
sender().sendMessage(IrisLanguage.text(BukkitCommandMessagesExtended.COMMAND_IRIS_RUNTIME_WORLD_CREATION_IS_DISABLED_ON_FOLIA));
|
||||
sender().sendMessage(IrisLanguage.text(BukkitCommandMessagesExtended.COMMAND_IRIS_PREPARING_WORLD_FILES_BUKKIT_YML_NEXT_STARTUP));
|
||||
|
||||
File worldFolder = IrisWorldStorage.dimensionRoot(name);
|
||||
IrisDimension installed = Iris.service(StudioSVC.class).installIntoWorld(sender(), dimension, worldFolder);
|
||||
if (installed == null) {
|
||||
sender().sendMessage(C.RED + "Failed to stage world files for dimension \"" + dimension.getLoadKey() + "\".");
|
||||
sender().sendMessage(IrisLanguage.text(BukkitCommandMessagesExtended.COMMAND_IRIS_FAILED_STAGE_WORLD_FILES_DIMENSION, MessageArgument.untrusted("value", dimension.getLoadKey())));
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -232,16 +238,16 @@ public class CommandIris implements DirectorExecutor {
|
||||
|
||||
if (main) {
|
||||
if (updateMainWorld(name)) {
|
||||
sender().sendMessage(C.GREEN + "Updated server.properties level-name to \"" + name + "\".");
|
||||
sender().sendMessage(IrisLanguage.text(BukkitCommandMessagesExtended.COMMAND_IRIS_UPDATED_SERVER_PROPERTIES_LEVEL_NAME, MessageArgument.untrusted("name", name)));
|
||||
} else {
|
||||
sender().sendMessage(C.RED + "World was staged, but failed to update server.properties main world.");
|
||||
sender().sendMessage(IrisLanguage.text(BukkitCommandMessagesExtended.COMMAND_IRIS_WORLD_WAS_STAGED_BUT_FAILED_UPDATE_SERVER_PROPERTIES_MAIN_WORLD));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
sender().sendMessage(C.GREEN + "Staged Iris world \"" + name + "\" with generator Iris:" + dimension.getLoadKey() + " and seed " + seed + ".");
|
||||
sender().sendMessage(IrisLanguage.text(BukkitCommandMessagesExtended.COMMAND_IRIS_STAGED_IRIS_WORLD_WITH_GENERATOR_IRIS_SEED, MessageArgument.untrusted("name", name), MessageArgument.untrusted("value", dimension.getLoadKey()), MessageArgument.untrusted("seed", seed)));
|
||||
if (main) {
|
||||
sender().sendMessage(C.GREEN + "This world is now configured as main for next restart.");
|
||||
sender().sendMessage(IrisLanguage.text(BukkitCommandMessagesExtended.COMMAND_IRIS_THIS_WORLD_IS_NOW_CONFIGURED_AS_MAIN_NEXT_RESTART));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@@ -269,18 +275,18 @@ public class CommandIris implements DirectorExecutor {
|
||||
Iris.info("Registered \"" + logicalWorldName + "\" in bukkit.yml");
|
||||
return true;
|
||||
} catch (IOException e) {
|
||||
sender().sendMessage(C.RED + "Failed to update bukkit.yml: " + e.getMessage());
|
||||
sender().sendMessage(IrisLanguage.text(BukkitCommandMessagesExtended.COMMAND_IRIS_FAILED_UPDATE_BUKKIT_YML, MessageArgument.untrusted("value", String.valueOf(e.getMessage()))));
|
||||
Iris.error("Failed to update bukkit.yml!");
|
||||
Iris.reportError(e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@Director(description = "Teleport to another world", aliases = {"tp"}, sync = true)
|
||||
@Director(description = "Teleport to another world", descriptionKey = "iris.director.commandiris.director.teleport_another_world", aliases = {"tp"}, sync = true)
|
||||
public void teleport(
|
||||
@Param(description = "World to teleport to")
|
||||
@Param(description = "World to teleport to", descriptionKey = "iris.director.commandiris.param.world_teleport")
|
||||
World world,
|
||||
@Param(description = "Player to teleport", defaultValue = "---", customHandler = NullablePlayerHandler.class)
|
||||
@Param(description = "Player to teleport", descriptionKey = "iris.director.commandiris.param.player_teleport", defaultValue = "---", customHandler = NullablePlayerHandler.class)
|
||||
Player player
|
||||
) {
|
||||
if (player == null && sender().isPlayer())
|
||||
@@ -288,30 +294,33 @@ public class CommandIris implements DirectorExecutor {
|
||||
|
||||
final Player target = player;
|
||||
if (target == null) {
|
||||
sender().sendMessage(C.RED + "The specified player does not exist.");
|
||||
sender().sendMessage(IrisLanguage.text(BukkitCommandMessagesExtended.COMMAND_IRIS_SPECIFIED_PLAYER_DOES_NOT_EXIST));
|
||||
return;
|
||||
}
|
||||
|
||||
final Location spawn = world.getSpawnLocation();
|
||||
final Runnable teleportTask = () -> {
|
||||
BukkitPlatform.teleportAsync(target, spawn);
|
||||
new VolmitSender(target).sendMessage(C.GREEN + "You have been teleported to " + world.getName() + ".");
|
||||
new VolmitSender(target).sendMessage(C.GREEN + IrisLanguage.text(
|
||||
RuntimeUiMessages.TELEPORTED_TO_WORLD,
|
||||
MessageArgument.untrusted("world", world.getName())
|
||||
));
|
||||
};
|
||||
if (!J.runEntity(target, teleportTask)) {
|
||||
teleportTask.run();
|
||||
}
|
||||
}
|
||||
|
||||
@Director(description = "Print version information")
|
||||
@Director(description = "Print version information", descriptionKey = "iris.director.commandiris.director.print_version_information")
|
||||
public void version() {
|
||||
sender().sendMessage(C.GREEN + "Iris v" + Iris.instance.getDescription().getVersion() + " by Volmit Software");
|
||||
sender().sendMessage(IrisLanguage.text(BukkitCommandMessagesExtended.COMMAND_IRIS_IRIS_V_BY_VOLMIT_SOFTWARE, MessageArgument.untrusted("value", Iris.instance.getDescription().getVersion())));
|
||||
}
|
||||
|
||||
/*
|
||||
/todo
|
||||
@Director(description = "Benchmark a pack", origin = DirectorOrigin.CONSOLE)
|
||||
@Director(description = "Benchmark a pack", descriptionKey = "iris.director.commandiris.director.benchmark_pack", origin = DirectorOrigin.CONSOLE)
|
||||
public void packbenchmark(
|
||||
@Param(description = "Dimension to benchmark")
|
||||
@Param(description = "Dimension to benchmark", descriptionKey = "iris.director.commandiris.param.dimension_benchmark")
|
||||
IrisDimension type
|
||||
) throws InterruptedException {
|
||||
|
||||
@@ -320,11 +329,11 @@ public class CommandIris implements DirectorExecutor {
|
||||
IrisPackBenchmarking.runBenchmark();
|
||||
} */
|
||||
|
||||
@Director(description = "Print world height information", origin = DirectorOrigin.PLAYER)
|
||||
@Director(description = "Print world height information", descriptionKey = "iris.director.commandiris.director.print_world_height_information", origin = DirectorOrigin.PLAYER)
|
||||
public void height() {
|
||||
if (sender().isPlayer()) {
|
||||
sender().sendMessage(C.GREEN + "" + sender().player().getWorld().getMinHeight() + " to " + sender().player().getWorld().getMaxHeight());
|
||||
sender().sendMessage(C.GREEN + "Total Height: " + (sender().player().getWorld().getMaxHeight() - sender().player().getWorld().getMinHeight()));
|
||||
sender().sendMessage(IrisLanguage.text(BukkitCommandMessagesExtended.COMMAND_IRIS_TO, MessageArgument.untrusted("value", sender().player().getWorld().getMinHeight()), MessageArgument.untrusted("value2", sender().player().getWorld().getMaxHeight())));
|
||||
sender().sendMessage(IrisLanguage.text(BukkitCommandMessagesExtended.COMMAND_IRIS_TOTAL_HEIGHT, MessageArgument.untrusted("value", (sender().player().getWorld().getMaxHeight() - sender().player().getWorld().getMinHeight()))));
|
||||
} else {
|
||||
World mainWorld = getServer().getWorlds().get(0);
|
||||
Iris.info(C.GREEN + "" + mainWorld.getMinHeight() + " to " + mainWorld.getMaxHeight());
|
||||
@@ -332,7 +341,7 @@ public class CommandIris implements DirectorExecutor {
|
||||
}
|
||||
}
|
||||
|
||||
@Director(description = "Check access of all worlds.", aliases = {"accesslist"})
|
||||
@Director(description = "Check access of all worlds.", descriptionKey = "iris.director.commandiris.director.check_access_all_worlds", aliases = {"accesslist"})
|
||||
public void worlds() {
|
||||
KList<World> IrisWorlds = new KList<>();
|
||||
KList<World> BukkitWorlds = new KList<>();
|
||||
@@ -349,13 +358,13 @@ public class CommandIris implements DirectorExecutor {
|
||||
}
|
||||
|
||||
if (sender().isPlayer()) {
|
||||
sender().sendMessage(C.BLUE + "Iris Worlds: ");
|
||||
sender().sendMessage(IrisLanguage.text(BukkitCommandMessagesExtended.COMMAND_IRIS_IRIS_WORLDS));
|
||||
for (World IrisWorld : IrisWorlds.copy()) {
|
||||
sender().sendMessage(C.IRIS + "- " +IrisWorld.getName());
|
||||
sender().sendMessage(IrisLanguage.text(BukkitCommandMessagesExtended.COMMAND_IRIS_MESSAGE, MessageArgument.untrusted("value", IrisWorld.getName())));
|
||||
}
|
||||
sender().sendMessage(C.GOLD + "Bukkit Worlds: ");
|
||||
sender().sendMessage(IrisLanguage.text(BukkitCommandMessagesExtended.COMMAND_IRIS_BUKKIT_WORLDS));
|
||||
for (World BukkitWorld : BukkitWorlds.copy()) {
|
||||
sender().sendMessage(C.GRAY + "- " +BukkitWorld.getName());
|
||||
sender().sendMessage(IrisLanguage.text(BukkitCommandMessagesExtended.COMMAND_IRIS_MESSAGE_2, MessageArgument.untrusted("value", BukkitWorld.getName())));
|
||||
}
|
||||
} else {
|
||||
Iris.info(C.BLUE + "Iris Worlds: ");
|
||||
@@ -370,37 +379,37 @@ public class CommandIris implements DirectorExecutor {
|
||||
}
|
||||
}
|
||||
|
||||
@Director(description = "Remove an Iris world", aliases = {"rm"}, sync = true)
|
||||
@Director(description = "Remove an Iris world", descriptionKey = "iris.director.commandiris.director.remove_iris_world", aliases = {"rm"}, sync = true)
|
||||
public void remove(
|
||||
@Param(description = "The world to remove")
|
||||
@Param(description = "The world to remove", descriptionKey = "iris.director.commandiris.param.world_remove")
|
||||
World world,
|
||||
@Param(description = "Whether to also remove the folder (if set to false, just does not load the world)", defaultValue = "true")
|
||||
@Param(description = "Whether to also remove the folder (if set to false, just does not load the world)", descriptionKey = "iris.director.commandiris.param.whether_also_remove_folder_if_set_false_just_does_not_load_world", defaultValue = "true")
|
||||
boolean delete
|
||||
) {
|
||||
if (!IrisToolbelt.isIrisWorld(world)) {
|
||||
sender().sendMessage(C.RED + "This is not an Iris world. Iris worlds: " + String.join(", ", getServer().getWorlds().stream().filter(IrisToolbelt::isIrisWorld).map(World::getName).toList()));
|
||||
sender().sendMessage(IrisLanguage.text(BukkitCommandMessagesExtended.COMMAND_IRIS_THIS_IS_NOT_IRIS_WORLD_IRIS_WORLDS, MessageArgument.untrusted("value", String.join(", ", getServer().getWorlds().stream().filter(IrisToolbelt::isIrisWorld).map(World::getName).toList()))));
|
||||
return;
|
||||
}
|
||||
sender().sendMessage(C.GREEN + "Removing world: " + world.getName());
|
||||
sender().sendMessage(IrisLanguage.text(BukkitCommandMessagesExtended.COMMAND_IRIS_REMOVING_WORLD, MessageArgument.untrusted("value", world.getName())));
|
||||
|
||||
if (!IrisToolbelt.evacuate(world)) {
|
||||
sender().sendMessage(C.RED + "Failed to evacuate world: " + world.getName());
|
||||
sender().sendMessage(IrisLanguage.text(BukkitCommandMessagesExtended.COMMAND_IRIS_FAILED_EVACUATE_WORLD, MessageArgument.untrusted("value", world.getName())));
|
||||
return;
|
||||
}
|
||||
|
||||
if (!WorldLifecycleService.get().unload(world, false)) {
|
||||
sender().sendMessage(C.RED + "Failed to unload world: " + world.getName());
|
||||
sender().sendMessage(IrisLanguage.text(BukkitCommandMessagesExtended.COMMAND_IRIS_FAILED_UNLOAD_WORLD, MessageArgument.untrusted("value", world.getName())));
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
if (IrisToolbelt.removeWorld(world)) {
|
||||
sender().sendMessage(C.GREEN + "Successfully removed " + world.getName() + " from bukkit.yml");
|
||||
sender().sendMessage(IrisLanguage.text(BukkitCommandMessagesExtended.COMMAND_IRIS_SUCCESSFULLY_REMOVED_FROM_BUKKIT_YML, MessageArgument.untrusted("value", world.getName())));
|
||||
} else {
|
||||
sender().sendMessage(C.YELLOW + "Looks like the world was already removed from bukkit.yml");
|
||||
sender().sendMessage(IrisLanguage.text(BukkitCommandMessagesExtended.COMMAND_IRIS_LOOKS_LIKE_WORLD_WAS_ALREADY_REMOVED_FROM_BUKKIT_YML));
|
||||
}
|
||||
} catch (IOException e) {
|
||||
sender().sendMessage(C.RED + "Failed to save bukkit.yml because of " + e.getMessage());
|
||||
sender().sendMessage(IrisLanguage.text(BukkitCommandMessagesExtended.COMMAND_IRIS_FAILED_SAVE_BUKKIT_YML_BECAUSE, MessageArgument.untrusted("value", String.valueOf(e.getMessage()))));
|
||||
Iris.reportError("Failed to remove world \"" + world.getName() + "\" from bukkit.yml.", e);
|
||||
}
|
||||
IrisToolbelt.evacuate(world, "Deleting world");
|
||||
@@ -414,16 +423,16 @@ public class CommandIris implements DirectorExecutor {
|
||||
int retries = 12;
|
||||
|
||||
if (deleteDirectory(world.getWorldFolder())) {
|
||||
sender.sendMessage(C.GREEN + "Successfully removed world folder");
|
||||
sender.sendMessage(IrisLanguage.text(BukkitCommandMessages.COMMAND_IRIS_SUCCESSFULLY_REMOVED_WORLD_FOLDER));
|
||||
} else {
|
||||
while(true){
|
||||
if (deleteDirectory(world.getWorldFolder())){
|
||||
sender.sendMessage(C.GREEN + "Successfully removed world folder");
|
||||
sender.sendMessage(IrisLanguage.text(BukkitCommandMessages.COMMAND_IRIS_SUCCESSFULLY_REMOVED_WORLD_FOLDER_2));
|
||||
break;
|
||||
}
|
||||
retries--;
|
||||
if (retries == 0){
|
||||
sender.sendMessage(C.RED + "Failed to remove world folder");
|
||||
sender.sendMessage(IrisLanguage.text(BukkitCommandMessages.COMMAND_IRIS_FAILED_REMOVE_WORLD_FOLDER));
|
||||
break;
|
||||
}
|
||||
J.sleep(3000);
|
||||
@@ -446,78 +455,90 @@ public class CommandIris implements DirectorExecutor {
|
||||
return dir.delete();
|
||||
}
|
||||
|
||||
@Director(description = "Toggle debug")
|
||||
@Director(description = "Toggle debug", descriptionKey = "iris.director.commandiris.director.toggle_debug")
|
||||
public void debug() {
|
||||
boolean to = !IrisSettings.get().getGeneral().isDebug();
|
||||
IrisSettings.get().getGeneral().setDebug(to);
|
||||
IrisSettings.get().forceSave();
|
||||
sender().sendMessage(C.GREEN + "Set debug to: " + to);
|
||||
sender().sendMessage(IrisLanguage.text(BukkitCommandMessagesExtended.COMMAND_IRIS_SET_DEBUG, MessageArgument.untrusted("to", to)));
|
||||
}
|
||||
|
||||
@Director(description = "Download a project.", aliases = "dl")
|
||||
@Director(description = "Download a project.", descriptionKey = "iris.director.commandiris.director.download_project", aliases = "dl")
|
||||
public void download(
|
||||
@Param(name = "pack", description = "The pack to download", aliases = "project")
|
||||
@Param(name = "pack", description = "The pack to download", descriptionKey = "iris.director.commandiris.param.pack_download", aliases = "project")
|
||||
String pack,
|
||||
@Param(name = "branch", description = "The branch to download from", defaultValue = "stable")
|
||||
@Param(name = "branch", description = "The branch to download from", descriptionKey = "iris.director.commandiris.param.branch_download_from", defaultValue = "stable")
|
||||
String branch,
|
||||
@Param(name = "overwrite", description = "Whether or not to overwrite the pack with the downloaded one", aliases = "force", defaultValue = "false")
|
||||
@Param(name = "overwrite", description = "Whether or not to overwrite the pack with the downloaded one", descriptionKey = "iris.director.commandiris.param.whether_not_overwrite_pack_with_downloaded_one", aliases = "force", defaultValue = "false")
|
||||
boolean overwrite
|
||||
) {
|
||||
if (PackDownloader.isDefaultOverworld(pack)) {
|
||||
sender().sendMessage(C.GREEN + "Downloading pack: " + pack + " (beta release)" + (overwrite ? " overwriting" : ""));
|
||||
sender().sendMessage(IrisLanguage.text(BukkitCommandMessagesExtended.COMMAND_IRIS_DOWNLOADING_PACK_BETA_RELEASE, MessageArgument.untrusted("pack", pack), MessageArgument.trusted("value", overwrite ? IrisLanguage.text(RuntimeUiMessages.DOWNLOAD_OVERWRITE_SUFFIX) : "")));
|
||||
Iris.service(StudioSVC.class).downloadDefaultOverworld(sender(), overwrite);
|
||||
} else {
|
||||
sender().sendMessage(C.GREEN + "Downloading pack: " + pack + "/" + branch + (overwrite ? " overwriting" : ""));
|
||||
sender().sendMessage(IrisLanguage.text(BukkitCommandMessagesExtended.COMMAND_IRIS_DOWNLOADING_PACK, MessageArgument.untrusted("pack", pack), MessageArgument.untrusted("branch", branch), MessageArgument.trusted("value", overwrite ? IrisLanguage.text(RuntimeUiMessages.DOWNLOAD_OVERWRITE_SUFFIX) : "")));
|
||||
Iris.service(StudioSVC.class).downloadSearch(sender(), "IrisDimensions/" + pack + "/" + branch, overwrite);
|
||||
}
|
||||
ServerConfigurator.installDataPacksIfChanged(true);
|
||||
}
|
||||
|
||||
@Director(description = "Get metrics for your world", aliases = "measure", origin = DirectorOrigin.PLAYER)
|
||||
@Director(description = "Get metrics for your world", descriptionKey = "iris.director.commandiris.director.get_metrics_your_world", aliases = "measure", origin = DirectorOrigin.PLAYER)
|
||||
public void metrics() {
|
||||
if (!IrisToolbelt.isIrisWorld(world())) {
|
||||
sender().sendMessage(C.RED + "You must be in an Iris world");
|
||||
sender().sendMessage(IrisLanguage.text(BukkitCommandMessagesExtended.COMMAND_IRIS_YOU_MUST_BE_IRIS_WORLD));
|
||||
return;
|
||||
}
|
||||
sender().sendMessage(C.GREEN + "Sending metrics...");
|
||||
sender().sendMessage(IrisLanguage.text(BukkitCommandMessagesExtended.COMMAND_IRIS_SENDING_METRICS));
|
||||
engine().printMetrics(sender());
|
||||
}
|
||||
|
||||
@Director(description = "Reload configuration file (this is also done automatically)")
|
||||
@Director(description = "Reload configuration file (this is also done automatically)", descriptionKey = "iris.director.commandiris.director.reload_configuration_file_this_is_also_done_automatically")
|
||||
public void reload() {
|
||||
IrisSettings.invalidate();
|
||||
IrisSettings.get();
|
||||
sender().sendMessage(C.GREEN + "Hotloaded settings");
|
||||
boolean localeLoaded = IrisLanguage.reload();
|
||||
if (localeLoaded) {
|
||||
sender().sendMessage(C.GREEN + IrisLanguage.text(
|
||||
IrisMessages.COMMAND_RELOAD_SUCCESS,
|
||||
MessageArgument.trusted("locale", IrisLanguage.activeLocale())
|
||||
));
|
||||
return;
|
||||
}
|
||||
sender().sendMessage(C.YELLOW + IrisLanguage.text(
|
||||
IrisMessages.COMMAND_RELOAD_FAILED,
|
||||
MessageArgument.untrusted("locale", IrisSettings.get().getGeneral().getLanguage()),
|
||||
MessageArgument.trusted("activeLocale", IrisLanguage.activeLocale())
|
||||
));
|
||||
}
|
||||
|
||||
|
||||
@Director(description = "Unload an Iris World", origin = DirectorOrigin.PLAYER, sync = true)
|
||||
@Director(description = "Unload an Iris World", descriptionKey = "iris.director.commandiris.director.unload_iris_world", origin = DirectorOrigin.PLAYER, sync = true)
|
||||
public void unloadWorld(
|
||||
@Param(description = "The world to unload")
|
||||
@Param(description = "The world to unload", descriptionKey = "iris.director.commandiris.param.world_unload")
|
||||
World world
|
||||
) {
|
||||
if (!IrisToolbelt.isIrisWorld(world)) {
|
||||
sender().sendMessage(C.RED + "This is not an Iris world. Iris worlds: " + String.join(", ", getServer().getWorlds().stream().filter(IrisToolbelt::isIrisWorld).map(World::getName).toList()));
|
||||
sender().sendMessage(IrisLanguage.text(BukkitCommandMessagesExtended.COMMAND_IRIS_THIS_IS_NOT_IRIS_WORLD_IRIS_WORLDS_2, MessageArgument.untrusted("value", String.join(", ", getServer().getWorlds().stream().filter(IrisToolbelt::isIrisWorld).map(World::getName).toList()))));
|
||||
return;
|
||||
}
|
||||
sender().sendMessage(C.GREEN + "Unloading world: " + world.getName());
|
||||
sender().sendMessage(IrisLanguage.text(BukkitCommandMessagesExtended.COMMAND_IRIS_UNLOADING_WORLD, MessageArgument.untrusted("value", world.getName())));
|
||||
try {
|
||||
IrisToolbelt.evacuate(world);
|
||||
boolean unloaded = WorldLifecycleService.get().unload(world, false);
|
||||
if (unloaded) {
|
||||
sender().sendMessage(C.GREEN + "World unloaded successfully.");
|
||||
sender().sendMessage(IrisLanguage.text(BukkitCommandMessagesExtended.COMMAND_IRIS_WORLD_UNLOADED_SUCCESSFULLY));
|
||||
} else {
|
||||
sender().sendMessage(C.RED + "Failed to unload the world.");
|
||||
sender().sendMessage(IrisLanguage.text(BukkitCommandMessagesExtended.COMMAND_IRIS_FAILED_UNLOAD_WORLD_2));
|
||||
}
|
||||
} catch (Exception e) {
|
||||
sender().sendMessage(C.RED + "Failed to unload the world: " + e.getMessage());
|
||||
sender().sendMessage(IrisLanguage.text(BukkitCommandMessagesExtended.COMMAND_IRIS_FAILED_UNLOAD_WORLD_3, MessageArgument.untrusted("value", String.valueOf(e.getMessage()))));
|
||||
Iris.reportError("Failed to unload world \"" + world.getName() + "\".", e);
|
||||
}
|
||||
}
|
||||
|
||||
@Director(description = "Load an Iris World", origin = DirectorOrigin.PLAYER, sync = true, aliases = {"import"})
|
||||
@Director(description = "Load an Iris World", descriptionKey = "iris.director.commandiris.director.load_iris_world", origin = DirectorOrigin.PLAYER, sync = true, aliases = {"import"})
|
||||
public void loadWorld(
|
||||
@Param(description = "The name of the world to load")
|
||||
@Param(description = "The name of the world to load", descriptionKey = "iris.director.commandiris.param.name_world_load")
|
||||
String world
|
||||
) {
|
||||
String logicalWorldName = IrisWorldStorage.logicalName(IrisWorldStorage.keyFromName(world));
|
||||
@@ -526,7 +547,7 @@ public class CommandIris implements DirectorExecutor {
|
||||
WorldEngine = logicalWorldName;
|
||||
|
||||
if (!worldExists) {
|
||||
sender().sendMessage(C.YELLOW + logicalWorldName + " Doesnt exist on the server.");
|
||||
sender().sendMessage(IrisLanguage.text(BukkitCommandMessagesExtended.COMMAND_IRIS_DOESNT_EXIST_ON_SERVER, MessageArgument.untrusted("logicalWorldName", logicalWorldName)));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -541,45 +562,45 @@ public class CommandIris implements DirectorExecutor {
|
||||
String fileName = file.getName();
|
||||
if (fileName.endsWith(".json")) {
|
||||
dimension = fileName.substring(0, fileName.length() - 5);
|
||||
sender().sendMessage(C.BLUE + "Generator: " + dimension);
|
||||
sender().sendMessage(IrisLanguage.text(BukkitCommandMessagesExtended.COMMAND_IRIS_GENERATOR, MessageArgument.untrusted("dimension", dimension)));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
sender().sendMessage(C.GOLD + logicalWorldName + " is not an iris world.");
|
||||
sender().sendMessage(IrisLanguage.text(BukkitCommandMessagesExtended.COMMAND_IRIS_IS_NOT_IRIS_WORLD, MessageArgument.untrusted("logicalWorldName", logicalWorldName)));
|
||||
return;
|
||||
}
|
||||
|
||||
if (dimension == null) {
|
||||
sender().sendMessage(C.RED + "Could not determine Iris dimension for " + logicalWorldName + ".");
|
||||
sender().sendMessage(IrisLanguage.text(BukkitCommandMessagesExtended.COMMAND_IRIS_COULD_NOT_DETERMINE_IRIS_DIMENSION, MessageArgument.untrusted("logicalWorldName", logicalWorldName)));
|
||||
return;
|
||||
}
|
||||
|
||||
sender().sendMessage(C.GREEN + "Loading world: " + logicalWorldName);
|
||||
sender().sendMessage(IrisLanguage.text(BukkitCommandMessagesExtended.COMMAND_IRIS_LOADING_WORLD, MessageArgument.untrusted("logicalWorldName", logicalWorldName)));
|
||||
|
||||
if (!registerWorldInBukkitYml(logicalWorldName, dimension, null)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (J.isFolia()) {
|
||||
sender().sendMessage(C.YELLOW + "Folia cannot load new worlds at runtime. Restart the server to load \"" + logicalWorldName + "\".");
|
||||
sender().sendMessage(IrisLanguage.text(BukkitCommandMessagesExtended.COMMAND_IRIS_FOLIA_CANNOT_LOAD_NEW_WORLDS_AT_RUNTIME_RESTART_SERVER_LOAD, MessageArgument.untrusted("logicalWorldName", logicalWorldName)));
|
||||
return;
|
||||
}
|
||||
|
||||
Iris.instance.checkForBukkitWorlds(logicalWorldName::equals);
|
||||
sender().sendMessage(C.GREEN + logicalWorldName + " loaded successfully.");
|
||||
sender().sendMessage(IrisLanguage.text(BukkitCommandMessagesExtended.COMMAND_IRIS_LOADED_SUCCESSFULLY, MessageArgument.untrusted("logicalWorldName", logicalWorldName)));
|
||||
}
|
||||
@Director(description = "Evacuate an iris world", origin = DirectorOrigin.PLAYER, sync = true)
|
||||
@Director(description = "Evacuate an iris world", descriptionKey = "iris.director.commandiris.director.evacuate_iris_world", origin = DirectorOrigin.PLAYER, sync = true)
|
||||
public void evacuate(
|
||||
@Param(description = "Evacuate the world")
|
||||
@Param(description = "Evacuate the world", descriptionKey = "iris.director.commandiris.param.evacuate_world")
|
||||
World world
|
||||
) {
|
||||
if (!IrisToolbelt.isIrisWorld(world)) {
|
||||
sender().sendMessage(C.RED + "This is not an Iris world. Iris worlds: " + String.join(", ", getServer().getWorlds().stream().filter(IrisToolbelt::isIrisWorld).map(World::getName).toList()));
|
||||
sender().sendMessage(IrisLanguage.text(BukkitCommandMessagesExtended.COMMAND_IRIS_THIS_IS_NOT_IRIS_WORLD_IRIS_WORLDS_3, MessageArgument.untrusted("value", String.join(", ", getServer().getWorlds().stream().filter(IrisToolbelt::isIrisWorld).map(World::getName).toList()))));
|
||||
return;
|
||||
}
|
||||
sender().sendMessage(C.GREEN + "Evacuating world" + world.getName());
|
||||
sender().sendMessage(IrisLanguage.text(BukkitCommandMessagesExtended.COMMAND_IRIS_EVACUATING_WORLD, MessageArgument.untrusted("value", world.getName())));
|
||||
IrisToolbelt.evacuate(world);
|
||||
}
|
||||
|
||||
|
||||
+92
-84
@@ -83,13 +83,18 @@ import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.TreeSet;
|
||||
|
||||
@Director(name = "object", aliases = "o", origin = DirectorOrigin.PLAYER, description = "Iris object manipulation")
|
||||
import art.arcane.iris.core.localization.IrisLanguage;
|
||||
import art.arcane.iris.core.localization.BukkitCommandMessages;
|
||||
import art.arcane.volmlib.util.localization.MessageArgument;
|
||||
import art.arcane.iris.core.localization.BukkitCommandMessagesExtended;
|
||||
import art.arcane.iris.core.localization.RuntimeUiMessages;
|
||||
@Director(name = "object", aliases = "o", origin = DirectorOrigin.PLAYER, description = "Iris object manipulation", descriptionKey = "iris.director.commandobject.director.iris_object_manipulation")
|
||||
public class CommandObject implements DirectorExecutor {
|
||||
@Director(description = "Open an object studio world (grid of every object; dimension optional, defaults to all packs)", sync = true)
|
||||
@Director(description = "Open an object studio world (grid of every object; dimension optional, defaults to all packs)", descriptionKey = "iris.director.commandobject.director.open_object_studio_world_grid_every_object_dimension_optional_defaults_all_packs", sync = true)
|
||||
public void studio(
|
||||
@Param(defaultValue = "null", description = "Optional dimension whose object pack to lay out; omit to aggregate objects from every pack", aliases = "dim", customHandler = NullableDimensionHandler.class)
|
||||
@Param(defaultValue = "null", description = "Optional dimension whose object pack to lay out; omit to aggregate objects from every pack", descriptionKey = "iris.director.commandobject.param.optional_dimension_whose_object_pack_lay_out_omit_aggregate_objects_from_every", aliases = "dim", customHandler = NullableDimensionHandler.class)
|
||||
IrisDimension dimension,
|
||||
@Param(defaultValue = "1337", description = "The seed to generate the studio with", aliases = "s")
|
||||
@Param(defaultValue = "1337", description = "The seed to generate the studio with", descriptionKey = "iris.director.commandobject.param.seed_generate_studio_with", aliases = "s")
|
||||
long seed
|
||||
) {
|
||||
VolmitSender commandSender = sender();
|
||||
@@ -130,7 +135,7 @@ public class CommandObject implements DirectorExecutor {
|
||||
}
|
||||
|
||||
if (hostDimension == null || sources.isEmpty()) {
|
||||
commandSender.sendMessage(C.RED + "No packs with objects were found on this server.");
|
||||
commandSender.sendMessage(IrisLanguage.text(BukkitCommandMessages.COMMAND_OBJECT_NO_PACKS_WITH_OBJECTS_WERE_FOUND_ON_THIS_SERVER));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -140,7 +145,7 @@ public class CommandObject implements DirectorExecutor {
|
||||
if (k != null) totalObjects += k.length;
|
||||
}
|
||||
if (totalObjects == 0) {
|
||||
commandSender.sendMessage(C.RED + "No objects to place across the selected pack(s).");
|
||||
commandSender.sendMessage(IrisLanguage.text(BukkitCommandMessages.COMMAND_OBJECT_NO_OBJECTS_PLACE_ACROSS_SELECTED_PACK_S));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -151,8 +156,7 @@ public class CommandObject implements DirectorExecutor {
|
||||
String scope = dimension == null
|
||||
? ("all packs [" + sources.size() + "]")
|
||||
: ("\"" + hostDimension.getName() + "\"");
|
||||
commandSender.sendMessage(C.GREEN + "Opening Object Studio for " + scope + " ("
|
||||
+ totalObjects + " objects)");
|
||||
commandSender.sendMessage(IrisLanguage.text(BukkitCommandMessages.COMMAND_OBJECT_OPENING_OBJECT_STUDIO_OBJECTS, MessageArgument.untrusted("scope", scope), MessageArgument.untrusted("totalObjects", totalObjects)));
|
||||
|
||||
IrisDimension finalHost = hostDimension;
|
||||
try {
|
||||
@@ -176,7 +180,7 @@ public class CommandObject implements DirectorExecutor {
|
||||
});
|
||||
} catch (Throwable e) {
|
||||
Iris.reportError("Failed to open object studio world \"" + finalHost.getLoadKey() + "\".", e);
|
||||
commandSender.sendMessage(C.RED + "Failed to open object studio: " + e.getMessage());
|
||||
commandSender.sendMessage(IrisLanguage.text(BukkitCommandMessages.COMMAND_OBJECT_FAILED_OPEN_OBJECT_STUDIO, MessageArgument.untrusted("value", String.valueOf(e.getMessage()))));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -269,14 +273,14 @@ public class CommandObject implements DirectorExecutor {
|
||||
};
|
||||
}
|
||||
|
||||
@Director(description = "Check the composition of an object")
|
||||
@Director(description = "Check the composition of an object", descriptionKey = "iris.director.commandobject.director.check_composition_object")
|
||||
public void analyze(
|
||||
@Param(description = "The object to analyze", customHandler = ObjectHandler.class)
|
||||
@Param(description = "The object to analyze", descriptionKey = "iris.director.commandobject.param.object_analyze", customHandler = ObjectHandler.class)
|
||||
String object
|
||||
) {
|
||||
IrisObject o = IrisData.loadAnyObject(object, data());
|
||||
sender().sendMessage("Object Size: " + o.getW() + " * " + o.getH() + " * " + o.getD() + "");
|
||||
sender().sendMessage("Blocks Used: " + NumberFormat.getIntegerInstance().format(o.getBlocks().size()));
|
||||
sender().sendMessage(IrisLanguage.text(BukkitCommandMessagesExtended.COMMAND_OBJECT_OBJECT_SIZE, MessageArgument.untrusted("value", o.getW()), MessageArgument.untrusted("value2", o.getH()), MessageArgument.untrusted("value3", o.getD())));
|
||||
sender().sendMessage(IrisLanguage.text(BukkitCommandMessagesExtended.COMMAND_OBJECT_BLOCKS_USED, MessageArgument.untrusted("value", NumberFormat.getIntegerInstance().format(o.getBlocks().size()))));
|
||||
|
||||
var queue = o.getBlocks().values();
|
||||
Map<Material, Set<BlockData>> unsorted = new HashMap<>();
|
||||
@@ -309,7 +313,7 @@ public class CommandObject implements DirectorExecutor {
|
||||
.sorted().toList();
|
||||
Set<Material> sortedMats = new TreeSet<>(Comparator.comparingInt(materials::get).reversed());
|
||||
sortedMats.addAll(sortedMatsList);
|
||||
sender().sendMessage("== Blocks in object ==");
|
||||
sender().sendMessage(IrisLanguage.text(BukkitCommandMessagesExtended.COMMAND_OBJECT_BLOCKS_OBJECT));
|
||||
|
||||
int n = 0;
|
||||
for (Material mat : sortedMats) {
|
||||
@@ -331,35 +335,35 @@ public class CommandObject implements DirectorExecutor {
|
||||
n++;
|
||||
|
||||
if (n >= 10) {
|
||||
sender().sendMessage(" + " + (sortedMats.size() - n) + " other block types");
|
||||
sender().sendMessage(IrisLanguage.text(BukkitCommandMessagesExtended.COMMAND_OBJECT_OTHER_BLOCK_TYPES, MessageArgument.untrusted("value", (sortedMats.size() - n))));
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Director(description = "Shrink an object to its minimum size")
|
||||
public void shrink(@Param(description = "The object to shrink", customHandler = ObjectHandler.class) String object) {
|
||||
@Director(description = "Shrink an object to its minimum size", descriptionKey = "iris.director.commandobject.director.shrink_object_its_minimum_size")
|
||||
public void shrink(@Param(description = "The object to shrink", descriptionKey = "iris.director.commandobject.param.object_shrink", customHandler = ObjectHandler.class) String object) {
|
||||
IrisObject o = IrisData.loadAnyObject(object, data());
|
||||
sender().sendMessage("Current Object Size: " + o.getW() + " * " + o.getH() + " * " + o.getD());
|
||||
sender().sendMessage(IrisLanguage.text(BukkitCommandMessagesExtended.COMMAND_OBJECT_CURRENT_OBJECT_SIZE, MessageArgument.untrusted("value", o.getW()), MessageArgument.untrusted("value2", o.getH()), MessageArgument.untrusted("value3", o.getD())));
|
||||
o.shrinkwrap();
|
||||
sender().sendMessage("New Object Size: " + o.getW() + " * " + o.getH() + " * " + o.getD());
|
||||
sender().sendMessage(IrisLanguage.text(BukkitCommandMessagesExtended.COMMAND_OBJECT_NEW_OBJECT_SIZE, MessageArgument.untrusted("value", o.getW()), MessageArgument.untrusted("value2", o.getH()), MessageArgument.untrusted("value3", o.getD())));
|
||||
try {
|
||||
o.write(o.getLoadFile());
|
||||
} catch (IOException e) {
|
||||
sender().sendMessage("Failed to save object " + o.getLoadFile() + ": " + e.getMessage());
|
||||
sender().sendMessage(IrisLanguage.text(BukkitCommandMessagesExtended.COMMAND_OBJECT_FAILED_SAVE_OBJECT, MessageArgument.untrusted("value", o.getLoadFile()), MessageArgument.untrusted("value2", String.valueOf(e.getMessage()))));
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@Director(description = "Grow organic branches through the canopy so every leaf survives vanilla decay",
|
||||
@Director(description = "Grow organic branches through the canopy so every leaf survives vanilla decay", descriptionKey = "iris.director.commandobject.director.grow_organic_branches_through_canopy_so_every_leaf_survives_vanilla_decay",
|
||||
origin = DirectorOrigin.BOTH)
|
||||
public void plausibilize(
|
||||
@Param(description = "Object key, prefix (trees/), or filesystem path",
|
||||
@Param(description = "Object key, prefix (trees/), or filesystem path", descriptionKey = "iris.director.commandobject.param.object_key_prefix_trees_filesystem_path",
|
||||
customHandler = ObjectTargetHandler.class)
|
||||
String target,
|
||||
@Param(name = "dryrun", description = "dryrun=true analyzes only, writes nothing", defaultValue = "false")
|
||||
@Param(name = "dryrun", description = "dryrun=true analyzes only, writes nothing", descriptionKey = "iris.director.commandobject.param.dryrun_true_analyzes_only_writes_nothing", defaultValue = "false")
|
||||
boolean dryRun,
|
||||
@Param(name = "reach", description = "reach=N max branch length in blocks from existing wood; farther leaf clusters are pinned persistent instead. reach=0 grows unlimited", defaultValue = "12")
|
||||
@Param(name = "reach", description = "reach=N max branch length in blocks from existing wood; farther leaf clusters are pinned persistent instead. reach=0 grows unlimited", descriptionKey = "iris.director.commandobject.param.reach_n_max_branch_length_blocks_from_existing_wood_farther_leaf_clusters", defaultValue = "12")
|
||||
int reach
|
||||
) {
|
||||
IrisData nearest = data();
|
||||
@@ -368,19 +372,23 @@ public class CommandObject implements DirectorExecutor {
|
||||
targets = resolveFromPacks(target);
|
||||
}
|
||||
if (targets.isEmpty()) {
|
||||
sender().sendMessage(C.RED + "No objects matched: " + target);
|
||||
sender().sendMessage(IrisLanguage.text(BukkitCommandMessagesExtended.COMMAND_OBJECT_NO_OBJECTS_MATCHED, MessageArgument.untrusted("target", target)));
|
||||
return;
|
||||
}
|
||||
|
||||
sender().sendMessage(C.IRIS + "Plausibilize [reach=" + reach + (dryRun ? ", DRY" : "")
|
||||
+ "] queued " + targets.size() + " object(s)");
|
||||
sender().sendMessage(IrisLanguage.text(
|
||||
BukkitCommandMessagesExtended.COMMAND_OBJECT_PLAUSIBILIZE_REACH_QUEUED_OBJECT_S,
|
||||
MessageArgument.trusted("reach", reach),
|
||||
MessageArgument.trusted("value", dryRun ? IrisLanguage.text(RuntimeUiMessages.TREE_DRY_SUFFIX) : ""),
|
||||
MessageArgument.trusted("value2", targets.size())
|
||||
));
|
||||
|
||||
org.bukkit.command.CommandSender s = sender();
|
||||
List<TreePlausibilizeBatch.Target> queued = targets;
|
||||
J.a(() -> TreePlausibilizeBatch.run(queued, dryRun, reach, nearest, (String line) ->
|
||||
s.sendMessage(line.startsWith("Done:") || line.startsWith("Totals:") || line.startsWith("[")
|
||||
? C.IRIS + line
|
||||
: C.GRAY + " " + line)));
|
||||
J.a(() -> TreePlausibilizeBatch.run(queued, dryRun, reach, nearest, (TreePlausibilizeBatch.Output output) ->
|
||||
s.sendMessage(output.headline()
|
||||
? C.IRIS + output.text()
|
||||
: C.GRAY + " " + output.text())));
|
||||
}
|
||||
|
||||
private static List<TreePlausibilizeBatch.Target> resolveFromPacks(String target) {
|
||||
@@ -408,7 +416,7 @@ public class CommandObject implements DirectorExecutor {
|
||||
return out;
|
||||
}
|
||||
|
||||
@Director(description = "Convert .schem files in the 'convert' folder to .iob files.")
|
||||
@Director(description = "Convert .schem files in the 'convert' folder to .iob files.", descriptionKey = "iris.director.commandobject.director.convert_schem_files_convert_folder_iob_files")
|
||||
public void convert () {
|
||||
try {
|
||||
IrisConverter.convertSchematics(sender());
|
||||
@@ -418,26 +426,26 @@ public class CommandObject implements DirectorExecutor {
|
||||
|
||||
}
|
||||
|
||||
@Director(description = "Get a powder that reveals objects", aliases = "d")
|
||||
@Director(description = "Get a powder that reveals objects", descriptionKey = "iris.director.commandobject.director.get_powder_that_reveals_objects", aliases = "d")
|
||||
public void dust() {
|
||||
player().getInventory().addItem(WandSVC.createDust());
|
||||
sender().playSound(Sound.AMBIENT_SOUL_SAND_VALLEY_ADDITIONS, 1f, 1.5f);
|
||||
}
|
||||
|
||||
@Director(description = "Contract a selection based on your looking direction", aliases = "-")
|
||||
@Director(description = "Contract a selection based on your looking direction", descriptionKey = "iris.director.commandobject.director.contract_selection_based_on_your_looking_direction", aliases = "-")
|
||||
public void contract(
|
||||
@Param(description = "The amount to inset by", defaultValue = "1")
|
||||
@Param(description = "The amount to inset by", descriptionKey = "iris.director.commandobject.param.amount_inset_by", defaultValue = "1")
|
||||
int amount
|
||||
) {
|
||||
if (!WandSVC.isHoldingWand(player())) {
|
||||
sender().sendMessage("Hold your wand.");
|
||||
sender().sendMessage(IrisLanguage.text(BukkitCommandMessagesExtended.COMMAND_OBJECT_HOLD_YOUR_WAND));
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
Location[] b = WandSVC.getCuboid(player());
|
||||
if (b == null || b[0] == null || b[1] == null) {
|
||||
sender().sendMessage("No area selected.");
|
||||
sender().sendMessage(IrisLanguage.text(BukkitCommandMessagesExtended.COMMAND_OBJECT_NO_AREA_SELECTED));
|
||||
return;
|
||||
}
|
||||
Location a1 = b[0].clone();
|
||||
@@ -453,13 +461,13 @@ public class CommandObject implements DirectorExecutor {
|
||||
sender().playSound(Sound.ENTITY_ITEM_FRAME_ROTATE_ITEM, 1f, 0.55f);
|
||||
}
|
||||
|
||||
@Director(description = "Set point 1 to look", aliases = "p1")
|
||||
@Director(description = "Set point 1 to look", descriptionKey = "iris.director.commandobject.director.set_point_1_look", aliases = "p1")
|
||||
public void position1(
|
||||
@Param(description = "Whether to use your current position, or where you look", defaultValue = "true")
|
||||
@Param(description = "Whether to use your current position, or where you look", descriptionKey = "iris.director.commandobject.param.whether_use_your_current_position_where_you_look", defaultValue = "true")
|
||||
boolean here
|
||||
) {
|
||||
if (!WandSVC.isHoldingWand(player())) {
|
||||
sender().sendMessage("Ready your Wand.");
|
||||
sender().sendMessage(IrisLanguage.text(BukkitCommandMessagesExtended.COMMAND_OBJECT_READY_YOUR_WAND));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -479,13 +487,13 @@ public class CommandObject implements DirectorExecutor {
|
||||
}
|
||||
}
|
||||
|
||||
@Director(description = "Set point 2 to look", aliases = "p2")
|
||||
@Director(description = "Set point 2 to look", descriptionKey = "iris.director.commandobject.director.set_point_2_look", aliases = "p2")
|
||||
public void position2(
|
||||
@Param(description = "Whether to use your current position, or where you look", defaultValue = "true")
|
||||
@Param(description = "Whether to use your current position, or where you look", descriptionKey = "iris.director.commandobject.param.whether_use_your_current_position_where_you_look_2", defaultValue = "true")
|
||||
boolean here
|
||||
) {
|
||||
if (!WandSVC.isHoldingWand(player())) {
|
||||
sender().sendMessage("Ready your Wand.");
|
||||
sender().sendMessage(IrisLanguage.text(BukkitCommandMessagesExtended.COMMAND_OBJECT_READY_YOUR_WAND_2));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -506,24 +514,24 @@ public class CommandObject implements DirectorExecutor {
|
||||
}
|
||||
}
|
||||
|
||||
@Director(description = "Paste an object", sync = true)
|
||||
@Director(description = "Paste an object", descriptionKey = "iris.director.commandobject.director.paste_object", sync = true)
|
||||
public void paste(
|
||||
@Param(description = "The object to paste", customHandler = ObjectHandler.class)
|
||||
@Param(description = "The object to paste", descriptionKey = "iris.director.commandobject.param.object_paste", customHandler = ObjectHandler.class)
|
||||
String object,
|
||||
@Param(description = "Whether or not to edit the object (need to hold wand)", defaultValue = "false")
|
||||
@Param(description = "Whether or not to edit the object (need to hold wand)", descriptionKey = "iris.director.commandobject.param.whether_not_edit_object_need_hold_wand", defaultValue = "false")
|
||||
boolean edit,
|
||||
@Param(description = "The amount of degrees to rotate by", defaultValue = "0")
|
||||
@Param(description = "The amount of degrees to rotate by", descriptionKey = "iris.director.commandobject.param.amount_degrees_rotate_by", defaultValue = "0")
|
||||
int rotate,
|
||||
@Param(description = "The factor by which to scale the object placement", defaultValue = "1")
|
||||
@Param(description = "The factor by which to scale the object placement", descriptionKey = "iris.director.commandobject.param.factor_by_which_scale_object_placement", defaultValue = "1")
|
||||
double scale
|
||||
// ,
|
||||
// @Param(description = "The scale interpolator to use", defaultValue = "none")
|
||||
// @Param(description = "The scale interpolator to use", descriptionKey = "iris.director.commandobject.param.scale_interpolator_use", defaultValue = "none")
|
||||
// IrisObjectPlacementScaleInterpolator interpolator
|
||||
) {
|
||||
IrisObject o = IrisData.loadAnyObject(object, data());
|
||||
double maxScale = Double.max(10 - o.getBlocks().size() / 10000d, 1);
|
||||
if (scale > maxScale) {
|
||||
sender().sendMessage(C.YELLOW + "Indicated scale exceeds maximum. Downscaled to maximum: " + maxScale);
|
||||
sender().sendMessage(IrisLanguage.text(BukkitCommandMessagesExtended.COMMAND_OBJECT_INDICATED_SCALE_EXCEEDS_MAXIMUM_DOWNSCALED_MAXIMUM, MessageArgument.untrusted("maxScale", maxScale)));
|
||||
scale = maxScale;
|
||||
}
|
||||
|
||||
@@ -552,70 +560,70 @@ public class CommandObject implements DirectorExecutor {
|
||||
if (WandSVC.isWand(wand)) {
|
||||
wand = newWand;
|
||||
player().getInventory().setItemInMainHand(wand);
|
||||
sender().sendMessage("Updated wand for " + "objects/" + o.getLoadKey() + ".iob ");
|
||||
sender().sendMessage(IrisLanguage.text(BukkitCommandMessagesExtended.COMMAND_OBJECT_UPDATED_WAND_OBJECTS_IOB, MessageArgument.untrusted("value", o.getLoadKey())));
|
||||
} else {
|
||||
int slot = WandSVC.findWand(player().getInventory());
|
||||
if (slot == -1) {
|
||||
player().getInventory().addItem(newWand);
|
||||
sender().sendMessage("Given new wand for " + "objects/" + o.getLoadKey() + ".iob ");
|
||||
sender().sendMessage(IrisLanguage.text(BukkitCommandMessagesExtended.COMMAND_OBJECT_GIVEN_NEW_WAND_OBJECTS_IOB, MessageArgument.untrusted("value", o.getLoadKey())));
|
||||
} else {
|
||||
player().getInventory().setItem(slot, newWand);
|
||||
sender().sendMessage("Updated wand for " + "objects/" + o.getLoadKey() + ".iob ");
|
||||
sender().sendMessage(IrisLanguage.text(BukkitCommandMessagesExtended.COMMAND_OBJECT_UPDATED_WAND_OBJECTS_IOB_2, MessageArgument.untrusted("value", o.getLoadKey())));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
sender().sendMessage(C.IRIS + "Placed " + object);
|
||||
sender().sendMessage(IrisLanguage.text(BukkitCommandMessagesExtended.COMMAND_OBJECT_PLACED, MessageArgument.untrusted("object", object)));
|
||||
}
|
||||
}
|
||||
|
||||
@Director(description = "Save an object")
|
||||
@Director(description = "Save an object", descriptionKey = "iris.director.commandobject.director.save_object")
|
||||
public void save(
|
||||
@Param(description = "The dimension to store the object in", contextual = true)
|
||||
@Param(description = "The dimension to store the object in", descriptionKey = "iris.director.commandobject.param.dimension_store_object", contextual = true)
|
||||
IrisDimension dimension,
|
||||
@Param(description = "The file to store it in, can use / for subfolders")
|
||||
@Param(description = "The file to store it in, can use / for subfolders", descriptionKey = "iris.director.commandobject.param.file_store_it_can_use_subfolders")
|
||||
String name,
|
||||
@Param(description = "Overwrite existing object files", defaultValue = "false", aliases = "force")
|
||||
@Param(description = "Overwrite existing object files", descriptionKey = "iris.director.commandobject.param.overwrite_existing_object_files", defaultValue = "false", aliases = "force")
|
||||
boolean overwrite,
|
||||
@Param(description = "Use legacy TileState serialization if possible", defaultValue = "true")
|
||||
@Param(description = "Use legacy TileState serialization if possible", descriptionKey = "iris.director.commandobject.param.use_legacy_tilestate_serialization_if_possible", defaultValue = "true")
|
||||
boolean legacy
|
||||
) {
|
||||
IrisObject o = WandSVC.createSchematic(player(), legacy);
|
||||
|
||||
if (o == null) {
|
||||
sender().sendMessage(C.YELLOW + "You need to hold your wand!");
|
||||
sender().sendMessage(IrisLanguage.text(BukkitCommandMessagesExtended.COMMAND_OBJECT_YOU_NEED_HOLD_YOUR_WAND));
|
||||
return;
|
||||
}
|
||||
|
||||
File file = Iris.service(StudioSVC.class).getWorkspaceFile(dimension.getLoadKey(), "objects", name + ".iob");
|
||||
|
||||
if (file.exists() && !overwrite) {
|
||||
sender().sendMessage(C.RED + "File already exists. Set overwrite=true to overwrite it.");
|
||||
sender().sendMessage(IrisLanguage.text(BukkitCommandMessagesExtended.COMMAND_OBJECT_FILE_ALREADY_EXISTS_SET_OVERWRITE_TRUE_OVERWRITE_IT));
|
||||
return;
|
||||
}
|
||||
try {
|
||||
o.write(file, sender());
|
||||
} catch (IOException e) {
|
||||
sender().sendMessage(C.RED + "Failed to save object because of an IOException: " + e.getMessage());
|
||||
sender().sendMessage(IrisLanguage.text(BukkitCommandMessagesExtended.COMMAND_OBJECT_FAILED_SAVE_OBJECT_BECAUSE_IOEXCEPTION, MessageArgument.untrusted("value", String.valueOf(e.getMessage()))));
|
||||
Iris.reportError(e);
|
||||
}
|
||||
|
||||
sender().playSound(Sound.BLOCK_ENCHANTMENT_TABLE_USE, 1f, 1.5f);
|
||||
sender().sendMessage(C.GREEN + "Successfully object to saved: " + dimension.getLoadKey() + "/objects/" + name);
|
||||
sender().sendMessage(IrisLanguage.text(BukkitCommandMessagesExtended.COMMAND_OBJECT_SUCCESSFULLY_OBJECT_SAVED_OBJECTS, MessageArgument.untrusted("value", dimension.getLoadKey()), MessageArgument.untrusted("name", name)));
|
||||
}
|
||||
|
||||
@Director(description = "Shift a selection in your looking direction")
|
||||
@Director(description = "Shift a selection in your looking direction", descriptionKey = "iris.director.commandobject.director.shift_selection_your_looking_direction")
|
||||
public void shift(
|
||||
@Param(description = "The amount to shift by", defaultValue = "1")
|
||||
@Param(description = "The amount to shift by", descriptionKey = "iris.director.commandobject.param.amount_shift_by", defaultValue = "1")
|
||||
int amount
|
||||
) {
|
||||
if (!WandSVC.isHoldingWand(player())) {
|
||||
sender().sendMessage("Hold your wand.");
|
||||
sender().sendMessage(IrisLanguage.text(BukkitCommandMessagesExtended.COMMAND_OBJECT_HOLD_YOUR_WAND_2));
|
||||
return;
|
||||
}
|
||||
|
||||
Location[] b = WandSVC.getCuboid(player());
|
||||
if (b == null || b[0] == null || b[1] == null) {
|
||||
sender().sendMessage("No area selected.");
|
||||
sender().sendMessage(IrisLanguage.text(BukkitCommandMessagesExtended.COMMAND_OBJECT_NO_AREA_SELECTED_2));
|
||||
return;
|
||||
}
|
||||
Location a1 = b[0].clone();
|
||||
@@ -634,52 +642,52 @@ public class CommandObject implements DirectorExecutor {
|
||||
sender().playSound(Sound.ENTITY_ITEM_FRAME_ROTATE_ITEM, 1f, 0.55f);
|
||||
}
|
||||
|
||||
@Director(description = "Undo a number of pastes", aliases = "u")
|
||||
@Director(description = "Undo a number of pastes", descriptionKey = "iris.director.commandobject.director.undo_number_pastes", aliases = "u")
|
||||
public void undo(
|
||||
@Param(description = "The amount of pastes to undo", defaultValue = "1")
|
||||
@Param(description = "The amount of pastes to undo", descriptionKey = "iris.director.commandobject.param.amount_pastes_undo", defaultValue = "1")
|
||||
int amount
|
||||
) {
|
||||
ObjectSVC service = Iris.service(ObjectSVC.class);
|
||||
int actualReverts = Math.min(service.getUndos().size(), amount);
|
||||
service.revertChanges(actualReverts);
|
||||
sender().sendMessage(C.BLUE + "Reverted " + actualReverts + C.BLUE +" pastes!");
|
||||
sender().sendMessage(IrisLanguage.text(BukkitCommandMessagesExtended.COMMAND_OBJECT_REVERTED_PASTES, MessageArgument.untrusted("actualReverts", actualReverts)));
|
||||
}
|
||||
|
||||
@Director(description = "Gets an object wand and grabs the current WorldEdit selection.", aliases = "we", origin = DirectorOrigin.PLAYER)
|
||||
@Director(description = "Gets an object wand and grabs the current WorldEdit selection.", descriptionKey = "iris.director.commandobject.director.gets_object_wand_grabs_current_worldedit_selection", aliases = "we", origin = DirectorOrigin.PLAYER)
|
||||
public void we() {
|
||||
if (!Bukkit.getPluginManager().isPluginEnabled("WorldEdit")) {
|
||||
sender().sendMessage(C.RED + "You can't get a WorldEdit selection without WorldEdit, you know.");
|
||||
sender().sendMessage(IrisLanguage.text(BukkitCommandMessagesExtended.COMMAND_OBJECT_YOU_CAN_T_GET_WORLDEDIT_SELECTION_WITHOUT_WORLDEDIT_YOU_KNOW));
|
||||
return;
|
||||
}
|
||||
|
||||
Cuboid locs = WorldEditLink.getSelection(sender().player());
|
||||
|
||||
if (locs == null) {
|
||||
sender().sendMessage(C.RED + "You don't have a WorldEdit selection in this world.");
|
||||
sender().sendMessage(IrisLanguage.text(BukkitCommandMessagesExtended.COMMAND_OBJECT_YOU_DON_T_HAVE_WORLDEDIT_SELECTION_THIS_WORLD));
|
||||
return;
|
||||
}
|
||||
|
||||
sender().player().getInventory().addItem(WandSVC.createWand(locs.getLowerNE(), locs.getUpperSW()));
|
||||
sender().sendMessage(C.GREEN + "A fresh wand with your current WorldEdit selection on it!");
|
||||
sender().sendMessage(IrisLanguage.text(BukkitCommandMessagesExtended.COMMAND_OBJECT_FRESH_WAND_WITH_YOUR_CURRENT_WORLDEDIT_SELECTION_ON_IT));
|
||||
}
|
||||
|
||||
@Director(description = "Get an object wand", sync = true)
|
||||
@Director(description = "Get an object wand", descriptionKey = "iris.director.commandobject.director.get_object_wand", sync = true)
|
||||
public void wand() {
|
||||
player().getInventory().addItem(WandSVC.createWand());
|
||||
sender().playSound(Sound.ITEM_ARMOR_EQUIP_NETHERITE, 1f, 1.5f);
|
||||
sender().sendMessage(C.GREEN + "Poof! Good luck building!");
|
||||
sender().sendMessage(IrisLanguage.text(BukkitCommandMessagesExtended.COMMAND_OBJECT_POOF_GOOD_LUCK_BUILDING));
|
||||
}
|
||||
|
||||
@Director(name = "x&y", description = "Autoselect up, down & out", sync = true)
|
||||
@Director(name = "x&y", description = "Autoselect up, down & out", descriptionKey = "iris.director.commandobject.director.autoselect_up_down_out", sync = true)
|
||||
public void xay() {
|
||||
if (!WandSVC.isHoldingWand(player())) {
|
||||
sender().sendMessage(C.YELLOW + "Hold your wand!");
|
||||
sender().sendMessage(IrisLanguage.text(BukkitCommandMessagesExtended.COMMAND_OBJECT_HOLD_YOUR_WAND_3));
|
||||
return;
|
||||
}
|
||||
|
||||
Location[] b = WandSVC.getCuboid(player());
|
||||
if (b == null || b[0] == null || b[1] == null) {
|
||||
sender().sendMessage("No area selected.");
|
||||
sender().sendMessage(IrisLanguage.text(BukkitCommandMessagesExtended.COMMAND_OBJECT_NO_AREA_SELECTED_3));
|
||||
return;
|
||||
}
|
||||
Location a1 = b[0].clone();
|
||||
@@ -718,19 +726,19 @@ public class CommandObject implements DirectorExecutor {
|
||||
player().getInventory().setItemInMainHand(WandSVC.createWand(b[0], b[1]));
|
||||
player().updateInventory();
|
||||
sender().playSound(Sound.ENTITY_ITEM_FRAME_ROTATE_ITEM, 1f, 0.55f);
|
||||
sender().sendMessage(C.GREEN + "Auto-select complete!");
|
||||
sender().sendMessage(IrisLanguage.text(BukkitCommandMessagesExtended.COMMAND_OBJECT_AUTO_SELECT_COMPLETE));
|
||||
}
|
||||
|
||||
@Director(name = "x+y", description = "Autoselect up & out", sync = true)
|
||||
@Director(name = "x+y", description = "Autoselect up & out", descriptionKey = "iris.director.commandobject.director.autoselect_up_out", sync = true)
|
||||
public void xpy() {
|
||||
if (!WandSVC.isHoldingWand(player())) {
|
||||
sender().sendMessage(C.YELLOW + "Hold your wand!");
|
||||
sender().sendMessage(IrisLanguage.text(BukkitCommandMessagesExtended.COMMAND_OBJECT_HOLD_YOUR_WAND_4));
|
||||
return;
|
||||
}
|
||||
|
||||
Location[] b = WandSVC.getCuboid(player());
|
||||
if (b == null || b[0] == null || b[1] == null) {
|
||||
sender().sendMessage("No area selected.");
|
||||
sender().sendMessage(IrisLanguage.text(BukkitCommandMessagesExtended.COMMAND_OBJECT_NO_AREA_SELECTED_4));
|
||||
return;
|
||||
}
|
||||
b[0].add(new Vector(0, 1, 0));
|
||||
@@ -759,6 +767,6 @@ public class CommandObject implements DirectorExecutor {
|
||||
player().getInventory().setItemInMainHand(WandSVC.createWand(b[0], b[1]));
|
||||
player().updateInventory();
|
||||
sender().playSound(Sound.ENTITY_ITEM_FRAME_ROTATE_ITEM, 1f, 0.55f);
|
||||
sender().sendMessage(C.GREEN + "Auto-select complete!");
|
||||
sender().sendMessage(IrisLanguage.text(BukkitCommandMessagesExtended.COMMAND_OBJECT_AUTO_SELECT_COMPLETE_2));
|
||||
}
|
||||
}
|
||||
|
||||
+86
-63
@@ -25,32 +25,36 @@ import art.arcane.iris.core.pack.PackValidationRegistry;
|
||||
import art.arcane.iris.core.pack.PackValidationResult;
|
||||
import art.arcane.iris.core.pack.PackValidator;
|
||||
import art.arcane.iris.util.common.director.DirectorExecutor;
|
||||
import art.arcane.iris.util.common.format.C;
|
||||
import art.arcane.iris.util.common.plugin.VolmitSender;
|
||||
import art.arcane.volmlib.util.director.annotations.Director;
|
||||
import art.arcane.volmlib.util.director.annotations.Param;
|
||||
import art.arcane.volmlib.util.localization.TextKey;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.List;
|
||||
|
||||
@Director(name = "pack", aliases = {"pk"}, description = "Pack validation and maintenance")
|
||||
import art.arcane.iris.core.localization.IrisLanguage;
|
||||
import art.arcane.iris.core.localization.BukkitCommandMessages;
|
||||
import art.arcane.volmlib.util.localization.MessageArgument;
|
||||
import art.arcane.iris.core.localization.BukkitRuntimeMessages;
|
||||
@Director(name = "pack", aliases = {"pk"}, description = "Pack validation and maintenance", descriptionKey = "iris.director.commandpack.director.pack_validation_maintenance")
|
||||
public class CommandPack implements DirectorExecutor {
|
||||
@Director(description = "Validate a pack (or all packs) and re-publish results", aliases = {"v"})
|
||||
@Director(description = "Validate a pack (or all packs) and re-publish results", descriptionKey = "iris.director.commandpack.director.validate_pack_all_packs_re_publish_results", aliases = {"v"})
|
||||
public void validate(
|
||||
@Param(description = "The pack folder name to validate (leave empty for all)", defaultValue = "")
|
||||
@Param(description = "The pack folder name to validate (leave empty for all)", descriptionKey = "iris.director.commandpack.param.pack_folder_name_validate_leave_empty_all", defaultValue = "")
|
||||
String pack
|
||||
) {
|
||||
VolmitSender s = sender();
|
||||
File packsRoot = Iris.instance.getDataFolder("packs");
|
||||
if (!packsRoot.isDirectory()) {
|
||||
s.sendMessage(C.RED + "packs/ folder not found.");
|
||||
s.sendMessage(IrisLanguage.text(BukkitRuntimeMessages.COMMAND_PACK_PACKS_FOLDER_NOT_FOUND));
|
||||
return;
|
||||
}
|
||||
|
||||
if (pack == null || pack.isBlank()) {
|
||||
File[] dirs = packsRoot.listFiles(File::isDirectory);
|
||||
if (dirs == null || dirs.length == 0) {
|
||||
s.sendMessage(C.YELLOW + "No packs to validate.");
|
||||
s.sendMessage(IrisLanguage.text(BukkitRuntimeMessages.COMMAND_PACK_NO_PACKS_VALIDATE));
|
||||
return;
|
||||
}
|
||||
int broken = 0;
|
||||
@@ -60,23 +64,23 @@ public class CommandPack implements DirectorExecutor {
|
||||
broken++;
|
||||
}
|
||||
}
|
||||
s.sendMessage(C.GREEN + "Validation complete. Broken packs: " + broken + "/" + dirs.length);
|
||||
s.sendMessage(IrisLanguage.text(BukkitRuntimeMessages.COMMAND_PACK_VALIDATION_COMPLETE_BROKEN_PACKS, MessageArgument.untrusted("broken", String.valueOf(broken)), MessageArgument.untrusted("value", String.valueOf(dirs.length))));
|
||||
return;
|
||||
}
|
||||
|
||||
File target = PackDirectoryResolver.resolveExisting(packsRoot, pack);
|
||||
if (target == null) {
|
||||
s.sendMessage(C.RED + "Pack '" + pack + "' not found under packs/.");
|
||||
s.sendMessage(IrisLanguage.text(BukkitRuntimeMessages.COMMAND_PACK_PACK_NOT_FOUND_UNDER_PACKS, MessageArgument.untrusted("pack", String.valueOf(pack))));
|
||||
return;
|
||||
}
|
||||
runValidate(s, target);
|
||||
}
|
||||
|
||||
@Director(description = "Preview or apply unused-resource cleanup", aliases = {"c"})
|
||||
@Director(description = "Preview or apply unused-resource cleanup", descriptionKey = "iris.director.commandpack.director.preview_apply_unused_resource_cleanup", aliases = {"c"})
|
||||
public void cleanup(
|
||||
@Param(description = "The pack folder name to clean")
|
||||
@Param(description = "The pack folder name to clean", descriptionKey = "iris.director.commandpack.param.pack_folder_name_clean")
|
||||
String pack,
|
||||
@Param(description = "preview or apply", defaultValue = "preview")
|
||||
@Param(description = "preview or apply", descriptionKey = "iris.director.commandpack.param.preview_apply", defaultValue = "preview")
|
||||
String mode
|
||||
) {
|
||||
VolmitSender s = sender();
|
||||
@@ -87,43 +91,47 @@ public class CommandPack implements DirectorExecutor {
|
||||
if ("apply".equalsIgnoreCase(mode)) {
|
||||
PackResourceCleanup.ApplyResult result = PackResourceCleanup.apply(packFolder);
|
||||
if (!result.success()) {
|
||||
s.sendMessage(C.RED + result.error());
|
||||
reportPaths(s, result.quarantinedPaths(), "still quarantined");
|
||||
s.sendMessage(IrisLanguage.text(
|
||||
BukkitRuntimeMessages.COMMAND_PACK_CLEANUP_FAILED,
|
||||
MessageArgument.untrusted("error", String.valueOf(result.error()))
|
||||
));
|
||||
reportPaths(s, result.quarantinedPaths(), BukkitRuntimeMessages.COMMAND_PACK_PATH_STILL_QUARANTINED);
|
||||
return;
|
||||
}
|
||||
if (!result.changed()) {
|
||||
s.sendMessage(C.GREEN + "No cleanup candidates found for pack '" + pack + "'.");
|
||||
s.sendMessage(IrisLanguage.text(BukkitRuntimeMessages.COMMAND_PACK_NO_CLEANUP_CANDIDATES_FOUND_PACK, MessageArgument.untrusted("pack", String.valueOf(pack))));
|
||||
return;
|
||||
}
|
||||
s.sendMessage(C.GREEN + "Quarantined " + result.quarantinedPaths().size()
|
||||
+ " cleanup candidate(s) under " + result.quarantinePath() + ".");
|
||||
reportPaths(s, result.quarantinedPaths(), "quarantined");
|
||||
s.sendMessage(IrisLanguage.text(BukkitRuntimeMessages.COMMAND_PACK_QUARANTINED_CLEANUP_CANDIDATE_S_UNDER, MessageArgument.untrusted("size", String.valueOf(result.quarantinedPaths().size())), MessageArgument.untrusted("quarantinePath", String.valueOf(result.quarantinePath()))));
|
||||
reportPaths(s, result.quarantinedPaths(), BukkitRuntimeMessages.COMMAND_PACK_PATH_QUARANTINED);
|
||||
return;
|
||||
}
|
||||
if (!"preview".equalsIgnoreCase(mode)) {
|
||||
s.sendMessage(C.RED + "Cleanup mode must be preview or apply.");
|
||||
s.sendMessage(IrisLanguage.text(BukkitRuntimeMessages.COMMAND_PACK_CLEANUP_MODE_MUST_BE_PREVIEW_APPLY));
|
||||
return;
|
||||
}
|
||||
PackResourceCleanup.Preview preview = PackResourceCleanup.preview(packFolder);
|
||||
if (!preview.success()) {
|
||||
s.sendMessage(C.RED + preview.error());
|
||||
s.sendMessage(IrisLanguage.text(
|
||||
BukkitRuntimeMessages.COMMAND_PACK_CLEANUP_FAILED,
|
||||
MessageArgument.untrusted("error", String.valueOf(preview.error()))
|
||||
));
|
||||
return;
|
||||
}
|
||||
if (!preview.hasCandidates()) {
|
||||
s.sendMessage(C.GREEN + "No cleanup candidates found for pack '" + pack + "'.");
|
||||
s.sendMessage(IrisLanguage.text(BukkitRuntimeMessages.COMMAND_PACK_NO_CLEANUP_CANDIDATES_FOUND_PACK_2, MessageArgument.untrusted("pack", String.valueOf(pack))));
|
||||
return;
|
||||
}
|
||||
s.sendMessage(C.YELLOW + "Cleanup preview for pack '" + pack + "': "
|
||||
+ preview.candidatePaths().size() + " candidate(s). No files were changed.");
|
||||
reportPaths(s, preview.candidatePaths(), "candidate");
|
||||
s.sendMessage(C.GRAY + "Run /iris pack cleanup " + pack + " mode=apply to quarantine these candidates after a fresh scan.");
|
||||
s.sendMessage(IrisLanguage.text(BukkitRuntimeMessages.COMMAND_PACK_CLEANUP_PREVIEW_PACK_CANDIDATE_S_NO_FILES_WERE_CHANGED, MessageArgument.untrusted("pack", String.valueOf(pack)), MessageArgument.untrusted("size", String.valueOf(preview.candidatePaths().size()))));
|
||||
reportPaths(s, preview.candidatePaths(), BukkitRuntimeMessages.COMMAND_PACK_PATH_CANDIDATE);
|
||||
s.sendMessage(IrisLanguage.text(BukkitRuntimeMessages.COMMAND_PACK_RUN_IRIS_PACK_CLEANUP_MODE_APPLY_QUARANTINE_THESE_CANDIDATES_AFTER_FRESH_SCAN, MessageArgument.untrusted("pack", String.valueOf(pack))));
|
||||
}
|
||||
|
||||
@Director(description = "Preview or apply restoration of the latest quarantine", aliases = {"r"})
|
||||
@Director(description = "Preview or apply restoration of the latest quarantine", descriptionKey = "iris.director.commandpack.director.preview_apply_restoration_latest_quarantine", aliases = {"r"})
|
||||
public void restore(
|
||||
@Param(description = "The pack folder name to restore")
|
||||
@Param(description = "The pack folder name to restore", descriptionKey = "iris.director.commandpack.param.pack_folder_name_restore")
|
||||
String pack,
|
||||
@Param(description = "preview or apply", defaultValue = "preview")
|
||||
@Param(description = "preview or apply", descriptionKey = "iris.director.commandpack.param.preview_apply_2", defaultValue = "preview")
|
||||
String mode
|
||||
) {
|
||||
VolmitSender s = sender();
|
||||
@@ -134,69 +142,78 @@ public class CommandPack implements DirectorExecutor {
|
||||
if ("apply".equalsIgnoreCase(mode)) {
|
||||
PackResourceCleanup.RestoreResult result = PackResourceCleanup.restoreLatest(packFolder);
|
||||
if (!result.conflicts().isEmpty()) {
|
||||
s.sendMessage(C.RED + "Restore refused because " + result.conflicts().size() + " destination(s) already exist.");
|
||||
reportPaths(s, result.conflicts(), "conflict");
|
||||
s.sendMessage(IrisLanguage.text(BukkitRuntimeMessages.COMMAND_PACK_RESTORE_REFUSED_BECAUSE_DESTINATION_S_ALREADY_EXIST, MessageArgument.untrusted("size", String.valueOf(result.conflicts().size()))));
|
||||
reportPaths(s, result.conflicts(), BukkitRuntimeMessages.COMMAND_PACK_PATH_CONFLICT);
|
||||
return;
|
||||
}
|
||||
if (!result.success()) {
|
||||
s.sendMessage(C.RED + result.error());
|
||||
s.sendMessage(IrisLanguage.text(
|
||||
BukkitRuntimeMessages.COMMAND_PACK_RESTORE_FAILED,
|
||||
MessageArgument.untrusted("error", String.valueOf(result.error()))
|
||||
));
|
||||
return;
|
||||
}
|
||||
if (!result.changed()) {
|
||||
s.sendMessage(C.YELLOW + "Nothing to restore for pack '" + pack + "'.");
|
||||
s.sendMessage(IrisLanguage.text(BukkitRuntimeMessages.COMMAND_PACK_NOTHING_RESTORE_PACK, MessageArgument.untrusted("pack", String.valueOf(pack))));
|
||||
return;
|
||||
}
|
||||
s.sendMessage(C.GREEN + "Restored " + result.restoredPaths().size()
|
||||
+ " file(s) from " + result.dumpPath() + ".");
|
||||
reportPaths(s, result.restoredPaths(), "restored");
|
||||
s.sendMessage(IrisLanguage.text(BukkitRuntimeMessages.COMMAND_PACK_RESTORED_FILE_S_FROM, MessageArgument.untrusted("size", String.valueOf(result.restoredPaths().size())), MessageArgument.untrusted("dumpPath", String.valueOf(result.dumpPath()))));
|
||||
reportPaths(s, result.restoredPaths(), BukkitRuntimeMessages.COMMAND_PACK_PATH_RESTORED);
|
||||
return;
|
||||
}
|
||||
if (!"preview".equalsIgnoreCase(mode)) {
|
||||
s.sendMessage(C.RED + "Restore mode must be preview or apply.");
|
||||
s.sendMessage(IrisLanguage.text(BukkitRuntimeMessages.COMMAND_PACK_RESTORE_MODE_MUST_BE_PREVIEW_APPLY));
|
||||
return;
|
||||
}
|
||||
PackResourceCleanup.RestorePreview preview = PackResourceCleanup.previewRestore(packFolder);
|
||||
if (!preview.success()) {
|
||||
s.sendMessage(C.RED + preview.error());
|
||||
s.sendMessage(IrisLanguage.text(
|
||||
BukkitRuntimeMessages.COMMAND_PACK_RESTORE_FAILED,
|
||||
MessageArgument.untrusted("error", String.valueOf(preview.error()))
|
||||
));
|
||||
return;
|
||||
}
|
||||
if (!preview.hasFiles()) {
|
||||
s.sendMessage(C.YELLOW + "Nothing to restore for pack '" + pack + "'.");
|
||||
s.sendMessage(IrisLanguage.text(BukkitRuntimeMessages.COMMAND_PACK_NOTHING_RESTORE_PACK_2, MessageArgument.untrusted("pack", String.valueOf(pack))));
|
||||
return;
|
||||
}
|
||||
s.sendMessage(C.YELLOW + "Restore preview for " + preview.dumpPath() + ": "
|
||||
+ preview.filePaths().size() + " file(s). No files were changed.");
|
||||
reportPaths(s, preview.filePaths(), "file");
|
||||
s.sendMessage(IrisLanguage.text(BukkitRuntimeMessages.COMMAND_PACK_RESTORE_PREVIEW_FILE_S_NO_FILES_WERE_CHANGED, MessageArgument.untrusted("dumpPath", String.valueOf(preview.dumpPath())), MessageArgument.untrusted("size", String.valueOf(preview.filePaths().size()))));
|
||||
reportPaths(s, preview.filePaths(), BukkitRuntimeMessages.COMMAND_PACK_PATH_FILE);
|
||||
if (!preview.conflicts().isEmpty()) {
|
||||
s.sendMessage(C.RED + "Restore is blocked by " + preview.conflicts().size() + " existing destination(s).");
|
||||
reportPaths(s, preview.conflicts(), "conflict");
|
||||
s.sendMessage(IrisLanguage.text(BukkitRuntimeMessages.COMMAND_PACK_RESTORE_IS_BLOCKED_BY_EXISTING_DESTINATION_S, MessageArgument.untrusted("size", String.valueOf(preview.conflicts().size()))));
|
||||
reportPaths(s, preview.conflicts(), BukkitRuntimeMessages.COMMAND_PACK_PATH_CONFLICT);
|
||||
return;
|
||||
}
|
||||
s.sendMessage(C.GRAY + "Run /iris pack restore " + pack + " mode=apply to restore after a fresh conflict check.");
|
||||
s.sendMessage(IrisLanguage.text(BukkitRuntimeMessages.COMMAND_PACK_RUN_IRIS_PACK_RESTORE_MODE_APPLY_RESTORE_AFTER_FRESH_CONFLICT_CHECK, MessageArgument.untrusted("pack", String.valueOf(pack))));
|
||||
}
|
||||
|
||||
@Director(description = "Show cached validation status for a pack", aliases = {"s"})
|
||||
@Director(description = "Show cached validation status for a pack", descriptionKey = "iris.director.commandpack.director.show_cached_validation_status_pack", aliases = {"s"})
|
||||
public void status(
|
||||
@Param(description = "The pack folder name", defaultValue = "")
|
||||
@Param(description = "The pack folder name", descriptionKey = "iris.director.commandpack.param.pack_folder_name", defaultValue = "")
|
||||
String pack
|
||||
) {
|
||||
VolmitSender s = sender();
|
||||
if (pack == null || pack.isBlank()) {
|
||||
if (PackValidationRegistry.snapshot().isEmpty()) {
|
||||
s.sendMessage(C.YELLOW + "No validation results recorded. Run /iris pack validate first.");
|
||||
s.sendMessage(IrisLanguage.text(BukkitRuntimeMessages.COMMAND_PACK_NO_VALIDATION_RESULTS_RECORDED_RUN_IRIS_PACK_VALIDATE_FIRST));
|
||||
return;
|
||||
}
|
||||
PackValidationRegistry.snapshot().forEach((name, result) -> {
|
||||
String tag = result.isLoadable() ? (C.GREEN + "OK") : (C.RED + "BROKEN");
|
||||
s.sendMessage(tag + C.RESET + " " + name
|
||||
+ C.GRAY + " (blocking=" + result.getBlockingErrors().size()
|
||||
+ ", warnings=" + result.getWarnings().size() + ")");
|
||||
TextKey key = result.isLoadable()
|
||||
? BukkitRuntimeMessages.COMMAND_PACK_STATUS_OK
|
||||
: BukkitRuntimeMessages.COMMAND_PACK_STATUS_BROKEN;
|
||||
s.sendMessage(IrisLanguage.text(
|
||||
key,
|
||||
MessageArgument.untrusted("pack", name),
|
||||
MessageArgument.trusted("blocking", result.getBlockingErrors().size()),
|
||||
MessageArgument.trusted("warnings", result.getWarnings().size())
|
||||
));
|
||||
});
|
||||
return;
|
||||
}
|
||||
PackValidationResult result = PackValidationRegistry.get(pack);
|
||||
if (result == null) {
|
||||
s.sendMessage(C.YELLOW + "No validation result for '" + pack + "'. Run /iris pack validate " + pack + ".");
|
||||
s.sendMessage(IrisLanguage.text(BukkitRuntimeMessages.COMMAND_PACK_NO_VALIDATION_RESULT_RUN_IRIS_PACK_VALIDATE, MessageArgument.untrusted("pack", String.valueOf(pack)), MessageArgument.untrusted("pack2", String.valueOf(pack))));
|
||||
return;
|
||||
}
|
||||
reportResult(s, result);
|
||||
@@ -210,50 +227,56 @@ public class CommandPack implements DirectorExecutor {
|
||||
return result;
|
||||
} catch (Throwable e) {
|
||||
Iris.reportError("Pack validation failed for '" + packFolder.getName() + "'", e);
|
||||
s.sendMessage(C.RED + "Validation of '" + packFolder.getName() + "' failed: " + e.getMessage());
|
||||
s.sendMessage(IrisLanguage.text(BukkitRuntimeMessages.COMMAND_PACK_VALIDATION_FAILED, MessageArgument.untrusted("name", String.valueOf(packFolder.getName())), MessageArgument.untrusted("error", String.valueOf(e.getMessage()))));
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private void reportResult(VolmitSender s, PackValidationResult result) {
|
||||
if (result.isLoadable()) {
|
||||
s.sendMessage(C.GREEN + "Pack '" + result.getPackName() + "' is loadable."
|
||||
+ C.GRAY + " (warnings=" + result.getWarnings().size() + ")");
|
||||
s.sendMessage(IrisLanguage.text(BukkitRuntimeMessages.COMMAND_PACK_PACK_IS_LOADABLE_WARNINGS, MessageArgument.untrusted("packName", String.valueOf(result.getPackName())), MessageArgument.untrusted("size", String.valueOf(result.getWarnings().size()))));
|
||||
} else {
|
||||
s.sendMessage(C.RED + "Pack '" + result.getPackName() + "' is BROKEN:");
|
||||
s.sendMessage(IrisLanguage.text(BukkitRuntimeMessages.COMMAND_PACK_PACK_IS_BROKEN, MessageArgument.untrusted("packName", String.valueOf(result.getPackName()))));
|
||||
for (String reason : result.getBlockingErrors()) {
|
||||
s.sendMessage(C.RED + " - " + reason);
|
||||
s.sendMessage(IrisLanguage.text(BukkitRuntimeMessages.COMMAND_PACK_MESSAGE, MessageArgument.untrusted("reason", String.valueOf(reason))));
|
||||
}
|
||||
}
|
||||
int wMax = Math.min(10, result.getWarnings().size());
|
||||
for (int i = 0; i < wMax; i++) {
|
||||
s.sendMessage(C.YELLOW + " ! " + result.getWarnings().get(i));
|
||||
s.sendMessage(IrisLanguage.text(BukkitRuntimeMessages.COMMAND_PACK_MESSAGE_2, MessageArgument.untrusted("value", String.valueOf(result.getWarnings().get(i)))));
|
||||
}
|
||||
if (result.getWarnings().size() > wMax) {
|
||||
s.sendMessage(C.GRAY + " ... and " + (result.getWarnings().size() - wMax) + " more warning(s).");
|
||||
s.sendMessage(IrisLanguage.text(
|
||||
BukkitRuntimeMessages.COMMAND_PACK_MORE_WARNING_S,
|
||||
MessageArgument.trusted("count", result.getWarnings().size() - wMax)
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
private File findPack(VolmitSender sender, String pack) {
|
||||
if (pack == null || pack.isBlank()) {
|
||||
sender.sendMessage(C.RED + "You must specify a pack name.");
|
||||
sender.sendMessage(IrisLanguage.text(BukkitCommandMessages.COMMAND_PACK_YOU_MUST_SPECIFY_PACK_NAME));
|
||||
return null;
|
||||
}
|
||||
File packFolder = PackDirectoryResolver.resolveExisting(Iris.instance.getDataFolder("packs"), pack);
|
||||
if (packFolder == null) {
|
||||
sender.sendMessage(C.RED + "Pack '" + pack + "' not found under packs/.");
|
||||
sender.sendMessage(IrisLanguage.text(BukkitCommandMessages.COMMAND_PACK_PACK_NOT_FOUND_UNDER_PACKS, MessageArgument.untrusted("pack", pack)));
|
||||
return null;
|
||||
}
|
||||
return packFolder;
|
||||
}
|
||||
|
||||
private void reportPaths(VolmitSender sender, List<String> paths, String label) {
|
||||
private void reportPaths(VolmitSender sender, List<String> paths, TextKey label) {
|
||||
int max = Math.min(10, paths.size());
|
||||
for (int i = 0; i < max; i++) {
|
||||
sender.sendMessage(C.GRAY + " - " + label + ": " + paths.get(i));
|
||||
sender.sendMessage(IrisLanguage.text(
|
||||
BukkitCommandMessages.COMMAND_PACK_MESSAGE,
|
||||
MessageArgument.untrusted("label", IrisLanguage.text(label)),
|
||||
MessageArgument.untrusted("value", paths.get(i))
|
||||
));
|
||||
}
|
||||
if (paths.size() > max) {
|
||||
sender.sendMessage(C.GRAY + " ... and " + (paths.size() - max) + " more.");
|
||||
sender.sendMessage(IrisLanguage.text(BukkitCommandMessages.COMMAND_PACK_MORE, MessageArgument.untrusted("value", (paths.size() - max))));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+25
-27
@@ -31,34 +31,38 @@ import art.arcane.volmlib.util.math.Position2;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
@Director(name = "pregen", aliases = "pregenerate", description = "Pregenerate your Iris worlds!")
|
||||
import art.arcane.iris.core.localization.IrisLanguage;
|
||||
import art.arcane.iris.core.localization.BukkitCommandMessagesExtended;
|
||||
import art.arcane.iris.core.localization.RuntimeUiMessages;
|
||||
import art.arcane.volmlib.util.localization.MessageArgument;
|
||||
@Director(name = "pregen", aliases = "pregenerate", description = "Pregenerate your Iris worlds!", descriptionKey = "iris.director.commandpregen.director.pregenerate_your_iris_worlds")
|
||||
public class CommandPregen implements DirectorExecutor {
|
||||
@Director(description = "Pregenerate a world")
|
||||
@Director(description = "Pregenerate a world", descriptionKey = "iris.director.commandpregen.director.pregenerate_world")
|
||||
public void start(
|
||||
@Param(description = "The radius of the pregen in blocks", aliases = "size")
|
||||
@Param(description = "The radius of the pregen in blocks", descriptionKey = "iris.director.commandpregen.param.radius_pregen_blocks", aliases = "size")
|
||||
int radius,
|
||||
@Param(description = "The world to pregen", contextual = true)
|
||||
@Param(description = "The world to pregen", descriptionKey = "iris.director.commandpregen.param.world_pregen", contextual = true)
|
||||
World world,
|
||||
@Param(aliases = "middle", description = "The center location of the pregen. Use \"me\" for your current location", defaultValue = "0,0")
|
||||
@Param(aliases = "middle", description = "The center location of the pregen. Use \"me\" for your current location", descriptionKey = "iris.director.commandpregen.param.center_location_pregen_use_me_your_current_location", defaultValue = "0,0")
|
||||
Vector center,
|
||||
@Param(description = "Open the Iris pregen gui", defaultValue = "true")
|
||||
@Param(description = "Open the Iris pregen gui", descriptionKey = "iris.director.commandpregen.param.open_iris_pregen_gui", defaultValue = "true")
|
||||
boolean gui,
|
||||
@Param(name = "serial", description = "Generate only one chunk at a time", defaultValue = "false")
|
||||
@Param(name = "serial", description = "Generate only one chunk at a time", descriptionKey = "iris.director.commandpregen.param.generate_only_one_chunk_at_time", defaultValue = "false")
|
||||
boolean serial
|
||||
) {
|
||||
if (radius <= 0) {
|
||||
sender().sendMessage(C.RED + "Pregen radius must be greater than zero blocks.");
|
||||
sender().sendMessage(IrisLanguage.text(BukkitCommandMessagesExtended.COMMAND_PREGEN_PREGEN_RADIUS_MUST_BE_GREATER_THAN_ZERO_BLOCKS));
|
||||
return;
|
||||
}
|
||||
if (serial && !IrisToolbelt.supportsStrictSerialPregeneration()) {
|
||||
sender().sendMessage(C.RED + "Strict serial pregeneration requires Paper or a Paper-compatible server.");
|
||||
sender().sendMessage(IrisLanguage.text(BukkitCommandMessagesExtended.COMMAND_PREGEN_STRICT_SERIAL_PREGENERATION_REQUIRES_PAPER_PAPER_COMPATIBLE_SERVER));
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
if (sender().isPlayer() && access() == null) {
|
||||
sender().sendMessage(C.RED + "The engine access for this world is null!");
|
||||
sender().sendMessage(C.RED + "Please make sure the world is loaded & the engine is initialized. Generate a new chunk, for example.");
|
||||
sender().sendMessage(IrisLanguage.text(BukkitCommandMessagesExtended.COMMAND_PREGEN_ENGINE_ACCESS_THIS_WORLD_IS_NULL));
|
||||
sender().sendMessage(IrisLanguage.text(BukkitCommandMessagesExtended.COMMAND_PREGEN_PLEASE_MAKE_SURE_WORLD_IS_LOADED_ENGINE_IS_INITIALIZED_GENERATE));
|
||||
}
|
||||
PregenTask task = PregenTask
|
||||
.builder()
|
||||
@@ -76,48 +80,42 @@ public class CommandPregen implements DirectorExecutor {
|
||||
sender().sendMessage(msg);
|
||||
Iris.info(msg);
|
||||
} catch (Throwable e) {
|
||||
sender().sendMessage(C.RED + "Failed to start pregeneration. See console for details.");
|
||||
sender().sendMessage(IrisLanguage.text(BukkitCommandMessagesExtended.COMMAND_PREGEN_FAILED_START_PREGENERATION_SEE_CONSOLE_DETAILS));
|
||||
Iris.reportError(e);
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@Director(description = "Stop the active pregeneration task", aliases = "x")
|
||||
@Director(description = "Stop the active pregeneration task", descriptionKey = "iris.director.commandpregen.director.stop_active_pregeneration_task", aliases = "x")
|
||||
public void stop() {
|
||||
if (PregeneratorJob.shutdownInstance()) {
|
||||
String message = C.BLUE + "Pregen stop requested; finishing active work before cancellation.";
|
||||
sender().sendMessage(message);
|
||||
Iris.info(message);
|
||||
} else {
|
||||
sender().sendMessage(C.YELLOW + "No active pregeneration tasks to stop");
|
||||
sender().sendMessage(IrisLanguage.text(BukkitCommandMessagesExtended.COMMAND_PREGEN_NO_ACTIVE_PREGENERATION_TASKS_STOP));
|
||||
}
|
||||
}
|
||||
|
||||
@Director(description = "Pause / continue the active pregeneration task", aliases = {"resume"})
|
||||
@Director(description = "Pause / continue the active pregeneration task", descriptionKey = "iris.director.commandpregen.director.pause_continue_active_pregeneration_task", aliases = {"resume"})
|
||||
public void pause() {
|
||||
if (PregeneratorJob.pauseResume()) {
|
||||
sender().sendMessage(C.GREEN + "Paused/unpaused pregeneration task, now: " + (PregeneratorJob.isPaused() ? "Paused" : "Running") + ".");
|
||||
sender().sendMessage(IrisLanguage.text(BukkitCommandMessagesExtended.COMMAND_PREGEN_PAUSED_UNPAUSED_PREGENERATION_TASK_NOW, MessageArgument.trusted("value", IrisLanguage.text(PregeneratorJob.isPaused() ? RuntimeUiMessages.STATUS_PAUSED : RuntimeUiMessages.STATUS_RUNNING))));
|
||||
} else {
|
||||
sender().sendMessage(C.YELLOW + "No active pregeneration tasks to pause/unpause.");
|
||||
sender().sendMessage(IrisLanguage.text(BukkitCommandMessagesExtended.COMMAND_PREGEN_NO_ACTIVE_PREGENERATION_TASKS_PAUSE_UNPAUSE));
|
||||
}
|
||||
}
|
||||
|
||||
@Director(description = "Show the active pregeneration status")
|
||||
@Director(description = "Show the active pregeneration status", descriptionKey = "iris.director.commandpregen.director.show_active_pregeneration_status")
|
||||
public void status() {
|
||||
PregeneratorJob.PregenProgress progress = PregeneratorJob.progressSnapshot();
|
||||
if (progress == null) {
|
||||
sender().sendMessage(C.YELLOW + "No active pregeneration task.");
|
||||
sender().sendMessage(IrisLanguage.text(BukkitCommandMessagesExtended.COMMAND_PREGEN_NO_ACTIVE_PREGENERATION_TASK));
|
||||
return;
|
||||
}
|
||||
|
||||
String world = progress.worldName() == null ? "?" : progress.worldName();
|
||||
sender().sendMessage(C.GREEN + "Pregen " + C.GOLD + world + C.GREEN + ": " + C.GOLD + Form.f(progress.generated()) + "/" + Form.f(progress.totalChunks())
|
||||
+ C.GREEN + " (" + C.GOLD + String.format("%.1f", progress.percent()) + "%" + C.GREEN + ")"
|
||||
+ (progress.paused() ? C.YELLOW + " PAUSED" : ""));
|
||||
sender().sendMessage(C.GREEN + "Speed: " + C.GOLD + Form.f((int) progress.chunksPerSecond()) + "/s" + C.GREEN
|
||||
+ " ETA: " + C.GOLD + Form.duration(progress.eta(), 2) + C.GREEN
|
||||
+ " Elapsed: " + C.GOLD + Form.duration(progress.elapsed(), 2) + C.GREEN
|
||||
+ " Method: " + C.GOLD + progress.method()
|
||||
+ (progress.failed() > 0 ? C.RED + " Failed: " + Form.f(progress.failed()) : ""));
|
||||
sender().sendMessage(IrisLanguage.text(BukkitCommandMessagesExtended.COMMAND_PREGEN_PREGEN, MessageArgument.untrusted("world", world), MessageArgument.untrusted("value", Form.f(progress.generated())), MessageArgument.untrusted("value2", Form.f(progress.totalChunks())), MessageArgument.untrusted("value3", String.format("%.1f", progress.percent())), MessageArgument.untrusted("value4", (progress.paused() ? C.YELLOW + " PAUSED" : ""))));
|
||||
sender().sendMessage(IrisLanguage.text(BukkitCommandMessagesExtended.COMMAND_PREGEN_SPEED_S_ETA_ELAPSED_METHOD, MessageArgument.untrusted("value", Form.f((int) progress.chunksPerSecond())), MessageArgument.untrusted("value2", Form.duration(progress.eta(), 2)), MessageArgument.untrusted("value3", Form.duration(progress.elapsed(), 2)), MessageArgument.untrusted("value4", progress.method()), MessageArgument.untrusted("value5", (progress.failed() > 0 ? C.RED + " Failed: " + Form.f(progress.failed()) : ""))));
|
||||
}
|
||||
}
|
||||
|
||||
+39
-37
@@ -67,67 +67,71 @@ import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
@Director(name = "structure", aliases = {"struct", "str"}, description = "Iris structure tools (index, import, info)")
|
||||
import art.arcane.iris.core.localization.IrisLanguage;
|
||||
import art.arcane.iris.core.localization.BukkitCommandMessages;
|
||||
import art.arcane.volmlib.util.localization.MessageArgument;
|
||||
import art.arcane.iris.core.localization.BukkitCommandMessagesExtended;
|
||||
@Director(name = "structure", aliases = {"struct", "str"}, description = "Iris structure tools (index, import, info)", descriptionKey = "iris.director.commandstructure.director.iris_structure_tools_index_import_info")
|
||||
public class CommandStructure implements DirectorExecutor {
|
||||
@Director(description = "Regenerate structure-index.json listing all vanilla, datapack & iris structures", aliases = {"ls"}, origin = DirectorOrigin.BOTH)
|
||||
@Director(description = "Regenerate structure-index.json listing all vanilla, datapack & iris structures", descriptionKey = "iris.director.commandstructure.director.regenerate_structure_index_json_listing_all_vanilla_datapack_iris_structures", aliases = {"ls"}, origin = DirectorOrigin.BOTH)
|
||||
public void list(
|
||||
@Param(description = "The dimension whose pack to index", aliases = "dim")
|
||||
@Param(description = "The dimension whose pack to index", descriptionKey = "iris.director.commandstructure.param.dimension_whose_pack_index", aliases = "dim")
|
||||
IrisDimension dimension
|
||||
) {
|
||||
IrisData data = dimension.getLoader();
|
||||
if (data == null) {
|
||||
sender().sendMessage(C.RED + "Could not resolve the pack for dimension " + dimension.getLoadKey());
|
||||
sender().sendMessage(IrisLanguage.text(BukkitCommandMessagesExtended.COMMAND_STRUCTURE_COULD_NOT_RESOLVE_PACK_DIMENSION, MessageArgument.untrusted("value", dimension.getLoadKey())));
|
||||
return;
|
||||
}
|
||||
File file = StructureIndexService.write(data);
|
||||
sender().sendMessage(C.GREEN + "Wrote structure index: " + C.WHITE + file.getPath());
|
||||
sender().sendMessage(IrisLanguage.text(BukkitCommandMessagesExtended.COMMAND_STRUCTURE_WROTE_STRUCTURE_INDEX, MessageArgument.untrusted("value", file.getPath())));
|
||||
}
|
||||
|
||||
@Director(name = "import", description = "Import EVERY structure - vanilla AND ingested datapacks - into this pack as editable Iris resources, always overwriting. Rebuilds jigsaw structures (villages, outposts, datapack jigsaws) as editable pool/piece graphs, imports every structure template NBT as an object, and assembles the multi-template structures (shipwrecks, ruined portals, ocean ruins, nether fossils). Run after ingesting a datapack and restarting. Regenerate chunks or use a fresh world for the imported copies to place.", aliases = {"import-all", "reimport", "imp", "all"}, origin = DirectorOrigin.BOTH)
|
||||
@Director(name = "import", description = "Import EVERY structure - vanilla AND ingested datapacks - into this pack as editable Iris resources, always overwriting. Rebuilds jigsaw structures (villages, outposts, datapack jigsaws) as editable pool/piece graphs, imports every structure template NBT as an object, and assembles the multi-template structures (shipwrecks, ruined portals, ocean ruins, nether fossils). Run after ingesting a datapack and restarting. Regenerate chunks or use a fresh world for the imported copies to place.", descriptionKey = "iris.director.commandstructure.director.import_every_structure_vanilla_ingested_datapacks_into_this_pack_as_editable_iris", aliases = {"import-all", "reimport", "imp", "all"}, origin = DirectorOrigin.BOTH)
|
||||
public void importAll(
|
||||
@Param(description = "The dimension whose pack to import into", aliases = "dim")
|
||||
@Param(description = "The dimension whose pack to import into", descriptionKey = "iris.director.commandstructure.param.dimension_whose_pack_import_into", aliases = "dim")
|
||||
IrisDimension dimension
|
||||
) {
|
||||
IrisData data = dimension.getLoader();
|
||||
if (data == null) {
|
||||
sender().sendMessage(C.RED + "Could not resolve the pack for dimension " + dimension.getLoadKey());
|
||||
sender().sendMessage(IrisLanguage.text(BukkitCommandMessagesExtended.COMMAND_STRUCTURE_COULD_NOT_RESOLVE_PACK_DIMENSION_2, MessageArgument.untrusted("value", dimension.getLoadKey())));
|
||||
return;
|
||||
}
|
||||
sender().sendMessage(C.GREEN + "Importing all vanilla & datapack structures into " + C.WHITE + dimension.getLoadKey() + C.GREEN + " (overwrite)...");
|
||||
sender().sendMessage(IrisLanguage.text(BukkitCommandMessagesExtended.COMMAND_STRUCTURE_IMPORTING_ALL_VANILLA_DATAPACK_STRUCTURES_INTO_OVERWRITE, MessageArgument.untrusted("value", dimension.getLoadKey())));
|
||||
BulkStructureImporter.Report jigsaws = BulkStructureImporter.importAllVanilla(data, StructureImporter.Mode.OVERWRITE, true, sender());
|
||||
BulkStructureImporter.Report templates = BulkStructureImporter.importAllTemplates(data, StructureImporter.Mode.OVERWRITE, sender());
|
||||
BulkStructureImporter.Report groups = BulkStructureImporter.importTemplateGroups(data, StructureImporter.Mode.OVERWRITE, sender());
|
||||
StructureCaptureImporter.Report captured = StructureCaptureImporter.importAllStructures(data, StructureImporter.Mode.OVERWRITE, sender());
|
||||
int imported = jigsaws.imported() + templates.imported() + groups.imported() + captured.imported();
|
||||
int failed = jigsaws.failed() + templates.failed() + groups.failed() + captured.failed();
|
||||
sender().sendMessage(C.GREEN + "Import complete: " + C.WHITE + imported + C.GREEN + " structures/objects written, " + C.WHITE + failed + C.GREEN + " failed.");
|
||||
sender().sendMessage(C.GRAY + "Reference them from a biome/region/dimension 'structures' list, or run /iris structure list " + dimension.getLoadKey() + " to refresh the index. Regenerate chunks for changes to take effect.");
|
||||
sender().sendMessage(IrisLanguage.text(BukkitCommandMessagesExtended.COMMAND_STRUCTURE_IMPORT_COMPLETE_STRUCTURES_OBJECTS_WRITTEN_FAILED, MessageArgument.untrusted("imported", imported), MessageArgument.untrusted("failed", failed)));
|
||||
sender().sendMessage(IrisLanguage.text(BukkitCommandMessagesExtended.COMMAND_STRUCTURE_REFERENCE_THEM_FROM_BIOME_REGION_DIMENSION_STRUCTURES_LIST_RUN_IRIS, MessageArgument.untrusted("value", dimension.getLoadKey())));
|
||||
}
|
||||
|
||||
@Director(name = "capture", description = "Capture code-generated structures that have no NBT template (swamp huts, igloos, etc.) into editable Iris objects by generating each one in a throwaway scratch world and reading back its blocks. Skips structures that already import as a structure, structures wider/taller than the capture cap (strongholds, mansions, monuments stay vanilla), and anything that will not generate in a flat overworld. Each captured structure becomes a single-piece Iris structure you can place from a biome/region/dimension 'structures' list. Runs automatically as the last pass of /iris structure import.", aliases = {"cap"}, origin = DirectorOrigin.BOTH)
|
||||
@Director(name = "capture", description = "Capture code-generated structures that have no NBT template (swamp huts, igloos, etc.) into editable Iris objects by generating each one in a throwaway scratch world and reading back its blocks. Skips structures that already import as a structure, structures wider/taller than the capture cap (strongholds, mansions, monuments stay vanilla), and anything that will not generate in a flat overworld. Each captured structure becomes a single-piece Iris structure you can place from a biome/region/dimension 'structures' list. Runs automatically as the last pass of /iris structure import.", descriptionKey = "iris.director.commandstructure.director.capture_code_generated_structures_that_have_no_nbt_template_swamp_huts_igloos", aliases = {"cap"}, origin = DirectorOrigin.BOTH)
|
||||
public void capture(
|
||||
@Param(description = "The dimension whose pack to capture into", aliases = "dim")
|
||||
@Param(description = "The dimension whose pack to capture into", descriptionKey = "iris.director.commandstructure.param.dimension_whose_pack_capture_into", aliases = "dim")
|
||||
IrisDimension dimension
|
||||
) {
|
||||
IrisData data = dimension.getLoader();
|
||||
if (data == null) {
|
||||
sender().sendMessage(C.RED + "Could not resolve the pack for dimension " + dimension.getLoadKey());
|
||||
sender().sendMessage(IrisLanguage.text(BukkitCommandMessagesExtended.COMMAND_STRUCTURE_COULD_NOT_RESOLVE_PACK_DIMENSION_3, MessageArgument.untrusted("value", dimension.getLoadKey())));
|
||||
return;
|
||||
}
|
||||
StructureCaptureImporter.Report report = StructureCaptureImporter.importAllStructures(data, StructureImporter.Mode.OVERWRITE, sender());
|
||||
sender().sendMessage(C.GRAY + "Captured " + report.imported() + " structures. Place them from a 'structures' list and regenerate chunks. Delete a structures/*.json to re-capture it.");
|
||||
sender().sendMessage(IrisLanguage.text(BukkitCommandMessagesExtended.COMMAND_STRUCTURE_CAPTURED_STRUCTURES_PLACE_THEM_FROM_STRUCTURES_LIST_REGENERATE_CHUNKS_DELETE, MessageArgument.untrusted("value", report.imported())));
|
||||
}
|
||||
|
||||
@Director(description = "Verify native structure eligibility and locate Iris-placed structures without running blocking native searches.", aliases = {"locateall"}, origin = DirectorOrigin.BOTH, sync = true)
|
||||
@Director(description = "Verify native structure eligibility and locate Iris-placed structures without running blocking native searches.", descriptionKey = "iris.director.commandstructure.director.verify_native_structure_eligibility_locate_iris_placed_structures_without_running_blocking_native", aliases = {"locateall"}, origin = DirectorOrigin.BOTH, sync = true)
|
||||
public void verify(
|
||||
@Param(description = "The dimension to verify", aliases = "dim")
|
||||
@Param(description = "The dimension to verify", descriptionKey = "iris.director.commandstructure.param.dimension_verify", aliases = "dim")
|
||||
IrisDimension dimension,
|
||||
@Param(description = "Search radius in chunks around the origin (larger is much slower)", defaultValue = "48")
|
||||
@Param(description = "Search radius in chunks around the origin (larger is much slower)", descriptionKey = "iris.director.commandstructure.param.search_radius_chunks_around_origin_larger_is_much_slower", defaultValue = "48")
|
||||
int radius
|
||||
) {
|
||||
World world = resolveIrisWorld(dimension);
|
||||
if (world == null) {
|
||||
sender().sendMessage(C.RED + "No loaded Iris world found for " + dimension.getLoadKey() + ". Join or create one first (the search runs against a live world).");
|
||||
sender().sendMessage(IrisLanguage.text(BukkitCommandMessagesExtended.COMMAND_STRUCTURE_NO_LOADED_IRIS_WORLD_FOUND_JOIN_CREATE_ONE_FIRST_SEARCH, MessageArgument.untrusted("value", dimension.getLoadKey())));
|
||||
return;
|
||||
}
|
||||
boolean senderIsPlayer = sender() != null && sender().isPlayer();
|
||||
@@ -138,7 +142,7 @@ public class CommandStructure implements DirectorExecutor {
|
||||
PlatformChunkGenerator access = IrisToolbelt.access(world);
|
||||
Engine engine = access == null ? null : access.getEngine();
|
||||
if (engine == null) {
|
||||
sender().sendMessage(C.RED + "The selected Iris world has no active generator engine.");
|
||||
sender().sendMessage(IrisLanguage.text(BukkitCommandMessagesExtended.COMMAND_STRUCTURE_SELECTED_IRIS_WORLD_HAS_NO_ACTIVE_GENERATOR_ENGINE));
|
||||
return;
|
||||
}
|
||||
KList<String> structureKeys = new KList<>();
|
||||
@@ -151,9 +155,7 @@ public class CommandStructure implements DirectorExecutor {
|
||||
}
|
||||
VolmitSender commandSender = sender();
|
||||
Player target = senderIsPlayer ? player() : null;
|
||||
commandSender.sendMessage(C.GREEN + "Verifying structures in " + C.WHITE + world.getName()
|
||||
+ C.GREEN + " from " + center.getBlockX() + "," + center.getBlockZ()
|
||||
+ " within " + searchRadius + " chunks...");
|
||||
commandSender.sendMessage(IrisLanguage.text(BukkitCommandMessages.COMMAND_STRUCTURE_VERIFYING_STRUCTURES_FROM_WITHIN_CHUNKS, MessageArgument.untrusted("value", world.getName()), MessageArgument.untrusted("value2", center.getBlockX()), MessageArgument.untrusted("value3", center.getBlockZ()), MessageArgument.untrusted("searchRadius", searchRadius)));
|
||||
int centerX = center.getBlockX();
|
||||
int centerZ = center.getBlockZ();
|
||||
J.a(() -> runVerification(engine, structureKeys, centerX, centerZ, searchRadius, commandSender, target));
|
||||
@@ -278,28 +280,28 @@ public class CommandStructure implements DirectorExecutor {
|
||||
&& dimensionKey.equals(generator.getEngine().getDimension().getLoadKey());
|
||||
}
|
||||
|
||||
@Director(description = "Resolve an iris structure's jigsaw graph and report piece count & bounds", origin = DirectorOrigin.BOTH)
|
||||
@Director(description = "Resolve an iris structure's jigsaw graph and report piece count & bounds", descriptionKey = "iris.director.commandstructure.director.resolve_iris_structure_s_jigsaw_graph_report_piece_count_bounds", origin = DirectorOrigin.BOTH)
|
||||
public void info(
|
||||
@Param(description = "The dimension whose pack holds the structure", aliases = "dim")
|
||||
@Param(description = "The dimension whose pack holds the structure", descriptionKey = "iris.director.commandstructure.param.dimension_whose_pack_holds_structure", aliases = "dim")
|
||||
IrisDimension dimension,
|
||||
@Param(description = "The iris structure key to inspect")
|
||||
@Param(description = "The iris structure key to inspect", descriptionKey = "iris.director.commandstructure.param.iris_structure_key_inspect")
|
||||
String structure
|
||||
) {
|
||||
IrisData data = dimension.getLoader();
|
||||
if (data == null) {
|
||||
sender().sendMessage(C.RED + "Could not resolve the pack for dimension " + dimension.getLoadKey());
|
||||
sender().sendMessage(IrisLanguage.text(BukkitCommandMessagesExtended.COMMAND_STRUCTURE_COULD_NOT_RESOLVE_PACK_DIMENSION_4, MessageArgument.untrusted("value", dimension.getLoadKey())));
|
||||
return;
|
||||
}
|
||||
IrisStructure s = data.load(IrisStructure.class, structure, false);
|
||||
if (s == null) {
|
||||
sender().sendMessage(C.RED + "No iris structure '" + structure + "' in this pack");
|
||||
sender().sendMessage(IrisLanguage.text(BukkitCommandMessagesExtended.COMMAND_STRUCTURE_NO_IRIS_STRUCTURE_THIS_PACK, MessageArgument.untrusted("structure", structure)));
|
||||
return;
|
||||
}
|
||||
StructureAssembler assembler = StructureAssembler.forData(
|
||||
data, s, new IrisPosition(0, 64, 0));
|
||||
KList<PlacedStructurePiece> pieces = assembler.assemble(new RNG(1234));
|
||||
if (pieces == null || pieces.isEmpty()) {
|
||||
sender().sendMessage(C.RED + "Structure '" + structure + "' assembled 0 pieces (check startPool '" + s.getStartPool() + "')");
|
||||
sender().sendMessage(IrisLanguage.text(BukkitCommandMessagesExtended.COMMAND_STRUCTURE_STRUCTURE_ASSEMBLED_0_PIECES_CHECK_STARTPOOL, MessageArgument.untrusted("structure", structure), MessageArgument.untrusted("value", s.getStartPool())));
|
||||
return;
|
||||
}
|
||||
int minX = Integer.MAX_VALUE;
|
||||
@@ -312,24 +314,24 @@ public class CommandStructure implements DirectorExecutor {
|
||||
maxX = Math.max(maxX, p.getMaxX());
|
||||
maxZ = Math.max(maxZ, p.getMaxZ());
|
||||
}
|
||||
sender().sendMessage(C.GREEN + "Structure '" + structure + "': " + C.WHITE + pieces.size() + C.GREEN + " pieces, footprint " + C.WHITE + (maxX - minX + 1) + "x" + (maxZ - minZ + 1) + C.GREEN + " blocks (sample seed 1234)");
|
||||
sender().sendMessage(IrisLanguage.text(BukkitCommandMessagesExtended.COMMAND_STRUCTURE_STRUCTURE_PIECES_FOOTPRINT_X_BLOCKS_SAMPLE_SEED_1234, MessageArgument.untrusted("structure", structure), MessageArgument.untrusted("value", pieces.size()), MessageArgument.untrusted("value2", (maxX - minX + 1)), MessageArgument.untrusted("value3", (maxZ - minZ + 1))));
|
||||
}
|
||||
|
||||
@Director(description = "Assemble and place an iris structure at your location (studio testing)", aliases = {"p"}, origin = DirectorOrigin.PLAYER, sync = true)
|
||||
@Director(description = "Assemble and place an iris structure at your location (studio testing)", descriptionKey = "iris.director.commandstructure.director.assemble_place_iris_structure_at_your_location_studio_testing", aliases = {"p"}, origin = DirectorOrigin.PLAYER, sync = true)
|
||||
public void place(
|
||||
@Param(description = "The dimension whose pack holds the structure", aliases = "dim")
|
||||
@Param(description = "The dimension whose pack holds the structure", descriptionKey = "iris.director.commandstructure.param.dimension_whose_pack_holds_structure_2", aliases = "dim")
|
||||
IrisDimension dimension,
|
||||
@Param(description = "The iris structure key to place")
|
||||
@Param(description = "The iris structure key to place", descriptionKey = "iris.director.commandstructure.param.iris_structure_key_place")
|
||||
String structure
|
||||
) {
|
||||
IrisData data = dimension.getLoader();
|
||||
if (data == null) {
|
||||
sender().sendMessage(C.RED + "Could not resolve the pack for dimension " + dimension.getLoadKey());
|
||||
sender().sendMessage(IrisLanguage.text(BukkitCommandMessagesExtended.COMMAND_STRUCTURE_COULD_NOT_RESOLVE_PACK_DIMENSION_5, MessageArgument.untrusted("value", dimension.getLoadKey())));
|
||||
return;
|
||||
}
|
||||
IrisStructure s = data.load(IrisStructure.class, structure, false);
|
||||
if (s == null) {
|
||||
sender().sendMessage(C.RED + "No iris structure '" + structure + "' in this pack");
|
||||
sender().sendMessage(IrisLanguage.text(BukkitCommandMessagesExtended.COMMAND_STRUCTURE_NO_IRIS_STRUCTURE_THIS_PACK_2, MessageArgument.untrusted("structure", structure)));
|
||||
return;
|
||||
}
|
||||
Location loc = player().getLocation();
|
||||
@@ -338,7 +340,7 @@ public class CommandStructure implements DirectorExecutor {
|
||||
RNG rng = new RNG((long) loc.getBlockX() * 341873128712L + loc.getBlockZ());
|
||||
KList<PlacedStructurePiece> pieces = assembler.assemble(rng);
|
||||
if (pieces == null || pieces.isEmpty()) {
|
||||
sender().sendMessage(C.RED + "Structure '" + structure + "' assembled 0 pieces");
|
||||
sender().sendMessage(IrisLanguage.text(BukkitCommandMessagesExtended.COMMAND_STRUCTURE_STRUCTURE_ASSEMBLED_0_PIECES, MessageArgument.untrusted("structure", structure)));
|
||||
return;
|
||||
}
|
||||
Map<Block, BlockData> future = new HashMap<>();
|
||||
@@ -353,7 +355,7 @@ public class CommandStructure implements DirectorExecutor {
|
||||
}
|
||||
p.getObject().place(p.getX(), p.getY(), p.getZ(), placer, config, rng, null, null, data);
|
||||
}
|
||||
sender().sendMessage(C.GREEN + "Placed '" + structure + "' (" + pieces.size() + " pieces) at your location.");
|
||||
sender().sendMessage(IrisLanguage.text(BukkitCommandMessagesExtended.COMMAND_STRUCTURE_PLACED_PIECES_AT_YOUR_LOCATION, MessageArgument.untrusted("structure", structure), MessageArgument.untrusted("value", pieces.size())));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+96
-89
@@ -26,6 +26,7 @@ import art.arcane.iris.core.gui.NoiseExplorerGUI;
|
||||
import art.arcane.iris.core.gui.VisionGUI;
|
||||
import art.arcane.iris.core.loader.IrisData;
|
||||
import art.arcane.iris.core.project.IrisProject;
|
||||
import art.arcane.iris.core.localization.RuntimeUiMessages;
|
||||
import art.arcane.iris.core.service.BoardSVC;
|
||||
import art.arcane.iris.core.service.StudioSVC;
|
||||
import art.arcane.iris.core.structure.BulkStructureImporter;
|
||||
@@ -99,7 +100,11 @@ import java.util.Objects;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
@Director(name = "studio", aliases = {"std", "s"}, description = "Studio Commands")
|
||||
import art.arcane.iris.core.localization.IrisLanguage;
|
||||
import art.arcane.iris.core.localization.BukkitCommandMessages;
|
||||
import art.arcane.volmlib.util.localization.MessageArgument;
|
||||
import art.arcane.iris.core.localization.BukkitCommandMessagesExtended;
|
||||
@Director(name = "studio", aliases = {"std", "s"}, description = "Studio Commands", descriptionKey = "iris.director.commandstudio.director.studio_commands")
|
||||
public class CommandStudio implements DirectorExecutor {
|
||||
private CommandEdit edit;
|
||||
//private CommandDeepSearch deepSearch;
|
||||
@@ -108,37 +113,37 @@ public class CommandStudio implements DirectorExecutor {
|
||||
return duration.toString().substring(2).replaceAll("(\\d[HMS])(?!$)", "$1 ").toLowerCase();
|
||||
}
|
||||
|
||||
@Director(description = "Open a new studio world", aliases = "o", sync = true)
|
||||
@Director(description = "Open a new studio world", descriptionKey = "iris.director.commandstudio.director.open_new_studio_world", aliases = "o", sync = true)
|
||||
public void open(
|
||||
@Param(description = "The dimension pack to open a studio for", aliases = "dim", customHandler = DimensionHandler.class)
|
||||
@Param(description = "The dimension pack to open a studio for", descriptionKey = "iris.director.commandstudio.param.dimension_pack_open_studio", aliases = "dim", customHandler = DimensionHandler.class)
|
||||
IrisDimension dimension,
|
||||
@Param(defaultValue = "1337", description = "The seed to generate the studio with", aliases = "s")
|
||||
@Param(defaultValue = "1337", description = "The seed to generate the studio with", descriptionKey = "iris.director.commandstudio.param.seed_generate_studio_with", aliases = "s")
|
||||
long seed) {
|
||||
sender().sendMessage(C.GREEN + "Opening studio for the \"" + dimension.getName() + "\" pack (seed: " + seed + ")");
|
||||
sender().sendMessage(IrisLanguage.text(BukkitCommandMessagesExtended.COMMAND_STUDIO_OPENING_STUDIO_PACK_SEED, MessageArgument.untrusted("value", dimension.getName()), MessageArgument.untrusted("seed", seed)));
|
||||
Iris.service(StudioSVC.class).open(sender(), seed, dimension.getLoadKey());
|
||||
}
|
||||
|
||||
@Director(description = "Import vanilla trees, mushrooms & objects (and structures/jigsaw) from the server into a pack's objects/vanilla folder", aliases = {"importv", "iv"}, origin = DirectorOrigin.BOTH)
|
||||
@Director(description = "Import vanilla trees, mushrooms & objects (and structures/jigsaw) from the server into a pack's objects/vanilla folder", descriptionKey = "iris.director.commandstudio.director.import_vanilla_trees_mushrooms_objects_structures_jigsaw_from_server_into_pack_s", aliases = {"importv", "iv"}, origin = DirectorOrigin.BOTH)
|
||||
public void importvanilla(
|
||||
@Param(description = "The dimension pack to import vanilla content into", aliases = {"pack", "dim"}, customHandler = DimensionHandler.class)
|
||||
@Param(description = "The dimension pack to import vanilla content into", descriptionKey = "iris.director.commandstudio.param.dimension_pack_import_vanilla_content_into", aliases = {"pack", "dim"}, customHandler = DimensionHandler.class)
|
||||
IrisDimension dimension,
|
||||
@Param(description = "How many variants to capture per tree/object feature", defaultValue = "3")
|
||||
@Param(description = "How many variants to capture per tree/object feature", descriptionKey = "iris.director.commandstudio.param.how_many_variants_capture_per_tree_object_feature", defaultValue = "3")
|
||||
int variants,
|
||||
@Param(description = "Also import vanilla & datapack structures/jigsaw into the pack", defaultValue = "true")
|
||||
@Param(description = "Also import vanilla & datapack structures/jigsaw into the pack", descriptionKey = "iris.director.commandstudio.param.also_import_vanilla_datapack_structures_jigsaw_into_pack", defaultValue = "true")
|
||||
boolean structures
|
||||
) {
|
||||
if (dimension == null) {
|
||||
sender().sendMessage(C.RED + "Provide a dimension pack: /iris std importvanilla pack=<dimension>");
|
||||
sender().sendMessage(IrisLanguage.text(BukkitCommandMessagesExtended.COMMAND_STUDIO_PROVIDE_DIMENSION_PACK_IRIS_STD_IMPORTVANILLA_PACK_DIMENSION));
|
||||
return;
|
||||
}
|
||||
IrisData data = dimension.getLoader();
|
||||
if (data == null) {
|
||||
sender().sendMessage(C.RED + "Could not resolve the pack for dimension " + dimension.getLoadKey());
|
||||
sender().sendMessage(IrisLanguage.text(BukkitCommandMessagesExtended.COMMAND_STUDIO_COULD_NOT_RESOLVE_PACK_DIMENSION, MessageArgument.untrusted("value", dimension.getLoadKey())));
|
||||
return;
|
||||
}
|
||||
|
||||
VolmitSender sender = sender();
|
||||
sender.sendMessage(C.GREEN + "Importing vanilla content into " + C.WHITE + dimension.getLoadKey() + C.GREEN + "...");
|
||||
sender.sendMessage(IrisLanguage.text(BukkitCommandMessages.COMMAND_STUDIO_IMPORTING_VANILLA_CONTENT_INTO, MessageArgument.untrusted("value", dimension.getLoadKey())));
|
||||
|
||||
FeatureImporter.Report features = FeatureImporter.importAllObjectFeatures(data, variants, sender);
|
||||
int imported = features.imported();
|
||||
@@ -152,73 +157,72 @@ public class CommandStudio implements DirectorExecutor {
|
||||
failed += jigsaws.failed() + templates.failed() + groups.failed();
|
||||
}
|
||||
|
||||
sender.sendMessage(C.GREEN + "importvanilla complete: " + C.WHITE + imported + C.GREEN + " objects/structures written, " + C.WHITE + failed + C.GREEN + " failed.");
|
||||
sender.sendMessage(C.GRAY + "Trees/objects are under objects/vanilla/...; reference them from biome object placements.");
|
||||
sender.sendMessage(IrisLanguage.text(BukkitCommandMessages.COMMAND_STUDIO_IMPORTVANILLA_COMPLETE_OBJECTS_STRUCTURES_WRITTEN_FAILED, MessageArgument.untrusted("imported", imported), MessageArgument.untrusted("failed", failed)));
|
||||
sender.sendMessage(IrisLanguage.text(BukkitCommandMessages.COMMAND_STUDIO_TREES_OBJECTS_ARE_UNDER_OBJECTS_VANILLA_REFERENCE_THEM_FROM_BIOME));
|
||||
}
|
||||
|
||||
@Director(description = "Open VSCode for a dimension", aliases = {"vsc"})
|
||||
@Director(description = "Open VSCode for a dimension", descriptionKey = "iris.director.commandstudio.director.open_vscode_dimension", aliases = {"vsc"})
|
||||
public void vscode(
|
||||
@Param(defaultValue = "default", description = "The dimension to open VSCode for", aliases = "dim", customHandler = DimensionHandler.class)
|
||||
@Param(defaultValue = "default", description = "The dimension to open VSCode for", descriptionKey = "iris.director.commandstudio.param.dimension_open_vscode", aliases = "dim", customHandler = DimensionHandler.class)
|
||||
IrisDimension dimension
|
||||
) {
|
||||
sender().sendMessage(C.GREEN + "Opening VSCode for the \"" + dimension.getName() + "\" pack");
|
||||
sender().sendMessage(IrisLanguage.text(BukkitCommandMessagesExtended.COMMAND_STUDIO_OPENING_VSCODE_PACK, MessageArgument.untrusted("value", dimension.getName())));
|
||||
Iris.service(StudioSVC.class).openVSCode(sender(), dimension.getLoadKey());
|
||||
}
|
||||
|
||||
@Director(description = "Close an open studio project", aliases = {"x"}, sync = true)
|
||||
@Director(description = "Close an open studio project", descriptionKey = "iris.director.commandstudio.director.close_open_studio_project", aliases = {"x"}, sync = true)
|
||||
public void close() {
|
||||
VolmitSender commandSender = sender();
|
||||
if (!Iris.service(StudioSVC.class).isProjectOpen()) {
|
||||
commandSender.sendMessage(C.RED + "No open studio projects.");
|
||||
commandSender.sendMessage(IrisLanguage.text(BukkitCommandMessages.COMMAND_STUDIO_NO_OPEN_STUDIO_PROJECTS));
|
||||
return;
|
||||
}
|
||||
|
||||
commandSender.sendMessage(C.YELLOW + "Closing studio...");
|
||||
commandSender.sendMessage(IrisLanguage.text(BukkitCommandMessages.COMMAND_STUDIO_CLOSING_STUDIO));
|
||||
Iris.service(StudioSVC.class).close().whenComplete((result, throwable) -> J.s(() -> {
|
||||
if (throwable != null) {
|
||||
commandSender.sendMessage(C.RED + "Studio close failed: " + throwable.getMessage());
|
||||
commandSender.sendMessage(IrisLanguage.text(BukkitCommandMessages.COMMAND_STUDIO_STUDIO_CLOSE_FAILED, MessageArgument.untrusted("value", String.valueOf(throwable.getMessage()))));
|
||||
return;
|
||||
}
|
||||
|
||||
if (result != null && result.failureCause() != null) {
|
||||
commandSender.sendMessage(C.RED + "Studio close failed: " + result.failureCause().getMessage());
|
||||
commandSender.sendMessage(IrisLanguage.text(BukkitCommandMessages.COMMAND_STUDIO_STUDIO_CLOSE_FAILED_2, MessageArgument.untrusted("value", String.valueOf(result.failureCause().getMessage()))));
|
||||
return;
|
||||
}
|
||||
|
||||
if (result != null && result.startupCleanupQueued()) {
|
||||
commandSender.sendMessage(C.YELLOW + "Studio closed. Remaining world-family cleanup was queued for startup fallback.");
|
||||
commandSender.sendMessage(IrisLanguage.text(BukkitCommandMessages.COMMAND_STUDIO_STUDIO_CLOSED_REMAINING_WORLD_FAMILY_CLEANUP_WAS_QUEUED_STARTUP_FALLBACK));
|
||||
return;
|
||||
}
|
||||
|
||||
commandSender.sendMessage(C.GREEN + "Studio closed.");
|
||||
commandSender.sendMessage(IrisLanguage.text(BukkitCommandMessages.COMMAND_STUDIO_STUDIO_CLOSED));
|
||||
}));
|
||||
}
|
||||
|
||||
@Director(description = "Toggle your Studio debug scoreboard", aliases = {"board", "sidebar", "sb"}, origin = DirectorOrigin.PLAYER)
|
||||
@Director(description = "Toggle your Studio debug scoreboard", descriptionKey = "iris.director.commandstudio.director.toggle_your_studio_debug_scoreboard", aliases = {"board", "sidebar", "sb"}, origin = DirectorOrigin.PLAYER)
|
||||
public void scoreboard() {
|
||||
Player target = player();
|
||||
VolmitSender commandSender = sender();
|
||||
if (!J.runEntity(target, () -> {
|
||||
PlatformChunkGenerator generator = IrisToolbelt.access(target.getWorld());
|
||||
if (generator == null || !generator.isStudio()) {
|
||||
commandSender.sendMessage(C.RED + "You must be in a Studio world to toggle the debug scoreboard.");
|
||||
commandSender.sendMessage(IrisLanguage.text(BukkitCommandMessages.COMMAND_STUDIO_YOU_MUST_BE_STUDIO_WORLD_TOGGLE_DEBUG_SCOREBOARD));
|
||||
return;
|
||||
}
|
||||
|
||||
boolean visible = Iris.service(BoardSVC.class).toggle(target);
|
||||
commandSender.sendMessage((visible ? C.GREEN : C.YELLOW)
|
||||
+ "Studio debug scoreboard " + (visible ? "enabled." : "disabled."));
|
||||
commandSender.sendMessage(IrisLanguage.text(BukkitCommandMessages.COMMAND_STUDIO_STUDIO_DEBUG_SCOREBOARD, MessageArgument.trusted("value", visible ? C.GREEN : C.YELLOW), MessageArgument.trusted("value2", IrisLanguage.text(visible ? RuntimeUiMessages.STATUS_ENABLED : RuntimeUiMessages.STATUS_DISABLED))));
|
||||
})) {
|
||||
commandSender.sendMessage(C.RED + "Could not update the Studio debug scoreboard right now.");
|
||||
commandSender.sendMessage(IrisLanguage.text(BukkitCommandMessages.COMMAND_STUDIO_COULD_NOT_UPDATE_STUDIO_DEBUG_SCOREBOARD_RIGHT_NOW));
|
||||
}
|
||||
}
|
||||
|
||||
@Director(description = "Create a new studio project", aliases = "+", sync = true)
|
||||
@Director(description = "Create a new studio project", descriptionKey = "iris.director.commandstudio.director.create_new_studio_project", aliases = "+", sync = true)
|
||||
public void create(
|
||||
@Param(description = "The name of this new Iris Project.", defaultValue = "studio")
|
||||
@Param(description = "The name of this new Iris Project.", descriptionKey = "iris.director.commandstudio.param.name_this_new_iris_project", defaultValue = "studio")
|
||||
String name,
|
||||
@Param(
|
||||
description = "Copy the contents of an existing project in your packs folder and use it as a template in this new project.",
|
||||
description = "Copy the contents of an existing project in your packs folder and use it as a template in this new project.", descriptionKey = "iris.director.commandstudio.param.copy_contents_existing_project_your_packs_folder_use_it_as_template_this",
|
||||
contextual = true,
|
||||
customHandler = NullableDimensionHandler.class
|
||||
)
|
||||
@@ -239,23 +243,23 @@ public class CommandStudio implements DirectorExecutor {
|
||||
}
|
||||
}
|
||||
|
||||
@Director(description = "Get the version of a pack")
|
||||
@Director(description = "Get the version of a pack", descriptionKey = "iris.director.commandstudio.director.get_version_pack")
|
||||
public void version(
|
||||
@Param(defaultValue = "default", description = "The dimension get the version of", aliases = "dim", contextual = true, customHandler = DimensionHandler.class)
|
||||
@Param(defaultValue = "default", description = "The dimension get the version of", descriptionKey = "iris.director.commandstudio.param.dimension_get_version", aliases = "dim", contextual = true, customHandler = DimensionHandler.class)
|
||||
IrisDimension dimension
|
||||
) {
|
||||
sender().sendMessage(C.GREEN + "The \"" + dimension.getName() + "\" pack has version: " + dimension.getVersion());
|
||||
sender().sendMessage(IrisLanguage.text(BukkitCommandMessagesExtended.COMMAND_STUDIO_PACK_HAS_VERSION, MessageArgument.untrusted("value", dimension.getName()), MessageArgument.untrusted("value2", dimension.getVersion())));
|
||||
}
|
||||
|
||||
@Director(description = "Open the noise explorer (External GUI)", aliases = {"nmap"})
|
||||
@Director(description = "Open the noise explorer (External GUI)", descriptionKey = "iris.director.commandstudio.director.open_noise_explorer_external_gui", aliases = {"nmap"})
|
||||
public void noise(
|
||||
@Param(description = "Optional pack generator to preview", defaultValue = "null", contextual = true)
|
||||
@Param(description = "Optional pack generator to preview", descriptionKey = "iris.director.commandstudio.param.optional_pack_generator_preview", defaultValue = "null", contextual = true)
|
||||
IrisGenerator generator,
|
||||
@Param(description = "The seed to preview the generator with", defaultValue = "12345")
|
||||
@Param(description = "The seed to preview the generator with", descriptionKey = "iris.director.commandstudio.param.seed_preview_generator_with", defaultValue = "12345")
|
||||
long seed
|
||||
) {
|
||||
if (noGUI()) return;
|
||||
sender().sendMessage(C.GREEN + "Opening Noise Explorer!");
|
||||
sender().sendMessage(IrisLanguage.text(BukkitCommandMessagesExtended.COMMAND_STUDIO_OPENING_NOISE_EXPLORER));
|
||||
|
||||
if (generator == null) {
|
||||
NoiseExplorerGUI.launch();
|
||||
@@ -266,11 +270,11 @@ public class CommandStudio implements DirectorExecutor {
|
||||
NoiseExplorerGUI.launch(supplier, "Custom Generator");
|
||||
}
|
||||
|
||||
@Director(description = "Show loot if a chest were right here", origin = DirectorOrigin.PLAYER, sync = true)
|
||||
@Director(description = "Show loot if a chest were right here", descriptionKey = "iris.director.commandstudio.director.show_loot_if_chest_were_right_here", origin = DirectorOrigin.PLAYER, sync = true)
|
||||
public void loot(
|
||||
@Param(description = "Fast insertion of items in virtual inventory (may cause performance drop)", defaultValue = "false")
|
||||
@Param(description = "Fast insertion of items in virtual inventory (may cause performance drop)", descriptionKey = "iris.director.commandstudio.param.fast_insertion_items_virtual_inventory_may_cause_performance_drop", defaultValue = "false")
|
||||
boolean fast,
|
||||
@Param(description = "Whether or not to append to the inventory currently open (if false, clears opened inventory)", defaultValue = "true")
|
||||
@Param(description = "Whether or not to append to the inventory currently open (if false, clears opened inventory)", descriptionKey = "iris.director.commandstudio.param.whether_not_append_inventory_currently_open_if_false_clears_opened_inventory", defaultValue = "true")
|
||||
boolean add
|
||||
) {
|
||||
if (noStudio()) return;
|
||||
@@ -282,7 +286,7 @@ public class CommandStudio implements DirectorExecutor {
|
||||
EngineBukkitOps.addItems(engine(), true, inv, tables, InventorySlotType.STORAGE, player().getWorld(), player().getLocation().getBlockX(), player().getLocation().getBlockY(), player().getLocation().getBlockZ());
|
||||
} catch (Throwable e) {
|
||||
Iris.reportError(e);
|
||||
sender().sendMessage(C.RED + "Cannot add items to virtual inventory because of: " + e.getMessage());
|
||||
sender().sendMessage(IrisLanguage.text(BukkitCommandMessagesExtended.COMMAND_STUDIO_CANNOT_ADD_ITEMS_VIRTUAL_INVENTORY_BECAUSE, MessageArgument.untrusted("value", String.valueOf(e.getMessage()))));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -298,7 +302,7 @@ public class CommandStudio implements DirectorExecutor {
|
||||
{
|
||||
if (!player.getOpenInventory().getType().equals(InventoryType.CHEST)) {
|
||||
J.csr(ta.get());
|
||||
sender.sendMessage(C.GREEN + "Opened inventory!");
|
||||
sender.sendMessage(IrisLanguage.text(BukkitCommandMessages.COMMAND_STUDIO_OPENED_INVENTORY));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -309,15 +313,15 @@ public class CommandStudio implements DirectorExecutor {
|
||||
EngineBukkitOps.addItems(engine, true, inv, tables, InventorySlotType.STORAGE, player.getWorld(), player.getLocation().getBlockX(), player.getLocation().getBlockY(), player.getLocation().getBlockZ());
|
||||
}, fast ? 5 : 35));
|
||||
|
||||
sender().sendMessage(C.GREEN + "Opening inventory now!");
|
||||
sender().sendMessage(IrisLanguage.text(BukkitCommandMessagesExtended.COMMAND_STUDIO_OPENING_INVENTORY_NOW));
|
||||
player().openInventory(inv);
|
||||
}
|
||||
|
||||
@Director(description = "Calculate the chance for each region to generate", origin = DirectorOrigin.PLAYER)
|
||||
public void regions(@Param(description = "The radius in chunks", defaultValue = "500") int radius) {
|
||||
@Director(description = "Calculate the chance for each region to generate", descriptionKey = "iris.director.commandstudio.director.calculate_chance_each_region_generate", origin = DirectorOrigin.PLAYER)
|
||||
public void regions(@Param(description = "The radius in chunks", descriptionKey = "iris.director.commandstudio.param.radius_chunks", defaultValue = "500") int radius) {
|
||||
var engine = engine();
|
||||
if (engine == null) {
|
||||
sender().sendMessage(C.RED + "Only works in an Iris world!");
|
||||
sender().sendMessage(IrisLanguage.text(BukkitCommandMessagesExtended.COMMAND_STUDIO_ONLY_WORKS_IRIS_WORLD));
|
||||
return;
|
||||
}
|
||||
var sender = sender();
|
||||
@@ -329,11 +333,14 @@ public class CommandStudio implements DirectorExecutor {
|
||||
engine.getDimension().getRegions().forEach(key -> data.put(key, new AtomicInteger(0)));
|
||||
var multiBurst = new MultiBurst("Region Sampler");
|
||||
var executor = multiBurst.burst(radius * radius);
|
||||
sender.sendMessage(C.GRAY + "Generating data...");
|
||||
sender.sendMessage(IrisLanguage.text(BukkitCommandMessages.COMMAND_STUDIO_GENERATING_DATA));
|
||||
var loc = player.getLocation();
|
||||
int totalTasks = d * d;
|
||||
AtomicInteger completedTasks = new AtomicInteger(0);
|
||||
int c = J.ar(() -> sender.sendProgress((double) completedTasks.get() / totalTasks, "Finding regions"), 0);
|
||||
int c = J.ar(() -> sender.sendProgress(
|
||||
(double) completedTasks.get() / totalTasks,
|
||||
IrisLanguage.text(RuntimeUiMessages.FINDING_REGIONS)
|
||||
), 0);
|
||||
new Spiraler(d, d, (x, z) -> executor.queue(() -> {
|
||||
var region = engine.getRegion((x << 4) + 8, (z << 4) + 8);
|
||||
data.computeIfAbsent(region.getLoadKey(), (k) -> new AtomicInteger(0))
|
||||
@@ -344,43 +351,43 @@ public class CommandStudio implements DirectorExecutor {
|
||||
multiBurst.close();
|
||||
J.car(c);
|
||||
|
||||
sender.sendMessage(C.GREEN + "Done!");
|
||||
sender.sendMessage(IrisLanguage.text(BukkitCommandMessages.COMMAND_STUDIO_DONE));
|
||||
var loader = engine.getData().getRegionLoader();
|
||||
data.forEach((k, v) -> sender.sendMessage(C.GREEN + k + ": " + loader.load(k).getRarity() + " / " + Form.f((double) v.get() / totalTasks * 100, 2) + "%"));
|
||||
data.forEach((k, v) -> sender.sendMessage(IrisLanguage.text(BukkitCommandMessages.COMMAND_STUDIO_MESSAGE, MessageArgument.untrusted("k", k), MessageArgument.untrusted("value", loader.load(k).getRarity()), MessageArgument.untrusted("value2", Form.f((double) v.get() / totalTasks * 100, 2)))));
|
||||
});
|
||||
}
|
||||
|
||||
@Director(description = "Render a world map (External GUI)", aliases = "render")
|
||||
@Director(description = "Render a world map (External GUI)", descriptionKey = "iris.director.commandstudio.director.render_world_map_external_gui", aliases = "render")
|
||||
public void map(
|
||||
@Param(name = "world", description = "The world to open the generator for", contextual = true)
|
||||
@Param(name = "world", description = "The world to open the generator for", descriptionKey = "iris.director.commandstudio.param.world_open_generator", contextual = true)
|
||||
World world
|
||||
) {
|
||||
if (noGUI()) return;
|
||||
|
||||
if (!IrisToolbelt.isIrisWorld(world)) {
|
||||
sender().sendMessage(C.RED + "You need to be in or specify an Iris-generated world!");
|
||||
sender().sendMessage(IrisLanguage.text(BukkitCommandMessagesExtended.COMMAND_STUDIO_YOU_NEED_BE_SPECIFY_IRIS_GENERATED_WORLD));
|
||||
return;
|
||||
}
|
||||
|
||||
VisionGUI.launch(IrisToolbelt.access(world).getEngine());
|
||||
sender().sendMessage(C.GREEN + "Opening map!");
|
||||
sender().sendMessage(IrisLanguage.text(BukkitCommandMessagesExtended.COMMAND_STUDIO_OPENING_MAP));
|
||||
}
|
||||
|
||||
@Director(description = "Package a dimension into a compressed format", aliases = "package")
|
||||
@Director(description = "Package a dimension into a compressed format", descriptionKey = "iris.director.commandstudio.director.package_dimension_into_compressed_format", aliases = "package")
|
||||
public void pkg(
|
||||
@Param(name = "dimension", description = "The dimension pack to compress", contextual = true, defaultValue = "default", customHandler = DimensionHandler.class)
|
||||
@Param(name = "dimension", description = "The dimension pack to compress", descriptionKey = "iris.director.commandstudio.param.dimension_pack_compress", contextual = true, defaultValue = "default", customHandler = DimensionHandler.class)
|
||||
IrisDimension dimension,
|
||||
@Param(name = "obfuscate", description = "Whether or not to obfuscate the pack", defaultValue = "false")
|
||||
@Param(name = "obfuscate", description = "Whether or not to obfuscate the pack", descriptionKey = "iris.director.commandstudio.param.whether_not_obfuscate_pack", defaultValue = "false")
|
||||
boolean obfuscate,
|
||||
@Param(name = "minify", description = "Whether or not to minify the pack", defaultValue = "true")
|
||||
@Param(name = "minify", description = "Whether or not to minify the pack", descriptionKey = "iris.director.commandstudio.param.whether_not_minify_pack", defaultValue = "true")
|
||||
boolean minify
|
||||
) {
|
||||
Iris.service(StudioSVC.class).compilePackage(sender(), dimension.getLoadKey(), obfuscate, minify);
|
||||
}
|
||||
|
||||
@Director(description = "Profiles the performance of a dimension", origin = DirectorOrigin.PLAYER)
|
||||
@Director(description = "Profiles the performance of a dimension", descriptionKey = "iris.director.commandstudio.director.profiles_performance_dimension", origin = DirectorOrigin.PLAYER)
|
||||
public void profile(
|
||||
@Param(description = "The dimension to profile", contextual = true, defaultValue = "default", customHandler = DimensionHandler.class)
|
||||
@Param(description = "The dimension to profile", descriptionKey = "iris.director.commandstudio.param.dimension_profile", contextual = true, defaultValue = "default", customHandler = DimensionHandler.class)
|
||||
IrisDimension dimension
|
||||
) {
|
||||
// Todo: Make this more accurate
|
||||
@@ -405,7 +412,7 @@ public class CommandStudio implements DirectorExecutor {
|
||||
KMap<String, Double> biomeTimings = new KMap<>();
|
||||
KMap<String, Double> regionTimings = new KMap<>();
|
||||
|
||||
sender().sendMessage("Calculating Performance Metrics for Noise generators");
|
||||
sender().sendMessage(IrisLanguage.text(BukkitCommandMessagesExtended.COMMAND_STUDIO_CALCULATING_PERFORMANCE_METRICS_NOISE_GENERATORS));
|
||||
|
||||
for (NoiseStyle i : NoiseStyle.values()) {
|
||||
CNG c = i.create(new RNG(i.hashCode()));
|
||||
@@ -433,7 +440,7 @@ public class CommandStudio implements DirectorExecutor {
|
||||
|
||||
fileText.add("");
|
||||
|
||||
sender().sendMessage("Calculating Interpolator Timings...");
|
||||
sender().sendMessage(IrisLanguage.text(BukkitCommandMessagesExtended.COMMAND_STUDIO_CALCULATING_INTERPOLATOR_TIMINGS));
|
||||
|
||||
for (InterpolationMethod i : InterpolationMethod.values()) {
|
||||
IrisInterpolator in = new IrisInterpolator();
|
||||
@@ -463,7 +470,7 @@ public class CommandStudio implements DirectorExecutor {
|
||||
|
||||
fileText.add("");
|
||||
|
||||
sender().sendMessage("Processing Generator Scores: ");
|
||||
sender().sendMessage(IrisLanguage.text(BukkitCommandMessagesExtended.COMMAND_STUDIO_PROCESSING_GENERATOR_SCORES));
|
||||
|
||||
KMap<String, KList<String>> btx = new KMap<>();
|
||||
|
||||
@@ -563,7 +570,7 @@ public class CommandStudio implements DirectorExecutor {
|
||||
m += mmm;
|
||||
|
||||
fileText.add("Average Score: " + m);
|
||||
sender().sendMessage("Score: " + Form.duration(m, 0));
|
||||
sender().sendMessage(IrisLanguage.text(BukkitCommandMessagesExtended.COMMAND_STUDIO_SCORE, MessageArgument.untrusted("value", Form.duration(m, 0))));
|
||||
|
||||
try {
|
||||
IO.writeAll(report, fileText.toString("\n"));
|
||||
@@ -572,7 +579,7 @@ public class CommandStudio implements DirectorExecutor {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
sender().sendMessage(C.GREEN + "Done! " + report.getPath());
|
||||
sender().sendMessage(IrisLanguage.text(BukkitCommandMessagesExtended.COMMAND_STUDIO_DONE, MessageArgument.untrusted("value", report.getPath())));
|
||||
}
|
||||
|
||||
private PlatformChunkGenerator resolveProfileGenerator(IrisDimension dimension) {
|
||||
@@ -617,32 +624,32 @@ public class CommandStudio implements DirectorExecutor {
|
||||
return engineDimension.getLoadKey().equalsIgnoreCase(dimension.getLoadKey());
|
||||
}
|
||||
|
||||
@Director(description = "Spawn an Iris entity", aliases = "summon", origin = DirectorOrigin.PLAYER)
|
||||
@Director(description = "Spawn an Iris entity", descriptionKey = "iris.director.commandstudio.director.spawn_iris_entity", aliases = "summon", origin = DirectorOrigin.PLAYER)
|
||||
public void spawn(
|
||||
@Param(description = "The entity to spawn")
|
||||
@Param(description = "The entity to spawn", descriptionKey = "iris.director.commandstudio.param.entity_spawn")
|
||||
IrisEntity entity,
|
||||
@Param(description = "The location to spawn the entity at", contextual = true)
|
||||
@Param(description = "The location to spawn the entity at", descriptionKey = "iris.director.commandstudio.param.location_spawn_entity_at", contextual = true)
|
||||
Vector location
|
||||
) {
|
||||
if (!IrisToolbelt.isIrisWorld(player().getWorld())) {
|
||||
sender().sendMessage(C.RED + "You have to be in an Iris world to spawn entities properly. Trying to spawn the best we can do.");
|
||||
sender().sendMessage(IrisLanguage.text(BukkitCommandMessagesExtended.COMMAND_STUDIO_YOU_HAVE_BE_IRIS_WORLD_SPAWN_ENTITIES_PROPERLY_TRYING_SPAWN));
|
||||
}
|
||||
entity.spawn(engine(), new Location(world(), location.getX(), location.getY(), location.getZ()));
|
||||
}
|
||||
|
||||
@Director(description = "Teleport to the active studio world", aliases = "stp", origin = DirectorOrigin.PLAYER, sync = true)
|
||||
@Director(description = "Teleport to the active studio world", descriptionKey = "iris.director.commandstudio.director.teleport_active_studio_world", aliases = "stp", origin = DirectorOrigin.PLAYER, sync = true)
|
||||
public void tpstudio() {
|
||||
if (!Iris.service(StudioSVC.class).isProjectOpen()) {
|
||||
sender().sendMessage(C.RED + "No studio world is open!");
|
||||
sender().sendMessage(IrisLanguage.text(BukkitCommandMessagesExtended.COMMAND_STUDIO_NO_STUDIO_WORLD_IS_OPEN));
|
||||
return;
|
||||
}
|
||||
|
||||
if (IrisToolbelt.isIrisWorld(world()) && engine().isStudio()) {
|
||||
sender().sendMessage(C.RED + "You are already in a studio world!");
|
||||
sender().sendMessage(IrisLanguage.text(BukkitCommandMessagesExtended.COMMAND_STUDIO_YOU_ARE_ALREADY_STUDIO_WORLD));
|
||||
return;
|
||||
}
|
||||
|
||||
sender().sendMessage(C.GREEN + "Sending you to the studio world!");
|
||||
sender().sendMessage(IrisLanguage.text(BukkitCommandMessagesExtended.COMMAND_STUDIO_SENDING_YOU_STUDIO_WORLD));
|
||||
Player player = player();
|
||||
IrisWorld studioWorld = Iris.service(StudioSVC.class)
|
||||
.getActiveProject()
|
||||
@@ -653,30 +660,30 @@ public class CommandStudio implements DirectorExecutor {
|
||||
.thenRun(() -> player.setGameMode(GameMode.SPECTATOR));
|
||||
}
|
||||
|
||||
@Director(description = "Update your dimension projects VSCode workspace")
|
||||
@Director(description = "Update your dimension projects VSCode workspace", descriptionKey = "iris.director.commandstudio.director.update_your_dimension_projects_vscode_workspace")
|
||||
public void update(
|
||||
@Param(description = "The dimension to update the workspace of", contextual = true, defaultValue = "default", customHandler = DimensionHandler.class)
|
||||
@Param(description = "The dimension to update the workspace of", descriptionKey = "iris.director.commandstudio.param.dimension_update_workspace", contextual = true, defaultValue = "default", customHandler = DimensionHandler.class)
|
||||
IrisDimension dimension
|
||||
) {
|
||||
sender().sendMessage(C.GOLD + "Updating Code Workspace for " + dimension.getName() + "...");
|
||||
sender().sendMessage(IrisLanguage.text(BukkitCommandMessagesExtended.COMMAND_STUDIO_UPDATING_CODE_WORKSPACE, MessageArgument.untrusted("value", dimension.getName())));
|
||||
if (new IrisProject(dimension.getLoader().getDataFolder()).updateWorkspace()) {
|
||||
sender().sendMessage(C.GREEN + "Updated Code Workspace for " + dimension.getName());
|
||||
sender().sendMessage(IrisLanguage.text(BukkitCommandMessagesExtended.COMMAND_STUDIO_UPDATED_CODE_WORKSPACE, MessageArgument.untrusted("value", dimension.getName())));
|
||||
} else {
|
||||
sender().sendMessage(C.RED + "Invalid project: " + dimension.getName() + ". Try deleting the code-workspace file and try again.");
|
||||
sender().sendMessage(IrisLanguage.text(BukkitCommandMessagesExtended.COMMAND_STUDIO_INVALID_PROJECT_TRY_DELETING_CODE_WORKSPACE_FILE_TRY_AGAIN, MessageArgument.untrusted("value", dimension.getName())));
|
||||
}
|
||||
}
|
||||
|
||||
@Director(aliases = "find-objects", description = "Capture an IGenData chunk report for nearby chunks")
|
||||
@Director(aliases = "find-objects", description = "Capture an IGenData chunk report for nearby chunks", descriptionKey = "iris.director.commandstudio.director.capture_igendata_chunk_report_nearby_chunks")
|
||||
public void objects() {
|
||||
if (!IrisToolbelt.isIrisWorld(player().getWorld())) {
|
||||
sender().sendMessage(C.RED + "You must be in an Iris world");
|
||||
sender().sendMessage(IrisLanguage.text(BukkitCommandMessagesExtended.COMMAND_STUDIO_YOU_MUST_BE_IRIS_WORLD));
|
||||
return;
|
||||
}
|
||||
|
||||
World world = player().getWorld();
|
||||
|
||||
if (!IrisToolbelt.isIrisWorld(world)) {
|
||||
sender().sendMessage("You must be in an iris world.");
|
||||
sender().sendMessage(IrisLanguage.text(BukkitCommandMessagesExtended.COMMAND_STUDIO_YOU_MUST_BE_IRIS_WORLD_2));
|
||||
return;
|
||||
}
|
||||
KList<Chunk> chunks = new KList<>();
|
||||
@@ -694,7 +701,7 @@ public class CommandStudio implements DirectorExecutor {
|
||||
}
|
||||
|
||||
new Spiraler(3, 3, (x, z) -> chunks.addIfMissing(world.getChunkAt(x + bx, z + bz))).drain();
|
||||
sender().sendMessage("Capturing IGenData from " + chunks.size() + " nearby chunks.");
|
||||
sender().sendMessage(IrisLanguage.text(BukkitCommandMessagesExtended.COMMAND_STUDIO_CAPTURING_IGENDATA_FROM_NEARBY_CHUNKS, MessageArgument.untrusted("value", chunks.size())));
|
||||
try {
|
||||
File ff = Iris.instance.getDataFile("reports/" + M.ms() + ".txt");
|
||||
PrintWriter pw = new PrintWriter(ff);
|
||||
@@ -788,7 +795,7 @@ public class CommandStudio implements DirectorExecutor {
|
||||
pw.println();
|
||||
pw.close();
|
||||
|
||||
sender().sendMessage("Reported to: " + ff.getPath());
|
||||
sender().sendMessage(IrisLanguage.text(BukkitCommandMessagesExtended.COMMAND_STUDIO_REPORTED, MessageArgument.untrusted("value", ff.getPath())));
|
||||
} catch (FileNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
Iris.reportError(e);
|
||||
@@ -831,7 +838,7 @@ public class CommandStudio implements DirectorExecutor {
|
||||
*/
|
||||
private boolean noGUI() {
|
||||
if (!IrisSettings.get().getGui().isUseServerLaunchedGuis()) {
|
||||
sender().sendMessage(C.RED + "You must have server launched GUIs enabled in the settings!");
|
||||
sender().sendMessage(IrisLanguage.text(BukkitCommandMessagesExtended.COMMAND_STUDIO_YOU_MUST_HAVE_SERVER_LAUNCHED_GUIS_ENABLED_SETTINGS));
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@@ -842,15 +849,15 @@ public class CommandStudio implements DirectorExecutor {
|
||||
*/
|
||||
private boolean noStudio() {
|
||||
if (!sender().isPlayer()) {
|
||||
sender().sendMessage(C.RED + "Players only!");
|
||||
sender().sendMessage(IrisLanguage.text(BukkitCommandMessagesExtended.COMMAND_STUDIO_PLAYERS_ONLY));
|
||||
return true;
|
||||
}
|
||||
if (!Iris.service(StudioSVC.class).isProjectOpen()) {
|
||||
sender().sendMessage(C.RED + "No studio world is open!");
|
||||
sender().sendMessage(IrisLanguage.text(BukkitCommandMessagesExtended.COMMAND_STUDIO_NO_STUDIO_WORLD_IS_OPEN_2));
|
||||
return true;
|
||||
}
|
||||
if (!IrisToolbelt.isStudio(world())) {
|
||||
sender().sendMessage(C.RED + "You must be in a studio world!");
|
||||
sender().sendMessage(IrisLanguage.text(BukkitCommandMessagesExtended.COMMAND_STUDIO_YOU_MUST_BE_STUDIO_WORLD));
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
||||
+33
-29
@@ -44,46 +44,50 @@ import org.bukkit.block.data.BlockData;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
@Director(name = "what", origin = DirectorOrigin.PLAYER, description = "Iris What?")
|
||||
import art.arcane.iris.core.localization.IrisLanguage;
|
||||
import art.arcane.iris.core.localization.BukkitCommandMessagesExtended;
|
||||
import art.arcane.iris.core.localization.RuntimeUiMessages;
|
||||
import art.arcane.volmlib.util.localization.MessageArgument;
|
||||
@Director(name = "what", origin = DirectorOrigin.PLAYER, description = "Iris What?", descriptionKey = "iris.director.commandwhat.director.iris_what")
|
||||
public class CommandWhat implements DirectorExecutor {
|
||||
@Director(description = "What is in my hand?", origin = DirectorOrigin.PLAYER)
|
||||
@Director(description = "What is in my hand?", descriptionKey = "iris.director.commandwhat.director.what_is_my_hand", origin = DirectorOrigin.PLAYER)
|
||||
public void hand() {
|
||||
try {
|
||||
BlockData bd = player().getInventory().getItemInMainHand().getType().createBlockData();
|
||||
if (!bd.getMaterial().equals(Material.AIR)) {
|
||||
sender().sendMessage("Material: " + C.GREEN + bd.getMaterial().name());
|
||||
sender().sendMessage("Full: " + C.WHITE + bd.getAsString(true));
|
||||
sender().sendMessage(IrisLanguage.text(BukkitCommandMessagesExtended.COMMAND_WHAT_MATERIAL, MessageArgument.untrusted("value", bd.getMaterial().name())));
|
||||
sender().sendMessage(IrisLanguage.text(BukkitCommandMessagesExtended.COMMAND_WHAT_FULL, MessageArgument.untrusted("value", bd.getAsString(true))));
|
||||
} else {
|
||||
sender().sendMessage("Please hold a block/item");
|
||||
sender().sendMessage(IrisLanguage.text(BukkitCommandMessagesExtended.COMMAND_WHAT_PLEASE_HOLD_BLOCK_ITEM));
|
||||
}
|
||||
} catch (Throwable e) {
|
||||
Iris.reportError(e);
|
||||
Material bd = player().getInventory().getItemInMainHand().getType();
|
||||
if (!bd.equals(Material.AIR)) {
|
||||
sender().sendMessage("Material: " + C.GREEN + bd.name());
|
||||
sender().sendMessage(IrisLanguage.text(BukkitCommandMessagesExtended.COMMAND_WHAT_MATERIAL_2, MessageArgument.untrusted("value", bd.name())));
|
||||
} else {
|
||||
sender().sendMessage("Please hold a block/item");
|
||||
sender().sendMessage(IrisLanguage.text(BukkitCommandMessagesExtended.COMMAND_WHAT_PLEASE_HOLD_BLOCK_ITEM_2));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Director(description = "What biome am i in?", origin = DirectorOrigin.PLAYER)
|
||||
@Director(description = "What biome am i in?", descriptionKey = "iris.director.commandwhat.director.what_biome_am_i", origin = DirectorOrigin.PLAYER)
|
||||
public void biome() {
|
||||
try {
|
||||
IrisBiome b = engine().getBiome(player().getLocation().getBlockX(), player().getLocation().getBlockY() - player().getWorld().getMinHeight(), player().getLocation().getBlockZ());
|
||||
Biome derivative = b.getDerivative();
|
||||
NamespacedKey derivativeKey = resolveBiomeKey(derivative);
|
||||
sender().sendMessage("IBiome: " + b.getLoadKey() + " (" + (derivativeKey == null ? "unregistered" : derivativeKey.getKey()) + ")");
|
||||
sender().sendMessage(IrisLanguage.text(BukkitCommandMessagesExtended.COMMAND_WHAT_IBIOME, MessageArgument.untrusted("value", b.getLoadKey()), MessageArgument.untrusted("value2", derivativeKey == null ? IrisLanguage.plain(RuntimeUiMessages.STATUS_UNREGISTERED) : derivativeKey.getKey())));
|
||||
|
||||
} catch (Throwable e) {
|
||||
Iris.reportError(e);
|
||||
Biome biome = player().getLocation().getBlock().getBiome();
|
||||
NamespacedKey key = resolveBiomeKey(biome);
|
||||
sender().sendMessage("Non-Iris Biome: " + (key == null ? "unregistered" : key));
|
||||
sender().sendMessage(IrisLanguage.text(BukkitCommandMessagesExtended.COMMAND_WHAT_NON_IRIS_BIOME, MessageArgument.untrusted("value", key == null ? IrisLanguage.plain(RuntimeUiMessages.STATUS_UNREGISTERED) : key)));
|
||||
|
||||
if (key == null || key.getKey().equals("custom")) {
|
||||
try {
|
||||
sender().sendMessage("Data Pack Biome: " + INMS.get().getTrueBiomeBaseKey(player().getLocation()) + " (ID: " + INMS.get().getTrueBiomeBaseId(INMS.get().getTrueBiomeBase(player().getLocation())) + ")");
|
||||
sender().sendMessage(IrisLanguage.text(BukkitCommandMessagesExtended.COMMAND_WHAT_DATA_PACK_BIOME_ID, MessageArgument.untrusted("value", INMS.get().getTrueBiomeBaseKey(player().getLocation())), MessageArgument.untrusted("value2", INMS.get().getTrueBiomeBaseId(INMS.get().getTrueBiomeBase(player().getLocation())))));
|
||||
} catch (Throwable ee) {
|
||||
Iris.reportError(ee);
|
||||
}
|
||||
@@ -91,66 +95,66 @@ public class CommandWhat implements DirectorExecutor {
|
||||
}
|
||||
}
|
||||
|
||||
@Director(description = "What region am i in?", origin = DirectorOrigin.PLAYER)
|
||||
@Director(description = "What region am i in?", descriptionKey = "iris.director.commandwhat.director.what_region_am_i", origin = DirectorOrigin.PLAYER)
|
||||
public void region() {
|
||||
try {
|
||||
Chunk chunk = world().getChunkAt(player().getLocation().getBlockX() >> 4, player().getLocation().getBlockZ() >> 4);
|
||||
IrisRegion r = EngineBukkitOps.getRegion(engine(), chunk);
|
||||
sender().sendMessage("IRegion: " + r.getLoadKey() + " (" + r.getName() + ")");
|
||||
sender().sendMessage(IrisLanguage.text(BukkitCommandMessagesExtended.COMMAND_WHAT_IREGION, MessageArgument.untrusted("value", r.getLoadKey()), MessageArgument.untrusted("value2", r.getName())));
|
||||
|
||||
} catch (Throwable e) {
|
||||
Iris.reportError(e);
|
||||
sender().sendMessage(C.IRIS + "Iris worlds only.");
|
||||
sender().sendMessage(IrisLanguage.text(BukkitCommandMessagesExtended.COMMAND_WHAT_IRIS_WORLDS_ONLY));
|
||||
}
|
||||
}
|
||||
|
||||
@Director(description = "What block am i looking at?", origin = DirectorOrigin.PLAYER)
|
||||
@Director(description = "What block am i looking at?", descriptionKey = "iris.director.commandwhat.director.what_block_am_i_looking_at", origin = DirectorOrigin.PLAYER)
|
||||
public void block() {
|
||||
BlockData bd;
|
||||
try {
|
||||
bd = player().getTargetBlockExact(128, FluidCollisionMode.NEVER).getBlockData();
|
||||
} catch (NullPointerException e) {
|
||||
Iris.reportError(e);
|
||||
sender().sendMessage("Please look at any block, not at the sky");
|
||||
sender().sendMessage(IrisLanguage.text(BukkitCommandMessagesExtended.COMMAND_WHAT_PLEASE_LOOK_AT_ANY_BLOCK_NOT_AT_SKY));
|
||||
bd = null;
|
||||
}
|
||||
|
||||
if (bd != null) {
|
||||
sender().sendMessage("Material: " + C.GREEN + bd.getMaterial().name());
|
||||
sender().sendMessage("Full: " + C.WHITE + bd.getAsString(true));
|
||||
sender().sendMessage(IrisLanguage.text(BukkitCommandMessagesExtended.COMMAND_WHAT_MATERIAL_3, MessageArgument.untrusted("value", bd.getMaterial().name())));
|
||||
sender().sendMessage(IrisLanguage.text(BukkitCommandMessagesExtended.COMMAND_WHAT_FULL_2, MessageArgument.untrusted("value", bd.getAsString(true))));
|
||||
|
||||
if (BukkitBlockResolution.isStorage(bd)) {
|
||||
sender().sendMessage(C.YELLOW + "* Storage Block (Loot Capable)");
|
||||
sender().sendMessage(IrisLanguage.text(BukkitCommandMessagesExtended.COMMAND_WHAT_STORAGE_BLOCK_LOOT_CAPABLE));
|
||||
}
|
||||
|
||||
if (BukkitBlockResolution.isLit(bd)) {
|
||||
sender().sendMessage(C.YELLOW + "* Lit Block (Light Capable)");
|
||||
sender().sendMessage(IrisLanguage.text(BukkitCommandMessagesExtended.COMMAND_WHAT_LIT_BLOCK_LIGHT_CAPABLE));
|
||||
}
|
||||
|
||||
if (BukkitBlockResolution.isFoliage(bd)) {
|
||||
sender().sendMessage(C.YELLOW + "* Foliage Block");
|
||||
sender().sendMessage(IrisLanguage.text(BukkitCommandMessagesExtended.COMMAND_WHAT_FOLIAGE_BLOCK));
|
||||
}
|
||||
|
||||
if (BukkitBlockResolution.isDecorant(bd)) {
|
||||
sender().sendMessage(C.YELLOW + "* Decorant Block");
|
||||
sender().sendMessage(IrisLanguage.text(BukkitCommandMessagesExtended.COMMAND_WHAT_DECORANT_BLOCK));
|
||||
}
|
||||
|
||||
if (BukkitBlockResolution.isFluid(bd)) {
|
||||
sender().sendMessage(C.YELLOW + "* Fluid Block");
|
||||
sender().sendMessage(IrisLanguage.text(BukkitCommandMessagesExtended.COMMAND_WHAT_FLUID_BLOCK));
|
||||
}
|
||||
|
||||
if (BukkitBlockResolution.isFoliagePlantable(bd)) {
|
||||
sender().sendMessage(C.YELLOW + "* Plantable Foliage Block");
|
||||
sender().sendMessage(IrisLanguage.text(BukkitCommandMessagesExtended.COMMAND_WHAT_PLANTABLE_FOLIAGE_BLOCK));
|
||||
}
|
||||
|
||||
if (BukkitBlockResolution.isSolid(bd)) {
|
||||
sender().sendMessage(C.YELLOW + "* Solid Block");
|
||||
sender().sendMessage(IrisLanguage.text(BukkitCommandMessagesExtended.COMMAND_WHAT_SOLID_BLOCK));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Director(description = "Show markers in chunk", origin = DirectorOrigin.PLAYER)
|
||||
public void markers(@Param(description = "Marker name such as cave_floor or cave_ceiling") String marker) {
|
||||
@Director(description = "Show markers in chunk", descriptionKey = "iris.director.commandwhat.director.show_markers_chunk", origin = DirectorOrigin.PLAYER)
|
||||
public void markers(@Param(description = "Marker name such as cave_floor or cave_ceiling", descriptionKey = "iris.director.commandwhat.param.marker_name_such_as_cave_floor_cave_ceiling") String marker) {
|
||||
Chunk c = player().getLocation().getChunk();
|
||||
|
||||
if (IrisToolbelt.isIrisWorld(c.getWorld())) {
|
||||
@@ -167,9 +171,9 @@ public class CommandWhat implements DirectorExecutor {
|
||||
}
|
||||
}
|
||||
|
||||
sender().sendMessage("Found " + v.get() + " Nearby Markers (" + marker + ")");
|
||||
sender().sendMessage(IrisLanguage.text(BukkitCommandMessagesExtended.COMMAND_WHAT_FOUND_NEARBY_MARKERS, MessageArgument.untrusted("value", v.get()), MessageArgument.untrusted("marker", marker)));
|
||||
} else {
|
||||
sender().sendMessage(C.IRIS + "Iris worlds only.");
|
||||
sender().sendMessage(IrisLanguage.text(BukkitCommandMessagesExtended.COMMAND_WHAT_IRIS_WORLDS_ONLY_2));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -29,6 +29,7 @@ import art.arcane.iris.util.common.format.C;
|
||||
import art.arcane.iris.util.common.plugin.IrisService;
|
||||
import art.arcane.iris.util.common.plugin.VolmitSender;
|
||||
import art.arcane.iris.util.common.scheduling.J;
|
||||
import art.arcane.volmlib.util.director.DirectorEngineOptions;
|
||||
import art.arcane.volmlib.util.director.compat.DirectorEngineFactory;
|
||||
import art.arcane.volmlib.util.director.context.DirectorContextRegistry;
|
||||
import art.arcane.volmlib.util.director.runtime.DirectorExecutionMode;
|
||||
@@ -38,7 +39,8 @@ import art.arcane.volmlib.util.director.runtime.DirectorInvocationHook;
|
||||
import art.arcane.volmlib.util.director.runtime.DirectorRuntimeEngine;
|
||||
import art.arcane.volmlib.util.director.runtime.DirectorRuntimeNode;
|
||||
import art.arcane.volmlib.util.director.runtime.DirectorSender;
|
||||
import art.arcane.volmlib.util.director.visual.DirectorVisualCommand;
|
||||
import art.arcane.volmlib.util.director.help.DirectorMiniMenu;
|
||||
import art.arcane.volmlib.util.director.help.DirectorMiniMenu.DirectorHelpPage;
|
||||
import art.arcane.volmlib.util.math.RNG;
|
||||
import org.bukkit.Sound;
|
||||
import org.bukkit.command.Command;
|
||||
@@ -57,12 +59,14 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
import art.arcane.iris.core.localization.IrisLanguage;
|
||||
import art.arcane.iris.core.localization.IrisMessages;
|
||||
import art.arcane.volmlib.util.localization.MessageArgument;
|
||||
public class CommandSVC implements IrisService, CommandExecutor, TabCompleter, DirectorInvocationHook {
|
||||
private static final String ROOT_COMMAND = "iris";
|
||||
private static final String ROOT_PERMISSION = "iris.all";
|
||||
|
||||
private final transient AtomicCache<DirectorRuntimeEngine> directorCache = new AtomicCache<>();
|
||||
private final transient AtomicCache<DirectorVisualCommand> helpCache = new AtomicCache<>();
|
||||
|
||||
@Override
|
||||
public void onEnable() {
|
||||
@@ -84,11 +88,13 @@ public class CommandSVC implements IrisService, CommandExecutor, TabCompleter, D
|
||||
public DirectorRuntimeEngine getDirector() {
|
||||
return directorCache.aquireNastyPrint(() -> DirectorEngineFactory.create(
|
||||
new CommandIris(),
|
||||
null,
|
||||
buildDirectorContexts(),
|
||||
this::dispatchDirector,
|
||||
this,
|
||||
DirectorSystem.handlers
|
||||
DirectorEngineOptions.builder()
|
||||
.contexts(buildDirectorContexts())
|
||||
.dispatcher(this::dispatchDirector)
|
||||
.invocationHook(this)
|
||||
.legacyHandlers(DirectorSystem.handlers)
|
||||
.textResolver(IrisLanguage.directorResolver())
|
||||
.build()
|
||||
));
|
||||
}
|
||||
|
||||
@@ -155,7 +161,10 @@ public class CommandSVC implements IrisService, CommandExecutor, TabCompleter, D
|
||||
|
||||
void executeRoot(CommandSender sender, String label, String[] args) {
|
||||
if (!sender.hasPermission(ROOT_PERMISSION)) {
|
||||
sender.sendMessage("You lack the Permission '" + ROOT_PERMISSION + "'");
|
||||
sender.sendMessage(IrisLanguage.text(
|
||||
IrisMessages.COMMAND_PERMISSION_DENIED,
|
||||
MessageArgument.trusted("permission", ROOT_PERMISSION)
|
||||
));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -212,25 +221,24 @@ public class CommandSVC implements IrisService, CommandExecutor, TabCompleter, D
|
||||
|
||||
playFailureSound(sender);
|
||||
if (result.getMessage() == null || result.getMessage().trim().isEmpty()) {
|
||||
new VolmitSender(sender).sendMessage(C.RED + "Unknown Iris Command");
|
||||
new VolmitSender(sender).sendMessage(C.RED + IrisLanguage.text(IrisMessages.COMMAND_UNKNOWN));
|
||||
}
|
||||
}
|
||||
|
||||
private boolean sendHelpIfRequested(CommandSender sender, String[] args) {
|
||||
Optional<DirectorVisualCommand.HelpRequest> request = DirectorVisualCommand.resolveHelp(getHelpRoot(), Arrays.asList(args));
|
||||
Optional<DirectorHelpPage> request = DirectorMiniMenu.resolveHelp(getDirector(), Arrays.asList(args), 17);
|
||||
if (request.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
VolmitSender volmitSender = new VolmitSender(sender);
|
||||
volmitSender.sendDirectorHelp(request.get().command(), request.get().page());
|
||||
DirectorMiniMenu.deliver(sender, DirectorMiniMenu.render(
|
||||
request.get(),
|
||||
DirectorMiniMenu.Theme.irisGreen(),
|
||||
IrisLanguage.directorResolver()
|
||||
));
|
||||
return true;
|
||||
}
|
||||
|
||||
private DirectorVisualCommand getHelpRoot() {
|
||||
return helpCache.aquireNastyPrint(() -> DirectorVisualCommand.createRoot(getDirector()));
|
||||
}
|
||||
|
||||
private DirectorExecutionResult runDirector(CommandSender sender, String label, String[] args) {
|
||||
try {
|
||||
return getDirector().execute(new DirectorInvocation(new BukkitDirectorSender(sender), label, Arrays.asList(args)));
|
||||
|
||||
+38
-25
@@ -3,7 +3,6 @@ package art.arcane.iris.core.service;
|
||||
import art.arcane.iris.core.loader.ResourceLoader;
|
||||
import art.arcane.iris.engine.framework.MeteredCache;
|
||||
import art.arcane.iris.spi.IrisServices;
|
||||
import art.arcane.iris.util.common.format.C;
|
||||
import art.arcane.iris.util.common.plugin.VolmitSender;
|
||||
import art.arcane.iris.util.project.stream.utility.CachedDoubleStream2D;
|
||||
import art.arcane.iris.util.project.stream.utility.CachedStream2D;
|
||||
@@ -12,6 +11,10 @@ import art.arcane.volmlib.util.format.Form;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import art.arcane.iris.core.localization.IrisLanguage;
|
||||
import art.arcane.iris.core.localization.BukkitCommandMessages;
|
||||
import art.arcane.iris.core.localization.RuntimeUiMessages;
|
||||
import art.arcane.volmlib.util.localization.MessageArgument;
|
||||
final class IrisEngineStatus {
|
||||
private IrisEngineStatus() {
|
||||
}
|
||||
@@ -20,30 +23,40 @@ final class IrisEngineStatus {
|
||||
CacheSummary caches = summarizeCaches();
|
||||
MaintenanceMetrics metrics = snapshot.metrics();
|
||||
|
||||
sender.sendMessage(C.DARK_PURPLE + "-------------------------");
|
||||
sender.sendMessage(C.DARK_PURPLE + "Status:");
|
||||
sender.sendMessage(C.DARK_PURPLE + "- Service: " + C.LIGHT_PURPLE + (snapshot.serviceRunning() ? "Running" : "Stopped"));
|
||||
sender.sendMessage(C.DARK_PURPLE + "- Metrics: " + C.LIGHT_PURPLE + (snapshot.metricsRunning() ? "Running" : "Stopped"));
|
||||
sender.sendMessage(C.DARK_PURPLE + "- Maintenance Period: " + C.LIGHT_PURPLE + Form.duration(snapshot.maintenancePeriodMillis()));
|
||||
sender.sendMessage(C.DARK_PURPLE + "- Worker Parallelism: " + C.LIGHT_PURPLE + snapshot.workerParallelism());
|
||||
sender.sendMessage(C.DARK_PURPLE + "- Active World Tasks: " + C.LIGHT_PURPLE + metrics.activeTasks());
|
||||
sender.sendMessage(C.DARK_PURPLE + "Tectonic Plates:");
|
||||
sender.sendMessage(C.DARK_PURPLE + "- Configured Retention: " + C.LIGHT_PURPLE + Form.duration(snapshot.retentionMillis()));
|
||||
sender.sendMessage(C.DARK_PURPLE + "- Heap Usage: " + C.LIGHT_PURPLE + Form.pc(snapshot.heapUsage()));
|
||||
sender.sendMessage(C.DARK_PURPLE + "- Resident: " + C.LIGHT_PURPLE + metrics.residentTectonicPlates());
|
||||
sender.sendMessage(C.DARK_PURPLE + "- Queued: " + C.LIGHT_PURPLE + metrics.queuedTectonicPlates());
|
||||
sender.sendMessage(C.DARK_PURPLE + "- Average Idle Duration: " + C.LIGHT_PURPLE + Form.duration(metrics.averageIdleDuration(), 2));
|
||||
sender.sendMessage(C.DARK_PURPLE + "- Max Idle Duration: " + C.LIGHT_PURPLE + Form.duration(metrics.maxIdleDuration(), 2));
|
||||
sender.sendMessage(C.DARK_PURPLE + "- Min Idle Duration: " + C.LIGHT_PURPLE + Form.duration(metrics.minIdleDuration(), 2));
|
||||
sender.sendMessage(C.DARK_PURPLE + "Caches:");
|
||||
sender.sendMessage(C.DARK_PURPLE + "- Resource: " + C.LIGHT_PURPLE + caches.sizes()[0] + " (" + caches.counts()[0] + ")");
|
||||
sender.sendMessage(C.DARK_PURPLE + "- 2D Stream: " + C.LIGHT_PURPLE + caches.sizes()[1] + " (" + caches.counts()[1] + ")");
|
||||
sender.sendMessage(C.DARK_PURPLE + "- 3D Stream: " + C.LIGHT_PURPLE + caches.sizes()[2] + " (" + caches.counts()[2] + ")");
|
||||
sender.sendMessage(C.DARK_PURPLE + "- Other: " + C.LIGHT_PURPLE + caches.sizes()[3] + " (" + caches.counts()[3] + ")");
|
||||
sender.sendMessage(C.DARK_PURPLE + "Other:");
|
||||
sender.sendMessage(C.DARK_PURPLE + "- Iris Worlds: " + C.LIGHT_PURPLE + metrics.worlds());
|
||||
sender.sendMessage(C.DARK_PURPLE + "- Loaded Chunks: " + C.LIGHT_PURPLE + metrics.loadedChunks());
|
||||
sender.sendMessage(C.DARK_PURPLE + "-------------------------");
|
||||
sender.sendMessage(IrisLanguage.text(BukkitCommandMessages.IRIS_ENGINE_STATUS_MESSAGE));
|
||||
sender.sendMessage(IrisLanguage.text(BukkitCommandMessages.IRIS_ENGINE_STATUS_STATUS));
|
||||
sender.sendMessage(IrisLanguage.text(
|
||||
BukkitCommandMessages.IRIS_ENGINE_STATUS_SERVICE,
|
||||
MessageArgument.trusted("value", status(snapshot.serviceRunning()))
|
||||
));
|
||||
sender.sendMessage(IrisLanguage.text(
|
||||
BukkitCommandMessages.IRIS_ENGINE_STATUS_METRICS,
|
||||
MessageArgument.trusted("value", status(snapshot.metricsRunning()))
|
||||
));
|
||||
sender.sendMessage(IrisLanguage.text(BukkitCommandMessages.IRIS_ENGINE_STATUS_MAINTENANCE_PERIOD, MessageArgument.untrusted("value", Form.duration(snapshot.maintenancePeriodMillis()))));
|
||||
sender.sendMessage(IrisLanguage.text(BukkitCommandMessages.IRIS_ENGINE_STATUS_WORKER_PARALLELISM, MessageArgument.untrusted("value", snapshot.workerParallelism())));
|
||||
sender.sendMessage(IrisLanguage.text(BukkitCommandMessages.IRIS_ENGINE_STATUS_ACTIVE_WORLD_TASKS, MessageArgument.untrusted("value", metrics.activeTasks())));
|
||||
sender.sendMessage(IrisLanguage.text(BukkitCommandMessages.IRIS_ENGINE_STATUS_TECTONIC_PLATES));
|
||||
sender.sendMessage(IrisLanguage.text(BukkitCommandMessages.IRIS_ENGINE_STATUS_CONFIGURED_RETENTION, MessageArgument.untrusted("value", Form.duration(snapshot.retentionMillis()))));
|
||||
sender.sendMessage(IrisLanguage.text(BukkitCommandMessages.IRIS_ENGINE_STATUS_HEAP_USAGE, MessageArgument.untrusted("value", Form.pc(snapshot.heapUsage()))));
|
||||
sender.sendMessage(IrisLanguage.text(BukkitCommandMessages.IRIS_ENGINE_STATUS_RESIDENT, MessageArgument.untrusted("value", metrics.residentTectonicPlates())));
|
||||
sender.sendMessage(IrisLanguage.text(BukkitCommandMessages.IRIS_ENGINE_STATUS_QUEUED, MessageArgument.untrusted("value", metrics.queuedTectonicPlates())));
|
||||
sender.sendMessage(IrisLanguage.text(BukkitCommandMessages.IRIS_ENGINE_STATUS_AVERAGE_IDLE_DURATION, MessageArgument.untrusted("value", Form.duration(metrics.averageIdleDuration(), 2))));
|
||||
sender.sendMessage(IrisLanguage.text(BukkitCommandMessages.IRIS_ENGINE_STATUS_MAX_IDLE_DURATION, MessageArgument.untrusted("value", Form.duration(metrics.maxIdleDuration(), 2))));
|
||||
sender.sendMessage(IrisLanguage.text(BukkitCommandMessages.IRIS_ENGINE_STATUS_MIN_IDLE_DURATION, MessageArgument.untrusted("value", Form.duration(metrics.minIdleDuration(), 2))));
|
||||
sender.sendMessage(IrisLanguage.text(BukkitCommandMessages.IRIS_ENGINE_STATUS_CACHES));
|
||||
sender.sendMessage(IrisLanguage.text(BukkitCommandMessages.IRIS_ENGINE_STATUS_RESOURCE, MessageArgument.untrusted("value", caches.sizes()[0]), MessageArgument.untrusted("value2", caches.counts()[0])));
|
||||
sender.sendMessage(IrisLanguage.text(BukkitCommandMessages.IRIS_ENGINE_STATUS_2D_STREAM, MessageArgument.untrusted("value", caches.sizes()[1]), MessageArgument.untrusted("value2", caches.counts()[1])));
|
||||
sender.sendMessage(IrisLanguage.text(BukkitCommandMessages.IRIS_ENGINE_STATUS_3D_STREAM, MessageArgument.untrusted("value", caches.sizes()[2]), MessageArgument.untrusted("value2", caches.counts()[2])));
|
||||
sender.sendMessage(IrisLanguage.text(BukkitCommandMessages.IRIS_ENGINE_STATUS_OTHER, MessageArgument.untrusted("value", caches.sizes()[3]), MessageArgument.untrusted("value2", caches.counts()[3])));
|
||||
sender.sendMessage(IrisLanguage.text(BukkitCommandMessages.IRIS_ENGINE_STATUS_OTHER_2));
|
||||
sender.sendMessage(IrisLanguage.text(BukkitCommandMessages.IRIS_ENGINE_STATUS_IRIS_WORLDS, MessageArgument.untrusted("value", metrics.worlds())));
|
||||
sender.sendMessage(IrisLanguage.text(BukkitCommandMessages.IRIS_ENGINE_STATUS_LOADED_CHUNKS, MessageArgument.untrusted("value", metrics.loadedChunks())));
|
||||
sender.sendMessage(IrisLanguage.text(BukkitCommandMessages.IRIS_ENGINE_STATUS_MESSAGE_2));
|
||||
}
|
||||
|
||||
private static String status(boolean running) {
|
||||
return IrisLanguage.text(running ? RuntimeUiMessages.STATUS_RUNNING : RuntimeUiMessages.STATUS_STOPPED);
|
||||
}
|
||||
|
||||
private static CacheSummary summarizeCaches() {
|
||||
|
||||
@@ -22,11 +22,14 @@ import org.bukkit.Bukkit;
|
||||
import org.bukkit.Chunk;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.NamespacedKey;
|
||||
import org.bukkit.Particle;
|
||||
import org.bukkit.Sound;
|
||||
import org.bukkit.World;
|
||||
import art.arcane.iris.Iris;
|
||||
import art.arcane.iris.core.IrisSettings;
|
||||
import art.arcane.iris.core.localization.IrisLanguage;
|
||||
import art.arcane.iris.core.localization.RuntimeUiMessages;
|
||||
import art.arcane.iris.core.edit.DustRevealer;
|
||||
import art.arcane.iris.core.link.WorldEditLink;
|
||||
import art.arcane.iris.core.wand.WandSelection;
|
||||
@@ -53,11 +56,11 @@ import org.bukkit.inventory.Inventory;
|
||||
import org.bukkit.inventory.ItemFlag;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.meta.ItemMeta;
|
||||
import org.bukkit.persistence.PersistentDataType;
|
||||
import org.bukkit.util.BlockVector;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
|
||||
@@ -103,7 +106,7 @@ public class WandSVC implements IrisService {
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "Scanning Selection";
|
||||
return IrisLanguage.text(RuntimeUiMessages.JOB_SCANNING_SELECTION);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -253,10 +256,11 @@ public class WandSVC implements IrisService {
|
||||
ItemStack is = new ItemStack(Material.GLOWSTONE_DUST);
|
||||
is.addUnsafeEnchantment(Enchantment.FIRE_ASPECT, 1);
|
||||
ItemMeta im = is.getItemMeta();
|
||||
im.setDisplayName(C.BOLD + "" + C.YELLOW + "Dust of Revealing");
|
||||
im.setDisplayName(C.BOLD + "" + C.YELLOW + IrisLanguage.text(RuntimeUiMessages.DUST_NAME));
|
||||
im.setUnbreakable(true);
|
||||
im.addItemFlags(ItemFlag.values());
|
||||
im.setLore(new KList<String>().qadd("Right click on a block to reveal it's placement structure!"));
|
||||
im.setLore(new KList<String>().qadd(IrisLanguage.text(RuntimeUiMessages.DUST_LORE)));
|
||||
im.getPersistentDataContainer().set(dustKey(), PersistentDataType.BYTE, (byte) 1);
|
||||
is.setItemMeta(im);
|
||||
|
||||
return is;
|
||||
@@ -269,19 +273,11 @@ public class WandSVC implements IrisService {
|
||||
* @return The slot number the wand is in. Or -1 if none are found
|
||||
*/
|
||||
public static int findWand(Inventory inventory) {
|
||||
ItemStack wand = createWand(); //Create blank wand
|
||||
ItemMeta meta = wand.getItemMeta();
|
||||
meta.setLore(new ArrayList<>()); //We are resetting the lore as the lore differs between wands
|
||||
wand.setItemMeta(meta);
|
||||
|
||||
for (int s = 0; s < inventory.getSize(); s++) {
|
||||
ItemStack stack = inventory.getItem(s);
|
||||
if (stack == null) continue;
|
||||
meta = stack.getItemMeta();
|
||||
meta.setLore(new ArrayList<>()); //Reset the lore on this too so we can compare them
|
||||
stack.setItemMeta(meta); //We dont need to clone the item as items from .get are cloned
|
||||
|
||||
if (wand.isSimilar(stack)) return s; //If the name, material and NBT is the same
|
||||
if (stack != null && isWand(stack)) {
|
||||
return s;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
@@ -297,10 +293,14 @@ public class WandSVC implements IrisService {
|
||||
ItemStack is = new ItemStack(Material.BLAZE_ROD);
|
||||
is.addUnsafeEnchantment(Enchantment.FIRE_ASPECT, 1);
|
||||
ItemMeta im = is.getItemMeta();
|
||||
im.setDisplayName(C.BOLD + "" + C.GOLD + "Wand of Iris");
|
||||
im.setDisplayName(C.BOLD + "" + C.GOLD + IrisLanguage.text(RuntimeUiMessages.WAND_NAME));
|
||||
im.setUnbreakable(true);
|
||||
im.addItemFlags(ItemFlag.values());
|
||||
im.setLore(new KList<String>().add(locationToString(a), locationToString(b)));
|
||||
im.setLore(new KList<String>().add(
|
||||
a == null ? IrisLanguage.text(RuntimeUiMessages.WAND_LORE_FIRST) : locationToString(a),
|
||||
b == null ? IrisLanguage.text(RuntimeUiMessages.WAND_LORE_SECOND) : locationToString(b)
|
||||
));
|
||||
im.getPersistentDataContainer().set(wandKey(), PersistentDataType.BYTE, (byte) 1);
|
||||
is.setItemMeta(im);
|
||||
|
||||
return is;
|
||||
@@ -343,7 +343,13 @@ public class WandSVC implements IrisService {
|
||||
* @return True if it is
|
||||
*/
|
||||
public static boolean isWand(ItemStack is) {
|
||||
if (is.getItemMeta() == null) return false;
|
||||
if (is == null || is.getItemMeta() == null) {
|
||||
return false;
|
||||
}
|
||||
Byte marker = is.getItemMeta().getPersistentDataContainer().get(wandKey(), PersistentDataType.BYTE);
|
||||
if (marker != null && marker == (byte) 1) {
|
||||
return true;
|
||||
}
|
||||
return is.getType().equals(wand.getType()) &&
|
||||
is.getItemMeta().getDisplayName().equals(wand.getItemMeta().getDisplayName()) &&
|
||||
is.getItemMeta().getEnchants().equals(wand.getItemMeta().getEnchants()) &&
|
||||
@@ -517,7 +523,19 @@ public class WandSVC implements IrisService {
|
||||
* @return True if it is
|
||||
*/
|
||||
public boolean isDust(ItemStack is) {
|
||||
return is.isSimilar(dust);
|
||||
if (is == null || is.getItemMeta() == null) {
|
||||
return false;
|
||||
}
|
||||
Byte marker = is.getItemMeta().getPersistentDataContainer().get(dustKey(), PersistentDataType.BYTE);
|
||||
return (marker != null && marker == (byte) 1) || is.isSimilar(dust);
|
||||
}
|
||||
|
||||
private static NamespacedKey wandKey() {
|
||||
return new NamespacedKey(Iris.instance, "wand");
|
||||
}
|
||||
|
||||
private static NamespacedKey dustKey() {
|
||||
return new NamespacedKey(Iris.instance, "dust");
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
package art.arcane.iris.client;
|
||||
|
||||
import art.arcane.iris.core.localization.ClientUiMessages;
|
||||
import art.arcane.iris.core.localization.IrisLanguage;
|
||||
import art.arcane.iris.spi.protocol.IrisMessage;
|
||||
import art.arcane.volmlib.util.localization.MessageArgument;
|
||||
|
||||
import java.util.ArrayDeque;
|
||||
|
||||
@@ -25,7 +28,7 @@ public final class IrisClientToasts {
|
||||
|
||||
public void enqueueHotload(String packKey, int changedFiles, boolean failed, String message) {
|
||||
int kind = failed ? IrisMessage.Toast.KIND_ERROR : IrisMessage.Toast.KIND_SUCCESS;
|
||||
enqueue(kind, "Studio Hotload", hotloadBody(packKey, changedFiles, failed, message));
|
||||
enqueue(kind, IrisLanguage.plain(ClientUiMessages.TOAST_STUDIO_HOTLOAD), hotloadBody(packKey, changedFiles, failed, message));
|
||||
}
|
||||
|
||||
public Pending poll() {
|
||||
@@ -51,14 +54,14 @@ public final class IrisClientToasts {
|
||||
builder.append(pack);
|
||||
}
|
||||
if (changedFiles != 0) {
|
||||
append(builder, changedFiles + (changedFiles == 1 ? " file" : " files"));
|
||||
append(builder, IrisLanguage.plain(ClientUiMessages.TOAST_CHANGED_FILES, MessageArgument.trusted("count", changedFiles)));
|
||||
}
|
||||
String text = normalize(message);
|
||||
if (!text.isEmpty()) {
|
||||
append(builder, text);
|
||||
}
|
||||
if (builder.isEmpty()) {
|
||||
return failed ? "reload failed" : "reloaded";
|
||||
return IrisLanguage.plain(failed ? ClientUiMessages.TOAST_RELOAD_FAILED : ClientUiMessages.TOAST_RELOADED);
|
||||
}
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
package art.arcane.iris.client;
|
||||
|
||||
import art.arcane.iris.core.localization.ClientUiMessages;
|
||||
import art.arcane.iris.core.localization.IrisLanguage;
|
||||
import art.arcane.iris.core.localization.RuntimeUiMessages;
|
||||
import art.arcane.iris.spi.protocol.IrisMessage;
|
||||
import art.arcane.volmlib.util.localization.MessageArgument;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.gui.Font;
|
||||
import net.minecraft.client.gui.GuiGraphicsExtractor;
|
||||
@@ -47,9 +51,14 @@ public final class IrisPregenHud {
|
||||
double percent = progress.chunksTotal() > 0L
|
||||
? clampPercent((double) progress.chunksDone() / (double) progress.chunksTotal() * 100.0D)
|
||||
: 0.0D;
|
||||
String title = "Iris Pregen";
|
||||
String stats = String.format("%,d / %,d (%.1f%%)", progress.chunksDone(), progress.chunksTotal(), percent);
|
||||
String tail = paused ? "PAUSED" : rateAndEta(progress);
|
||||
String title = IrisLanguage.plain(RuntimeUiMessages.PREGEN_HEADER);
|
||||
String stats = IrisLanguage.plain(
|
||||
ClientUiMessages.PREGEN_STATS,
|
||||
MessageArgument.trusted("done", String.format("%,d", progress.chunksDone())),
|
||||
MessageArgument.trusted("total", String.format("%,d", progress.chunksTotal())),
|
||||
MessageArgument.trusted("percent", String.format("%.1f", percent))
|
||||
);
|
||||
String tail = paused ? IrisLanguage.plain(ClientUiMessages.PREGEN_PAUSED) : rateAndEta(progress);
|
||||
int accent = paused ? PAUSED_COLOR : BAR_RUNNING_COLOR;
|
||||
|
||||
int lineHeight = font.lineHeight;
|
||||
@@ -120,11 +129,15 @@ public final class IrisPregenHud {
|
||||
}
|
||||
|
||||
private static String rateAndEta(IrisMessage.PregenProgress progress) {
|
||||
String rate = String.format("%,.0f/s", progress.chunksPerSecond());
|
||||
String rate = String.format("%,.0f", progress.chunksPerSecond());
|
||||
if (progress.etaMillis() > 0L) {
|
||||
return rate + " ETA " + formatDuration(progress.etaMillis());
|
||||
return IrisLanguage.plain(
|
||||
ClientUiMessages.PREGEN_RATE_ETA,
|
||||
MessageArgument.trusted("rate", rate),
|
||||
MessageArgument.trusted("eta", formatDuration(progress.etaMillis()))
|
||||
);
|
||||
}
|
||||
return rate;
|
||||
return IrisLanguage.plain(ClientUiMessages.PREGEN_RATE, MessageArgument.trusted("rate", rate));
|
||||
}
|
||||
|
||||
private static String formatDuration(long etaMillis) {
|
||||
@@ -133,12 +146,12 @@ public final class IrisPregenHud {
|
||||
long minutes = (totalSeconds % 3600L) / 60L;
|
||||
long seconds = totalSeconds % 60L;
|
||||
if (hours > 0L) {
|
||||
return hours + "h " + minutes + "m";
|
||||
return IrisLanguage.plain(ClientUiMessages.DURATION_HOURS_MINUTES, MessageArgument.trusted("hours", hours), MessageArgument.trusted("minutes", minutes));
|
||||
}
|
||||
if (minutes > 0L) {
|
||||
return minutes + "m " + seconds + "s";
|
||||
return IrisLanguage.plain(ClientUiMessages.DURATION_MINUTES_SECONDS, MessageArgument.trusted("minutes", minutes), MessageArgument.trusted("seconds", seconds));
|
||||
}
|
||||
return seconds + "s";
|
||||
return IrisLanguage.plain(ClientUiMessages.DURATION_SECONDS, MessageArgument.trusted("seconds", seconds));
|
||||
}
|
||||
|
||||
private static double clampPercent(double value) {
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
package art.arcane.iris.client;
|
||||
|
||||
import art.arcane.iris.core.localization.ClientUiMessages;
|
||||
import art.arcane.iris.core.localization.IrisLanguage;
|
||||
import art.arcane.iris.spi.protocol.IrisMessage;
|
||||
import art.arcane.volmlib.util.localization.MessageArgument;
|
||||
import com.mojang.blaze3d.platform.NativeImage;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.gui.GuiGraphicsExtractor;
|
||||
@@ -45,7 +48,7 @@ public final class IrisVisionScreen extends Screen {
|
||||
private String renderedDimensionKey;
|
||||
|
||||
public IrisVisionScreen() {
|
||||
super(Component.literal("Iris Vision"));
|
||||
super(Component.literal(IrisLanguage.plain(ClientUiMessages.VISION_TITLE)));
|
||||
this.textures = new LinkedHashMap<>(64, 0.75f, true);
|
||||
this.centerBlockX = 0.0D;
|
||||
this.centerBlockZ = 0.0D;
|
||||
@@ -72,14 +75,14 @@ public final class IrisVisionScreen extends Screen {
|
||||
graphics.fill(0, 0, width, height, BACKGROUND_COLOR);
|
||||
IrisClientSession session = IrisClient.session();
|
||||
if (!session.isReady()) {
|
||||
drawCentered(graphics, "Connecting to Iris server...", MUTED_COLOR);
|
||||
drawHeader(graphics, "Iris Vision", "not connected");
|
||||
drawCentered(graphics, IrisLanguage.plain(ClientUiMessages.VISION_CONNECTING), MUTED_COLOR);
|
||||
drawHeader(graphics, IrisLanguage.plain(ClientUiMessages.VISION_TITLE), IrisLanguage.plain(ClientUiMessages.VISION_NOT_CONNECTED));
|
||||
return;
|
||||
}
|
||||
IrisMessage.DimensionStatus status = IrisClient.dimension().status();
|
||||
if (!IrisClient.visionAvailable() || status == null) {
|
||||
drawCentered(graphics, "Not an Iris world", MUTED_COLOR);
|
||||
drawHeader(graphics, "Iris Vision", status == null ? "no dimension data" : label(status));
|
||||
drawCentered(graphics, IrisLanguage.plain(ClientUiMessages.VISION_NOT_IRIS_WORLD), MUTED_COLOR);
|
||||
drawHeader(graphics, IrisLanguage.plain(ClientUiMessages.VISION_TITLE), status == null ? IrisLanguage.plain(ClientUiMessages.VISION_NO_DIMENSION_DATA) : label(status));
|
||||
return;
|
||||
}
|
||||
syncWorld(status);
|
||||
@@ -159,8 +162,18 @@ public final class IrisVisionScreen extends Screen {
|
||||
|
||||
drawMarkers(graphics, mouseX, mouseY, minTileX, maxTileX, minTileZ, maxTileZ, originX, originY, blocksPerPixel);
|
||||
drawPlayer(graphics, blocksPerPixel);
|
||||
drawHeader(graphics, "Iris Vision", label(status) + " zoom " + zoom + " x" + (long) centerBlockX + " z" + (long) centerBlockZ);
|
||||
drawFooter(graphics, "Drag to pan Scroll to zoom Esc to close");
|
||||
drawHeader(
|
||||
graphics,
|
||||
IrisLanguage.plain(ClientUiMessages.VISION_TITLE),
|
||||
IrisLanguage.plain(
|
||||
ClientUiMessages.VISION_HEADER_DETAIL,
|
||||
MessageArgument.trusted("status", label(status)),
|
||||
MessageArgument.trusted("zoom", zoom),
|
||||
MessageArgument.trusted("x", (long) centerBlockX),
|
||||
MessageArgument.trusted("z", (long) centerBlockZ)
|
||||
)
|
||||
);
|
||||
drawFooter(graphics, IrisLanguage.plain(ClientUiMessages.VISION_FOOTER_HINT));
|
||||
}
|
||||
|
||||
private void requestMissing(IrisClientTileCache cache, List<IrisTileKey> missing, int centerTileX, int centerTileZ) {
|
||||
@@ -319,8 +332,14 @@ public final class IrisVisionScreen extends Screen {
|
||||
}
|
||||
|
||||
private static String label(IrisMessage.DimensionStatus status) {
|
||||
String pack = status.packKey() == null || status.packKey().isEmpty() ? "" : " pack " + status.packKey();
|
||||
return status.dimensionKey() + pack;
|
||||
if (status.packKey() == null || status.packKey().isEmpty()) {
|
||||
return String.valueOf(status.dimensionKey());
|
||||
}
|
||||
return IrisLanguage.plain(
|
||||
ClientUiMessages.VISION_DIMENSION_PACK,
|
||||
MessageArgument.untrusted("dimension", String.valueOf(status.dimensionKey())),
|
||||
MessageArgument.untrusted("pack", status.packKey())
|
||||
);
|
||||
}
|
||||
|
||||
private record TileTexture(Identifier id, DynamicTexture texture) {
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
package art.arcane.iris.client;
|
||||
|
||||
import art.arcane.iris.core.localization.ClientUiMessages;
|
||||
import art.arcane.iris.core.localization.IrisLanguage;
|
||||
import art.arcane.iris.spi.protocol.IrisMessage;
|
||||
import art.arcane.volmlib.util.localization.MessageArgument;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.gui.Font;
|
||||
import net.minecraft.client.gui.GuiGraphicsExtractor;
|
||||
@@ -44,25 +47,31 @@ public final class IrisWhatOverlay {
|
||||
IrisClient.cursor().requestFor(blockX, blockZ);
|
||||
|
||||
IrisMessage.CursorInfo info = IrisClient.cursor().latest();
|
||||
List<String> lines = new ArrayList<>();
|
||||
List<OverlayLine> lines = new ArrayList<>();
|
||||
if (info == null) {
|
||||
lines.add("querying " + blockX + ", " + blockZ + "...");
|
||||
lines.add(new OverlayLine(IrisLanguage.plain(ClientUiMessages.WHAT_QUERYING, MessageArgument.trusted("x", blockX), MessageArgument.trusted("z", blockZ)), false));
|
||||
} else {
|
||||
lines.add("Biome: " + display(info.biomeKey()));
|
||||
lines.add("Region: " + display(info.regionKey()));
|
||||
lines.add(new OverlayLine(IrisLanguage.plain(ClientUiMessages.WHAT_BIOME, MessageArgument.untrusted("biome", display(info.biomeKey()))), false));
|
||||
lines.add(new OverlayLine(IrisLanguage.plain(ClientUiMessages.WHAT_REGION, MessageArgument.untrusted("region", display(info.regionKey()))), false));
|
||||
if (info.caveBiomeKey() != null && !info.caveBiomeKey().isEmpty()) {
|
||||
lines.add("Cave: " + display(info.caveBiomeKey()));
|
||||
lines.add(new OverlayLine(IrisLanguage.plain(ClientUiMessages.WHAT_CAVE, MessageArgument.untrusted("cave", display(info.caveBiomeKey()))), false));
|
||||
}
|
||||
lines.add("Height: " + info.height() + " (" + info.blockX() + ", " + info.blockZ() + ")");
|
||||
lines.add(new OverlayLine(IrisLanguage.plain(
|
||||
ClientUiMessages.WHAT_HEIGHT,
|
||||
MessageArgument.trusted("height", info.height()),
|
||||
MessageArgument.trusted("x", info.blockX()),
|
||||
MessageArgument.trusted("z", info.blockZ())
|
||||
), true));
|
||||
}
|
||||
draw(graphics, minecraft.font, lines);
|
||||
}
|
||||
|
||||
private static void draw(GuiGraphicsExtractor graphics, Font font, List<String> lines) {
|
||||
private static void draw(GuiGraphicsExtractor graphics, Font font, List<OverlayLine> lines) {
|
||||
int lineHeight = font.lineHeight;
|
||||
int contentWidth = font.width("Iris What");
|
||||
for (String line : lines) {
|
||||
contentWidth = Math.max(contentWidth, font.width(line));
|
||||
String title = IrisLanguage.plain(ClientUiMessages.WHAT_TITLE);
|
||||
int contentWidth = font.width(title);
|
||||
for (OverlayLine line : lines) {
|
||||
contentWidth = Math.max(contentWidth, font.width(line.text()));
|
||||
}
|
||||
int originX = graphics.guiWidth() / 2 + CURSOR_OFFSET;
|
||||
int originY = graphics.guiHeight() / 2 + CURSOR_OFFSET;
|
||||
@@ -71,10 +80,10 @@ public final class IrisWhatOverlay {
|
||||
graphics.fill(originX - PADDING, originY - PADDING, originX + contentWidth + PADDING, originY + contentHeight + PADDING, PANEL_COLOR);
|
||||
|
||||
int cursorY = originY;
|
||||
graphics.text(font, "Iris What", originX, cursorY, TITLE_COLOR);
|
||||
graphics.text(font, title, originX, cursorY, TITLE_COLOR);
|
||||
cursorY += lineHeight + ROW_GAP;
|
||||
for (String line : lines) {
|
||||
graphics.text(font, line, originX, cursorY, line.startsWith("Height") ? MUTED_COLOR : TEXT_COLOR);
|
||||
for (OverlayLine line : lines) {
|
||||
graphics.text(font, line.text(), originX, cursorY, line.muted() ? MUTED_COLOR : TEXT_COLOR);
|
||||
cursorY += lineHeight + ROW_GAP;
|
||||
}
|
||||
}
|
||||
@@ -82,4 +91,7 @@ public final class IrisWhatOverlay {
|
||||
private static String display(String key) {
|
||||
return key == null || key.isEmpty() ? "-" : key;
|
||||
}
|
||||
|
||||
private record OverlayLine(String text, boolean muted) {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,3 +4,4 @@ accessible field net/minecraft/server/MinecraftServer executor Ljava/util/concur
|
||||
accessible field net/minecraft/server/MinecraftServer storageSource Lnet/minecraft/world/level/storage/LevelStorageSource$LevelStorageAccess;
|
||||
accessible field net/minecraft/server/packs/repository/PackRepository sources Ljava/util/Set;
|
||||
mutable field net/minecraft/server/packs/repository/PackRepository sources Ljava/util/Set;
|
||||
accessible field net/minecraft/core/MappedRegistry frozen Z
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
public net.minecraft.server.MinecraftServer levels
|
||||
public net.minecraft.server.MinecraftServer executor
|
||||
public net.minecraft.server.MinecraftServer storageSource
|
||||
public net.minecraft.core.MappedRegistry frozen
|
||||
|
||||
+15
-4
@@ -152,9 +152,19 @@ public final class ModdedDimensionManager {
|
||||
}
|
||||
|
||||
public static Handle createPersistent(MinecraftServer server, String dimensionId, String pack, String packDimensionKey, long seed) {
|
||||
Handle handle = create(server, dimensionId, pack, packDimensionKey, seed);
|
||||
ModdedDimensionRegistryStore.put(server, new ModdedDimensionRegistryStore.PersistentDimension(dimensionId, pack, packDimensionKey, seed));
|
||||
return handle;
|
||||
try {
|
||||
return create(server, dimensionId, pack, packDimensionKey, seed);
|
||||
} catch (Throwable e) {
|
||||
ModdedDimensionRegistryStore.remove(server, dimensionId);
|
||||
if (e instanceof RuntimeException runtimeException) {
|
||||
throw runtimeException;
|
||||
}
|
||||
if (e instanceof Error fatalError) {
|
||||
throw fatalError;
|
||||
}
|
||||
throw new IllegalStateException("Iris runtime dimension injection failed for " + dimensionId, e);
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean removePersistent(MinecraftServer server, String dimensionId, boolean wipeStorage) {
|
||||
@@ -265,9 +275,10 @@ public final class ModdedDimensionManager {
|
||||
IrisDimension dimension = loadPackDimension(pack, packDimensionKey);
|
||||
String typeRef = ModdedForcedDatapack.dimensionTypeRef(dimension);
|
||||
ResourceKey<DimensionType> typeKey = ResourceKey.create(Registries.DIMENSION_TYPE, Identifier.parse(typeRef));
|
||||
Holder.Reference<DimensionType> packType = ModdedForcedDatapack.requireRegisteredDimensionType(
|
||||
ModdedRuntimeRegistry.ensureCustomBiomes(registryAccess, dimension, pack);
|
||||
ModdedRuntimeRegistry.ensureDimensionType(registryAccess, registry, typeKey, typeRef, dimension);
|
||||
return ModdedForcedDatapack.requireRegisteredDimensionType(
|
||||
typeRef, registry.get(typeKey), pack, packDimensionKey);
|
||||
return packType;
|
||||
}
|
||||
|
||||
private static IrisDimension loadPackDimension(String pack, String packDimensionKey) {
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
package art.arcane.iris.modded;
|
||||
|
||||
import art.arcane.iris.core.gui.GuiHost;
|
||||
import art.arcane.iris.core.localization.IrisLanguage;
|
||||
import art.arcane.iris.engine.decorator.DecoratorPlatformHooks;
|
||||
import art.arcane.iris.engine.framework.Engine;
|
||||
import art.arcane.iris.engine.framework.EngineEffectsProvider;
|
||||
@@ -260,6 +261,7 @@ public final class ModdedEngineBootstrap {
|
||||
ModdedIrisLog.info("Iris " + moddedLoader.modVersion() + " bootstrapping on Minecraft " + moddedLoader.minecraftVersion() + " (" + loaderDescription + ")");
|
||||
selfTest(moddedLoader.getClass().getClassLoader());
|
||||
bind();
|
||||
IrisLanguage.initialize();
|
||||
MainWorldService.reconcileEarly();
|
||||
chunkGeneratorRegistration.run();
|
||||
ModdedIrisLog.info("Iris chunk generator registered as irisworldgen:iris");
|
||||
|
||||
+3
-1
@@ -19,6 +19,8 @@
|
||||
package art.arcane.iris.modded;
|
||||
|
||||
import art.arcane.iris.core.loader.IrisData;
|
||||
import art.arcane.iris.core.localization.IrisLanguage;
|
||||
import art.arcane.iris.core.localization.RuntimeUiMessages;
|
||||
import art.arcane.iris.core.nms.datapack.DataVersion;
|
||||
import art.arcane.iris.core.nms.datapack.IDataFixer;
|
||||
import art.arcane.iris.engine.object.IrisDimension;
|
||||
@@ -85,7 +87,7 @@ public final class ModdedForcedDatapack {
|
||||
private static Pack requireReadablePack(Path directory) {
|
||||
PackLocationInfo location = new PackLocationInfo(
|
||||
PACK_ID,
|
||||
Component.literal("Iris World Generation"),
|
||||
Component.literal(IrisLanguage.plain(RuntimeUiMessages.FORCED_DATAPACK_NAME)),
|
||||
PackSource.BUILT_IN,
|
||||
Optional.empty());
|
||||
PackSelectionConfig selection = new PackSelectionConfig(true, Pack.Position.TOP, true);
|
||||
|
||||
+10
-3
@@ -18,7 +18,10 @@
|
||||
|
||||
package art.arcane.iris.modded;
|
||||
|
||||
import art.arcane.iris.core.localization.IrisLanguage;
|
||||
import art.arcane.iris.core.localization.PackDownloadMessages;
|
||||
import art.arcane.iris.core.pack.PackDownloader;
|
||||
import art.arcane.volmlib.util.localization.MessageArgument;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
@@ -38,11 +41,11 @@ public final class ModdedPackInstaller {
|
||||
|
||||
public static boolean install(Path configDir, String pack, String branch, Consumer<String> feedback) {
|
||||
if (pack == null || !PACK_NAME.matcher(pack).matches()) {
|
||||
feedback.accept("Invalid pack name '" + pack + "' (allowed: a-z, 0-9, _ and -)");
|
||||
feedback.accept(IrisLanguage.plain(PackDownloadMessages.INVALID_PACK_NAME, MessageArgument.untrusted("pack", String.valueOf(pack))));
|
||||
return false;
|
||||
}
|
||||
if (branch == null || !BRANCH_NAME.matcher(branch).matches()) {
|
||||
feedback.accept("Invalid branch name '" + branch + "' (allowed: letters, digits, . _ and -)");
|
||||
feedback.accept(IrisLanguage.plain(PackDownloadMessages.INVALID_BRANCH_NAME, MessageArgument.untrusted("branch", String.valueOf(branch))));
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -54,7 +57,11 @@ public final class ModdedPackInstaller {
|
||||
return PackDownloader.download(packs, "IrisDimensions/" + pack, branch, true, false, feedback) != null;
|
||||
} catch (IOException error) {
|
||||
LOGGER.error("Iris pack download failed for IrisDimensions/{} ({})", pack, branch, error);
|
||||
feedback.accept("Pack download failed: " + error.getClass().getSimpleName() + (error.getMessage() == null ? "" : " - " + error.getMessage()));
|
||||
feedback.accept(IrisLanguage.plain(
|
||||
PackDownloadMessages.DOWNLOAD_FAILED,
|
||||
MessageArgument.untrusted("type", error.getClass().getSimpleName()),
|
||||
MessageArgument.trusted("errorMessage", IrisLanguage.errorDetail(error))
|
||||
));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
+136
@@ -0,0 +1,136 @@
|
||||
/*
|
||||
* Iris is a World Generator for Minecraft Servers
|
||||
* Copyright (c) 2026 Arcane Arts (Volmit Software)
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package art.arcane.iris.modded;
|
||||
|
||||
import art.arcane.iris.core.loader.IrisData;
|
||||
import art.arcane.iris.core.nms.datapack.DataVersion;
|
||||
import art.arcane.iris.core.nms.datapack.IDataFixer;
|
||||
import art.arcane.iris.engine.object.IrisBiome;
|
||||
import art.arcane.iris.engine.object.IrisBiomeCustom;
|
||||
import art.arcane.iris.engine.object.IrisDimension;
|
||||
import art.arcane.iris.util.common.data.DataProvider;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonParser;
|
||||
import com.mojang.serialization.Codec;
|
||||
import com.mojang.serialization.JsonOps;
|
||||
import net.minecraft.core.Holder;
|
||||
import net.minecraft.core.MappedRegistry;
|
||||
import net.minecraft.core.RegistrationInfo;
|
||||
import net.minecraft.core.Registry;
|
||||
import net.minecraft.core.RegistryAccess;
|
||||
import net.minecraft.core.registries.Registries;
|
||||
import net.minecraft.resources.Identifier;
|
||||
import net.minecraft.resources.RegistryOps;
|
||||
import net.minecraft.resources.ResourceKey;
|
||||
import net.minecraft.world.level.biome.Biome;
|
||||
import net.minecraft.world.level.dimension.DimensionType;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.HashSet;
|
||||
import java.util.Locale;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
|
||||
public final class ModdedRuntimeRegistry {
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger("Iris");
|
||||
private static final Object LOCK = new Object();
|
||||
|
||||
private ModdedRuntimeRegistry() {
|
||||
}
|
||||
|
||||
static void ensureDimensionType(RegistryAccess registryAccess, Registry<DimensionType> registry,
|
||||
ResourceKey<DimensionType> typeKey, String typeRef, IrisDimension dimension) {
|
||||
if (registry.get(typeKey).isPresent()) {
|
||||
return;
|
||||
}
|
||||
IDataFixer fixer = DataVersion.getLatest().get();
|
||||
String json = dimension.getDimensionType().toJson(fixer);
|
||||
DimensionType type = decode(registryAccess, DimensionType.DIRECT_CODEC, json, typeRef);
|
||||
registerIntoFrozen(registry, typeKey, type, typeRef);
|
||||
LOGGER.info("Iris registered runtime dimension type '{}'", typeRef);
|
||||
}
|
||||
|
||||
static void ensureCustomBiomes(RegistryAccess registryAccess, IrisDimension dimension, String pack) {
|
||||
File packFolder = ModdedWorldEngines.packFolder(pack);
|
||||
if (!packFolder.isDirectory()) {
|
||||
return;
|
||||
}
|
||||
Registry<Biome> registry = registryAccess.lookupOrThrow(Registries.BIOME);
|
||||
IrisData data = IrisData.get(packFolder);
|
||||
DataProvider provider = () -> data;
|
||||
IDataFixer fixer = DataVersion.getLatest().get();
|
||||
String namespace = dimension.getLoadKey().toLowerCase(Locale.ROOT);
|
||||
Set<String> seen = new HashSet<>();
|
||||
int registered = 0;
|
||||
for (IrisBiome irisBiome : dimension.getAllBiomes(provider)) {
|
||||
if (!irisBiome.isCustom()) {
|
||||
continue;
|
||||
}
|
||||
for (IrisBiomeCustom customBiome : irisBiome.getCustomDerivitives()) {
|
||||
String biomeId = customBiome.getId();
|
||||
if (!seen.add(biomeId)) {
|
||||
continue;
|
||||
}
|
||||
String biomeRef = namespace + ":" + biomeId;
|
||||
ResourceKey<Biome> biomeKey = ResourceKey.create(Registries.BIOME, Identifier.parse(biomeRef));
|
||||
if (registry.get(biomeKey).isPresent()) {
|
||||
continue;
|
||||
}
|
||||
String json = customBiome.generateJson(fixer);
|
||||
Biome biome = decode(registryAccess, Biome.DIRECT_CODEC, json, biomeRef);
|
||||
registerIntoFrozen(registry, biomeKey, biome, biomeRef);
|
||||
registered++;
|
||||
}
|
||||
}
|
||||
if (registered > 0) {
|
||||
LOGGER.info("Iris registered {} runtime biome(s) for pack '{}'", registered, pack);
|
||||
}
|
||||
}
|
||||
|
||||
private static <T> T decode(RegistryAccess registryAccess, Codec<T> codec, String json, String ref) {
|
||||
JsonElement element = JsonParser.parseString(json);
|
||||
RegistryOps<JsonElement> ops = RegistryOps.create(JsonOps.INSTANCE, registryAccess);
|
||||
return codec.parse(ops, element).getOrThrow((String message) ->
|
||||
new IllegalStateException("Iris could not decode runtime registry entry '" + ref + "': " + message));
|
||||
}
|
||||
|
||||
private static <T> Holder.Reference<T> registerIntoFrozen(Registry<T> registry, ResourceKey<T> key, T value, String ref) {
|
||||
if (!(registry instanceof MappedRegistry<T> mapped)) {
|
||||
throw new IllegalStateException("Iris cannot register '" + ref + "' at runtime: "
|
||||
+ registry.getClass().getName() + " is not a MappedRegistry");
|
||||
}
|
||||
synchronized (LOCK) {
|
||||
Optional<Holder.Reference<T>> raced = registry.get(key);
|
||||
if (raced.isPresent()) {
|
||||
return raced.get();
|
||||
}
|
||||
boolean wasFrozen = mapped.frozen;
|
||||
mapped.frozen = false;
|
||||
try {
|
||||
return mapped.register(key, value, RegistrationInfo.BUILT_IN);
|
||||
} finally {
|
||||
if (wasFrozen) {
|
||||
mapped.freeze();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+136
-120
@@ -19,6 +19,7 @@
|
||||
package art.arcane.iris.modded.command;
|
||||
|
||||
import art.arcane.iris.core.IrisSettings;
|
||||
import art.arcane.iris.core.localization.IrisMessages;
|
||||
import art.arcane.iris.core.gui.GuiHost;
|
||||
import art.arcane.iris.core.loader.IrisRegistrant;
|
||||
import art.arcane.iris.core.pack.PackDownloader;
|
||||
@@ -106,6 +107,10 @@ import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
import art.arcane.iris.core.localization.IrisLanguage;
|
||||
import art.arcane.iris.core.localization.ModdedCommandMessages;
|
||||
import art.arcane.iris.core.localization.RuntimeUiMessages;
|
||||
import art.arcane.volmlib.util.localization.MessageArgument;
|
||||
public final class IrisModdedCommands {
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger("Iris");
|
||||
private static final Predicate<CommandSourceStack> GATE = Commands.hasPermission(Commands.LEVEL_GAMEMASTERS);
|
||||
@@ -386,27 +391,27 @@ public final class IrisModdedCommands {
|
||||
private static int editBiome(CommandSourceStack source, String key) {
|
||||
Engine engine = engineFor(source.getLevel());
|
||||
if (engine == null) {
|
||||
fail(source, "This dimension is not generated by Iris.");
|
||||
fail(source, IrisLanguage.plain(ModdedCommandMessages.IRIS_MODDED_COMMANDS_THIS_DIMENSION_IS_NOT_GENERATED_BY_IRIS));
|
||||
return 0;
|
||||
}
|
||||
IrisBiome biome;
|
||||
if (key == null || key.isBlank()) {
|
||||
ServerPlayer player = source.getPlayer();
|
||||
if (player == null) {
|
||||
fail(source, "Console must name a biome: /iris edit biome <key>");
|
||||
fail(source, IrisLanguage.plain(ModdedCommandMessages.IRIS_MODDED_COMMANDS_CONSOLE_MUST_NAME_BIOME_IRIS_EDIT_BIOME_KEY));
|
||||
return 0;
|
||||
}
|
||||
BlockPos pos = player.blockPosition();
|
||||
try {
|
||||
biome = engine.getBiome(pos.getX(), pos.getY() - engine.getMinHeight(), pos.getZ());
|
||||
} catch (Throwable e) {
|
||||
fail(source, "Biome lookup failed: " + e.getClass().getSimpleName());
|
||||
fail(source, IrisLanguage.plain(ModdedCommandMessages.IRIS_MODDED_COMMANDS_BIOME_LOOKUP_FAILED, MessageArgument.untrusted("value", e.getClass().getSimpleName())));
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
biome = engine.getData().getBiomeLoader().load(key.trim());
|
||||
if (biome == null) {
|
||||
fail(source, "Unknown biome: " + key);
|
||||
fail(source, IrisLanguage.plain(ModdedCommandMessages.IRIS_MODDED_COMMANDS_UNKNOWN_BIOME, MessageArgument.untrusted("key", key)));
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@@ -416,27 +421,27 @@ public final class IrisModdedCommands {
|
||||
private static int editRegion(CommandSourceStack source, String key) {
|
||||
Engine engine = engineFor(source.getLevel());
|
||||
if (engine == null) {
|
||||
fail(source, "This dimension is not generated by Iris.");
|
||||
fail(source, IrisLanguage.plain(ModdedCommandMessages.IRIS_MODDED_COMMANDS_THIS_DIMENSION_IS_NOT_GENERATED_BY_IRIS_2));
|
||||
return 0;
|
||||
}
|
||||
IrisRegion region;
|
||||
if (key == null || key.isBlank()) {
|
||||
ServerPlayer player = source.getPlayer();
|
||||
if (player == null) {
|
||||
fail(source, "Console must name a region: /iris edit region <key>");
|
||||
fail(source, IrisLanguage.plain(ModdedCommandMessages.IRIS_MODDED_COMMANDS_CONSOLE_MUST_NAME_REGION_IRIS_EDIT_REGION_KEY));
|
||||
return 0;
|
||||
}
|
||||
BlockPos pos = player.blockPosition();
|
||||
try {
|
||||
region = engine.getRegion(pos.getX(), pos.getZ());
|
||||
} catch (Throwable e) {
|
||||
fail(source, "Region lookup failed: " + e.getClass().getSimpleName());
|
||||
fail(source, IrisLanguage.plain(ModdedCommandMessages.IRIS_MODDED_COMMANDS_REGION_LOOKUP_FAILED, MessageArgument.untrusted("value", e.getClass().getSimpleName())));
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
region = engine.getData().getRegionLoader().load(key.trim());
|
||||
if (region == null) {
|
||||
fail(source, "Unknown region: " + key);
|
||||
fail(source, IrisLanguage.plain(ModdedCommandMessages.IRIS_MODDED_COMMANDS_UNKNOWN_REGION, MessageArgument.untrusted("key", key)));
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@@ -446,7 +451,7 @@ public final class IrisModdedCommands {
|
||||
private static int editDimension(CommandSourceStack source) {
|
||||
Engine engine = engineFor(source.getLevel());
|
||||
if (engine == null) {
|
||||
fail(source, "This dimension is not generated by Iris.");
|
||||
fail(source, IrisLanguage.plain(ModdedCommandMessages.IRIS_MODDED_COMMANDS_THIS_DIMENSION_IS_NOT_GENERATED_BY_IRIS_3));
|
||||
return 0;
|
||||
}
|
||||
return openJson(source, engine.getDimension());
|
||||
@@ -454,11 +459,11 @@ public final class IrisModdedCommands {
|
||||
|
||||
private static int openJson(CommandSourceStack source, IrisRegistrant registrant) {
|
||||
if (!GuiHost.isAvailable() || !Desktop.isDesktopSupported()) {
|
||||
fail(source, "Cannot open files here: " + ModdedGuiHost.guiUnavailableReason());
|
||||
fail(source, IrisLanguage.plain(ModdedCommandMessages.IRIS_MODDED_COMMANDS_CANNOT_OPEN_FILES_HERE, MessageArgument.untrusted("value", ModdedGuiHost.guiUnavailableReason())));
|
||||
return 0;
|
||||
}
|
||||
if (registrant == null || registrant.getLoadFile() == null || !registrant.getLoadFile().isFile()) {
|
||||
fail(source, "Cannot find the file; perhaps it was not loaded directly from a file?");
|
||||
fail(source, IrisLanguage.plain(ModdedCommandMessages.IRIS_MODDED_COMMANDS_CANNOT_FIND_FILE_PERHAPS_IT_WAS_NOT_LOADED_DIRECTLY_FROM));
|
||||
return 0;
|
||||
}
|
||||
File file = registrant.getLoadFile();
|
||||
@@ -466,29 +471,29 @@ public final class IrisModdedCommands {
|
||||
Desktop.getDesktop().open(file);
|
||||
} catch (Throwable e) {
|
||||
LOGGER.error("Iris edit failed to open {}", file, e);
|
||||
fail(source, "Could not open " + file.getName() + ": " + e.getClass().getSimpleName());
|
||||
fail(source, IrisLanguage.plain(ModdedCommandMessages.IRIS_MODDED_COMMANDS_COULD_NOT_OPEN, MessageArgument.untrusted("value", file.getName()), MessageArgument.untrusted("value2", e.getClass().getSimpleName())));
|
||||
return 0;
|
||||
}
|
||||
ok(source, "Opening " + registrant.getTypeName() + " " + file.getName() + " in your editor.");
|
||||
ok(source, IrisLanguage.plain(ModdedCommandMessages.IRIS_MODDED_COMMANDS_OPENING_YOUR_EDITOR, MessageArgument.untrusted("value", registrant.getTypeName()), MessageArgument.untrusted("value2", file.getName())));
|
||||
return 1;
|
||||
}
|
||||
|
||||
private static int tp(CommandSourceStack source, ServerLevel level, ServerPlayer target) {
|
||||
ServerPlayer player = target != null ? target : source.getPlayer();
|
||||
if (player == null) {
|
||||
fail(source, "Console must name a player: /iris tp <dimension> <player>");
|
||||
fail(source, IrisLanguage.plain(ModdedCommandMessages.IRIS_MODDED_COMMANDS_CONSOLE_MUST_NAME_PLAYER_IRIS_TP_DIMENSION_PLAYER));
|
||||
return 0;
|
||||
}
|
||||
if (!(level.getChunkSource().getGenerator() instanceof IrisModdedChunkGenerator)) {
|
||||
fail(source, level.dimension().identifier() + " is not generated by Iris.");
|
||||
fail(source, IrisLanguage.plain(ModdedCommandMessages.IRIS_MODDED_COMMANDS_IS_NOT_GENERATED_BY_IRIS, MessageArgument.untrusted("value", level.dimension().identifier())));
|
||||
return 0;
|
||||
}
|
||||
String dimensionId = level.dimension().identifier().toString();
|
||||
if (!ModdedDimensionManager.teleport(player, source.getServer(), dimensionId, 8.5D, Double.MIN_VALUE, 8.5D)) {
|
||||
fail(source, "Teleport failed: dimension " + dimensionId + " is not loaded.");
|
||||
fail(source, IrisLanguage.plain(ModdedCommandMessages.IRIS_MODDED_COMMANDS_TELEPORT_FAILED_DIMENSION_IS_NOT_LOADED, MessageArgument.untrusted("dimensionId", dimensionId)));
|
||||
return 0;
|
||||
}
|
||||
ok(source, "Teleporting " + player.getScoreboardName() + " to " + dimensionId + "...");
|
||||
ok(source, IrisLanguage.plain(ModdedCommandMessages.IRIS_MODDED_COMMANDS_TELEPORTING, MessageArgument.untrusted("value", player.getScoreboardName()), MessageArgument.untrusted("dimensionId", dimensionId)));
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -496,16 +501,16 @@ public final class IrisModdedCommands {
|
||||
MinecraftServer server = source.getServer();
|
||||
ServerLevel level = target != null ? target : source.getLevel();
|
||||
if (!(level.getChunkSource().getGenerator() instanceof IrisModdedChunkGenerator)) {
|
||||
fail(source, level.dimension().identifier() + " is not generated by Iris.");
|
||||
fail(source, IrisLanguage.plain(ModdedCommandMessages.IRIS_MODDED_COMMANDS_IS_NOT_GENERATED_BY_IRIS_2, MessageArgument.untrusted("value", level.dimension().identifier())));
|
||||
return 0;
|
||||
}
|
||||
ServerLevel fallback = server.overworld();
|
||||
if (fallback == level) {
|
||||
fail(source, "Cannot evacuate the primary world; there is nowhere to send players.");
|
||||
fail(source, IrisLanguage.plain(ModdedCommandMessages.IRIS_MODDED_COMMANDS_CANNOT_EVACUATE_PRIMARY_WORLD_THERE_IS_NOWHERE_SEND_PLAYERS));
|
||||
return 0;
|
||||
}
|
||||
int count = ModdedDimensionManager.evacuate(server, level);
|
||||
ok(source, "Evacuated " + count + " player(s) from " + level.dimension().identifier() + " to " + fallback.dimension().identifier() + ".");
|
||||
ok(source, IrisLanguage.plain(ModdedCommandMessages.IRIS_MODDED_COMMANDS_EVACUATED_PLAYER_S_FROM, MessageArgument.untrusted("count", count), MessageArgument.untrusted("value", level.dimension().identifier()), MessageArgument.untrusted("value2", fallback.dimension().identifier())));
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -513,7 +518,7 @@ public final class IrisModdedCommands {
|
||||
boolean to = !IrisSettings.get().getGeneral().isDebug();
|
||||
IrisSettings.get().getGeneral().setDebug(to);
|
||||
IrisSettings.get().forceSave();
|
||||
ok(source, "Set debug to: " + to);
|
||||
ok(source, IrisLanguage.plain(ModdedCommandMessages.IRIS_MODDED_COMMANDS_SET_DEBUG, MessageArgument.untrusted("to", to)));
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -522,39 +527,51 @@ public final class IrisModdedCommands {
|
||||
IrisSettings.invalidate();
|
||||
}
|
||||
IrisSettings.get();
|
||||
ok(source, "Hotloaded settings");
|
||||
boolean localeLoaded = IrisLanguage.reload();
|
||||
if (localeLoaded) {
|
||||
ok(source, IrisLanguage.plain(
|
||||
IrisMessages.COMMAND_RELOAD_SUCCESS,
|
||||
MessageArgument.trusted("locale", IrisLanguage.activeLocale())
|
||||
));
|
||||
return 1;
|
||||
}
|
||||
fail(source, IrisLanguage.plain(
|
||||
IrisMessages.COMMAND_RELOAD_FAILED,
|
||||
MessageArgument.untrusted("locale", IrisSettings.get().getGeneral().getLanguage()),
|
||||
MessageArgument.trusted("activeLocale", IrisLanguage.activeLocale())
|
||||
));
|
||||
return 1;
|
||||
}
|
||||
|
||||
private static int whatHand(CommandSourceStack source) {
|
||||
ServerPlayer player = source.getPlayer();
|
||||
if (player == null) {
|
||||
fail(source, "This command can only be used by players (it inspects your held item).");
|
||||
fail(source, IrisLanguage.plain(ModdedCommandMessages.IRIS_MODDED_COMMANDS_THIS_COMMAND_CAN_ONLY_BE_USED_BY_PLAYERS_IT_INSPECTS));
|
||||
return 0;
|
||||
}
|
||||
ItemStack stack = player.getMainHandItem();
|
||||
if (stack.isEmpty()) {
|
||||
fail(source, "Your main hand is empty.");
|
||||
fail(source, IrisLanguage.plain(ModdedCommandMessages.IRIS_MODDED_COMMANDS_YOUR_MAIN_HAND_IS_EMPTY));
|
||||
return 0;
|
||||
}
|
||||
ok(source, "Hand: " + BuiltInRegistries.ITEM.getKey(stack.getItem()) + " x" + stack.getCount());
|
||||
ok(source, IrisLanguage.plain(ModdedCommandMessages.IRIS_MODDED_COMMANDS_HAND_X, MessageArgument.untrusted("value", BuiltInRegistries.ITEM.getKey(stack.getItem())), MessageArgument.untrusted("value2", stack.getCount())));
|
||||
return 1;
|
||||
}
|
||||
|
||||
private static int regen(CommandSourceStack source, int radius) {
|
||||
ServerPlayer player = source.getPlayer();
|
||||
if (player == null) {
|
||||
fail(source, "This command can only be used by players.");
|
||||
fail(source, IrisLanguage.plain(ModdedCommandMessages.IRIS_MODDED_COMMANDS_THIS_COMMAND_CAN_ONLY_BE_USED_BY_PLAYERS));
|
||||
return 0;
|
||||
}
|
||||
ServerLevel level = source.getLevel();
|
||||
if (!(level.getChunkSource().getGenerator() instanceof IrisModdedChunkGenerator irisGenerator)) {
|
||||
fail(source, "This dimension is not generated by Iris.");
|
||||
fail(source, IrisLanguage.plain(ModdedCommandMessages.IRIS_MODDED_COMMANDS_THIS_DIMENSION_IS_NOT_GENERATED_BY_IRIS_4));
|
||||
return 0;
|
||||
}
|
||||
Engine engine = engineFor(level);
|
||||
if (engine == null) {
|
||||
fail(source, "This dimension is not generated by Iris.");
|
||||
fail(source, IrisLanguage.plain(ModdedCommandMessages.IRIS_MODDED_COMMANDS_THIS_DIMENSION_IS_NOT_GENERATED_BY_IRIS_5));
|
||||
return 0;
|
||||
}
|
||||
ModdedRegen.start(source, level, irisGenerator, engine, player, radius);
|
||||
@@ -570,15 +587,15 @@ public final class IrisModdedCommands {
|
||||
Engine engine = engineFor(level);
|
||||
if (engine == null) {
|
||||
if (withDimension) {
|
||||
fail(source, level.dimension().identifier() + " is not generated by Iris; see /iris info for loaded Iris dimensions.");
|
||||
fail(source, IrisLanguage.plain(ModdedCommandMessages.IRIS_MODDED_COMMANDS_IS_NOT_GENERATED_BY_IRIS_SEE_IRIS_INFO_LOADED_IRIS, MessageArgument.untrusted("value", level.dimension().identifier())));
|
||||
} else {
|
||||
fail(source, "The current dimension (" + level.dimension().identifier() + ") is not generated by Iris. Name one explicitly: /iris pregen start " + radius + " <dimension>; see /iris info for loaded Iris dimensions.");
|
||||
fail(source, IrisLanguage.plain(ModdedCommandMessages.IRIS_MODDED_COMMANDS_CURRENT_DIMENSION_IS_NOT_GENERATED_BY_IRIS_NAME_ONE_EXPLICITLY, MessageArgument.untrusted("value", level.dimension().identifier()), MessageArgument.untrusted("radius", radius)));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
boolean showGui = gui && ModdedGuiHost.isGuiLaunchable();
|
||||
if (!ModdedPregenJob.start(source.getServer(), level, engine, radius, centerX, centerZ, showGui, sync, !nocache)) {
|
||||
fail(source, "A pregeneration task is already running. Stop it first with /iris pregen stop.");
|
||||
fail(source, IrisLanguage.plain(ModdedCommandMessages.IRIS_MODDED_COMMANDS_PREGENERATION_TASK_IS_ALREADY_RUNNING_STOP_IT_FIRST_WITH_IRIS));
|
||||
return 0;
|
||||
}
|
||||
ModdedPregenBossBar.begin(source.getPlayer());
|
||||
@@ -591,35 +608,34 @@ public final class IrisModdedCommands {
|
||||
guiNote = " (GUI requested but unavailable: " + ModdedGuiHost.guiUnavailableReason() + ")";
|
||||
}
|
||||
String modeNote = " Mode: " + (sync ? "sync" : "async") + (nocache ? ", cache disabled." : ", resumable (checkpoint cache).");
|
||||
ok(source, "Pregen started in " + level.dimension().identifier() + " of " + (radius * 2) + " by " + (radius * 2)
|
||||
+ " blocks from " + centerX + "," + centerZ + "." + modeNote + " Progress logs to console; see /iris pregen status." + guiNote);
|
||||
ok(source, IrisLanguage.plain(ModdedCommandMessages.IRIS_MODDED_COMMANDS_PREGEN_STARTED_BY_BLOCKS_FROM_PROGRESS_LOGS_CONSOLE_SEE_IRIS, MessageArgument.untrusted("value", level.dimension().identifier()), MessageArgument.untrusted("value2", (radius * 2)), MessageArgument.untrusted("value3", (radius * 2)), MessageArgument.untrusted("centerX", centerX), MessageArgument.untrusted("centerZ", centerZ), MessageArgument.untrusted("modeNote", modeNote), MessageArgument.untrusted("guiNote", guiNote)));
|
||||
return 1;
|
||||
}
|
||||
|
||||
private static int pregenStop(CommandSourceStack source) {
|
||||
if (ModdedPregenJob.stop()) {
|
||||
ModdedPregenBossBar.clear();
|
||||
ok(source, "Stopping pregeneration; finishing up the current region...");
|
||||
ok(source, IrisLanguage.plain(ModdedCommandMessages.IRIS_MODDED_COMMANDS_STOPPING_PREGENERATION_FINISHING_UP_CURRENT_REGION));
|
||||
return 1;
|
||||
}
|
||||
fail(source, "No active pregeneration task to stop.");
|
||||
fail(source, IrisLanguage.plain(ModdedCommandMessages.IRIS_MODDED_COMMANDS_NO_ACTIVE_PREGENERATION_TASK_STOP));
|
||||
return 0;
|
||||
}
|
||||
|
||||
private static int pregenPause(CommandSourceStack source) {
|
||||
Boolean paused = ModdedPregenJob.pauseResume();
|
||||
if (paused == null) {
|
||||
fail(source, "No active pregeneration task to pause/resume.");
|
||||
fail(source, IrisLanguage.plain(ModdedCommandMessages.IRIS_MODDED_COMMANDS_NO_ACTIVE_PREGENERATION_TASK_PAUSE_RESUME));
|
||||
return 0;
|
||||
}
|
||||
ok(source, "Pregeneration is now " + (paused.booleanValue() ? "paused" : "running") + ".");
|
||||
ok(source, IrisLanguage.plain(ModdedCommandMessages.IRIS_MODDED_COMMANDS_PREGENERATION_IS_NOW, MessageArgument.trusted("value", IrisLanguage.plain(paused.booleanValue() ? RuntimeUiMessages.STATUS_PAUSED_LOWER : RuntimeUiMessages.STATUS_RUNNING_LOWER))));
|
||||
return 1;
|
||||
}
|
||||
|
||||
private static int pregenStatus(CommandSourceStack source) {
|
||||
Component status = ModdedPregenJob.statusComponent();
|
||||
if (status == null) {
|
||||
fail(source, "No active pregeneration task.");
|
||||
fail(source, IrisLanguage.plain(ModdedCommandMessages.IRIS_MODDED_COMMANDS_NO_ACTIVE_PREGENERATION_TASK));
|
||||
return 0;
|
||||
}
|
||||
ok(source, status);
|
||||
@@ -629,8 +645,7 @@ public final class IrisModdedCommands {
|
||||
private static int version(CommandSourceStack source) {
|
||||
ModdedLoader loader = ModdedEngineBootstrap.loader();
|
||||
int engines = engineCount(source.getServer());
|
||||
ok(source, "Iris " + loader.modVersion() + " by Volmit Software on " + loader.platformName()
|
||||
+ " (Minecraft " + loader.minecraftVersion() + "), " + engines + " Iris dimension(s)");
|
||||
ok(source, IrisLanguage.plain(ModdedCommandMessages.IRIS_MODDED_COMMANDS_IRIS_BY_VOLMIT_SOFTWARE_ON_MINECRAFT_IRIS_DIMENSION_S, MessageArgument.untrusted("value", loader.modVersion()), MessageArgument.untrusted("value2", loader.platformName()), MessageArgument.untrusted("value3", loader.minecraftVersion()), MessageArgument.untrusted("engines", engines)));
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -661,9 +676,13 @@ public final class IrisModdedCommands {
|
||||
+ " generated=" + engine.getGenerated()
|
||||
+ " data=" + engine.getData().getDataFolder().getAbsolutePath());
|
||||
}
|
||||
ok(source, "Loaded dimensions: " + total + " (" + iris + " Iris)");
|
||||
ok(source, IrisLanguage.plain(ModdedCommandMessages.IRIS_MODDED_COMMANDS_LOADED_DIMENSIONS_IRIS, MessageArgument.untrusted("total", total), MessageArgument.untrusted("iris", iris)));
|
||||
if (lines.isEmpty()) {
|
||||
ok(source, filter == null ? "No Iris dimensions are loaded." : "No Iris dimension matches '" + filter + "'.");
|
||||
if (filter == null) {
|
||||
ok(source, IrisLanguage.plain(ModdedCommandMessages.MODDED_DATAPACK_COMMANDS_NO_IRIS_DIMENSIONS_ARE_LOADED));
|
||||
} else {
|
||||
ok(source, IrisLanguage.plain(RuntimeUiMessages.MODDED_NO_DIMENSION_MATCH, MessageArgument.untrusted("filter", filter)));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
for (String line : lines) {
|
||||
@@ -675,58 +694,58 @@ public final class IrisModdedCommands {
|
||||
private static int what(CommandSourceStack source) {
|
||||
ServerPlayer player = source.getPlayer();
|
||||
if (player == null) {
|
||||
fail(source, "This command can only be used by players.");
|
||||
fail(source, IrisLanguage.plain(ModdedCommandMessages.IRIS_MODDED_COMMANDS_THIS_COMMAND_CAN_ONLY_BE_USED_BY_PLAYERS_2));
|
||||
return 0;
|
||||
}
|
||||
ServerLevel level = source.getLevel();
|
||||
Engine engine = engineFor(level);
|
||||
if (engine == null) {
|
||||
fail(source, "This dimension is not generated by Iris.");
|
||||
fail(source, IrisLanguage.plain(ModdedCommandMessages.IRIS_MODDED_COMMANDS_THIS_DIMENSION_IS_NOT_GENERATED_BY_IRIS_6));
|
||||
return 0;
|
||||
}
|
||||
BlockPos pos = player.blockPosition();
|
||||
int relativeY = pos.getY() - engine.getMinHeight();
|
||||
try {
|
||||
IrisBiome biome = engine.getBiome(pos.getX(), relativeY, pos.getZ());
|
||||
ok(source, "Biome: " + biome.getLoadKey() + " (" + biome.getName() + ")");
|
||||
ok(source, IrisLanguage.plain(ModdedCommandMessages.IRIS_MODDED_COMMANDS_BIOME, MessageArgument.untrusted("value", biome.getLoadKey()), MessageArgument.untrusted("value2", biome.getName())));
|
||||
} catch (Throwable e) {
|
||||
fail(source, "Biome lookup failed: " + e.getClass().getSimpleName());
|
||||
fail(source, IrisLanguage.plain(ModdedCommandMessages.IRIS_MODDED_COMMANDS_BIOME_LOOKUP_FAILED_2, MessageArgument.untrusted("value", e.getClass().getSimpleName())));
|
||||
}
|
||||
try {
|
||||
IrisRegion region = engine.getRegion(pos.getX(), pos.getZ());
|
||||
ok(source, "Region: " + region.getLoadKey() + " (" + region.getName() + ")");
|
||||
ok(source, IrisLanguage.plain(ModdedCommandMessages.IRIS_MODDED_COMMANDS_REGION, MessageArgument.untrusted("value", region.getLoadKey()), MessageArgument.untrusted("value2", region.getName())));
|
||||
} catch (Throwable e) {
|
||||
fail(source, "Region lookup failed: " + e.getClass().getSimpleName());
|
||||
fail(source, IrisLanguage.plain(ModdedCommandMessages.IRIS_MODDED_COMMANDS_REGION_LOOKUP_FAILED_2, MessageArgument.untrusted("value", e.getClass().getSimpleName())));
|
||||
}
|
||||
try {
|
||||
IrisBiome cave = engine.getCaveBiome(pos.getX(), relativeY, pos.getZ());
|
||||
ok(source, "Cave biome: " + (cave == null ? "none" : cave.getLoadKey()));
|
||||
ok(source, IrisLanguage.plain(ModdedCommandMessages.IRIS_MODDED_COMMANDS_CAVE_BIOME, MessageArgument.untrusted("value", cave == null ? IrisLanguage.plain(RuntimeUiMessages.STATUS_NONE) : cave.getLoadKey())));
|
||||
} catch (Throwable e) {
|
||||
fail(source, "Cave biome lookup failed: " + e.getClass().getSimpleName());
|
||||
fail(source, IrisLanguage.plain(ModdedCommandMessages.IRIS_MODDED_COMMANDS_CAVE_BIOME_LOOKUP_FAILED, MessageArgument.untrusted("value", e.getClass().getSimpleName())));
|
||||
}
|
||||
int surfaceY = level.getHeight(Heightmap.Types.WORLD_SURFACE, pos.getX(), pos.getZ());
|
||||
BlockState surface = level.getBlockState(new BlockPos(pos.getX(), surfaceY - 1, pos.getZ()));
|
||||
ok(source, "Surface block: " + BuiltInRegistries.BLOCK.getKey(surface.getBlock()) + " (y=" + (surfaceY - 1) + ")");
|
||||
ok(source, "Position: " + pos.getX() + " " + pos.getY() + " " + pos.getZ() + " (chunk " + (pos.getX() >> 4) + "," + (pos.getZ() >> 4) + ")");
|
||||
ok(source, IrisLanguage.plain(ModdedCommandMessages.IRIS_MODDED_COMMANDS_SURFACE_BLOCK_Y, MessageArgument.untrusted("value", BuiltInRegistries.BLOCK.getKey(surface.getBlock())), MessageArgument.untrusted("value2", (surfaceY - 1))));
|
||||
ok(source, IrisLanguage.plain(ModdedCommandMessages.IRIS_MODDED_COMMANDS_POSITION_CHUNK, MessageArgument.untrusted("value", pos.getX()), MessageArgument.untrusted("value2", pos.getY()), MessageArgument.untrusted("value3", pos.getZ()), MessageArgument.untrusted("value4", (pos.getX() >> 4)), MessageArgument.untrusted("value5", (pos.getZ() >> 4))));
|
||||
return 1;
|
||||
}
|
||||
|
||||
private static int whatBlock(CommandSourceStack source) {
|
||||
ServerPlayer player = source.getPlayer();
|
||||
if (player == null) {
|
||||
fail(source, "This command can only be used by players (it inspects the block you are looking at).");
|
||||
fail(source, IrisLanguage.plain(ModdedCommandMessages.IRIS_MODDED_COMMANDS_THIS_COMMAND_CAN_ONLY_BE_USED_BY_PLAYERS_IT_INSPECTS_2));
|
||||
return 0;
|
||||
}
|
||||
HitResult hit = player.pick(128.0D, 1.0F, false);
|
||||
if (hit.getType() != HitResult.Type.BLOCK || !(hit instanceof BlockHitResult blockHit)) {
|
||||
fail(source, "Look at a block, not the sky.");
|
||||
fail(source, IrisLanguage.plain(ModdedCommandMessages.IRIS_MODDED_COMMANDS_LOOK_AT_BLOCK_NOT_SKY));
|
||||
return 0;
|
||||
}
|
||||
ServerLevel level = source.getLevel();
|
||||
BlockPos pos = blockHit.getBlockPos();
|
||||
BlockState state = level.getBlockState(pos);
|
||||
PlatformBlockState platform = ModdedBlockState.of(state, null);
|
||||
ok(source, "Block: " + platform.key() + " (y=" + pos.getY() + ")");
|
||||
ok(source, IrisLanguage.plain(ModdedCommandMessages.IRIS_MODDED_COMMANDS_BLOCK_Y, MessageArgument.untrusted("value", platform.key()), MessageArgument.untrusted("value2", pos.getY())));
|
||||
List<String> flags = new ArrayList<>();
|
||||
if (platform.isSolid()) {
|
||||
flags.add("solid");
|
||||
@@ -761,20 +780,27 @@ public final class IrisModdedCommands {
|
||||
if (platform.hasTileEntity()) {
|
||||
flags.add("tile entity");
|
||||
}
|
||||
ok(source, flags.isEmpty() ? "Properties: (none)" : "Properties: " + String.join(", ", flags));
|
||||
if (flags.isEmpty()) {
|
||||
ok(source, IrisLanguage.plain(IrisMessages.MODDED_PROPERTIES_NONE));
|
||||
return 1;
|
||||
}
|
||||
ok(source, IrisLanguage.plain(
|
||||
IrisMessages.MODDED_PROPERTIES,
|
||||
MessageArgument.untrusted("properties", String.join(", ", flags))
|
||||
));
|
||||
return 1;
|
||||
}
|
||||
|
||||
private static int whatMarkers(CommandSourceStack source, String markerRaw) {
|
||||
ServerPlayer player = source.getPlayer();
|
||||
if (player == null) {
|
||||
fail(source, "This command can only be used by players (markers render as particles around you).");
|
||||
fail(source, IrisLanguage.plain(ModdedCommandMessages.IRIS_MODDED_COMMANDS_THIS_COMMAND_CAN_ONLY_BE_USED_BY_PLAYERS_MARKERS_RENDER));
|
||||
return 0;
|
||||
}
|
||||
ServerLevel level = source.getLevel();
|
||||
Engine engine = engineFor(level);
|
||||
if (engine == null) {
|
||||
fail(source, "This dimension is not generated by Iris.");
|
||||
fail(source, IrisLanguage.plain(ModdedCommandMessages.IRIS_MODDED_COMMANDS_THIS_DIMENSION_IS_NOT_GENERATED_BY_IRIS_7));
|
||||
return 0;
|
||||
}
|
||||
String marker = markerRaw.trim();
|
||||
@@ -782,7 +808,7 @@ public final class IrisModdedCommands {
|
||||
int chunkX = origin.getX() >> 4;
|
||||
int chunkZ = origin.getZ() >> 4;
|
||||
MinecraftServer server = source.getServer();
|
||||
ok(source, "Scanning for '" + marker + "' markers around you...");
|
||||
ok(source, IrisLanguage.plain(ModdedCommandMessages.IRIS_MODDED_COMMANDS_SCANNING_MARKERS_AROUND_YOU, MessageArgument.untrusted("marker", marker)));
|
||||
Thread thread = new Thread(() -> {
|
||||
List<int[]> hits = new ArrayList<>();
|
||||
MatterMarker matterMarker = new MatterMarker(marker);
|
||||
@@ -796,7 +822,7 @@ public final class IrisModdedCommands {
|
||||
}
|
||||
} catch (Throwable e) {
|
||||
LOGGER.error("Iris marker scan failed for {}", marker, e);
|
||||
server.execute(() -> fail(source, "Marker scan failed: " + e.getClass().getSimpleName()));
|
||||
server.execute(() -> fail(source, IrisLanguage.plain(ModdedCommandMessages.IRIS_MODDED_COMMANDS_MARKER_SCAN_FAILED, MessageArgument.untrusted("value", e.getClass().getSimpleName()))));
|
||||
return;
|
||||
}
|
||||
server.execute(() -> {
|
||||
@@ -805,7 +831,7 @@ public final class IrisModdedCommands {
|
||||
hit[0] + 0.5D, hit[1] + 1.0D, hit[2] + 0.5D,
|
||||
3, 0.2D, 0.2D, 0.2D, 0.0D);
|
||||
}
|
||||
ok(source, "Found " + hits.size() + " nearby marker(s) (" + marker + ")");
|
||||
ok(source, IrisLanguage.plain(ModdedCommandMessages.IRIS_MODDED_COMMANDS_FOUND_NEARBY_MARKER_S, MessageArgument.untrusted("value", hits.size()), MessageArgument.untrusted("marker", marker)));
|
||||
});
|
||||
}, "Iris Marker Scan");
|
||||
thread.setDaemon(true);
|
||||
@@ -816,18 +842,18 @@ public final class IrisModdedCommands {
|
||||
private static int gotoBiome(CommandSourceStack source, String key) {
|
||||
ServerPlayer player = source.getPlayer();
|
||||
if (player == null) {
|
||||
fail(source, "This command can only be used by players.");
|
||||
fail(source, IrisLanguage.plain(ModdedCommandMessages.IRIS_MODDED_COMMANDS_THIS_COMMAND_CAN_ONLY_BE_USED_BY_PLAYERS_3));
|
||||
return 0;
|
||||
}
|
||||
ServerLevel level = source.getLevel();
|
||||
Engine engine = engineFor(level);
|
||||
if (engine == null) {
|
||||
fail(source, "This dimension is not generated by Iris.");
|
||||
fail(source, IrisLanguage.plain(ModdedCommandMessages.IRIS_MODDED_COMMANDS_THIS_DIMENSION_IS_NOT_GENERATED_BY_IRIS_8));
|
||||
return 0;
|
||||
}
|
||||
IrisBiome biome = engine.getData().getBiomeLoader().load(key.trim());
|
||||
if (biome == null) {
|
||||
fail(source, "Unknown biome: " + key);
|
||||
fail(source, IrisLanguage.plain(ModdedCommandMessages.IRIS_MODDED_COMMANDS_UNKNOWN_BIOME_2, MessageArgument.untrusted("key", key)));
|
||||
return 0;
|
||||
}
|
||||
locate(source, level, engine, player, Locator.surfaceBiome(biome.getLoadKey()), "biome " + biome.getLoadKey());
|
||||
@@ -837,22 +863,22 @@ public final class IrisModdedCommands {
|
||||
private static int gotoRegion(CommandSourceStack source, String key) {
|
||||
ServerPlayer player = source.getPlayer();
|
||||
if (player == null) {
|
||||
fail(source, "This command can only be used by players.");
|
||||
fail(source, IrisLanguage.plain(ModdedCommandMessages.IRIS_MODDED_COMMANDS_THIS_COMMAND_CAN_ONLY_BE_USED_BY_PLAYERS_4));
|
||||
return 0;
|
||||
}
|
||||
ServerLevel level = source.getLevel();
|
||||
Engine engine = engineFor(level);
|
||||
if (engine == null) {
|
||||
fail(source, "This dimension is not generated by Iris.");
|
||||
fail(source, IrisLanguage.plain(ModdedCommandMessages.IRIS_MODDED_COMMANDS_THIS_DIMENSION_IS_NOT_GENERATED_BY_IRIS_9));
|
||||
return 0;
|
||||
}
|
||||
IrisRegion region = engine.getData().getRegionLoader().load(key.trim());
|
||||
if (region == null) {
|
||||
fail(source, "Unknown region: " + key);
|
||||
fail(source, IrisLanguage.plain(ModdedCommandMessages.IRIS_MODDED_COMMANDS_UNKNOWN_REGION_2, MessageArgument.untrusted("key", key)));
|
||||
return 0;
|
||||
}
|
||||
if (!engine.getDimension().getRegions().contains(region.getLoadKey())) {
|
||||
fail(source, region.getLoadKey() + " is not defined in the dimension!");
|
||||
fail(source, IrisLanguage.plain(ModdedCommandMessages.IRIS_MODDED_COMMANDS_IS_NOT_DEFINED_DIMENSION, MessageArgument.untrusted("value", region.getLoadKey())));
|
||||
return 0;
|
||||
}
|
||||
locate(source, level, engine, player, Locator.region(region.getLoadKey()), "region " + region.getLoadKey());
|
||||
@@ -863,19 +889,17 @@ public final class IrisModdedCommands {
|
||||
ServerLevel level = source.getLevel();
|
||||
Engine engine = engineFor(level);
|
||||
if (engine == null) {
|
||||
fail(source, "This dimension is not generated by Iris.");
|
||||
fail(source, IrisLanguage.plain(ModdedCommandMessages.IRIS_MODDED_COMMANDS_THIS_DIMENSION_IS_NOT_GENERATED_BY_IRIS_10));
|
||||
return 0;
|
||||
}
|
||||
String key = keyRaw.trim();
|
||||
if (!engine.hasObjectPlacement(key)) {
|
||||
fail(source, key + " is not configured in any region/biome object placements ("
|
||||
+ engine.getData().getObjectLoader().getPossibleKeys().length + " object keys loaded).");
|
||||
fail(source, IrisLanguage.plain(ModdedCommandMessages.IRIS_MODDED_COMMANDS_IS_NOT_CONFIGURED_ANY_REGION_BIOME_OBJECT_PLACEMENTS_OBJECT_KEYS, MessageArgument.untrusted("key", key), MessageArgument.untrusted("value", engine.getData().getObjectLoader().getPossibleKeys().length)));
|
||||
return 0;
|
||||
}
|
||||
ServerPlayer player = source.getPlayer();
|
||||
if (player == null) {
|
||||
fail(source, "This command can only be used by players. (object key '" + key + "' resolved against "
|
||||
+ engine.getData().getObjectLoader().getPossibleKeys().length + " loaded object keys)");
|
||||
fail(source, IrisLanguage.plain(ModdedCommandMessages.IRIS_MODDED_COMMANDS_THIS_COMMAND_CAN_ONLY_BE_USED_BY_PLAYERS_OBJECT_KEY, MessageArgument.untrusted("key", key), MessageArgument.untrusted("value", engine.getData().getObjectLoader().getPossibleKeys().length)));
|
||||
return 0;
|
||||
}
|
||||
locate(source, level, engine, player, Locator.object(key), "object " + key);
|
||||
@@ -886,17 +910,17 @@ public final class IrisModdedCommands {
|
||||
ServerLevel level = source.getLevel();
|
||||
Engine engine = engineFor(level);
|
||||
if (engine == null) {
|
||||
fail(source, "This dimension is not generated by Iris.");
|
||||
fail(source, IrisLanguage.plain(ModdedCommandMessages.IRIS_MODDED_COMMANDS_THIS_DIMENSION_IS_NOT_GENERATED_BY_IRIS_11));
|
||||
return 0;
|
||||
}
|
||||
String key = keyRaw.trim();
|
||||
if (key.isEmpty()) {
|
||||
fail(source, "Name an Iris or native structure to locate.");
|
||||
fail(source, IrisLanguage.plain(ModdedCommandMessages.IRIS_MODDED_COMMANDS_NAME_IRIS_NATIVE_STRUCTURE_LOCATE));
|
||||
return 0;
|
||||
}
|
||||
ServerPlayer player = source.getPlayer();
|
||||
if (player == null) {
|
||||
fail(source, "This command can only be used by players.");
|
||||
fail(source, IrisLanguage.plain(ModdedCommandMessages.IRIS_MODDED_COMMANDS_THIS_COMMAND_CAN_ONLY_BE_USED_BY_PLAYERS_5));
|
||||
return 0;
|
||||
}
|
||||
Optional<NativeStructureTarget> resolved = resolveNativeStructure(source, level, engine, key);
|
||||
@@ -905,7 +929,7 @@ public final class IrisModdedCommands {
|
||||
locateIrisStructure(source, level, engine, player, key);
|
||||
return 1;
|
||||
}
|
||||
fail(source, "Unknown structure '" + key + "'. Use tab completion to choose an Iris placement or a registered native/datapack structure.");
|
||||
fail(source, IrisLanguage.plain(ModdedCommandMessages.IRIS_MODDED_COMMANDS_UNKNOWN_STRUCTURE_USE_TAB_COMPLETION_CHOOSE_IRIS_PLACEMENT_REGISTERED_NATIVE, MessageArgument.untrusted("key", key)));
|
||||
return 0;
|
||||
}
|
||||
NativeStructureTarget target = resolved.get();
|
||||
@@ -924,7 +948,7 @@ public final class IrisModdedCommands {
|
||||
fail(source, nativeUnavailableMessage(target.key(), target.availability()));
|
||||
return 0;
|
||||
}
|
||||
ok(source, "Searching for native structure " + target.key() + " within " + NATIVE_STRUCTURE_LOCATE_RADIUS + " chunks...");
|
||||
ok(source, IrisLanguage.plain(ModdedCommandMessages.IRIS_MODDED_COMMANDS_SEARCHING_NATIVE_STRUCTURE_WITHIN_CHUNKS, MessageArgument.untrusted("value", target.key()), MessageArgument.untrusted("NATIVESTRUCTURELOCATERADIUS", NATIVE_STRUCTURE_LOCATE_RADIUS)));
|
||||
runNativeStructureLocate(source, level, player, target);
|
||||
return 1;
|
||||
}
|
||||
@@ -934,18 +958,17 @@ public final class IrisModdedCommands {
|
||||
MinecraftServer server = source.getServer();
|
||||
int blockX = player.blockPosition().getX();
|
||||
int blockZ = player.blockPosition().getZ();
|
||||
ok(source, "Searching for Iris-placed structure " + key + "...");
|
||||
ok(source, IrisLanguage.plain(ModdedCommandMessages.IRIS_MODDED_COMMANDS_SEARCHING_IRIS_PLACED_STRUCTURE, MessageArgument.untrusted("key", key)));
|
||||
Thread thread = new Thread(() -> {
|
||||
try {
|
||||
IrisStructureLocator.LocateResult result =
|
||||
IrisStructureLocator.locate(engine, key, blockX, blockZ, 1024);
|
||||
if (result.status() == IrisStructureLocator.LocateStatus.SEARCH_LIMIT_REACHED) {
|
||||
server.execute(() -> fail(source, "Unable to locate Iris-placed structure " + key
|
||||
+ ": the density search safety limit was reached before the full 1024-chunk radius was searched."));
|
||||
server.execute(() -> fail(source, IrisLanguage.plain(ModdedCommandMessages.IRIS_MODDED_COMMANDS_UNABLE_LOCATE_IRIS_PLACED_STRUCTURE_DENSITY_SEARCH_SAFETY_LIMIT_WAS, MessageArgument.untrusted("key", key))));
|
||||
return;
|
||||
}
|
||||
if (!result.found()) {
|
||||
server.execute(() -> fail(source, "Could not find Iris-placed structure " + key + " within 1024 chunks."));
|
||||
server.execute(() -> fail(source, IrisLanguage.plain(ModdedCommandMessages.IRIS_MODDED_COMMANDS_COULD_NOT_FIND_IRIS_PLACED_STRUCTURE_WITHIN_1024_CHUNKS, MessageArgument.untrusted("key", key))));
|
||||
return;
|
||||
}
|
||||
int targetX = result.originX();
|
||||
@@ -955,7 +978,7 @@ public final class IrisModdedCommands {
|
||||
"Iris-placed structure " + key));
|
||||
} catch (Throwable e) {
|
||||
LOGGER.error("Iris structure locate failed for {}", key, e);
|
||||
server.execute(() -> fail(source, "Search failed: " + e.getClass().getSimpleName()));
|
||||
server.execute(() -> fail(source, IrisLanguage.plain(ModdedCommandMessages.IRIS_MODDED_COMMANDS_SEARCH_FAILED, MessageArgument.untrusted("value", e.getClass().getSimpleName()))));
|
||||
}
|
||||
}, "Iris Structure Locator");
|
||||
thread.setDaemon(true);
|
||||
@@ -984,8 +1007,7 @@ public final class IrisModdedCommands {
|
||||
NATIVE_STRUCTURE_LOCATE_RADIUS,
|
||||
false);
|
||||
if (found == null) {
|
||||
fail(source, "Could not find native structure " + target.key() + " within "
|
||||
+ NATIVE_STRUCTURE_LOCATE_RADIUS + " chunks.");
|
||||
fail(source, IrisLanguage.plain(ModdedCommandMessages.IRIS_MODDED_COMMANDS_COULD_NOT_FIND_NATIVE_STRUCTURE_WITHIN_CHUNKS, MessageArgument.untrusted("value", target.key()), MessageArgument.untrusted("NATIVESTRUCTURELOCATERADIUS", NATIVE_STRUCTURE_LOCATE_RADIUS)));
|
||||
return;
|
||||
}
|
||||
BlockPos position = found.getFirst();
|
||||
@@ -998,18 +1020,18 @@ public final class IrisModdedCommands {
|
||||
"native structure " + target.key());
|
||||
} catch (Throwable e) {
|
||||
LOGGER.error("Native structure locate failed for {}", target.key(), e);
|
||||
fail(source, "Search for native structure " + target.key() + " failed: " + e.getClass().getSimpleName());
|
||||
fail(source, IrisLanguage.plain(ModdedCommandMessages.IRIS_MODDED_COMMANDS_SEARCH_NATIVE_STRUCTURE_FAILED, MessageArgument.untrusted("value", target.key()), MessageArgument.untrusted("value2", e.getClass().getSimpleName())));
|
||||
}
|
||||
}
|
||||
|
||||
private static void teleportToStructure(CommandSourceStack source, ServerLevel level, ServerPlayer player,
|
||||
int targetX, int targetY, int targetZ, String label) {
|
||||
if (player.hasDisconnected() || player.isRemoved()) {
|
||||
fail(source, "The player disconnected before the structure search completed.");
|
||||
fail(source, IrisLanguage.plain(ModdedCommandMessages.IRIS_MODDED_COMMANDS_PLAYER_DISCONNECTED_BEFORE_STRUCTURE_SEARCH_COMPLETED));
|
||||
return;
|
||||
}
|
||||
if (player.level() != level) {
|
||||
fail(source, "You changed dimensions before the structure search completed; run the command again.");
|
||||
fail(source, IrisLanguage.plain(ModdedCommandMessages.IRIS_MODDED_COMMANDS_YOU_CHANGED_DIMENSIONS_BEFORE_STRUCTURE_SEARCH_COMPLETED_RUN_COMMAND_AGAIN));
|
||||
return;
|
||||
}
|
||||
level.getChunk(targetX >> 4, targetZ >> 4);
|
||||
@@ -1017,17 +1039,17 @@ public final class IrisModdedCommands {
|
||||
boolean teleported = player.teleportTo(level, targetX + 0.5D, clampedY, targetZ + 0.5D,
|
||||
Set.<Relative>of(), player.getYRot(), player.getXRot(), false);
|
||||
if (!teleported) {
|
||||
fail(source, "Found " + label + " at " + targetX + " " + clampedY + " " + targetZ + ", but teleportation failed.");
|
||||
fail(source, IrisLanguage.plain(ModdedCommandMessages.IRIS_MODDED_COMMANDS_FOUND_AT_BUT_TELEPORTATION_FAILED, MessageArgument.untrusted("label", label), MessageArgument.untrusted("targetX", targetX), MessageArgument.untrusted("clampedY", clampedY), MessageArgument.untrusted("targetZ", targetZ)));
|
||||
return;
|
||||
}
|
||||
ok(source, "Teleported to " + label + " at " + targetX + " " + clampedY + " " + targetZ);
|
||||
ok(source, IrisLanguage.plain(ModdedCommandMessages.IRIS_MODDED_COMMANDS_TELEPORTED_AT, MessageArgument.untrusted("label", label), MessageArgument.untrusted("targetX", targetX), MessageArgument.untrusted("clampedY", clampedY), MessageArgument.untrusted("targetZ", targetZ)));
|
||||
}
|
||||
|
||||
static int verifyStructures(CommandSourceStack source, String keyRaw) {
|
||||
ServerLevel level = source.getLevel();
|
||||
Engine engine = engineFor(level);
|
||||
if (engine == null) {
|
||||
fail(source, "This dimension is not generated by Iris.");
|
||||
fail(source, IrisLanguage.plain(ModdedCommandMessages.IRIS_MODDED_COMMANDS_THIS_DIMENSION_IS_NOT_GENERATED_BY_IRIS_12));
|
||||
return 0;
|
||||
}
|
||||
String key = keyRaw == null ? "" : keyRaw.trim();
|
||||
@@ -1056,11 +1078,7 @@ public final class IrisModdedCommands {
|
||||
}
|
||||
}
|
||||
int irisPlaced = IrisStructureLocator.placedKeys(engine).size();
|
||||
ok(source, "Structure reachability: " + available + " native generation-eligible, " + irisPlaced
|
||||
+ " Iris-placed, " + disabled + " native disabled, " + suppressed
|
||||
+ " native replaced by Iris placements, " + unreachableBiomes
|
||||
+ " native excluded by this pack's biomes, and " + unsupported
|
||||
+ " registered native structures unsupported in this dimension. Use /iris structure verify <key> for one structure.");
|
||||
ok(source, IrisLanguage.plain(ModdedCommandMessages.IRIS_MODDED_COMMANDS_STRUCTURE_REACHABILITY_NATIVE_GENERATION_ELIGIBLE_IRIS_PLACED_NATIVE_DISABLED_NATIVE, MessageArgument.untrusted("available", available), MessageArgument.untrusted("irisPlaced", irisPlaced), MessageArgument.untrusted("disabled", disabled), MessageArgument.untrusted("suppressed", suppressed), MessageArgument.untrusted("unreachableBiomes", unreachableBiomes), MessageArgument.untrusted("unsupported", unsupported)));
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -1068,24 +1086,22 @@ public final class IrisModdedCommands {
|
||||
Optional<NativeStructureTarget> target = resolveNativeStructure(source, level, engine, key);
|
||||
if (target.isEmpty()) {
|
||||
if (IrisStructureLocator.isPlaced(engine, key)) {
|
||||
ok(source, "Structure " + key + " is Iris-placed and locatable with /iris goto structure " + key + ".");
|
||||
ok(source, IrisLanguage.plain(ModdedCommandMessages.IRIS_MODDED_COMMANDS_STRUCTURE_IS_IRIS_PLACED_LOCATABLE_WITH_IRIS_GOTO_STRUCTURE, MessageArgument.untrusted("key", key), MessageArgument.untrusted("key2", key)));
|
||||
return 1;
|
||||
}
|
||||
fail(source, "Unknown structure '" + key + "'. It is neither Iris-placed nor registered by vanilla or a datapack.");
|
||||
fail(source, IrisLanguage.plain(ModdedCommandMessages.IRIS_MODDED_COMMANDS_UNKNOWN_STRUCTURE_IT_IS_NEITHER_IRIS_PLACED_NOR_REGISTERED_BY, MessageArgument.untrusted("key", key)));
|
||||
return 0;
|
||||
}
|
||||
NativeStructureTarget resolved = target.get();
|
||||
if (resolved.availability() == NativeStructureAvailability.IRIS_SUPPRESSED) {
|
||||
ok(source, "Structure " + resolved.key()
|
||||
+ " is explicitly replaced by an Iris placement and locatable with /iris goto structure "
|
||||
+ resolved.key() + ".");
|
||||
ok(source, IrisLanguage.plain(ModdedCommandMessages.IRIS_MODDED_COMMANDS_STRUCTURE_IS_EXPLICITLY_REPLACED_BY_IRIS_PLACEMENT_LOCATABLE_WITH_IRIS, MessageArgument.untrusted("value", resolved.key()), MessageArgument.untrusted("value2", resolved.key())));
|
||||
return 1;
|
||||
}
|
||||
if (resolved.availability() != NativeStructureAvailability.AVAILABLE) {
|
||||
fail(source, nativeUnavailableMessage(resolved.key(), resolved.availability()));
|
||||
return 0;
|
||||
}
|
||||
ok(source, "Native structure " + resolved.key() + " is enabled, supported by this dimension's generator state, and locatable with /iris goto structure " + resolved.key() + ".");
|
||||
ok(source, IrisLanguage.plain(ModdedCommandMessages.IRIS_MODDED_COMMANDS_NATIVE_STRUCTURE_IS_ENABLED_SUPPORTED_BY_THIS_DIMENSION_S_GENERATOR, MessageArgument.untrusted("value", resolved.key()), MessageArgument.untrusted("value2", resolved.key())));
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -1162,13 +1178,13 @@ public final class IrisModdedCommands {
|
||||
ServerLevel level = source.getLevel();
|
||||
Engine engine = engineFor(level);
|
||||
if (engine == null) {
|
||||
fail(source, "This dimension is not generated by Iris.");
|
||||
fail(source, IrisLanguage.plain(ModdedCommandMessages.IRIS_MODDED_COMMANDS_THIS_DIMENSION_IS_NOT_GENERATED_BY_IRIS_13));
|
||||
return 0;
|
||||
}
|
||||
String type = typeRaw.trim();
|
||||
ServerPlayer player = source.getPlayer();
|
||||
if (player == null) {
|
||||
fail(source, "This command can only be used by players. (POI type '" + type + "' accepted)");
|
||||
fail(source, IrisLanguage.plain(ModdedCommandMessages.IRIS_MODDED_COMMANDS_THIS_COMMAND_CAN_ONLY_BE_USED_BY_PLAYERS_POI_TYPE, MessageArgument.untrusted("type", type)));
|
||||
return 0;
|
||||
}
|
||||
locate(source, level, engine, player, Locator.poi(type), "POI " + type);
|
||||
@@ -1179,13 +1195,13 @@ public final class IrisModdedCommands {
|
||||
MinecraftServer server = source.getServer();
|
||||
int chunkX = player.blockPosition().getX() >> 4;
|
||||
int chunkZ = player.blockPosition().getZ() >> 4;
|
||||
ok(source, "Searching for " + label + "...");
|
||||
ok(source, IrisLanguage.plain(ModdedCommandMessages.IRIS_MODDED_COMMANDS_SEARCHING, MessageArgument.untrusted("label", label)));
|
||||
CompletableFuture<Position2> search;
|
||||
try {
|
||||
search = locator.find(engine, new Position2(chunkX, chunkZ), LOCATE_TIMEOUT_MS, (Integer checks) -> {
|
||||
});
|
||||
} catch (WrongEngineBroException e) {
|
||||
fail(source, "The engine for this world has been closed; rejoin the dimension and try again.");
|
||||
fail(source, IrisLanguage.plain(ModdedCommandMessages.IRIS_MODDED_COMMANDS_ENGINE_THIS_WORLD_HAS_BEEN_CLOSED_REJOIN_DIMENSION_TRY_AGAIN));
|
||||
return;
|
||||
}
|
||||
UUID playerId = player.getUUID();
|
||||
@@ -1212,7 +1228,7 @@ public final class IrisModdedCommands {
|
||||
LOGGER.error("Iris locate failed for {}", label, failure);
|
||||
server.execute(() -> {
|
||||
if (ACTIVE_LOCATE_REQUESTS.remove(playerId, search)) {
|
||||
fail(source, "Search failed: " + failure);
|
||||
fail(source, IrisLanguage.plain(ModdedCommandMessages.IRIS_MODDED_COMMANDS_SEARCH_FAILED_2, MessageArgument.untrusted("failure", failure)));
|
||||
}
|
||||
});
|
||||
return;
|
||||
@@ -1220,7 +1236,7 @@ public final class IrisModdedCommands {
|
||||
if (at == null) {
|
||||
server.execute(() -> {
|
||||
if (ACTIVE_LOCATE_REQUESTS.remove(playerId, search)) {
|
||||
fail(source, "Could not find " + label + " within the search timeout.");
|
||||
fail(source, IrisLanguage.plain(ModdedCommandMessages.IRIS_MODDED_COMMANDS_COULD_NOT_FIND_WITHIN_SEARCH_TIMEOUT, MessageArgument.untrusted("label", label)));
|
||||
}
|
||||
});
|
||||
return;
|
||||
@@ -1240,9 +1256,9 @@ public final class IrisModdedCommands {
|
||||
IrisContext.Scope ignored = IrisContext.open(engine, lease.sessionId(), null)) {
|
||||
int blockY = engine.getMinHeight() + engine.getHeight(blockX, blockZ, false) + 2;
|
||||
player.teleportTo(level, blockX + 0.5D, blockY, blockZ + 0.5D, Set.<Relative>of(), player.getYRot(), player.getXRot(), false);
|
||||
ok(source, "Teleported to " + label + " at " + blockX + " " + blockY + " " + blockZ);
|
||||
ok(source, IrisLanguage.plain(ModdedCommandMessages.IRIS_MODDED_COMMANDS_TELEPORTED_AT_2, MessageArgument.untrusted("label", label), MessageArgument.untrusted("blockX", blockX), MessageArgument.untrusted("blockY", blockY), MessageArgument.untrusted("blockZ", blockZ)));
|
||||
} catch (GenerationSessionException e) {
|
||||
fail(source, "The engine changed while locating " + label + "; try again.");
|
||||
fail(source, IrisLanguage.plain(ModdedCommandMessages.IRIS_MODDED_COMMANDS_ENGINE_CHANGED_WHILE_LOCATING_TRY_AGAIN, MessageArgument.untrusted("label", label)));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1259,11 +1275,11 @@ public final class IrisModdedCommands {
|
||||
ServerLevel level = source.getLevel();
|
||||
Engine engine = engineFor(level);
|
||||
if (engine == null) {
|
||||
fail(source, "This dimension is not generated by Iris.");
|
||||
fail(source, IrisLanguage.plain(ModdedCommandMessages.IRIS_MODDED_COMMANDS_THIS_DIMENSION_IS_NOT_GENERATED_BY_IRIS_14));
|
||||
return 0;
|
||||
}
|
||||
ok(source, "World seed: " + level.getSeed());
|
||||
ok(source, "Engine seed: " + engine.getSeedManager().getSeed() + " (mixed: " + engine.getSeedManager().getFullMixedSeed() + ")");
|
||||
ok(source, IrisLanguage.plain(ModdedCommandMessages.IRIS_MODDED_COMMANDS_WORLD_SEED, MessageArgument.untrusted("value", level.getSeed())));
|
||||
ok(source, IrisLanguage.plain(ModdedCommandMessages.IRIS_MODDED_COMMANDS_ENGINE_SEED_MIXED, MessageArgument.untrusted("value", engine.getSeedManager().getSeed()), MessageArgument.untrusted("value2", engine.getSeedManager().getFullMixedSeed())));
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -1271,7 +1287,7 @@ public final class IrisModdedCommands {
|
||||
ServerLevel level = source.getLevel();
|
||||
Engine engine = engineFor(level);
|
||||
if (engine == null) {
|
||||
fail(source, "This dimension is not generated by Iris.");
|
||||
fail(source, IrisLanguage.plain(ModdedCommandMessages.IRIS_MODDED_COMMANDS_THIS_DIMENSION_IS_NOT_GENERATED_BY_IRIS_15));
|
||||
return 0;
|
||||
}
|
||||
ModdedGoldenHash.start(source, level, engine, radius, threads, mode);
|
||||
@@ -1282,14 +1298,14 @@ public final class IrisModdedCommands {
|
||||
MinecraftServer server = source.getServer();
|
||||
boolean defaultOverworld = PackDownloader.isDefaultOverworld(pack);
|
||||
String downloadSource = defaultOverworld ? "beta release" : "branch " + branch;
|
||||
ok(source, "Downloading IrisDimensions/" + pack + " (" + downloadSource + ")...");
|
||||
ok(source, IrisLanguage.plain(ModdedCommandMessages.IRIS_MODDED_COMMANDS_DOWNLOADING_IRISDIMENSIONS, MessageArgument.untrusted("pack", pack), MessageArgument.untrusted("downloadSource", downloadSource)));
|
||||
Thread thread = new Thread(() -> {
|
||||
boolean installed = ModdedPackInstaller.install(ModdedEngineBootstrap.loader().configDir(), pack, branch,
|
||||
(String message) -> server.execute(() -> ok(source, message)));
|
||||
if (installed) {
|
||||
server.execute(() -> ok(source, "Pack '" + pack + "' installed. Its exact dimension types and custom biomes join the forced Iris datapack on the next server restart; restart before creating worlds from this pack."));
|
||||
server.execute(() -> ok(source, IrisLanguage.plain(ModdedCommandMessages.IRIS_MODDED_COMMANDS_PACK_INSTALLED_ITS_EXACT_DIMENSION_TYPES_CUSTOM_BIOMES_JOIN_FORCED, MessageArgument.untrusted("pack", pack))));
|
||||
} else {
|
||||
server.execute(() -> fail(source, "Pack download failed for " + pack + " (" + downloadSource + "; see console)."));
|
||||
server.execute(() -> fail(source, IrisLanguage.plain(ModdedCommandMessages.IRIS_MODDED_COMMANDS_PACK_DOWNLOAD_FAILED_SEE_CONSOLE, MessageArgument.untrusted("pack", pack), MessageArgument.untrusted("downloadSource", downloadSource))));
|
||||
}
|
||||
}, "Iris Pack Download");
|
||||
thread.setDaemon(true);
|
||||
@@ -1301,17 +1317,17 @@ public final class IrisModdedCommands {
|
||||
ServerLevel level = source.getLevel();
|
||||
Engine engine = engineFor(level);
|
||||
if (engine == null) {
|
||||
fail(source, "This dimension is not generated by Iris.");
|
||||
fail(source, IrisLanguage.plain(ModdedCommandMessages.IRIS_MODDED_COMMANDS_THIS_DIMENSION_IS_NOT_GENERATED_BY_IRIS_16));
|
||||
return 0;
|
||||
}
|
||||
ok(source, "Generated: " + engine.getGenerated() + " chunk(s), " + String.format("%.1f", engine.getGeneratedPerSecond()) + "/s");
|
||||
ok(source, IrisLanguage.plain(ModdedCommandMessages.IRIS_MODDED_COMMANDS_GENERATED_CHUNK_S_S, MessageArgument.untrusted("value", engine.getGenerated()), MessageArgument.untrusted("value2", String.format("%.1f", engine.getGeneratedPerSecond()))));
|
||||
KMap<String, Double> pulled = engine.getMetrics().pull();
|
||||
Map<String, Double> sorted = new TreeMap<>(pulled);
|
||||
for (Map.Entry<String, Double> entry : sorted.entrySet()) {
|
||||
if (entry.getValue() == null || entry.getValue() <= 0D) {
|
||||
continue;
|
||||
}
|
||||
ok(source, " " + entry.getKey() + ": " + String.format("%.2f", entry.getValue()) + "ms");
|
||||
ok(source, IrisLanguage.plain(ModdedCommandMessages.IRIS_MODDED_COMMANDS_MS, MessageArgument.untrusted("value", entry.getKey()), MessageArgument.untrusted("value2", String.format("%.2f", entry.getValue()))));
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
+120
-109
@@ -24,6 +24,12 @@ import net.minecraft.network.chat.ClickEvent;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.network.chat.HoverEvent;
|
||||
import net.minecraft.network.chat.MutableComponent;
|
||||
import art.arcane.iris.core.localization.IrisMessages;
|
||||
import art.arcane.iris.core.localization.IrisLanguage;
|
||||
import art.arcane.iris.core.localization.ModdedHelpMessages;
|
||||
import art.arcane.volmlib.util.director.help.DirectorHelpMessages;
|
||||
import art.arcane.volmlib.util.localization.MessageArgument;
|
||||
import art.arcane.volmlib.util.localization.TextKey;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedHashMap;
|
||||
@@ -50,124 +56,124 @@ final class ModdedCommandHelp {
|
||||
|
||||
static {
|
||||
SECTIONS.put("", List.of(
|
||||
Entry.command("version", "", "Print version information"),
|
||||
Entry.command("info", "[dimension]", "List loaded Iris dimensions and pack details"),
|
||||
Entry.command("what", "[block|hand|markers]", "Inspect the Iris biome, region, cave biome, surface and chunk at your position, the block you look at, your held item, or nearby markers"),
|
||||
Entry.group("find", "Find and teleport to Iris biomes, regions, objects, Iris structures, native structures and points of interest", "goto"),
|
||||
Entry.command("tp", "<dimension> [player]", "Teleport yourself or a named player into a loaded Iris dimension"),
|
||||
Entry.command("evacuate", "[dimension]", "Teleport every player out of an Iris dimension to the primary world spawn"),
|
||||
Entry.command("seed", "", "Print world and engine seed information"),
|
||||
Entry.command("debug", "", "Toggle Iris debug logging and save settings.json"),
|
||||
Entry.command("reload", "", "Reload settings.json (also hotloaded automatically every 3s)"),
|
||||
Entry.command("download", "<pack> [branch]", "Download a pack project", "dl"),
|
||||
Entry.command("metrics", "", "Print generation metrics for your current Iris dimension", "measure"),
|
||||
Entry.command("regen", "[radius]", "Delete and regenerate nearby chunks in place", "rg"),
|
||||
Entry.group("pregen", "Pregenerate an Iris dimension", "pregenerate"),
|
||||
Entry.command("wand", "", "Get an Iris object wand"),
|
||||
Entry.group("object", "Object wand, save, paste, analyze and undo tools", "o"),
|
||||
Entry.group("edit", "Open pack biome, region and dimension json files in your desktop editor"),
|
||||
Entry.command("create", "<name> <pack|pack:dimensionKey> [seed]", "Create and inject a persistent Iris dimension; quote pack:dimensionKey to pick a specific pack dimension"),
|
||||
Entry.group("studio", "Pack project creation, packaging and reports", "std", "s"),
|
||||
Entry.group("pack", "Pack validation and maintenance", "pk"),
|
||||
Entry.group("world", "Runtime Iris dimension creation, removal and status", "w"),
|
||||
Entry.group("datapack", "World datapack install and status helpers", "datapacks", "dp"),
|
||||
Entry.group("structure", "Iris structure index, info and placement tools", "struct", "str"),
|
||||
Entry.command("goldenhash", "[radius] [threads] [capture|verify]", "Generate deterministic block hashes for parity testing", "gold"),
|
||||
Entry.group("developer", "Developer diagnostics: Sentry test, network interfaces, region-file scan", "dev")
|
||||
Entry.command("version", "", ModdedHelpMessages.COMMAND_VERSION_PRINT_VERSION_INFORMATION),
|
||||
Entry.command("info", "[dimension]", ModdedHelpMessages.COMMAND_INFO_LIST_LOADED_IRIS_DIMENSIONS_AND_PACK_DETAILS),
|
||||
Entry.command("what", "[block|hand|markers]", ModdedHelpMessages.COMMAND_WHAT_INSPECT_THE_IRIS_BIOME_REGION_CAVE_BIOME_SURFACE_AND_CHUNK_AT_YOUR),
|
||||
Entry.group("find", ModdedHelpMessages.GROUP_FIND_FIND_AND_TELEPORT_TO_IRIS_BIOMES_REGIONS_OBJECTS_IRIS_STRUCTURES_NATIVE_STRUCTURES, "goto"),
|
||||
Entry.command("tp", "<dimension> [player]", ModdedHelpMessages.COMMAND_TP_TELEPORT_YOURSELF_OR_A_NAMED_PLAYER_INTO_A_LOADED_IRIS_DIMENSION),
|
||||
Entry.command("evacuate", "[dimension]", ModdedHelpMessages.COMMAND_EVACUATE_TELEPORT_EVERY_PLAYER_OUT_OF_AN_IRIS_DIMENSION_TO_THE_PRIMARY_WORLD),
|
||||
Entry.command("seed", "", ModdedHelpMessages.COMMAND_SEED_PRINT_WORLD_AND_ENGINE_SEED_INFORMATION),
|
||||
Entry.command("debug", "", ModdedHelpMessages.COMMAND_DEBUG_TOGGLE_IRIS_DEBUG_LOGGING_AND_SAVE_SETTINGS_JSON),
|
||||
Entry.command("reload", "", ModdedHelpMessages.COMMAND_RELOAD_RELOAD_SETTINGS_JSON_ALSO_HOTLOADED_AUTOMATICALLY_EVERY_3S),
|
||||
Entry.command("download", "<pack> [branch]", ModdedHelpMessages.COMMAND_DOWNLOAD_DOWNLOAD_A_PACK_PROJECT, "dl"),
|
||||
Entry.command("metrics", "", ModdedHelpMessages.COMMAND_METRICS_PRINT_GENERATION_METRICS_FOR_YOUR_CURRENT_IRIS_DIMENSION, "measure"),
|
||||
Entry.command("regen", "[radius]", ModdedHelpMessages.COMMAND_REGEN_DELETE_AND_REGENERATE_NEARBY_CHUNKS_IN_PLACE, "rg"),
|
||||
Entry.group("pregen", ModdedHelpMessages.GROUP_PREGEN_PREGENERATE_AN_IRIS_DIMENSION, "pregenerate"),
|
||||
Entry.command("wand", "", ModdedHelpMessages.COMMAND_WAND_GET_AN_IRIS_OBJECT_WAND),
|
||||
Entry.group("object", ModdedHelpMessages.GROUP_OBJECT_OBJECT_WAND_SAVE_PASTE_ANALYZE_AND_UNDO_TOOLS, "o"),
|
||||
Entry.group("edit", ModdedHelpMessages.GROUP_EDIT_OPEN_PACK_BIOME_REGION_AND_DIMENSION_JSON_FILES_IN_YOUR_DESKTOP_EDITOR),
|
||||
Entry.command("create", "<name> <pack|pack:dimensionKey> [seed]", ModdedHelpMessages.COMMAND_CREATE_CREATE_AND_INJECT_A_PERSISTENT_IRIS_DIMENSION_QUOTE_PACK_DIMENSIONKEY_TO_PICK),
|
||||
Entry.group("studio", ModdedHelpMessages.GROUP_STUDIO_PACK_PROJECT_CREATION_PACKAGING_AND_REPORTS, "std", "s"),
|
||||
Entry.group("pack", ModdedHelpMessages.GROUP_PACK_PACK_VALIDATION_AND_MAINTENANCE, "pk"),
|
||||
Entry.group("world", ModdedHelpMessages.GROUP_WORLD_RUNTIME_IRIS_DIMENSION_CREATION_REMOVAL_AND_STATUS, "w"),
|
||||
Entry.group("datapack", ModdedHelpMessages.GROUP_DATAPACK_WORLD_DATAPACK_INSTALL_AND_STATUS_HELPERS, "datapacks", "dp"),
|
||||
Entry.group("structure", ModdedHelpMessages.GROUP_STRUCTURE_IRIS_STRUCTURE_INDEX_INFO_AND_PLACEMENT_TOOLS, "struct", "str"),
|
||||
Entry.command("goldenhash", "[radius] [threads] [capture|verify]", ModdedHelpMessages.COMMAND_GOLDENHASH_GENERATE_DETERMINISTIC_BLOCK_HASHES_FOR_PARITY_TESTING, "gold"),
|
||||
Entry.group("developer", ModdedHelpMessages.GROUP_DEVELOPER_DEVELOPER_DIAGNOSTICS_SENTRY_TEST_NETWORK_INTERFACES_REGION_FILE_SCAN, "dev")
|
||||
));
|
||||
SECTIONS.put("find", List.of(
|
||||
Entry.command("biome", "<key>", "Find an Iris biome"),
|
||||
Entry.command("region", "<key>", "Find an Iris region"),
|
||||
Entry.command("object", "<key>", "Find an object placement"),
|
||||
Entry.command("structure", "<key>", "Find an Iris-placed or native/datapack structure"),
|
||||
Entry.command("poi", "<type>", "Find a supported point of interest")
|
||||
Entry.command("biome", "<key>", ModdedHelpMessages.COMMAND_BIOME_FIND_AN_IRIS_BIOME),
|
||||
Entry.command("region", "<key>", ModdedHelpMessages.COMMAND_REGION_FIND_AN_IRIS_REGION),
|
||||
Entry.command("object", "<key>", ModdedHelpMessages.COMMAND_OBJECT_FIND_AN_OBJECT_PLACEMENT),
|
||||
Entry.command("structure", "<key>", ModdedHelpMessages.COMMAND_STRUCTURE_FIND_AN_IRIS_PLACED_OR_NATIVE_DATAPACK_STRUCTURE),
|
||||
Entry.command("poi", "<type>", ModdedHelpMessages.COMMAND_POI_FIND_A_SUPPORTED_POINT_OF_INTEREST)
|
||||
));
|
||||
SECTIONS.put("goto", SECTIONS.get("find"));
|
||||
SECTIONS.put("edit", List.of(
|
||||
Entry.command("biome", "[key]", "Open a biome json in your desktop editor; no key opens the biome at your position"),
|
||||
Entry.command("region", "[key]", "Open a region json in your desktop editor; no key opens the region at your position"),
|
||||
Entry.command("dimension", "", "Open the current pack's dimension json in your desktop editor")
|
||||
Entry.command("biome", "[key]", ModdedHelpMessages.COMMAND_BIOME_OPEN_A_BIOME_JSON_IN_YOUR_DESKTOP_EDITOR_NO_KEY_OPENS_THE),
|
||||
Entry.command("region", "[key]", ModdedHelpMessages.COMMAND_REGION_OPEN_A_REGION_JSON_IN_YOUR_DESKTOP_EDITOR_NO_KEY_OPENS_THE),
|
||||
Entry.command("dimension", "", ModdedHelpMessages.COMMAND_DIMENSION_OPEN_THE_CURRENT_PACK_S_DIMENSION_JSON_IN_YOUR_DESKTOP_EDITOR)
|
||||
));
|
||||
SECTIONS.put("pregen", List.of(
|
||||
Entry.command("start", "<radius> [dimension] [at] [x] [z] [gui] [sync] [nocache]", "Start pregeneration; radius in blocks, resumable checkpoint cache on by default, center via 'at <x> <z>', flags compose in any order"),
|
||||
Entry.command("stop", "", "Stop the active pregeneration task", "x"),
|
||||
Entry.command("pause", "", "Pause or resume pregeneration", "resume"),
|
||||
Entry.command("status", "", "Show pregeneration status")
|
||||
Entry.command("start", "<radius> [dimension] [at] [x] [z] [gui] [sync] [nocache]", ModdedHelpMessages.COMMAND_START_START_PREGENERATION_RADIUS_IN_BLOCKS_RESUMABLE_CHECKPOINT_CACHE_ON_BY_DEFAULT_CENTER),
|
||||
Entry.command("stop", "", ModdedHelpMessages.COMMAND_STOP_STOP_THE_ACTIVE_PREGENERATION_TASK, "x"),
|
||||
Entry.command("pause", "", ModdedHelpMessages.COMMAND_PAUSE_PAUSE_OR_RESUME_PREGENERATION, "resume"),
|
||||
Entry.command("status", "", ModdedHelpMessages.COMMAND_STATUS_SHOW_PREGENERATION_STATUS)
|
||||
));
|
||||
SECTIONS.put("pregenerate", SECTIONS.get("pregen"));
|
||||
SECTIONS.put("object", List.of(
|
||||
Entry.command("wand", "", "Get an Iris object wand"),
|
||||
Entry.command("dust", "", "Get dust that reveals object placements", "d"),
|
||||
Entry.command("save", "[overwrite] <name>", "Save the selected wand volume as an object"),
|
||||
Entry.command("paste", "[at] [x] [y] [z] [rotate] [degrees] <key>", "Paste an object at your position or a given position, optionally rotated"),
|
||||
Entry.command("expand", "[amount]", "Expand the wand selection in your looking direction"),
|
||||
Entry.command("contract", "[amount]", "Contract the wand selection in your looking direction", "-"),
|
||||
Entry.command("shift", "[amount]", "Shift the wand selection in your looking direction"),
|
||||
Entry.command("position1", "[look]", "Set selection point 1", "p1"),
|
||||
Entry.command("position2", "[look]", "Set selection point 2", "p2"),
|
||||
Entry.command("x+y", "", "Autoselect up and out", "xpy"),
|
||||
Entry.command("x&y", "", "Autoselect up, down and out", "xay"),
|
||||
Entry.command("analyze", "<key>", "Show object composition"),
|
||||
Entry.command("shrink", "<key>", "Shrink an object to its minimum size"),
|
||||
Entry.command("plausibilize", "<key|prefix/> [dryrun=true] [reach=N]", "Grow branches so tree leaves survive vanilla decay"),
|
||||
Entry.command("undo", "[amount]", "Undo pasted objects", "u")
|
||||
Entry.command("wand", "", ModdedHelpMessages.COMMAND_WAND_GET_AN_IRIS_OBJECT_WAND_2),
|
||||
Entry.command("dust", "", ModdedHelpMessages.COMMAND_DUST_GET_DUST_THAT_REVEALS_OBJECT_PLACEMENTS, "d"),
|
||||
Entry.command("save", "[overwrite] <name>", ModdedHelpMessages.COMMAND_SAVE_SAVE_THE_SELECTED_WAND_VOLUME_AS_AN_OBJECT),
|
||||
Entry.command("paste", "[at] [x] [y] [z] [rotate] [degrees] <key>", ModdedHelpMessages.COMMAND_PASTE_PASTE_AN_OBJECT_AT_YOUR_POSITION_OR_A_GIVEN_POSITION_OPTIONALLY_ROTATED),
|
||||
Entry.command("expand", "[amount]", ModdedHelpMessages.COMMAND_EXPAND_EXPAND_THE_WAND_SELECTION_IN_YOUR_LOOKING_DIRECTION),
|
||||
Entry.command("contract", "[amount]", ModdedHelpMessages.COMMAND_CONTRACT_CONTRACT_THE_WAND_SELECTION_IN_YOUR_LOOKING_DIRECTION, "-"),
|
||||
Entry.command("shift", "[amount]", ModdedHelpMessages.COMMAND_SHIFT_SHIFT_THE_WAND_SELECTION_IN_YOUR_LOOKING_DIRECTION),
|
||||
Entry.command("position1", "[look]", ModdedHelpMessages.COMMAND_POSITION1_SET_SELECTION_POINT_1, "p1"),
|
||||
Entry.command("position2", "[look]", ModdedHelpMessages.COMMAND_POSITION2_SET_SELECTION_POINT_2, "p2"),
|
||||
Entry.command("x+y", "", ModdedHelpMessages.COMMAND_X_Y_AUTOSELECT_UP_AND_OUT, "xpy"),
|
||||
Entry.command("x&y", "", ModdedHelpMessages.COMMAND_X_Y_AUTOSELECT_UP_DOWN_AND_OUT, "xay"),
|
||||
Entry.command("analyze", "<key>", ModdedHelpMessages.COMMAND_ANALYZE_SHOW_OBJECT_COMPOSITION),
|
||||
Entry.command("shrink", "<key>", ModdedHelpMessages.COMMAND_SHRINK_SHRINK_AN_OBJECT_TO_ITS_MINIMUM_SIZE),
|
||||
Entry.command("plausibilize", "<key|prefix/> [dryrun=true] [reach=N]", ModdedHelpMessages.COMMAND_PLAUSIBILIZE_GROW_BRANCHES_SO_TREE_LEAVES_SURVIVE_VANILLA_DECAY),
|
||||
Entry.command("undo", "[amount]", ModdedHelpMessages.COMMAND_UNDO_UNDO_PASTED_OBJECTS, "u")
|
||||
));
|
||||
SECTIONS.put("o", SECTIONS.get("object"));
|
||||
SECTIONS.put("studio", List.of(
|
||||
Entry.command("create", "<name> [template]", "Create a new pack project", "+"),
|
||||
Entry.command("package", "[pack]", "Package a dimension into a compressed format"),
|
||||
Entry.command("version", "[pack]", "Print a pack version"),
|
||||
Entry.command("regions", "[radius]", "Calculate nearby region distribution"),
|
||||
Entry.command("open", "<pack> [seed]", "Open a temporary studio dimension for a pack", "o"),
|
||||
Entry.command("close", "", "Close the open studio dimension and discard its world", "x"),
|
||||
Entry.command("tpstudio", "", "Teleport into the open studio dimension", "stp"),
|
||||
Entry.command("status", "", "Show the open studio dimension and its pack"),
|
||||
Entry.command("noise", "[generator] [seed]", "Open the Noise Explorer GUI on the server display", "nmap"),
|
||||
Entry.command("map", "", "Open the Vision map GUI on the server display", "render"),
|
||||
Entry.command("vscode", "[pack]", "Regenerate the .code-workspace for a pack and open it in your desktop editor", "vsc"),
|
||||
Entry.command("update", "[pack]", "Regenerate the .code-workspace for a pack"),
|
||||
Entry.command("importvanilla", "", "Explain vanilla import workflow", "importv", "iv")
|
||||
Entry.command("create", "<name> [template]", ModdedHelpMessages.COMMAND_CREATE_CREATE_A_NEW_PACK_PROJECT, "+"),
|
||||
Entry.command("package", "[pack]", ModdedHelpMessages.COMMAND_PACKAGE_PACKAGE_A_DIMENSION_INTO_A_COMPRESSED_FORMAT),
|
||||
Entry.command("version", "[pack]", ModdedHelpMessages.COMMAND_VERSION_PRINT_A_PACK_VERSION),
|
||||
Entry.command("regions", "[radius]", ModdedHelpMessages.COMMAND_REGIONS_CALCULATE_NEARBY_REGION_DISTRIBUTION),
|
||||
Entry.command("open", "<pack> [seed]", ModdedHelpMessages.COMMAND_OPEN_OPEN_A_TEMPORARY_STUDIO_DIMENSION_FOR_A_PACK, "o"),
|
||||
Entry.command("close", "", ModdedHelpMessages.COMMAND_CLOSE_CLOSE_THE_OPEN_STUDIO_DIMENSION_AND_DISCARD_ITS_WORLD, "x"),
|
||||
Entry.command("tpstudio", "", ModdedHelpMessages.COMMAND_TPSTUDIO_TELEPORT_INTO_THE_OPEN_STUDIO_DIMENSION, "stp"),
|
||||
Entry.command("status", "", ModdedHelpMessages.COMMAND_STATUS_SHOW_THE_OPEN_STUDIO_DIMENSION_AND_ITS_PACK),
|
||||
Entry.command("noise", "[generator] [seed]", ModdedHelpMessages.COMMAND_NOISE_OPEN_THE_NOISE_EXPLORER_GUI_ON_THE_SERVER_DISPLAY, "nmap"),
|
||||
Entry.command("map", "", ModdedHelpMessages.COMMAND_MAP_OPEN_THE_VISION_MAP_GUI_ON_THE_SERVER_DISPLAY, "render"),
|
||||
Entry.command("vscode", "[pack]", ModdedHelpMessages.COMMAND_VSCODE_REGENERATE_THE_CODE_WORKSPACE_FOR_A_PACK_AND_OPEN_IT_IN_YOUR, "vsc"),
|
||||
Entry.command("update", "[pack]", ModdedHelpMessages.COMMAND_UPDATE_REGENERATE_THE_CODE_WORKSPACE_FOR_A_PACK),
|
||||
Entry.command("importvanilla", "", ModdedHelpMessages.COMMAND_IMPORTVANILLA_EXPLAIN_VANILLA_IMPORT_WORKFLOW, "importv", "iv")
|
||||
));
|
||||
SECTIONS.put("std", SECTIONS.get("studio"));
|
||||
SECTIONS.put("s", SECTIONS.get("studio"));
|
||||
SECTIONS.put("pack", List.of(
|
||||
Entry.command("validate", "[pack]", "Validate a pack or every pack", "v"),
|
||||
Entry.command("cleanup", "<pack> [apply]", "Preview or quarantine unused-resource candidates", "c"),
|
||||
Entry.command("restore", "<pack> [apply]", "Preview or restore the latest quarantine", "r"),
|
||||
Entry.command("status", "[pack]", "Show cached validation status", "s")
|
||||
Entry.command("validate", "[pack]", ModdedHelpMessages.COMMAND_VALIDATE_VALIDATE_A_PACK_OR_EVERY_PACK, "v"),
|
||||
Entry.command("cleanup", "<pack> [apply]", ModdedHelpMessages.COMMAND_CLEANUP_PREVIEW_OR_QUARANTINE_UNUSED_RESOURCE_CANDIDATES, "c"),
|
||||
Entry.command("restore", "<pack> [apply]", ModdedHelpMessages.COMMAND_RESTORE_PREVIEW_OR_RESTORE_THE_LATEST_QUARANTINE, "r"),
|
||||
Entry.command("status", "[pack]", ModdedHelpMessages.COMMAND_STATUS_SHOW_CACHED_VALIDATION_STATUS, "s")
|
||||
));
|
||||
SECTIONS.put("pk", SECTIONS.get("pack"));
|
||||
SECTIONS.put("world", List.of(
|
||||
Entry.command("enable", "<dimension> <pack|pack:dimensionKey> [seed|random]", "Create and inject a persistent Iris dimension at runtime; downloads the pack if missing, quote pack:dimensionKey to pick a specific pack dimension", "create"),
|
||||
Entry.command("replace-overworld", "<pack|pack:dimensionKey> [seed|random]", "Inject an Iris primary world and route players there instead of the vanilla overworld"),
|
||||
Entry.command("disable", "<dimension>", "Evacuate and unload an Iris dimension; world data on disk is kept for re-enabling"),
|
||||
Entry.command("delete", "<dimension>", "Disable an Iris dimension and wipe its chunk and mantle data from disk", "remove", "rm"),
|
||||
Entry.command("list", "", "List loaded Iris dimensions", "ls"),
|
||||
Entry.command("status", "", "Show loaded Iris dimensions and the configured primary world")
|
||||
Entry.command("enable", "<dimension> <pack|pack:dimensionKey> [seed|random]", ModdedHelpMessages.COMMAND_ENABLE_CREATE_AND_INJECT_A_PERSISTENT_IRIS_DIMENSION_AT_RUNTIME_DOWNLOADS_THE_PACK, "create"),
|
||||
Entry.command("replace-overworld", "<pack|pack:dimensionKey> [seed|random]", ModdedHelpMessages.COMMAND_REPLACE_OVERWORLD_INJECT_AN_IRIS_PRIMARY_WORLD_AND_ROUTE_PLAYERS_THERE_INSTEAD_OF_THE),
|
||||
Entry.command("disable", "<dimension>", ModdedHelpMessages.COMMAND_DISABLE_EVACUATE_AND_UNLOAD_AN_IRIS_DIMENSION_WORLD_DATA_ON_DISK_IS_KEPT),
|
||||
Entry.command("delete", "<dimension>", ModdedHelpMessages.COMMAND_DELETE_DISABLE_AN_IRIS_DIMENSION_AND_WIPE_ITS_CHUNK_AND_MANTLE_DATA_FROM, "remove", "rm"),
|
||||
Entry.command("list", "", ModdedHelpMessages.COMMAND_LIST_LIST_LOADED_IRIS_DIMENSIONS, "ls"),
|
||||
Entry.command("status", "", ModdedHelpMessages.COMMAND_STATUS_SHOW_LOADED_IRIS_DIMENSIONS_AND_THE_CONFIGURED_PRIMARY_WORLD)
|
||||
));
|
||||
SECTIONS.put("w", SECTIONS.get("world"));
|
||||
SECTIONS.put("datapack", List.of(
|
||||
Entry.command("status", "", "Check loaded Iris dimension type overrides"),
|
||||
Entry.command("install", "", "Install dimension type overrides for loaded Iris dimensions"),
|
||||
Entry.command("list", "", "List configured and installed datapacks", "ls"),
|
||||
Entry.command("ingest", "", "Explain Bukkit datapack ingest workflow", "pull"),
|
||||
Entry.command("remove", "<id>", "Explain datapack removal workflow", "rm")
|
||||
Entry.command("status", "", ModdedHelpMessages.COMMAND_STATUS_CHECK_LOADED_IRIS_DIMENSION_TYPE_OVERRIDES),
|
||||
Entry.command("install", "", ModdedHelpMessages.COMMAND_INSTALL_INSTALL_DIMENSION_TYPE_OVERRIDES_FOR_LOADED_IRIS_DIMENSIONS),
|
||||
Entry.command("list", "", ModdedHelpMessages.COMMAND_LIST_LIST_CONFIGURED_AND_INSTALLED_DATAPACKS, "ls"),
|
||||
Entry.command("ingest", "", ModdedHelpMessages.COMMAND_INGEST_EXPLAIN_BUKKIT_DATAPACK_INGEST_WORKFLOW, "pull"),
|
||||
Entry.command("remove", "<id>", ModdedHelpMessages.COMMAND_REMOVE_EXPLAIN_DATAPACK_REMOVAL_WORKFLOW, "rm")
|
||||
));
|
||||
SECTIONS.put("datapacks", SECTIONS.get("datapack"));
|
||||
SECTIONS.put("dp", SECTIONS.get("datapack"));
|
||||
SECTIONS.put("structure", List.of(
|
||||
Entry.command("list", "", "Regenerate structure-index.json", "ls"),
|
||||
Entry.command("info", "<key>", "Resolve an Iris structure graph and report bounds"),
|
||||
Entry.command("place", "<key>", "Assemble and place an Iris structure at your location", "p"),
|
||||
Entry.command("import", "", "Explain Bukkit structure import workflow", "import-all", "reimport", "imp", "all"),
|
||||
Entry.command("capture", "", "Explain Bukkit structure capture workflow", "cap"),
|
||||
Entry.command("verify", "[key]", "Report native and Iris structure reachability in the current dimension", "locateall")
|
||||
Entry.command("list", "", ModdedHelpMessages.COMMAND_LIST_REGENERATE_STRUCTURE_INDEX_JSON, "ls"),
|
||||
Entry.command("info", "<key>", ModdedHelpMessages.COMMAND_INFO_RESOLVE_AN_IRIS_STRUCTURE_GRAPH_AND_REPORT_BOUNDS),
|
||||
Entry.command("place", "<key>", ModdedHelpMessages.COMMAND_PLACE_ASSEMBLE_AND_PLACE_AN_IRIS_STRUCTURE_AT_YOUR_LOCATION, "p"),
|
||||
Entry.command("import", "", ModdedHelpMessages.COMMAND_IMPORT_EXPLAIN_BUKKIT_STRUCTURE_IMPORT_WORKFLOW, "import-all", "reimport", "imp", "all"),
|
||||
Entry.command("capture", "", ModdedHelpMessages.COMMAND_CAPTURE_EXPLAIN_BUKKIT_STRUCTURE_CAPTURE_WORKFLOW, "cap"),
|
||||
Entry.command("verify", "[key]", ModdedHelpMessages.COMMAND_VERIFY_REPORT_NATIVE_AND_IRIS_STRUCTURE_REACHABILITY_IN_THE_CURRENT_DIMENSION, "locateall")
|
||||
));
|
||||
SECTIONS.put("struct", SECTIONS.get("structure"));
|
||||
SECTIONS.put("str", SECTIONS.get("structure"));
|
||||
SECTIONS.put("developer", List.of(
|
||||
Entry.command("sentry", "", "Send a test exception to the Iris error reporter"),
|
||||
Entry.command("network", "", "List network interfaces and their addresses", "ip")
|
||||
Entry.command("sentry", "", ModdedHelpMessages.COMMAND_SENTRY_SEND_A_TEST_EXCEPTION_TO_THE_IRIS_ERROR_REPORTER),
|
||||
Entry.command("network", "", ModdedHelpMessages.COMMAND_NETWORK_LIST_NETWORK_INTERFACES_AND_THEIR_ADDRESSES, "ip")
|
||||
));
|
||||
SECTIONS.put("dev", SECTIONS.get("developer"));
|
||||
}
|
||||
@@ -179,7 +185,10 @@ final class ModdedCommandHelp {
|
||||
String normalized = normalize(path);
|
||||
List<Entry> entries = SECTIONS.get(normalized);
|
||||
if (entries == null) {
|
||||
ModdedCommandFeedback.fail(source, "Unknown Iris help section: " + normalized);
|
||||
ModdedCommandFeedback.fail(source, IrisLanguage.plain(
|
||||
IrisMessages.MODDED_HELP_UNKNOWN_SECTION,
|
||||
MessageArgument.untrusted("section", normalized)
|
||||
));
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -208,9 +217,11 @@ final class ModdedCommandHelp {
|
||||
String parent = parentPath(path);
|
||||
String command = parent.isEmpty() ? "/iris" : "/iris help " + parent;
|
||||
MutableComponent hover = Component.empty()
|
||||
.append(text("Click to go back to ", DARK_GREEN))
|
||||
.append(text(parent.isEmpty() ? "Iris" : parent, PARAMETER_ALT));
|
||||
return text("〈 Back", BACK).withStyle((style) -> style
|
||||
.append(text(IrisLanguage.plain(
|
||||
IrisMessages.MODDED_HELP_BACK_HOVER,
|
||||
MessageArgument.untrusted("parent", parent.isEmpty() ? "Iris" : parent)
|
||||
), DARK_GREEN));
|
||||
return text("〈 " + IrisLanguage.plain(DirectorHelpMessages.BACK), BACK).withStyle((style) -> style
|
||||
.withClickEvent(new ClickEvent.RunCommand(command))
|
||||
.withHoverEvent(new HoverEvent.ShowText(hover)));
|
||||
}
|
||||
@@ -239,7 +250,7 @@ final class ModdedCommandHelp {
|
||||
|
||||
private static MutableComponent nodes(Entry entry) {
|
||||
if (entry.group()) {
|
||||
return text(" - Category of Commands", CATEGORY);
|
||||
return text(" - " + IrisLanguage.plain(DirectorHelpMessages.COMMAND_GROUP), CATEGORY);
|
||||
}
|
||||
|
||||
List<String> tokens = usageTokens(entry.usage());
|
||||
@@ -273,18 +284,18 @@ final class ModdedCommandHelp {
|
||||
hover.append(text(name, PARAMETER));
|
||||
hover.append(Component.literal("\n"));
|
||||
hover.append(text("✎ ", DESCRIPTION_ICON));
|
||||
hover.append(text("Command parameter", DESCRIPTION));
|
||||
hover.append(text(IrisLanguage.plain(IrisMessages.MODDED_HELP_COMMAND_PARAMETER), DESCRIPTION));
|
||||
hover.append(Component.literal("\n"));
|
||||
if (required) {
|
||||
hover.append(text("⚠ ", REQUIRED));
|
||||
hover.append(text("This parameter is required.", REQUIRED_TEXT));
|
||||
hover.append(text(IrisLanguage.plain(IrisMessages.MODDED_HELP_PARAMETER_REQUIRED), REQUIRED_TEXT));
|
||||
} else {
|
||||
hover.append(text("✔ ", DESCRIPTION_ICON));
|
||||
hover.append(text("This parameter is optional.", USAGE));
|
||||
hover.append(text(IrisLanguage.plain(IrisMessages.MODDED_HELP_PARAMETER_OPTIONAL), USAGE));
|
||||
}
|
||||
hover.append(Component.literal("\n"));
|
||||
hover.append(text("✢ ", DARK_GREEN));
|
||||
hover.append(text("This parameter is read as text by Brigadier.", HOVER_TYPE));
|
||||
hover.append(text(IrisLanguage.plain(IrisMessages.MODDED_HELP_BRIGADIER_TEXT), HOVER_TYPE));
|
||||
|
||||
return title.withStyle((style) -> style.withHoverEvent(new HoverEvent.ShowText(hover)));
|
||||
}
|
||||
@@ -294,15 +305,15 @@ final class ModdedCommandHelp {
|
||||
hover.append(text(names(entry), PARAMETER));
|
||||
hover.append(Component.literal("\n"));
|
||||
hover.append(text("✎ ", DESCRIPTION_ICON));
|
||||
hover.append(text(entry.description(), DESCRIPTION));
|
||||
hover.append(text(IrisLanguage.plain(entry.description()), DESCRIPTION));
|
||||
hover.append(Component.literal("\n"));
|
||||
hover.append(text("✒ ", USAGE_ICON));
|
||||
if (entry.group()) {
|
||||
hover.append(text("This is a command category. Click to run.", USAGE));
|
||||
hover.append(text(IrisLanguage.plain(DirectorHelpMessages.COMMAND_GROUP), USAGE));
|
||||
} else if (entry.usage().isBlank()) {
|
||||
hover.append(text("There are no parameters. Click to type command.", USAGE));
|
||||
hover.append(text(IrisLanguage.plain(DirectorHelpMessages.NO_PARAMETERS), USAGE));
|
||||
} else {
|
||||
hover.append(text("Hover over all of the parameters to learn more.", USAGE));
|
||||
hover.append(text(IrisLanguage.plain(DirectorHelpMessages.PARAMETERS), USAGE));
|
||||
hover.append(Component.literal("\n"));
|
||||
hover.append(text("✦ ", EXAMPLE_ICON));
|
||||
hover.append(text(suggestion, PARAMETER));
|
||||
@@ -311,7 +322,7 @@ final class ModdedCommandHelp {
|
||||
String parent = path.isEmpty() ? "/iris" : "/iris " + path;
|
||||
if (entry.aliases().length > 0) {
|
||||
hover.append(Component.literal("\n"));
|
||||
hover.append(text("Aliases: ", DARK_GREEN));
|
||||
hover.append(text(IrisLanguage.plain(DirectorHelpMessages.ALIASES) + ": ", DARK_GREEN));
|
||||
List<String> aliases = new ArrayList<>(entry.aliases().length);
|
||||
for (String alias : entry.aliases()) {
|
||||
aliases.add(parent + " " + alias);
|
||||
@@ -324,11 +335,11 @@ final class ModdedCommandHelp {
|
||||
private static MutableComponent opNotice() {
|
||||
MutableComponent notice = Component.empty();
|
||||
notice.append(text("⚠ ", REQUIRED));
|
||||
notice.append(text("Iris commands need operator permission (level 2). ", REQUIRED_TEXT));
|
||||
notice.append(text("Run ", DESCRIPTION));
|
||||
notice.append(text("/op <you>", PARAMETER_ALT));
|
||||
notice.append(text(" from the console (or enable cheats in singleplayer); ", DESCRIPTION));
|
||||
notice.append(text("until then these commands will not run or tab-complete.", USAGE));
|
||||
notice.append(text(IrisLanguage.plain(IrisMessages.MODDED_HELP_OPERATOR_NOTICE) + " ", REQUIRED_TEXT));
|
||||
notice.append(text(IrisLanguage.plain(
|
||||
IrisMessages.MODDED_HELP_OPERATOR_INSTRUCTION,
|
||||
MessageArgument.trusted("command", "/op <you>")
|
||||
), DESCRIPTION));
|
||||
return notice;
|
||||
}
|
||||
|
||||
@@ -404,12 +415,12 @@ final class ModdedCommandHelp {
|
||||
return normalized;
|
||||
}
|
||||
|
||||
private record Entry(String name, String usage, String description, boolean group, String... aliases) {
|
||||
static Entry command(String name, String usage, String description, String... aliases) {
|
||||
private record Entry(String name, String usage, TextKey description, boolean group, String... aliases) {
|
||||
static Entry command(String name, String usage, TextKey description, String... aliases) {
|
||||
return new Entry(name, usage, description, false, aliases);
|
||||
}
|
||||
|
||||
static Entry group(String name, String description, String... aliases) {
|
||||
static Entry group(String name, TextKey description, String... aliases) {
|
||||
return new Entry(name, "", description, true, aliases);
|
||||
}
|
||||
}
|
||||
|
||||
+21
-22
@@ -45,6 +45,10 @@ import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
import art.arcane.iris.core.localization.IrisLanguage;
|
||||
import art.arcane.iris.core.localization.ModdedCommandMessages;
|
||||
import art.arcane.iris.core.localization.RuntimeUiMessages;
|
||||
import art.arcane.volmlib.util.localization.MessageArgument;
|
||||
public final class ModdedDatapackCommands {
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger("Iris");
|
||||
private static final Predicate<CommandSourceStack> GATE = Commands.hasPermission(Commands.LEVEL_GAMEMASTERS);
|
||||
@@ -118,8 +122,7 @@ public final class ModdedDatapackCommands {
|
||||
|
||||
Engine engine = IrisModdedCommands.engineFor(level);
|
||||
if (engine == null || engine.getDimension() == null) {
|
||||
IrisModdedCommands.ok(source, dimensionId + ": type=" + typeKey + " active=" + activeMin + ".." + activeMax
|
||||
+ " logical=" + active.logicalHeight() + " (pack=" + irisGenerator.dimensionKey() + ", engine not started; pack heights unknown)");
|
||||
IrisModdedCommands.ok(source, IrisLanguage.plain(ModdedCommandMessages.MODDED_DATAPACK_COMMANDS_TYPE_ACTIVE_LOGICAL_PACK_ENGINE_NOT_STARTED_PACK_HEIGHTS_UNKNOWN, MessageArgument.untrusted("dimensionId", dimensionId), MessageArgument.untrusted("typeKey", typeKey), MessageArgument.untrusted("activeMin", activeMin), MessageArgument.untrusted("activeMax", activeMax), MessageArgument.untrusted("value", active.logicalHeight()), MessageArgument.untrusted("value2", irisGenerator.dimensionKey())));
|
||||
continue;
|
||||
}
|
||||
IrisDimension dimension = engine.getDimension();
|
||||
@@ -128,22 +131,18 @@ public final class ModdedDatapackCommands {
|
||||
int packLogical = dimension.getLogicalHeight();
|
||||
boolean matches = packMin == activeMin && packMax == activeMax && packLogical == active.logicalHeight();
|
||||
File override = overrideFile(server, irisGenerator.dimensionKey());
|
||||
IrisModdedCommands.ok(source, dimensionId + ": type=" + typeKey
|
||||
+ " active=" + activeMin + ".." + activeMax + " logical=" + active.logicalHeight()
|
||||
+ " | pack '" + dimension.getLoadKey() + "' wants " + packMin + ".." + packMax + " logical=" + packLogical
|
||||
+ " | " + (matches ? "MATCH" : "MISMATCH")
|
||||
+ (override.isFile() ? " (world datapack override installed)" : ""));
|
||||
IrisModdedCommands.ok(source, IrisLanguage.plain(ModdedCommandMessages.MODDED_DATAPACK_COMMANDS_TYPE_ACTIVE_LOGICAL_PACK_WANTS_LOGICAL, MessageArgument.untrusted("dimensionId", dimensionId), MessageArgument.untrusted("typeKey", typeKey), MessageArgument.untrusted("activeMin", activeMin), MessageArgument.untrusted("activeMax", activeMax), MessageArgument.untrusted("value", active.logicalHeight()), MessageArgument.untrusted("value2", dimension.getLoadKey()), MessageArgument.untrusted("packMin", packMin), MessageArgument.untrusted("packMax", packMax), MessageArgument.untrusted("packLogical", packLogical), MessageArgument.trusted("value3", IrisLanguage.plain(matches ? RuntimeUiMessages.STATUS_MATCH : RuntimeUiMessages.STATUS_MISMATCH)), MessageArgument.trusted("value4", override.isFile() ? IrisLanguage.plain(RuntimeUiMessages.DATAPACK_OVERRIDE_SUFFIX) : "")));
|
||||
if (!matches) {
|
||||
mismatches++;
|
||||
IrisModdedCommands.fail(source, " WARNING: the active dimension type does not match the pack. Iris will refuse to start this world engine instead of clipping terrain. Run /iris world enable <dimension> <pack> for new worlds, or /iris datapack install for already-loaded Iris dimensions, then restart.");
|
||||
IrisModdedCommands.fail(source, IrisLanguage.plain(ModdedCommandMessages.MODDED_DATAPACK_COMMANDS_WARNING_ACTIVE_DIMENSION_TYPE_DOES_NOT_MATCH_PACK_IRIS_WILL));
|
||||
}
|
||||
}
|
||||
if (irisLevels == 0) {
|
||||
IrisModdedCommands.fail(source, "No Iris dimensions are loaded.");
|
||||
IrisModdedCommands.fail(source, IrisLanguage.plain(ModdedCommandMessages.MODDED_DATAPACK_COMMANDS_NO_IRIS_DIMENSIONS_ARE_LOADED));
|
||||
return 0;
|
||||
}
|
||||
if (mismatches == 0) {
|
||||
IrisModdedCommands.ok(source, "All " + irisLevels + " Iris dimension(s) match their pack height ranges.");
|
||||
IrisModdedCommands.ok(source, IrisLanguage.plain(ModdedCommandMessages.MODDED_DATAPACK_COMMANDS_ALL_IRIS_DIMENSION_S_MATCH_THEIR_PACK_HEIGHT_RANGES, MessageArgument.untrusted("irisLevels", irisLevels)));
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
@@ -157,7 +156,7 @@ public final class ModdedDatapackCommands {
|
||||
}
|
||||
Engine engine = IrisModdedCommands.engineFor(level);
|
||||
if (engine == null || engine.getDimension() == null) {
|
||||
IrisModdedCommands.fail(source, level.dimension().identifier() + ": engine not started; cannot derive its dimension type yet.");
|
||||
IrisModdedCommands.fail(source, IrisLanguage.plain(ModdedCommandMessages.MODDED_DATAPACK_COMMANDS_ENGINE_NOT_STARTED_CANNOT_DERIVE_ITS_DIMENSION_TYPE_YET, MessageArgument.untrusted("value", level.dimension().identifier())));
|
||||
continue;
|
||||
}
|
||||
IrisDimension dimension = engine.getDimension();
|
||||
@@ -166,7 +165,7 @@ public final class ModdedDatapackCommands {
|
||||
json = dimension.getDimensionType().toJson(DataVersion.getLatest().get());
|
||||
} catch (Throwable e) {
|
||||
LOGGER.error("Iris dimension type generation failed for {}", dimension.getLoadKey(), e);
|
||||
IrisModdedCommands.fail(source, level.dimension().identifier() + ": dimension type generation failed: " + e.getMessage());
|
||||
IrisModdedCommands.fail(source, IrisLanguage.plain(ModdedCommandMessages.MODDED_DATAPACK_COMMANDS_DIMENSION_TYPE_GENERATION_FAILED, MessageArgument.untrusted("value", level.dimension().identifier()), MessageArgument.untrusted("value2", String.valueOf(e.getMessage()))));
|
||||
continue;
|
||||
}
|
||||
File output = overrideFile(server, irisGenerator.dimensionKey());
|
||||
@@ -176,11 +175,11 @@ public final class ModdedDatapackCommands {
|
||||
written.add(output.getPath());
|
||||
} catch (IOException e) {
|
||||
LOGGER.error("Iris dimension type write failed for {}", output, e);
|
||||
IrisModdedCommands.fail(source, "Failed to write " + output + ": " + e.getMessage());
|
||||
IrisModdedCommands.fail(source, IrisLanguage.plain(ModdedCommandMessages.MODDED_DATAPACK_COMMANDS_FAILED_WRITE, MessageArgument.untrusted("output", output), MessageArgument.untrusted("value", String.valueOf(e.getMessage()))));
|
||||
}
|
||||
}
|
||||
if (written.isEmpty()) {
|
||||
IrisModdedCommands.fail(source, "No Iris dimensions with running engines found; nothing was installed.");
|
||||
IrisModdedCommands.fail(source, IrisLanguage.plain(ModdedCommandMessages.MODDED_DATAPACK_COMMANDS_NO_IRIS_DIMENSIONS_WITH_RUNNING_ENGINES_FOUND_NOTHING_WAS_INSTALLED));
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -200,14 +199,14 @@ public final class ModdedDatapackCommands {
|
||||
written.add(mcmeta.getPath());
|
||||
} catch (IOException e) {
|
||||
LOGGER.error("Iris pack.mcmeta write failed for {}", mcmeta, e);
|
||||
IrisModdedCommands.fail(source, "Failed to write " + mcmeta + ": " + e.getMessage());
|
||||
IrisModdedCommands.fail(source, IrisLanguage.plain(ModdedCommandMessages.MODDED_DATAPACK_COMMANDS_FAILED_WRITE_2, MessageArgument.untrusted("mcmeta", mcmeta), MessageArgument.untrusted("value", String.valueOf(e.getMessage()))));
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (String path : written) {
|
||||
IrisModdedCommands.ok(source, "Wrote " + path);
|
||||
IrisModdedCommands.ok(source, IrisLanguage.plain(ModdedCommandMessages.MODDED_DATAPACK_COMMANDS_WROTE, MessageArgument.untrusted("path", path)));
|
||||
}
|
||||
IrisModdedCommands.ok(source, "World datapack '" + WORLD_PACK_NAME + "' dimension type overrides installed. Restart the server for the dimension types to apply.");
|
||||
IrisModdedCommands.ok(source, IrisLanguage.plain(ModdedCommandMessages.MODDED_DATAPACK_COMMANDS_WORLD_DATAPACK_DIMENSION_TYPE_OVERRIDES_INSTALLED_RESTART_SERVER_DIMENSION_TYPES, MessageArgument.untrusted("WORLDPACKNAME", WORLD_PACK_NAME)));
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -239,12 +238,12 @@ public final class ModdedDatapackCommands {
|
||||
}
|
||||
}
|
||||
|
||||
IrisModdedCommands.ok(source, "Configured datapack imports: " + configured.size());
|
||||
IrisModdedCommands.ok(source, IrisLanguage.plain(ModdedCommandMessages.MODDED_DATAPACK_COMMANDS_CONFIGURED_DATAPACK_IMPORTS, MessageArgument.untrusted("value", configured.size())));
|
||||
for (String url : configured) {
|
||||
IrisModdedCommands.ok(source, " - " + url);
|
||||
IrisModdedCommands.ok(source, IrisLanguage.plain(ModdedCommandMessages.MODDED_DATAPACK_COMMANDS_MESSAGE, MessageArgument.untrusted("url", url)));
|
||||
}
|
||||
if (!configured.isEmpty()) {
|
||||
IrisModdedCommands.ok(source, "Modrinth ingest is Bukkit-only; install these manually into world/datapacks if needed.");
|
||||
IrisModdedCommands.ok(source, IrisLanguage.plain(ModdedCommandMessages.MODDED_DATAPACK_COMMANDS_MODRINTH_INGEST_IS_BUKKIT_ONLY_INSTALL_THESE_MANUALLY_INTO_WORLD));
|
||||
}
|
||||
|
||||
File datapacks = worldDatapacksFolder(server);
|
||||
@@ -257,9 +256,9 @@ public final class ModdedDatapackCommands {
|
||||
}
|
||||
}
|
||||
}
|
||||
IrisModdedCommands.ok(source, "Installed world datapacks: " + names.size());
|
||||
IrisModdedCommands.ok(source, IrisLanguage.plain(ModdedCommandMessages.MODDED_DATAPACK_COMMANDS_INSTALLED_WORLD_DATAPACKS, MessageArgument.untrusted("value", names.size())));
|
||||
for (String name : names) {
|
||||
IrisModdedCommands.ok(source, " - " + name);
|
||||
IrisModdedCommands.ok(source, IrisLanguage.plain(ModdedCommandMessages.MODDED_DATAPACK_COMMANDS_MESSAGE_2, MessageArgument.untrusted("name", name)));
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
+6
-3
@@ -33,6 +33,9 @@ import java.util.Collections;
|
||||
import java.util.Enumeration;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
import art.arcane.iris.core.localization.IrisLanguage;
|
||||
import art.arcane.iris.core.localization.ModdedCommandMessages;
|
||||
import art.arcane.volmlib.util.localization.MessageArgument;
|
||||
final class ModdedDeveloperCommands {
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger("Iris");
|
||||
private static final Predicate<CommandSourceStack> GATE = Commands.hasPermission(Commands.LEVEL_GAMEMASTERS);
|
||||
@@ -53,7 +56,7 @@ final class ModdedDeveloperCommands {
|
||||
|
||||
private static int sentry(CommandSourceStack source) {
|
||||
IrisPlatforms.get().reportError(new Exception("This is an Iris Sentry test exception"));
|
||||
ModdedCommandFeedback.ok(source, "Dispatched a test exception to the Iris error reporter (Sentry if enabled).");
|
||||
ModdedCommandFeedback.ok(source, IrisLanguage.plain(ModdedCommandMessages.MODDED_DEVELOPER_COMMANDS_DISPATCHED_TEST_EXCEPTION_IRIS_ERROR_REPORTER_SENTRY_IF_ENABLED));
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -63,13 +66,13 @@ final class ModdedDeveloperCommands {
|
||||
for (NetworkInterface networkInterface : Collections.list(interfaces)) {
|
||||
ModdedCommandFeedback.ok(source, networkInterface.getDisplayName());
|
||||
for (InetAddress address : Collections.list(networkInterface.getInetAddresses())) {
|
||||
ModdedCommandFeedback.ok(source, " " + address.getHostAddress());
|
||||
ModdedCommandFeedback.ok(source, IrisLanguage.plain(ModdedCommandMessages.MODDED_DEVELOPER_COMMANDS_MESSAGE, MessageArgument.untrusted("value", address.getHostAddress())));
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
} catch (SocketException error) {
|
||||
LOGGER.error("Iris developer network dump failed", error);
|
||||
ModdedCommandFeedback.fail(source, "Network scan failed: " + error.getClass().getSimpleName());
|
||||
ModdedCommandFeedback.fail(source, IrisLanguage.plain(ModdedCommandMessages.MODDED_DEVELOPER_COMMANDS_NETWORK_SCAN_FAILED, MessageArgument.untrusted("value", error.getClass().getSimpleName())));
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
+65
-15
@@ -18,10 +18,13 @@
|
||||
|
||||
package art.arcane.iris.modded.command;
|
||||
|
||||
import art.arcane.iris.core.localization.IrisLanguage;
|
||||
import art.arcane.iris.core.localization.RuntimeUiMessages;
|
||||
import art.arcane.iris.engine.framework.Engine;
|
||||
import art.arcane.iris.engine.object.IrisBiome;
|
||||
import art.arcane.iris.engine.object.IrisRegion;
|
||||
import art.arcane.iris.modded.ModdedBlockState;
|
||||
import art.arcane.volmlib.util.localization.MessageArgument;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.particles.DustParticleOptions;
|
||||
import net.minecraft.network.chat.Component;
|
||||
@@ -50,7 +53,7 @@ public final class ModdedDustRevealer {
|
||||
public static void reveal(ServerPlayer player, ServerLevel level, BlockPos pos) {
|
||||
Engine engine = IrisModdedCommands.engineFor(level);
|
||||
if (engine == null) {
|
||||
player.sendSystemMessage(Component.literal("This dimension is not generated by Iris."));
|
||||
player.sendSystemMessage(Component.literal(IrisLanguage.plain(RuntimeUiMessages.DUST_IRIS_WORLD_REQUIRED)));
|
||||
return;
|
||||
}
|
||||
describe(player, level, engine, pos);
|
||||
@@ -60,7 +63,10 @@ public final class ModdedDustRevealer {
|
||||
if (key == null) {
|
||||
return;
|
||||
}
|
||||
player.sendSystemMessage(Component.literal("Found object " + key));
|
||||
player.sendSystemMessage(Component.literal(IrisLanguage.plain(
|
||||
RuntimeUiMessages.DUST_FOUND_OBJECT,
|
||||
MessageArgument.untrusted("object", key)
|
||||
)));
|
||||
MinecraftServer server = level.getServer();
|
||||
BlockPos origin = pos.immutable();
|
||||
Thread thread = new Thread(() -> {
|
||||
@@ -71,8 +77,11 @@ public final class ModdedDustRevealer {
|
||||
hit.getX() + 0.5D, hit.getY() + 0.5D, hit.getZ() + 0.5D,
|
||||
3, 0.25D, 0.25D, 0.25D, 0.0D);
|
||||
}
|
||||
player.sendSystemMessage(Component.literal("Revealed " + hits.size() + " block(s) of " + key
|
||||
+ (hits.size() >= MAX_HITS ? " (capped)" : "")));
|
||||
player.sendSystemMessage(Component.literal(IrisLanguage.plain(
|
||||
hits.size() >= MAX_HITS ? RuntimeUiMessages.DUST_REVEALED_CAPPED : RuntimeUiMessages.DUST_REVEALED,
|
||||
MessageArgument.trusted("count", hits.size()),
|
||||
MessageArgument.untrusted("object", key)
|
||||
)));
|
||||
});
|
||||
}, "Iris Dust Revealer");
|
||||
thread.setDaemon(true);
|
||||
@@ -133,31 +142,72 @@ public final class ModdedDustRevealer {
|
||||
IrisRegion region = safe(() -> engine.getRegion(x, z));
|
||||
|
||||
List<String> lines = new ArrayList<>();
|
||||
lines.add("--- Iris Dust @ " + x + ", " + y + ", " + z + " ---");
|
||||
lines.add("Block: " + ModdedBlockState.serialize(level.getBlockState(pos)));
|
||||
lines.add(IrisLanguage.plain(
|
||||
RuntimeUiMessages.DUST_HEADER,
|
||||
MessageArgument.trusted("x", x),
|
||||
MessageArgument.trusted("y", y),
|
||||
MessageArgument.trusted("z", z)
|
||||
));
|
||||
lines.add(IrisLanguage.plain(
|
||||
RuntimeUiMessages.DUST_BLOCK,
|
||||
MessageArgument.untrusted("block", ModdedBlockState.serialize(level.getBlockState(pos)))
|
||||
));
|
||||
if (offset > 0) {
|
||||
lines.add("Position: +" + offset + " ABOVE surface (surface Y=" + surfaceY + ")");
|
||||
lines.add(IrisLanguage.plain(
|
||||
RuntimeUiMessages.DUST_POSITION_ABOVE,
|
||||
MessageArgument.trusted("offset", offset),
|
||||
MessageArgument.trusted("surfaceY", surfaceY)
|
||||
));
|
||||
} else if (offset < 0) {
|
||||
lines.add("Position: " + (-offset) + " below surface (surface Y=" + surfaceY + ")");
|
||||
lines.add(IrisLanguage.plain(
|
||||
RuntimeUiMessages.DUST_POSITION_BELOW,
|
||||
MessageArgument.trusted("offset", -offset),
|
||||
MessageArgument.trusted("surfaceY", surfaceY)
|
||||
));
|
||||
} else {
|
||||
lines.add("Position: at surface (Y=" + surfaceY + ")");
|
||||
lines.add(IrisLanguage.plain(
|
||||
RuntimeUiMessages.DUST_POSITION_AT,
|
||||
MessageArgument.trusted("surfaceY", surfaceY)
|
||||
));
|
||||
}
|
||||
lines.add("Object @block: " + (objectKey == null ? "none" : objectKey));
|
||||
lines.add(IrisLanguage.plain(
|
||||
RuntimeUiMessages.DUST_OBJECT_AT_BLOCK,
|
||||
MessageArgument.untrusted(
|
||||
"object",
|
||||
objectKey == null ? IrisLanguage.plain(RuntimeUiMessages.DUST_NONE) : objectKey
|
||||
)
|
||||
));
|
||||
if (surfaceBiome != null) {
|
||||
lines.add("Surface biome: " + surfaceBiome.getLoadKey());
|
||||
lines.add(IrisLanguage.plain(
|
||||
RuntimeUiMessages.DUST_SURFACE_BIOME,
|
||||
MessageArgument.untrusted("biome", surfaceBiome.getLoadKey())
|
||||
));
|
||||
}
|
||||
if (biomeHere != null && (surfaceBiome == null || !biomeHere.getLoadKey().equals(surfaceBiome.getLoadKey()))) {
|
||||
lines.add("Biome @Y: " + biomeHere.getLoadKey());
|
||||
lines.add(IrisLanguage.plain(
|
||||
RuntimeUiMessages.DUST_BIOME_AT_Y,
|
||||
MessageArgument.untrusted("biome", biomeHere.getLoadKey())
|
||||
));
|
||||
}
|
||||
if (caveBiome != null && (surfaceBiome == null || !caveBiome.getLoadKey().equals(surfaceBiome.getLoadKey()))) {
|
||||
lines.add("Cave/Mantle biome: " + caveBiome.getLoadKey());
|
||||
lines.add(IrisLanguage.plain(
|
||||
RuntimeUiMessages.DUST_CAVE_BIOME,
|
||||
MessageArgument.untrusted("biome", caveBiome.getLoadKey())
|
||||
));
|
||||
}
|
||||
if (region != null) {
|
||||
lines.add("Region: " + region.getLoadKey() + " (" + region.getName() + ")");
|
||||
lines.add(IrisLanguage.plain(
|
||||
RuntimeUiMessages.DUST_REGION,
|
||||
MessageArgument.untrusted("region", region.getLoadKey()),
|
||||
MessageArgument.untrusted("name", region.getName())
|
||||
));
|
||||
}
|
||||
Set<String> objects = safe(() -> engine.getObjectsAt(x >> 4, z >> 4));
|
||||
if (objects != null && !objects.isEmpty()) {
|
||||
lines.add("Objects in chunk: " + objects);
|
||||
lines.add(IrisLanguage.plain(
|
||||
RuntimeUiMessages.DUST_OBJECTS_IN_CHUNK,
|
||||
MessageArgument.untrusted("objects", objects)
|
||||
));
|
||||
}
|
||||
for (String line : lines) {
|
||||
player.sendSystemMessage(Component.literal(line));
|
||||
|
||||
+24
-4
@@ -36,6 +36,10 @@ import java.io.File;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
import art.arcane.iris.core.localization.IrisLanguage;
|
||||
import art.arcane.iris.core.localization.ModdedCommandMessages;
|
||||
import art.arcane.iris.core.localization.RuntimeProgressMessages;
|
||||
import art.arcane.volmlib.util.localization.MessageArgument;
|
||||
public final class ModdedGoldenHash {
|
||||
public enum Mode {
|
||||
AUTO,
|
||||
@@ -80,13 +84,18 @@ public final class ModdedGoldenHash {
|
||||
|
||||
public static void start(CommandSourceStack source, ServerLevel level, Engine engine, int radius, int threads, Mode mode) {
|
||||
if (!ACTIVE.compareAndSet(false, true)) {
|
||||
IrisModdedCommands.fail(source, "A goldenhash scan is already running.");
|
||||
IrisModdedCommands.fail(source, IrisLanguage.plain(ModdedCommandMessages.MODDED_GOLDEN_HASH_GOLDENHASH_SCAN_IS_ALREADY_RUNNING));
|
||||
return;
|
||||
}
|
||||
ModdedGoldenHash scan = new ModdedGoldenHash(source, level, engine, radius, threads, mode);
|
||||
int boundedRadius = Math.max(0, radius);
|
||||
int chunks = (boundedRadius * 2 + 1) * (boundedRadius * 2 + 1);
|
||||
scan.ok("GoldenHash started: " + chunks + " chunk(s) around 0,0 in buffers (world untouched), threads=" + Math.max(1, threads) + " mode=" + mode);
|
||||
scan.ok(IrisLanguage.plain(
|
||||
RuntimeProgressMessages.GOLDEN_STARTED,
|
||||
MessageArgument.trusted("chunks", chunks),
|
||||
MessageArgument.trusted("threads", Math.max(1, threads)),
|
||||
MessageArgument.untrusted("mode", mode)
|
||||
));
|
||||
LOGGER.info("goldenhash start: dim={} seed={} radius={} threads={} mode={} file={}",
|
||||
engine.getDimension().getLoadKey(), engine.getSeedManager().getSeed(), boundedRadius, Math.max(1, threads), mode, scan.hashEngine.getGoldenFile().getName());
|
||||
Thread thread = new Thread(() -> {
|
||||
@@ -161,14 +170,25 @@ public final class ModdedGoldenHash {
|
||||
int doneCount = hashed.incrementAndGet();
|
||||
int stride = total <= 64 ? 1 : 32;
|
||||
if (doneCount % stride == 0 || doneCount == total) {
|
||||
ModdedGoldenHash.this.ok("[" + doneCount + "/" + total + "] chunk " + chunkX + "," + chunkZ + " hashed");
|
||||
ModdedGoldenHash.this.ok(IrisLanguage.plain(
|
||||
RuntimeProgressMessages.GOLDEN_CHUNK_HASHED,
|
||||
MessageArgument.trusted("done", doneCount),
|
||||
MessageArgument.trusted("total", total),
|
||||
MessageArgument.trusted("x", chunkX),
|
||||
MessageArgument.trusted("z", chunkZ)
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void chunkFailed(int chunkX, int chunkZ, Throwable error) {
|
||||
LOGGER.error("goldenhash chunk {},{} failed", chunkX, chunkZ, error);
|
||||
ModdedGoldenHash.this.fail("Chunk " + chunkX + "," + chunkZ + " FAILED: " + error.getClass().getSimpleName());
|
||||
ModdedGoldenHash.this.fail(IrisLanguage.plain(
|
||||
RuntimeProgressMessages.GOLDEN_CHUNK_FAILED,
|
||||
MessageArgument.trusted("x", chunkX),
|
||||
MessageArgument.trusted("z", chunkZ),
|
||||
MessageArgument.untrusted("type", error.getClass().getSimpleName())
|
||||
));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
+60
-55
@@ -69,6 +69,10 @@ import java.util.Map;
|
||||
import java.util.UUID;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
import art.arcane.iris.core.localization.IrisLanguage;
|
||||
import art.arcane.iris.core.localization.ModdedCommandMessages;
|
||||
import art.arcane.iris.core.localization.RuntimeUiMessages;
|
||||
import art.arcane.volmlib.util.localization.MessageArgument;
|
||||
public final class ModdedObjectCommands {
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger("Iris");
|
||||
private static final Predicate<CommandSourceStack> GATE = Commands.hasPermission(Commands.LEVEL_GAMEMASTERS);
|
||||
@@ -218,55 +222,55 @@ public final class ModdedObjectCommands {
|
||||
public static int giveWand(CommandSourceStack source) {
|
||||
ServerPlayer player = source.getPlayer();
|
||||
if (player == null) {
|
||||
IrisModdedCommands.fail(source, "This command can only be used by players. (the wand is a physical item)");
|
||||
IrisModdedCommands.fail(source, IrisLanguage.plain(ModdedCommandMessages.MODDED_OBJECT_COMMANDS_THIS_COMMAND_CAN_ONLY_BE_USED_BY_PLAYERS_WAND_IS));
|
||||
return 0;
|
||||
}
|
||||
if (!player.getInventory().add(ModdedWandService.createWand())) {
|
||||
IrisModdedCommands.fail(source, "Your inventory is full.");
|
||||
IrisModdedCommands.fail(source, IrisLanguage.plain(ModdedCommandMessages.MODDED_OBJECT_COMMANDS_YOUR_INVENTORY_IS_FULL));
|
||||
return 0;
|
||||
}
|
||||
IrisModdedCommands.ok(source, "Poof! Good luck building! (left click = corner 1, right click = corner 2)");
|
||||
IrisModdedCommands.ok(source, IrisLanguage.plain(ModdedCommandMessages.MODDED_OBJECT_COMMANDS_POOF_GOOD_LUCK_BUILDING_LEFT_CLICK_CORNER_1_RIGHT_CLICK));
|
||||
return 1;
|
||||
}
|
||||
|
||||
private static int giveDust(CommandSourceStack source) {
|
||||
ServerPlayer player = source.getPlayer();
|
||||
if (player == null) {
|
||||
IrisModdedCommands.fail(source, "This command can only be used by players. (the dust is a physical item)");
|
||||
IrisModdedCommands.fail(source, IrisLanguage.plain(ModdedCommandMessages.MODDED_OBJECT_COMMANDS_THIS_COMMAND_CAN_ONLY_BE_USED_BY_PLAYERS_DUST_IS));
|
||||
return 0;
|
||||
}
|
||||
if (!player.getInventory().add(ModdedWandService.createDust())) {
|
||||
IrisModdedCommands.fail(source, "Your inventory is full.");
|
||||
IrisModdedCommands.fail(source, IrisLanguage.plain(ModdedCommandMessages.MODDED_OBJECT_COMMANDS_YOUR_INVENTORY_IS_FULL_2));
|
||||
return 0;
|
||||
}
|
||||
IrisModdedCommands.ok(source, "Right click a block to reveal the object it belongs to.");
|
||||
IrisModdedCommands.ok(source, IrisLanguage.plain(ModdedCommandMessages.MODDED_OBJECT_COMMANDS_RIGHT_CLICK_BLOCK_REVEAL_OBJECT_IT_BELONGS));
|
||||
return 1;
|
||||
}
|
||||
|
||||
private static int save(CommandSourceStack source, String nameRaw, boolean overwrite) {
|
||||
ServerPlayer player = source.getPlayer();
|
||||
if (player == null) {
|
||||
IrisModdedCommands.fail(source, "This command can only be used by players. (saving captures your wand selection)");
|
||||
IrisModdedCommands.fail(source, IrisLanguage.plain(ModdedCommandMessages.MODDED_OBJECT_COMMANDS_THIS_COMMAND_CAN_ONLY_BE_USED_BY_PLAYERS_SAVING_CAPTURES));
|
||||
return 0;
|
||||
}
|
||||
ServerLevel level = player.level();
|
||||
Engine engine = IrisModdedCommands.engineFor(level);
|
||||
if (engine == null) {
|
||||
IrisModdedCommands.fail(source, "This dimension is not generated by Iris; objects save into the dimension's pack.");
|
||||
IrisModdedCommands.fail(source, IrisLanguage.plain(ModdedCommandMessages.MODDED_OBJECT_COMMANDS_THIS_DIMENSION_IS_NOT_GENERATED_BY_IRIS_OBJECTS_SAVE_INTO));
|
||||
return 0;
|
||||
}
|
||||
if (!ModdedWandService.isHoldingWand(player)) {
|
||||
IrisModdedCommands.fail(source, "Hold your Iris wand. (/iris wand)");
|
||||
IrisModdedCommands.fail(source, IrisLanguage.plain(ModdedCommandMessages.MODDED_OBJECT_COMMANDS_HOLD_YOUR_IRIS_WAND_IRIS_WAND));
|
||||
return 0;
|
||||
}
|
||||
ModdedWandService.Selection selection = ModdedWandService.selection(player);
|
||||
if (selection == null) {
|
||||
IrisModdedCommands.fail(source, "No area selected. Left/right click blocks with the wand first.");
|
||||
IrisModdedCommands.fail(source, IrisLanguage.plain(ModdedCommandMessages.MODDED_OBJECT_COMMANDS_NO_AREA_SELECTED_LEFT_RIGHT_CLICK_BLOCKS_WITH_WAND_FIRST));
|
||||
return 0;
|
||||
}
|
||||
String name = nameRaw.trim().replace('\\', '/');
|
||||
if (name.isEmpty() || name.contains("..")) {
|
||||
IrisModdedCommands.fail(source, "Invalid object name: " + nameRaw);
|
||||
IrisModdedCommands.fail(source, IrisLanguage.plain(ModdedCommandMessages.MODDED_OBJECT_COMMANDS_INVALID_OBJECT_NAME, MessageArgument.untrusted("nameRaw", nameRaw)));
|
||||
return 0;
|
||||
}
|
||||
BlockPos min = selection.min();
|
||||
@@ -276,12 +280,12 @@ public final class ModdedObjectCommands {
|
||||
int d = max.getZ() - min.getZ() + 1;
|
||||
long volume = (long) w * h * d;
|
||||
if (volume > MAX_SAVE_VOLUME) {
|
||||
IrisModdedCommands.fail(source, "Selection too large: " + volume + " blocks (max " + MAX_SAVE_VOLUME + ").");
|
||||
IrisModdedCommands.fail(source, IrisLanguage.plain(ModdedCommandMessages.MODDED_OBJECT_COMMANDS_SELECTION_TOO_LARGE_BLOCKS_MAX, MessageArgument.untrusted("volume", volume), MessageArgument.untrusted("MAXSAVEVOLUME", MAX_SAVE_VOLUME)));
|
||||
return 0;
|
||||
}
|
||||
File file = new File(engine.getData().getDataFolder(), "objects" + File.separator + name.replace('/', File.separatorChar) + ".iob");
|
||||
if (file.exists() && !overwrite) {
|
||||
IrisModdedCommands.fail(source, "File already exists. Use /iris object save overwrite " + name);
|
||||
IrisModdedCommands.fail(source, IrisLanguage.plain(ModdedCommandMessages.MODDED_OBJECT_COMMANDS_FILE_ALREADY_EXISTS_USE_IRIS_OBJECT_SAVE_OVERWRITE, MessageArgument.untrusted("name", name)));
|
||||
return 0;
|
||||
}
|
||||
int[] tilesSkipped = {0};
|
||||
@@ -295,7 +299,7 @@ public final class ModdedObjectCommands {
|
||||
object.write(file);
|
||||
} catch (IOException e) {
|
||||
LOGGER.error("Iris object save failed for {}", file.getAbsolutePath(), e);
|
||||
IrisModdedCommands.fail(source, "Failed to save object: " + e.getMessage());
|
||||
IrisModdedCommands.fail(source, IrisLanguage.plain(ModdedCommandMessages.MODDED_OBJECT_COMMANDS_FAILED_SAVE_OBJECT, MessageArgument.untrusted("value", String.valueOf(e.getMessage()))));
|
||||
return 0;
|
||||
}
|
||||
StringBuilder tileNote = new StringBuilder();
|
||||
@@ -308,8 +312,7 @@ public final class ModdedObjectCommands {
|
||||
} else if (tilesSkipped[0] > 0) {
|
||||
tileNote.append(" (").append(tilesSkipped[0]).append(" tile state(s) could not be captured)");
|
||||
}
|
||||
IrisModdedCommands.ok(source, "Saved " + engine.getData().getDataFolder().getName() + "/objects/" + name + ".iob: "
|
||||
+ w + "x" + h + "x" + d + ", " + object.getBlocks().size() + " block(s)" + tileNote);
|
||||
IrisModdedCommands.ok(source, IrisLanguage.plain(ModdedCommandMessages.MODDED_OBJECT_COMMANDS_SAVED_OBJECTS_IOB_X_X_BLOCK_S, MessageArgument.untrusted("value", engine.getData().getDataFolder().getName()), MessageArgument.untrusted("name", name), MessageArgument.untrusted("w", w), MessageArgument.untrusted("h", h), MessageArgument.untrusted("d", d), MessageArgument.untrusted("value2", object.getBlocks().size()), MessageArgument.untrusted("tileNote", tileNote)));
|
||||
LOGGER.info("Iris object save: {} {}x{}x{} blocks={} tilesSaved={} tilesSkipped={} -> {}", name, w, h, d, object.getBlocks().size(), tilesSaved[0], tilesSkipped[0], file.getAbsolutePath());
|
||||
return 1;
|
||||
}
|
||||
@@ -371,7 +374,7 @@ public final class ModdedObjectCommands {
|
||||
LOGGER.error("Iris object load failed for {}", key, e);
|
||||
}
|
||||
if (object == null || object.getBlocks().size() == 0) {
|
||||
IrisModdedCommands.fail(source, "Unknown or empty object: " + key);
|
||||
IrisModdedCommands.fail(source, IrisLanguage.plain(ModdedCommandMessages.MODDED_OBJECT_COMMANDS_UNKNOWN_EMPTY_OBJECT, MessageArgument.untrusted("key", key)));
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -379,12 +382,12 @@ public final class ModdedObjectCommands {
|
||||
BlockPos target = at;
|
||||
if (target == null) {
|
||||
if (player == null) {
|
||||
IrisModdedCommands.fail(source, "Console must specify coordinates: /iris object paste at <x> <y> <z> [rotate <degrees>] " + key);
|
||||
IrisModdedCommands.fail(source, IrisLanguage.plain(ModdedCommandMessages.MODDED_OBJECT_COMMANDS_CONSOLE_MUST_SPECIFY_COORDINATES_IRIS_OBJECT_PASTE_AT_X_Y, MessageArgument.untrusted("key", key)));
|
||||
return 0;
|
||||
}
|
||||
HitResult hit = player.pick(TARGET_RANGE, 1.0F, false);
|
||||
if (hit.getType() != HitResult.Type.BLOCK || !(hit instanceof BlockHitResult blockHit)) {
|
||||
IrisModdedCommands.fail(source, "You are not looking at a block within " + (int) TARGET_RANGE + " blocks.");
|
||||
IrisModdedCommands.fail(source, IrisLanguage.plain(ModdedCommandMessages.MODDED_OBJECT_COMMANDS_YOU_ARE_NOT_LOOKING_AT_BLOCK_WITHIN_BLOCKS, MessageArgument.untrusted("value", (int) TARGET_RANGE)));
|
||||
return 0;
|
||||
}
|
||||
target = blockHit.getBlockPos().above();
|
||||
@@ -398,14 +401,13 @@ public final class ModdedObjectCommands {
|
||||
} catch (Throwable e) {
|
||||
LOGGER.error("Iris paste failed for {}", key, e);
|
||||
ModdedObjectUndo.record(player == null ? ModdedObjectUndo.CONSOLE : player.getUUID(), level, placer.undoSnapshot());
|
||||
IrisModdedCommands.fail(source, "Paste failed: " + e.getClass().getSimpleName() + " (partial changes recorded for undo)");
|
||||
IrisModdedCommands.fail(source, IrisLanguage.plain(ModdedCommandMessages.MODDED_OBJECT_COMMANDS_PASTE_FAILED_PARTIAL_CHANGES_RECORDED_UNDO, MessageArgument.untrusted("value", e.getClass().getSimpleName())));
|
||||
return 0;
|
||||
}
|
||||
UUID owner = player == null ? ModdedObjectUndo.CONSOLE : player.getUUID();
|
||||
ModdedObjectUndo.record(owner, level, placer.undoSnapshot());
|
||||
String tileNote = tileNote(placer);
|
||||
IrisModdedCommands.ok(source, "Placed " + key + " at " + target.getX() + " " + target.getY() + " " + target.getZ()
|
||||
+ " rot=" + rotation + " (" + placer.writes() + " write(s), " + placer.nonAirWrites() + " non-air" + tileNote + ")");
|
||||
IrisModdedCommands.ok(source, IrisLanguage.plain(ModdedCommandMessages.MODDED_OBJECT_COMMANDS_PLACED_AT_ROT_WRITE_S_NON_AIR, MessageArgument.untrusted("key", key), MessageArgument.untrusted("value", target.getX()), MessageArgument.untrusted("value2", target.getY()), MessageArgument.untrusted("value3", target.getZ()), MessageArgument.untrusted("rotation", rotation), MessageArgument.untrusted("value4", placer.writes()), MessageArgument.untrusted("value5", placer.nonAirWrites()), MessageArgument.untrusted("tileNote", tileNote)));
|
||||
LOGGER.info("Iris paste: {} at {},{},{} rot={} writes={} nonAir={} tilesRestored={} tilesSkipped={}",
|
||||
key, target.getX(), target.getY(), target.getZ(), rotation, placer.writes(), placer.nonAirWrites(), placer.restoredTiles(), placer.skippedTiles());
|
||||
return placer.writes() > 0 ? 1 : 0;
|
||||
@@ -414,16 +416,16 @@ public final class ModdedObjectCommands {
|
||||
private static int resize(CommandSourceStack source, int amount, ResizeOp op) {
|
||||
ServerPlayer player = source.getPlayer();
|
||||
if (player == null) {
|
||||
IrisModdedCommands.fail(source, "This command can only be used by players.");
|
||||
IrisModdedCommands.fail(source, IrisLanguage.plain(ModdedCommandMessages.MODDED_OBJECT_COMMANDS_THIS_COMMAND_CAN_ONLY_BE_USED_BY_PLAYERS));
|
||||
return 0;
|
||||
}
|
||||
if (!ModdedWandService.isHoldingWand(player)) {
|
||||
IrisModdedCommands.fail(source, "Hold your Iris wand. (/iris wand)");
|
||||
IrisModdedCommands.fail(source, IrisLanguage.plain(ModdedCommandMessages.MODDED_OBJECT_COMMANDS_HOLD_YOUR_IRIS_WAND_IRIS_WAND_2));
|
||||
return 0;
|
||||
}
|
||||
ModdedWandService.Selection selection = ModdedWandService.selection(player);
|
||||
if (selection == null) {
|
||||
IrisModdedCommands.fail(source, "No area selected.");
|
||||
IrisModdedCommands.fail(source, IrisLanguage.plain(ModdedCommandMessages.MODDED_OBJECT_COMMANDS_NO_AREA_SELECTED));
|
||||
return 0;
|
||||
}
|
||||
Direction direction = Direction.getApproximateNearest(player.getLookAngle());
|
||||
@@ -458,26 +460,25 @@ public final class ModdedObjectCommands {
|
||||
BlockPos first = new BlockPos(mins[0], mins[1], mins[2]);
|
||||
BlockPos second = new BlockPos(maxs[0], maxs[1], maxs[2]);
|
||||
ModdedWandService.setSelection(player, first, second);
|
||||
IrisModdedCommands.ok(source, op.name().toLowerCase(Locale.ROOT) + " " + amount + " " + direction.getName()
|
||||
+ ": " + describe(first, second));
|
||||
IrisModdedCommands.ok(source, IrisLanguage.plain(ModdedCommandMessages.MODDED_OBJECT_COMMANDS_MESSAGE, MessageArgument.untrusted("value", op.name().toLowerCase(Locale.ROOT)), MessageArgument.untrusted("amount", amount), MessageArgument.untrusted("value2", direction.getName()), MessageArgument.untrusted("value3", describe(first, second))));
|
||||
return 1;
|
||||
}
|
||||
|
||||
private static int position(CommandSourceStack source, boolean first, boolean look) {
|
||||
ServerPlayer player = source.getPlayer();
|
||||
if (player == null) {
|
||||
IrisModdedCommands.fail(source, "This command can only be used by players.");
|
||||
IrisModdedCommands.fail(source, IrisLanguage.plain(ModdedCommandMessages.MODDED_OBJECT_COMMANDS_THIS_COMMAND_CAN_ONLY_BE_USED_BY_PLAYERS_2));
|
||||
return 0;
|
||||
}
|
||||
if (!ModdedWandService.isHoldingWand(player)) {
|
||||
IrisModdedCommands.fail(source, "Ready your wand. (/iris wand)");
|
||||
IrisModdedCommands.fail(source, IrisLanguage.plain(ModdedCommandMessages.MODDED_OBJECT_COMMANDS_READY_YOUR_WAND_IRIS_WAND));
|
||||
return 0;
|
||||
}
|
||||
BlockPos pos;
|
||||
if (look) {
|
||||
HitResult hit = player.pick(TARGET_RANGE, 1.0F, false);
|
||||
if (hit.getType() != HitResult.Type.BLOCK || !(hit instanceof BlockHitResult blockHit)) {
|
||||
IrisModdedCommands.fail(source, "You are not looking at a block.");
|
||||
IrisModdedCommands.fail(source, IrisLanguage.plain(ModdedCommandMessages.MODDED_OBJECT_COMMANDS_YOU_ARE_NOT_LOOKING_AT_BLOCK));
|
||||
return 0;
|
||||
}
|
||||
pos = blockHit.getBlockPos();
|
||||
@@ -492,23 +493,23 @@ public final class ModdedObjectCommands {
|
||||
} else {
|
||||
ModdedWandService.setSelection(player, fallback, pos);
|
||||
}
|
||||
IrisModdedCommands.ok(source, "Position " + (first ? 1 : 2) + " set to " + pos.getX() + " " + pos.getY() + " " + pos.getZ());
|
||||
IrisModdedCommands.ok(source, IrisLanguage.plain(ModdedCommandMessages.MODDED_OBJECT_COMMANDS_POSITION_SET, MessageArgument.untrusted("value", (first ? 1 : 2)), MessageArgument.untrusted("value2", pos.getX()), MessageArgument.untrusted("value3", pos.getY()), MessageArgument.untrusted("value4", pos.getZ())));
|
||||
return 1;
|
||||
}
|
||||
|
||||
private static int autoSelect(CommandSourceStack source, boolean down) {
|
||||
ServerPlayer player = source.getPlayer();
|
||||
if (player == null) {
|
||||
IrisModdedCommands.fail(source, "This command can only be used by players.");
|
||||
IrisModdedCommands.fail(source, IrisLanguage.plain(ModdedCommandMessages.MODDED_OBJECT_COMMANDS_THIS_COMMAND_CAN_ONLY_BE_USED_BY_PLAYERS_3));
|
||||
return 0;
|
||||
}
|
||||
if (!ModdedWandService.isHoldingWand(player)) {
|
||||
IrisModdedCommands.fail(source, "Hold your wand!");
|
||||
IrisModdedCommands.fail(source, IrisLanguage.plain(ModdedCommandMessages.MODDED_OBJECT_COMMANDS_HOLD_YOUR_WAND));
|
||||
return 0;
|
||||
}
|
||||
ModdedWandService.Selection selection = ModdedWandService.selection(player);
|
||||
if (selection == null) {
|
||||
IrisModdedCommands.fail(source, "No area selected.");
|
||||
IrisModdedCommands.fail(source, IrisLanguage.plain(ModdedCommandMessages.MODDED_OBJECT_COMMANDS_NO_AREA_SELECTED_2));
|
||||
return 0;
|
||||
}
|
||||
ServerLevel level = player.level();
|
||||
@@ -516,7 +517,7 @@ public final class ModdedObjectCommands {
|
||||
BlockPos max = selection.max();
|
||||
long volume = (long) (max.getX() - min.getX() + 1) * (max.getY() - min.getY() + 1) * (max.getZ() - min.getZ() + 1);
|
||||
if (volume > MAX_AUTOSELECT_VOLUME) {
|
||||
IrisModdedCommands.fail(source, "Selection too large for auto-select: " + volume + " blocks (max " + MAX_AUTOSELECT_VOLUME + ").");
|
||||
IrisModdedCommands.fail(source, IrisLanguage.plain(ModdedCommandMessages.MODDED_OBJECT_COMMANDS_SELECTION_TOO_LARGE_AUTO_SELECT_BLOCKS_MAX, MessageArgument.untrusted("volume", volume), MessageArgument.untrusted("MAXAUTOSELECTVOLUME", MAX_AUTOSELECT_VOLUME)));
|
||||
return 0;
|
||||
}
|
||||
int levelMinY = level.getMinY();
|
||||
@@ -561,7 +562,7 @@ public final class ModdedObjectCommands {
|
||||
BlockPos first = new BlockPos(minX, bottomY, minZ);
|
||||
BlockPos second = new BlockPos(maxX, topMaxY, maxZ);
|
||||
ModdedWandService.setSelection(player, first, second);
|
||||
IrisModdedCommands.ok(source, "Auto-select complete: " + describe(first, second));
|
||||
IrisModdedCommands.ok(source, IrisLanguage.plain(ModdedCommandMessages.MODDED_OBJECT_COMMANDS_AUTO_SELECT_COMPLETE, MessageArgument.untrusted("value", describe(first, second))));
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -590,11 +591,11 @@ public final class ModdedObjectCommands {
|
||||
LOGGER.error("Iris object load failed for {}", key, e);
|
||||
}
|
||||
if (object == null) {
|
||||
IrisModdedCommands.fail(source, "Unknown object: " + key);
|
||||
IrisModdedCommands.fail(source, IrisLanguage.plain(ModdedCommandMessages.MODDED_OBJECT_COMMANDS_UNKNOWN_OBJECT, MessageArgument.untrusted("key", key)));
|
||||
return 0;
|
||||
}
|
||||
IrisModdedCommands.ok(source, "Object Size: " + object.getW() + " * " + object.getH() + " * " + object.getD());
|
||||
IrisModdedCommands.ok(source, "Blocks Used: " + object.getBlocks().size());
|
||||
IrisModdedCommands.ok(source, IrisLanguage.plain(ModdedCommandMessages.MODDED_OBJECT_COMMANDS_OBJECT_SIZE, MessageArgument.untrusted("value", object.getW()), MessageArgument.untrusted("value2", object.getH()), MessageArgument.untrusted("value3", object.getD())));
|
||||
IrisModdedCommands.ok(source, IrisLanguage.plain(ModdedCommandMessages.MODDED_OBJECT_COMMANDS_BLOCKS_USED, MessageArgument.untrusted("value", object.getBlocks().size())));
|
||||
Map<String, Integer> counts = new HashMap<>();
|
||||
Iterator<PlatformBlockState> values = object.getBlocks().values();
|
||||
while (values.hasNext()) {
|
||||
@@ -603,15 +604,15 @@ public final class ModdedObjectCommands {
|
||||
}
|
||||
List<Map.Entry<String, Integer>> sorted = new ArrayList<>(counts.entrySet());
|
||||
sorted.sort(Comparator.comparingInt((Map.Entry<String, Integer> entry) -> entry.getValue()).reversed());
|
||||
IrisModdedCommands.ok(source, "== Blocks in object ==");
|
||||
IrisModdedCommands.ok(source, IrisLanguage.plain(ModdedCommandMessages.MODDED_OBJECT_COMMANDS_BLOCKS_OBJECT));
|
||||
int shown = 0;
|
||||
for (Map.Entry<String, Integer> entry : sorted) {
|
||||
IrisModdedCommands.ok(source, " - " + entry.getKey() + " * " + entry.getValue());
|
||||
IrisModdedCommands.ok(source, IrisLanguage.plain(ModdedCommandMessages.MODDED_OBJECT_COMMANDS_MESSAGE_2, MessageArgument.untrusted("value", entry.getKey()), MessageArgument.untrusted("value2", entry.getValue())));
|
||||
shown++;
|
||||
if (shown >= 10) {
|
||||
int remaining = sorted.size() - shown;
|
||||
if (remaining > 0) {
|
||||
IrisModdedCommands.ok(source, " + " + remaining + " other block state(s)");
|
||||
IrisModdedCommands.ok(source, IrisLanguage.plain(ModdedCommandMessages.MODDED_OBJECT_COMMANDS_OTHER_BLOCK_STATE_S, MessageArgument.untrusted("remaining", remaining)));
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -630,22 +631,22 @@ public final class ModdedObjectCommands {
|
||||
LOGGER.error("Iris object load failed for {}", key, e);
|
||||
}
|
||||
if (object == null) {
|
||||
IrisModdedCommands.fail(source, "Unknown object: " + key);
|
||||
IrisModdedCommands.fail(source, IrisLanguage.plain(ModdedCommandMessages.MODDED_OBJECT_COMMANDS_UNKNOWN_OBJECT_2, MessageArgument.untrusted("key", key)));
|
||||
return 0;
|
||||
}
|
||||
IrisModdedCommands.ok(source, "Current Object Size: " + object.getW() + " * " + object.getH() + " * " + object.getD());
|
||||
IrisModdedCommands.ok(source, IrisLanguage.plain(ModdedCommandMessages.MODDED_OBJECT_COMMANDS_CURRENT_OBJECT_SIZE, MessageArgument.untrusted("value", object.getW()), MessageArgument.untrusted("value2", object.getH()), MessageArgument.untrusted("value3", object.getD())));
|
||||
object.shrinkwrap();
|
||||
IrisModdedCommands.ok(source, "New Object Size: " + object.getW() + " * " + object.getH() + " * " + object.getD());
|
||||
IrisModdedCommands.ok(source, IrisLanguage.plain(ModdedCommandMessages.MODDED_OBJECT_COMMANDS_NEW_OBJECT_SIZE, MessageArgument.untrusted("value", object.getW()), MessageArgument.untrusted("value2", object.getH()), MessageArgument.untrusted("value3", object.getD())));
|
||||
File file = object.getLoadFile();
|
||||
if (file == null) {
|
||||
IrisModdedCommands.fail(source, "Object has no load file; cannot persist the shrink.");
|
||||
IrisModdedCommands.fail(source, IrisLanguage.plain(ModdedCommandMessages.MODDED_OBJECT_COMMANDS_OBJECT_HAS_NO_LOAD_FILE_CANNOT_PERSIST_SHRINK));
|
||||
return 0;
|
||||
}
|
||||
try {
|
||||
object.write(file);
|
||||
} catch (IOException e) {
|
||||
LOGGER.error("Iris object shrink save failed for {}", file.getAbsolutePath(), e);
|
||||
IrisModdedCommands.fail(source, "Failed to save object " + file.getName() + ": " + e.getMessage());
|
||||
IrisModdedCommands.fail(source, IrisLanguage.plain(ModdedCommandMessages.MODDED_OBJECT_COMMANDS_FAILED_SAVE_OBJECT_2, MessageArgument.untrusted("value", file.getName()), MessageArgument.untrusted("value2", String.valueOf(e.getMessage()))));
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
@@ -667,7 +668,7 @@ public final class ModdedObjectCommands {
|
||||
try {
|
||||
reach = Integer.parseInt(lower.substring("reach=".length()));
|
||||
} catch (NumberFormatException e) {
|
||||
IrisModdedCommands.fail(source, "Invalid reach: " + token);
|
||||
IrisModdedCommands.fail(source, IrisLanguage.plain(ModdedCommandMessages.MODDED_OBJECT_COMMANDS_INVALID_REACH, MessageArgument.untrusted("token", token)));
|
||||
return 0;
|
||||
}
|
||||
continue;
|
||||
@@ -680,16 +681,20 @@ public final class ModdedObjectCommands {
|
||||
String target = targetBuilder.toString();
|
||||
List<TreePlausibilizeBatch.Target> targets = TreePlausibilizeBatch.resolve(target, data);
|
||||
if (targets.isEmpty()) {
|
||||
IrisModdedCommands.fail(source, "No objects matched: " + target);
|
||||
IrisModdedCommands.fail(source, IrisLanguage.plain(ModdedCommandMessages.MODDED_OBJECT_COMMANDS_NO_OBJECTS_MATCHED, MessageArgument.untrusted("target", target)));
|
||||
return 0;
|
||||
}
|
||||
IrisModdedCommands.ok(source, "Plausibilize [reach=" + reach + (dryRun ? ", DRY" : "")
|
||||
+ "] queued " + targets.size() + " object(s)");
|
||||
IrisModdedCommands.ok(source, IrisLanguage.plain(
|
||||
ModdedCommandMessages.MODDED_OBJECT_COMMANDS_PLAUSIBILIZE_REACH_QUEUED_OBJECT_S,
|
||||
MessageArgument.trusted("reach", reach),
|
||||
MessageArgument.trusted("value", dryRun ? IrisLanguage.plain(RuntimeUiMessages.TREE_DRY_SUFFIX) : ""),
|
||||
MessageArgument.trusted("value2", targets.size())
|
||||
));
|
||||
boolean dry = dryRun;
|
||||
int reachFinal = reach;
|
||||
MinecraftServer server = source.getServer();
|
||||
J.a(() -> TreePlausibilizeBatch.run(targets, dry, reachFinal, data, (String line) ->
|
||||
server.execute(() -> IrisModdedCommands.ok(source, line))));
|
||||
J.a(() -> TreePlausibilizeBatch.run(targets, dry, reachFinal, data, (TreePlausibilizeBatch.Output output) ->
|
||||
server.execute(() -> IrisModdedCommands.ok(source, output.text()))));
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -698,11 +703,11 @@ public final class ModdedObjectCommands {
|
||||
UUID owner = player == null ? ModdedObjectUndo.CONSOLE : player.getUUID();
|
||||
int available = ModdedObjectUndo.size(owner);
|
||||
if (available == 0) {
|
||||
IrisModdedCommands.fail(source, "Nothing to undo.");
|
||||
IrisModdedCommands.fail(source, IrisLanguage.plain(ModdedCommandMessages.MODDED_OBJECT_COMMANDS_NOTHING_UNDO));
|
||||
return 0;
|
||||
}
|
||||
int reverted = ModdedObjectUndo.undo(owner, Math.min(amount, available));
|
||||
IrisModdedCommands.ok(source, "Reverted " + reverted + " paste(s)!");
|
||||
IrisModdedCommands.ok(source, IrisLanguage.plain(ModdedCommandMessages.MODDED_OBJECT_COMMANDS_REVERTED_PASTE_S, MessageArgument.untrusted("reverted", reverted)));
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
+33
-37
@@ -39,6 +39,9 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
import art.arcane.iris.core.localization.IrisLanguage;
|
||||
import art.arcane.iris.core.localization.ModdedCommandMessages;
|
||||
import art.arcane.volmlib.util.localization.MessageArgument;
|
||||
public final class ModdedPackCommands {
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger("Iris");
|
||||
private static final Predicate<CommandSourceStack> GATE = Commands.hasPermission(Commands.LEVEL_GAMEMASTERS);
|
||||
@@ -101,7 +104,7 @@ public final class ModdedPackCommands {
|
||||
private static int validate(CommandSourceStack source, String pack) {
|
||||
File packsRoot = packsRoot();
|
||||
if (!packsRoot.isDirectory()) {
|
||||
IrisModdedCommands.fail(source, "Packs folder not found: " + packsRoot.getAbsolutePath());
|
||||
IrisModdedCommands.fail(source, IrisLanguage.plain(ModdedCommandMessages.MODDED_PACK_COMMANDS_PACKS_FOLDER_NOT_FOUND, MessageArgument.untrusted("value", packsRoot.getAbsolutePath())));
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -109,7 +112,7 @@ public final class ModdedPackCommands {
|
||||
if (pack == null || pack.isBlank()) {
|
||||
File[] dirs = packsRoot.listFiles(File::isDirectory);
|
||||
if (dirs == null || dirs.length == 0) {
|
||||
IrisModdedCommands.fail(source, "No packs to validate under " + packsRoot.getAbsolutePath());
|
||||
IrisModdedCommands.fail(source, IrisLanguage.plain(ModdedCommandMessages.MODDED_PACK_COMMANDS_NO_PACKS_VALIDATE_UNDER, MessageArgument.untrusted("value", packsRoot.getAbsolutePath())));
|
||||
return 0;
|
||||
}
|
||||
for (File dir : dirs) {
|
||||
@@ -118,14 +121,14 @@ public final class ModdedPackCommands {
|
||||
} else {
|
||||
File target = PackDirectoryResolver.resolveExisting(packsRoot, pack);
|
||||
if (target == null) {
|
||||
IrisModdedCommands.fail(source, "Pack '" + pack + "' not found under " + packsRoot.getAbsolutePath());
|
||||
IrisModdedCommands.fail(source, IrisLanguage.plain(ModdedCommandMessages.MODDED_PACK_COMMANDS_PACK_NOT_FOUND_UNDER, MessageArgument.untrusted("pack", pack), MessageArgument.untrusted("value", packsRoot.getAbsolutePath())));
|
||||
return 0;
|
||||
}
|
||||
targets.add(target);
|
||||
}
|
||||
|
||||
MinecraftServer server = source.getServer();
|
||||
IrisModdedCommands.ok(source, "Validating " + targets.size() + " pack(s)...");
|
||||
IrisModdedCommands.ok(source, IrisLanguage.plain(ModdedCommandMessages.MODDED_PACK_COMMANDS_VALIDATING_PACK_S, MessageArgument.untrusted("value", targets.size())));
|
||||
Thread thread = new Thread(() -> {
|
||||
int broken = 0;
|
||||
for (File target : targets) {
|
||||
@@ -138,12 +141,12 @@ public final class ModdedPackCommands {
|
||||
server.execute(() -> report(source, result));
|
||||
} catch (Throwable e) {
|
||||
LOGGER.error("Iris pack validation failed for {}", target.getName(), e);
|
||||
server.execute(() -> IrisModdedCommands.fail(source, "Validation of '" + target.getName() + "' failed: " + e.getMessage()));
|
||||
server.execute(() -> IrisModdedCommands.fail(source, IrisLanguage.plain(ModdedCommandMessages.MODDED_PACK_COMMANDS_VALIDATION_FAILED, MessageArgument.untrusted("value", target.getName()), MessageArgument.untrusted("value2", String.valueOf(e.getMessage())))));
|
||||
broken++;
|
||||
}
|
||||
}
|
||||
int brokenTotal = broken;
|
||||
server.execute(() -> IrisModdedCommands.ok(source, "Validation complete. Broken packs: " + brokenTotal + "/" + targets.size()));
|
||||
server.execute(() -> IrisModdedCommands.ok(source, IrisLanguage.plain(ModdedCommandMessages.MODDED_PACK_COMMANDS_VALIDATION_COMPLETE_BROKEN_PACKS, MessageArgument.untrusted("brokenTotal", brokenTotal), MessageArgument.untrusted("value", targets.size()))));
|
||||
}, "Iris Pack Validator");
|
||||
thread.setDaemon(true);
|
||||
thread.start();
|
||||
@@ -153,7 +156,7 @@ public final class ModdedPackCommands {
|
||||
private static int cleanup(CommandSourceStack source, String pack, boolean apply) {
|
||||
File packFolder = PackDirectoryResolver.resolveExisting(packsRoot(), pack);
|
||||
if (packFolder == null) {
|
||||
IrisModdedCommands.fail(source, "Pack '" + pack + "' not found under " + packsRoot().getAbsolutePath());
|
||||
IrisModdedCommands.fail(source, IrisLanguage.plain(ModdedCommandMessages.MODDED_PACK_COMMANDS_PACK_NOT_FOUND_UNDER_2, MessageArgument.untrusted("pack", pack), MessageArgument.untrusted("value", packsRoot().getAbsolutePath())));
|
||||
return 0;
|
||||
}
|
||||
MinecraftServer server = source.getServer();
|
||||
@@ -174,7 +177,7 @@ public final class ModdedPackCommands {
|
||||
private static int restore(CommandSourceStack source, String pack, boolean apply) {
|
||||
File packFolder = PackDirectoryResolver.resolveExisting(packsRoot(), pack);
|
||||
if (packFolder == null) {
|
||||
IrisModdedCommands.fail(source, "Pack '" + pack + "' not found under " + packsRoot().getAbsolutePath());
|
||||
IrisModdedCommands.fail(source, IrisLanguage.plain(ModdedCommandMessages.MODDED_PACK_COMMANDS_PACK_NOT_FOUND_UNDER_3, MessageArgument.untrusted("pack", pack), MessageArgument.untrusted("value", packsRoot().getAbsolutePath())));
|
||||
return 0;
|
||||
}
|
||||
MinecraftServer server = source.getServer();
|
||||
@@ -196,21 +199,19 @@ public final class ModdedPackCommands {
|
||||
if (pack == null || pack.isBlank()) {
|
||||
Map<String, PackValidationResult> snapshot = PackValidationRegistry.snapshot();
|
||||
if (snapshot.isEmpty()) {
|
||||
IrisModdedCommands.fail(source, "No validation results recorded. Run /iris pack validate first.");
|
||||
IrisModdedCommands.fail(source, IrisLanguage.plain(ModdedCommandMessages.MODDED_PACK_COMMANDS_NO_VALIDATION_RESULTS_RECORDED_RUN_IRIS_PACK_VALIDATE_FIRST));
|
||||
return 0;
|
||||
}
|
||||
for (Map.Entry<String, PackValidationResult> entry : snapshot.entrySet()) {
|
||||
PackValidationResult result = entry.getValue();
|
||||
String tag = result.isLoadable() ? "OK" : "BROKEN";
|
||||
IrisModdedCommands.ok(source, tag + " " + entry.getKey()
|
||||
+ " (blocking=" + result.getBlockingErrors().size()
|
||||
+ ", warnings=" + result.getWarnings().size() + ")");
|
||||
IrisModdedCommands.ok(source, IrisLanguage.plain(ModdedCommandMessages.MODDED_PACK_COMMANDS_BLOCKING_WARNINGS, MessageArgument.untrusted("tag", tag), MessageArgument.untrusted("value", entry.getKey()), MessageArgument.untrusted("value2", result.getBlockingErrors().size()), MessageArgument.untrusted("value3", result.getWarnings().size())));
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
PackValidationResult result = PackValidationRegistry.get(pack);
|
||||
if (result == null) {
|
||||
IrisModdedCommands.fail(source, "No validation result for '" + pack + "'. Run /iris pack validate " + pack + ".");
|
||||
IrisModdedCommands.fail(source, IrisLanguage.plain(ModdedCommandMessages.MODDED_PACK_COMMANDS_NO_VALIDATION_RESULT_RUN_IRIS_PACK_VALIDATE, MessageArgument.untrusted("pack", pack), MessageArgument.untrusted("pack2", pack)));
|
||||
return 0;
|
||||
}
|
||||
report(source, result);
|
||||
@@ -219,20 +220,19 @@ public final class ModdedPackCommands {
|
||||
|
||||
private static void report(CommandSourceStack source, PackValidationResult result) {
|
||||
if (result.isLoadable()) {
|
||||
IrisModdedCommands.ok(source, "Pack '" + result.getPackName() + "' is loadable."
|
||||
+ " (warnings=" + result.getWarnings().size() + ")");
|
||||
IrisModdedCommands.ok(source, IrisLanguage.plain(ModdedCommandMessages.MODDED_PACK_COMMANDS_PACK_IS_LOADABLE_WARNINGS, MessageArgument.untrusted("value", result.getPackName()), MessageArgument.untrusted("value2", result.getWarnings().size())));
|
||||
} else {
|
||||
IrisModdedCommands.fail(source, "Pack '" + result.getPackName() + "' is BROKEN:");
|
||||
IrisModdedCommands.fail(source, IrisLanguage.plain(ModdedCommandMessages.MODDED_PACK_COMMANDS_PACK_IS_BROKEN, MessageArgument.untrusted("value", result.getPackName())));
|
||||
for (String reason : result.getBlockingErrors()) {
|
||||
IrisModdedCommands.fail(source, " - " + reason);
|
||||
IrisModdedCommands.fail(source, IrisLanguage.plain(ModdedCommandMessages.MODDED_PACK_COMMANDS_MESSAGE, MessageArgument.untrusted("reason", reason)));
|
||||
}
|
||||
}
|
||||
int warningMax = Math.min(10, result.getWarnings().size());
|
||||
for (int i = 0; i < warningMax; i++) {
|
||||
IrisModdedCommands.ok(source, " ! " + result.getWarnings().get(i));
|
||||
IrisModdedCommands.ok(source, IrisLanguage.plain(ModdedCommandMessages.MODDED_PACK_COMMANDS_MESSAGE_2, MessageArgument.untrusted("value", result.getWarnings().get(i))));
|
||||
}
|
||||
if (result.getWarnings().size() > warningMax) {
|
||||
IrisModdedCommands.ok(source, " ... and " + (result.getWarnings().size() - warningMax) + " more warning(s).");
|
||||
IrisModdedCommands.ok(source, IrisLanguage.plain(ModdedCommandMessages.MODDED_PACK_COMMANDS_MORE_WARNING_S, MessageArgument.untrusted("value", (result.getWarnings().size() - warningMax))));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -242,13 +242,12 @@ public final class ModdedPackCommands {
|
||||
return;
|
||||
}
|
||||
if (!result.hasCandidates()) {
|
||||
IrisModdedCommands.ok(source, "No cleanup candidates found for pack '" + pack + "'.");
|
||||
IrisModdedCommands.ok(source, IrisLanguage.plain(ModdedCommandMessages.MODDED_PACK_COMMANDS_NO_CLEANUP_CANDIDATES_FOUND_PACK, MessageArgument.untrusted("pack", pack)));
|
||||
return;
|
||||
}
|
||||
IrisModdedCommands.ok(source, "Cleanup preview for pack '" + pack + "': "
|
||||
+ result.candidatePaths().size() + " candidate(s). No files were changed.");
|
||||
IrisModdedCommands.ok(source, IrisLanguage.plain(ModdedCommandMessages.MODDED_PACK_COMMANDS_CLEANUP_PREVIEW_PACK_CANDIDATE_S_NO_FILES_WERE_CHANGED, MessageArgument.untrusted("pack", pack), MessageArgument.untrusted("value", result.candidatePaths().size())));
|
||||
reportPaths(source, result.candidatePaths(), "candidate");
|
||||
IrisModdedCommands.ok(source, "Run /iris pack cleanup " + pack + " apply to quarantine after a fresh scan.");
|
||||
IrisModdedCommands.ok(source, IrisLanguage.plain(ModdedCommandMessages.MODDED_PACK_COMMANDS_RUN_IRIS_PACK_CLEANUP_APPLY_QUARANTINE_AFTER_FRESH_SCAN, MessageArgument.untrusted("pack", pack)));
|
||||
}
|
||||
|
||||
private static void reportCleanupApply(CommandSourceStack source, String pack, PackResourceCleanup.ApplyResult result) {
|
||||
@@ -258,11 +257,10 @@ public final class ModdedPackCommands {
|
||||
return;
|
||||
}
|
||||
if (!result.changed()) {
|
||||
IrisModdedCommands.ok(source, "No cleanup candidates found for pack '" + pack + "'.");
|
||||
IrisModdedCommands.ok(source, IrisLanguage.plain(ModdedCommandMessages.MODDED_PACK_COMMANDS_NO_CLEANUP_CANDIDATES_FOUND_PACK_2, MessageArgument.untrusted("pack", pack)));
|
||||
return;
|
||||
}
|
||||
IrisModdedCommands.ok(source, "Quarantined " + result.quarantinedPaths().size()
|
||||
+ " cleanup candidate(s) under " + result.quarantinePath() + ".");
|
||||
IrisModdedCommands.ok(source, IrisLanguage.plain(ModdedCommandMessages.MODDED_PACK_COMMANDS_QUARANTINED_CLEANUP_CANDIDATE_S_UNDER, MessageArgument.untrusted("value", result.quarantinedPaths().size()), MessageArgument.untrusted("value2", result.quarantinePath())));
|
||||
reportPaths(source, result.quarantinedPaths(), "quarantined");
|
||||
}
|
||||
|
||||
@@ -272,23 +270,22 @@ public final class ModdedPackCommands {
|
||||
return;
|
||||
}
|
||||
if (!result.hasFiles()) {
|
||||
IrisModdedCommands.ok(source, "Nothing to restore for pack '" + pack + "'.");
|
||||
IrisModdedCommands.ok(source, IrisLanguage.plain(ModdedCommandMessages.MODDED_PACK_COMMANDS_NOTHING_RESTORE_PACK, MessageArgument.untrusted("pack", pack)));
|
||||
return;
|
||||
}
|
||||
IrisModdedCommands.ok(source, "Restore preview for " + result.dumpPath() + ": "
|
||||
+ result.filePaths().size() + " file(s). No files were changed.");
|
||||
IrisModdedCommands.ok(source, IrisLanguage.plain(ModdedCommandMessages.MODDED_PACK_COMMANDS_RESTORE_PREVIEW_FILE_S_NO_FILES_WERE_CHANGED, MessageArgument.untrusted("value", result.dumpPath()), MessageArgument.untrusted("value2", result.filePaths().size())));
|
||||
reportPaths(source, result.filePaths(), "file");
|
||||
if (!result.conflicts().isEmpty()) {
|
||||
IrisModdedCommands.fail(source, "Restore is blocked by " + result.conflicts().size() + " existing destination(s).");
|
||||
IrisModdedCommands.fail(source, IrisLanguage.plain(ModdedCommandMessages.MODDED_PACK_COMMANDS_RESTORE_IS_BLOCKED_BY_EXISTING_DESTINATION_S, MessageArgument.untrusted("value", result.conflicts().size())));
|
||||
reportPaths(source, result.conflicts(), "conflict");
|
||||
return;
|
||||
}
|
||||
IrisModdedCommands.ok(source, "Run /iris pack restore " + pack + " apply to restore after a fresh conflict check.");
|
||||
IrisModdedCommands.ok(source, IrisLanguage.plain(ModdedCommandMessages.MODDED_PACK_COMMANDS_RUN_IRIS_PACK_RESTORE_APPLY_RESTORE_AFTER_FRESH_CONFLICT_CHECK, MessageArgument.untrusted("pack", pack)));
|
||||
}
|
||||
|
||||
private static void reportRestoreApply(CommandSourceStack source, String pack, PackResourceCleanup.RestoreResult result) {
|
||||
if (!result.conflicts().isEmpty()) {
|
||||
IrisModdedCommands.fail(source, "Restore refused because " + result.conflicts().size() + " destination(s) already exist.");
|
||||
IrisModdedCommands.fail(source, IrisLanguage.plain(ModdedCommandMessages.MODDED_PACK_COMMANDS_RESTORE_REFUSED_BECAUSE_DESTINATION_S_ALREADY_EXIST, MessageArgument.untrusted("value", result.conflicts().size())));
|
||||
reportPaths(source, result.conflicts(), "conflict");
|
||||
return;
|
||||
}
|
||||
@@ -297,21 +294,20 @@ public final class ModdedPackCommands {
|
||||
return;
|
||||
}
|
||||
if (!result.changed()) {
|
||||
IrisModdedCommands.ok(source, "Nothing to restore for pack '" + pack + "'.");
|
||||
IrisModdedCommands.ok(source, IrisLanguage.plain(ModdedCommandMessages.MODDED_PACK_COMMANDS_NOTHING_RESTORE_PACK_2, MessageArgument.untrusted("pack", pack)));
|
||||
return;
|
||||
}
|
||||
IrisModdedCommands.ok(source, "Restored " + result.restoredPaths().size()
|
||||
+ " file(s) from " + result.dumpPath() + ".");
|
||||
IrisModdedCommands.ok(source, IrisLanguage.plain(ModdedCommandMessages.MODDED_PACK_COMMANDS_RESTORED_FILE_S_FROM, MessageArgument.untrusted("value", result.restoredPaths().size()), MessageArgument.untrusted("value2", result.dumpPath())));
|
||||
reportPaths(source, result.restoredPaths(), "restored");
|
||||
}
|
||||
|
||||
private static void reportPaths(CommandSourceStack source, List<String> paths, String label) {
|
||||
int max = Math.min(10, paths.size());
|
||||
for (int i = 0; i < max; i++) {
|
||||
IrisModdedCommands.ok(source, " - " + label + ": " + paths.get(i));
|
||||
IrisModdedCommands.ok(source, IrisLanguage.plain(ModdedCommandMessages.MODDED_PACK_COMMANDS_MESSAGE_3, MessageArgument.untrusted("label", label), MessageArgument.untrusted("value", paths.get(i))));
|
||||
}
|
||||
if (paths.size() > max) {
|
||||
IrisModdedCommands.ok(source, " ... and " + (paths.size() - max) + " more.");
|
||||
IrisModdedCommands.ok(source, IrisLanguage.plain(ModdedCommandMessages.MODDED_PACK_COMMANDS_MORE, MessageArgument.untrusted("value", (paths.size() - max))));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+40
-16
@@ -1,13 +1,16 @@
|
||||
package art.arcane.iris.modded.command;
|
||||
|
||||
import art.arcane.iris.core.gui.PregeneratorJob;
|
||||
import art.arcane.iris.core.localization.IrisLanguage;
|
||||
import art.arcane.iris.core.localization.RuntimeUiMessages;
|
||||
import art.arcane.iris.core.protocol.IrisProtocolServer;
|
||||
import art.arcane.iris.core.protocol.IrisSession;
|
||||
import art.arcane.iris.spi.IrisServices;
|
||||
import art.arcane.iris.spi.protocol.IrisProtocol;
|
||||
import art.arcane.volmlib.util.format.Form;
|
||||
import art.arcane.volmlib.util.localization.MessageArgument;
|
||||
import art.arcane.volmlib.util.localization.TextKey;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.network.chat.MutableComponent;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.server.level.ServerBossEvent;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
@@ -35,7 +38,12 @@ public final class ModdedPregenBossBar {
|
||||
return;
|
||||
}
|
||||
viewer = player.getUUID();
|
||||
bar = new ServerBossEvent(BAR_ID, Component.literal("Iris Pregen starting..."), BossEvent.BossBarColor.GREEN, BossEvent.BossBarOverlay.PROGRESS);
|
||||
bar = new ServerBossEvent(
|
||||
BAR_ID,
|
||||
Component.literal(IrisLanguage.plain(RuntimeUiMessages.PREGEN_STARTING)),
|
||||
BossEvent.BossBarColor.GREEN,
|
||||
BossEvent.BossBarOverlay.PROGRESS
|
||||
);
|
||||
bar.setProgress(0.0F);
|
||||
bar.addPlayer(player);
|
||||
sinceUpdate = UPDATE_INTERVAL_TICKS;
|
||||
@@ -73,22 +81,38 @@ public final class ModdedPregenBossBar {
|
||||
}
|
||||
|
||||
private static Component nameFor(PregeneratorJob.PregenProgress progress) {
|
||||
MutableComponent name = Component.empty();
|
||||
name.append(ModdedCommandFeedback.text("Iris Pregen ", ModdedCommandFeedback.DARK_GREEN));
|
||||
name.append(ModdedCommandFeedback.text(Form.f(progress.generated()) + "/" + Form.f(progress.totalChunks()), ModdedCommandFeedback.VALUE));
|
||||
name.append(ModdedCommandFeedback.text(" " + String.format("%.1f", progress.percent()) + "%", ModdedCommandFeedback.USAGE));
|
||||
TextKey message = progress.paused()
|
||||
? RuntimeUiMessages.PREGEN_BOSSBAR_PAUSED
|
||||
: RuntimeUiMessages.PREGEN_BOSSBAR_RUNNING;
|
||||
if (progress.paused()) {
|
||||
name.append(ModdedCommandFeedback.text(" PAUSED", ModdedCommandFeedback.REQUIRED));
|
||||
return name;
|
||||
return ModdedCommandFeedback.text(IrisLanguage.plain(
|
||||
message,
|
||||
MessageArgument.trusted("generated", Form.f(progress.generated())),
|
||||
MessageArgument.trusted("total", Form.f(progress.totalChunks())),
|
||||
MessageArgument.trusted("percent", String.format("%.1f", progress.percent()))
|
||||
), ModdedCommandFeedback.DARK_GREEN);
|
||||
}
|
||||
name.append(ModdedCommandFeedback.text(" " + Form.f((int) progress.chunksPerSecond()) + "/s", ModdedCommandFeedback.VALUE));
|
||||
if (progress.eta() > 0L) {
|
||||
name.append(ModdedCommandFeedback.text(" ETA " + Form.duration(progress.eta(), 1), ModdedCommandFeedback.DARK_GREEN));
|
||||
}
|
||||
if (progress.failed() > 0L) {
|
||||
name.append(ModdedCommandFeedback.text(" failed " + Form.f(progress.failed()), ModdedCommandFeedback.REQUIRED));
|
||||
}
|
||||
return name;
|
||||
String eta = progress.eta() > 0L
|
||||
? IrisLanguage.plain(
|
||||
RuntimeUiMessages.PREGEN_ETA_FRAGMENT,
|
||||
MessageArgument.trusted("eta", Form.duration(progress.eta(), 1))
|
||||
)
|
||||
: "";
|
||||
String failed = progress.failed() > 0L
|
||||
? IrisLanguage.plain(
|
||||
RuntimeUiMessages.PREGEN_FAILED_FRAGMENT,
|
||||
MessageArgument.trusted("failed", Form.f(progress.failed()))
|
||||
)
|
||||
: "";
|
||||
return ModdedCommandFeedback.text(IrisLanguage.plain(
|
||||
message,
|
||||
MessageArgument.trusted("generated", Form.f(progress.generated())),
|
||||
MessageArgument.trusted("total", Form.f(progress.totalChunks())),
|
||||
MessageArgument.trusted("percent", String.format("%.1f", progress.percent())),
|
||||
MessageArgument.trusted("speed", Form.f((int) progress.chunksPerSecond())),
|
||||
MessageArgument.trusted("eta", eta),
|
||||
MessageArgument.trusted("failed", failed)
|
||||
), ModdedCommandFeedback.DARK_GREEN);
|
||||
}
|
||||
|
||||
private static boolean hasClientPregenHud(ServerPlayer player) {
|
||||
|
||||
+51
-23
@@ -19,6 +19,8 @@
|
||||
package art.arcane.iris.modded.command;
|
||||
|
||||
import art.arcane.iris.core.gui.PregeneratorJob;
|
||||
import art.arcane.iris.core.localization.IrisLanguage;
|
||||
import art.arcane.iris.core.localization.RuntimeUiMessages;
|
||||
import art.arcane.iris.core.pregenerator.PregenPerformanceProfile;
|
||||
import art.arcane.iris.core.pregenerator.PregenTask;
|
||||
import art.arcane.iris.core.pregenerator.PregeneratorMethod;
|
||||
@@ -27,6 +29,7 @@ import art.arcane.iris.core.pregenerator.methods.CachedPregenMethod;
|
||||
import art.arcane.iris.engine.framework.Engine;
|
||||
import art.arcane.volmlib.util.format.Form;
|
||||
import art.arcane.volmlib.util.math.Position2;
|
||||
import art.arcane.volmlib.util.localization.MessageArgument;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.network.chat.MutableComponent;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
@@ -119,41 +122,66 @@ public final class ModdedPregenJob {
|
||||
}
|
||||
|
||||
MutableComponent status = Component.empty();
|
||||
status.append(ModdedCommandFeedback.header("Iris Pregen"));
|
||||
status.append(ModdedCommandFeedback.header(IrisLanguage.plain(RuntimeUiMessages.PREGEN_HEADER)));
|
||||
status.append(Component.literal("\n"));
|
||||
status.append(ModdedCommandFeedback.text("Dimension ", ModdedCommandFeedback.DARK_GREEN));
|
||||
status.append(ModdedCommandFeedback.text(dimension, ModdedCommandFeedback.PARAMETER_ALT));
|
||||
status.append(ModdedCommandFeedback.text(" · Method ", ModdedCommandFeedback.DARK_GREEN));
|
||||
status.append(ModdedCommandFeedback.text(progress.method(), ModdedCommandFeedback.PARAMETER));
|
||||
status.append(ModdedCommandFeedback.text(IrisLanguage.plain(
|
||||
RuntimeUiMessages.PREGEN_STATUS_CONTEXT,
|
||||
MessageArgument.untrusted("dimension", dimension),
|
||||
MessageArgument.untrusted("method", progress.method())
|
||||
), ModdedCommandFeedback.DARK_GREEN));
|
||||
status.append(Component.literal("\n"));
|
||||
status.append(ModdedCommandFeedback.progressBar(progress.percent(), 32));
|
||||
status.append(ModdedCommandFeedback.text(" " + String.format("%.1f", progress.percent()) + "%", ModdedCommandFeedback.USAGE));
|
||||
status.append(ModdedCommandFeedback.text(" " + IrisLanguage.plain(
|
||||
RuntimeUiMessages.PREGEN_STATUS_PROGRESS,
|
||||
MessageArgument.trusted("percent", String.format("%.1f", progress.percent()))
|
||||
), ModdedCommandFeedback.USAGE));
|
||||
status.append(Component.literal("\n"));
|
||||
status.append(ModdedCommandFeedback.text("Chunks ", ModdedCommandFeedback.DARK_GREEN));
|
||||
status.append(ModdedCommandFeedback.text(Form.f(progress.generated()) + "/" + Form.f(progress.totalChunks()), ModdedCommandFeedback.VALUE));
|
||||
status.append(ModdedCommandFeedback.text(" · Speed ", ModdedCommandFeedback.DARK_GREEN));
|
||||
status.append(ModdedCommandFeedback.text(Form.f((int) progress.chunksPerSecond()) + "/s", ModdedCommandFeedback.VALUE));
|
||||
if (progress.failed() > 0) {
|
||||
status.append(ModdedCommandFeedback.text(" · Failed ", ModdedCommandFeedback.DARK_GREEN));
|
||||
status.append(ModdedCommandFeedback.text(Form.f(progress.failed()), ModdedCommandFeedback.REQUIRED));
|
||||
}
|
||||
status.append(ModdedCommandFeedback.text(chunksStatus(progress), ModdedCommandFeedback.DARK_GREEN));
|
||||
status.append(Component.literal("\n"));
|
||||
status.append(ModdedCommandFeedback.text("ETA ", ModdedCommandFeedback.DARK_GREEN));
|
||||
status.append(ModdedCommandFeedback.text(Form.duration(progress.eta(), 2), ModdedCommandFeedback.VALUE));
|
||||
status.append(ModdedCommandFeedback.text(" · Elapsed ", ModdedCommandFeedback.DARK_GREEN));
|
||||
status.append(ModdedCommandFeedback.text(Form.duration(progress.elapsed(), 2), ModdedCommandFeedback.VALUE));
|
||||
if (progress.paused()) {
|
||||
status.append(ModdedCommandFeedback.text(" · PAUSED", ModdedCommandFeedback.REQUIRED, true, false));
|
||||
}
|
||||
status.append(ModdedCommandFeedback.text(IrisLanguage.plain(
|
||||
progress.paused()
|
||||
? RuntimeUiMessages.PREGEN_STATUS_TIME_PAUSED
|
||||
: RuntimeUiMessages.PREGEN_STATUS_TIME,
|
||||
MessageArgument.trusted("eta", Form.duration(progress.eta(), 2)),
|
||||
MessageArgument.trusted("elapsed", Form.duration(progress.elapsed(), 2))
|
||||
), ModdedCommandFeedback.DARK_GREEN));
|
||||
status.append(Component.literal("\n"));
|
||||
status.append(ModdedCommandFeedback.button("Pause/Resume", "/iris pregen pause", "Toggle pregeneration pause state", true));
|
||||
status.append(ModdedCommandFeedback.button(
|
||||
IrisLanguage.plain(RuntimeUiMessages.PREGEN_PAUSE_BUTTON),
|
||||
"/iris pregen pause",
|
||||
IrisLanguage.plain(RuntimeUiMessages.PREGEN_PAUSE_HOVER),
|
||||
true
|
||||
));
|
||||
status.append(ModdedCommandFeedback.text(" ", ModdedCommandFeedback.OPTIONAL));
|
||||
status.append(ModdedCommandFeedback.button("Stop", "/iris pregen stop", "Finish the current region and stop pregeneration", true));
|
||||
status.append(ModdedCommandFeedback.button(
|
||||
IrisLanguage.plain(RuntimeUiMessages.PREGEN_STOP_BUTTON),
|
||||
"/iris pregen stop",
|
||||
IrisLanguage.plain(RuntimeUiMessages.PREGEN_STOP_HOVER),
|
||||
true
|
||||
));
|
||||
status.append(Component.literal("\n"));
|
||||
status.append(ModdedCommandFeedback.footer());
|
||||
return status;
|
||||
}
|
||||
|
||||
private static String chunksStatus(PregeneratorJob.PregenProgress progress) {
|
||||
if (progress.failed() > 0) {
|
||||
return IrisLanguage.plain(
|
||||
RuntimeUiMessages.PREGEN_STATUS_CHUNKS_FAILED,
|
||||
MessageArgument.trusted("generated", Form.f(progress.generated())),
|
||||
MessageArgument.trusted("total", Form.f(progress.totalChunks())),
|
||||
MessageArgument.trusted("speed", Form.f((int) progress.chunksPerSecond())),
|
||||
MessageArgument.trusted("failed", Form.f(progress.failed()))
|
||||
);
|
||||
}
|
||||
return IrisLanguage.plain(
|
||||
RuntimeUiMessages.PREGEN_STATUS_CHUNKS,
|
||||
MessageArgument.trusted("generated", Form.f(progress.generated())),
|
||||
MessageArgument.trusted("total", Form.f(progress.totalChunks())),
|
||||
MessageArgument.trusted("speed", Form.f((int) progress.chunksPerSecond()))
|
||||
);
|
||||
}
|
||||
|
||||
private static ActivePregen matchingActive(String worldIdentity) {
|
||||
ActivePregen active = ACTIVE.get();
|
||||
return active != null && active.targets(worldIdentity) ? active : null;
|
||||
|
||||
+3
-1
@@ -61,6 +61,8 @@ import java.util.concurrent.Semaphore;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
import art.arcane.iris.core.localization.IrisLanguage;
|
||||
import art.arcane.iris.core.localization.ModdedCommandMessages;
|
||||
public final class ModdedRegen {
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger("Iris");
|
||||
private static final int APPLY_AHEAD = 8;
|
||||
@@ -88,7 +90,7 @@ public final class ModdedRegen {
|
||||
|
||||
public static void start(CommandSourceStack source, ServerLevel level, IrisModdedChunkGenerator generator, Engine engine, ServerPlayer player, int radius) {
|
||||
if (!ACTIVE.compareAndSet(false, true)) {
|
||||
IrisModdedCommands.fail(source, "A regen is already running.");
|
||||
IrisModdedCommands.fail(source, IrisLanguage.plain(ModdedCommandMessages.MODDED_REGEN_REGEN_IS_ALREADY_RUNNING));
|
||||
return;
|
||||
}
|
||||
int centerX = player.blockPosition().getX() >> 4;
|
||||
|
||||
+13
-11
@@ -48,6 +48,9 @@ import java.util.UUID;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
import art.arcane.iris.core.localization.IrisLanguage;
|
||||
import art.arcane.iris.core.localization.ModdedCommandMessages;
|
||||
import art.arcane.volmlib.util.localization.MessageArgument;
|
||||
public final class ModdedStructureCommands {
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger("Iris");
|
||||
private static final Predicate<CommandSourceStack> GATE = Commands.hasPermission(Commands.LEVEL_GAMEMASTERS);
|
||||
@@ -116,7 +119,7 @@ public final class ModdedStructureCommands {
|
||||
private static IrisData dataFor(CommandSourceStack source) {
|
||||
Engine engine = IrisModdedCommands.engineFor(source.getLevel());
|
||||
if (engine == null) {
|
||||
IrisModdedCommands.fail(source, "This dimension is not generated by Iris. Run this from an Iris dimension so the pack can be resolved.");
|
||||
IrisModdedCommands.fail(source, IrisLanguage.plain(ModdedCommandMessages.MODDED_STRUCTURE_COMMANDS_THIS_DIMENSION_IS_NOT_GENERATED_BY_IRIS_RUN_THIS_FROM));
|
||||
return null;
|
||||
}
|
||||
return engine.getData();
|
||||
@@ -128,7 +131,7 @@ public final class ModdedStructureCommands {
|
||||
return 0;
|
||||
}
|
||||
File file = StructureIndexService.write(data);
|
||||
IrisModdedCommands.ok(source, "Wrote structure index: " + file.getPath());
|
||||
IrisModdedCommands.ok(source, IrisLanguage.plain(ModdedCommandMessages.MODDED_STRUCTURE_COMMANDS_WROTE_STRUCTURE_INDEX, MessageArgument.untrusted("value", file.getPath())));
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -140,14 +143,14 @@ public final class ModdedStructureCommands {
|
||||
String key = keyRaw.trim();
|
||||
IrisStructure structure = data.load(IrisStructure.class, key, false);
|
||||
if (structure == null) {
|
||||
IrisModdedCommands.fail(source, "No iris structure '" + key + "' in this pack");
|
||||
IrisModdedCommands.fail(source, IrisLanguage.plain(ModdedCommandMessages.MODDED_STRUCTURE_COMMANDS_NO_IRIS_STRUCTURE_THIS_PACK, MessageArgument.untrusted("key", key)));
|
||||
return 0;
|
||||
}
|
||||
StructureAssembler assembler = StructureAssembler.forData(
|
||||
data, structure, new IrisPosition(0, 64, 0));
|
||||
KList<PlacedStructurePiece> pieces = assembler.assemble(new RNG(1234));
|
||||
if (pieces == null || pieces.isEmpty()) {
|
||||
IrisModdedCommands.fail(source, "Structure '" + key + "' assembled 0 pieces (check startPool '" + structure.getStartPool() + "')");
|
||||
IrisModdedCommands.fail(source, IrisLanguage.plain(ModdedCommandMessages.MODDED_STRUCTURE_COMMANDS_STRUCTURE_ASSEMBLED_0_PIECES_CHECK_STARTPOOL, MessageArgument.untrusted("key", key), MessageArgument.untrusted("value", structure.getStartPool())));
|
||||
return 0;
|
||||
}
|
||||
int minX = Integer.MAX_VALUE;
|
||||
@@ -160,15 +163,14 @@ public final class ModdedStructureCommands {
|
||||
maxX = Math.max(maxX, piece.getMaxX());
|
||||
maxZ = Math.max(maxZ, piece.getMaxZ());
|
||||
}
|
||||
IrisModdedCommands.ok(source, "Structure '" + key + "': " + pieces.size() + " pieces, footprint "
|
||||
+ (maxX - minX + 1) + "x" + (maxZ - minZ + 1) + " blocks (sample seed 1234)");
|
||||
IrisModdedCommands.ok(source, IrisLanguage.plain(ModdedCommandMessages.MODDED_STRUCTURE_COMMANDS_STRUCTURE_PIECES_FOOTPRINT_X_BLOCKS_SAMPLE_SEED_1234, MessageArgument.untrusted("key", key), MessageArgument.untrusted("value", pieces.size()), MessageArgument.untrusted("value2", (maxX - minX + 1)), MessageArgument.untrusted("value3", (maxZ - minZ + 1))));
|
||||
return 1;
|
||||
}
|
||||
|
||||
private static int place(CommandSourceStack source, String keyRaw) {
|
||||
ServerPlayer player = source.getPlayer();
|
||||
if (player == null) {
|
||||
IrisModdedCommands.fail(source, "This command can only be used by players (the structure is assembled at your position).");
|
||||
IrisModdedCommands.fail(source, IrisLanguage.plain(ModdedCommandMessages.MODDED_STRUCTURE_COMMANDS_THIS_COMMAND_CAN_ONLY_BE_USED_BY_PLAYERS_STRUCTURE_IS));
|
||||
return 0;
|
||||
}
|
||||
ServerLevel level = source.getLevel();
|
||||
@@ -180,7 +182,7 @@ public final class ModdedStructureCommands {
|
||||
String key = keyRaw.trim();
|
||||
IrisStructure structure = data.load(IrisStructure.class, key, false);
|
||||
if (structure == null) {
|
||||
IrisModdedCommands.fail(source, "No iris structure '" + key + "' in this pack");
|
||||
IrisModdedCommands.fail(source, IrisLanguage.plain(ModdedCommandMessages.MODDED_STRUCTURE_COMMANDS_NO_IRIS_STRUCTURE_THIS_PACK_2, MessageArgument.untrusted("key", key)));
|
||||
return 0;
|
||||
}
|
||||
int originX = player.blockPosition().getX();
|
||||
@@ -191,7 +193,7 @@ public final class ModdedStructureCommands {
|
||||
RNG rng = new RNG((long) originX * 341873128712L + originZ);
|
||||
KList<PlacedStructurePiece> pieces = assembler.assemble(rng);
|
||||
if (pieces == null || pieces.isEmpty()) {
|
||||
IrisModdedCommands.fail(source, "Structure '" + key + "' assembled 0 pieces");
|
||||
IrisModdedCommands.fail(source, IrisLanguage.plain(ModdedCommandMessages.MODDED_STRUCTURE_COMMANDS_STRUCTURE_ASSEMBLED_0_PIECES, MessageArgument.untrusted("key", key)));
|
||||
return 0;
|
||||
}
|
||||
ModdedObjectPlacer placer = new ModdedObjectPlacer(level, engine);
|
||||
@@ -210,12 +212,12 @@ public final class ModdedStructureCommands {
|
||||
} catch (Throwable e) {
|
||||
LOGGER.error("Iris structure place failed for {}", key, e);
|
||||
ModdedObjectUndo.record(owner, level, placer.undoSnapshot());
|
||||
IrisModdedCommands.fail(source, "Place failed: " + e.getClass().getSimpleName() + " (partial changes recorded for undo)");
|
||||
IrisModdedCommands.fail(source, IrisLanguage.plain(ModdedCommandMessages.MODDED_STRUCTURE_COMMANDS_PLACE_FAILED_PARTIAL_CHANGES_RECORDED_UNDO, MessageArgument.untrusted("value", e.getClass().getSimpleName())));
|
||||
return 0;
|
||||
}
|
||||
ModdedObjectUndo.record(owner, level, placer.undoSnapshot());
|
||||
String tileNote = ModdedObjectCommands.tileNote(placer);
|
||||
IrisModdedCommands.ok(source, "Placed '" + key + "' (" + pieces.size() + " pieces, " + placer.writes() + " write(s)" + tileNote + ") at your location. /iris object undo to revert.");
|
||||
IrisModdedCommands.ok(source, IrisLanguage.plain(ModdedCommandMessages.MODDED_STRUCTURE_COMMANDS_PLACED_PIECES_WRITE_S_AT_YOUR_LOCATION_IRIS_OBJECT_UNDO, MessageArgument.untrusted("key", key), MessageArgument.untrusted("value", pieces.size()), MessageArgument.untrusted("value2", placer.writes()), MessageArgument.untrusted("tileNote", tileNote)));
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
+57
-54
@@ -82,6 +82,9 @@ import java.util.function.Predicate;
|
||||
import java.util.function.Supplier;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import art.arcane.iris.core.localization.IrisLanguage;
|
||||
import art.arcane.iris.core.localization.ModdedCommandMessages;
|
||||
import art.arcane.volmlib.util.localization.MessageArgument;
|
||||
public final class ModdedStudioCommands {
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger("Iris");
|
||||
private static final Predicate<CommandSourceStack> GATE = Commands.hasPermission(Commands.LEVEL_GAMEMASTERS);
|
||||
@@ -184,7 +187,7 @@ public final class ModdedStudioCommands {
|
||||
}
|
||||
|
||||
private static int openHelp(CommandSourceStack source) {
|
||||
IrisModdedCommands.fail(source, "Provide a dimension pack: /iris studio open <pack> [seed]");
|
||||
IrisModdedCommands.fail(source, IrisLanguage.plain(ModdedCommandMessages.MODDED_STUDIO_COMMANDS_PROVIDE_DIMENSION_PACK_IRIS_STUDIO_OPEN_PACK_SEED));
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -215,22 +218,22 @@ public final class ModdedStudioCommands {
|
||||
}
|
||||
if (generatorKey == null || generatorKey.isBlank()) {
|
||||
NoiseExplorerGUI.launch();
|
||||
IrisModdedCommands.ok(source, "Opening the Noise Explorer on the server display.");
|
||||
IrisModdedCommands.ok(source, IrisLanguage.plain(ModdedCommandMessages.MODDED_STUDIO_COMMANDS_OPENING_NOISE_EXPLORER_ON_SERVER_DISPLAY));
|
||||
return 1;
|
||||
}
|
||||
if (engine == null) {
|
||||
IrisModdedCommands.fail(source, "This dimension is not generated by Iris; run /iris studio noise from an Iris dimension to resolve generators, or omit the generator name.");
|
||||
IrisModdedCommands.fail(source, IrisLanguage.plain(ModdedCommandMessages.MODDED_STUDIO_COMMANDS_THIS_DIMENSION_IS_NOT_GENERATED_BY_IRIS_RUN_IRIS_STUDIO));
|
||||
return 0;
|
||||
}
|
||||
IrisGenerator generator = engine.getData().getGeneratorLoader().load(generatorKey.trim());
|
||||
if (generator == null) {
|
||||
IrisModdedCommands.fail(source, "Unknown generator '" + generatorKey + "' in pack " + engine.getDimension().getLoadKey() + ".");
|
||||
IrisModdedCommands.fail(source, IrisLanguage.plain(ModdedCommandMessages.MODDED_STUDIO_COMMANDS_UNKNOWN_GENERATOR_PACK, MessageArgument.untrusted("generatorKey", generatorKey), MessageArgument.untrusted("value", engine.getDimension().getLoadKey())));
|
||||
return 0;
|
||||
}
|
||||
long mixedSeed = new RNG(seed).nextParallelRNG(3245).lmax();
|
||||
Supplier<Function2<Double, Double, Double>> supplier = () -> (Double x, Double z) -> generator.getHeight(x, z, mixedSeed);
|
||||
NoiseExplorerGUI.launch(supplier, generatorKey.trim());
|
||||
IrisModdedCommands.ok(source, "Opening the Noise Explorer for generator '" + generatorKey.trim() + "' (seed " + seed + ").");
|
||||
IrisModdedCommands.ok(source, IrisLanguage.plain(ModdedCommandMessages.MODDED_STUDIO_COMMANDS_OPENING_NOISE_EXPLORER_GENERATOR_SEED, MessageArgument.untrusted("value", generatorKey.trim()), MessageArgument.untrusted("seed", seed)));
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -238,7 +241,7 @@ public final class ModdedStudioCommands {
|
||||
ServerLevel level = source.getLevel();
|
||||
Engine engine = IrisModdedCommands.engineFor(level);
|
||||
if (engine == null) {
|
||||
IrisModdedCommands.fail(source, "This dimension is not generated by Iris; stand in an Iris (or studio) dimension and run /iris studio map.");
|
||||
IrisModdedCommands.fail(source, IrisLanguage.plain(ModdedCommandMessages.MODDED_STUDIO_COMMANDS_THIS_DIMENSION_IS_NOT_GENERATED_BY_IRIS_STAND_IRIS_STUDIO));
|
||||
return 0;
|
||||
}
|
||||
if (!GuiHost.isAvailable() || !IrisSettings.get().getGui().isUseServerLaunchedGuis()) {
|
||||
@@ -248,7 +251,7 @@ public final class ModdedStudioCommands {
|
||||
ServerPlayer player = source.getPlayer();
|
||||
ModdedGuiHost.bindContext(source.getServer(), level, engine, player == null ? null : player.getUUID());
|
||||
VisionGUI.launch(engine);
|
||||
IrisModdedCommands.ok(source, "Opening the Vision map for " + level.dimension().identifier() + " on the server display.");
|
||||
IrisModdedCommands.ok(source, IrisLanguage.plain(ModdedCommandMessages.MODDED_STUDIO_COMMANDS_OPENING_VISION_MAP_ON_SERVER_DISPLAY, MessageArgument.untrusted("value", level.dimension().identifier())));
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -269,10 +272,10 @@ public final class ModdedStudioCommands {
|
||||
workspace = ModdedWorkspaceGenerator.writeWorkspace(IrisData.get(folder), folder);
|
||||
} catch (IOException e) {
|
||||
LOGGER.error("Iris workspace write failed for {}", folder, e);
|
||||
IrisModdedCommands.fail(source, "Failed to write workspace for " + folder.getAbsolutePath() + ": " + e.getMessage());
|
||||
IrisModdedCommands.fail(source, IrisLanguage.plain(ModdedCommandMessages.MODDED_STUDIO_COMMANDS_FAILED_WRITE_WORKSPACE, MessageArgument.untrusted("value", folder.getAbsolutePath()), MessageArgument.untrusted("value2", String.valueOf(e.getMessage()))));
|
||||
return 0;
|
||||
}
|
||||
IrisModdedCommands.ok(source, "Workspace regenerated: " + workspace.getAbsolutePath() + " with JSON schemas for autocomplete.");
|
||||
IrisModdedCommands.ok(source, IrisLanguage.plain(ModdedCommandMessages.MODDED_STUDIO_COMMANDS_WORKSPACE_REGENERATED_WITH_JSON_SCHEMAS_AUTOCOMPLETE, MessageArgument.untrusted("value", workspace.getAbsolutePath())));
|
||||
if (!open) {
|
||||
return 1;
|
||||
}
|
||||
@@ -284,10 +287,10 @@ public final class ModdedStudioCommands {
|
||||
Desktop.getDesktop().open(workspace);
|
||||
} catch (Throwable e) {
|
||||
LOGGER.error("Iris workspace open failed for {}", workspace, e);
|
||||
IrisModdedCommands.fail(source, "Could not open " + workspace.getName() + ": " + e.getClass().getSimpleName());
|
||||
IrisModdedCommands.fail(source, IrisLanguage.plain(ModdedCommandMessages.MODDED_STUDIO_COMMANDS_COULD_NOT_OPEN, MessageArgument.untrusted("value", workspace.getName()), MessageArgument.untrusted("value2", e.getClass().getSimpleName())));
|
||||
return 0;
|
||||
}
|
||||
IrisModdedCommands.ok(source, "Opening " + workspace.getName() + " in your editor.");
|
||||
IrisModdedCommands.ok(source, IrisLanguage.plain(ModdedCommandMessages.MODDED_STUDIO_COMMANDS_OPENING_YOUR_EDITOR, MessageArgument.untrusted("value", workspace.getName())));
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -319,14 +322,14 @@ public final class ModdedStudioCommands {
|
||||
if (name == null || name.isBlank()) {
|
||||
Engine engine = IrisModdedCommands.engineFor(source.getLevel());
|
||||
if (engine == null || engine.getDimension() == null) {
|
||||
IrisModdedCommands.fail(source, "This dimension is not generated by Iris; specify a pack name explicitly.");
|
||||
IrisModdedCommands.fail(source, IrisLanguage.plain(ModdedCommandMessages.MODDED_STUDIO_COMMANDS_THIS_DIMENSION_IS_NOT_GENERATED_BY_IRIS_SPECIFY_PACK_NAME));
|
||||
return null;
|
||||
}
|
||||
name = engine.getDimension().getLoadKey();
|
||||
}
|
||||
File folder = new File(ModdedPackCommands.packsRoot(), name);
|
||||
if (!folder.isDirectory() || !new File(folder, "dimensions").isDirectory()) {
|
||||
IrisModdedCommands.fail(source, "Pack '" + name + "' not found under " + ModdedPackCommands.packsRoot().getAbsolutePath());
|
||||
IrisModdedCommands.fail(source, IrisLanguage.plain(ModdedCommandMessages.MODDED_STUDIO_COMMANDS_PACK_NOT_FOUND_UNDER, MessageArgument.untrusted("name", name), MessageArgument.untrusted("value", ModdedPackCommands.packsRoot().getAbsolutePath())));
|
||||
return null;
|
||||
}
|
||||
return folder;
|
||||
@@ -346,14 +349,14 @@ public final class ModdedStudioCommands {
|
||||
|
||||
private static int open(CommandSourceStack source, String pack, long seed) {
|
||||
if (pack == null || pack.isBlank()) {
|
||||
IrisModdedCommands.fail(source, "Provide a dimension pack: /iris studio open <pack> [seed]");
|
||||
IrisModdedCommands.fail(source, IrisLanguage.plain(ModdedCommandMessages.MODDED_STUDIO_COMMANDS_PROVIDE_DIMENSION_PACK_IRIS_STUDIO_OPEN_PACK_SEED_2));
|
||||
return 0;
|
||||
}
|
||||
ServerPlayer player = source.getPlayer();
|
||||
UUID owner = player == null ? CONSOLE_OWNER : player.getUUID();
|
||||
String dimensionId = player == null ? studioConsoleDimensionId() : studioDimensionId(player);
|
||||
MinecraftServer server = source.getServer();
|
||||
IrisModdedCommands.ok(source, "Opening studio for '" + pack + "' (seed " + seed + ")...");
|
||||
IrisModdedCommands.ok(source, IrisLanguage.plain(ModdedCommandMessages.MODDED_STUDIO_COMMANDS_OPENING_STUDIO_SEED, MessageArgument.untrusted("pack", pack), MessageArgument.untrusted("seed", seed)));
|
||||
Thread thread = new Thread(() -> openAsync(source, server, owner, dimensionId, pack, seed), "Iris Studio Open");
|
||||
thread.setDaemon(true);
|
||||
thread.start();
|
||||
@@ -364,18 +367,18 @@ public final class ModdedStudioCommands {
|
||||
try {
|
||||
File packFolder = new File(ModdedPackCommands.packsRoot(), pack);
|
||||
if (!new File(packFolder, "dimensions/" + pack + ".json").isFile()) {
|
||||
server.execute(() -> IrisModdedCommands.ok(source, "Pack '" + pack + "' missing; downloading IrisDimensions/" + pack + "..."));
|
||||
server.execute(() -> IrisModdedCommands.ok(source, IrisLanguage.plain(ModdedCommandMessages.MODDED_STUDIO_COMMANDS_PACK_MISSING_DOWNLOADING_IRISDIMENSIONS, MessageArgument.untrusted("pack", pack), MessageArgument.untrusted("pack2", pack))));
|
||||
boolean installed = ModdedPackInstaller.install(ModdedEngineBootstrap.loader().configDir(), pack, "master",
|
||||
(String line) -> server.execute(() -> IrisModdedCommands.ok(source, line)));
|
||||
if (!installed || !new File(packFolder, "dimensions/" + pack + ".json").isFile()) {
|
||||
server.execute(() -> IrisModdedCommands.fail(source, "Pack '" + pack + "' could not be downloaded; check the name and try /iris download " + pack + "."));
|
||||
server.execute(() -> IrisModdedCommands.fail(source, IrisLanguage.plain(ModdedCommandMessages.MODDED_STUDIO_COMMANDS_PACK_COULD_NOT_BE_DOWNLOADED_CHECK_NAME_TRY_IRIS_DOWNLOAD, MessageArgument.untrusted("pack", pack), MessageArgument.untrusted("pack2", pack))));
|
||||
return;
|
||||
}
|
||||
}
|
||||
IrisData data = IrisData.get(packFolder);
|
||||
IrisDimension dimension = data.getDimensionLoader().load(pack);
|
||||
if (dimension == null) {
|
||||
server.execute(() -> IrisModdedCommands.fail(source, "Pack '" + pack + "' has no dimensions/" + pack + ".json"));
|
||||
server.execute(() -> IrisModdedCommands.fail(source, IrisLanguage.plain(ModdedCommandMessages.MODDED_STUDIO_COMMANDS_PACK_HAS_NO_DIMENSIONS_JSON, MessageArgument.untrusted("pack", pack), MessageArgument.untrusted("pack2", pack))));
|
||||
return;
|
||||
}
|
||||
server.execute(() -> {
|
||||
@@ -387,7 +390,7 @@ public final class ModdedStudioCommands {
|
||||
});
|
||||
} catch (Throwable e) {
|
||||
LOGGER.error("Iris studio open failed for {}", pack, e);
|
||||
server.execute(() -> IrisModdedCommands.fail(source, "Studio open failed: " + e.getClass().getSimpleName() + (e.getMessage() == null ? "" : " - " + e.getMessage())));
|
||||
server.execute(() -> IrisModdedCommands.fail(source, IrisLanguage.plain(ModdedCommandMessages.MODDED_STUDIO_COMMANDS_STUDIO_OPEN_FAILED, MessageArgument.untrusted("value", e.getClass().getSimpleName()), MessageArgument.trusted("errorMessage", IrisLanguage.errorDetail(e)))));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -397,7 +400,7 @@ public final class ModdedStudioCommands {
|
||||
handle = ModdedDimensionManager.create(server, dimensionId, pack, pack, seed);
|
||||
} catch (Throwable e) {
|
||||
LOGGER.error("Iris console studio injection failed for {} ({})", dimensionId, pack, e);
|
||||
IrisModdedCommands.fail(source, "Studio injection failed: " + e.getClass().getSimpleName() + (e.getMessage() == null ? "" : " - " + e.getMessage()));
|
||||
IrisModdedCommands.fail(source, IrisLanguage.plain(ModdedCommandMessages.MODDED_STUDIO_COMMANDS_STUDIO_INJECTION_FAILED, MessageArgument.untrusted("value", e.getClass().getSimpleName()), MessageArgument.trusted("errorMessage", IrisLanguage.errorDetail(e))));
|
||||
return;
|
||||
}
|
||||
STUDIOS.put(CONSOLE_OWNER, dimensionId);
|
||||
@@ -411,10 +414,10 @@ public final class ModdedStudioCommands {
|
||||
} catch (Throwable e) {
|
||||
LOGGER.error("Iris console studio surface probe failed for {}", dimensionId, e);
|
||||
}
|
||||
IrisModdedCommands.ok(source, "Console studio open: " + dimensionId + " now runs '" + pack + "' seed " + seed + " (transient; not written to iris-dimensions.json and cleared on restart).");
|
||||
IrisModdedCommands.ok(source, "Enter it with: /execute in " + dimensionId + " run tp @s 8.5 " + surface + " 8.5");
|
||||
IrisModdedCommands.ok(source, "Pregen it with: /iris pregen start <radius> " + dimensionId);
|
||||
IrisModdedCommands.ok(source, "Remove it with: /iris studio close");
|
||||
IrisModdedCommands.ok(source, IrisLanguage.plain(ModdedCommandMessages.MODDED_STUDIO_COMMANDS_CONSOLE_STUDIO_OPEN_NOW_RUNS_SEED_TRANSIENT_NOT_WRITTEN_IRIS, MessageArgument.untrusted("dimensionId", dimensionId), MessageArgument.untrusted("pack", pack), MessageArgument.untrusted("seed", seed)));
|
||||
IrisModdedCommands.ok(source, IrisLanguage.plain(ModdedCommandMessages.MODDED_STUDIO_COMMANDS_ENTER_IT_WITH_EXECUTE_RUN_TP_S_8_5_8, MessageArgument.untrusted("dimensionId", dimensionId), MessageArgument.untrusted("surface", surface)));
|
||||
IrisModdedCommands.ok(source, IrisLanguage.plain(ModdedCommandMessages.MODDED_STUDIO_COMMANDS_PREGEN_IT_WITH_IRIS_PREGEN_START_RADIUS, MessageArgument.untrusted("dimensionId", dimensionId)));
|
||||
IrisModdedCommands.ok(source, IrisLanguage.plain(ModdedCommandMessages.MODDED_STUDIO_COMMANDS_REMOVE_IT_WITH_IRIS_STUDIO_CLOSE));
|
||||
}
|
||||
|
||||
private static void injectAndTeleport(CommandSourceStack source, MinecraftServer server, UUID owner, String dimensionId, String pack, long seed) {
|
||||
@@ -427,7 +430,7 @@ public final class ModdedStudioCommands {
|
||||
handle = ModdedDimensionManager.create(server, dimensionId, pack, pack, seed);
|
||||
} catch (Throwable e) {
|
||||
LOGGER.error("Iris studio injection failed for {} ({})", dimensionId, pack, e);
|
||||
IrisModdedCommands.fail(source, "Studio injection failed: " + e.getClass().getSimpleName() + (e.getMessage() == null ? "" : " - " + e.getMessage()));
|
||||
IrisModdedCommands.fail(source, IrisLanguage.plain(ModdedCommandMessages.MODDED_STUDIO_COMMANDS_STUDIO_INJECTION_FAILED_2, MessageArgument.untrusted("value", e.getClass().getSimpleName()), MessageArgument.trusted("errorMessage", IrisLanguage.errorDetail(e))));
|
||||
return;
|
||||
}
|
||||
STUDIOS.put(owner, dimensionId);
|
||||
@@ -442,7 +445,7 @@ public final class ModdedStudioCommands {
|
||||
LOGGER.error("Iris studio surface probe failed for {}", dimensionId, e);
|
||||
}
|
||||
player.teleportTo(studio, 8.5D, surface, 8.5D, java.util.Set.<Relative>of(), player.getYRot(), player.getXRot(), false);
|
||||
IrisModdedCommands.ok(source, "Studio open: " + dimensionId + " now runs '" + pack + "' seed " + seed + ". Use /iris studio close when done.");
|
||||
IrisModdedCommands.ok(source, IrisLanguage.plain(ModdedCommandMessages.MODDED_STUDIO_COMMANDS_STUDIO_OPEN_NOW_RUNS_SEED_USE_IRIS_STUDIO_CLOSE_WHEN, MessageArgument.untrusted("dimensionId", dimensionId), MessageArgument.untrusted("pack", pack), MessageArgument.untrusted("seed", seed)));
|
||||
}
|
||||
|
||||
private static int close(CommandSourceStack source) {
|
||||
@@ -451,17 +454,17 @@ public final class ModdedStudioCommands {
|
||||
UUID owner = player == null ? CONSOLE_OWNER : player.getUUID();
|
||||
String dimensionId = STUDIOS.remove(owner);
|
||||
if (dimensionId == null) {
|
||||
IrisModdedCommands.fail(source, "You do not have an open studio. Use /iris studio open <pack> first.");
|
||||
IrisModdedCommands.fail(source, IrisLanguage.plain(ModdedCommandMessages.MODDED_STUDIO_COMMANDS_YOU_DO_NOT_HAVE_OPEN_STUDIO_USE_IRIS_STUDIO_OPEN));
|
||||
return 0;
|
||||
}
|
||||
try {
|
||||
ModdedDimensionManager.remove(server, dimensionId, true);
|
||||
} catch (Throwable e) {
|
||||
LOGGER.error("Iris studio close failed for {}", dimensionId, e);
|
||||
IrisModdedCommands.fail(source, "Studio close failed: " + e.getClass().getSimpleName() + (e.getMessage() == null ? "" : " - " + e.getMessage()));
|
||||
IrisModdedCommands.fail(source, IrisLanguage.plain(ModdedCommandMessages.MODDED_STUDIO_COMMANDS_STUDIO_CLOSE_FAILED, MessageArgument.untrusted("value", e.getClass().getSimpleName()), MessageArgument.trusted("errorMessage", IrisLanguage.errorDetail(e))));
|
||||
return 0;
|
||||
}
|
||||
IrisModdedCommands.ok(source, "Studio closed: " + dimensionId + " was evacuated, unloaded and its region data deleted.");
|
||||
IrisModdedCommands.ok(source, IrisLanguage.plain(ModdedCommandMessages.MODDED_STUDIO_COMMANDS_STUDIO_CLOSED_WAS_EVACUATED_UNLOADED_ITS_REGION_DATA_DELETED, MessageArgument.untrusted("dimensionId", dimensionId)));
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -475,14 +478,14 @@ public final class ModdedStudioCommands {
|
||||
}
|
||||
}
|
||||
if (studios.isEmpty()) {
|
||||
IrisModdedCommands.ok(source, "No studio dimensions are currently open.");
|
||||
IrisModdedCommands.ok(source, IrisLanguage.plain(ModdedCommandMessages.MODDED_STUDIO_COMMANDS_NO_STUDIO_DIMENSIONS_ARE_CURRENTLY_OPEN));
|
||||
return 1;
|
||||
}
|
||||
IrisModdedCommands.ok(source, "Active studio dimension(s): " + studios.size());
|
||||
IrisModdedCommands.ok(source, IrisLanguage.plain(ModdedCommandMessages.MODDED_STUDIO_COMMANDS_ACTIVE_STUDIO_DIMENSION_S, MessageArgument.untrusted("value", studios.size())));
|
||||
for (ModdedDimensionManager.Handle handle : studios) {
|
||||
UUID owner = ownerOf(handle.dimensionId());
|
||||
String ownerName = owner == null ? "unclaimed" : ownerName(server, owner);
|
||||
IrisModdedCommands.ok(source, " " + handle.dimensionId() + ": pack '" + handle.pack() + "' seed " + handle.seed() + " owner " + ownerName);
|
||||
IrisModdedCommands.ok(source, IrisLanguage.plain(ModdedCommandMessages.MODDED_STUDIO_COMMANDS_PACK_SEED_OWNER, MessageArgument.untrusted("value", handle.dimensionId()), MessageArgument.untrusted("value2", handle.pack()), MessageArgument.untrusted("value3", handle.seed()), MessageArgument.untrusted("ownerName", ownerName)));
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
@@ -507,19 +510,19 @@ public final class ModdedStudioCommands {
|
||||
private static int tpStudio(CommandSourceStack source) {
|
||||
ServerPlayer player = source.getPlayer();
|
||||
if (player == null) {
|
||||
IrisModdedCommands.fail(source, "This command can only be used by players.");
|
||||
IrisModdedCommands.fail(source, IrisLanguage.plain(ModdedCommandMessages.MODDED_STUDIO_COMMANDS_THIS_COMMAND_CAN_ONLY_BE_USED_BY_PLAYERS));
|
||||
return 0;
|
||||
}
|
||||
MinecraftServer server = source.getServer();
|
||||
String dimensionId = STUDIOS.get(player.getUUID());
|
||||
if (dimensionId == null) {
|
||||
IrisModdedCommands.fail(source, "You do not have an open studio. Use /iris studio open <pack> first.");
|
||||
IrisModdedCommands.fail(source, IrisLanguage.plain(ModdedCommandMessages.MODDED_STUDIO_COMMANDS_YOU_DO_NOT_HAVE_OPEN_STUDIO_USE_IRIS_STUDIO_OPEN_2));
|
||||
return 0;
|
||||
}
|
||||
ServerLevel studio = ModdedDimensionManager.level(server, dimensionId);
|
||||
if (studio == null) {
|
||||
STUDIOS.remove(player.getUUID());
|
||||
IrisModdedCommands.fail(source, "Your studio dimension is no longer loaded. Use /iris studio open <pack> again.");
|
||||
IrisModdedCommands.fail(source, IrisLanguage.plain(ModdedCommandMessages.MODDED_STUDIO_COMMANDS_YOUR_STUDIO_DIMENSION_IS_NO_LONGER_LOADED_USE_IRIS_STUDIO));
|
||||
return 0;
|
||||
}
|
||||
int surface = studio.getMaxY();
|
||||
@@ -532,7 +535,7 @@ public final class ModdedStudioCommands {
|
||||
LOGGER.error("Iris tpstudio surface probe failed", e);
|
||||
}
|
||||
player.teleportTo(studio, 8.5D, surface, 8.5D, java.util.Set.<Relative>of(), player.getYRot(), player.getXRot(), false);
|
||||
IrisModdedCommands.ok(source, "Teleported to your studio (" + dimensionId + ").");
|
||||
IrisModdedCommands.ok(source, IrisLanguage.plain(ModdedCommandMessages.MODDED_STUDIO_COMMANDS_TELEPORTED_YOUR_STUDIO, MessageArgument.untrusted("dimensionId", dimensionId)));
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -544,36 +547,36 @@ public final class ModdedStudioCommands {
|
||||
IrisData data = IrisData.get(folder);
|
||||
IrisDimension dimension = data.getDimensionLoader().load(folder.getName());
|
||||
if (dimension == null) {
|
||||
IrisModdedCommands.fail(source, "Pack '" + folder.getName() + "' has no dimensions/" + folder.getName() + ".json");
|
||||
IrisModdedCommands.fail(source, IrisLanguage.plain(ModdedCommandMessages.MODDED_STUDIO_COMMANDS_PACK_HAS_NO_DIMENSIONS_JSON_2, MessageArgument.untrusted("value", folder.getName()), MessageArgument.untrusted("value2", folder.getName())));
|
||||
return 0;
|
||||
}
|
||||
IrisModdedCommands.ok(source, "The \"" + dimension.getName() + "\" pack has version: " + dimension.getVersion());
|
||||
IrisModdedCommands.ok(source, IrisLanguage.plain(ModdedCommandMessages.MODDED_STUDIO_COMMANDS_PACK_HAS_VERSION, MessageArgument.untrusted("value", dimension.getName()), MessageArgument.untrusted("value2", dimension.getVersion())));
|
||||
return 1;
|
||||
}
|
||||
|
||||
private static int create(CommandSourceStack source, String nameRaw, String template) {
|
||||
String name = nameRaw.toLowerCase(Locale.ROOT);
|
||||
if (!PROJECT_NAME.matcher(name).matches()) {
|
||||
IrisModdedCommands.fail(source, "Invalid project name '" + nameRaw + "' (allowed: a-z, 0-9, _ and -)");
|
||||
IrisModdedCommands.fail(source, IrisLanguage.plain(ModdedCommandMessages.MODDED_STUDIO_COMMANDS_INVALID_PROJECT_NAME_ALLOWED_Z_0_9, MessageArgument.untrusted("nameRaw", nameRaw)));
|
||||
return 0;
|
||||
}
|
||||
File packsRoot = ModdedPackCommands.packsRoot();
|
||||
File target = new File(packsRoot, name);
|
||||
if (target.exists()) {
|
||||
IrisModdedCommands.fail(source, "Pack '" + name + "' already exists at " + target.getAbsolutePath());
|
||||
IrisModdedCommands.fail(source, IrisLanguage.plain(ModdedCommandMessages.MODDED_STUDIO_COMMANDS_PACK_ALREADY_EXISTS_AT, MessageArgument.untrusted("name", name), MessageArgument.untrusted("value", target.getAbsolutePath())));
|
||||
return 0;
|
||||
}
|
||||
MinecraftServer server = source.getServer();
|
||||
IrisModdedCommands.ok(source, "Creating project '" + name + "' from template '" + template + "'...");
|
||||
IrisModdedCommands.ok(source, IrisLanguage.plain(ModdedCommandMessages.MODDED_STUDIO_COMMANDS_CREATING_PROJECT_FROM_TEMPLATE, MessageArgument.untrusted("name", name), MessageArgument.untrusted("template", template)));
|
||||
Thread thread = new Thread(() -> {
|
||||
try {
|
||||
File templateFolder = new File(packsRoot, template);
|
||||
if (!new File(templateFolder, "dimensions/" + template + ".json").isFile()) {
|
||||
server.execute(() -> IrisModdedCommands.ok(source, "Template '" + template + "' is not installed; downloading IrisDimensions/" + template + "..."));
|
||||
server.execute(() -> IrisModdedCommands.ok(source, IrisLanguage.plain(ModdedCommandMessages.MODDED_STUDIO_COMMANDS_TEMPLATE_IS_NOT_INSTALLED_DOWNLOADING_IRISDIMENSIONS, MessageArgument.untrusted("template", template), MessageArgument.untrusted("template2", template))));
|
||||
boolean installed = ModdedPackInstaller.install(ModdedEngineBootstrap.loader().configDir(), template, "master",
|
||||
(String line) -> server.execute(() -> IrisModdedCommands.ok(source, line)));
|
||||
if (!installed || !new File(templateFolder, "dimensions/" + template + ".json").isFile()) {
|
||||
server.execute(() -> IrisModdedCommands.fail(source, "Template '" + template + "' could not be downloaded; install a pack with dimensions/" + template + ".json first."));
|
||||
server.execute(() -> IrisModdedCommands.fail(source, IrisLanguage.plain(ModdedCommandMessages.MODDED_STUDIO_COMMANDS_TEMPLATE_COULD_NOT_BE_DOWNLOADED_INSTALL_PACK_WITH_DIMENSIONS_JSON, MessageArgument.untrusted("template", template), MessageArgument.untrusted("template2", template))));
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -584,12 +587,12 @@ public final class ModdedStudioCommands {
|
||||
LOGGER.error("Iris studio create workspace generation failed for {}", name, e);
|
||||
}
|
||||
server.execute(() -> {
|
||||
IrisModdedCommands.ok(source, "Created project '" + name + "' at " + target.getAbsolutePath());
|
||||
IrisModdedCommands.ok(source, "Edit dimensions/" + name + ".json and the rest of the pack. A VSCode workspace with JSON schema autocomplete was generated; open it or rerun /iris studio vscode.");
|
||||
IrisModdedCommands.ok(source, IrisLanguage.plain(ModdedCommandMessages.MODDED_STUDIO_COMMANDS_CREATED_PROJECT_AT, MessageArgument.untrusted("name", name), MessageArgument.untrusted("value", target.getAbsolutePath())));
|
||||
IrisModdedCommands.ok(source, IrisLanguage.plain(ModdedCommandMessages.MODDED_STUDIO_COMMANDS_EDIT_DIMENSIONS_JSON_REST_PACK_VSCODE_WORKSPACE_WITH_JSON_SCHEMA, MessageArgument.untrusted("name", name)));
|
||||
});
|
||||
} catch (Throwable e) {
|
||||
LOGGER.error("Iris studio create failed for {}", name, e);
|
||||
server.execute(() -> IrisModdedCommands.fail(source, "Project creation failed: " + e.getClass().getSimpleName() + (e.getMessage() == null ? "" : " - " + e.getMessage())));
|
||||
server.execute(() -> IrisModdedCommands.fail(source, IrisLanguage.plain(ModdedCommandMessages.MODDED_STUDIO_COMMANDS_PROJECT_CREATION_FAILED, MessageArgument.untrusted("value", e.getClass().getSimpleName()), MessageArgument.trusted("errorMessage", IrisLanguage.errorDetail(e)))));
|
||||
}
|
||||
}, "Iris Studio Create");
|
||||
thread.setDaemon(true);
|
||||
@@ -604,14 +607,14 @@ public final class ModdedStudioCommands {
|
||||
}
|
||||
MinecraftServer server = source.getServer();
|
||||
String dimKey = folder.getName();
|
||||
IrisModdedCommands.ok(source, "Packaging dimension '" + dimKey + "'...");
|
||||
IrisModdedCommands.ok(source, IrisLanguage.plain(ModdedCommandMessages.MODDED_STUDIO_COMMANDS_PACKAGING_DIMENSION, MessageArgument.untrusted("dimKey", dimKey)));
|
||||
Thread thread = new Thread(() -> {
|
||||
try {
|
||||
File result = compilePackage(folder, dimKey);
|
||||
server.execute(() -> IrisModdedCommands.ok(source, "Package compiled: " + result.getAbsolutePath()));
|
||||
server.execute(() -> IrisModdedCommands.ok(source, IrisLanguage.plain(ModdedCommandMessages.MODDED_STUDIO_COMMANDS_PACKAGE_COMPILED, MessageArgument.untrusted("value", result.getAbsolutePath()))));
|
||||
} catch (Throwable e) {
|
||||
LOGGER.error("Iris package failed for {}", dimKey, e);
|
||||
server.execute(() -> IrisModdedCommands.fail(source, "Packaging failed: " + e.getClass().getSimpleName() + (e.getMessage() == null ? "" : " - " + e.getMessage())));
|
||||
server.execute(() -> IrisModdedCommands.fail(source, IrisLanguage.plain(ModdedCommandMessages.MODDED_STUDIO_COMMANDS_PACKAGING_FAILED, MessageArgument.untrusted("value", e.getClass().getSimpleName()), MessageArgument.trusted("errorMessage", IrisLanguage.errorDetail(e)))));
|
||||
}
|
||||
}, "Iris Studio Package");
|
||||
thread.setDaemon(true);
|
||||
@@ -758,18 +761,18 @@ public final class ModdedStudioCommands {
|
||||
private static int regions(CommandSourceStack source, int radius) {
|
||||
ServerPlayer player = source.getPlayer();
|
||||
if (player == null) {
|
||||
IrisModdedCommands.fail(source, "This command can only be used by players (sampling is centered on your position).");
|
||||
IrisModdedCommands.fail(source, IrisLanguage.plain(ModdedCommandMessages.MODDED_STUDIO_COMMANDS_THIS_COMMAND_CAN_ONLY_BE_USED_BY_PLAYERS_SAMPLING_IS));
|
||||
return 0;
|
||||
}
|
||||
Engine engine = IrisModdedCommands.engineFor(source.getLevel());
|
||||
if (engine == null) {
|
||||
IrisModdedCommands.fail(source, "This dimension is not generated by Iris.");
|
||||
IrisModdedCommands.fail(source, IrisLanguage.plain(ModdedCommandMessages.MODDED_STUDIO_COMMANDS_THIS_DIMENSION_IS_NOT_GENERATED_BY_IRIS));
|
||||
return 0;
|
||||
}
|
||||
MinecraftServer server = source.getServer();
|
||||
int blockX = player.blockPosition().getX();
|
||||
int blockZ = player.blockPosition().getZ();
|
||||
IrisModdedCommands.ok(source, "Sampling region distribution in " + (radius * 2) + "x" + (radius * 2) + " chunks around you...");
|
||||
IrisModdedCommands.ok(source, IrisLanguage.plain(ModdedCommandMessages.MODDED_STUDIO_COMMANDS_SAMPLING_REGION_DISTRIBUTION_X_CHUNKS_AROUND_YOU, MessageArgument.untrusted("value", (radius * 2)), MessageArgument.untrusted("value2", (radius * 2))));
|
||||
Thread thread = new Thread(() -> {
|
||||
try {
|
||||
int diameter = radius * 2;
|
||||
@@ -787,11 +790,11 @@ public final class ModdedStudioCommands {
|
||||
server.execute(() -> counts.forEach((String key, AtomicInteger count) -> {
|
||||
IrisRegion region = engine.getData().getRegionLoader().load(key);
|
||||
String rarity = region == null ? "?" : String.valueOf(region.getRarity());
|
||||
IrisModdedCommands.ok(source, key + ": rarity=" + rarity + " / " + Form.f((double) count.get() / totalTasks * 100, 2) + "%");
|
||||
IrisModdedCommands.ok(source, IrisLanguage.plain(ModdedCommandMessages.MODDED_STUDIO_COMMANDS_RARITY, MessageArgument.untrusted("key", key), MessageArgument.untrusted("rarity", rarity), MessageArgument.untrusted("value", Form.f((double) count.get() / totalTasks * 100, 2))));
|
||||
}));
|
||||
} catch (Throwable e) {
|
||||
LOGGER.error("Iris region sampling failed", e);
|
||||
server.execute(() -> IrisModdedCommands.fail(source, "Region sampling failed: " + e.getClass().getSimpleName()));
|
||||
server.execute(() -> IrisModdedCommands.fail(source, IrisLanguage.plain(ModdedCommandMessages.MODDED_STUDIO_COMMANDS_REGION_SAMPLING_FAILED, MessageArgument.untrusted("value", e.getClass().getSimpleName()))));
|
||||
}
|
||||
}, "Iris Region Sampler");
|
||||
thread.setDaemon(true);
|
||||
|
||||
+15
-6
@@ -18,6 +18,9 @@
|
||||
|
||||
package art.arcane.iris.modded.command;
|
||||
|
||||
import art.arcane.iris.core.localization.IrisLanguage;
|
||||
import art.arcane.iris.core.localization.RuntimeUiMessages;
|
||||
import art.arcane.volmlib.util.localization.MessageArgument;
|
||||
import net.minecraft.ChatFormatting;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.component.DataComponents;
|
||||
@@ -78,10 +81,10 @@ public final class ModdedWandService {
|
||||
|
||||
public static ItemStack createWand() {
|
||||
ItemStack stack = new ItemStack(Items.BLAZE_ROD);
|
||||
stack.set(DataComponents.CUSTOM_NAME, Component.literal("Wand of Iris").withStyle(ChatFormatting.BOLD, ChatFormatting.GOLD));
|
||||
stack.set(DataComponents.CUSTOM_NAME, Component.literal(IrisLanguage.plain(RuntimeUiMessages.WAND_NAME)).withStyle(ChatFormatting.BOLD, ChatFormatting.GOLD));
|
||||
stack.set(DataComponents.LORE, new ItemLore(List.of(
|
||||
Component.literal("Left click a block to set the first corner"),
|
||||
Component.literal("Right click a block to set the second corner"))));
|
||||
Component.literal(IrisLanguage.plain(RuntimeUiMessages.WAND_LORE_FIRST)),
|
||||
Component.literal(IrisLanguage.plain(RuntimeUiMessages.WAND_LORE_SECOND)))));
|
||||
stack.set(DataComponents.UNBREAKABLE, Unit.INSTANCE);
|
||||
stack.set(DataComponents.ENCHANTMENT_GLINT_OVERRIDE, Boolean.TRUE);
|
||||
stack.set(DataComponents.CUSTOM_DATA, CustomData.of(flagTag(WAND_TAG)));
|
||||
@@ -90,9 +93,9 @@ public final class ModdedWandService {
|
||||
|
||||
public static ItemStack createDust() {
|
||||
ItemStack stack = new ItemStack(Items.GLOWSTONE_DUST);
|
||||
stack.set(DataComponents.CUSTOM_NAME, Component.literal("Dust of Revealing").withStyle(ChatFormatting.BOLD, ChatFormatting.YELLOW));
|
||||
stack.set(DataComponents.CUSTOM_NAME, Component.literal(IrisLanguage.plain(RuntimeUiMessages.DUST_NAME)).withStyle(ChatFormatting.BOLD, ChatFormatting.YELLOW));
|
||||
stack.set(DataComponents.LORE, new ItemLore(List.of(
|
||||
Component.literal("Right click on a block to reveal it's placement structure!"))));
|
||||
Component.literal(IrisLanguage.plain(RuntimeUiMessages.DUST_LORE)))));
|
||||
stack.set(DataComponents.UNBREAKABLE, Unit.INSTANCE);
|
||||
stack.set(DataComponents.ENCHANTMENT_GLINT_OVERRIDE, Boolean.TRUE);
|
||||
stack.set(DataComponents.CUSTOM_DATA, CustomData.of(flagTag(DUST_TAG)));
|
||||
@@ -161,7 +164,13 @@ public final class ModdedWandService {
|
||||
return first ? new Selection(dimension, corner, other) : new Selection(dimension, other, corner);
|
||||
});
|
||||
level.playSound(null, pos, SoundEvents.END_PORTAL_FRAME_FILL, SoundSource.PLAYERS, 1.0F, first ? 0.67F : 1.17F);
|
||||
player.sendOverlayMessage(Component.literal("Position " + (first ? 1 : 2) + " set to " + corner.getX() + ", " + corner.getY() + ", " + corner.getZ()));
|
||||
player.sendOverlayMessage(Component.literal(IrisLanguage.plain(
|
||||
RuntimeUiMessages.WAND_POSITION_SET,
|
||||
MessageArgument.trusted("position", first ? 1 : 2),
|
||||
MessageArgument.trusted("x", corner.getX()),
|
||||
MessageArgument.trusted("y", corner.getY()),
|
||||
MessageArgument.trusted("z", corner.getZ())
|
||||
)));
|
||||
}
|
||||
|
||||
public static Selection selection(ServerPlayer player) {
|
||||
|
||||
+43
-40
@@ -51,6 +51,10 @@ import java.util.Locale;
|
||||
import java.util.concurrent.ThreadLocalRandom;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
import art.arcane.iris.core.localization.IrisLanguage;
|
||||
import art.arcane.iris.core.localization.ModdedCommandMessages;
|
||||
import art.arcane.iris.core.localization.RuntimeUiMessages;
|
||||
import art.arcane.volmlib.util.localization.MessageArgument;
|
||||
public final class ModdedWorldCommands {
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger("Iris");
|
||||
private static final Predicate<CommandSourceStack> GATE = Commands.hasPermission(Commands.LEVEL_GAMEMASTERS);
|
||||
@@ -169,13 +173,13 @@ public final class ModdedWorldCommands {
|
||||
if (packFolder.isDirectory()) {
|
||||
return enableInstalled(source, server, dimensionId, pack, packDimension, seed);
|
||||
}
|
||||
IrisModdedCommands.ok(source, "Pack '" + pack + "' is not installed; downloading IrisDimensions/" + pack + "...");
|
||||
IrisModdedCommands.ok(source, IrisLanguage.plain(ModdedCommandMessages.MODDED_WORLD_COMMANDS_PACK_IS_NOT_INSTALLED_DOWNLOADING_IRISDIMENSIONS, MessageArgument.untrusted("pack", pack), MessageArgument.untrusted("pack2", pack)));
|
||||
Thread thread = new Thread(() -> {
|
||||
boolean installed = ModdedPackInstaller.install(ModdedEngineBootstrap.loader().configDir(), pack, "master",
|
||||
(String line) -> server.execute(() -> IrisModdedCommands.ok(source, line)));
|
||||
server.execute(() -> {
|
||||
if (!installed || !packFolder.isDirectory()) {
|
||||
IrisModdedCommands.fail(source, "Pack '" + pack + "' could not be downloaded; check the name or install it with /iris download " + pack + ".");
|
||||
IrisModdedCommands.fail(source, IrisLanguage.plain(ModdedCommandMessages.MODDED_WORLD_COMMANDS_PACK_COULD_NOT_BE_DOWNLOADED_CHECK_NAME_INSTALL_IT_WITH, MessageArgument.untrusted("pack", pack), MessageArgument.untrusted("pack2", pack)));
|
||||
return;
|
||||
}
|
||||
enableInstalled(source, server, dimensionId, pack, packDimension, seed);
|
||||
@@ -197,11 +201,11 @@ public final class ModdedWorldCommands {
|
||||
ModdedDimensionManager.createPersistent(server, dimensionId, pack, packDimension, seed);
|
||||
} catch (Throwable e) {
|
||||
LOGGER.error("Iris world injection failed for {} (pack={} dim={})", dimensionId, pack, packDimension, e);
|
||||
IrisModdedCommands.fail(source, "Failed to inject Iris world '" + dimensionId + "': " + e.getClass().getSimpleName() + (e.getMessage() == null ? "" : " - " + e.getMessage()));
|
||||
IrisModdedCommands.fail(source, IrisLanguage.plain(ModdedCommandMessages.MODDED_WORLD_COMMANDS_FAILED_INJECT_IRIS_WORLD, MessageArgument.untrusted("dimensionId", dimensionId), MessageArgument.untrusted("value", e.getClass().getSimpleName()), MessageArgument.trusted("errorMessage", IrisLanguage.errorDetail(e))));
|
||||
return 0;
|
||||
}
|
||||
IrisModdedCommands.ok(source, "Created Iris world " + dimensionId + " from pack '" + pack + "' dimension '" + packDimension + "' (seed " + seed + ").");
|
||||
IrisModdedCommands.ok(source, "It is live now and re-injected on every startup. Teleport in with /iris world status or a portal; no restart required.");
|
||||
IrisModdedCommands.ok(source, IrisLanguage.plain(ModdedCommandMessages.MODDED_WORLD_COMMANDS_CREATED_IRIS_WORLD_FROM_PACK_DIMENSION_SEED, MessageArgument.untrusted("dimensionId", dimensionId), MessageArgument.untrusted("pack", pack), MessageArgument.untrusted("packDimension", packDimension), MessageArgument.untrusted("seed", seed)));
|
||||
IrisModdedCommands.ok(source, IrisLanguage.plain(ModdedCommandMessages.MODDED_WORLD_COMMANDS_IT_IS_LIVE_NOW_RE_INJECTED_ON_EVERY_STARTUP_TELEPORT));
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -228,21 +232,21 @@ public final class ModdedWorldCommands {
|
||||
ModdedDimensionManager.createPersistent(server, dimensionId, pack, packDimension, seed);
|
||||
} catch (Throwable e) {
|
||||
LOGGER.error("Iris primary world injection failed for {} (pack={} dim={})", dimensionId, pack, packDimension, e);
|
||||
IrisModdedCommands.fail(source, "Failed to inject Iris primary world: " + e.getClass().getSimpleName() + (e.getMessage() == null ? "" : " - " + e.getMessage()));
|
||||
IrisModdedCommands.fail(source, IrisLanguage.plain(ModdedCommandMessages.MODDED_WORLD_COMMANDS_FAILED_INJECT_IRIS_PRIMARY_WORLD, MessageArgument.untrusted("value", e.getClass().getSimpleName()), MessageArgument.trusted("errorMessage", IrisLanguage.errorDetail(e))));
|
||||
return 0;
|
||||
}
|
||||
ModdedModConfig.setPrimaryWorld(dimensionId);
|
||||
ModdedPrimaryWorldRouter.clear();
|
||||
IrisModdedCommands.ok(source, "Iris primary world set to " + dimensionId + " (pack '" + pack + "' dimension '" + packDimension + "' seed " + seed + ").");
|
||||
IrisModdedCommands.ok(source, "The vanilla overworld generator cannot be hot-swapped, so this does NOT regenerate the existing overworld.");
|
||||
IrisModdedCommands.ok(source, "Instead, " + dimensionId + " is now the configured primary world: players in the vanilla overworld are routed there on join, and it re-injects on every startup.");
|
||||
IrisModdedCommands.ok(source, IrisLanguage.plain(ModdedCommandMessages.MODDED_WORLD_COMMANDS_IRIS_PRIMARY_WORLD_SET_PACK_DIMENSION_SEED, MessageArgument.untrusted("dimensionId", dimensionId), MessageArgument.untrusted("pack", pack), MessageArgument.untrusted("packDimension", packDimension), MessageArgument.untrusted("seed", seed)));
|
||||
IrisModdedCommands.ok(source, IrisLanguage.plain(ModdedCommandMessages.MODDED_WORLD_COMMANDS_VANILLA_OVERWORLD_GENERATOR_CANNOT_BE_HOT_SWAPPED_SO_THIS_DOES));
|
||||
IrisModdedCommands.ok(source, IrisLanguage.plain(ModdedCommandMessages.MODDED_WORLD_COMMANDS_INSTEAD_IS_NOW_CONFIGURED_PRIMARY_WORLD_PLAYERS_VANILLA_OVERWORLD_ARE, MessageArgument.untrusted("dimensionId", dimensionId)));
|
||||
return 1;
|
||||
}
|
||||
|
||||
private static int clearMainWorld(CommandSourceStack source) {
|
||||
ModdedModConfig.setMainWorld("", 0L);
|
||||
MainWorldService.clearOverride();
|
||||
IrisModdedCommands.ok(source, "Iris main world override cleared. The overworld keeps its current generator; edit server.properties level-type and restart to change it back.");
|
||||
IrisModdedCommands.ok(source, IrisLanguage.plain(ModdedCommandMessages.MODDED_WORLD_COMMANDS_IRIS_MAIN_WORLD_OVERRIDE_CLEARED_OVERWORLD_KEEPS_ITS_CURRENT_GENERATOR));
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -258,7 +262,7 @@ public final class ModdedWorldCommands {
|
||||
try {
|
||||
seed = Long.parseLong(seedRaw.trim());
|
||||
} catch (NumberFormatException e) {
|
||||
IrisModdedCommands.fail(source, "Invalid seed '" + seedRaw + "'. Use a number or 'random'.");
|
||||
IrisModdedCommands.fail(source, IrisLanguage.plain(ModdedCommandMessages.MODDED_WORLD_COMMANDS_INVALID_SEED_USE_NUMBER_RANDOM, MessageArgument.untrusted("seedRaw", seedRaw)));
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@@ -272,13 +276,13 @@ public final class ModdedWorldCommands {
|
||||
if (packFolder.isDirectory()) {
|
||||
return applyMainWorld(source, pack, packDimension, packRaw, seed);
|
||||
}
|
||||
IrisModdedCommands.ok(source, "Pack '" + pack + "' is not installed; downloading IrisDimensions/" + pack + "...");
|
||||
IrisModdedCommands.ok(source, IrisLanguage.plain(ModdedCommandMessages.MODDED_WORLD_COMMANDS_PACK_IS_NOT_INSTALLED_DOWNLOADING_IRISDIMENSIONS_2, MessageArgument.untrusted("pack", pack), MessageArgument.untrusted("pack2", pack)));
|
||||
Thread thread = new Thread(() -> {
|
||||
boolean installed = ModdedPackInstaller.install(ModdedEngineBootstrap.loader().configDir(), pack, "master",
|
||||
(String line) -> server.execute(() -> IrisModdedCommands.ok(source, line)));
|
||||
server.execute(() -> {
|
||||
if (!installed || !packFolder.isDirectory()) {
|
||||
IrisModdedCommands.fail(source, "Pack '" + pack + "' could not be downloaded; check the name or install it with /iris download " + pack + ".");
|
||||
IrisModdedCommands.fail(source, IrisLanguage.plain(ModdedCommandMessages.MODDED_WORLD_COMMANDS_PACK_COULD_NOT_BE_DOWNLOADED_CHECK_NAME_INSTALL_IT_WITH_2, MessageArgument.untrusted("pack", pack), MessageArgument.untrusted("pack2", pack)));
|
||||
return;
|
||||
}
|
||||
applyMainWorld(source, pack, packDimension, packRaw, seed);
|
||||
@@ -299,23 +303,23 @@ public final class ModdedWorldCommands {
|
||||
}
|
||||
} catch (Throwable e) {
|
||||
LOGGER.error("Iris main world pack load failed for {} (dim={})", pack, packDimension, e);
|
||||
IrisModdedCommands.fail(source, "Pack '" + pack + "' is not ready yet (still loading or validating). Try the command again in a moment.");
|
||||
IrisModdedCommands.fail(source, IrisLanguage.plain(ModdedCommandMessages.MODDED_WORLD_COMMANDS_PACK_IS_NOT_READY_YET_STILL_LOADING_VALIDATING_TRY_COMMAND, MessageArgument.untrusted("pack", pack)));
|
||||
return 0;
|
||||
}
|
||||
ModdedModConfig.setMainWorld(packRef, seed);
|
||||
if (!MainWorldService.stage(packRef, seed)) {
|
||||
IrisModdedCommands.fail(source, "Failed to write server.properties; check file permissions and set level-type manually.");
|
||||
IrisModdedCommands.fail(source, IrisLanguage.plain(ModdedCommandMessages.MODDED_WORLD_COMMANDS_FAILED_WRITE_SERVER_PROPERTIES_CHECK_FILE_PERMISSIONS_SET_LEVEL_TYPE));
|
||||
return 0;
|
||||
}
|
||||
String preset = MainWorldService.presetIdFor(packRef);
|
||||
IrisModdedCommands.ok(source, "Iris main world set to '" + pack + "' (preset " + preset + ", seed " + (seed == 0L ? "random" : Long.toString(seed)) + ").");
|
||||
IrisModdedCommands.ok(source, "server.properties level-type is now " + preset + ". On the next restart the overworld, nether, and end regenerate as this Iris world.");
|
||||
IrisModdedCommands.ok(source, "Player data (inventories, advancements, stats) is kept; existing terrain in those dimensions is replaced. This applies once.");
|
||||
IrisModdedCommands.ok(source, IrisLanguage.plain(ModdedCommandMessages.MODDED_WORLD_COMMANDS_IRIS_MAIN_WORLD_SET_PRESET_SEED, MessageArgument.untrusted("pack", pack), MessageArgument.untrusted("preset", preset), MessageArgument.untrusted("value", seed == 0L ? IrisLanguage.plain(RuntimeUiMessages.STATUS_RANDOM) : Long.toString(seed))));
|
||||
IrisModdedCommands.ok(source, IrisLanguage.plain(ModdedCommandMessages.MODDED_WORLD_COMMANDS_SERVER_PROPERTIES_LEVEL_TYPE_IS_NOW_ON_NEXT_RESTART_OVERWORLD, MessageArgument.untrusted("preset", preset)));
|
||||
IrisModdedCommands.ok(source, IrisLanguage.plain(ModdedCommandMessages.MODDED_WORLD_COMMANDS_PLAYER_DATA_INVENTORIES_ADVANCEMENTS_STATS_IS_KEPT_EXISTING_TERRAIN_THOSE));
|
||||
if (ModdedModConfig.get().mainWorldAutoRestart()) {
|
||||
IrisModdedCommands.ok(source, "mainWorldAutoRestart is enabled - stopping the server now so your restart wrapper brings it back on the new main world.");
|
||||
IrisModdedCommands.ok(source, IrisLanguage.plain(ModdedCommandMessages.MODDED_WORLD_COMMANDS_MAINWORLDAUTORESTART_IS_ENABLED_STOPPING_SERVER_NOW_SO_YOUR_RESTART_WRAPPER));
|
||||
source.getServer().halt(false);
|
||||
} else {
|
||||
IrisModdedCommands.ok(source, "Restart the server now to generate it. (Set mainWorldAutoRestart=true in modded.json to have Iris stop the server for you.)");
|
||||
IrisModdedCommands.ok(source, IrisLanguage.plain(ModdedCommandMessages.MODDED_WORLD_COMMANDS_RESTART_SERVER_NOW_GENERATE_IT_SET_MAINWORLDAUTORESTART_TRUE_MODDED_JSON));
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
@@ -325,12 +329,11 @@ public final class ModdedWorldCommands {
|
||||
ModdedStartup.requirePackForWorldCreation(pack);
|
||||
return false;
|
||||
} catch (BrokenPackException e) {
|
||||
IrisModdedCommands.fail(source, "Refusing to create world '" + dimensionId
|
||||
+ "' using pack '" + pack + "' because required validation failed:");
|
||||
IrisModdedCommands.fail(source, IrisLanguage.plain(ModdedCommandMessages.MODDED_WORLD_COMMANDS_REFUSING_CREATE_WORLD_USING_PACK_BECAUSE_REQUIRED_VALIDATION_FAILED, MessageArgument.untrusted("dimensionId", dimensionId), MessageArgument.untrusted("pack", pack)));
|
||||
for (String reason : e.getReasons()) {
|
||||
IrisModdedCommands.fail(source, " - " + reason);
|
||||
IrisModdedCommands.fail(source, IrisLanguage.plain(ModdedCommandMessages.MODDED_WORLD_COMMANDS_MESSAGE, MessageArgument.untrusted("reason", reason)));
|
||||
}
|
||||
IrisModdedCommands.fail(source, "Fix the pack and run /iris pack validate " + pack + " to revalidate.");
|
||||
IrisModdedCommands.fail(source, IrisLanguage.plain(ModdedCommandMessages.MODDED_WORLD_COMMANDS_FIX_PACK_RUN_IRIS_PACK_VALIDATE_REVALIDATE, MessageArgument.untrusted("pack", pack)));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -338,13 +341,13 @@ public final class ModdedWorldCommands {
|
||||
private static boolean loadPackDimension(CommandSourceStack source, String pack, String packDimension) {
|
||||
File packFolder = new File(ModdedPackCommands.packsRoot(), pack);
|
||||
if (!packFolder.isDirectory()) {
|
||||
IrisModdedCommands.fail(source, "Pack '" + pack + "' was not found under " + ModdedPackCommands.packsRoot().getAbsolutePath());
|
||||
IrisModdedCommands.fail(source, IrisLanguage.plain(ModdedCommandMessages.MODDED_WORLD_COMMANDS_PACK_WAS_NOT_FOUND_UNDER, MessageArgument.untrusted("pack", pack), MessageArgument.untrusted("value", ModdedPackCommands.packsRoot().getAbsolutePath())));
|
||||
return false;
|
||||
}
|
||||
IrisData data = IrisData.get(packFolder);
|
||||
IrisDimension dimension = data.getDimensionLoader().load(packDimension);
|
||||
if (dimension == null) {
|
||||
IrisModdedCommands.fail(source, "Pack '" + pack + "' does not contain dimensions/" + packDimension + ".json");
|
||||
IrisModdedCommands.fail(source, IrisLanguage.plain(ModdedCommandMessages.MODDED_WORLD_COMMANDS_PACK_DOES_NOT_CONTAIN_DIMENSIONS_JSON, MessageArgument.untrusted("pack", pack), MessageArgument.untrusted("packDimension", packDimension)));
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
@@ -364,7 +367,7 @@ public final class ModdedWorldCommands {
|
||||
&& packDimension.matches("[A-Za-z0-9_/.-]+") && !packDimension.contains("..")) {
|
||||
return true;
|
||||
}
|
||||
IrisModdedCommands.fail(source, "Invalid pack reference '" + pack + (pack.equals(packDimension) ? "" : ":" + packDimension) + "'. Use pack or pack:dimensionKey.");
|
||||
IrisModdedCommands.fail(source, IrisLanguage.plain(ModdedCommandMessages.MODDED_WORLD_COMMANDS_INVALID_PACK_REFERENCE_USE_PACK_PACK_DIMENSIONKEY, MessageArgument.untrusted("pack", pack), MessageArgument.untrusted("value", (pack.equals(packDimension) ? "" : ":" + packDimension))));
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -379,7 +382,7 @@ public final class ModdedWorldCommands {
|
||||
try {
|
||||
return Long.parseLong(value);
|
||||
} catch (NumberFormatException e) {
|
||||
IrisModdedCommands.fail(source, "Invalid seed '" + seedRaw + "'. Use a number or 'random'.");
|
||||
IrisModdedCommands.fail(source, IrisLanguage.plain(ModdedCommandMessages.MODDED_WORLD_COMMANDS_INVALID_SEED_USE_NUMBER_RANDOM_2, MessageArgument.untrusted("seedRaw", seedRaw)));
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -398,7 +401,7 @@ public final class ModdedWorldCommands {
|
||||
removed = ModdedDimensionManager.removePersistent(server, dimensionId, wipeStorage);
|
||||
} catch (Throwable e) {
|
||||
LOGGER.error("Iris world removal failed for {}", dimensionId, e);
|
||||
IrisModdedCommands.fail(source, "Failed to remove Iris world '" + dimensionId + "': " + e.getClass().getSimpleName() + (e.getMessage() == null ? "" : " - " + e.getMessage()));
|
||||
IrisModdedCommands.fail(source, IrisLanguage.plain(ModdedCommandMessages.MODDED_WORLD_COMMANDS_FAILED_REMOVE_IRIS_WORLD, MessageArgument.untrusted("dimensionId", dimensionId), MessageArgument.untrusted("value", e.getClass().getSimpleName()), MessageArgument.trusted("errorMessage", IrisLanguage.errorDetail(e))));
|
||||
return 0;
|
||||
}
|
||||
if (dimensionId.equals(ModdedModConfig.get().primaryWorld())) {
|
||||
@@ -407,17 +410,17 @@ public final class ModdedWorldCommands {
|
||||
}
|
||||
if (!removed) {
|
||||
if (wipeStorage) {
|
||||
IrisModdedCommands.ok(source, "Iris world '" + dimensionId + "' was not loaded; cleared its persistent registry entry and wiped its stored chunk/mantle data.");
|
||||
IrisModdedCommands.ok(source, IrisLanguage.plain(ModdedCommandMessages.MODDED_WORLD_COMMANDS_IRIS_WORLD_WAS_NOT_LOADED_CLEARED_ITS_PERSISTENT_REGISTRY_ENTRY, MessageArgument.untrusted("dimensionId", dimensionId)));
|
||||
} else {
|
||||
IrisModdedCommands.ok(source, "Iris world '" + dimensionId + "' was not loaded; cleared its persistent registry entry. World data on disk is kept.");
|
||||
IrisModdedCommands.ok(source, IrisLanguage.plain(ModdedCommandMessages.MODDED_WORLD_COMMANDS_IRIS_WORLD_WAS_NOT_LOADED_CLEARED_ITS_PERSISTENT_REGISTRY_ENTRY_2, MessageArgument.untrusted("dimensionId", dimensionId)));
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
if (wipeStorage) {
|
||||
IrisModdedCommands.ok(source, "Deleted Iris world '" + dimensionId + "': evacuated, unloaded, chunk/mantle data wiped, and dropped from the startup registry.");
|
||||
IrisModdedCommands.ok(source, IrisLanguage.plain(ModdedCommandMessages.MODDED_WORLD_COMMANDS_DELETED_IRIS_WORLD_EVACUATED_UNLOADED_CHUNK_MANTLE_DATA_WIPED_DROPPED, MessageArgument.untrusted("dimensionId", dimensionId)));
|
||||
} else {
|
||||
IrisModdedCommands.ok(source, "Disabled Iris world '" + dimensionId + "': evacuated, unloaded, and dropped from the startup registry.");
|
||||
IrisModdedCommands.ok(source, "World data on disk is kept; re-enable with /iris world enable " + dimensionId + " <pack> or delete it with /iris world delete " + dimensionId + ".");
|
||||
IrisModdedCommands.ok(source, IrisLanguage.plain(ModdedCommandMessages.MODDED_WORLD_COMMANDS_DISABLED_IRIS_WORLD_EVACUATED_UNLOADED_DROPPED_FROM_STARTUP_REGISTRY, MessageArgument.untrusted("dimensionId", dimensionId)));
|
||||
IrisModdedCommands.ok(source, IrisLanguage.plain(ModdedCommandMessages.MODDED_WORLD_COMMANDS_WORLD_DATA_ON_DISK_IS_KEPT_RE_ENABLE_WITH_IRIS, MessageArgument.untrusted("dimensionId", dimensionId), MessageArgument.untrusted("dimensionId2", dimensionId)));
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
@@ -428,27 +431,27 @@ public final class ModdedWorldCommands {
|
||||
for (ServerLevel level : server.getAllLevels()) {
|
||||
if (level.getChunkSource().getGenerator() instanceof IrisModdedChunkGenerator generator) {
|
||||
loaded++;
|
||||
IrisModdedCommands.ok(source, "Loaded Iris level: " + level.dimension().identifier() + " -> pack '" + generator.activePack() + "' dimension '" + generator.activeDimensionKey() + "'");
|
||||
IrisModdedCommands.ok(source, IrisLanguage.plain(ModdedCommandMessages.MODDED_WORLD_COMMANDS_LOADED_IRIS_LEVEL_PACK_DIMENSION, MessageArgument.untrusted("value", level.dimension().identifier()), MessageArgument.untrusted("value2", generator.activePack()), MessageArgument.untrusted("value3", generator.activeDimensionKey())));
|
||||
}
|
||||
}
|
||||
String primary = ModdedModConfig.get().primaryWorld();
|
||||
if (!primary.isBlank()) {
|
||||
IrisModdedCommands.ok(source, "Primary world: " + primary + (ModdedModConfig.get().routePlayersToPrimaryWorld() ? " (players routed there)" : " (routing disabled)"));
|
||||
IrisModdedCommands.ok(source, IrisLanguage.plain(ModdedCommandMessages.MODDED_WORLD_COMMANDS_PRIMARY_WORLD, MessageArgument.untrusted("primary", primary), MessageArgument.trusted("value", IrisLanguage.plain(ModdedModConfig.get().routePlayersToPrimaryWorld() ? RuntimeUiMessages.PRIMARY_PLAYERS_ROUTED_SUFFIX : RuntimeUiMessages.PRIMARY_ROUTING_DISABLED_SUFFIX))));
|
||||
}
|
||||
if (loaded == 0) {
|
||||
IrisModdedCommands.fail(source, "No Iris dimensions are currently loaded. Create one with /iris world create <name> <pack>.");
|
||||
IrisModdedCommands.fail(source, IrisLanguage.plain(ModdedCommandMessages.MODDED_WORLD_COMMANDS_NO_IRIS_DIMENSIONS_ARE_CURRENTLY_LOADED_CREATE_ONE_WITH_IRIS));
|
||||
}
|
||||
return loaded > 0 ? 1 : 0;
|
||||
}
|
||||
|
||||
private static int list(CommandSourceStack source) {
|
||||
List<String> dimensions = loadedIrisDimensions(source.getServer());
|
||||
IrisModdedCommands.ok(source, "Loaded Iris dimensions: " + dimensions.size());
|
||||
IrisModdedCommands.ok(source, IrisLanguage.plain(ModdedCommandMessages.MODDED_WORLD_COMMANDS_LOADED_IRIS_DIMENSIONS, MessageArgument.untrusted("value", dimensions.size())));
|
||||
for (String dimension : dimensions) {
|
||||
IrisModdedCommands.ok(source, " - " + dimension);
|
||||
IrisModdedCommands.ok(source, IrisLanguage.plain(ModdedCommandMessages.MODDED_WORLD_COMMANDS_MESSAGE_2, MessageArgument.untrusted("dimension", dimension)));
|
||||
}
|
||||
if (dimensions.isEmpty()) {
|
||||
IrisModdedCommands.ok(source, "Use /iris world create <name> <pack> to inject one without restarting.");
|
||||
IrisModdedCommands.ok(source, IrisLanguage.plain(ModdedCommandMessages.MODDED_WORLD_COMMANDS_USE_IRIS_WORLD_CREATE_NAME_PACK_INJECT_ONE_WITHOUT_RESTARTING));
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
+3
@@ -19,6 +19,7 @@
|
||||
package art.arcane.iris.modded.service;
|
||||
|
||||
import art.arcane.iris.core.IrisSettings;
|
||||
import art.arcane.iris.core.localization.IrisLanguage;
|
||||
import art.arcane.iris.spi.IrisPlatforms;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import org.slf4j.Logger;
|
||||
@@ -52,12 +53,14 @@ public final class ModdedSettingsHotloadService implements ModdedTickableService
|
||||
lastPollAt = now;
|
||||
long modified = settingsFile().lastModified();
|
||||
if (modified == lastModified) {
|
||||
IrisLanguage.update();
|
||||
return;
|
||||
}
|
||||
if (IrisSettings.settings != null) {
|
||||
IrisSettings.invalidate();
|
||||
}
|
||||
IrisSettings.get();
|
||||
IrisLanguage.reload();
|
||||
lastModified = settingsFile().lastModified();
|
||||
LOGGER.info("Hotloaded settings.json");
|
||||
}
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"key.categories.irisworldgen.iris": "Iris",
|
||||
"key.irisworldgen.toggle_pregen_hud": "Vorgenerierungs-HUD umschalten"
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"key.categories.irisworldgen.iris": "Iris",
|
||||
"key.irisworldgen.toggle_pregen_hud": "Alternar HUD de pregeneración"
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"key.categories.irisworldgen.iris": "Iris",
|
||||
"key.irisworldgen.toggle_pregen_hud": "Vaihda esigeneroinnin HUD"
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"key.categories.irisworldgen.iris": "Iris",
|
||||
"key.irisworldgen.toggle_pregen_hud": "Activer ou désactiver le HUD de prégénération"
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"key.categories.irisworldgen.iris": "Iris",
|
||||
"key.irisworldgen.toggle_pregen_hud": "הפעלה או כיבוי של תצוגת הקדם-יצירה"
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"key.categories.irisworldgen.iris": "Iris",
|
||||
"key.irisworldgen.toggle_pregen_hud": "Attiva o disattiva l'HUD di pregenerazione"
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"key.categories.irisworldgen.iris": "Iris",
|
||||
"key.irisworldgen.toggle_pregen_hud": "事前生成 HUD の切り替え"
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"key.categories.irisworldgen.iris": "Iris",
|
||||
"key.irisworldgen.toggle_pregen_hud": "사전 생성 HUD 전환"
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"key.categories.irisworldgen.iris": "Iris",
|
||||
"key.irisworldgen.toggle_pregen_hud": "Perjungti išankstinio generavimo HUD"
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"key.categories.irisworldgen.iris": "Iris",
|
||||
"key.irisworldgen.toggle_pregen_hud": "HUD voor vooraf genereren in- of uitschakelen"
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"key.categories.irisworldgen.iris": "Iris",
|
||||
"key.irisworldgen.toggle_pregen_hud": "Przełącz interfejs wstępnego generowania"
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"key.categories.irisworldgen.iris": "Iris",
|
||||
"key.irisworldgen.toggle_pregen_hud": "Alternar HUD de pré-geração"
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"key.categories.irisworldgen.iris": "Iris",
|
||||
"key.irisworldgen.toggle_pregen_hud": "Переключить HUD предварительной генерации"
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"key.categories.irisworldgen.iris": "Iris",
|
||||
"key.irisworldgen.toggle_pregen_hud": "Ön oluşturma HUD'unu aç veya kapat"
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"key.categories.irisworldgen.iris": "Iris",
|
||||
"key.irisworldgen.toggle_pregen_hud": "Bật hoặc tắt HUD tạo trước"
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"key.categories.irisworldgen.iris": "Iris",
|
||||
"key.irisworldgen.toggle_pregen_hud": "切换预生成 HUD"
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"key.categories.irisworldgen.iris": "Iris",
|
||||
"key.irisworldgen.toggle_pregen_hud": "切換預先生成 HUD"
|
||||
}
|
||||
+85
@@ -0,0 +1,85 @@
|
||||
package art.arcane.iris.modded;
|
||||
|
||||
import art.arcane.volmlib.util.localization.VolmitLocales;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonParser;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.net.URL;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
public class IrisModLanguageAssetsTest {
|
||||
private static final String ROOT = "assets/irisworldgen/lang/";
|
||||
private static final String TOGGLE_KEY = "key.irisworldgen.toggle_pregen_hud";
|
||||
|
||||
@Test
|
||||
public void minecraftLanguageAssetsMatchSharedLocaleManifest() throws Exception {
|
||||
JsonObject english = read("en_us");
|
||||
assertEquals(2, english.size());
|
||||
|
||||
for (String locale : VolmitLocales.nonEnglish()) {
|
||||
String minecraftLocale = VolmitLocales.minecraftCode(locale);
|
||||
JsonObject translated = read(minecraftLocale);
|
||||
assertEquals(minecraftLocale, english.keySet(), translated.keySet());
|
||||
for (String key : english.keySet()) {
|
||||
JsonElement value = translated.get(key);
|
||||
assertTrue(minecraftLocale + ": " + key, value.isJsonPrimitive());
|
||||
assertTrue(minecraftLocale + ": " + key, value.getAsJsonPrimitive().isString());
|
||||
assertFalse(minecraftLocale + ": " + key, value.getAsString().isBlank());
|
||||
}
|
||||
assertFalse(
|
||||
minecraftLocale + " contains an English HUD label",
|
||||
english.get(TOGGLE_KEY).getAsString().equals(translated.get(TOGGLE_KEY).getAsString())
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void minecraftLanguageResourceSetMatchesSharedLocaleManifestAndEnglishBaseline() throws Exception {
|
||||
Set<String> expected = VolmitLocales.nonEnglish().stream()
|
||||
.map(VolmitLocales::minecraftCode)
|
||||
.map(locale -> locale + ".json")
|
||||
.collect(Collectors.toCollection(LinkedHashSet::new));
|
||||
expected.add("en_us.json");
|
||||
|
||||
assertEquals(expected, resourceFiles());
|
||||
}
|
||||
|
||||
private JsonObject read(String locale) throws Exception {
|
||||
String resource = ROOT + locale + ".json";
|
||||
InputStream input = IrisModLanguageAssetsTest.class.getClassLoader().getResourceAsStream(resource);
|
||||
assertNotNull("Missing mod language asset: " + resource, input);
|
||||
try (InputStream stream = input;
|
||||
InputStreamReader reader = new InputStreamReader(stream, StandardCharsets.UTF_8)) {
|
||||
JsonElement parsed = JsonParser.parseReader(reader);
|
||||
assertTrue("Mod language asset is not an object: " + resource, parsed.isJsonObject());
|
||||
return parsed.getAsJsonObject();
|
||||
}
|
||||
}
|
||||
|
||||
private Set<String> resourceFiles() throws Exception {
|
||||
URL resource = IrisModLanguageAssetsTest.class.getClassLoader().getResource(ROOT);
|
||||
assertNotNull("Missing mod language resource directory", resource);
|
||||
assertEquals("file", resource.getProtocol());
|
||||
try (Stream<Path> paths = Files.list(Path.of(resource.toURI()))) {
|
||||
return paths
|
||||
.filter(Files::isRegularFile)
|
||||
.map(path -> path.getFileName().toString())
|
||||
.collect(Collectors.toUnmodifiableSet());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,3 +1,4 @@
|
||||
public net.minecraft.server.MinecraftServer levels
|
||||
public net.minecraft.server.MinecraftServer executor
|
||||
public net.minecraft.server.MinecraftServer storageSource
|
||||
public net.minecraft.core.MappedRegistry frozen
|
||||
|
||||
Reference in New Issue
Block a user