2525import java .util .*;
2626import java .util .logging .Level ;
2727
28- /**
29- * QuickShop universal text manager
30- * With multi-files and multi-languages support
31- */
3228public class TextManager {
3329 private final QuickShop plugin ;
3430 private final Distribution distribution ;
3531 // <File <Locale, Section>>
3632 private final Map <String , Map <String , JsonConfiguration >> locale2ContentMapping = new HashMap <>();
3733 private final static String languageFileCrowdin = "/master/src/main/resources/lang/%locale%/messages.json" ;
3834 public List <PostProcessor > postProcessors = new ArrayList <>();
39- // <File, Section>
40- private final Map <String , JsonConfiguration > bundledMapping = new HashMap <>();
4135 private JsonConfiguration bundledLang = new JsonConfiguration ();
4236
4337 public TextManager (QuickShop plugin ) {
@@ -46,78 +40,69 @@ public TextManager(QuickShop plugin) {
4640 load ();
4741 }
4842
49- /**
50- * Generate and returns the override files storage folder for specific file
51- *
52- * @param distributionPath The file name or path on distribution platform
53- * @return The storage folder
54- */
5543 @ NotNull
56- private File getOverrideFilesFolder (@ NotNull String distributionPath ) {
57- File folder = new File (new File (plugin .getDataFolder (), "overrides" ), getFileNameFromFullPath (distributionPath ) + ".overrides" );
44+ private File getOverrideFilesFolder (@ NotNull String crowdinPath ) {
45+ File file = new File (crowdinPath );
46+ File folder = new File (new File (plugin .getDataFolder (), "overrides" ), file .getName () + ".overrides" );
5847 folder .mkdirs ();
5948 return folder ;
6049 }
6150
62- private String getFileNameFromFullPath (@ NotNull String path ) {
63- return new File (path ).getName ();
64- }
65-
6651 public void load () {
6752 plugin .getLogger ().info ("Checking for translation updates..." );
6853 locale2ContentMapping .clear ();
6954 postProcessors .clear ();
7055 // Load mapping
71-
72-
56+ //for (String availableFile : distribution.getAvailableFiles()) {
57+ try {
58+ bundledLang .loadFromString (new String (IOUtils .toByteArray (new InputStreamReader (plugin .getResource ("lang-original/messages.json" )), StandardCharsets .UTF_8 )));
59+ } catch (IOException | InvalidConfigurationException ex ) {
60+ bundledLang = new JsonConfiguration ();
61+ plugin .getLogger ().log (Level .SEVERE , "Cannot load bundled language file from Jar, some strings may missing!" , ex );
62+ }
7363 // init file mapping
7464 locale2ContentMapping .computeIfAbsent (languageFileCrowdin , e -> new HashMap <>());
7565 // Multi File and Multi-Language loader
7666
77- distribution . getAvailableFiles (). parallelStream (). forEach ( crowdinFile -> {
78- JsonConfiguration bundledLang = new JsonConfiguration ();
67+
68+ distribution . getAvailableLanguages (). parallelStream (). forEach ( crowdinCode -> distribution . getAvailableFiles (). parallelStream (). forEach ( crowdinFile -> {
7969 try {
80- bundledLang .loadFromString (new String (IOUtils .toByteArray (new InputStreamReader (plugin .getResource ("bundled/" + getFileNameFromFullPath (crowdinFile ))), StandardCharsets .UTF_8 )));
81- } catch (IOException | InvalidConfigurationException ex ) {
82- bundledLang = new JsonConfiguration ();
83- plugin .getLogger ().log (Level .SEVERE , "Cannot load bundled file " + crowdinFile + " from Jar, some strings may missing!" , ex );
84- }
85- bundledMapping .put (crowdinFile , bundledLang );
86- distribution .getAvailableLanguages ().parallelStream ().forEach (crowdinCode -> {
70+ // load OTA text from Crowdin
71+
72+ String minecraftCode = crowdinCode .toLowerCase (Locale .ROOT ).replace ("-" , "_" );
73+
74+ Util .debugLog ("Loading translation for locale: " + crowdinCode + " (" + minecraftCode + ")" );
75+ JsonConfiguration configuration = new JsonConfiguration ();
8776 try {
88- // load OTA text from Crowdin
89- String minecraftCode = crowdinCode .toLowerCase (Locale .ROOT ).replace ("-" , "_" );
90- Util .debugLog ("Loading translation for locale: " + crowdinCode + " (" + minecraftCode + ")" );
91- JsonConfiguration configuration = new JsonConfiguration ();
92- try {
93- configuration .loadFromString (distribution .getFile (crowdinFile , crowdinCode ));
94- } catch (InvalidConfigurationException exception ) {
95- configuration .loadFromString (distribution .getFile (crowdinFile , crowdinCode , true ));
96- }
97- // load override text (allow user modification the translation)
98- JsonConfiguration override = new JsonConfiguration ();
99- File localOverrideFile = new File (getOverrideFilesFolder (crowdinFile ), minecraftCode + ".json" );
100- if (!localOverrideFile .exists ()) {
101- localOverrideFile .getParentFile ().mkdirs ();
102- localOverrideFile .createNewFile ();
103- }
104- override .loadFromString (Util .readToString (localOverrideFile ));
105- for (String key : override .getKeys (true )) {
106- if (key .equals ("language-version" ) || key .equals ("config-version" ) || key .equals ("version" ))
107- continue ;
108- configuration .set (key , override .get (key ));
109- }
110- locale2ContentMapping .get (languageFileCrowdin ).computeIfAbsent (minecraftCode , e -> configuration );
111- } catch (CrowdinOTA .OTAException e ) {
112- plugin .getLogger ().warning ("Couldn't update the translation for locale " + crowdinCode + " because it not configured, please report to QuickShop" );
113- } catch (IOException e ) {
114- plugin .getLogger ().log (Level .WARNING , "Couldn't update the translation for locale " + crowdinCode + " please check your network connection." , e );
115- } catch (Exception e ) {
116- plugin .getLogger ().log (Level .WARNING , "Couldn't update the translation for locale " + crowdinCode + "." , e );
77+ configuration .loadFromString (distribution .getFile (crowdinFile , crowdinCode ));
78+ } catch (InvalidConfigurationException exception ) {
79+ configuration .loadFromString (distribution .getFile (crowdinFile , crowdinCode , true ));
11780 }
118- });
119- });
120-
81+ // load override text (allow user modification the translation)
82+ JsonConfiguration override = new JsonConfiguration ();
83+ File localOverrideFile = new File (getOverrideFilesFolder (crowdinFile ), minecraftCode + ".json" );
84+ if (!localOverrideFile .exists ()) {
85+ localOverrideFile .getParentFile ().mkdirs ();
86+ localOverrideFile .createNewFile ();
87+ }
88+ override .loadFromString (Util .readToString (localOverrideFile ));
89+ for (String key : override .getKeys (true )) {
90+ if (key .equals ("language-version" ) || key .equals ("config-version" ) || key .equals ("version" ))
91+ continue ;
92+ configuration .set (key , override .get (key ));
93+ }
94+ locale2ContentMapping .get (languageFileCrowdin ).computeIfAbsent (minecraftCode , e -> configuration );
95+ Util .debugLog ("Locale " + crowdinFile );
96+ if (configuration .getInt ("language-version" ) < bundledLang .getInt ("language-version" ))
97+ Util .debugLog ("Locale " + crowdinCode + " file version is outdated, some string will fallback to English." );
98+ } catch (CrowdinOTA .OTAException e ) {
99+ plugin .getLogger ().warning ("Couldn't update the translation for locale " + crowdinCode + " because it not configured, please report to QuickShop" );
100+ } catch (IOException e ) {
101+ plugin .getLogger ().log (Level .WARNING , "Couldn't update the translation for locale " + crowdinCode + " please check your network connection." , e );
102+ } catch (Exception e ) {
103+ plugin .getLogger ().log (Level .WARNING , "Couldn't update the translation for locale " + crowdinCode + "." , e );
104+ }
105+ }));
121106
122107
123108// for (String availableLanguage : distribution.getAvailableLanguages()) {
@@ -129,27 +114,27 @@ public void load() {
129114 }
130115
131116 public Text of (@ NotNull String path , String ... args ) {
132- return new Text (this , (CommandSender ) null , languageFileCrowdin , path , args );
117+ return new Text (this , (CommandSender ) null , locale2ContentMapping . get ( languageFileCrowdin ) , path , args );
133118 }
134119
135120 public Text of (@ Nullable CommandSender sender , @ NotNull String path , String ... args ) {
136- return new Text (this , sender , languageFileCrowdin , path , args );
121+ return new Text (this , sender , locale2ContentMapping . get ( languageFileCrowdin ) , path , args );
137122 }
138123
139124 public Text of (@ Nullable UUID sender , @ NotNull String path , String ... args ) {
140- return new Text (this , sender , languageFileCrowdin , path , args );
125+ return new Text (this , sender , locale2ContentMapping . get ( languageFileCrowdin ) , path , args );
141126 }
142127
143128 public TextList ofList (@ NotNull String path , String ... args ) {
144- return new TextList (this , (CommandSender ) null , languageFileCrowdin , path , args );
129+ return new TextList (this , (CommandSender ) null , locale2ContentMapping . get ( languageFileCrowdin ) , path , args );
145130 }
146131
147132 public TextList ofList (@ Nullable UUID sender , @ NotNull String path , String ... args ) {
148- return new TextList (this , sender , languageFileCrowdin , path , args );
133+ return new TextList (this , sender , locale2ContentMapping . get ( languageFileCrowdin ) , path , args );
149134 }
150135
151136 public TextList ofList (@ Nullable CommandSender sender , @ NotNull String path , String ... args ) {
152- return new TextList (this , sender , languageFileCrowdin , path , args );
137+ return new TextList (this , sender , locale2ContentMapping . get ( languageFileCrowdin ) , path , args );
153138 }
154139
155140 public static class TextList {
@@ -160,23 +145,23 @@ public static class TextList {
160145 private final CommandSender sender ;
161146 private final String [] args ;
162147
163- private TextList (TextManager manager , CommandSender sender , String file , String path , String ... args ) {
148+ private TextList (TextManager manager , CommandSender sender , Map < String , JsonConfiguration > mapping , String path , String ... args ) {
164149 this .plugin = manager .plugin ;
165150 this .manager = manager ;
166151 this .sender = sender ;
167- this .mapping = manager . locale2ContentMapping . get ( file ) ;
152+ this .mapping = mapping ;
168153 this .path = path ;
169154 this .args = args ;
170155 }
171156
172- private TextList (TextManager manager , UUID sender , String file , String path , String ... args ) {
157+ private TextList (TextManager manager , UUID sender , Map < String , JsonConfiguration > mapping , String path , String ... args ) {
173158 this .plugin = manager .plugin ;
174159 this .manager = manager ;
175160 if (sender != null )
176161 this .sender = Bukkit .getPlayer (sender );
177162 else
178163 this .sender = null ;
179- this .mapping = manager . locale2ContentMapping . get ( file ) ;
164+ this .mapping = mapping ;
180165 this .path = path ;
181166 this .args = args ;
182167 }
@@ -244,23 +229,23 @@ public static class Text {
244229 private final CommandSender sender ;
245230 private final String [] args ;
246231
247- private Text (TextManager manager , CommandSender sender , String file , String path , String ... args ) {
232+ private Text (TextManager manager , CommandSender sender , Map < String , JsonConfiguration > mapping , String path , String ... args ) {
248233 this .plugin = manager .plugin ;
249234 this .manager = manager ;
250235 this .sender = sender ;
251- this .mapping = manager . locale2ContentMapping . get ( file ) ;
236+ this .mapping = mapping ;
252237 this .path = path ;
253238 this .args = args ;
254239 }
255240
256- private Text (TextManager manager , UUID sender , String file , String path , String ... args ) {
241+ private Text (TextManager manager , UUID sender , Map < String , JsonConfiguration > mapping , String path , String ... args ) {
257242 this .plugin = manager .plugin ;
258243 this .manager = manager ;
259244 if (sender != null )
260245 this .sender = Bukkit .getPlayer (sender );
261246 else
262247 this .sender = null ;
263- this .mapping = manager . locale2ContentMapping . get ( file ) ;
248+ this .mapping = mapping ;
264249 this .path = path ;
265250 this .args = args ;
266251 }
0 commit comments