Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 7 additions & 8 deletions build.gradle
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
plugins {
id "fabric-loom" version "${loom_version}"
id "net.fabricmc.fabric-loom" version "${loom_version}"
}

version = project.mod_version
Expand All @@ -15,11 +15,10 @@ repositories {

dependencies {
minecraft "com.mojang:minecraft:${project.minecraft_version}"
mappings "net.fabricmc:yarn:${project.yarn_mappings}:v2"
modImplementation "net.fabricmc:fabric-loader:${project.loader_version}"
modImplementation "net.fabricmc.fabric-api:fabric-api:${project.fabric_api_version}"
implementation "net.fabricmc:fabric-loader:${project.loader_version}"
implementation "net.fabricmc.fabric-api:fabric-api:${project.fabric_api_version}"

modImplementation "com.terraformersmc:modmenu:${project.modmenu_version}"
implementation "com.terraformersmc:modmenu:${project.modmenu_version}"

compileOnly "org.apache.commons:commons-compress:1.28.0"
compileOnly "commons-io:commons-io:2.20.0"
Expand All @@ -34,14 +33,14 @@ processResources {
}

tasks.withType(JavaCompile).configureEach {
it.options.release = 21
it.options.release = 25
}

java {
withSourcesJar()

sourceCompatibility = JavaVersion.VERSION_21
targetCompatibility = JavaVersion.VERSION_21
sourceCompatibility = JavaVersion.VERSION_25
targetCompatibility = JavaVersion.VERSION_25
}

jar {
Expand Down
13 changes: 6 additions & 7 deletions gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,15 @@ org.gradle.jvmargs=-Xmx1G
org.gradle.parallel=true

# Fabric Properties (https://fabricmc.net/develop)
minecraft_version=1.21.11
yarn_mappings=1.21.11+build.3
loader_version=0.18.2
loom_version=1.14-SNAPSHOT
minecraft_version=26.1
loader_version=0.18.5
loom_version=1.15-SNAPSHOT

# Mod Properties
mod_version = 1.4.5
maven_group=com.github.rashnain
archives_base_name = SaveMod-fabric-mc1.21.11
archives_base_name = SaveMod-fabric-mc26.1

# Dependencies
fabric_api_version=0.139.5+1.21.11
modmenu_version=17.0.0-alpha.1
fabric_api_version=0.144.3+26.1
modmenu_version=18.0.0-alpha.8
2 changes: 1 addition & 1 deletion gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-9.2.1-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-9.4.1-bin.zip
networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME
Expand Down
25 changes: 13 additions & 12 deletions src/main/java/com/github/rashnain/savemod/SaveMod.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,36 +3,34 @@
import com.github.rashnain.savemod.config.SaveModConfig;
import com.github.rashnain.savemod.gui.NameSaveScreen;
import com.github.rashnain.savemod.gui.SelectSaveScreen;
import com.mojang.blaze3d.platform.InputConstants;
import net.fabricmc.api.ClientModInitializer;
import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents;
import net.fabricmc.fabric.api.client.keybinding.v1.KeyBindingHelper;
import net.minecraft.client.option.KeyBinding;
import net.minecraft.client.util.InputUtil;
import net.minecraft.util.Identifier;
import net.fabricmc.fabric.api.client.keymapping.v1.KeyMappingHelper;
import net.minecraft.client.KeyMapping;
import net.minecraft.resources.Identifier;
import org.lwjgl.glfw.GLFW;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.nio.file.Path;

public class SaveMod implements ClientModInitializer {

private static final String MOD_ID = "savemod";
public static final Logger LOGGER = LoggerFactory.getLogger("SaveMod");

public static final Path DIR = Path.of("savemod");

public static String worldDir;

@Override
public void onInitializeClient() {
KeyBinding.Category key_category = KeyBinding.Category.create(Identifier.of("savemod", "main"));
KeyBinding openList = KeyBindingHelper.registerKeyBinding(new KeyBinding("key.savemod.open_list", InputUtil.Type.KEYSYM, GLFW.GLFW_KEY_UNKNOWN, key_category));
KeyBinding save = KeyBindingHelper.registerKeyBinding(new KeyBinding("key.savemod.save", InputUtil.Type.KEYSYM, GLFW.GLFW_KEY_UNKNOWN, key_category));
KeyMapping.Category key_category = KeyMapping.Category.register(Identifier.fromNamespaceAndPath("savemod", "main"));
KeyMapping openList = KeyMappingHelper.registerKeyMapping(new KeyMapping("key.savemod.open_list", InputConstants.Type.KEYSYM, GLFW.GLFW_KEY_UNKNOWN, key_category));
KeyMapping save = KeyMappingHelper.registerKeyMapping(new KeyMapping("key.savemod.save", InputConstants.Type.KEYSYM, GLFW.GLFW_KEY_UNKNOWN, key_category));

ClientTickEvents.END_CLIENT_TICK.register(client -> {
if (openList.isPressed() && client.isIntegratedServerRunning())
if (openList.isDown() && client.hasSingleplayerServer())
client.setScreen(new SelectSaveScreen(null));
if (save.isPressed() && client.isIntegratedServerRunning())
if (save.isDown() && client.hasSingleplayerServer())
client.setScreen(new NameSaveScreen(null, "", SaveMod.worldDir, saveName -> {
SelectSaveScreen saveScreen = new SelectSaveScreen(null);
client.setScreen(saveScreen);
Expand All @@ -43,4 +41,7 @@ public void onInitializeClient() {
SaveModConfig.load();
}

public static Identifier id(String path) {
return Identifier.fromNamespaceAndPath(MOD_ID, path);
}
}
10 changes: 2 additions & 8 deletions src/main/java/com/github/rashnain/savemod/SaveSummary.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
import java.util.Date;

public class SaveSummary {

private static final long ONE_MB = 1048576;
private final String saveFileName;
private final String worldDir;
private final long size;
Expand Down Expand Up @@ -45,12 +45,6 @@ public long getLastPlayed() {
}

public String getSizeInMB() {
long megaByte = 1000000;

if (size < megaByte)
return "< 1";

return String.valueOf(size / megaByte);
return size < ONE_MB ? "< 1" : String.valueOf(size / ONE_MB);
}

}
25 changes: 12 additions & 13 deletions src/main/java/com/github/rashnain/savemod/config/SaveModConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,19 @@

import com.github.rashnain.savemod.SaveMod;
import net.fabricmc.loader.api.FabricLoader;
import net.minecraft.client.gui.tooltip.Tooltip;
import net.minecraft.client.option.SimpleOption;
import net.minecraft.text.Text;
import net.minecraft.client.OptionInstance;
import net.minecraft.client.gui.components.Tooltip;
import net.minecraft.network.chat.Component;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Properties;

public class SaveModConfig {

public static final SimpleOption<Boolean> gameMenu = SimpleOption.ofBoolean("options.savemod.gameMenu", value -> Tooltip.of(Text.translatable("options.savemod.gameMenu.tooltip")), true);
public static final SimpleOption<Boolean> worldEntries = SimpleOption.ofBoolean("options.savemod.worldEntries", value -> Tooltip.of(Text.translatable("options.savemod.worldEntries.tooltip")), false);
public static final SimpleOption<Boolean> compression = SimpleOption.ofBoolean("options.savemod.compression", value -> Tooltip.of(Text.translatable("options.savemod.compression.tooltip")), true);
public static final OptionInstance<Boolean> gameMenu = OptionInstance.createBoolean("options.savemod.gameMenu", value -> Tooltip.create(Component.translatable("options.savemod.gameMenu.tooltip")), true);
public static final OptionInstance<Boolean> worldEntries = OptionInstance.createBoolean("options.savemod.worldEntries", value -> Tooltip.create(Component.translatable("options.savemod.worldEntries.tooltip")), false);
public static final OptionInstance<Boolean> compression = OptionInstance.createBoolean("options.savemod.compression", value -> Tooltip.create(Component.translatable("options.savemod.compression.tooltip")), true);

private static final Path configPath = FabricLoader.getInstance().getConfigDir().resolve("savemod.properties");
private static final Properties properties = new Properties();
Expand All @@ -26,9 +25,9 @@ public static void load() {
else {
try {
properties.load(Files.newInputStream(configPath));
gameMenu.setValue(Boolean.valueOf(properties.getProperty("show-button-on-game-menu", "true")));
worldEntries.setValue(Boolean.valueOf(properties.getProperty("show-button-on-world-entries", "false")));
compression.setValue(Boolean.valueOf(properties.getProperty("compress-saves", "true")));
gameMenu.set(Boolean.valueOf(properties.getProperty("show-button-on-game-menu", "true")));
worldEntries.set(Boolean.valueOf(properties.getProperty("show-button-on-world-entries", "false")));
compression.set(Boolean.valueOf(properties.getProperty("compress-saves", "true")));
} catch (IOException e) {
SaveMod.LOGGER.error("Could not load config : {}", e.getMessage());
}
Expand All @@ -44,9 +43,9 @@ public static void save() {
}
}
properties.clear();
properties.setProperty("show-button-on-game-menu", String.valueOf(gameMenu.getValue()));
properties.setProperty("show-button-on-world-entries", String.valueOf(worldEntries.getValue()));
properties.setProperty("compress-saves", String.valueOf(compression.getValue()));
properties.setProperty("show-button-on-game-menu", String.valueOf(gameMenu.get()));
properties.setProperty("show-button-on-world-entries", String.valueOf(worldEntries.get()));
properties.setProperty("compress-saves", String.valueOf(compression.get()));
try {
properties.store(Files.newOutputStream(configPath), "Configuration file for SaveMod");
} catch (IOException e) {
Expand Down
59 changes: 29 additions & 30 deletions src/main/java/com/github/rashnain/savemod/gui/NameSaveScreen.java
Original file line number Diff line number Diff line change
@@ -1,38 +1,37 @@
package com.github.rashnain.savemod.gui;

import net.minecraft.client.gui.DrawContext;
import net.minecraft.client.gui.screen.Screen;
import net.minecraft.client.gui.widget.ButtonWidget;
import net.minecraft.client.gui.widget.TextFieldWidget;
import net.minecraft.client.input.KeyInput;
import net.minecraft.screen.ScreenTexts;
import net.minecraft.text.Text;
import net.minecraft.client.gui.GuiGraphicsExtractor;
import net.minecraft.client.gui.components.Button;
import net.minecraft.client.gui.components.EditBox;
import net.minecraft.client.gui.screens.Screen;
import net.minecraft.client.input.KeyEvent;
import net.minecraft.network.chat.CommonComponents;
import net.minecraft.network.chat.Component;

import java.util.function.Consumer;

public class NameSaveScreen extends Screen {

private final Screen parent;
private final String previousName;
private final String worldName;
private final Consumer<String> consumer;
private TextFieldWidget nameBox;
private EditBox nameBox;

public NameSaveScreen(Screen parent, String previousName, String worldName, Consumer<String> consumer) {
super(Text.empty());
super(Component.empty());
this.parent = parent;
this.previousName = previousName;
this.worldName = worldName;
this.consumer = consumer;
}

@Override
public boolean keyPressed(KeyInput input) {
public boolean keyPressed(KeyEvent input) {
if (super.keyPressed(input))
return true;

if (getFocused() == nameBox && input.getKeycode() == 257 || input.getKeycode() == 335) {
consumer.accept(nameBox.getText());
if (getFocused() == nameBox && input.input() == 257 || input.input() == 335) {
consumer.accept(nameBox.getValue());
return true;
}

Expand All @@ -41,40 +40,40 @@ public boolean keyPressed(KeyInput input) {

@Override
protected void init() {
nameBox = new TextFieldWidget(textRenderer, width / 2 - 100, height / 2 - 10, 200, 20, null, Text.empty());
addDrawableChild(nameBox);
nameBox = new EditBox(font, width / 2 - 100, height / 2 - 10, 200, 20, null, Component.empty());
addRenderableWidget(nameBox);

if (previousName != null && !previousName.equals(worldName))
nameBox.setText(previousName);
nameBox.setValue(previousName);

Text message;
Component message;
if (previousName == null || previousName.isEmpty())
message = Text.translatable("savemod.name.create");
message = Component.translatable("savemod.name.create");
else
message = Text.translatable("savemod.name.rename");
message = Component.translatable("savemod.name.rename");

addDrawableChild(ButtonWidget.builder(message, button -> consumer.accept(nameBox.getText())
).dimensions(width / 2 - 150 - 5, height / 2 + 25, 150, 20).build());
addRenderableWidget(Button.builder(message, button -> consumer.accept(nameBox.getValue())
).bounds(width / 2 - 150 - 5, height / 2 + 25, 150, 20).build());

addDrawableChild(ButtonWidget.builder(ScreenTexts.CANCEL, button -> close()
).dimensions(width / 2 + 5, height / 2 + 25, 150, 20).build());
addRenderableWidget(Button.builder(CommonComponents.GUI_CANCEL, button -> onClose()
).bounds(width / 2 + 5, height / 2 + 25, 150, 20).build());

setInitialFocus(nameBox);
}

@Override
public void render(DrawContext context, int mouseX, int mouseY, float delta) {
super.render(context, mouseX, mouseY, delta);
public void extractRenderState(GuiGraphicsExtractor context, int mouseX, int mouseY, float delta) {
super.extractRenderState(context, mouseX, mouseY, delta);
if (previousName == null || previousName.isEmpty())
context.drawCenteredTextWithShadow(textRenderer, Text.translatable("savemod.name.title.new"), width / 2, height / 2 - 45, -1);
context.centeredText(font, Component.translatable("savemod.name.title.new"), width / 2, height / 2 - 45, -1);
else
context.drawCenteredTextWithShadow(textRenderer, Text.translatable("savemod.name.title.rename"), width / 2, height / 2 - 45, -1);
context.drawCenteredTextWithShadow(textRenderer, Text.translatable("savemod.name.hint", worldName), width / 2, height / 2 - 30, -0x808080);
context.centeredText(font, Component.translatable("savemod.name.title.rename"), width / 2, height / 2 - 45, -1);
context.centeredText(font, Component.translatable("savemod.name.hint", worldName), width / 2, height / 2 - 30, -0x808080);
}

@Override
public void close() {
client.setScreen(parent);
public void onClose() {
minecraft.setScreen(parent);
}

}
49 changes: 24 additions & 25 deletions src/main/java/com/github/rashnain/savemod/gui/OptionsScreen.java
Original file line number Diff line number Diff line change
@@ -1,43 +1,42 @@
package com.github.rashnain.savemod.gui;

import com.github.rashnain.savemod.config.SaveModConfig;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.gui.DrawContext;
import net.minecraft.client.gui.screen.Screen;
import net.minecraft.client.gui.screen.option.GameOptionsScreen;
import net.minecraft.client.gui.widget.ButtonWidget;
import net.minecraft.client.gui.widget.OptionListWidget;
import net.minecraft.screen.ScreenTexts;
import net.minecraft.text.Text;

public class OptionsScreen extends GameOptionsScreen {

private OptionListWidget optionList;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.GuiGraphicsExtractor;
import net.minecraft.client.gui.components.Button;
import net.minecraft.client.gui.components.OptionsList;
import net.minecraft.client.gui.screens.Screen;
import net.minecraft.client.gui.screens.options.OptionsSubScreen;
import net.minecraft.network.chat.CommonComponents;
import net.minecraft.network.chat.Component;

public class OptionsScreen extends OptionsSubScreen {
private OptionsList optionList;

public OptionsScreen(Screen parent) {
super(parent, MinecraftClient.getInstance().options, Text.translatable("savemod.options"));
super(parent, Minecraft.getInstance().options, Component.translatable("savemod.options"));
}

@Override
protected void init() {
optionList = new OptionListWidget(client, width, this);
optionList.addSingleOptionEntry(SaveModConfig.gameMenu);
optionList.addSingleOptionEntry(SaveModConfig.worldEntries);
optionList.addSingleOptionEntry(SaveModConfig.compression);
addSelectableChild(optionList);

addDrawableChild(ButtonWidget.builder(ScreenTexts.DONE, button -> close()
).dimensions(width / 2 - 100, height - 27,200, 20).build());
optionList = new OptionsList(minecraft, width, this);
optionList.addBig(SaveModConfig.gameMenu);
optionList.addBig(SaveModConfig.worldEntries);
optionList.addBig(SaveModConfig.compression);
addWidget(optionList);

addRenderableWidget(Button.builder(CommonComponents.GUI_DONE, button -> onClose()
).bounds(width / 2 - 100, height - 27,200, 20).build());
}

@Override
protected void addOptions() {}

@Override
public void render(DrawContext context, int mouseX, int mouseY, float delta) {
super.render(context, mouseX, mouseY, delta);
optionList.render(context, mouseX, mouseY, delta);
context.drawCenteredTextWithShadow(textRenderer, title, width / 2, 12, -1);
public void extractRenderState(GuiGraphicsExtractor context, int mouseX, int mouseY, float delta) {
super.extractRenderState(context, mouseX, mouseY, delta);
optionList.extractRenderState(context, mouseX, mouseY, delta);
context.centeredText(font, title, width / 2, 12, -1);
}

@Override
Expand Down
Loading