mirror of
https://github.com/HMCL-dev/HMCL.git
synced 2025-09-22 02:31:22 -04:00
update
This commit is contained in:
parent
65402fa914
commit
7992260575
@ -0,0 +1,159 @@
|
||||
/*
|
||||
* Hello Minecraft! Launcher
|
||||
* Copyright (C) 2025 huangyuhui <huanghongxun2008@126.com> and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package org.jackhuang.hmcl.gradle.l10n;
|
||||
|
||||
import org.gradle.api.DefaultTask;
|
||||
import org.gradle.api.file.RegularFileProperty;
|
||||
import org.gradle.api.tasks.InputFile;
|
||||
import org.gradle.api.tasks.OutputFile;
|
||||
import org.gradle.api.tasks.TaskAction;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/// @author Glavo
|
||||
public abstract class UpsideDownTranslate extends DefaultTask {
|
||||
|
||||
@InputFile
|
||||
public abstract RegularFileProperty getInputFile();
|
||||
|
||||
@OutputFile
|
||||
public abstract RegularFileProperty getOutputFile();
|
||||
|
||||
@TaskAction
|
||||
public void run() throws IOException {
|
||||
Path inputFile = getInputFile().get().getAsFile().toPath();
|
||||
Path outputFile = getOutputFile().get().getAsFile().toPath();
|
||||
|
||||
Properties english = new Properties();
|
||||
try (var reader = Files.newBufferedReader(inputFile)) {
|
||||
english.load(reader);
|
||||
}
|
||||
|
||||
Properties output = new Properties();
|
||||
Translator translator = new Translator();
|
||||
english.forEach((k, v) -> output.put(k, translator.translate(v.toString())));
|
||||
|
||||
try (var writer = Files.newBufferedWriter(outputFile)) {
|
||||
output.store(writer, "This file is automatically generated, please do not modify it manually");
|
||||
}
|
||||
}
|
||||
|
||||
private static final class Translator {
|
||||
private static final Map<Integer, Integer> mapper = new LinkedHashMap<>();
|
||||
|
||||
private static void putChars(char baseChar, String upsideDownChars) {
|
||||
for (int i = 0; i < upsideDownChars.length(); i++) {
|
||||
mapper.put(baseChar + i, (int) upsideDownChars.charAt(i));
|
||||
}
|
||||
}
|
||||
|
||||
private static void putChars(String baseChars, String upsideDownChars) {
|
||||
if (baseChars.length() != upsideDownChars.length()) {
|
||||
throw new IllegalArgumentException("baseChars and upsideDownChars must have same length");
|
||||
}
|
||||
|
||||
for (int i = 0; i < baseChars.length(); i++) {
|
||||
mapper.put((int) baseChars.charAt(i), (int) upsideDownChars.charAt(i));
|
||||
}
|
||||
}
|
||||
|
||||
static {
|
||||
putChars('a', "ɐqɔpǝɟbɥıظʞןɯuuodbɹsʇnʌʍxʎz");
|
||||
putChars('A', "ⱯᗺƆᗡƎℲ⅁HIſʞꞀWNOԀὉᴚS⟘∩ΛMXʎZ");
|
||||
putChars('0', "0ƖᄅƐㄣϛ9ㄥ86");
|
||||
putChars("_,;.?!/\\'", "‾'؛˙¿¡/\\,");
|
||||
}
|
||||
|
||||
private static final Pattern FORMAT_PATTERN = Pattern.compile("^%(\\d\\$)?[sd]");
|
||||
private static final Pattern XML_TAG_PATTERN = Pattern.compile("^<(?<tag>[a-zA-Z]+)( href=\"[^\"]*\")?>");
|
||||
|
||||
private final StringBuilder lineBuilder = new StringBuilder();
|
||||
|
||||
private void appendToLineBuilder(String input) {
|
||||
for (int i = 0; i < input.length(); ) {
|
||||
int ch = input.codePointAt(i);
|
||||
|
||||
if (ch == '%') {
|
||||
Matcher matcher = FORMAT_PATTERN.matcher(input).region(i, input.length());
|
||||
if (matcher.find()) {
|
||||
String formatString = matcher.group();
|
||||
lineBuilder.insert(0, formatString);
|
||||
i += formatString.length();
|
||||
continue;
|
||||
}
|
||||
} else if (ch == '<') {
|
||||
Matcher matcher = XML_TAG_PATTERN.matcher(input).region(i, input.length());
|
||||
if (matcher.find()) {
|
||||
String beginTag = matcher.group();
|
||||
String endTag = "</" + matcher.group(1) + ">";
|
||||
|
||||
int endTagOffset = input.indexOf(endTag, i + beginTag.length());
|
||||
if (endTagOffset > 0) {
|
||||
lineBuilder.insert(0, endTag);
|
||||
appendToLineBuilder(input.substring(i + beginTag.length(), endTagOffset));
|
||||
lineBuilder.insert(0, beginTag);
|
||||
|
||||
i = endTagOffset + endTag.length();
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Integer udCh = mapper.getOrDefault(ch, ch);
|
||||
if (Character.isBmpCodePoint(udCh)) {
|
||||
lineBuilder.insert(0, udCh);
|
||||
} else {
|
||||
lineBuilder.insert(0, Character.toChars(udCh));
|
||||
}
|
||||
|
||||
i += Character.charCount(ch);
|
||||
}
|
||||
}
|
||||
|
||||
private final StringBuilder resultBuilder = new StringBuilder();
|
||||
|
||||
String translate(String input) {
|
||||
resultBuilder.setLength(0);
|
||||
|
||||
for (int i = 0; i < input.length(); ) {
|
||||
int idx = input.indexOf('\n');
|
||||
String line = input.substring(0, idx < 0 ? input.length() : idx);
|
||||
|
||||
this.lineBuilder.setLength(0);
|
||||
appendToLineBuilder(line);
|
||||
resultBuilder.append(lineBuilder);
|
||||
|
||||
if (idx < 0) {
|
||||
break;
|
||||
} else {
|
||||
resultBuilder.append('\n');
|
||||
i = idx + 1;
|
||||
}
|
||||
}
|
||||
|
||||
return resultBuilder.toString();
|
||||
}
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user