mirror of
https://github.com/CitizensDev/Citizens2.git
synced 2024-12-29 12:37:37 +01:00
Promote Translator to API, move to Colorizer
This commit is contained in:
parent
f58bac5cd0
commit
1dc12ccf9b
@ -3,6 +3,7 @@ package net.citizensnpcs;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.Iterator;
|
||||
import java.util.Locale;
|
||||
|
||||
import net.citizensnpcs.Settings.Setting;
|
||||
import net.citizensnpcs.api.CitizensAPI;
|
||||
@ -19,6 +20,7 @@ import net.citizensnpcs.api.scripting.ObjectProvider;
|
||||
import net.citizensnpcs.api.scripting.ScriptCompiler;
|
||||
import net.citizensnpcs.api.trait.Trait;
|
||||
import net.citizensnpcs.api.trait.TraitFactory;
|
||||
import net.citizensnpcs.api.util.Translator;
|
||||
import net.citizensnpcs.command.CommandContext;
|
||||
import net.citizensnpcs.command.CommandManager;
|
||||
import net.citizensnpcs.command.CommandManager.CommandInfo;
|
||||
@ -173,6 +175,7 @@ public class Citizens extends JavaPlugin implements CitizensPlugin {
|
||||
|
||||
@Override
|
||||
public void onEnable() {
|
||||
setupTranslator();
|
||||
CitizensAPI.setImplementation(this);
|
||||
// Disable if the server is not using the compatible Minecraft version
|
||||
String mcVersion = Util.getMinecraftVersion();
|
||||
@ -289,6 +292,28 @@ public class Citizens extends JavaPlugin implements CitizensPlugin {
|
||||
}
|
||||
}
|
||||
|
||||
private void setupTranslator() {
|
||||
Locale locale = Locale.getDefault();
|
||||
String setting = Setting.LOCALE.asString();
|
||||
if (!setting.isEmpty()) {
|
||||
String[] parts = setting.split("[\\._]");
|
||||
switch (parts.length) {
|
||||
case 1:
|
||||
locale = new Locale(parts[0]);
|
||||
break;
|
||||
case 2:
|
||||
locale = new Locale(parts[0], parts[1]);
|
||||
break;
|
||||
case 3:
|
||||
locale = new Locale(parts[0], parts[1], parts[2]);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
Translator.setInstance(new File(getDataFolder(), "lang"), locale);
|
||||
}
|
||||
|
||||
private void startMetrics() {
|
||||
try {
|
||||
Metrics metrics = new Metrics(Citizens.this);
|
||||
|
@ -17,6 +17,7 @@ import net.citizensnpcs.api.trait.trait.MobType;
|
||||
import net.citizensnpcs.api.trait.trait.Owner;
|
||||
import net.citizensnpcs.api.trait.trait.Spawned;
|
||||
import net.citizensnpcs.api.trait.trait.Speech;
|
||||
import net.citizensnpcs.api.util.Colorizer;
|
||||
import net.citizensnpcs.api.util.DataKey;
|
||||
import net.citizensnpcs.api.util.MemoryDataKey;
|
||||
import net.citizensnpcs.command.Command;
|
||||
@ -274,7 +275,7 @@ public class NPCCommands {
|
||||
permission = "npc.create")
|
||||
@Requirements
|
||||
public void create(CommandContext args, CommandSender sender, NPC npc) throws CommandException {
|
||||
String name = StringHelper.parseColors(args.getJoinedStrings(1));
|
||||
String name = Colorizer.parseColors(args.getJoinedStrings(1));
|
||||
if (name.length() > 16) {
|
||||
Messaging.sendErrorTr(sender, Messages.NPC_NAME_TOO_LONG);
|
||||
name = name.substring(0, 15);
|
||||
@ -966,9 +967,8 @@ public class NPCCommands {
|
||||
min = 2,
|
||||
permission = "npc.speak")
|
||||
public void speak(CommandContext args, CommandSender sender, NPC npc) throws CommandException {
|
||||
|
||||
String type = npc.getTrait(Speech.class).getDefaultVocalChord();
|
||||
String message = StringHelper.parseColors(args.getJoinedStrings(1));
|
||||
String message = Colorizer.parseColors(args.getJoinedStrings(1));
|
||||
|
||||
if (message.length() <= 0) {
|
||||
Messaging.send(sender, "Default Vocal Chord for " + npc.getName() + ": "
|
||||
|
@ -3,9 +3,9 @@ package net.citizensnpcs.npc.entity;
|
||||
import net.citizensnpcs.Settings.Setting;
|
||||
import net.citizensnpcs.api.CitizensAPI;
|
||||
import net.citizensnpcs.api.npc.NPC;
|
||||
import net.citizensnpcs.api.util.Colorizer;
|
||||
import net.citizensnpcs.npc.AbstractEntityController;
|
||||
import net.citizensnpcs.util.NMS;
|
||||
import net.citizensnpcs.util.StringHelper;
|
||||
import net.minecraft.server.v1_4_R1.PlayerInteractManager;
|
||||
import net.minecraft.server.v1_4_R1.WorldServer;
|
||||
|
||||
@ -19,7 +19,7 @@ public class HumanController extends AbstractEntityController {
|
||||
@Override
|
||||
protected LivingEntity createEntity(final Location at, final NPC npc) {
|
||||
WorldServer ws = ((CraftWorld) at.getWorld()).getHandle();
|
||||
final EntityHumanNPC handle = new EntityHumanNPC(ws.getServer().getServer(), ws, StringHelper.parseColors(npc
|
||||
final EntityHumanNPC handle = new EntityHumanNPC(ws.getServer().getServer(), ws, Colorizer.parseColors(npc
|
||||
.getFullName()), new PlayerInteractManager(ws), npc);
|
||||
handle.getBukkitEntity().teleport(at);
|
||||
Bukkit.getScheduler().scheduleSyncDelayedTask(CitizensAPI.getPlugin(), new Runnable() {
|
||||
|
@ -6,6 +6,8 @@ import java.util.regex.Pattern;
|
||||
import net.citizensnpcs.Settings.Setting;
|
||||
import net.citizensnpcs.api.npc.NPC;
|
||||
import net.citizensnpcs.api.trait.trait.Owner;
|
||||
import net.citizensnpcs.api.util.Colorizer;
|
||||
import net.citizensnpcs.api.util.Translator;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.ChatColor;
|
||||
@ -37,6 +39,24 @@ public class Messaging {
|
||||
log(Level.INFO, Translator.translate(key, msg));
|
||||
}
|
||||
|
||||
private static String prettify(String message) {
|
||||
String trimmed = message.trim();
|
||||
String messageColour = Colorizer.parseColors(Setting.MESSAGE_COLOUR.asString());
|
||||
if (!trimmed.isEmpty()) {
|
||||
if (trimmed.charAt(0) == ChatColor.COLOR_CHAR) {
|
||||
ChatColor test = ChatColor.getByChar(trimmed.substring(1, 2));
|
||||
if (test == null) {
|
||||
message = messageColour + message;
|
||||
} else
|
||||
messageColour = test.toString();
|
||||
} else
|
||||
message = messageColour + message;
|
||||
}
|
||||
message = message.replace("[[", Colorizer.parseColors(Setting.HIGHLIGHT_COLOUR.asString()));
|
||||
message = message.replace("]]", messageColour);
|
||||
return message;
|
||||
}
|
||||
|
||||
public static void send(CommandSender sender, Object... msg) {
|
||||
sendMessageTo(sender, SPACE.join(msg));
|
||||
}
|
||||
@ -50,23 +70,9 @@ public class Messaging {
|
||||
}
|
||||
|
||||
private static void sendMessageTo(CommandSender sender, String rawMessage) {
|
||||
rawMessage = StringHelper.parseColors(rawMessage);
|
||||
rawMessage = Colorizer.parseColors(rawMessage);
|
||||
for (String message : CHAT_NEWLINE_SPLITTER.split(rawMessage)) {
|
||||
String trimmed = message.trim();
|
||||
String messageColour = StringHelper.parseColors(Setting.MESSAGE_COLOUR.asString());
|
||||
if (!trimmed.isEmpty()) {
|
||||
if (trimmed.charAt(0) == ChatColor.COLOR_CHAR) {
|
||||
ChatColor test = ChatColor.getByChar(trimmed.substring(1, 2));
|
||||
if (test == null) {
|
||||
message = messageColour + message;
|
||||
} else
|
||||
messageColour = test.toString();
|
||||
} else
|
||||
message = messageColour + message;
|
||||
}
|
||||
message = message.replace("[[", StringHelper.parseColors(Setting.HIGHLIGHT_COLOUR.asString()));
|
||||
message = message.replace("]]", messageColour);
|
||||
sender.sendMessage(message);
|
||||
sender.sendMessage(prettify(message));
|
||||
}
|
||||
}
|
||||
|
||||
@ -98,22 +104,7 @@ public class Messaging {
|
||||
}
|
||||
|
||||
public static String tr(String key, Object... messages) {
|
||||
String message = Translator.translate(key, messages);
|
||||
String trimmed = message.trim();
|
||||
String messageColour = StringHelper.parseColors(Setting.MESSAGE_COLOUR.asString());
|
||||
if (!trimmed.isEmpty()) {
|
||||
if (trimmed.charAt(0) == ChatColor.COLOR_CHAR) {
|
||||
ChatColor test = ChatColor.getByChar(trimmed.substring(1, 2));
|
||||
if (test == null) {
|
||||
message = messageColour + message;
|
||||
} else
|
||||
messageColour = test.toString();
|
||||
} else
|
||||
message = messageColour + message;
|
||||
}
|
||||
message = message.replace("[[", StringHelper.parseColors(Setting.HIGHLIGHT_COLOUR.asString()));
|
||||
message = message.replace("]]", messageColour);
|
||||
return message;
|
||||
return prettify(Translator.translate(key, messages));
|
||||
}
|
||||
|
||||
public static String tryTranslate(Object possible) {
|
||||
|
@ -1,16 +1,11 @@
|
||||
package net.citizensnpcs.util;
|
||||
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import net.citizensnpcs.Settings.Setting;
|
||||
import net.citizensnpcs.api.util.Colorizer;
|
||||
|
||||
import org.bukkit.ChatColor;
|
||||
|
||||
public class StringHelper {
|
||||
private static Pattern COLOR_MATCHER;
|
||||
|
||||
private static String GROUP = ChatColor.COLOR_CHAR + "$1";
|
||||
|
||||
public static String capitalize(Object string) {
|
||||
String capitalize = string.toString();
|
||||
@ -67,13 +62,8 @@ public class StringHelper {
|
||||
return p[n];
|
||||
}
|
||||
|
||||
public static String parseColors(String parsed) {
|
||||
Matcher matcher = COLOR_MATCHER.matcher(ChatColor.translateAlternateColorCodes('&', parsed));
|
||||
return matcher.replaceAll(GROUP);
|
||||
}
|
||||
|
||||
public static String wrap(Object string) {
|
||||
return wrap(string, parseColors(Setting.MESSAGE_COLOUR.asString()));
|
||||
return wrap(string, Colorizer.parseColors(Setting.MESSAGE_COLOUR.asString()));
|
||||
}
|
||||
|
||||
public static String wrap(Object string, ChatColor colour) {
|
||||
@ -81,18 +71,11 @@ public class StringHelper {
|
||||
}
|
||||
|
||||
public static String wrap(Object string, String colour) {
|
||||
return parseColors(Setting.HIGHLIGHT_COLOUR.asString()) + string.toString() + colour;
|
||||
return Colorizer.parseColors(Setting.HIGHLIGHT_COLOUR.asString()) + string.toString() + colour;
|
||||
}
|
||||
|
||||
public static String wrapHeader(Object string) {
|
||||
String highlight = Setting.HIGHLIGHT_COLOUR.asString();
|
||||
return highlight + "=====[ " + string.toString() + highlight + " ]=====";
|
||||
}
|
||||
|
||||
static {
|
||||
String colors = "";
|
||||
for (ChatColor color : ChatColor.values())
|
||||
colors += color.getChar();
|
||||
COLOR_MATCHER = Pattern.compile("\\<([COLORS])\\>".replace("COLORS", colors), Pattern.CASE_INSENSITIVE);
|
||||
}
|
||||
}
|
@ -1,287 +0,0 @@
|
||||
package net.citizensnpcs.util;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.text.MessageFormat;
|
||||
import java.util.ListResourceBundle;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.MissingResourceException;
|
||||
import java.util.Properties;
|
||||
import java.util.PropertyResourceBundle;
|
||||
import java.util.ResourceBundle;
|
||||
|
||||
import net.citizensnpcs.Settings.Setting;
|
||||
import net.citizensnpcs.api.CitizensAPI;
|
||||
|
||||
import com.google.common.collect.Maps;
|
||||
import com.google.common.io.Closeables;
|
||||
import com.google.common.io.Files;
|
||||
import com.google.common.io.InputSupplier;
|
||||
|
||||
public class Translator {
|
||||
private final Locale defaultLocale;
|
||||
private final Map<String, MessageFormat> messageFormatCache = Maps.newHashMap();
|
||||
private ResourceBundle preferredBundle;
|
||||
private final File resourceFile;
|
||||
|
||||
private Translator(File resourceFile, Locale locale) {
|
||||
this.resourceFile = resourceFile;
|
||||
this.defaultLocale = locale;
|
||||
try {
|
||||
preferredBundle = ResourceBundle.getBundle(PREFIX, defaultLocale,
|
||||
new FileClassLoader(Translator.class.getClassLoader(), resourceFile));
|
||||
} catch (MissingResourceException e) {
|
||||
preferredBundle = getDefaultBundle();
|
||||
Messaging.log(translate(Messages.MISSING_TRANSLATIONS, locale));
|
||||
}
|
||||
}
|
||||
|
||||
private String format(String key, Locale locale, Object... msg) {
|
||||
String unreplaced = translate(key, locale);
|
||||
MessageFormat formatter = getFormatter(unreplaced);
|
||||
return formatter.format(msg);
|
||||
}
|
||||
|
||||
private ResourceBundle getBundle(Locale locale) {
|
||||
try {
|
||||
ResourceBundle bundle = ResourceBundle.getBundle(PREFIX, locale,
|
||||
new FileClassLoader(Translator.class.getClassLoader(), resourceFile));
|
||||
return bundle == null ? preferredBundle : bundle;
|
||||
} catch (MissingResourceException e) {
|
||||
return preferredBundle;
|
||||
}
|
||||
}
|
||||
|
||||
private ResourceBundle getDefaultBundle() {
|
||||
return getDefaultResourceBundle(resourceFile, PREFIX + "_en.properties");
|
||||
}
|
||||
|
||||
private MessageFormat getFormatter(String unreplaced) {
|
||||
MessageFormat formatter = messageFormatCache.get(unreplaced);
|
||||
if (formatter == null)
|
||||
messageFormatCache.put(unreplaced, formatter = new MessageFormat(unreplaced));
|
||||
return formatter;
|
||||
}
|
||||
|
||||
private String translate(String key, Locale locale) {
|
||||
ResourceBundle bundle = preferredBundle;
|
||||
if (locale != defaultLocale)
|
||||
bundle = getBundle(locale);
|
||||
try {
|
||||
return bundle.getString(key);
|
||||
} catch (MissingResourceException e) {
|
||||
try {
|
||||
return getDefaultBundle().getString(key);
|
||||
} catch (MissingResourceException ex) {
|
||||
return "?" + key + "?";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static class FileClassLoader extends ClassLoader {
|
||||
private final File folder;
|
||||
|
||||
public FileClassLoader(ClassLoader classLoader, File folder) {
|
||||
super(classLoader);
|
||||
this.folder = folder;
|
||||
}
|
||||
|
||||
@Override
|
||||
public URL getResource(String string) {
|
||||
File file = new File(folder, string);
|
||||
if (file.exists()) {
|
||||
try {
|
||||
return file.toURI().toURL();
|
||||
} catch (MalformedURLException ex) {
|
||||
}
|
||||
} else {
|
||||
string = string.replaceFirst("/", "");
|
||||
URL test = Translator.class.getResource('/' + string);
|
||||
if (test != null)
|
||||
return test;
|
||||
}
|
||||
return super.getResource(string);
|
||||
}
|
||||
|
||||
@Override
|
||||
public InputStream getResourceAsStream(String string) {
|
||||
File file = new File(folder, string);
|
||||
if (file.exists()) {
|
||||
try {
|
||||
return new FileInputStream(file);
|
||||
} catch (FileNotFoundException ex) {
|
||||
}
|
||||
} else {
|
||||
string = string.replaceFirst("/", "");
|
||||
InputStream stream = Translator.class.getResourceAsStream('/' + string);
|
||||
if (stream != null) {
|
||||
new Thread(new SaveResourceThread(folder, string)).start();
|
||||
return stream;
|
||||
}
|
||||
}
|
||||
return super.getResourceAsStream(string);
|
||||
}
|
||||
}
|
||||
|
||||
private static class SaveResourceThread implements Runnable {
|
||||
private final String fileName;
|
||||
private final File rootFolder;
|
||||
|
||||
private SaveResourceThread(File rootFolder, String fileName) {
|
||||
this.rootFolder = rootFolder;
|
||||
this.fileName = fileName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
File file = new File(rootFolder, fileName);
|
||||
if (file.exists())
|
||||
return;
|
||||
final InputStream stream = Translator.class.getResourceAsStream('/' + fileName);
|
||||
if (stream == null)
|
||||
return;
|
||||
InputSupplier<InputStream> in = new InputSupplier<InputStream>() {
|
||||
@Override
|
||||
public InputStream getInput() throws IOException {
|
||||
return stream;
|
||||
}
|
||||
};
|
||||
try {
|
||||
rootFolder.mkdirs();
|
||||
File to = File.createTempFile(fileName, null, rootFolder);
|
||||
to.deleteOnExit();
|
||||
Files.copy(in, to);
|
||||
if (!file.exists())
|
||||
to.renameTo(file);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static ResourceBundle defaultBundle;
|
||||
|
||||
private static Translator instance;
|
||||
|
||||
public static final String PREFIX = "messages";
|
||||
|
||||
private static void createInstance() {
|
||||
Locale locale = Locale.getDefault();
|
||||
String setting = Setting.LOCALE.asString();
|
||||
if (!setting.isEmpty()) {
|
||||
String[] parts = setting.split("[\\._]");
|
||||
switch (parts.length) {
|
||||
case 1:
|
||||
locale = new Locale(parts[0]);
|
||||
break;
|
||||
case 2:
|
||||
locale = new Locale(parts[0], parts[1]);
|
||||
break;
|
||||
case 3:
|
||||
locale = new Locale(parts[0], parts[1], parts[2]);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
instance = new Translator(new File(CitizensAPI.getDataFolder(), "lang"), locale);
|
||||
Messaging.logTr(Messages.LOCALE_NOTIFICATION, locale);
|
||||
}
|
||||
|
||||
private static Properties getDefaultBundleProperties() {
|
||||
Properties defaults = new Properties();
|
||||
InputStream in = null;
|
||||
try {
|
||||
in = Messages.class.getResourceAsStream("/" + PREFIX + "_en.properties");
|
||||
defaults.load(in);
|
||||
} catch (IOException e) {
|
||||
} finally {
|
||||
Closeables.closeQuietly(in);
|
||||
}
|
||||
return defaults;
|
||||
}
|
||||
|
||||
private static ResourceBundle getDefaultResourceBundle(File resourceDirectory, String fileName) {
|
||||
if (Translator.defaultBundle != null)
|
||||
return Translator.defaultBundle;
|
||||
resourceDirectory.mkdirs();
|
||||
|
||||
File bundleFile = new File(resourceDirectory, fileName);
|
||||
if (!bundleFile.exists()) {
|
||||
try {
|
||||
bundleFile.createNewFile();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
Translator.populateDefaults(bundleFile);
|
||||
FileInputStream stream = null;
|
||||
try {
|
||||
stream = new FileInputStream(bundleFile);
|
||||
Translator.defaultBundle = new PropertyResourceBundle(stream);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
Translator.defaultBundle = Translator.getFallbackResourceBundle();
|
||||
} finally {
|
||||
Closeables.closeQuietly(stream);
|
||||
}
|
||||
return Translator.defaultBundle;
|
||||
}
|
||||
|
||||
private static ResourceBundle getFallbackResourceBundle() {
|
||||
return new ListResourceBundle() {
|
||||
@Override
|
||||
protected Object[][] getContents() {
|
||||
return new Object[0][0];
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private static void populateDefaults(File bundleFile) {
|
||||
Properties properties = new Properties();
|
||||
InputStream in = null;
|
||||
try {
|
||||
in = new FileInputStream(bundleFile);
|
||||
properties.load(in);
|
||||
} catch (IOException e) {
|
||||
} finally {
|
||||
Closeables.closeQuietly(in);
|
||||
}
|
||||
Properties defaults = getDefaultBundleProperties();
|
||||
for (Entry<Object, Object> entry : defaults.entrySet()) {
|
||||
if (!properties.containsKey(entry.getKey()))
|
||||
properties.put(entry.getKey(), entry.getValue());
|
||||
}
|
||||
OutputStream stream = null;
|
||||
try {
|
||||
stream = new FileOutputStream(bundleFile);
|
||||
properties.store(stream, "");
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
Closeables.closeQuietly(stream);
|
||||
}
|
||||
}
|
||||
|
||||
public static String translate(String key, Locale preferredLocale, Object... msg) {
|
||||
if (instance == null)
|
||||
createInstance();
|
||||
return StringHelper.parseColors(msg.length == 0 ? instance.translate(key, preferredLocale) : instance.format(
|
||||
key, preferredLocale, msg));
|
||||
}
|
||||
|
||||
public static String translate(String key, Object... msg) {
|
||||
if (instance == null)
|
||||
createInstance();
|
||||
return translate(key, instance.defaultLocale, msg);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user