From 17ad6f9be53923add2900243a77253a90580b3a9 Mon Sep 17 00:00:00 2001 From: gardenevery Date: Wed, 1 Apr 2026 01:01:13 +0800 Subject: [PATCH 01/11] ui optimize --- .../client/gui/GuiCreateWorld.java.patch | 266 +++++++++++++++++- .../client/gui/GuiOptions.java.patch | 40 ++- .../minecraft/world/WorldSettings.java.patch | 42 +++ .../world/storage/WorldInfo.java.patch | 23 +- .../client/gui/EditGameRulesGui.java | 179 ++++++++++++ .../client/gui/WorldOptionsGui.java | 100 +++++++ .../resources/assets/forge/lang/en_us.lang | 20 ++ .../resources/assets/forge/lang/zh_cn.lang | 20 ++ 8 files changed, 674 insertions(+), 16 deletions(-) create mode 100644 patches/minecraft/net/minecraft/world/WorldSettings.java.patch create mode 100644 src/main/java/com/cleanroommc/client/gui/EditGameRulesGui.java create mode 100644 src/main/java/com/cleanroommc/client/gui/WorldOptionsGui.java diff --git a/patches/minecraft/net/minecraft/client/gui/GuiCreateWorld.java.patch b/patches/minecraft/net/minecraft/client/gui/GuiCreateWorld.java.patch index 29f9068b5..40f486a5a 100644 --- a/patches/minecraft/net/minecraft/client/gui/GuiCreateWorld.java.patch +++ b/patches/minecraft/net/minecraft/client/gui/GuiCreateWorld.java.patch @@ -1,15 +1,158 @@ --- before/net/minecraft/client/gui/GuiCreateWorld.java +++ after/net/minecraft/client/gui/GuiCreateWorld.java -@@ -240,6 +240,8 @@ +@@ -43,6 +43,11 @@ + private String worldName; + private int selectedIndex; + public String chunkProviderSettingsJson = ""; ++ private GuiButton btnDifficulty; ++ private net.minecraft.world.EnumDifficulty currentDifficulty = net.minecraft.world.EnumDifficulty.NORMAL; ++ private net.minecraft.world.EnumDifficulty savedDifficulty; ++ private GuiButton btnWorld; ++ private GuiButton btnGame; + private static final String[] DISALLOWED_FILENAMES = new String[] + { + "CON", +@@ -90,24 +95,29 @@ + { + Keyboard.enableRepeatEvents(true); + this.buttonList.clear(); +- this.buttonList.add(new GuiButton(0, this.width / 2 - 155, this.height - 28, 150, 20, I18n.format("selectWorld.create"))); +- this.buttonList.add(new GuiButton(1, this.width / 2 + 5, this.height - 28, 150, 20, I18n.format("gui.cancel"))); +- this.btnGameMode = this.addButton(new GuiButton(2, this.width / 2 - 75, 115, 150, 20, I18n.format("selectWorld.gameMode"))); +- this.btnMoreOptions = this.addButton(new GuiButton(3, this.width / 2 - 75, 187, 150, 20, I18n.format("selectWorld.moreWorldOptions"))); +- this.btnMapFeatures = this.addButton(new GuiButton(4, this.width / 2 - 155, 100, 150, 20, I18n.format("selectWorld.mapFeatures"))); ++ this.buttonList.add(new GuiButton(0, this.width / 2 - 154, this.height - 26, 150, 20, I18n.format("selectWorld.create"))); ++ this.buttonList.add(new GuiButton(1, this.width / 2 + 4, this.height - 26, 150, 20, I18n.format("gui.cancel"))); ++ this.btnGameMode = this.addButton(new GuiButton(2, this.width / 2 - 105, 78, 211, 20, I18n.format("selectWorld.gameMode"))); ++ this.btnGame = this.addButton(new GuiButton(12, this.width / 2 - 124, 5, 120, 20, I18n.format("fml.game"))); ++ this.btnWorld = this.addButton(new GuiButton(3, this.width / 2 - 2, 5, 120, 20, I18n.format("fml.world"))); ++ this.btnWorld.enabled = true; ++ this.btnGame.enabled = false; ++ this.btnMapFeatures = this.addButton(new GuiButton(4, this.width / 2 + 111, 110, 45, 20, I18n.format("selectWorld.mapFeatures"))); + this.btnMapFeatures.visible = false; +- this.btnBonusItems = this.addButton(new GuiButton(7, this.width / 2 + 5, 151, 150, 20, I18n.format("selectWorld.bonusItems"))); ++ this.btnBonusItems = this.addButton(new GuiButton(7, this.width / 2 + 111, 134, 45, 20, I18n.format("selectWorld.bonusItems"))); + this.btnBonusItems.visible = false; +- this.btnMapType = this.addButton(new GuiButton(5, this.width / 2 + 5, 100, 150, 20, I18n.format("selectWorld.mapType"))); ++ this.btnMapType = this.addButton(new GuiButton(5, this.width / 2 - 155, 37, 150, 20, I18n.format("selectWorld.mapType"))); + this.btnMapType.visible = false; +- this.btnAllowCommands = this.addButton(new GuiButton(6, this.width / 2 - 155, 151, 150, 20, I18n.format("selectWorld.allowCommands"))); +- this.btnAllowCommands.visible = false; +- this.btnCustomizeType = this.addButton(new GuiButton(8, this.width / 2 + 5, 120, 150, 20, I18n.format("selectWorld.customizeType"))); ++ this.btnAllowCommands = this.addButton(new GuiButton(6, this.width / 2 - 105, 134, 211, 20, I18n.format("selectWorld.allowCommands"))); ++ this.btnAllowCommands.visible = !this.inMoreWorldOptionsDisplay; ++ this.btnDifficulty = this.addButton(new GuiButton(11, this.width / 2 - 105, 106, 211, 20, currentDifficulty.getTranslationKey())); ++ this.btnDifficulty.visible = !this.inMoreWorldOptionsDisplay; ++ this.btnCustomizeType = this.addButton(new GuiButton(8, this.width / 2 + 5, 37, 150, 20, I18n.format("selectWorld.customizeType"))); + this.btnCustomizeType.visible = false; +- this.worldNameField = new GuiTextField(9, this.fontRenderer, this.width / 2 - 100, 60, 200, 20); ++ this.worldNameField = new GuiTextField(9, this.fontRenderer, this.width / 2 - 103, 51, 206, 18); + this.worldNameField.setFocused(true); + this.worldNameField.setText(this.worldName); +- this.worldSeedField = new GuiTextField(10, this.fontRenderer, this.width / 2 - 100, 60, 200, 20); ++ this.worldSeedField = new GuiTextField(10, this.fontRenderer, this.width / 2 - 154, 79, 306, 18); + this.worldSeedField.setText(this.worldSeed); + this.showMoreWorldOptions(this.inMoreWorldOptionsDisplay); + this.calcSaveDirName(); +@@ -142,22 +152,22 @@ + + if (this.generateStructuresEnabled) + { +- this.btnMapFeatures.displayString = this.btnMapFeatures.displayString + I18n.format("options.on"); ++ this.btnMapFeatures.displayString = I18n.format("options.on"); + } + else + { +- this.btnMapFeatures.displayString = this.btnMapFeatures.displayString + I18n.format("options.off"); ++ this.btnMapFeatures.displayString = I18n.format("options.off"); + } + + this.btnBonusItems.displayString = I18n.format("selectWorld.bonusItems") + " "; + + if (this.bonusChestEnabled && !this.hardCoreMode) + { +- this.btnBonusItems.displayString = this.btnBonusItems.displayString + I18n.format("options.on"); ++ this.btnBonusItems.displayString = I18n.format("options.on"); + } + else + { +- this.btnBonusItems.displayString = this.btnBonusItems.displayString + I18n.format("options.off"); ++ this.btnBonusItems.displayString = I18n.format("options.off"); + } + + this.btnMapType.displayString = I18n.format("selectWorld.mapType") +@@ -173,6 +183,16 @@ + { + this.btnAllowCommands.displayString = this.btnAllowCommands.displayString + I18n.format("options.off"); + } ++ if (this.hardCoreMode) ++ { ++ this.btnDifficulty.displayString = I18n.format("options.difficulty") + ": " + I18n.format(net.minecraft.world.EnumDifficulty.HARD.getTranslationKey()); ++ this.btnDifficulty.enabled = false; ++ } ++ else ++ { ++ this.btnDifficulty.displayString = I18n.format("options.difficulty") + ": " + I18n.format(this.currentDifficulty.getTranslationKey()); ++ this.btnDifficulty.enabled = true; ++ } + } + + public static String getUncollidingSaveDirName(ISaveFormat saveLoader, String name) +@@ -240,8 +260,10 @@ } } + WorldType.WORLD_TYPES[this.selectedIndex].onGUICreateWorldPress(); + WorldSettings worldsettings = new WorldSettings( - i, GameType.getByName(this.gameMode), this.generateStructuresEnabled, this.hardCoreMode, WorldType.WORLD_TYPES[this.selectedIndex] +- i, GameType.getByName(this.gameMode), this.generateStructuresEnabled, this.hardCoreMode, WorldType.WORLD_TYPES[this.selectedIndex] ++ i, GameType.getByName(this.gameMode), this.generateStructuresEnabled, this.hardCoreMode, WorldType.WORLD_TYPES[this.selectedIndex], this.currentDifficulty ); -@@ -348,14 +350,7 @@ + worldsettings.setGeneratorOptions(this.chunkProviderSettingsJson); + +@@ -257,9 +279,9 @@ + + this.mc.launchIntegratedServer(this.saveDirName, this.worldNameField.getText().trim(), worldsettings); + } +- else if (button.id == 3) ++ else if (button.id == 3 && this.btnWorld.enabled) + { +- this.toggleMoreWorldOptions(); ++ this.showMoreWorldOptions(true); + } + else if (button.id == 2) + { +@@ -273,6 +295,8 @@ + this.hardCoreMode = false; + this.gameMode = "hardcore"; + this.hardCoreMode = true; ++ this.savedDifficulty = this.currentDifficulty; ++ this.currentDifficulty = net.minecraft.world.EnumDifficulty.HARD; + this.btnAllowCommands.enabled = false; + this.btnBonusItems.enabled = false; + this.updateDisplayState(); +@@ -286,6 +310,12 @@ + + this.hardCoreMode = false; + this.gameMode = "creative"; ++ if (this.savedDifficulty != null) ++ { ++ this.currentDifficulty = this.savedDifficulty; ++ this.savedDifficulty = null; ++ } ++ else this.currentDifficulty = net.minecraft.world.EnumDifficulty.NORMAL; + this.updateDisplayState(); + this.hardCoreMode = false; + this.btnAllowCommands.enabled = true; +@@ -339,6 +369,7 @@ + this.chunkProviderSettingsJson = ""; + this.updateDisplayState(); + this.showMoreWorldOptions(this.inMoreWorldOptionsDisplay); ++ this.btnCustomizeType.enabled = WorldType.WORLD_TYPES[this.selectedIndex].isCustomizable(); + } + else if (button.id == 6) + { +@@ -348,15 +379,14 @@ } else if (button.id == 8) { @@ -21,24 +164,74 @@ - { - this.mc.displayGuiScreen(new GuiCustomizeWorldScreen(this, this.chunkProviderSettingsJson)); - } +- } + WorldType.WORLD_TYPES[this.selectedIndex].onCustomizeButton(mc, this); - } ++ } ++ else if (button.id == 11 && !this.hardCoreMode) ++ { ++ this.currentDifficulty = net.minecraft.world.EnumDifficulty.byId((this.currentDifficulty.getId() + 1) % 4); ++ this.updateDisplayState(); ++ } ++ else if (button.id == 12 && this.btnGame.enabled) this.showMoreWorldOptions(false); } } -@@ -415,11 +410,7 @@ + +@@ -382,12 +412,16 @@ + private void showMoreWorldOptions(boolean toggle) + { + this.inMoreWorldOptionsDisplay = toggle; +- ++ this.btnWorld.visible = true; ++ this.btnGame.visible = true; ++ this.btnWorld.enabled = !toggle; ++ this.btnGame.enabled = toggle; + if (WorldType.WORLD_TYPES[this.selectedIndex] == WorldType.DEBUG_ALL_BLOCK_STATES) + { + this.btnGameMode.visible = !this.inMoreWorldOptionsDisplay; + this.btnGameMode.enabled = false; +- ++ this.btnAllowCommands.visible = false; ++ this.btnDifficulty.visible = false; + if (this.savedGameMode == null) + { + this.savedGameMode = this.gameMode; +@@ -404,7 +438,8 @@ + { + this.btnGameMode.visible = !this.inMoreWorldOptionsDisplay; + this.btnGameMode.enabled = true; +- ++ this.btnAllowCommands.visible = !this.inMoreWorldOptionsDisplay; ++ this.btnDifficulty.visible = !this.inMoreWorldOptionsDisplay; + if (this.savedGameMode != null) + { + this.gameMode = this.savedGameMode; +@@ -414,23 +449,14 @@ + this.btnMapFeatures.visible = this.inMoreWorldOptionsDisplay && WorldType.WORLD_TYPES[this.selectedIndex] != WorldType.CUSTOMIZED; this.btnBonusItems.visible = this.inMoreWorldOptionsDisplay; this.btnMapType.visible = this.inMoreWorldOptionsDisplay; - this.btnAllowCommands.visible = this.inMoreWorldOptionsDisplay; +- this.btnAllowCommands.visible = this.inMoreWorldOptionsDisplay; - this.btnCustomizeType.visible = this.inMoreWorldOptionsDisplay - && ( - WorldType.WORLD_TYPES[this.selectedIndex] == WorldType.FLAT - || WorldType.WORLD_TYPES[this.selectedIndex] == WorldType.CUSTOMIZED - ); -+ this.btnCustomizeType.visible = this.inMoreWorldOptionsDisplay && WorldType.WORLD_TYPES[this.selectedIndex].isCustomizable(); ++ this.btnCustomizeType.visible = this.inMoreWorldOptionsDisplay; ++ if (this.inMoreWorldOptionsDisplay) this.btnCustomizeType.enabled = WorldType.WORLD_TYPES[this.selectedIndex].isCustomizable(); } this.updateDisplayState(); -@@ -460,6 +451,23 @@ + + if (this.inMoreWorldOptionsDisplay) + { +- this.btnMoreOptions.displayString = I18n.format("gui.done"); +- } +- else +- { +- this.btnMoreOptions.displayString = I18n.format("selectWorld.moreWorldOptions"); + } + } + +@@ -460,6 +486,23 @@ @Override protected void mouseClicked(int mouseX, int mouseY, int mouseButton) throws IOException { @@ -55,10 +248,65 @@ + + this.chunkProviderSettingsJson = ""; + this.updateDisplayState(); -+ this.showMoreWorldOptions(this.inMoreWorldOptionsDisplay); ++ if (this.inMoreWorldOptionsDisplay) this.showMoreWorldOptions(true); + } + } + super.mouseClicked(mouseX, mouseY, mouseButton); if (this.inMoreWorldOptionsDisplay) +@@ -476,16 +519,14 @@ + public void drawScreen(int mouseX, int mouseY, float partialTicks) + { + this.drawDefaultBackground(); +- this.drawCenteredString(this.fontRenderer, I18n.format("selectWorld.create"), this.width / 2, 20, -1); + + if (this.inMoreWorldOptionsDisplay) + { +- this.drawString(this.fontRenderer, I18n.format("selectWorld.enterSeed"), this.width / 2 - 100, 47, -6250336); +- this.drawString(this.fontRenderer, I18n.format("selectWorld.seedInfo"), this.width / 2 - 100, 85, -6250336); +- ++ this.drawString(this.fontRenderer, I18n.format("selectWorld.enterSeed"), this.width / 2 - 155, 65, -6250336); ++ this.drawString(this.fontRenderer, I18n.format("fml.generate_structures.title"), this.width / 2 - 155, 116, -6250336); ++ this.drawString(this.fontRenderer, I18n.format("fml.bonus_chest.title"), this.width / 2 - 155, 140, -6250336); + if (this.btnMapFeatures.visible) + { +- this.drawString(this.fontRenderer, I18n.format("selectWorld.mapFeatures.info"), this.width / 2 - 150, 122, -6250336); + } + + if (this.btnAllowCommands.visible) +@@ -497,25 +538,12 @@ + + if (WorldType.WORLD_TYPES[this.selectedIndex].hasInfoNotice()) + { +- this.fontRenderer +- .drawSplitString( +- I18n.format(WorldType.WORLD_TYPES[this.selectedIndex].getInfoTranslationKey()), +- this.btnMapType.x + 2, +- this.btnMapType.y + 22, +- this.btnMapType.getButtonWidth(), +- 10526880 +- ); + } + } + else + { +- this.drawString(this.fontRenderer, I18n.format("selectWorld.enterName"), this.width / 2 - 100, 47, -6250336); +- this.drawString( +- this.fontRenderer, I18n.format("selectWorld.resultFolder") + " " + this.saveDirName, this.width / 2 - 100, 85, -6250336 +- ); ++ this.drawString(this.fontRenderer, I18n.format("selectWorld.enterName"), this.width / 2 - 104, 37, -6250336); + this.worldNameField.drawTextBox(); +- this.drawString(this.fontRenderer, this.gameModeDesc1, this.width / 2 - 100, 137, -6250336); +- this.drawString(this.fontRenderer, this.gameModeDesc2, this.width / 2 - 100, 149, -6250336); + } + + super.drawScreen(mouseX, mouseY, partialTicks); +@@ -523,6 +551,7 @@ + + public void recreateFromExistingWorld(WorldInfo original) + { ++ this.currentDifficulty = original.getDifficulty(); + this.worldName = I18n.format("selectWorld.newWorld.copyOf", original.getWorldName()); + this.worldSeed = original.getSeed() + ""; + this.selectedIndex = original.getTerrainType().getId(); diff --git a/patches/minecraft/net/minecraft/client/gui/GuiOptions.java.patch b/patches/minecraft/net/minecraft/client/gui/GuiOptions.java.patch index 6c2d484ca..6fe5adf74 100644 --- a/patches/minecraft/net/minecraft/client/gui/GuiOptions.java.patch +++ b/patches/minecraft/net/minecraft/client/gui/GuiOptions.java.patch @@ -1,11 +1,45 @@ --- before/net/minecraft/client/gui/GuiOptions.java +++ after/net/minecraft/client/gui/GuiOptions.java -@@ -85,7 +85,7 @@ - this.difficultyButton.enabled = false; - } +@@ -64,28 +64,9 @@ + if (this.mc.world != null) + { + EnumDifficulty enumdifficulty = this.mc.world.getDifficulty(); +- this.difficultyButton = new GuiButton( +- 108, this.width / 2 - 155 + i % 2 * 160, this.height / 6 - 12 + 24 * (i >> 1), 150, 20, this.getDifficultyText(enumdifficulty) +- ); +- this.buttonList.add(this.difficultyButton); +- +- if (this.mc.isSingleplayer() && !this.mc.world.getWorldInfo().isHardcoreModeEnabled()) +- { +- this.difficultyButton.setWidth(this.difficultyButton.getButtonWidth() - 20); +- this.lockButton = new GuiLockIconButton( +- 109, this.difficultyButton.x + this.difficultyButton.getButtonWidth(), this.difficultyButton.y +- ); +- this.buttonList.add(this.lockButton); +- this.lockButton.setLocked(this.mc.world.getWorldInfo().isDifficultyLocked()); +- this.lockButton.enabled = !this.lockButton.isLocked(); +- this.difficultyButton.enabled = !this.lockButton.isLocked(); +- } +- else +- { +- this.difficultyButton.enabled = false; +- } ++ this.buttonList.add(new GuiButton(107, this.width / 2 + 5, this.height / 6 - 12, 150, 20, I18n.format("fml.world_options"))); } - else + else if (false) // removed realms button { this.buttonList .add( +@@ -241,6 +222,11 @@ + { + this.mc.gameSettings.saveOptions(); + this.mc.displayGuiScreen(new GuiScreenOptionsSounds(this, this.settings)); ++ } ++ if (button.id == 107) ++ { ++ this.mc.gameSettings.saveOptions(); ++ this.mc.displayGuiScreen(new com.cleanroommc.client.gui.WorldOptionsGui(this)); + } + } + } diff --git a/patches/minecraft/net/minecraft/world/WorldSettings.java.patch b/patches/minecraft/net/minecraft/world/WorldSettings.java.patch new file mode 100644 index 000000000..954e93a8a --- /dev/null +++ b/patches/minecraft/net/minecraft/world/WorldSettings.java.patch @@ -0,0 +1,42 @@ +--- before/net/minecraft/world/WorldSettings.java ++++ after/net/minecraft/world/WorldSettings.java +@@ -14,6 +14,7 @@ + private boolean commandsAllowed; + private boolean bonusChestEnabled; + private String generatorOptions = ""; ++ private EnumDifficulty difficulty = EnumDifficulty.NORMAL; + + public WorldSettings(long seedIn, GameType gameType, boolean enableMapFeatures, boolean hardcoreMode, WorldType worldTypeIn) + { +@@ -24,9 +25,19 @@ + this.terrainType = worldTypeIn; + } + ++ public WorldSettings(long seedIn, GameType gameType, boolean enableMapFeatures, boolean hardcoreMode, WorldType worldTypeIn, EnumDifficulty difficulty) ++ { ++ this.seed = seedIn; ++ this.gameType = gameType; ++ this.mapFeaturesEnabled = enableMapFeatures; ++ this.hardcoreEnabled = hardcoreMode; ++ this.terrainType = worldTypeIn; ++ this.difficulty = difficulty; ++ } ++ + public WorldSettings(WorldInfo info) + { +- this(info.getSeed(), info.getGameType(), info.isMapFeaturesEnabled(), info.isHardcoreModeEnabled(), info.getTerrainType()); ++ this(info.getSeed(), info.getGameType(), info.isMapFeaturesEnabled(), info.isHardcoreModeEnabled(), info.getTerrainType(), info.getDifficulty()); + } + + public WorldSettings enableBonusChest() +@@ -91,5 +102,10 @@ + public String getGeneratorOptions() + { + return this.generatorOptions; ++ } ++ ++ public EnumDifficulty getDifficulty() ++ { ++ return this.difficulty; + } + } diff --git a/patches/minecraft/net/minecraft/world/storage/WorldInfo.java.patch b/patches/minecraft/net/minecraft/world/storage/WorldInfo.java.patch index f47d2ca37..dd979beff 100644 --- a/patches/minecraft/net/minecraft/world/storage/WorldInfo.java.patch +++ b/patches/minecraft/net/minecraft/world/storage/WorldInfo.java.patch @@ -20,7 +20,22 @@ } } } -@@ -367,6 +368,7 @@ +@@ -261,12 +262,13 @@ + { + this.populateFromWorldSettings(settings); + this.levelName = name; +- this.difficulty = DEFAULT_DIFFICULTY; ++ this.difficulty = settings.getDifficulty(); + this.initialized = false; + } + + public void populateFromWorldSettings(WorldSettings settings) + { ++ this.difficulty = settings.getDifficulty(); + this.randomSeed = settings.getSeed(); + this.gameType = settings.getGameType(); + this.mapFeaturesEnabled = settings.isMapFeaturesEnabled(); +@@ -367,6 +369,7 @@ nbt.setDouble("BorderSizeLerpTarget", this.borderSizeLerpTarget); nbt.setDouble("BorderWarningBlocks", this.borderWarningDistance); nbt.setDouble("BorderWarningTime", this.borderWarningTime); @@ -28,7 +43,7 @@ if (this.difficulty != null) { -@@ -377,9 +379,10 @@ +@@ -377,9 +380,10 @@ nbt.setTag("GameRules", this.gameRules.writeToNBT()); NBTTagCompound nbttagcompound1 = new NBTTagCompound(); @@ -41,7 +56,7 @@ } nbt.setTag("DimensionData", nbttagcompound1); -@@ -709,6 +712,7 @@ +@@ -709,6 +713,7 @@ public void setDifficulty(EnumDifficulty newDifficulty) { @@ -49,7 +64,7 @@ this.difficulty = newDifficulty; } -@@ -832,16 +836,47 @@ +@@ -832,16 +837,47 @@ } ); } diff --git a/src/main/java/com/cleanroommc/client/gui/EditGameRulesGui.java b/src/main/java/com/cleanroommc/client/gui/EditGameRulesGui.java new file mode 100644 index 000000000..9c28a6695 --- /dev/null +++ b/src/main/java/com/cleanroommc/client/gui/EditGameRulesGui.java @@ -0,0 +1,179 @@ +package com.cleanroommc.client.gui; + +import java.io.IOException; + +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.GuiButton; +import net.minecraft.client.gui.GuiScreen; +import net.minecraft.client.gui.GuiYesNo; +import net.minecraft.client.gui.GuiYesNoCallback; +import net.minecraft.client.resources.I18n; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; + +@SideOnly(Side.CLIENT) +public class EditGameRulesGui extends GuiScreen implements GuiYesNoCallback { + private final GuiScreen parent; + private final boolean[] ruleStates = new boolean[8]; + private final boolean[] originalStates = new boolean[8]; + private boolean changed = false; + + private final String[] titles = { + "fml.death_messages.title", + "fml.mob_loot.title", + "fml.destructive_mob_actions.title", + "fml.keep_inventory.title", + "fml.spectators_generate_terrain.title", + "fml.spawn_mobs.title", + "fml.advance_time.title", + "fml.update_weather.title" + }; + + private final String[] ruleKeys = { + "showDeathMessages", + "doMobLoot", + "mobGriefing", + "keepInventory", + "spectatorsGenerateChunks", + "doMobSpawning", + "doDaylightCycle", + "doWeatherCycle" + }; + + public EditGameRulesGui(GuiScreen parentIn) { + this.parent = parentIn; + } + + @Override + public void initGui() { + var world = Minecraft.getMinecraft().world; + if (world != null) { + var gameRules = world.getGameRules(); + for (int i = 0; i < ruleKeys.length; i++) { + ruleStates[i] = gameRules.getBoolean(ruleKeys[i]); + originalStates[i] = ruleStates[i]; + } + } else { + for (int i = 0; i < ruleStates.length; i++) { + ruleStates[i] = false; + originalStates[i] = false; + } + } + + this.buttonList.add(new GuiButton(0, this.width / 2 - 154, this.height / 6 + 180, 150, 20, + I18n.format("gui.done"))); + this.buttonList.add(new GuiButton(1, this.width / 2 + 4, this.height / 6 + 180, 150, 20, + I18n.format("gui.cancel"))); + + int lineHeight = 170 / (titles.length - 1); + for (int i = 0; i < titles.length; i++) { + int y = 30 + lineHeight * i; + int buttonId = 2 + i; + int x = this.width / 2 + 63; + var buttonText = ruleStates[i] ? I18n.format("gui.yes") : I18n.format("gui.no"); + var btn = new GuiButton(buttonId, x, y - 6, 45, 20, buttonText); + this.buttonList.add(btn); + } + } + + @Override + protected void actionPerformed(GuiButton button) { + if (!button.enabled) { + return; + } + + switch (button.id) { + case 0 -> { + applyChanges(); + this.mc.displayGuiScreen(this.parent); + } + case 1 -> onCancel(); + default -> { + int index = button.id - 2; + if (index >= 0 && index < ruleStates.length) { + ruleStates[index] = !ruleStates[index]; + button.displayString = ruleStates[index] ? I18n.format("gui.yes") : I18n.format("gui.no"); + if (ruleStates[index] != originalStates[index]) { + setChanged(true); + } else { + boolean anyChanged = false; + for (int i = 0; i < ruleStates.length; i++) { + if (ruleStates[i] != originalStates[i]) { + anyChanged = true; + break; + } + } + + if (!anyChanged) { + setChanged(false); + } + } + } + } + } + } + + private void applyChanges() { + var world = Minecraft.getMinecraft().world; + for (int i = 0; i < ruleKeys.length; i++) { + if (ruleStates[i] != originalStates[i]) { + var command = String.format("/gamerule %s %s", ruleKeys[i], ruleStates[i]); + mc.player.sendChatMessage(command); + if (world != null) { + world.getGameRules().setOrCreateGameRule(ruleKeys[i], Boolean.toString(ruleStates[i])); + } + } + } + setChanged(false); + } + + @Override + protected void keyTyped(char typedChar, int keyCode) throws IOException { + if (keyCode == 1) { + onCancel(); + } else { + super.keyTyped(typedChar, keyCode); + } + } + + private void onCancel() { + if (this.isChange()) { + this.mc.displayGuiScreen(new GuiYesNo(this, + I18n.format("fml.game_rule_changes.title"), + I18n.format("fml.abandon_game_rule_changes"), + 0)); + } else { + this.mc.displayGuiScreen(this.parent); + } + } + + @Override + public void drawScreen(int mouseX, int mouseY, float partialTicks) { + this.drawDefaultBackground(); + this.drawCenteredString(this.fontRenderer, I18n.format("fml.edit_game_rules.title"), this.width / 2, 4, 0xFFFFFF); + + int lineHeight = 170 / (titles.length - 1); + for (int i = 0; i < titles.length; i++) { + int y = 30 + lineHeight * i; + this.drawCenteredString(this.fontRenderer, I18n.format(titles[i]), this.width / 2 - 80, y, 0xFFFFFF); + } + super.drawScreen(mouseX, mouseY, partialTicks); + } + + public boolean isChange() { + return changed; + } + + public void setChanged(boolean changed) { + this.changed = changed; + } + + @Override + public void confirmClicked(boolean result, int id) { + if (result) { + this.mc.displayGuiScreen(this.parent); + } else { + this.mc.displayGuiScreen(this); + } + } +} diff --git a/src/main/java/com/cleanroommc/client/gui/WorldOptionsGui.java b/src/main/java/com/cleanroommc/client/gui/WorldOptionsGui.java new file mode 100644 index 000000000..162ba167f --- /dev/null +++ b/src/main/java/com/cleanroommc/client/gui/WorldOptionsGui.java @@ -0,0 +1,100 @@ +package com.cleanroommc.client.gui; + +import java.io.IOException; + +import net.minecraft.client.gui.GuiButton; +import net.minecraft.client.gui.GuiLockIconButton; +import net.minecraft.client.gui.GuiScreen; +import net.minecraft.client.gui.GuiYesNo; +import net.minecraft.client.resources.I18n; +import net.minecraft.world.EnumDifficulty; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; + +@SideOnly(Side.CLIENT) +public class WorldOptionsGui extends GuiScreen { + private final GuiScreen parent; + private GuiButton difficultyButton; + private GuiLockIconButton lockButton; + + public WorldOptionsGui(GuiScreen parentIn) { + this.parent = parentIn; + } + + @Override + public void initGui() { + this.difficultyButton = new GuiButton(0, this.width / 2 - 154, this.height / 3 - 22, + 130, 20, this.getDifficultyText(this.mc.world.getDifficulty())); + this.lockButton = new GuiLockIconButton(1, this.width / 2 - 24, this.height / 3 - 22); + + this.lockButton.setLocked(this.mc.world.getWorldInfo().isDifficultyLocked()); + this.lockButton.enabled = !this.lockButton.isLocked(); + this.difficultyButton.enabled = !this.lockButton.isLocked(); + + this.buttonList.add(this.difficultyButton); + this.buttonList.add(this.lockButton); + var editGameRulesButton = new GuiButton(2, this.width / 2 + 4, this.height / 3 - 22, 150, + 20, I18n.format("fml.edit_game_rules")); + editGameRulesButton.enabled = this.mc.player.canUseCommand(2, "gamerule"); + this.buttonList.add(editGameRulesButton); + this.buttonList.add(new GuiButton(3, this.width / 2 - 100, this.height - 26, I18n.format("gui.done"))); + } + + @Override + protected void actionPerformed(GuiButton button) { + if (button.enabled) { + switch (button.id) { + case 0 -> { + this.mc.world.getWorldInfo().setDifficulty(EnumDifficulty.byId(this.mc.world.getDifficulty().getId() + 1)); + this.difficultyButton.displayString = this.getDifficultyText(this.mc.world.getDifficulty()); + } + case 1 -> this.mc.displayGuiScreen(new GuiYesNo(this, + I18n.format("difficulty.lock.title"), + I18n.format("difficulty.lock.question", + I18n.format(this.mc.world.getWorldInfo().getDifficulty().getTranslationKey())), + 1 + )); + case 2 -> { + this.mc.gameSettings.saveOptions(); + this.mc.displayGuiScreen(new EditGameRulesGui(this)); + } + case 3 -> { + this.mc.gameSettings.saveOptions(); + this.mc.displayGuiScreen(this.parent); + } + } + } + } + + @Override + public void confirmClicked(boolean result, int id) { + if (id == 1 && result) { + this.mc.world.getWorldInfo().setDifficultyLocked(true); + this.lockButton.setLocked(true); + this.lockButton.enabled = false; + this.difficultyButton.enabled = false; + } + this.mc.displayGuiScreen(this); + } + + @Override + protected void keyTyped(char typedChar, int keyCode) throws IOException { + if (keyCode == 1) { + this.mc.gameSettings.saveOptions(); + this.mc.displayGuiScreen(this.parent); + } else { + super.keyTyped(typedChar, keyCode); + } + } + + @Override + public void drawScreen(int mouseX, int mouseY, float partialTicks) { + this.drawDefaultBackground(); + this.drawCenteredString(this.fontRenderer, I18n.format("fml.world_options.title"), this.width / 2, 12, 0xFFFFFF); + super.drawScreen(mouseX, mouseY, partialTicks); + } + + public String getDifficultyText(EnumDifficulty difficulty) { + return I18n.format("options.difficulty") + ": " + I18n.format(difficulty.getTranslationKey()); + } +} diff --git a/src/main/resources/assets/forge/lang/en_us.lang b/src/main/resources/assets/forge/lang/en_us.lang index 153c71f1a..3ed553104 100644 --- a/src/main/resources/assets/forge/lang/en_us.lang +++ b/src/main/resources/assets/forge/lang/en_us.lang @@ -277,6 +277,26 @@ fml.button.continue=Continue fml.button.open.mods.folder=Open Mods Folder fml.button.open.file=Open %s +fml.game=Game +fml.world=World +fml.generate_structures.title=Generate Structures +fml.bonus_chest.title=Bonus Chest +fml.world_options=World Options... +fml.world_options.title=World Options +fml.game_rules.title=Game Rules +fml.edit_game_rules=Edit Game Rules... +fml.edit_game_rules.title=Edit Game Rules +fml.game_rule_changes.title=Game Rule Changes +fml.abandon_game_rule_changes=Are you sure you want to discard your pending game rule changes? +fml.death_messages.title=Show death messages +fml.mob_loot.title=Drop mob loot +fml.destructive_mob_actions.title=Allow destructive mob actions +fml.keep_inventory.title=Keep inventory after death +fml.spectators_generate_terrain.title=Allow spectators to generate terrain +fml.spawn_mobs.title=Spawn mobs +fml.advance_time.title=Advance time of day +fml.update_weather.title=Update weather + forge.container.enchant.limitedEnchantability=Limited Enchantability attribute.name.generic.reachDistance=Reach Distance attribute.name.forge.swimSpeed=Swim Speed diff --git a/src/main/resources/assets/forge/lang/zh_cn.lang b/src/main/resources/assets/forge/lang/zh_cn.lang index a051f6c71..ada4a5904 100644 --- a/src/main/resources/assets/forge/lang/zh_cn.lang +++ b/src/main/resources/assets/forge/lang/zh_cn.lang @@ -239,6 +239,26 @@ fml.button.continue=继续 fml.button.open.mods.folder=打开Mods文件夹 fml.button.open.file=打开%s +fml.game=游戏 +fml.world=世界 +fml.generate_structures.title=生成结构 +fml.bonus_chest.title=奖励箱 +fml.world_options=世界选项... +fml.world_options.title=世界选项 +fml.game_rules.title=游戏规则 +fml.edit_game_rules=编辑游戏规则... +fml.edit_game_rules.title=编辑游戏规则 +fml.game_rule_changes.title=游戏规则更改 +fml.abandon_game_rule_changes=你确定要放弃未保存的游戏规则更改吗? +fml.death_messages.title=显示死亡消息 +fml.mob_loot.title=生物战利品掉落 +fml.destructive_mob_actions.title=允许破坏性生物行为 +fml.keep_inventory.title=死亡后保留物品栏 +fml.spectators_generate_terrain.title=允许旁观者生成地形 +fml.spawn_mobs.title=生成生物 +fml.advance_time.title=游戏内时间流逝 +fml.update_weather.title=天气更替 + forge.container.enchant.limitedEnchantability=附魔能力限制 attribute.name.generic.reachDistance=触及半径 attribute.name.forge.swimSpeed=游泳速度 From 083ceca99fcc592e49e3801357b886e081b4e7de Mon Sep 17 00:00:00 2001 From: gardenevery Date: Wed, 1 Apr 2026 17:31:37 +0800 Subject: [PATCH 02/11] optimize world options --- .../client/gui/GuiOptions.java.patch | 39 ++++----- .../client/gui/EditGameRulesGui.java | 83 +++++++++---------- .../client/gui/WorldOptionsGui.java | 6 +- 3 files changed, 56 insertions(+), 72 deletions(-) diff --git a/patches/minecraft/net/minecraft/client/gui/GuiOptions.java.patch b/patches/minecraft/net/minecraft/client/gui/GuiOptions.java.patch index 6fe5adf74..d978b9e5c 100644 --- a/patches/minecraft/net/minecraft/client/gui/GuiOptions.java.patch +++ b/patches/minecraft/net/minecraft/client/gui/GuiOptions.java.patch @@ -1,37 +1,26 @@ --- before/net/minecraft/client/gui/GuiOptions.java +++ after/net/minecraft/client/gui/GuiOptions.java -@@ -64,28 +64,9 @@ - if (this.mc.world != null) +@@ -61,7 +61,7 @@ + i++; + } + +- if (this.mc.world != null) ++ if (this.mc.world != null && !this.mc.player.canUseCommand(2, "gamerule")) { EnumDifficulty enumdifficulty = this.mc.world.getDifficulty(); -- this.difficultyButton = new GuiButton( -- 108, this.width / 2 - 155 + i % 2 * 160, this.height / 6 - 12 + 24 * (i >> 1), 150, 20, this.getDifficultyText(enumdifficulty) -- ); -- this.buttonList.add(this.difficultyButton); -- -- if (this.mc.isSingleplayer() && !this.mc.world.getWorldInfo().isHardcoreModeEnabled()) -- { -- this.difficultyButton.setWidth(this.difficultyButton.getButtonWidth() - 20); -- this.lockButton = new GuiLockIconButton( -- 109, this.difficultyButton.x + this.difficultyButton.getButtonWidth(), this.difficultyButton.y -- ); -- this.buttonList.add(this.lockButton); -- this.lockButton.setLocked(this.mc.world.getWorldInfo().isDifficultyLocked()); -- this.lockButton.enabled = !this.lockButton.isLocked(); -- this.difficultyButton.enabled = !this.lockButton.isLocked(); -- } -- else -- { -- this.difficultyButton.enabled = false; -- } -+ this.buttonList.add(new GuiButton(107, this.width / 2 + 5, this.height / 6 - 12, 150, 20, I18n.format("fml.world_options"))); - } + this.difficultyButton = new GuiButton( +@@ -84,8 +84,8 @@ + { + this.difficultyButton.enabled = false; + } +- } - else ++ } else if (this.mc.world != null && this.mc.player.canUseCommand(2, "gamerule")) this.buttonList.add(new GuiButton(107, this.width / 2 + 5, this.height / 6 - 12, 150, 20, I18n.format("fml.world_options"))); + else if (false) // removed realms button { this.buttonList .add( -@@ -241,6 +222,11 @@ +@@ -241,6 +241,11 @@ { this.mc.gameSettings.saveOptions(); this.mc.displayGuiScreen(new GuiScreenOptionsSounds(this, this.settings)); diff --git a/src/main/java/com/cleanroommc/client/gui/EditGameRulesGui.java b/src/main/java/com/cleanroommc/client/gui/EditGameRulesGui.java index 9c28a6695..e3e67ff44 100644 --- a/src/main/java/com/cleanroommc/client/gui/EditGameRulesGui.java +++ b/src/main/java/com/cleanroommc/client/gui/EditGameRulesGui.java @@ -1,7 +1,5 @@ package com.cleanroommc.client.gui; -import java.io.IOException; - import net.minecraft.client.Minecraft; import net.minecraft.client.gui.GuiButton; import net.minecraft.client.gui.GuiScreen; @@ -14,11 +12,11 @@ @SideOnly(Side.CLIENT) public class EditGameRulesGui extends GuiScreen implements GuiYesNoCallback { private final GuiScreen parent; - private final boolean[] ruleStates = new boolean[8]; - private final boolean[] originalStates = new boolean[8]; + private final boolean[] ruleStates; + private final boolean[] originalStates; private boolean changed = false; - private final String[] titles = { + private static final String[] TITLES = { "fml.death_messages.title", "fml.mob_loot.title", "fml.destructive_mob_actions.title", @@ -29,7 +27,7 @@ public class EditGameRulesGui extends GuiScreen implements GuiYesNoCallback { "fml.update_weather.title" }; - private final String[] ruleKeys = { + private static final String[] RULE_KEYS = { "showDeathMessages", "doMobLoot", "mobGriefing", @@ -42,31 +40,36 @@ public class EditGameRulesGui extends GuiScreen implements GuiYesNoCallback { public EditGameRulesGui(GuiScreen parentIn) { this.parent = parentIn; + this.ruleStates = new boolean[RULE_KEYS.length]; + this.originalStates = new boolean[RULE_KEYS.length]; + loadRulesFromWorld(); } - @Override - public void initGui() { - var world = Minecraft.getMinecraft().world; - if (world != null) { - var gameRules = world.getGameRules(); - for (int i = 0; i < ruleKeys.length; i++) { - ruleStates[i] = gameRules.getBoolean(ruleKeys[i]); + private void loadRulesFromWorld() { + var mc = Minecraft.getMinecraft(); + if (mc.world != null) { + var gameRules = mc.world.getGameRules(); + for (int i = 0; i < RULE_KEYS.length; i++) { + ruleStates[i] = gameRules.getBoolean(RULE_KEYS[i]); originalStates[i] = ruleStates[i]; } } else { - for (int i = 0; i < ruleStates.length; i++) { + for (int i = 0; i < RULE_KEYS.length; i++) { ruleStates[i] = false; originalStates[i] = false; } } + } - this.buttonList.add(new GuiButton(0, this.width / 2 - 154, this.height / 6 + 180, 150, 20, - I18n.format("gui.done"))); - this.buttonList.add(new GuiButton(1, this.width / 2 + 4, this.height / 6 + 180, 150, 20, - I18n.format("gui.cancel"))); + @Override + public void initGui() { + this.buttonList.add(new GuiButton(0, this.width / 2 - 154, this.height / 6 + 180, 150, + 20, I18n.format("gui.done"))); + this.buttonList.add(new GuiButton(1, this.width / 2 + 4, this.height / 6 + 180, 150, + 20, I18n.format("gui.cancel"))); - int lineHeight = 170 / (titles.length - 1); - for (int i = 0; i < titles.length; i++) { + int lineHeight = 170 / (TITLES.length - 1); + for (int i = 0; i < TITLES.length; i++) { int y = 30 + lineHeight * i; int buttonId = 2 + i; int x = this.width / 2 + 63; @@ -93,42 +96,36 @@ protected void actionPerformed(GuiButton button) { if (index >= 0 && index < ruleStates.length) { ruleStates[index] = !ruleStates[index]; button.displayString = ruleStates[index] ? I18n.format("gui.yes") : I18n.format("gui.no"); - if (ruleStates[index] != originalStates[index]) { - setChanged(true); - } else { - boolean anyChanged = false; - for (int i = 0; i < ruleStates.length; i++) { - if (ruleStates[i] != originalStates[i]) { - anyChanged = true; - break; - } - } - - if (!anyChanged) { - setChanged(false); + boolean anyChanged = false; + for (int i = 0; i < ruleStates.length; i++) { + if (ruleStates[i] != originalStates[i]) { + anyChanged = true; + break; } } + setChanged(anyChanged); } } } } private void applyChanges() { - var world = Minecraft.getMinecraft().world; - for (int i = 0; i < ruleKeys.length; i++) { + var mc = Minecraft.getMinecraft(); + for (int i = 0; i < RULE_KEYS.length; i++) { if (ruleStates[i] != originalStates[i]) { - var command = String.format("/gamerule %s %s", ruleKeys[i], ruleStates[i]); + var command = String.format("/gamerule %s %s", RULE_KEYS[i], ruleStates[i]); mc.player.sendChatMessage(command); - if (world != null) { - world.getGameRules().setOrCreateGameRule(ruleKeys[i], Boolean.toString(ruleStates[i])); + if (mc.world != null) { + mc.world.getGameRules().setOrCreateGameRule(RULE_KEYS[i], Boolean.toString(ruleStates[i])); } } } + System.arraycopy(ruleStates, 0, originalStates, 0, ruleStates.length); setChanged(false); } @Override - protected void keyTyped(char typedChar, int keyCode) throws IOException { + protected void keyTyped(char typedChar, int keyCode) throws java.io.IOException { if (keyCode == 1) { onCancel(); } else { @@ -137,7 +134,7 @@ protected void keyTyped(char typedChar, int keyCode) throws IOException { } private void onCancel() { - if (this.isChange()) { + if (isChange()) { this.mc.displayGuiScreen(new GuiYesNo(this, I18n.format("fml.game_rule_changes.title"), I18n.format("fml.abandon_game_rule_changes"), @@ -152,10 +149,10 @@ public void drawScreen(int mouseX, int mouseY, float partialTicks) { this.drawDefaultBackground(); this.drawCenteredString(this.fontRenderer, I18n.format("fml.edit_game_rules.title"), this.width / 2, 4, 0xFFFFFF); - int lineHeight = 170 / (titles.length - 1); - for (int i = 0; i < titles.length; i++) { + int lineHeight = 170 / (TITLES.length - 1); + for (int i = 0; i < TITLES.length; i++) { int y = 30 + lineHeight * i; - this.drawCenteredString(this.fontRenderer, I18n.format(titles[i]), this.width / 2 - 80, y, 0xFFFFFF); + this.drawCenteredString(this.fontRenderer, I18n.format(TITLES[i]), this.width / 2 - 80, y, 0xFFFFFF); } super.drawScreen(mouseX, mouseY, partialTicks); } diff --git a/src/main/java/com/cleanroommc/client/gui/WorldOptionsGui.java b/src/main/java/com/cleanroommc/client/gui/WorldOptionsGui.java index 162ba167f..b1fb79d90 100644 --- a/src/main/java/com/cleanroommc/client/gui/WorldOptionsGui.java +++ b/src/main/java/com/cleanroommc/client/gui/WorldOptionsGui.java @@ -33,10 +33,8 @@ public void initGui() { this.buttonList.add(this.difficultyButton); this.buttonList.add(this.lockButton); - var editGameRulesButton = new GuiButton(2, this.width / 2 + 4, this.height / 3 - 22, 150, - 20, I18n.format("fml.edit_game_rules")); - editGameRulesButton.enabled = this.mc.player.canUseCommand(2, "gamerule"); - this.buttonList.add(editGameRulesButton); + this.buttonList.add(new GuiButton(2, this.width / 2 + 4, this.height / 3 - 22, 150, + 20, I18n.format("fml.edit_game_rules"))); this.buttonList.add(new GuiButton(3, this.width / 2 - 100, this.height - 26, I18n.format("gui.done"))); } From 36ddb42701b1a52bcff4b34d55e8291486e96945 Mon Sep 17 00:00:00 2001 From: gardenevery Date: Wed, 1 Apr 2026 17:44:18 +0800 Subject: [PATCH 03/11] optimize patch --- .../client/gui/GuiCreateWorld.java.patch | 22 +++++++++---------- 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/patches/minecraft/net/minecraft/client/gui/GuiCreateWorld.java.patch b/patches/minecraft/net/minecraft/client/gui/GuiCreateWorld.java.patch index 40f486a5a..c0a844dc6 100644 --- a/patches/minecraft/net/minecraft/client/gui/GuiCreateWorld.java.patch +++ b/patches/minecraft/net/minecraft/client/gui/GuiCreateWorld.java.patch @@ -176,11 +176,10 @@ } } -@@ -382,12 +412,16 @@ - private void showMoreWorldOptions(boolean toggle) +@@ -383,11 +413,17 @@ { this.inMoreWorldOptionsDisplay = toggle; -- + + this.btnWorld.visible = true; + this.btnGame.visible = true; + this.btnWorld.enabled = !toggle; @@ -189,23 +188,22 @@ { this.btnGameMode.visible = !this.inMoreWorldOptionsDisplay; this.btnGameMode.enabled = false; -- + + this.btnAllowCommands.visible = false; + this.btnDifficulty.visible = false; if (this.savedGameMode == null) { this.savedGameMode = this.gameMode; -@@ -404,7 +438,8 @@ - { +@@ -405,6 +441,8 @@ this.btnGameMode.visible = !this.inMoreWorldOptionsDisplay; this.btnGameMode.enabled = true; -- + + this.btnAllowCommands.visible = !this.inMoreWorldOptionsDisplay; + this.btnDifficulty.visible = !this.inMoreWorldOptionsDisplay; if (this.savedGameMode != null) { this.gameMode = this.savedGameMode; -@@ -414,23 +449,14 @@ +@@ -414,23 +452,14 @@ this.btnMapFeatures.visible = this.inMoreWorldOptionsDisplay && WorldType.WORLD_TYPES[this.selectedIndex] != WorldType.CUSTOMIZED; this.btnBonusItems.visible = this.inMoreWorldOptionsDisplay; this.btnMapType.visible = this.inMoreWorldOptionsDisplay; @@ -231,7 +229,7 @@ } } -@@ -460,6 +486,23 @@ +@@ -460,6 +489,23 @@ @Override protected void mouseClicked(int mouseX, int mouseY, int mouseButton) throws IOException { @@ -255,7 +253,7 @@ super.mouseClicked(mouseX, mouseY, mouseButton); if (this.inMoreWorldOptionsDisplay) -@@ -476,16 +519,14 @@ +@@ -476,16 +522,14 @@ public void drawScreen(int mouseX, int mouseY, float partialTicks) { this.drawDefaultBackground(); @@ -275,7 +273,7 @@ } if (this.btnAllowCommands.visible) -@@ -497,25 +538,12 @@ +@@ -497,25 +541,12 @@ if (WorldType.WORLD_TYPES[this.selectedIndex].hasInfoNotice()) { @@ -302,7 +300,7 @@ } super.drawScreen(mouseX, mouseY, partialTicks); -@@ -523,6 +551,7 @@ +@@ -523,6 +554,7 @@ public void recreateFromExistingWorld(WorldInfo original) { From a5edbd979ffe06833c1f747a19bcc4bed15b13db Mon Sep 17 00:00:00 2001 From: gardenevery Date: Wed, 1 Apr 2026 18:27:42 +0800 Subject: [PATCH 04/11] optimize patch --- .../net/minecraft/client/gui/GuiOptions.java.patch | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/patches/minecraft/net/minecraft/client/gui/GuiOptions.java.patch b/patches/minecraft/net/minecraft/client/gui/GuiOptions.java.patch index d978b9e5c..38bede772 100644 --- a/patches/minecraft/net/minecraft/client/gui/GuiOptions.java.patch +++ b/patches/minecraft/net/minecraft/client/gui/GuiOptions.java.patch @@ -9,18 +9,17 @@ { EnumDifficulty enumdifficulty = this.mc.world.getDifficulty(); this.difficultyButton = new GuiButton( -@@ -84,8 +84,8 @@ - { +@@ -85,7 +85,8 @@ this.difficultyButton.enabled = false; } -- } + } - else -+ } else if (this.mc.world != null && this.mc.player.canUseCommand(2, "gamerule")) this.buttonList.add(new GuiButton(107, this.width / 2 + 5, this.height / 6 - 12, 150, 20, I18n.format("fml.world_options"))); ++ else if (this.mc.world != null && this.mc.player.canUseCommand(2, "gamerule")) this.buttonList.add(new GuiButton(107, this.width / 2 + 5, this.height / 6 - 12, 150, 20, I18n.format("fml.world_options"))); + else if (false) // removed realms button { this.buttonList .add( -@@ -241,6 +241,11 @@ +@@ -241,6 +242,11 @@ { this.mc.gameSettings.saveOptions(); this.mc.displayGuiScreen(new GuiScreenOptionsSounds(this, this.settings)); From 791ec18195a1b074cee9512f82441602664d1161 Mon Sep 17 00:00:00 2001 From: gardenevery Date: Wed, 1 Apr 2026 22:48:31 +0800 Subject: [PATCH 05/11] optimize EditGameRulesGui --- .../client/gui/EditGameRulesGui.java | 47 +++++++++---------- 1 file changed, 22 insertions(+), 25 deletions(-) diff --git a/src/main/java/com/cleanroommc/client/gui/EditGameRulesGui.java b/src/main/java/com/cleanroommc/client/gui/EditGameRulesGui.java index e3e67ff44..cf088af33 100644 --- a/src/main/java/com/cleanroommc/client/gui/EditGameRulesGui.java +++ b/src/main/java/com/cleanroommc/client/gui/EditGameRulesGui.java @@ -49,12 +49,12 @@ private void loadRulesFromWorld() { var mc = Minecraft.getMinecraft(); if (mc.world != null) { var gameRules = mc.world.getGameRules(); - for (int i = 0; i < RULE_KEYS.length; i++) { + for (int i = 0; i < 8; i++) { ruleStates[i] = gameRules.getBoolean(RULE_KEYS[i]); originalStates[i] = ruleStates[i]; } } else { - for (int i = 0; i < RULE_KEYS.length; i++) { + for (int i = 0; i < 8; i++) { ruleStates[i] = false; originalStates[i] = false; } @@ -63,18 +63,17 @@ private void loadRulesFromWorld() { @Override public void initGui() { - this.buttonList.add(new GuiButton(0, this.width / 2 - 154, this.height / 6 + 180, 150, + this.buttonList.add(new GuiButton(8, this.width / 2 - 154, this.height / 6 + 180, 150, 20, I18n.format("gui.done"))); - this.buttonList.add(new GuiButton(1, this.width / 2 + 4, this.height / 6 + 180, 150, + this.buttonList.add(new GuiButton(9, this.width / 2 + 4, this.height / 6 + 180, 150, 20, I18n.format("gui.cancel"))); - int lineHeight = 170 / (TITLES.length - 1); - for (int i = 0; i < TITLES.length; i++) { + int lineHeight = 170 / 7; + for (int i = 0; i < 8; i++) { int y = 30 + lineHeight * i; - int buttonId = 2 + i; int x = this.width / 2 + 63; var buttonText = ruleStates[i] ? I18n.format("gui.yes") : I18n.format("gui.no"); - var btn = new GuiButton(buttonId, x, y - 6, 45, 20, buttonText); + var btn = new GuiButton(i, x, y - 6, 45, 20, buttonText); this.buttonList.add(btn); } } @@ -86,32 +85,30 @@ protected void actionPerformed(GuiButton button) { } switch (button.id) { - case 0 -> { + case 8 -> { applyChanges(); this.mc.displayGuiScreen(this.parent); } - case 1 -> onCancel(); + case 9 -> onCancel(); default -> { - int index = button.id - 2; - if (index >= 0 && index < ruleStates.length) { - ruleStates[index] = !ruleStates[index]; - button.displayString = ruleStates[index] ? I18n.format("gui.yes") : I18n.format("gui.no"); - boolean anyChanged = false; - for (int i = 0; i < ruleStates.length; i++) { - if (ruleStates[i] != originalStates[i]) { - anyChanged = true; - break; - } + int index = button.id; + ruleStates[index] = !ruleStates[index]; + button.displayString = ruleStates[index] ? I18n.format("gui.yes") : I18n.format("gui.no"); + boolean anyChanged = false; + for (int i = 0; i < 8; i++) { + if (ruleStates[i] != originalStates[i]) { + anyChanged = true; + break; } - setChanged(anyChanged); } + setChanged(anyChanged); } } } private void applyChanges() { var mc = Minecraft.getMinecraft(); - for (int i = 0; i < RULE_KEYS.length; i++) { + for (int i = 0; i < 8; i++) { if (ruleStates[i] != originalStates[i]) { var command = String.format("/gamerule %s %s", RULE_KEYS[i], ruleStates[i]); mc.player.sendChatMessage(command); @@ -149,10 +146,10 @@ public void drawScreen(int mouseX, int mouseY, float partialTicks) { this.drawDefaultBackground(); this.drawCenteredString(this.fontRenderer, I18n.format("fml.edit_game_rules.title"), this.width / 2, 4, 0xFFFFFF); - int lineHeight = 170 / (TITLES.length - 1); - for (int i = 0; i < TITLES.length; i++) { + int lineHeight = 170 / 7; + for (int i = 0; i < 8; i++) { int y = 30 + lineHeight * i; - this.drawCenteredString(this.fontRenderer, I18n.format(TITLES[i]), this.width / 2 - 80, y, 0xFFFFFF); + this.drawCenteredString(this.fontRenderer, I18n.format(TITLES[i]), this.width / 2 - 65, y, 0xFFFFFF); } super.drawScreen(mouseX, mouseY, partialTicks); } From cd2740fbb2725e912b6ae8b9db9ce563c7fd15d3 Mon Sep 17 00:00:00 2001 From: gardenevery Date: Thu, 2 Apr 2026 00:53:28 +0800 Subject: [PATCH 06/11] optimize patch --- .../client/gui/GuiCreateWorld.java.patch | 66 +++++++------------ 1 file changed, 25 insertions(+), 41 deletions(-) diff --git a/patches/minecraft/net/minecraft/client/gui/GuiCreateWorld.java.patch b/patches/minecraft/net/minecraft/client/gui/GuiCreateWorld.java.patch index c0a844dc6..2fc22191f 100644 --- a/patches/minecraft/net/minecraft/client/gui/GuiCreateWorld.java.patch +++ b/patches/minecraft/net/minecraft/client/gui/GuiCreateWorld.java.patch @@ -81,7 +81,7 @@ } this.btnMapType.displayString = I18n.format("selectWorld.mapType") -@@ -173,6 +183,16 @@ +@@ -173,6 +183,13 @@ { this.btnAllowCommands.displayString = this.btnAllowCommands.displayString + I18n.format("options.off"); } @@ -90,27 +90,23 @@ + this.btnDifficulty.displayString = I18n.format("options.difficulty") + ": " + I18n.format(net.minecraft.world.EnumDifficulty.HARD.getTranslationKey()); + this.btnDifficulty.enabled = false; + } -+ else -+ { -+ this.btnDifficulty.displayString = I18n.format("options.difficulty") + ": " + I18n.format(this.currentDifficulty.getTranslationKey()); -+ this.btnDifficulty.enabled = true; -+ } ++ else this.btnDifficulty.displayString = I18n.format("options.difficulty") + ": " + I18n.format(this.currentDifficulty.getTranslationKey()); ++ this.btnDifficulty.enabled = true; } public static String getUncollidingSaveDirName(ISaveFormat saveLoader, String name) -@@ -240,8 +260,10 @@ +@@ -240,8 +257,9 @@ } } + WorldType.WORLD_TYPES[this.selectedIndex].onGUICreateWorldPress(); -+ WorldSettings worldsettings = new WorldSettings( - i, GameType.getByName(this.gameMode), this.generateStructuresEnabled, this.hardCoreMode, WorldType.WORLD_TYPES[this.selectedIndex] + i, GameType.getByName(this.gameMode), this.generateStructuresEnabled, this.hardCoreMode, WorldType.WORLD_TYPES[this.selectedIndex], this.currentDifficulty ); worldsettings.setGeneratorOptions(this.chunkProviderSettingsJson); -@@ -257,9 +279,9 @@ +@@ -257,9 +275,9 @@ this.mc.launchIntegratedServer(this.saveDirName, this.worldNameField.getText().trim(), worldsettings); } @@ -122,7 +118,7 @@ } else if (button.id == 2) { -@@ -273,6 +295,8 @@ +@@ -273,6 +291,8 @@ this.hardCoreMode = false; this.gameMode = "hardcore"; this.hardCoreMode = true; @@ -131,7 +127,7 @@ this.btnAllowCommands.enabled = false; this.btnBonusItems.enabled = false; this.updateDisplayState(); -@@ -286,6 +310,12 @@ +@@ -286,6 +306,12 @@ this.hardCoreMode = false; this.gameMode = "creative"; @@ -144,7 +140,7 @@ this.updateDisplayState(); this.hardCoreMode = false; this.btnAllowCommands.enabled = true; -@@ -339,6 +369,7 @@ +@@ -339,6 +365,7 @@ this.chunkProviderSettingsJson = ""; this.updateDisplayState(); this.showMoreWorldOptions(this.inMoreWorldOptionsDisplay); @@ -152,7 +148,7 @@ } else if (button.id == 6) { -@@ -348,15 +379,14 @@ +@@ -348,15 +375,14 @@ } else if (button.id == 8) { @@ -176,7 +172,7 @@ } } -@@ -383,11 +413,17 @@ +@@ -383,8 +409,14 @@ { this.inMoreWorldOptionsDisplay = toggle; @@ -186,15 +182,12 @@ + this.btnGame.enabled = toggle; if (WorldType.WORLD_TYPES[this.selectedIndex] == WorldType.DEBUG_ALL_BLOCK_STATES) { ++ this.btnAllowCommands.visible = false; ++ this.btnDifficulty.visible = false; this.btnGameMode.visible = !this.inMoreWorldOptionsDisplay; this.btnGameMode.enabled = false; -+ this.btnAllowCommands.visible = false; -+ this.btnDifficulty.visible = false; - if (this.savedGameMode == null) - { - this.savedGameMode = this.gameMode; -@@ -405,6 +441,8 @@ +@@ -405,6 +437,8 @@ this.btnGameMode.visible = !this.inMoreWorldOptionsDisplay; this.btnGameMode.enabled = true; @@ -203,7 +196,7 @@ if (this.savedGameMode != null) { this.gameMode = this.savedGameMode; -@@ -414,23 +452,14 @@ +@@ -414,23 +448,14 @@ this.btnMapFeatures.visible = this.inMoreWorldOptionsDisplay && WorldType.WORLD_TYPES[this.selectedIndex] != WorldType.CUSTOMIZED; this.btnBonusItems.visible = this.inMoreWorldOptionsDisplay; this.btnMapType.visible = this.inMoreWorldOptionsDisplay; @@ -229,31 +222,22 @@ } } -@@ -460,6 +489,23 @@ +@@ -460,6 +485,14 @@ @Override protected void mouseClicked(int mouseX, int mouseY, int mouseButton) throws IOException { -+ if (this.btnMapType.mousePressed(this.mc, mouseX, mouseY)) { -+ if (mouseButton == 1) { -+ -+ do { -+ this.selectedIndex--; -+ -+ if (this.selectedIndex < 0) { -+ this.selectedIndex = WorldType.WORLD_TYPES.length - 1; -+ } -+ } while (!this.canSelectCurWorldType()); -+ -+ this.chunkProviderSettingsJson = ""; -+ this.updateDisplayState(); -+ if (this.inMoreWorldOptionsDisplay) this.showMoreWorldOptions(true); -+ } ++ if (this.btnMapType.mousePressed(this.mc, mouseX, mouseY) && mouseButton == 1) { ++ do { ++ this.selectedIndex = (this.selectedIndex - 1 + WorldType.WORLD_TYPES.length) % WorldType.WORLD_TYPES.length; ++ } while (!this.canSelectCurWorldType()); ++ this.chunkProviderSettingsJson = ""; ++ this.updateDisplayState(); ++ if (this.inMoreWorldOptionsDisplay) this.showMoreWorldOptions(true); + } -+ super.mouseClicked(mouseX, mouseY, mouseButton); if (this.inMoreWorldOptionsDisplay) -@@ -476,16 +522,14 @@ +@@ -476,16 +509,14 @@ public void drawScreen(int mouseX, int mouseY, float partialTicks) { this.drawDefaultBackground(); @@ -273,7 +257,7 @@ } if (this.btnAllowCommands.visible) -@@ -497,25 +541,12 @@ +@@ -497,25 +528,12 @@ if (WorldType.WORLD_TYPES[this.selectedIndex].hasInfoNotice()) { @@ -300,7 +284,7 @@ } super.drawScreen(mouseX, mouseY, partialTicks); -@@ -523,6 +554,7 @@ +@@ -523,6 +541,7 @@ public void recreateFromExistingWorld(WorldInfo original) { From 2b40f3cbb5a02de7152e6223c0f637a9f9ce625a Mon Sep 17 00:00:00 2001 From: gardenevery Date: Thu, 2 Apr 2026 05:47:40 +0800 Subject: [PATCH 07/11] optimize default resource pack --- .../ResourcePackListEntryDefault.java.patch | 29 +++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 patches/minecraft/net/minecraft/client/resources/ResourcePackListEntryDefault.java.patch diff --git a/patches/minecraft/net/minecraft/client/resources/ResourcePackListEntryDefault.java.patch b/patches/minecraft/net/minecraft/client/resources/ResourcePackListEntryDefault.java.patch new file mode 100644 index 000000000..7abcc095b --- /dev/null +++ b/patches/minecraft/net/minecraft/client/resources/ResourcePackListEntryDefault.java.patch @@ -0,0 +1,29 @@ +--- before/net/minecraft/client/resources/ResourcePackListEntryDefault.java ++++ after/net/minecraft/client/resources/ResourcePackListEntryDefault.java +@@ -24,4 +24,26 @@ + { + return false; + } ++ ++ @Override ++ protected boolean canMoveUp() ++ { ++ java.util.List list = this.resourcePacksGUI.getListContaining(this); ++ int i = list.indexOf(this); ++ return i > 0 && list.get(i - 1).showHoverOverlay(); ++ } ++ ++ @Override ++ protected boolean canMoveDown() ++ { ++ java.util.List list = this.resourcePacksGUI.getListContaining(this); ++ int i = list.indexOf(this); ++ return i >= 0 && i < list.size() - 1 && list.get(i + 1).showHoverOverlay(); ++ } ++ ++ @Override ++ protected boolean showHoverOverlay() ++ { ++ return true; ++ } + } From c1e39ac8abb351d51dfe3280ea8a92a474a472dd Mon Sep 17 00:00:00 2001 From: gardenevery Date: Thu, 2 Apr 2026 06:05:38 +0800 Subject: [PATCH 08/11] Revert "optimize default resource pack" This reverts commit 2b40f3cbb5a02de7152e6223c0f637a9f9ce625a. --- .../ResourcePackListEntryDefault.java.patch | 29 ------------------- 1 file changed, 29 deletions(-) delete mode 100644 patches/minecraft/net/minecraft/client/resources/ResourcePackListEntryDefault.java.patch diff --git a/patches/minecraft/net/minecraft/client/resources/ResourcePackListEntryDefault.java.patch b/patches/minecraft/net/minecraft/client/resources/ResourcePackListEntryDefault.java.patch deleted file mode 100644 index 7abcc095b..000000000 --- a/patches/minecraft/net/minecraft/client/resources/ResourcePackListEntryDefault.java.patch +++ /dev/null @@ -1,29 +0,0 @@ ---- before/net/minecraft/client/resources/ResourcePackListEntryDefault.java -+++ after/net/minecraft/client/resources/ResourcePackListEntryDefault.java -@@ -24,4 +24,26 @@ - { - return false; - } -+ -+ @Override -+ protected boolean canMoveUp() -+ { -+ java.util.List list = this.resourcePacksGUI.getListContaining(this); -+ int i = list.indexOf(this); -+ return i > 0 && list.get(i - 1).showHoverOverlay(); -+ } -+ -+ @Override -+ protected boolean canMoveDown() -+ { -+ java.util.List list = this.resourcePacksGUI.getListContaining(this); -+ int i = list.indexOf(this); -+ return i >= 0 && i < list.size() - 1 && list.get(i + 1).showHoverOverlay(); -+ } -+ -+ @Override -+ protected boolean showHoverOverlay() -+ { -+ return true; -+ } - } From 8df6fb7f81251032fc3eaa7be9f5666673e2de08 Mon Sep 17 00:00:00 2001 From: gardenevery Date: Thu, 2 Apr 2026 23:02:01 +0800 Subject: [PATCH 09/11] add restrictions screen --- .../client/gui/EditGameRulesGui.java | 7 +- .../client/gui/RestrictionsGui.java | 99 +++++++++++++++++++ .../client/gui/WorldOptionsGui.java | 11 ++- .../resources/assets/forge/lang/en_us.lang | 12 +++ .../resources/assets/forge/lang/zh_cn.lang | 12 +++ 5 files changed, 136 insertions(+), 5 deletions(-) create mode 100644 src/main/java/com/cleanroommc/client/gui/RestrictionsGui.java diff --git a/src/main/java/com/cleanroommc/client/gui/EditGameRulesGui.java b/src/main/java/com/cleanroommc/client/gui/EditGameRulesGui.java index cf088af33..e20cfcb5e 100644 --- a/src/main/java/com/cleanroommc/client/gui/EditGameRulesGui.java +++ b/src/main/java/com/cleanroommc/client/gui/EditGameRulesGui.java @@ -63,9 +63,9 @@ private void loadRulesFromWorld() { @Override public void initGui() { - this.buttonList.add(new GuiButton(8, this.width / 2 - 154, this.height / 6 + 180, 150, + this.buttonList.add(new GuiButton(8, this.width / 2 - 154, this.height - 26, 150, 20, I18n.format("gui.done"))); - this.buttonList.add(new GuiButton(9, this.width / 2 + 4, this.height / 6 + 180, 150, + this.buttonList.add(new GuiButton(9, this.width / 2 + 4, this.height - 26, 150, 20, I18n.format("gui.cancel"))); int lineHeight = 170 / 7; @@ -144,7 +144,8 @@ private void onCancel() { @Override public void drawScreen(int mouseX, int mouseY, float partialTicks) { this.drawDefaultBackground(); - this.drawCenteredString(this.fontRenderer, I18n.format("fml.edit_game_rules.title"), this.width / 2, 4, 0xFFFFFF); + this.drawCenteredString(this.fontRenderer, I18n.format("fml.edit_game_rules.title"), + this.width / 2, 4, 0xFFFFFF); int lineHeight = 170 / 7; for (int i = 0; i < 8; i++) { diff --git a/src/main/java/com/cleanroommc/client/gui/RestrictionsGui.java b/src/main/java/com/cleanroommc/client/gui/RestrictionsGui.java new file mode 100644 index 000000000..01b00bde5 --- /dev/null +++ b/src/main/java/com/cleanroommc/client/gui/RestrictionsGui.java @@ -0,0 +1,99 @@ +package com.cleanroommc.client.gui; + +import java.io.IOException; + +import net.minecraft.client.gui.GuiButton; +import net.minecraft.client.gui.GuiScreen; +import net.minecraft.client.gui.ScreenChatOptions; +import net.minecraft.client.resources.I18n; +import net.minecraft.entity.player.EntityPlayer.EnumChatVisibility; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; + +@SideOnly(Side.CLIENT) +public class RestrictionsGui extends GuiScreen { + private final GuiScreen parent; + + public RestrictionsGui(GuiScreen parentIn) { + this.parent = parentIn; + } + + @Override + public void initGui() { + if (this.mc.gameSettings.chatVisibility != EnumChatVisibility.FULL) { + this.buttonList.add(new GuiButton(0, this.width / 2 - 100, 80, I18n.format("fml.chat_settings_screen"))); + } + this.buttonList.add(new GuiButton(1, this.width / 2 - 100, this.height - 26, I18n.format("gui.done"))); + } + + @Override + protected void actionPerformed(GuiButton button) { + if (button.enabled) { + switch (button.id) { + case 0 -> this.mc.displayGuiScreen(new ScreenChatOptions(this.parent, this.mc.gameSettings)); + case 1 -> this.mc.displayGuiScreen(this.parent); + } + } + } + + @Override + protected void keyTyped(char typedChar, int keyCode) throws IOException { + if (keyCode == 1) { + this.mc.gameSettings.saveOptions(); + this.mc.displayGuiScreen(this.parent); + } else { + super.keyTyped(typedChar, keyCode); + } + } + + @Override + public void drawScreen(int mouseX, int mouseY, float partialTicks) { + this.drawDefaultBackground(); + var enumChatVisibility = this.mc.gameSettings.chatVisibility; + this.drawCenteredString(this.fontRenderer, I18n.format("fml.restrictions.title"), + this.width / 2, 12, 0xFFFFFF); + + if (enumChatVisibility != EnumChatVisibility.FULL) { + this.drawCenteredString(this.fontRenderer, I18n.format("fml.chat_restricted"), + this.width / 2, 67, 0xFF0000); + } + + this.drawChatStatus(enumChatVisibility); + super.drawScreen(mouseX, mouseY, partialTicks); + } + + private void drawChatStatus(EnumChatVisibility enumChatVisibility) { + switch (enumChatVisibility) { + case FULL -> { + this.drawCenteredString(this.fontRenderer, I18n.format("fml.send_chat_messages"), + this.width / 2, 67, 0x00FF00); + this.drawCenteredString(this.fontRenderer, I18n.format("fml.send_commands"), + this.width / 2, 76, 0x00FF00); + this.drawCenteredString(this.fontRenderer, I18n.format("fml.receive_system_messages"), + this.width / 2, 85, 0x00FF00); + this.drawCenteredString(this.fontRenderer, I18n.format("fml.receive_player_messages"), + this.width / 2, 94, 0x00FF00); + } + case SYSTEM -> { + this.drawCenteredString(this.fontRenderer, I18n.format("fml.cannot_send_chat_messages"), + this.width / 2, 114, 0xFF0000); + this.drawCenteredString(this.fontRenderer, I18n.format("fml.send_commands"), + this.width / 2, 123, 0x00FF00); + this.drawCenteredString(this.fontRenderer, I18n.format("fml.receive_system_messages"), + this.width / 2, 132, 0x00FF00); + this.drawCenteredString(this.fontRenderer, I18n.format("fml.cannot_receive_player_messages"), + this.width / 2, 141, 0xFF0000); + } + case HIDDEN -> { + this.drawCenteredString(this.fontRenderer, I18n.format("fml.cannot_send_chat_messages"), + this.width / 2, 114, 0xFF0000); + this.drawCenteredString(this.fontRenderer, I18n.format("fml.cannot_send_commands"), + this.width / 2, 123, 0xFF0000); + this.drawCenteredString(this.fontRenderer, I18n.format("fml.cannot_receive_system_messages"), + this.width / 2, 132, 0xFF0000); + this.drawCenteredString(this.fontRenderer, I18n.format("fml.cannot_receive_player_messages"), + this.width / 2, 141, 0xFF0000); + } + } + } +} diff --git a/src/main/java/com/cleanroommc/client/gui/WorldOptionsGui.java b/src/main/java/com/cleanroommc/client/gui/WorldOptionsGui.java index b1fb79d90..dc93c00fc 100644 --- a/src/main/java/com/cleanroommc/client/gui/WorldOptionsGui.java +++ b/src/main/java/com/cleanroommc/client/gui/WorldOptionsGui.java @@ -35,7 +35,9 @@ public void initGui() { this.buttonList.add(this.lockButton); this.buttonList.add(new GuiButton(2, this.width / 2 + 4, this.height / 3 - 22, 150, 20, I18n.format("fml.edit_game_rules"))); - this.buttonList.add(new GuiButton(3, this.width / 2 - 100, this.height - 26, I18n.format("gui.done"))); + this.buttonList.add(new GuiButton(3, this.width / 2 - 154, this.height / 3 + 2, 150, + 20, I18n.format("fml.restrictions"))); + this.buttonList.add(new GuiButton(4, this.width / 2 - 100, this.height - 26, I18n.format("gui.done"))); } @Override @@ -57,6 +59,10 @@ protected void actionPerformed(GuiButton button) { this.mc.displayGuiScreen(new EditGameRulesGui(this)); } case 3 -> { + this.mc.gameSettings.saveOptions(); + this.mc.displayGuiScreen(new RestrictionsGui(this)); + } + case 4 -> { this.mc.gameSettings.saveOptions(); this.mc.displayGuiScreen(this.parent); } @@ -88,7 +94,8 @@ protected void keyTyped(char typedChar, int keyCode) throws IOException { @Override public void drawScreen(int mouseX, int mouseY, float partialTicks) { this.drawDefaultBackground(); - this.drawCenteredString(this.fontRenderer, I18n.format("fml.world_options.title"), this.width / 2, 12, 0xFFFFFF); + this.drawCenteredString(this.fontRenderer, I18n.format("fml.world_options.title"), + this.width / 2, 12, 0xFFFFFF); super.drawScreen(mouseX, mouseY, partialTicks); } diff --git a/src/main/resources/assets/forge/lang/en_us.lang b/src/main/resources/assets/forge/lang/en_us.lang index 3ed553104..794060c60 100644 --- a/src/main/resources/assets/forge/lang/en_us.lang +++ b/src/main/resources/assets/forge/lang/en_us.lang @@ -296,6 +296,18 @@ fml.spectators_generate_terrain.title=Allow spectators to generate terrain fml.spawn_mobs.title=Spawn mobs fml.advance_time.title=Advance time of day fml.update_weather.title=Update weather +fml.restrictions=Restrictions... +fml.restrictions.title=Restrictions +fml.chat_settings_screen=Go to the Chat Settings screen +fml.chat_restricted=Player chat is restricted in client settings. +fml.send_chat_messages=You can send chat messages +fml.cannot_send_chat_messages=You can't send chat messages +fml.send_commands=You can send commands +fml.cannot_send_commands=You can't send commands +fml.receive_system_messages=You can receive system messages from the server +fml.cannot_receive_system_messages=You can't receive system messages from the server +fml.receive_player_messages=You can receive messages from players +fml.cannot_receive_player_messages=You can't receive messages from players forge.container.enchant.limitedEnchantability=Limited Enchantability attribute.name.generic.reachDistance=Reach Distance diff --git a/src/main/resources/assets/forge/lang/zh_cn.lang b/src/main/resources/assets/forge/lang/zh_cn.lang index ada4a5904..5f8ad8366 100644 --- a/src/main/resources/assets/forge/lang/zh_cn.lang +++ b/src/main/resources/assets/forge/lang/zh_cn.lang @@ -258,6 +258,18 @@ fml.spectators_generate_terrain.title=允许旁观者生成地形 fml.spawn_mobs.title=生成生物 fml.advance_time.title=游戏内时间流逝 fml.update_weather.title=天气更替 +fml.restrictions=行为限制... +fml.restrictions.title=行为限制 +fml.chat_settings_screen=前往聊天设置屏幕 +fml.chat_restricted=玩家聊天功能受客户端设置限制。 +fml.send_chat_messages=你可以发送聊天消息 +fml.cannot_send_chat_messages=你无法发送聊天消息 +fml.send_commands=你可以发送命令 +fml.cannot_send_commands=你无法发送命令 +fml.receive_system_messages=你可以从服务器收到系统消息 +fml.cannot_receive_system_messages=你无法从服务器收到系统消息 +fml.receive_player_messages=你可以收到来自玩家的消息 +fml.cannot_receive_player_messages=你无法收到来自玩家的消息 forge.container.enchant.limitedEnchantability=附魔能力限制 attribute.name.generic.reachDistance=触及半径 From 5959b4f0cfa76e0cb5b037074df2ab480d27b6ba Mon Sep 17 00:00:00 2001 From: gardenevery Date: Fri, 3 Apr 2026 01:02:16 +0800 Subject: [PATCH 10/11] optimize restrictions screen --- .../cleanroommc/client/gui/RestrictionsGui.java | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/src/main/java/com/cleanroommc/client/gui/RestrictionsGui.java b/src/main/java/com/cleanroommc/client/gui/RestrictionsGui.java index 01b00bde5..d7c11230c 100644 --- a/src/main/java/com/cleanroommc/client/gui/RestrictionsGui.java +++ b/src/main/java/com/cleanroommc/client/gui/RestrictionsGui.java @@ -39,7 +39,6 @@ protected void actionPerformed(GuiButton button) { @Override protected void keyTyped(char typedChar, int keyCode) throws IOException { if (keyCode == 1) { - this.mc.gameSettings.saveOptions(); this.mc.displayGuiScreen(this.parent); } else { super.keyTyped(typedChar, keyCode); @@ -49,16 +48,9 @@ protected void keyTyped(char typedChar, int keyCode) throws IOException { @Override public void drawScreen(int mouseX, int mouseY, float partialTicks) { this.drawDefaultBackground(); - var enumChatVisibility = this.mc.gameSettings.chatVisibility; this.drawCenteredString(this.fontRenderer, I18n.format("fml.restrictions.title"), this.width / 2, 12, 0xFFFFFF); - - if (enumChatVisibility != EnumChatVisibility.FULL) { - this.drawCenteredString(this.fontRenderer, I18n.format("fml.chat_restricted"), - this.width / 2, 67, 0xFF0000); - } - - this.drawChatStatus(enumChatVisibility); + this.drawChatStatus(this.mc.gameSettings.chatVisibility); super.drawScreen(mouseX, mouseY, partialTicks); } @@ -75,6 +67,8 @@ private void drawChatStatus(EnumChatVisibility enumChatVisibility) { this.width / 2, 94, 0x00FF00); } case SYSTEM -> { + this.drawCenteredString(this.fontRenderer, I18n.format("fml.chat_restricted"), + this.width / 2, 67, 0xFF0000); this.drawCenteredString(this.fontRenderer, I18n.format("fml.cannot_send_chat_messages"), this.width / 2, 114, 0xFF0000); this.drawCenteredString(this.fontRenderer, I18n.format("fml.send_commands"), @@ -85,6 +79,8 @@ private void drawChatStatus(EnumChatVisibility enumChatVisibility) { this.width / 2, 141, 0xFF0000); } case HIDDEN -> { + this.drawCenteredString(this.fontRenderer, I18n.format("fml.chat_restricted"), + this.width / 2, 67, 0xFF0000); this.drawCenteredString(this.fontRenderer, I18n.format("fml.cannot_send_chat_messages"), this.width / 2, 114, 0xFF0000); this.drawCenteredString(this.fontRenderer, I18n.format("fml.cannot_send_commands"), From 71178ca14ca6726c4048bfa8995366b680a6cb6d Mon Sep 17 00:00:00 2001 From: gardenevery Date: Sat, 4 Apr 2026 19:57:09 +0800 Subject: [PATCH 11/11] optimize the handling of the exit screen --- .../client/gui/EditGameRulesGui.java | 6 ++-- .../client/gui/RestrictionsGui.java | 4 +-- .../client/gui/WorldOptionsGui.java | 35 ++++++++++++++----- 3 files changed, 30 insertions(+), 15 deletions(-) diff --git a/src/main/java/com/cleanroommc/client/gui/EditGameRulesGui.java b/src/main/java/com/cleanroommc/client/gui/EditGameRulesGui.java index e20cfcb5e..5d4206184 100644 --- a/src/main/java/com/cleanroommc/client/gui/EditGameRulesGui.java +++ b/src/main/java/com/cleanroommc/client/gui/EditGameRulesGui.java @@ -68,9 +68,8 @@ public void initGui() { this.buttonList.add(new GuiButton(9, this.width / 2 + 4, this.height - 26, 150, 20, I18n.format("gui.cancel"))); - int lineHeight = 170 / 7; for (int i = 0; i < 8; i++) { - int y = 30 + lineHeight * i; + int y = 30 + 24 * i; int x = this.width / 2 + 63; var buttonText = ruleStates[i] ? I18n.format("gui.yes") : I18n.format("gui.no"); var btn = new GuiButton(i, x, y - 6, 45, 20, buttonText); @@ -147,9 +146,8 @@ public void drawScreen(int mouseX, int mouseY, float partialTicks) { this.drawCenteredString(this.fontRenderer, I18n.format("fml.edit_game_rules.title"), this.width / 2, 4, 0xFFFFFF); - int lineHeight = 170 / 7; for (int i = 0; i < 8; i++) { - int y = 30 + lineHeight * i; + int y = 30 + 24 * i; this.drawCenteredString(this.fontRenderer, I18n.format(TITLES[i]), this.width / 2 - 65, y, 0xFFFFFF); } super.drawScreen(mouseX, mouseY, partialTicks); diff --git a/src/main/java/com/cleanroommc/client/gui/RestrictionsGui.java b/src/main/java/com/cleanroommc/client/gui/RestrictionsGui.java index d7c11230c..c59e94927 100644 --- a/src/main/java/com/cleanroommc/client/gui/RestrictionsGui.java +++ b/src/main/java/com/cleanroommc/client/gui/RestrictionsGui.java @@ -48,8 +48,8 @@ protected void keyTyped(char typedChar, int keyCode) throws IOException { @Override public void drawScreen(int mouseX, int mouseY, float partialTicks) { this.drawDefaultBackground(); - this.drawCenteredString(this.fontRenderer, I18n.format("fml.restrictions.title"), - this.width / 2, 12, 0xFFFFFF); + this.drawCenteredString(this.fontRenderer, I18n.format("fml.restrictions.title"), this.width / 2, + 12, 0xFFFFFF); this.drawChatStatus(this.mc.gameSettings.chatVisibility); super.drawScreen(mouseX, mouseY, partialTicks); } diff --git a/src/main/java/com/cleanroommc/client/gui/WorldOptionsGui.java b/src/main/java/com/cleanroommc/client/gui/WorldOptionsGui.java index dc93c00fc..72f52920d 100644 --- a/src/main/java/com/cleanroommc/client/gui/WorldOptionsGui.java +++ b/src/main/java/com/cleanroommc/client/gui/WorldOptionsGui.java @@ -6,6 +6,7 @@ import net.minecraft.client.gui.GuiLockIconButton; import net.minecraft.client.gui.GuiScreen; import net.minecraft.client.gui.GuiYesNo; +import net.minecraft.client.gui.GuiYesNoCallback; import net.minecraft.client.resources.I18n; import net.minecraft.world.EnumDifficulty; import net.minecraftforge.fml.relauncher.Side; @@ -23,21 +24,22 @@ public WorldOptionsGui(GuiScreen parentIn) { @Override public void initGui() { - this.difficultyButton = new GuiButton(0, this.width / 2 - 154, this.height / 3 - 22, - 130, 20, this.getDifficultyText(this.mc.world.getDifficulty())); + this.difficultyButton = new GuiButton(0, this.width / 2 - 154, this.height / 3 - 22, 130, + 20, this.getDifficultyText(this.mc.world.getDifficulty())); this.lockButton = new GuiLockIconButton(1, this.width / 2 - 24, this.height / 3 - 22); - this.lockButton.setLocked(this.mc.world.getWorldInfo().isDifficultyLocked()); - this.lockButton.enabled = !this.lockButton.isLocked(); - this.difficultyButton.enabled = !this.lockButton.isLocked(); - this.buttonList.add(this.difficultyButton); this.buttonList.add(this.lockButton); + this.buttonList.add(new GuiButton(2, this.width / 2 + 4, this.height / 3 - 22, 150, 20, I18n.format("fml.edit_game_rules"))); this.buttonList.add(new GuiButton(3, this.width / 2 - 154, this.height / 3 + 2, 150, 20, I18n.format("fml.restrictions"))); this.buttonList.add(new GuiButton(4, this.width / 2 - 100, this.height - 26, I18n.format("gui.done"))); + + this.lockButton.setLocked(this.mc.world.getWorldInfo().isDifficultyLocked()); + this.lockButton.enabled = !this.lockButton.isLocked(); + this.difficultyButton.enabled = !this.lockButton.isLocked(); } @Override @@ -48,7 +50,7 @@ protected void actionPerformed(GuiButton button) { this.mc.world.getWorldInfo().setDifficulty(EnumDifficulty.byId(this.mc.world.getDifficulty().getId() + 1)); this.difficultyButton.displayString = this.getDifficultyText(this.mc.world.getDifficulty()); } - case 1 -> this.mc.displayGuiScreen(new GuiYesNo(this, + case 1 -> this.mc.displayGuiScreen(new FixedGuiYesNo(this, I18n.format("difficulty.lock.title"), I18n.format("difficulty.lock.question", I18n.format(this.mc.world.getWorldInfo().getDifficulty().getTranslationKey())), @@ -94,12 +96,27 @@ protected void keyTyped(char typedChar, int keyCode) throws IOException { @Override public void drawScreen(int mouseX, int mouseY, float partialTicks) { this.drawDefaultBackground(); - this.drawCenteredString(this.fontRenderer, I18n.format("fml.world_options.title"), - this.width / 2, 12, 0xFFFFFF); + this.drawCenteredString(this.fontRenderer, I18n.format("fml.world_options.title"), this.width / 2, + 12, 0xFFFFFF); super.drawScreen(mouseX, mouseY, partialTicks); } public String getDifficultyText(EnumDifficulty difficulty) { return I18n.format("options.difficulty") + ": " + I18n.format(difficulty.getTranslationKey()); } + + private static class FixedGuiYesNo extends GuiYesNo { + public FixedGuiYesNo(GuiYesNoCallback parentScreenIn, String messageLine1In, String messageLine2In, int parentButtonClickedIdIn) { + super(parentScreenIn, messageLine1In, messageLine2In, parentButtonClickedIdIn); + } + + @Override + public void keyTyped(char typedChar, int keyCode) throws IOException { + if (keyCode == 1) { + this.parentScreen.confirmClicked(false, this.parentButtonClickedId); + } else { + super.keyTyped(typedChar, keyCode); + } + } + } }