Skip to content

Commit 8f7fa14

Browse files
committed
Add LangManager for language support, update Spigot API version, and modify README
1 parent 97c5969 commit 8f7fa14

14 files changed

Lines changed: 298 additions & 39 deletions

File tree

build.gradle

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ repositories {
1919
maven {
2020
url 'https://hub.spigotmc.org/nexus/content/repositories/snapshots/'
2121
}
22+
2223
maven {
2324
url 'https://oss.sonatype.org/content/repositories/snapshots/'
2425
}
@@ -31,7 +32,8 @@ dependencies {
3132
implementation 'io.projectreactor:reactor-core:3.6.9'
3233
implementation 'org.springframework.boot:spring-boot-starter-webflux:3.2.2'
3334

34-
compileOnly 'org.spigotmc:spigot-api:1.8-R0.1-SNAPSHOT'
35+
// Version moderne sans problèmes de dépendances
36+
compileOnly 'org.spigotmc:spigot-api:1.16.5-R0.1-SNAPSHOT'
3537
}
3638

3739
application {

readme.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ Stable Version: 0.3.0-STABLE
2626
Support Lib : Java 23
2727
2828
Hook -----------------------|
29-
- Support Minecraft 1.8 - Latest Version
29+
- Support Minecraft 1.16 - Latest Version
3030
- Support LangType 0.1.0 - Latest Version
3131
3232
- Coming Soon.

src/main/java/fr/sandro642/github/ConnectLib.java

Lines changed: 25 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ public class ConnectLib {
3131
private static YamlUtils yamlUtils = new YamlUtils();
3232
private static final Map<String,String> routes = new HashMap<>();
3333
private static Logs logs = new Logs();
34+
private static LangManager langManager;
3435

3536
/**
3637
* Init the ConnectLib with the specified resource type and routes.
@@ -39,15 +40,6 @@ public class ConnectLib {
3940
*/
4041
public static void initialize(ResourceType resourceType, LangType langType, Class<? extends Enum<?>>... routes) {
4142
try {
42-
Map<Enum<?>, String> routesEnums = new HashMap<>();
43-
for (Class<? extends Enum<?>> route : routes) {
44-
if (route == null) {
45-
ConnectLib.Logger().ERROR("Route class cannot be null.");
46-
}
47-
48-
routesEnums.putAll(EnumLoader.convertRouteImport(route));
49-
}
50-
5143
logger = new Logger();
5244
storeAndRetrieve = new StoreAndRetrieve();
5345
yamlUtils = new YamlUtils();
@@ -57,8 +49,18 @@ public static void initialize(ResourceType resourceType, LangType langType, Clas
5749
LangSupport().setLangTypeVariable(langType);
5850
HookManager().FILE_LOCATION_KEY();
5951

60-
yamlUtils.generateTemplateIfNotExists(routesEnums);
52+
langManager = new LangManager();
6153

54+
Map<Enum<?>, String> routesEnums = new HashMap<>();
55+
for (Class<? extends Enum<?>> route : routes) {
56+
if (route == null) {
57+
ConnectLib.Logger().ERROR(langManager.getMessage("connectlib.class", "initialise.routeclass"));
58+
continue;
59+
}
60+
routesEnums.putAll(EnumLoader.convertRouteImport(route));
61+
}
62+
63+
yamlUtils.generateTemplateIfNotExists(routesEnums);
6264
logs.setPathFile();
6365

6466
String baseUrl = yamlUtils.getURL();
@@ -71,7 +73,7 @@ public static void initialize(ResourceType resourceType, LangType langType, Clas
7173
ConnectLib.routes.putAll(yamlRoutes);
7274
}
7375
} catch (Exception e) {
74-
ConnectLib.Logger().ERROR("Error while initializing ConnectLib: " + e.getMessage());
76+
ConnectLib.Logger().ERROR(langManager.getMessage("connectlib.class", "initialise.catcherror", Map.of("exception", e.getMessage())));
7577
}
7678
}
7779

@@ -156,8 +158,20 @@ public static HookManager HookManager() {
156158
return HookManager.getInstance();
157159
}
158160

161+
/**
162+
* Return the instance of LangSupport.
163+
* @return LangSupport instance
164+
*/
159165
public static LangSupport LangSupport() {
160166
return LangSupport.getInstance();
161167

162168
}
169+
170+
/**
171+
* Return the instance of LangManager.
172+
* @return LangManager instance
173+
*/
174+
public static LangManager LangManager() {
175+
return langManager;
176+
}
163177
}

src/main/java/fr/sandro642/github/hook/LangSupport.java

Lines changed: 8 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -21,25 +21,7 @@ public class LangSupport {
2121
/**
2222
* Prefix for language files.
2323
*/
24-
private final String PREFIX = "lang";
25-
26-
/**
27-
* Paths for different languages.
28-
* FRENCH_PATH, ENGLISH_PATH, SPANISH_PATH, GERMAN_PATH, ITALIAN_PATH, PORTUGUESE_PATH, RUSSIAN_PATH
29-
*/
30-
private final String FRENCH_PATH = ConnectLib.HookManager().BASE_PATH() + "/" + PREFIX + "/";
31-
32-
private final String ENGLISH_PATH = ConnectLib.HookManager().BASE_PATH() + "/" + PREFIX + "/";
33-
34-
private final String SPANISH_PATH = ConnectLib.HookManager().BASE_PATH() + "/" + PREFIX + "/";
35-
36-
private final String GERMAN_PATH = ConnectLib.HookManager().BASE_PATH() + "/" + PREFIX + "/";
37-
38-
private final String ITALIAN_PATH = ConnectLib.HookManager().BASE_PATH() + "/" + PREFIX + "/";
39-
40-
private final String PORTUGUESE_PATH = ConnectLib.HookManager().BASE_PATH() + "/" + PREFIX + "/";
41-
42-
private final String RUSSIAN_PATH = ConnectLib.HookManager().BASE_PATH() + "/" + PREFIX + "/";
24+
private final String PREFIX = "lang/";
4325

4426
/**
4527
* Private singleton langType.
@@ -72,19 +54,19 @@ public String getPathFile() {
7254

7355
switch (langTypeSingleton) {
7456
case FRENCH:
75-
return FRENCH_PATH + langTypeSingleton.getLang() + ".lang";
57+
return PREFIX + langTypeSingleton.getLang() + ".lang";
7658
case ENGLISH:
77-
return ENGLISH_PATH + langTypeSingleton.getLang() + ".lang";
59+
return PREFIX + langTypeSingleton.getLang() + ".lang";
7860
case SPANISH:
79-
return SPANISH_PATH + langTypeSingleton.getLang() + ".lang";
61+
return PREFIX + langTypeSingleton.getLang() + ".lang";
8062
case GERMAN:
81-
return GERMAN_PATH + langTypeSingleton.getLang() + ".lang";
63+
return PREFIX + langTypeSingleton.getLang() + ".lang";
8264
case ITALIAN:
83-
return ITALIAN_PATH + langTypeSingleton.getLang() + ".lang";
65+
return PREFIX + langTypeSingleton.getLang() + ".lang";
8466
case PORTUGUESE:
85-
return PORTUGUESE_PATH + langTypeSingleton.getLang() + ".lang";
67+
return PREFIX + langTypeSingleton.getLang() + ".lang";
8668
case RUSSIAN:
87-
return RUSSIAN_PATH + langTypeSingleton.getLang() + ".lang";
69+
return PREFIX + langTypeSingleton.getLang() + ".lang";
8870

8971
default:
9072
ConnectLib.Logger().CRITICAL("Unsupported LangType: " + langTypeSingleton);

src/main/java/fr/sandro642/github/lang/FR_EU.lang

Whitespace-only changes.
Lines changed: 243 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,243 @@
1+
package fr.sandro642.github.misc;
2+
3+
import fr.sandro642.github.ConnectLib;
4+
5+
import java.io.BufferedReader;
6+
import java.io.IOException;
7+
import java.io.InputStream;
8+
import java.io.InputStreamReader;
9+
import java.nio.charset.StandardCharsets;
10+
import java.util.HashMap;
11+
import java.util.Map;
12+
import java.util.regex.Matcher;
13+
import java.util.regex.Pattern;
14+
15+
/**
16+
* LangManager handles loading and retrieving language messages
17+
* from .lang files with placeholder support.
18+
*
19+
* @author Sandro642
20+
* @version 1.0
21+
*/
22+
public class LangManager {
23+
24+
private final Map<String, Map<String, String>> messages;
25+
private static final Pattern CATEGORY_PATTERN = Pattern.compile("\\[(.+)]");
26+
private static final Pattern MESSAGE_PATTERN = Pattern.compile("(.+?):\\s*(.+)");
27+
private boolean loadedSuccessfully;
28+
private String loadError;
29+
30+
/**
31+
* LangManager constructor.
32+
* Automatically loads the language file configured in ConnectLib.
33+
*/
34+
public LangManager() {
35+
this.messages = new HashMap<>();
36+
this.loadedSuccessfully = false;
37+
this.loadError = null;
38+
39+
try {
40+
String langFilePath = ConnectLib.LangSupport().getPathFile();
41+
42+
if (langFilePath == null) {
43+
this.loadError = "LangType has not been defined. Call LangSupport().setLangTypeVariable() first.";
44+
System.err.println("Error loading language file: " + loadError);
45+
return;
46+
}
47+
48+
loadLangFile(langFilePath);
49+
this.loadedSuccessfully = true;
50+
} catch (IllegalArgumentException e) {
51+
this.loadError = e.getMessage();
52+
System.err.println("Error loading language file: " + e.getMessage());
53+
} catch (Exception e) {
54+
this.loadError = e.getMessage();
55+
System.err.println("Error loading language file: " + e.getMessage());
56+
e.printStackTrace();
57+
}
58+
}
59+
60+
/**
61+
* Loads the language file and parses its content.
62+
*
63+
* @param langFilePath path to the language file retrieved from ConnectLib
64+
*/
65+
private void loadLangFile(String langFilePath) {
66+
try {
67+
// Remove leading / if present for getResourceAsStream
68+
String resourcePath = langFilePath.startsWith("/") ? langFilePath.substring(1) : langFilePath;
69+
70+
InputStream inputStream = getClass().getClassLoader().getResourceAsStream(resourcePath);
71+
72+
if (inputStream == null) {
73+
throw new RuntimeException("Language file not found: " + langFilePath + " (searched: " + resourcePath + ")");
74+
}
75+
76+
try (BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8))) {
77+
String currentCategory = null;
78+
String line;
79+
80+
while ((line = reader.readLine()) != null) {
81+
line = line.trim();
82+
83+
// Ignore empty lines and comments
84+
if (line.isEmpty() || line.startsWith("#")) {
85+
continue;
86+
}
87+
88+
// Detect a category
89+
Matcher categoryMatcher = CATEGORY_PATTERN.matcher(line);
90+
if (categoryMatcher.matches()) {
91+
currentCategory = categoryMatcher.group(1);
92+
messages.putIfAbsent(currentCategory, new HashMap<>());
93+
continue;
94+
}
95+
96+
// Detect a message
97+
Matcher messageMatcher = MESSAGE_PATTERN.matcher(line);
98+
if (messageMatcher.matches() && currentCategory != null) {
99+
String key = messageMatcher.group(1).trim();
100+
String value = messageMatcher.group(2).trim();
101+
messages.get(currentCategory).put(key, value);
102+
}
103+
}
104+
}
105+
} catch (IOException e) {
106+
throw new RuntimeException("Error reading language file", e);
107+
}
108+
}
109+
110+
/**
111+
* Retrieves a translated message with argument replacement (varargs version).
112+
* Arguments are passed as pairs: placeholder_name, value
113+
*
114+
* @param category The message category (e.g., "connectlib.class")
115+
* @param messagePath The message path (e.g., "initialise.catcherror")
116+
* @param arguments Arguments to replace in the message (e.g., "exception", "NullPointerException")
117+
* @return The formatted message with replaced arguments
118+
*
119+
* @example
120+
* <pre>
121+
* getMessage("connectlib.class", "initialise.catcherror", "exception", "NullPointerException")
122+
* </pre>
123+
*/
124+
public String getMessage(String category, String messagePath, String... arguments) {
125+
if (arguments == null || arguments.length == 0) {
126+
return getMessage(category, messagePath, (Map<String, String>) null);
127+
}
128+
129+
// Convert varargs to Map
130+
Map<String, String> argsMap = new HashMap<>();
131+
for (int i = 0; i < arguments.length - 1; i += 2) {
132+
argsMap.put(arguments[i], arguments[i + 1]);
133+
}
134+
135+
return getMessage(category, messagePath, argsMap);
136+
}
137+
138+
/**
139+
* Retrieves a translated message with argument replacement (Map version).
140+
*
141+
* @param category The message category (e.g., "connectlib.class")
142+
* @param messagePath The message path (e.g., "initialise.catcherror")
143+
* @param arguments Map containing key-value pairs to replace placeholders
144+
* @return The formatted message with replaced arguments
145+
*
146+
* @example
147+
* <pre>
148+
* Map&lt;String, String&gt; args = new HashMap&lt;&gt;();
149+
* args.put("exception", "NullPointerException");
150+
* getMessage("connectlib.class", "initialise.catcherror", args)
151+
*
152+
* // Or with Map.of() (Java 9+)
153+
* getMessage("connectlib.class", "initialise.catcherror", Map.of("exception", "NullPointerException"))
154+
* </pre>
155+
*/
156+
public String getMessage(String category, String messagePath, Map<String, String> arguments) {
157+
if (!loadedSuccessfully) {
158+
return "Error: language file not loaded (" + (loadError != null ? loadError : "unknown reason") + ")";
159+
}
160+
161+
Map<String, String> categoryMessages = messages.get(category);
162+
163+
if (categoryMessages == null) {
164+
return "Message not found: category [" + category + "] does not exist";
165+
}
166+
167+
String message = categoryMessages.get(messagePath);
168+
169+
if (message == null) {
170+
return "Message not found: [" + category + "] " + messagePath;
171+
}
172+
173+
// Replace arguments
174+
if (arguments != null && !arguments.isEmpty()) {
175+
for (Map.Entry<String, String> entry : arguments.entrySet()) {
176+
String placeholder = "%" + entry.getKey() + "%";
177+
String value = entry.getValue();
178+
message = message.replace(placeholder, value);
179+
}
180+
}
181+
182+
return message;
183+
}
184+
185+
/**
186+
* Checks if the language file was loaded successfully.
187+
*
188+
* @return true if loading succeeded, false otherwise
189+
*/
190+
public boolean isLoadedSuccessfully() {
191+
return loadedSuccessfully;
192+
}
193+
194+
/**
195+
* Returns the loading error if there is one.
196+
*
197+
* @return The error message or null if no error
198+
*/
199+
public String getLoadError() {
200+
return loadError;
201+
}
202+
203+
/**
204+
* Checks if a category exists in the language file.
205+
*
206+
* @param category The category name to check
207+
* @return true if the category exists, false otherwise
208+
*/
209+
public boolean hasCategory(String category) {
210+
return messages.containsKey(category);
211+
}
212+
213+
/**
214+
* Checks if a message exists in a category.
215+
*
216+
* @param category The category name
217+
* @param messagePath The message path in the category
218+
* @return true if the message exists, false otherwise
219+
*/
220+
public boolean hasMessage(String category, String messagePath) {
221+
return messages.containsKey(category) &&
222+
messages.get(category).containsKey(messagePath);
223+
}
224+
225+
/**
226+
* Retrieves all available categories.
227+
*
228+
* @return A Set containing all category names
229+
*/
230+
public java.util.Set<String> getCategories() {
231+
return messages.keySet();
232+
}
233+
234+
/**
235+
* Retrieves all messages from a category.
236+
*
237+
* @param category The category name
238+
* @return A Map containing all messages in the category, or null if the category doesn't exist
239+
*/
240+
public Map<String, String> getMessagesInCategory(String category) {
241+
return messages.get(category);
242+
}
243+
}
File renamed without changes.
File renamed without changes.
File renamed without changes.

0 commit comments

Comments
 (0)