Made the code work + Cleaned up Code
This commit is contained in:
@@ -83,7 +83,8 @@ class AssetsLibraryList extends AssetLibrary {
|
||||
if (l is IModsAssetLibrary) {
|
||||
var lib = cast(l, IModsAssetLibrary);
|
||||
for(e in lib.getFolders(folder))
|
||||
content.push(e);
|
||||
if(!content.contains(e))
|
||||
content.push(e);
|
||||
}
|
||||
#end
|
||||
}
|
||||
|
||||
@@ -62,7 +62,7 @@ class ModsFolder {
|
||||
Options.lastLoadedMod = currentModFolder = mod;
|
||||
reloadMods();
|
||||
Logs.traceColored([
|
||||
Logs.logText('Switched to mod ', GRAY),
|
||||
Logs.logText('Switched to mod: '),
|
||||
Logs.logText(mod, GREEN)
|
||||
], VERBOSE);
|
||||
}
|
||||
|
||||
@@ -23,8 +23,6 @@ class Paths
|
||||
*/
|
||||
public static inline final SOUND_EXT = #if web "mp3" #else "ogg" #end;
|
||||
|
||||
public static inline var translFolderName:String = "translations";
|
||||
|
||||
public static var assetsTree:AssetsLibraryList;
|
||||
|
||||
public static var tempFramesCache:Map<String, FlxFramesCollection> = [];
|
||||
@@ -38,12 +36,6 @@ class Paths
|
||||
public static inline function getPath(file:String, ?library:String)
|
||||
return library != null ? '$library:assets/$library/$file' : 'assets/$file';
|
||||
|
||||
public static inline function translationsMain(key:String)
|
||||
return getPath('$translFolderName/$key');
|
||||
|
||||
public static inline function translations(key:String)
|
||||
return translationsMain('${TranslationUtil.curLanguage}/$key');
|
||||
|
||||
public static inline function video(key:String, ?ext:String = "mp4")
|
||||
return getPath('videos/$key.$ext');
|
||||
|
||||
|
||||
@@ -10,14 +10,14 @@ class TranslatedAssetLibrary extends AssetLibrary implements IModsAssetLibrary {
|
||||
public var libName:String;
|
||||
public var modName:String;
|
||||
public var basePath:String;
|
||||
public var prefix:String = Paths.translFolderName + "/";
|
||||
public var prefix:String = TranslationUtil.LANG_FOLDER + "/";
|
||||
|
||||
public var langFolder(get, set):String;
|
||||
@:noCompletion private inline function get_langFolder():String {
|
||||
return libName;
|
||||
}
|
||||
@:noCompletion private inline function set_langFolder(value:String):String {
|
||||
basePath = prefix + (libName = modName = (value != null ? value : TranslationUtil.DEFAULT_LANGUAGE.split("/")[0])) + "/";
|
||||
basePath = prefix + (libName = modName = (value != null ? value : TranslationUtil.DEFAULT_LANGUAGE)) + "/";
|
||||
return libName;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,27 +1,15 @@
|
||||
package funkin.backend.assets;
|
||||
|
||||
import lime.utils.Log;
|
||||
import lime.utils.AssetManifest;
|
||||
|
||||
import haxe.io.Path;
|
||||
import lime.app.Event;
|
||||
import lime.app.Future;
|
||||
import lime.app.Promise;
|
||||
import lime.media.AudioBuffer;
|
||||
import lime.graphics.Image;
|
||||
import lime.text.Font;
|
||||
import lime.utils.AssetType;
|
||||
import lime.utils.Bytes;
|
||||
import lime.utils.Assets as LimeAssets;
|
||||
import openfl.text.Font as OpenFLFont;
|
||||
import openfl.utils.AssetLibrary;
|
||||
|
||||
|
||||
#if MOD_SUPPORT
|
||||
import sys.FileStat;
|
||||
import sys.FileSystem;
|
||||
import sys.io.File;
|
||||
import haxe.zip.Reader;
|
||||
import funkin.backend.utils.SysZip;
|
||||
import funkin.backend.utils.SysZip.SysZipEntry;
|
||||
|
||||
|
||||
@@ -98,23 +98,26 @@ class Logs {
|
||||
public static function traceColored(text:Array<LogText>, level:Level = INFO) {
|
||||
__showInConsole(prepareColoredTrace(text, level));
|
||||
}
|
||||
public static function trace(text:String, level:Level = INFO, color:ConsoleColor = LIGHTGRAY) {
|
||||
traceColored([{
|
||||
text: text,
|
||||
color: color
|
||||
}], level);
|
||||
public static function trace(text:String, level:Level = INFO, color:ConsoleColor = LIGHTGRAY, ?prefix:String) {
|
||||
var text = [logText(text, color)];
|
||||
if(prefix != null) text.insert(0, getPrefix(prefix));
|
||||
traceColored(text, level);
|
||||
}
|
||||
|
||||
public inline static function verbose(text:String, level:Level = VERBOSE, color:ConsoleColor = LIGHTGRAY) {
|
||||
Logs.trace(text, level, color);
|
||||
public inline static function getPrefix(prefix:String) {
|
||||
return logText('[${prefix}] ', BLUE);
|
||||
}
|
||||
|
||||
public inline static function warn(text:String, level:Level = WARNING, color:ConsoleColor = YELLOW) {
|
||||
Logs.trace(text, level, color);
|
||||
public inline static function verbose(text:String, level:Level = VERBOSE, color:ConsoleColor = LIGHTGRAY, ?prefix:String) {
|
||||
Logs.trace(text, level, color, prefix);
|
||||
}
|
||||
|
||||
public inline static function error(text:String, level:Level = ERROR, color:ConsoleColor = RED) {
|
||||
Logs.trace(text, level, color);
|
||||
public inline static function warn(text:String, level:Level = WARNING, color:ConsoleColor = YELLOW, ?prefix:String) {
|
||||
Logs.trace(text, level, color, prefix);
|
||||
}
|
||||
|
||||
public inline static function error(text:String, level:Level = ERROR, color:ConsoleColor = RED, ?prefix:String) {
|
||||
Logs.trace(text, level, color, prefix);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -55,6 +55,7 @@ class MainState extends FlxState {
|
||||
|
||||
Main.refreshAssets();
|
||||
ModsFolder.onModSwitch.dispatch(ModsFolder.currentModFolder);
|
||||
TranslationUtil.findAllLanguages();
|
||||
TranslationUtil.setLanguage();
|
||||
DiscordUtil.init();
|
||||
EventsData.reloadEvents();
|
||||
|
||||
@@ -140,7 +140,16 @@ class CoolUtil
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the last of an Array
|
||||
* Returns the first element of an Array
|
||||
* @param array Array
|
||||
* @return T Last element
|
||||
*/
|
||||
public static inline function first<T>(array:Array<T>):T {
|
||||
return array[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the last element of an Array
|
||||
* @param array Array
|
||||
* @return T Last element
|
||||
*/
|
||||
@@ -703,6 +712,19 @@ class CoolUtil
|
||||
|
||||
@:noUsing public static inline function flxeaseFromString(mainEase:String, suffix:String)
|
||||
return Reflect.field(FlxEase, mainEase + (mainEase == "linear" ? "" : suffix));
|
||||
|
||||
public static function sortAlphabetically(array:Array<String>, ?lowercase:Bool=false) {
|
||||
array.sort(function(a1, a2):Int {
|
||||
if(lowercase) {
|
||||
a1 = a1.toLowerCase();
|
||||
a2 = a2.toLowerCase();
|
||||
}
|
||||
if (a1 < a2) return -1;
|
||||
if (a1 > a2) return 1;
|
||||
return 0;
|
||||
});
|
||||
return array;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -285,7 +285,7 @@ class DiscordUtil
|
||||
user = DUser.initRaw(request);
|
||||
|
||||
Logs.traceColored([
|
||||
Logs.logText("[Discord] ", BLUE),
|
||||
Logs.getPrefix("Discord"),
|
||||
Logs.logText("Connected to User " + user.globalName + " ("),
|
||||
Logs.logText(user.handle, GRAY),
|
||||
Logs.logText(")")
|
||||
@@ -301,7 +301,7 @@ class DiscordUtil
|
||||
var finalMsg:String = cast(message, String);
|
||||
|
||||
Logs.traceColored([
|
||||
Logs.logText("[Discord] ", BLUE),
|
||||
Logs.getPrefix("Discord"),
|
||||
Logs.logText("Disconnected ("),
|
||||
Logs.logText('$errorCode: $finalMsg', RED),
|
||||
Logs.logText(")")
|
||||
@@ -315,7 +315,7 @@ class DiscordUtil
|
||||
var finalMsg:String = cast(message, String);
|
||||
|
||||
Logs.traceColored([
|
||||
Logs.logText("[Discord] ", BLUE),
|
||||
Logs.getPrefix("Discord"),
|
||||
Logs.logText('Error ($errorCode: $finalMsg)', RED)
|
||||
], ERROR);
|
||||
|
||||
@@ -324,7 +324,7 @@ class DiscordUtil
|
||||
|
||||
private static function onJoin(joinSecret:cpp.ConstCharStar):Void
|
||||
{
|
||||
Logs.traceColored([Logs.logText("[Discord] ", BLUE), Logs.logText("Someone has just joined", GREEN)], INFO);
|
||||
Logs.traceColored([Logs.getPrefix("Discord"), Logs.logText("Someone has just joined", GREEN)], INFO);
|
||||
|
||||
call("onJoinGame", [cast(joinSecret, String)]);
|
||||
}
|
||||
@@ -332,7 +332,7 @@ class DiscordUtil
|
||||
private static function onSpectate(spectateSecret:cpp.ConstCharStar):Void
|
||||
{
|
||||
Logs.traceColored([
|
||||
Logs.logText("[Discord] ", BLUE),
|
||||
Logs.getPrefix("Discord"),
|
||||
Logs.logText("Someone started spectating your game", YELLOW)
|
||||
], INFO);
|
||||
|
||||
@@ -342,7 +342,7 @@ class DiscordUtil
|
||||
private static function onJoinReq(request:cpp.RawConstPointer<DiscordUser>):Void
|
||||
{
|
||||
Logs.traceColored([
|
||||
Logs.logText("[Discord] ", BLUE),
|
||||
Logs.getPrefix("Discord"),
|
||||
Logs.logText("Someone has just requested to join", YELLOW)
|
||||
], INFO);
|
||||
|
||||
|
||||
@@ -1,18 +1,20 @@
|
||||
package funkin.backend.utils;
|
||||
|
||||
typedef IniMap = Map<String, String>;
|
||||
|
||||
/**
|
||||
* DOESNT SUPPORT CATEGORIES YET!!
|
||||
* Parses an ini file and returns a map of its contents.
|
||||
* WARNING: This is not a full ini parser, it only supports the basics. So no sections
|
||||
*/
|
||||
class IniUtil {
|
||||
public static inline function parseAsset(assetPath:String, ?defaultVariables:Map<String, String>)
|
||||
public static inline function parseAsset(assetPath:String, ?defaultVariables:IniMap):IniMap
|
||||
return parseString(Assets.getText(assetPath), defaultVariables);
|
||||
|
||||
public static function parseString(data:String, ?defaultVariables:Map<String, String>) {
|
||||
public static function parseString(data:String, ?defaultVariables:IniMap):IniMap {
|
||||
var trimmed:String;
|
||||
var splitContent = [for(e in data.split("\n")) if ((trimmed = e.trim()) != "") trimmed];
|
||||
|
||||
var finalMap:Map<String, String> = [];
|
||||
var finalMap:IniMap = [];
|
||||
if (defaultVariables != null)
|
||||
for(k=>e in defaultVariables)
|
||||
finalMap[k] = e;
|
||||
@@ -20,7 +22,7 @@ class IniUtil {
|
||||
for(line in splitContent) {
|
||||
// comment
|
||||
if (line.startsWith(";")) continue;
|
||||
// categories; not supported yet
|
||||
// sections; not supported yet
|
||||
if (line.startsWith("[") && line.endsWith("]")) continue;
|
||||
|
||||
var index = line.indexOf("=");
|
||||
|
||||
@@ -10,7 +10,7 @@ class SortedArrayUtil {
|
||||
* @param getVal Function that returns the position value of T
|
||||
* @return Index
|
||||
*/
|
||||
public static inline function binarySearch<T>(array:Array<T>, val:Float, getVal:T->Float):Int {
|
||||
public static function binarySearch<T>(array:Array<T>, val:Float, getVal:T->Float):Int {
|
||||
if (array.length <= 0) return 0; // if the array is empty, it should be equal to zero (the beginning)
|
||||
if (getVal(array[0]) > val) return 0; // in case its the minimum
|
||||
if (getVal(array[array.length-1]) < val) return array.length; // in case its the maximum
|
||||
@@ -46,4 +46,10 @@ class SortedArrayUtil {
|
||||
if (val != null)
|
||||
array.insert(binarySearch(array, getVal(val), getVal), val);
|
||||
}
|
||||
|
||||
public static function removeSorted<T>(array:Array<T>, val:T, getVal:T->Float) {
|
||||
var index = binarySearch(array, getVal(val), getVal);
|
||||
if (index != -1)
|
||||
array.splice(index, 1);
|
||||
}
|
||||
}
|
||||
@@ -1,10 +1,8 @@
|
||||
package funkin.backend.utils;
|
||||
|
||||
import funkin.backend.utils.IniUtil;
|
||||
import funkin.backend.assets.TranslatedAssetLibrary;
|
||||
import funkin.backend.assets.ModsFolderLibrary;
|
||||
import funkin.backend.assets.ModsFolder;
|
||||
import funkin.backend.assets.IModsAssetLibrary;
|
||||
import funkin.backend.assets.ZipFolderLibrary;
|
||||
import openfl.utils.Assets;
|
||||
import haxe.io.Path;
|
||||
import haxe.xml.Access;
|
||||
@@ -15,6 +13,7 @@ import haxe.Exception;
|
||||
*
|
||||
* Made by @NexIsDumb originally for the Poldhub mod.
|
||||
*/
|
||||
@:allow(funkin.backend.assets.TranslatedAssetLibrary)
|
||||
class TranslationUtil
|
||||
{
|
||||
/**
|
||||
@@ -22,42 +21,51 @@ class TranslationUtil
|
||||
*
|
||||
* It'll never be `null`.
|
||||
*/
|
||||
public static var transMap(default, set):Map<String, IFormatInfo> = [];
|
||||
|
||||
@:noCompletion private static function set_transMap(value:Map<String, IFormatInfo>):Map<String, IFormatInfo> {
|
||||
if (value == null) value = [];
|
||||
return transMap = value;
|
||||
}
|
||||
public static var stringMap(default, set):Map<String, IFormatInfo> = [];
|
||||
|
||||
/**
|
||||
* The default language used inside of the source code.
|
||||
*/
|
||||
public static var DEFAULT_LANGUAGE:String = 'en/English'; // no inline so psycopathic mods can edit it - Nex
|
||||
public static var DEFAULT_LANGUAGE:String = 'en'; // no inline so psychopathic mods can edit it - Nex
|
||||
|
||||
/**
|
||||
* Returns the current language config.
|
||||
*/
|
||||
public static var config:IniMap = [];
|
||||
/**
|
||||
* Returns the current language.
|
||||
*/
|
||||
public static var curLanguage(get, set):String;
|
||||
@:noCompletion private static function get_curLanguage():String {
|
||||
return Options.language;
|
||||
}
|
||||
@:noCompletion private static function set_curLanguage(value:String):String {
|
||||
return Options.language = value;
|
||||
}
|
||||
/**
|
||||
* Returns the current language name.
|
||||
*/
|
||||
public static var curLanguageName(get, set):String;
|
||||
|
||||
/**
|
||||
* Returns if the current language is the default one (`DEFAULT_LANGUAGE`).
|
||||
*/
|
||||
public static var isDefaultLanguage(get, never):Bool;
|
||||
@:noCompletion private static function get_isDefaultLanguage():Bool
|
||||
return Options.language == DEFAULT_LANGUAGE;
|
||||
|
||||
/**
|
||||
* Returns if any translation are loaded.
|
||||
*/
|
||||
public static var isAnyTransLoaded(get, never):Bool;
|
||||
@:noCompletion private static function get_isAnyTransLoaded():Bool
|
||||
return Lambda.count(transMap) > 0;
|
||||
public static var isLanguageLoaded(get, never):Bool;
|
||||
|
||||
/**
|
||||
* Returns an array has a list of the languages that were found.
|
||||
*/
|
||||
public static var foundLanguages:Array<String> = [];
|
||||
|
||||
// Private
|
||||
private static inline var LANG_FOLDER:String = "languages";
|
||||
private static var langConfigs:Map<String, IniMap> = [];
|
||||
private static var nameMap:Map<String, String> = [];
|
||||
private static inline function getDefaultNameMap():Map<String, String> {
|
||||
return ['en' => 'English'];
|
||||
}
|
||||
private static inline function getDefaultConfig(name:String):IniMap {
|
||||
return ["name" => getLanguageName(name), "credits" => "", "version" => "1.0.0"];
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the language.
|
||||
@@ -69,11 +77,19 @@ class TranslationUtil
|
||||
public static function setLanguage(?name:String) {
|
||||
#if TRANSLATIONS_SUPPORT
|
||||
if(name == null) name = curLanguage;
|
||||
name = name.split("/")[0];
|
||||
|
||||
transMap = loadLanguage(name);
|
||||
for(mod in ModsFolder.getLoadedModsLibs()) if(mod is TranslatedAssetLibrary)
|
||||
cast(mod, TranslatedAssetLibrary).langFolder = name.split("/")[0];
|
||||
config = getConfig(name);
|
||||
stringMap = loadLanguage(name);
|
||||
|
||||
Logs.traceColored([
|
||||
Logs.getPrefix("Language"),
|
||||
Logs.logText("Set Language To: "),
|
||||
Logs.logText('${getLanguageName(name)} ($name)', GREEN)
|
||||
], VERBOSE);
|
||||
|
||||
for(mod in ModsFolder.getLoadedModsLibs(false))
|
||||
if(mod is TranslatedAssetLibrary)
|
||||
cast(mod, TranslatedAssetLibrary).langFolder = name;
|
||||
#end
|
||||
}
|
||||
|
||||
@@ -86,7 +102,7 @@ class TranslationUtil
|
||||
{
|
||||
#if TRANSLATIONS_SUPPORT
|
||||
if (id == null) id = defString;
|
||||
if (transMap.exists(id)) return transMap.get(id).format(params);
|
||||
if (stringMap.exists(id)) return stringMap.get(id).format(params);
|
||||
#end
|
||||
return FormatUtil.get(defString).format(params);
|
||||
}
|
||||
@@ -94,64 +110,149 @@ class TranslationUtil
|
||||
/**
|
||||
* Returns an array that specifies which languages were found.
|
||||
*/
|
||||
public static function getLanguages():Array<String>
|
||||
public static function findAllLanguages()
|
||||
{
|
||||
var languages:Array<String> = [];
|
||||
#if TRANSLATIONS_SUPPORT
|
||||
var main:String = Paths.translationsMain('');
|
||||
for (l in Paths.assetsTree.getFolders(main)) {
|
||||
var path:String = main + l + "/config.ini";
|
||||
if(Assets.exists(path)) languages.push('$l/' + IniUtil.parseAsset(path, ["name" => l])["name"]);
|
||||
else for(f in Paths.assetsTree.getFiles(main + l)) if(Path.extension(path = '$l/$f') == "xml") {
|
||||
languages.push(Path.withoutExtension(path));
|
||||
break; // only gets the first xml's name if theres no config.ini! - Nex
|
||||
foundLanguages = [];
|
||||
nameMap = getDefaultNameMap();
|
||||
var mainPath:String = translationsMain("");
|
||||
var langName:String = null;
|
||||
for (lang in Paths.assetsTree.getFolders("assets/" + mainPath)) {
|
||||
var path:String = Path.join([mainPath, lang, "config.ini"]);
|
||||
|
||||
var config = getDefaultConfig(lang);
|
||||
|
||||
if(Assets.exists(path)) {
|
||||
config = IniUtil.parseAsset(path, config);
|
||||
langName = config["name"];
|
||||
} else { // if there was no config.ini, use the file name as the language name
|
||||
for(file in Paths.getFolderContent(mainPath + lang).sortAlphabetically()) {
|
||||
if(Path.extension(path = '$lang/$file') == "xml") {
|
||||
config["name"] = (langName = Path.withoutExtension(file));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
nameMap.set(lang, langName);
|
||||
langConfigs.set(lang, config);
|
||||
foundLanguages.push('$lang/$langName');
|
||||
}
|
||||
|
||||
// Ensure that the default language is always first
|
||||
var englishName = TranslationUtil.DEFAULT_LANGUAGE + "/" + getLanguageName(TranslationUtil.DEFAULT_LANGUAGE);
|
||||
if (foundLanguages.contains(englishName))
|
||||
foundLanguages.remove(englishName);
|
||||
foundLanguages.insert(0, englishName);
|
||||
#end
|
||||
return languages;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a map of translations based on its XML.
|
||||
*/
|
||||
public static function loadLanguage(folderName:String):Map<String, IFormatInfo>
|
||||
public static function loadLanguage(lang:String):Map<String, IFormatInfo>
|
||||
{
|
||||
#if TRANSLATIONS_SUPPORT
|
||||
var mainPath:String = Paths.translationsMain(folderName);
|
||||
FormatUtil.clear(); // Clean up the format cache
|
||||
var mainPath:String = translationsMain(lang);
|
||||
var leMap:Map<String, IFormatInfo> = [];
|
||||
for(file in Paths.getFolderContent(mainPath)) if(Path.extension(file) == "xml") {
|
||||
var xml:Access = null;
|
||||
try xml = new Access(Xml.parse(Assets.getText('$mainPath/$file')))
|
||||
catch(e) {
|
||||
Logs.error('Error while parsing $file: ${Std.string(e)}');
|
||||
return [];
|
||||
}
|
||||
if (xml == null) return [];
|
||||
if (!xml.hasNode.translations) {
|
||||
Logs.warn("A translation xml file requires a translations root element.");
|
||||
return [];
|
||||
}
|
||||
|
||||
FormatUtil.clear(); // Clean up the format cache
|
||||
for(node in xml.node.translations.elements) {
|
||||
switch(node.name) {
|
||||
case "trans":
|
||||
if (!node.has.id) {
|
||||
Logs.warn("A translation node requires an ID attribute.");
|
||||
continue;
|
||||
}
|
||||
|
||||
var string:String = node.has.string ? node.att.string : node.x.nodeValue;
|
||||
string = string.replace("\\n", "\n").replace("\r", ""); // remove stupid windows line breaks and convert newline literals to newlines
|
||||
leMap.set(node.att.id, FormatUtil.get(string));
|
||||
}
|
||||
var translations = [];
|
||||
function parseXml(xml:Access) {
|
||||
for(node in xml.elements) {
|
||||
if (node.name == "group") // Cosmetic name
|
||||
parseXml(node);
|
||||
else if(node.name == "text" || node.name == "trans" || node.name == "lang" || node.name == "string")
|
||||
translations.push(node);
|
||||
}
|
||||
}
|
||||
|
||||
for(file in Paths.getFolderContent(mainPath, true).sortAlphabetically()) {
|
||||
if(Path.extension(file) != "xml") continue;
|
||||
|
||||
// Parse the XML
|
||||
var xml:Access = null;
|
||||
try xml = new Access(Xml.parse(Assets.getText(file)))
|
||||
catch(e) Logs.error('Error while parsing $file: ${Std.string(e)}', "Language");
|
||||
|
||||
if (xml == null) continue;
|
||||
if (!xml.hasNode.language) {
|
||||
Logs.warn('File $file requires a <language> root element.', "Language");
|
||||
continue;
|
||||
}
|
||||
|
||||
var langNode = xml.node.language;
|
||||
|
||||
//if (langNode.has.name) {
|
||||
// getConfig(lang).set("name", langNode.att.name);
|
||||
//}
|
||||
|
||||
parseXml(langNode);
|
||||
}
|
||||
|
||||
for(node in translations) {
|
||||
if (!node.has.id) {
|
||||
Logs.warn('A <${node.name}> node requires an ID attribute.', "Language");
|
||||
continue;
|
||||
}
|
||||
|
||||
var value:String = node.has.string ? node.att.string : node.innerData;
|
||||
value = value.replace("\\n", "\n").replace("\r", ""); // remove stupid windows line breaks and convert newline literals to newlines
|
||||
leMap.set(node.att.id, FormatUtil.get(value));
|
||||
}
|
||||
|
||||
return leMap;
|
||||
#else
|
||||
return [];
|
||||
#end
|
||||
}
|
||||
|
||||
// Utils
|
||||
|
||||
public static function getLanguageName(lang:String) {
|
||||
return nameMap.exists(lang) ? nameMap.get(lang) : lang;
|
||||
}
|
||||
|
||||
public static function getLanguageFromName(name:String) {
|
||||
var reverseMap = new Map<String, String>();
|
||||
for(key => val in nameMap) reverseMap.set(val, key);
|
||||
return reverseMap.exists(name) ? reverseMap.get(name) : name;
|
||||
}
|
||||
|
||||
public static function getConfig(lang:String):IniMap {
|
||||
return langConfigs.exists(lang) ? langConfigs.get(lang) : getDefaultConfig(lang);
|
||||
}
|
||||
|
||||
public static inline function translationsMain(key:String)
|
||||
return '$LANG_FOLDER/$key';
|
||||
|
||||
public static inline function translations(key:String)
|
||||
return translationsMain('$curLanguage/$key');
|
||||
|
||||
// getters & setters
|
||||
|
||||
@:noCompletion private static function set_stringMap(value:Map<String, IFormatInfo>):Map<String, IFormatInfo> {
|
||||
if (value == null) value = [];
|
||||
return stringMap = value;
|
||||
}
|
||||
|
||||
@:noCompletion private static function get_curLanguage():String {
|
||||
return Options.language;
|
||||
}
|
||||
@:noCompletion private static function set_curLanguage(value:String):String {
|
||||
return Options.language = value;
|
||||
}
|
||||
|
||||
@:noCompletion private static function get_curLanguageName():String {
|
||||
return getLanguageName(Options.language);
|
||||
}
|
||||
@:noCompletion private static function set_curLanguageName(value:String):String {
|
||||
return Options.language = getLanguageFromName(value);
|
||||
}
|
||||
|
||||
@:noCompletion private static function get_isDefaultLanguage():Bool
|
||||
return Options.language == DEFAULT_LANGUAGE;
|
||||
|
||||
@:noCompletion private static function get_isLanguageLoaded():Bool
|
||||
return Lambda.count(stringMap) > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -187,6 +288,10 @@ class StrFormatInfo implements IFormatInfo {
|
||||
public function format(params:Array<Dynamic>):String {
|
||||
return string;
|
||||
}
|
||||
|
||||
public function toString():String {
|
||||
return "StrFormatInfo(" + string + ")";
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: add support for @:({0}==1?(Hello):(World))
|
||||
@@ -235,6 +340,10 @@ class ParamFormatInfo implements IFormatInfo {
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
public function toString():String {
|
||||
return 'ParamFormatInfo([${strings.join(", ")}] [${indexes.join(", ")}])';
|
||||
}
|
||||
}
|
||||
|
||||
interface IFormatInfo {
|
||||
|
||||
@@ -6,15 +6,14 @@ class MiscOptions extends OptionsScreen {
|
||||
super("Miscellaneous", "Use this menu to reset save data or engine settings.");
|
||||
|
||||
{ // Language Option
|
||||
var lanArray:Array<String> = TranslationUtil.getLanguages();
|
||||
if (lanArray.contains(TranslationUtil.DEFAULT_LANGUAGE))
|
||||
lanArray.remove(TranslationUtil.DEFAULT_LANGUAGE);
|
||||
lanArray.insert(0, TranslationUtil.DEFAULT_LANGUAGE);
|
||||
var lanArray:Array<String> = TranslationUtil.foundLanguages;
|
||||
|
||||
// TODO: add credits based on the config file
|
||||
add(new ArrayOption(
|
||||
"Language",
|
||||
'The language that the engine currently uses (the default one is ${TranslationUtil.DEFAULT_LANGUAGE}).',
|
||||
lanArray, [for(lan in lanArray) lan.split("/").last()], "language",
|
||||
[for(lan in lanArray) lan.split("/").first()],
|
||||
[for(lan in lanArray) lan.split("/").last()], "language",
|
||||
function(path:String) {
|
||||
TranslationUtil.setLanguage(path);
|
||||
parent.remove(this);
|
||||
|
||||
Reference in New Issue
Block a user