Skip to content

Commit

Permalink
Translation support (#6)
Browse files Browse the repository at this point in the history
Support translations through resource bundles.
By default the locale is set to the JVM's default locale (falling back to English), and once changed in the dropdown, it will be saved in the user's MC directory under (a hidden) `libraries/.neoforge_installer.properties` file
  • Loading branch information
Matyrobbrt authored Jan 11, 2024
1 parent c7a5fb8 commit 524fc20
Show file tree
Hide file tree
Showing 15 changed files with 539 additions and 153 deletions.
12 changes: 12 additions & 0 deletions crowdin.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
project_id_env: NEOFORGE_CROWDIN_PROJECT_ID
api_token_env: NEOFORGE_CROWDIN_API_TOKEN
base_path: .
base_url: 'https://neoforged.api.crowdin.com'
preserve_hierarchy: 1
commit_message: '[ci skip]'
pull_request_labels:
- l10n
files:
- source: /src/main/resources/neoforged/installer.xml
translation: /src/main/resources/neoforged/installer_%two_letters_code%.%file_extension%
dest: /messages.%file_extension%
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
import net.minecraftforge.installer.actions.ProgressCallback;
import net.minecraftforge.installer.json.InstallV1;
import net.minecraftforge.installer.json.Util;
import net.minecraftforge.installer.ui.InstallerPanel;
import net.neoforged.cliutils.progress.ProgressInterceptor;
import net.neoforged.cliutils.progress.ProgressManager;
import net.neoforged.cliutils.progress.ProgressReporter;
Expand Down Expand Up @@ -209,7 +210,7 @@ private static OutputStream getLog() throws FileNotFoundException
return new BufferedOutputStream(new FileOutputStream(output));
}

static void hookStdOut(ProgressCallback monitor)
public static void hookStdOut(ProgressCallback monitor)
{
final Pattern endingWhitespace = Pattern.compile("\\r?\\n$");
final OutputStream monitorStream = new OutputStream() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
import net.minecraftforge.installer.json.Version;
import net.minecraftforge.installer.json.Version.Library;
import net.minecraftforge.installer.json.Version.LibraryDownload;
import net.minecraftforge.installer.ui.TranslatedMessage;

public abstract class Action {
protected final InstallV1 profile;
Expand All @@ -57,7 +58,7 @@ protected void error(String message) {

public abstract boolean run(File target, Predicate<String> optionals, File installer) throws ActionCanceledException;
public abstract TargetValidator getTargetValidator();
public abstract String getSuccessMessage();
public abstract TranslatedMessage getSuccessMessage();

public String getSponsorMessage() {
return profile.getMirror() != null && profile.getMirror().isAdvertised() ? String.format(SimpleInstaller.headless ? "Data kindly mirrored by %2$s at %1$s" : "<html><a href=\'%s\'>Data kindly mirrored by %s</a></html>", profile.getMirror().getHomepage(), profile.getMirror().getName()) : null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,9 @@

public enum Actions
{
CLIENT("Install client", "Install a new profile to the Mojang client launcher", ClientInstall::new, () -> "Successfully installed client into launcher."),
SERVER("Install server", "Create a new modded server installation", ServerInstall::new, () -> "The server installed successfully"),
EXTRACT("Extract", "Extract the contained jar file", ExtractAction::new, () -> "All files successfully extract.");
CLIENT("installer.action.install.client.name", "installer.action.install.client.tooltip", ClientInstall::new, () -> "Successfully installed client into launcher."),
SERVER("installer.action.install.server.name", "installer.action.install.server.tooltip", ServerInstall::new, () -> "The server installed successfully"),
EXTRACT("installer.action.extract.name", "installer.action.extract.tooltip", ExtractAction::new, () -> "All files successfully extract.");

private String label;
private String tooltip;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
import net.minecraftforge.installer.json.Version.Download;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import net.minecraftforge.installer.ui.TranslatedMessage;

public class ClientInstall extends Action {

Expand Down Expand Up @@ -200,9 +201,10 @@ public TargetValidator getTargetValidator() {
}

@Override
public String getSuccessMessage() {
if (downloadedCount() > 0)
return String.format("Successfully installed client profile %s for version %s into launcher, and downloaded %d libraries", profile.getProfile(), profile.getVersion(), downloadedCount());
return String.format("Successfully installed client profile %s for version %s into launcher", profile.getProfile(), profile.getVersion());
public TranslatedMessage getSuccessMessage() {
if (downloadedCount() > 0) {
return new TranslatedMessage("installer.action.install.client.finished.withlibs", profile.getProfile(), profile.getVersion(), downloadedCount());
}
return new TranslatedMessage("installer.action.install.client.finished.withoutlibs", profile.getProfile(), profile.getVersion());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import net.minecraftforge.installer.DownloadUtils;
import net.minecraftforge.installer.json.Artifact;
import net.minecraftforge.installer.json.InstallV1;
import net.minecraftforge.installer.ui.TranslatedMessage;

public class ExtractAction extends Action {

Expand Down Expand Up @@ -88,7 +89,7 @@ public TargetValidator getTargetValidator() {
}

@Override
public String getSuccessMessage() {
return "Extracted successfully";
public TranslatedMessage getSuccessMessage() {
return new TranslatedMessage("installer.action.extract.finished");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
import net.minecraftforge.installer.json.Util;
import net.minecraftforge.installer.json.Version;
import net.minecraftforge.installer.json.Version.Download;
import net.minecraftforge.installer.ui.TranslatedMessage;

public class ServerInstall extends Action {
private List<Artifact> grabbed = new ArrayList<>();
Expand Down Expand Up @@ -133,9 +134,10 @@ public TargetValidator getTargetValidator() {
}

@Override
public String getSuccessMessage() {
if (!grabbed.isEmpty())
return String.format("Successfully downloaded minecraft server, downloaded %d libraries and installed %s", grabbed.size(), profile.getVersion());
return String.format("Successfully downloaded minecraft server and installed %s", profile.getVersion());
public TranslatedMessage getSuccessMessage() {
if (grabbed.isEmpty()) {
return new TranslatedMessage("installer.action.install.server.finished.withoutlibs", profile.getVersion());
}
return new TranslatedMessage("installer.action.install.server.finished.withlibs", grabbed.size(), profile.getVersion());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
*/
package net.minecraftforge.installer.actions;

import net.minecraftforge.installer.ui.TranslatedMessage;
import org.jetbrains.annotations.NotNull;

import java.io.File;
Expand All @@ -39,24 +40,24 @@ default TargetValidator and(TargetValidator other) {
}

static TargetValidator isDirectory() {
return target -> target.isDirectory() ? ValidationResult.valid() : ValidationResult.invalid(true, "The specified path needs to be a directory");
return target -> target.isDirectory() ? ValidationResult.valid() : ValidationResult.invalid(true, "installer.target.error.notdirectory");
}

static TargetValidator shouldExist(boolean critical) {
return target -> target.exists() ? ValidationResult.valid() : ValidationResult.invalid(critical, "The specified directory does not exist" + (critical ? "" : "<br/>It will be created"));
return target -> target.exists() ? ValidationResult.valid() : ValidationResult.invalid(critical, critical ? "installer.target.error.directory.doesntexist.critical" : "installer.target.error.directory.doesntexist.create");
}

static TargetValidator shouldBeEmpty() {
return target -> Objects.requireNonNull(target.list()).length == 0 ? ValidationResult.valid() : ValidationResult.invalid(false, "There are already files in the target directory");
return target -> Objects.requireNonNull(target.list()).length == 0 ? ValidationResult.valid() : ValidationResult.invalid(false, "installer.target.error.directory.notempty");
}

static TargetValidator isMCInstallationDirectory() {
return target -> (new File(target, "launcher_profiles.json").exists() ||
new File(target, "launcher_profiles_microsoft_store.json").exists()) ? ValidationResult.valid() : ValidationResult.invalid(true, "The directory is missing a launcher profile. Please run the minecraft launcher first");
new File(target, "launcher_profiles_microsoft_store.json").exists()) ? ValidationResult.valid() : ValidationResult.invalid(true, "installer.target.error.missingprofile");
}

class ValidationResult {
private static final ValidationResult VALID = new ValidationResult(true, false, "");
private static final ValidationResult VALID = new ValidationResult(true, false, new TranslatedMessage(""));

/**
* Whether the target directory is valid for installation.
Expand All @@ -69,9 +70,9 @@ class ValidationResult {
/**
* A message to display to users if the target is invalid.
*/
public final String message;
public final TranslatedMessage message;

private ValidationResult(boolean valid, boolean critical, String message) {
private ValidationResult(boolean valid, boolean critical, TranslatedMessage message) {
this.valid = valid;
this.critical = critical;
this.message = message;
Expand All @@ -81,8 +82,8 @@ public static ValidationResult valid() {
return VALID;
}

public static ValidationResult invalid(boolean critical, String message) {
return new ValidationResult(false, critical, message);
public static ValidationResult invalid(boolean critical, String messageKey) {
return new ValidationResult(false, critical, new TranslatedMessage(messageKey));
}

public ValidationResult combine(Supplier<ValidationResult> other) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,24 @@
package net.minecraftforge.installer;
/*
* Installer
* Copyright (c) 2016-2018.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation version 2.1
* of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
package net.minecraftforge.installer.ui;

import net.minecraftforge.installer.SimpleInstaller;

import javax.imageio.ImageIO;
import java.awt.Image;
Expand Down
Loading

0 comments on commit 524fc20

Please sign in to comment.