瀏覽代碼

UUID updater changes + locale fixes

Co-authored-by: t00thpick1 <t00thpick1dirko@gmail.com>
nossr50 5 年之前
父節點
當前提交
428c093ae4

+ 3 - 0
Changelog.txt

@@ -1,5 +1,8 @@
 Version 2.1.134
 Version 2.1.134
     Fixed a NPE that could happen with thrown potions
     Fixed a NPE that could happen with thrown potions
+    Fixed a locale mistake in locale hu_HU
+    Fixed a locale mistake in locale ru
+    Changed the UUID updater task to not catastrophically fail when requests failed
 
 
 Version 2.1.133
 Version 2.1.133
     A fix for an 'array out of bounds' error related to players clicking outside the inventory windows has been fixed
     A fix for an 'array out of bounds' error related to players clicking outside the inventory windows has been fixed

+ 0 - 18
src/main/java/com/gmail/nossr50/config/HiddenConfig.java

@@ -12,9 +12,6 @@ public class HiddenConfig {
     private boolean chunkletsEnabled;
     private boolean chunkletsEnabled;
     private int conversionRate;
     private int conversionRate;
     private boolean useEnchantmentBuffs;
     private boolean useEnchantmentBuffs;
-    private int uuidConvertAmount;
-    private int mojangRateLimit;
-    private long mojangLimitPeriod;
 
 
     public HiddenConfig(String fileName) {
     public HiddenConfig(String fileName) {
         this.fileName = fileName;
         this.fileName = fileName;
@@ -36,9 +33,6 @@ public class HiddenConfig {
             chunkletsEnabled = config.getBoolean("Options.Chunklets", true);
             chunkletsEnabled = config.getBoolean("Options.Chunklets", true);
             conversionRate = config.getInt("Options.ConversionRate", 1);
             conversionRate = config.getInt("Options.ConversionRate", 1);
             useEnchantmentBuffs = config.getBoolean("Options.EnchantmentBuffs", true);
             useEnchantmentBuffs = config.getBoolean("Options.EnchantmentBuffs", true);
-            uuidConvertAmount = config.getInt("Options.UUIDConvertAmount", 5);
-            mojangRateLimit = config.getInt("Options.MojangRateLimit", 50000);
-            mojangLimitPeriod = config.getLong("Options.MojangLimitPeriod", 600000);
         }
         }
     }
     }
 
 
@@ -53,16 +47,4 @@ public class HiddenConfig {
     public boolean useEnchantmentBuffs() {
     public boolean useEnchantmentBuffs() {
         return useEnchantmentBuffs;
         return useEnchantmentBuffs;
     }
     }
-
-    public int getUUIDConvertAmount() {
-        return uuidConvertAmount;
-    }
-
-    public int getMojangRateLimit() {
-        return mojangRateLimit;
-    }
-
-    public long getMojangLimitPeriod() {
-        return mojangLimitPeriod;
-    }
 }
 }

+ 1 - 1
src/main/java/com/gmail/nossr50/database/FlatfileDatabaseManager.java

@@ -34,7 +34,7 @@ public final class FlatfileDatabaseManager implements DatabaseManager {
         updateLeaderboards();
         updateLeaderboards();
 
 
         if (mcMMO.getUpgradeManager().shouldUpgrade(UpgradeType.ADD_UUIDS)) {
         if (mcMMO.getUpgradeManager().shouldUpgrade(UpgradeType.ADD_UUIDS)) {
-            new UUIDUpdateAsyncTask(mcMMO.p, getStoredUsers()).runTaskAsynchronously(mcMMO.p);
+            new UUIDUpdateAsyncTask(mcMMO.p, getStoredUsers()).start();
         }
         }
     }
     }
 
 

+ 3 - 1
src/main/java/com/gmail/nossr50/database/SQLDatabaseManager.java

@@ -1338,7 +1338,9 @@ public final class SQLDatabaseManager implements DatabaseManager {
                 }
                 }
 
 
                 if (!names.isEmpty()) {
                 if (!names.isEmpty()) {
-                    new UUIDUpdateAsyncTask(mcMMO.p, names).run();
+                    UUIDUpdateAsyncTask updateTask = new UUIDUpdateAsyncTask(mcMMO.p, names);
+                    updateTask.start();
+                    updateTask.waitUntilFinished();
                 }
                 }
             } finally {
             } finally {
                 massUpdateLock.unlock();
                 massUpdateLock.unlock();

+ 95 - 70
src/main/java/com/gmail/nossr50/runnables/database/UUIDUpdateAsyncTask.java

@@ -1,105 +1,130 @@
 package com.gmail.nossr50.runnables.database;
 package com.gmail.nossr50.runnables.database;
 
 
-import com.gmail.nossr50.config.HiddenConfig;
-import com.gmail.nossr50.database.DatabaseManager;
 import com.gmail.nossr50.datatypes.database.UpgradeType;
 import com.gmail.nossr50.datatypes.database.UpgradeType;
 import com.gmail.nossr50.mcMMO;
 import com.gmail.nossr50.mcMMO;
 import com.gmail.nossr50.util.Misc;
 import com.gmail.nossr50.util.Misc;
-import com.gmail.nossr50.util.uuid.UUIDFetcher;
-import org.bukkit.scheduler.BukkitRunnable;
+import com.google.common.collect.ImmutableList;
+import com.google.gson.Gson;
+import com.google.gson.JsonObject;
 
 
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.net.HttpURLConnection;
+import java.net.URL;
 import java.util.HashMap;
 import java.util.HashMap;
 import java.util.List;
 import java.util.List;
 import java.util.Map;
 import java.util.Map;
 import java.util.UUID;
 import java.util.UUID;
 import java.util.logging.Level;
 import java.util.logging.Level;
 
 
-public class UUIDUpdateAsyncTask extends BukkitRunnable {
-    private mcMMO plugin;
-    private static final int MAX_LOOKUP = Math.max(HiddenConfig.getInstance().getUUIDConvertAmount(), 100);
-    private static final int RATE_LIMIT = HiddenConfig.getInstance().getMojangRateLimit();
-    private static final long LIMIT_PERIOD = HiddenConfig.getInstance().getMojangLimitPeriod();
-    private static final int BATCH_SIZE = MAX_LOOKUP * 3;
+public class UUIDUpdateAsyncTask implements Runnable {
+    private static final Gson GSON = new Gson();
+    private static final String PROFILE_URL = "https://api.mojang.com/profiles/minecraft";
 
 
-    private List<String> userNames;
-    private int size;
-    private int checkedUsers;
-    private long startMillis;
+    private static final int HARD_LIMIT_PERIOD = 600; // Mojang rate limit period is 600 seconds, wait that long if they reject us
+    private static final int RETRY_PERIOD = 60; // Wait 60 seconds on connection failure
+    private static final int DELAY_PERIOD = 100; // Wait 100 seconds between each batch
+
+    private static final int BATCH_SIZE = 100; // 100 at a time
+
+    private final Object awaiter = new Object();
+    private final mcMMO plugin;
+    private final ImmutableList<String> userNames;
+    private int position = 0;
 
 
     public UUIDUpdateAsyncTask(mcMMO plugin, List<String> userNames) {
     public UUIDUpdateAsyncTask(mcMMO plugin, List<String> userNames) {
         this.plugin = plugin;
         this.plugin = plugin;
-        this.userNames = userNames;
-
-        this.checkedUsers = 0;
-        this.startMillis = System.currentTimeMillis();
+        this.userNames = ImmutableList.copyOf(userNames);
     }
     }
 
 
     @Override
     @Override
     public void run() {
     public void run() {
-        size = userNames.size();
+        // First iteration
+        if (position == 0)
+            plugin.getLogger().info("Starting to check and update UUIDs, total amount of users: " + userNames.size());
 
 
-        plugin.getLogger().info("Starting to check and update UUIDs, total amount of users: " + size);
+        List<String> batch = userNames.subList(position, Math.min(userNames.size(), position + BATCH_SIZE));
 
 
-        List<String> userNamesSection;
-        Map<String, UUID> fetchedUUIDs = new HashMap<String, UUID>();
+        Map<String, UUID> fetchedUUIDs = new HashMap<>();
+        HttpURLConnection connection;
+        try {
+            connection = (HttpURLConnection) new URL(PROFILE_URL).openConnection();
+            connection.setRequestMethod("POST");
+            connection.setRequestProperty("Content-Type", "application/json");
+            connection.setUseCaches(false);
+            connection.setDoInput(true);
+            connection.setDoOutput(true);
 
 
-        while (size != 0) {
-            if (checkedUsers + 100 > RATE_LIMIT) {
-                try {
-                    Thread.sleep(LIMIT_PERIOD);
-                } catch (InterruptedException e) {
-                    e.printStackTrace();
-                    return;
-                }
-                startMillis = System.currentTimeMillis();
-                checkedUsers = 0;
-            }
-            if (size > MAX_LOOKUP) {
-                userNamesSection = userNames.subList(size - MAX_LOOKUP, size);
-                size -= MAX_LOOKUP;
+            String body = GSON.toJson(batch.toArray(new String[0]));
+
+            try (OutputStream output = connection.getOutputStream()) {
+                output.write(body.getBytes());
+                output.flush();
             }
             }
-            else {
-                userNamesSection = userNames.subList(0, size);
-                size = 0;
+            switch (connection.getResponseCode()) {
+                case HttpURLConnection.HTTP_OK:
+                    break; // All is good
+                case HttpURLConnection.HTTP_BAD_REQUEST:
+                case HttpURLConnection.HTTP_FORBIDDEN:
+                    // Rejected, probably rate limit, just wait it out
+                    this.runTaskLaterAsynchronously(plugin, Misc.TICK_CONVERSION_FACTOR * HARD_LIMIT_PERIOD);
+                    return;
+                default:
+                    // Unknown failure
+                    this.runTaskLaterAsynchronously(plugin, Misc.TICK_CONVERSION_FACTOR * RETRY_PERIOD);
+                    return;
             }
             }
 
 
-            try {
-                fetchedUUIDs.putAll(new UUIDFetcher(userNamesSection).call());
-            }
-            catch (Exception e) {
-                // Handle 429
-                if(e.getMessage() != null)
-                {
-                    if (e.getMessage().contains("429")) {
-                        size += userNamesSection.size();
-                        try {
-                            Thread.sleep(LIMIT_PERIOD);
-                        } catch (InterruptedException ex) {
-                            e.printStackTrace();
-                            return;
-                        }
-                        continue;
-                    }
+            try (InputStream input = connection.getInputStream();
+                 InputStreamReader reader = new InputStreamReader(input)) {
+                for (JsonObject jsonProfile : GSON.fromJson(reader, JsonObject[].class)) {
+                    UUID id = toUUID(jsonProfile.get("id").getAsString());
+                    String name = jsonProfile.get("name").getAsString();
+                    fetchedUUIDs.put(name, id);
                 }
                 }
-
-                plugin.getLogger().log(Level.SEVERE, "Unable to fetch UUIDs!", e);
-                return;
             }
             }
+        } catch (IOException e) {
+            // failure
+            plugin.getLogger().log(Level.SEVERE, "Unable to contact mojang API!", e);
+            this.runTaskLaterAsynchronously(plugin, Misc.TICK_CONVERSION_FACTOR * RETRY_PERIOD);
+            return;
+        }
 
 
-            checkedUsers += userNamesSection.size();
-            userNamesSection.clear();
-            size = userNames.size();
+        if (fetchedUUIDs.size() != 0)
+            mcMMO.getDatabaseManager().saveUserUUIDs(fetchedUUIDs);
 
 
-            Misc.printProgress(checkedUsers, DatabaseManager.progressInterval, startMillis);
-            if (fetchedUUIDs.size() >= BATCH_SIZE) {
-                mcMMO.getDatabaseManager().saveUserUUIDs(fetchedUUIDs);
-                fetchedUUIDs = new HashMap<String, UUID>();
-            }
-        }
+        position += batch.size();
+        plugin.getLogger().info(String.format("Conversion progress: %d/%d users", position, userNames.size()));
 
 
-        if (fetchedUUIDs.size() == 0 || mcMMO.getDatabaseManager().saveUserUUIDs(fetchedUUIDs)) {
+        if (position == userNames.size())
+        {
             mcMMO.getUpgradeManager().setUpgradeCompleted(UpgradeType.ADD_UUIDS);
             mcMMO.getUpgradeManager().setUpgradeCompleted(UpgradeType.ADD_UUIDS);
-            plugin.getLogger().info("UUID upgrade completed!");
+            awaiter.notify();
+        }
+        else
+            this.runTaskLaterAsynchronously(plugin, Misc.TICK_CONVERSION_FACTOR * DELAY_PERIOD); // Schedule next batch
+    }
+
+    // Bukkit runnables don't let themselves reschedule themselves, so we are a pseudo bukkit runnable.
+    private void runTaskLaterAsynchronously(mcMMO plugin, int delay) {
+        plugin.getServer().getScheduler().runTaskLaterAsynchronously(plugin, this, delay);
+    }
+
+    public void start() {
+        plugin.getServer().getScheduler().runTaskAsynchronously(plugin, this);
+    }
+
+    private static UUID toUUID(String id) {
+        return UUID.fromString(id.substring(0, 8) + "-" + id.substring(8, 12) + "-" + id.substring(12, 16) + "-" + id.substring(16, 20) + "-" + id.substring(20, 32));
+    }
+
+    public void waitUntilFinished() {
+        try {
+            awaiter.wait();
+        } catch (InterruptedException e) {
+            // I guess we don't care in this event
         }
         }
     }
     }
 }
 }

+ 1 - 9
src/main/resources/hidden.yml

@@ -8,12 +8,4 @@ Options:
     # Square root of the number of chunks to convert per tick.
     # Square root of the number of chunks to convert per tick.
     ConversionRate: 1
     ConversionRate: 1
     # true to use enchantment buffs for Super Breaker & Giga Drill Breaker, false to use potion buffs
     # true to use enchantment buffs for Super Breaker & Giga Drill Breaker, false to use potion buffs
-    EnchantmentBuffs: true
-
-    # Amount of users to convert every interval
-    UUIDConvertAmount: 100
-    # Amount of users to be converted at a time before waiting MojangLimitPeriod milliseconds to begin again
-    # This setting is for large servers to avoid being temp banned from mojang api
-    MojangRateLimit: 300
-    # Amount of time to wait after hitting the MojangRateLimit in UUID conversion
-    MojangLimitPeriod: 6000
+    EnchantmentBuffs: true

+ 0 - 1
src/main/resources/locale/locale_hu_HU.properties

@@ -979,7 +979,6 @@ Skills.Child=[[GOLD]](ALK\u00C9PESS\u00C9G)
 Skills.Disarmed=[[DARK_RED]]Lefegyvereztek!
 Skills.Disarmed=[[DARK_RED]]Lefegyvereztek!
 Skills.Header=-----[] [[GREEN]]{0}[[RED]] []-----
 Skills.Header=-----[] [[GREEN]]{0}[[RED]] []-----
 Skills.NeedMore=[[DARK_RED]]T\u00F6bb[[GRAY]]{0}-ra/re van sz\u00FCks\u00E9ged
 Skills.NeedMore=[[DARK_RED]]T\u00F6bb[[GRAY]]{0}-ra/re van sz\u00FCks\u00E9ged
-Skills.NeedMore=[[DARK_RED]]T\u00F6bb[[GRAY]]{0}{1}-ra/re van sz\u00FCks\u00E9ged
 Skills.Parents= ANYAK\u00C9PESS\u00C9G
 Skills.Parents= ANYAK\u00C9PESS\u00C9G
 Skills.Stats={0}[[GREEN]]{1}[[DARK_AQUA]] XP([[GRAY]]{2}[[DARK_AQUA]]/[[GRAY]]{3}[[DARK_AQUA]])
 Skills.Stats={0}[[GREEN]]{1}[[DARK_AQUA]] XP([[GRAY]]{2}[[DARK_AQUA]]/[[GRAY]]{3}[[DARK_AQUA]])
 Skills.ChildStats={0}[[GREEN]]{1}
 Skills.ChildStats={0}[[GREEN]]{1}

+ 13 - 13
src/main/resources/locale/locale_ja_JP.properties

@@ -829,9 +829,9 @@ Commands.xplock.locked=[[GOLD]]\u3042\u306a\u305f\u306eXP\u30d0\u30fc\u306f\u73f
 Commands.xplock.unlocked=[[GOLD]]\u3042\u306a\u305f\u306eXP\u30d0\u30fc\u306f\u73fe\u5728[[GREEN]]\u30ed\u30c3\u30af\u89e3\u9664[[GOLD]]\u3055\u308c\u3066\u3044\u307e\u3059\uff01
 Commands.xplock.unlocked=[[GOLD]]\u3042\u306a\u305f\u306eXP\u30d0\u30fc\u306f\u73fe\u5728[[GREEN]]\u30ed\u30c3\u30af\u89e3\u9664[[GOLD]]\u3055\u308c\u3066\u3044\u307e\u3059\uff01
 Commands.xprate.modified=[[RED]]XP\u30ec\u30fc\u30c8\u306f{0}\u306b\u5909\u66f4\u3055\u308c\u307e\u3057\u305f
 Commands.xprate.modified=[[RED]]XP\u30ec\u30fc\u30c8\u306f{0}\u306b\u5909\u66f4\u3055\u308c\u307e\u3057\u305f
 Commands.xprate.over=[[RED]]mcMMO XP\u30ec\u30fc\u30c8\u30a4\u30d9\u30f3\u30c8\u304c\u7d42\u308f\u308a\u307e\u3057\u305f\uff01
 Commands.xprate.over=[[RED]]mcMMO XP\u30ec\u30fc\u30c8\u30a4\u30d9\u30f3\u30c8\u304c\u7d42\u308f\u308a\u307e\u3057\u305f\uff01
-Commands.xprate.proper.0=[[RED]]XP\u30ec\u30fc\u30c8\u3092\u5909\u66f4\u3059\u308b\u305f\u3081\u306e\u6b63\u3057\u3044\u65b9\u6cd5\u306f\/xprate <integer> <true\/false> \u3067\u3059\u3002
-Commands.xprate.proper.1=[[RED]]XP\u30ec\u30fc\u30c8\u3092\u30c7\u30d5\u30a9\u30eb\u30c8\u306b\u623b\u3059\u6b63\u3057\u3044\u65b9\u6cd5\u306f\/xprate reset \u3067\u3059\u3002
-Commands.xprate.proper.2=[[RED]]XP\u30ec\u30fc\u30c8\u3092\u30c7\u30d5\u30a9\u30eb\u30c8\u306b\u623b\u3059\u6b63\u3057\u3044\u65b9\u6cd5\u306f\/xprate reset \u3067\u3059\u3002
+Commands.xprate.proper.0=[[RED]]XP\u30ec\u30fc\u30c8\u3092\u5909\u66f4\u3059\u308b\u305f\u3081\u306e\u6b63\u3057\u3044\u65b9\u6cd5\u306f/xprate <integer> <true/false> \u3067\u3059\u3002
+Commands.xprate.proper.1=[[RED]]XP\u30ec\u30fc\u30c8\u3092\u30c7\u30d5\u30a9\u30eb\u30c8\u306b\u623b\u3059\u6b63\u3057\u3044\u65b9\u6cd5\u306f/xprate reset \u3067\u3059\u3002
+Commands.xprate.proper.2=[[RED]]XP\u30ec\u30fc\u30c8\u3092\u30c7\u30d5\u30a9\u30eb\u30c8\u306b\u623b\u3059\u6b63\u3057\u3044\u65b9\u6cd5\u306f/xprate reset \u3067\u3059\u3002
 Commands.NegativeNumberWarn=\u8ca0\u306e\u5024\u3092\u4f7f\u308f\u306a\u3044\u3067\u304f\u3060\u3055\u3044\u3002
 Commands.NegativeNumberWarn=\u8ca0\u306e\u5024\u3092\u4f7f\u308f\u306a\u3044\u3067\u304f\u3060\u3055\u3044\u3002
 Commands.Event.Start=[[GREEN]]mcMMO[[GOLD]] \u30a4\u30d9\u30f3\u30c8\uff01
 Commands.Event.Start=[[GREEN]]mcMMO[[GOLD]] \u30a4\u30d9\u30f3\u30c8\uff01
 Commands.Event.Stop=[[GREEN]]mcMMO[[DARK_AQUA]] \u30a4\u30d9\u30f3\u30c8\u7d42\u4e86\uff01
 Commands.Event.Stop=[[GREEN]]mcMMO[[DARK_AQUA]] \u30a4\u30d9\u30f3\u30c8\u7d42\u4e86\uff01
@@ -1056,17 +1056,17 @@ Smelting.SkillName=\u7cbe\u932c
 
 
 # COMMAND DESCRIPTIONS
 # COMMAND DESCRIPTIONS
 Commands.Description.addlevels=\u30e6\u30fc\u30b6\u30fc\u306bmcMMO\u30ec\u30d9\u30eb\u3092\u8ffd\u52a0\u3059\u308b
 Commands.Description.addlevels=\u30e6\u30fc\u30b6\u30fc\u306bmcMMO\u30ec\u30d9\u30eb\u3092\u8ffd\u52a0\u3059\u308b
-Commands.Description.adminchat=mcMMO\u7ba1\u7406\u8005\u30c1\u30e3\u30c3\u30c8\u306e\u30aa\u30f3\/\u30aa\u30d5\u306e\u5207\u308a\u66ff\u3048\u3001\u307e\u305f\u306f\u7ba1\u7406\u8005\u30c1\u30e3\u30c3\u30c8\u30e1\u30c3\u30bb\u30fc\u30b8\u306e\u9001\u4fe1
+Commands.Description.adminchat=mcMMO\u7ba1\u7406\u8005\u30c1\u30e3\u30c3\u30c8\u306e\u30aa\u30f3/\u30aa\u30d5\u306e\u5207\u308a\u66ff\u3048\u3001\u307e\u305f\u306f\u7ba1\u7406\u8005\u30c1\u30e3\u30c3\u30c8\u30e1\u30c3\u30bb\u30fc\u30b8\u306e\u9001\u4fe1
 Commands.Description.addxp=\u30e6\u30fc\u30b6\u30fc\u306bmcMMO XP\u3092\u8ffd\u52a0\u3059\u308b
 Commands.Description.addxp=\u30e6\u30fc\u30b6\u30fc\u306bmcMMO XP\u3092\u8ffd\u52a0\u3059\u308b
-Commands.Description.hardcore=mcMMO\u30cf\u30fc\u30c9\u30b3\u30a2\u306e\u30d1\u30fc\u30bb\u30f3\u30c6\u30fc\u30b8\u3092\u5909\u66f4\u3059\u308b\u304b\u3001\u30cf\u30fc\u30c9\u30b3\u30a2\u30e2\u30fc\u30c9\u306e\u30aa\u30f3\/\u30aa\u30d5\u3092\u5207\u308a\u66ff\u3048\u307e\u3059
+Commands.Description.hardcore=mcMMO\u30cf\u30fc\u30c9\u30b3\u30a2\u306e\u30d1\u30fc\u30bb\u30f3\u30c6\u30fc\u30b8\u3092\u5909\u66f4\u3059\u308b\u304b\u3001\u30cf\u30fc\u30c9\u30b3\u30a2\u30e2\u30fc\u30c9\u306e\u30aa\u30f3/\u30aa\u30d5\u3092\u5207\u308a\u66ff\u3048\u307e\u3059
 Commands.Description.inspect=\u4ed6\u306e\u30d7\u30ec\u30a4\u30e4\u30fc\u306e\u8a73\u7d30\u306amcMMO\u60c5\u5831\u3092\u898b\u308b
 Commands.Description.inspect=\u4ed6\u306e\u30d7\u30ec\u30a4\u30e4\u30fc\u306e\u8a73\u7d30\u306amcMMO\u60c5\u5831\u3092\u898b\u308b
-Commands.Description.mcability=\u53f3\u30af\u30ea\u30c3\u30af\u3067mcMMO\u30a2\u30d3\u30ea\u30c6\u30a3\u306e\u6709\u52b9\u306b\u3064\u3044\u3066\u30aa\u30f3\/\u30aa\u30d5\u3092\u5207\u308a\u66ff\u3048\u307e\u3059
+Commands.Description.mcability=\u53f3\u30af\u30ea\u30c3\u30af\u3067mcMMO\u30a2\u30d3\u30ea\u30c6\u30a3\u306e\u6709\u52b9\u306b\u3064\u3044\u3066\u30aa\u30f3/\u30aa\u30d5\u3092\u5207\u308a\u66ff\u3048\u307e\u3059
 Commands.Description.mccooldown=mcMMO\u30a2\u30d3\u30ea\u30c6\u30a3\u306e\u30af\u30fc\u30eb\u30c0\u30a6\u30f3\u3092\u3059\u3079\u3066\u898b\u308b
 Commands.Description.mccooldown=mcMMO\u30a2\u30d3\u30ea\u30c6\u30a3\u306e\u30af\u30fc\u30eb\u30c0\u30a6\u30f3\u3092\u3059\u3079\u3066\u898b\u308b
-Commands.Description.mcchatspy=mcMMO\u30d1\u30fc\u30c6\u30a3\u30fc\u30c1\u30e3\u30c3\u30c8\u306e\u30b9\u30d1\u30a4\u306b\u3064\u3044\u3066\u30aa\u30f3\/\u30aa\u30d5\u3092\u5207\u308a\u66ff\u3048\u307e\u3059
-Commands.Description.mcgod=mcMMO\u306e\u30b4\u30c3\u30c9\u30e2\u30fc\u30c9\u306e\u30aa\u30f3\/\u30aa\u30d5\u3092\u5207\u308a\u66ff\u3048\u307e\u3059
+Commands.Description.mcchatspy=mcMMO\u30d1\u30fc\u30c6\u30a3\u30fc\u30c1\u30e3\u30c3\u30c8\u306e\u30b9\u30d1\u30a4\u306b\u3064\u3044\u3066\u30aa\u30f3/\u30aa\u30d5\u3092\u5207\u308a\u66ff\u3048\u307e\u3059
+Commands.Description.mcgod=mcMMO\u306e\u30b4\u30c3\u30c9\u30e2\u30fc\u30c9\u306e\u30aa\u30f3/\u30aa\u30d5\u3092\u5207\u308a\u66ff\u3048\u307e\u3059
 Commands.Description.mchud=mcMMO HUD\u30b9\u30bf\u30a4\u30eb\u3092\u5909\u66f4\u3059\u308b
 Commands.Description.mchud=mcMMO HUD\u30b9\u30bf\u30a4\u30eb\u3092\u5909\u66f4\u3059\u308b
 Commands.Description.mcmmo=mcMMO\u306e\u7c21\u5358\u306a\u8aac\u660e\u3092\u8868\u793a\u3059\u308b
 Commands.Description.mcmmo=mcMMO\u306e\u7c21\u5358\u306a\u8aac\u660e\u3092\u8868\u793a\u3059\u308b
-Commands.Description.mcnotify=mcMMO\u30a2\u30d3\u30ea\u30c6\u30a3\u306e\u30c1\u30e3\u30c3\u30c8\u8868\u793a\u901a\u77e5\u306b\u3064\u3044\u3066\u30aa\u30f3\/\u30aa\u30d5\u3092\u5207\u308a\u66ff\u3048\u307e\u3059
+Commands.Description.mcnotify=mcMMO\u30a2\u30d3\u30ea\u30c6\u30a3\u306e\u30c1\u30e3\u30c3\u30c8\u8868\u793a\u901a\u77e5\u306b\u3064\u3044\u3066\u30aa\u30f3/\u30aa\u30d5\u3092\u5207\u308a\u66ff\u3048\u307e\u3059
 Commands.Description.mcpurge=mcMMO\u30ec\u30d9\u30eb\u306e\u306a\u3044\u30e6\u30fc\u30b6\u30fc\u304a\u3088\u3073{0}\u30f6\u6708\u4ee5\u4e0a\u63a5\u7d9a\u3057\u3066\u3044\u306a\u3044\u30e6\u30fc\u30b6\u30fc\u3092mcMMO\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u304b\u3089\u524a\u9664\u3057\u307e\u3059\u3002
 Commands.Description.mcpurge=mcMMO\u30ec\u30d9\u30eb\u306e\u306a\u3044\u30e6\u30fc\u30b6\u30fc\u304a\u3088\u3073{0}\u30f6\u6708\u4ee5\u4e0a\u63a5\u7d9a\u3057\u3066\u3044\u306a\u3044\u30e6\u30fc\u30b6\u30fc\u3092mcMMO\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u304b\u3089\u524a\u9664\u3057\u307e\u3059\u3002
 Commands.Description.mcrank=\u30d7\u30ec\u30a4\u30e4\u30fc\u306emcMMO\u30e9\u30f3\u30ad\u30f3\u30b0\u3092\u8868\u793a\u3059\u308b
 Commands.Description.mcrank=\u30d7\u30ec\u30a4\u30e4\u30fc\u306emcMMO\u30e9\u30f3\u30ad\u30f3\u30b0\u3092\u8868\u793a\u3059\u308b
 Commands.Description.mcrefresh=mcMMO\u306e\u3059\u3079\u3066\u306e\u30af\u30fc\u30eb\u30c0\u30a6\u30f3\u3092\u66f4\u65b0\u3059\u308b
 Commands.Description.mcrefresh=mcMMO\u306e\u3059\u3079\u3066\u306e\u30af\u30fc\u30eb\u30c0\u30a6\u30f3\u3092\u66f4\u65b0\u3059\u308b
@@ -1078,13 +1078,13 @@ Commands.Description.mmoedit=\u30e6\u30fc\u30b6\u30fc\u306emcMMO\u30ec\u30d9\u30
 Commands.Description.mmodebug=\u30d6\u30ed\u30c3\u30af\u3092\u53e9\u3044\u305f\u3068\u304d\u306b\u6709\u7528\u306a\u60c5\u5831\u3092\u51fa\u529b\u3059\u308b\u30c7\u30d0\u30c3\u30b0\u30e2\u30fc\u30c9\u3092\u5207\u308a\u66ff\u3048\u307e\u3059\u3002
 Commands.Description.mmodebug=\u30d6\u30ed\u30c3\u30af\u3092\u53e9\u3044\u305f\u3068\u304d\u306b\u6709\u7528\u306a\u60c5\u5831\u3092\u51fa\u529b\u3059\u308b\u30c7\u30d0\u30c3\u30b0\u30e2\u30fc\u30c9\u3092\u5207\u308a\u66ff\u3048\u307e\u3059\u3002
 Commands.Description.mmoupdate=mcMMO\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u3092\u53e4\u3044\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u304b\u3089\u73fe\u5728\u306e\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u306b\u79fb\u884c\u3057\u307e\u3059\u3002
 Commands.Description.mmoupdate=mcMMO\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u3092\u53e4\u3044\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u304b\u3089\u73fe\u5728\u306e\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u306b\u79fb\u884c\u3057\u307e\u3059\u3002
 Commands.Description.mcconvert=\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u306e\u7a2e\u985e\u307e\u305f\u306f\u7d4c\u9a13\u5024\u5f0f\u306e\u7a2e\u985e\u3092\u5909\u63db\u3059\u308b
 Commands.Description.mcconvert=\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u306e\u7a2e\u985e\u307e\u305f\u306f\u7d4c\u9a13\u5024\u5f0f\u306e\u7a2e\u985e\u3092\u5909\u63db\u3059\u308b
-Commands.Description.mmoshowdb=\u73fe\u5728\u306e\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u30bf\u30a4\u30d7\u306e\u540d\u524d\u3092\u8868\u793a\u3057\u307e\u3059\uff08\u5f8c\u3067\/mmoupdate\u3067\u4f7f\u7528\u3059\u308b\u305f\u3081\uff09
+Commands.Description.mmoshowdb=\u73fe\u5728\u306e\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u30bf\u30a4\u30d7\u306e\u540d\u524d\u3092\u8868\u793a\u3057\u307e\u3059\uff08\u5f8c\u3067/mmoupdate\u3067\u4f7f\u7528\u3059\u308b\u305f\u3081\uff09
 Commands.Description.party=\u3055\u307e\u3056\u307e\u306amcMMO\u30d1\u30fc\u30c6\u30a3\u306e\u8a2d\u5b9a\u3092\u7ba1\u7406\u3059\u308b
 Commands.Description.party=\u3055\u307e\u3056\u307e\u306amcMMO\u30d1\u30fc\u30c6\u30a3\u306e\u8a2d\u5b9a\u3092\u7ba1\u7406\u3059\u308b
-Commands.Description.partychat=mcMMO\u30d1\u30fc\u30c6\u30a3\u30c1\u30e3\u30c3\u30c8\u306e\u30aa\u30f3\/\u30aa\u30d5\u3092\u5207\u308a\u66ff\u3048\u305f\u308a\u3001\u30d1\u30fc\u30c6\u30a3\u30c1\u30e3\u30c3\u30c8\u30e1\u30c3\u30bb\u30fc\u30b8\u3092\u9001\u4fe1\u3057\u305f\u308a\u3057\u307e\u3059
+Commands.Description.partychat=mcMMO\u30d1\u30fc\u30c6\u30a3\u30c1\u30e3\u30c3\u30c8\u306e\u30aa\u30f3/\u30aa\u30d5\u3092\u5207\u308a\u66ff\u3048\u305f\u308a\u3001\u30d1\u30fc\u30c6\u30a3\u30c1\u30e3\u30c3\u30c8\u30e1\u30c3\u30bb\u30fc\u30b8\u3092\u9001\u4fe1\u3057\u305f\u308a\u3057\u307e\u3059
 Commands.Description.ptp=mcMMO\u30d1\u30fc\u30c6\u30a3\u30fc\u30e1\u30f3\u30d0\u30fc\u306b\u30c6\u30ec\u30dd\u30fc\u30c8\u3059\u308b
 Commands.Description.ptp=mcMMO\u30d1\u30fc\u30c6\u30a3\u30fc\u30e1\u30f3\u30d0\u30fc\u306b\u30c6\u30ec\u30dd\u30fc\u30c8\u3059\u308b
 Commands.Description.Skill={0}\u306e\u8a73\u7d30\u306amcMMO\u30b9\u30ad\u30eb\u60c5\u5831\u3092\u8868\u793a\u3057\u307e\u3059
 Commands.Description.Skill={0}\u306e\u8a73\u7d30\u306amcMMO\u30b9\u30ad\u30eb\u60c5\u5831\u3092\u8868\u793a\u3057\u307e\u3059
 Commands.Description.skillreset=\u30e6\u30fc\u30b6\u30fc\u306emcMMO\u30ec\u30d9\u30eb\u3092\u30ea\u30bb\u30c3\u30c8\u3059\u308b
 Commands.Description.skillreset=\u30e6\u30fc\u30b6\u30fc\u306emcMMO\u30ec\u30d9\u30eb\u3092\u30ea\u30bb\u30c3\u30c8\u3059\u308b
-Commands.Description.vampirism=mcMMO\u306e\u30f4\u30a1\u30f3\u30d1\u30a4\u30a2\u306e\u5272\u5408\u3092\u5909\u66f4\u3059\u308b\u304b\u3001\u307e\u305f\u306f\u30f4\u30a1\u30f3\u30d1\u30a4\u30a2\u30e2\u30fc\u30c9\u306e\u30aa\u30f3\/\u30aa\u30d5\u306b\u5207\u308a\u66ff\u3048\u307e\u3059
+Commands.Description.vampirism=mcMMO\u306e\u30f4\u30a1\u30f3\u30d1\u30a4\u30a2\u306e\u5272\u5408\u3092\u5909\u66f4\u3059\u308b\u304b\u3001\u307e\u305f\u306f\u30f4\u30a1\u30f3\u30d1\u30a4\u30a2\u30e2\u30fc\u30c9\u306e\u30aa\u30f3/\u30aa\u30d5\u306b\u5207\u308a\u66ff\u3048\u307e\u3059
 Commands.Description.xplock=mcMMO XP\u30d0\u30fc\u3092\u7279\u5b9a\u306emcMMO\u30b9\u30ad\u30eb\u306b\u56fa\u5b9a\u3059\u308b
 Commands.Description.xplock=mcMMO XP\u30d0\u30fc\u3092\u7279\u5b9a\u306emcMMO\u30b9\u30ad\u30eb\u306b\u56fa\u5b9a\u3059\u308b
 Commands.Description.xprate=mcMMO XP\u306e\u30ec\u30fc\u30c8\u3092\u5909\u66f4\u3059\u308b\u304b\u3001mcMMO XP\u306e\u30a4\u30d9\u30f3\u30c8\u3092\u958b\u59cb\u3059\u308b
 Commands.Description.xprate=mcMMO XP\u306e\u30ec\u30fc\u30c8\u3092\u5909\u66f4\u3059\u308b\u304b\u3001mcMMO XP\u306e\u30a4\u30d9\u30f3\u30c8\u3092\u958b\u59cb\u3059\u308b
 
 
@@ -1117,7 +1117,7 @@ Holiday.AprilFools.Levelup=[[GOLD]]{0}\u306f\u30ec\u30d9\u30eb[[GREEN]]{1}[[GOLD
 Holiday.Anniversary=[[BLUE]]{0}\u5468\u5e74\u8a18\u5ff5\uff01\n[[BLUE]]nossr50\u306e\u5168\u3066\u306e\u4ed5\u4e8b\u3068\u5168\u3066\u306e\u958b\u767a\u3092\u8a18\u5ff5\u3057\u3066\uff01
 Holiday.Anniversary=[[BLUE]]{0}\u5468\u5e74\u8a18\u5ff5\uff01\n[[BLUE]]nossr50\u306e\u5168\u3066\u306e\u4ed5\u4e8b\u3068\u5168\u3066\u306e\u958b\u767a\u3092\u8a18\u5ff5\u3057\u3066\uff01
 
 
 # Reminder Messages
 # Reminder Messages
-Reminder.Squelched=[[GRAY]]\u30ea\u30de\u30a4\u30f3\u30c0\u30fc: \u3042\u306a\u305f\u306f\u73fe\u5728mcMMO\u304b\u3089\u901a\u77e5\u3092\u53d7\u3051\u53d6\u3063\u3066\u3044\u307e\u305b\u3093\u3002\u901a\u77e5\u3092\u6709\u52b9\u306b\u3059\u308b\u305f\u3081\u306b\u306f\/mcnotify\u30b3\u30de\u30f3\u30c9\u3092\u3082\u3046\u4e00\u5ea6\u5b9f\u884c\u3057\u3066\u304f\u3060\u3055\u3044\u3002\u3053\u308c\u306f\u81ea\u52d5\u5316\u3055\u308c\u305f1\u6642\u9593\u3054\u3068\u306e\u901a\u77e5\u3067\u3059\u3002
+Reminder.Squelched=[[GRAY]]\u30ea\u30de\u30a4\u30f3\u30c0\u30fc: \u3042\u306a\u305f\u306f\u73fe\u5728mcMMO\u304b\u3089\u901a\u77e5\u3092\u53d7\u3051\u53d6\u3063\u3066\u3044\u307e\u305b\u3093\u3002\u901a\u77e5\u3092\u6709\u52b9\u306b\u3059\u308b\u305f\u3081\u306b\u306f/mcnotify\u30b3\u30de\u30f3\u30c9\u3092\u3082\u3046\u4e00\u5ea6\u5b9f\u884c\u3057\u3066\u304f\u3060\u3055\u3044\u3002\u3053\u308c\u306f\u81ea\u52d5\u5316\u3055\u308c\u305f1\u6642\u9593\u3054\u3068\u306e\u901a\u77e5\u3067\u3059\u3002
 
 
 # Locale
 # Locale
 Locale.Reloaded=[[GREEN]]\u30ed\u30b1\u30fc\u30eb \u30ea\u30ed\u30fc\u30c9\uff01
 Locale.Reloaded=[[GREEN]]\u30ed\u30b1\u30fc\u30eb \u30ea\u30ed\u30fc\u30c9\uff01

+ 0 - 1
src/main/resources/locale/locale_ru.properties

@@ -466,7 +466,6 @@ Taming.Summon.Complete=[[GREEN]]\u0412\u044b\u0437\u043e\u0432 \u0437\u0430\u043
 Taming.Summon.Fail.Ocelot=\u0412\u043e\u043a\u0440\u0443\u0433 \u0412\u0430\u0441 \u0441\u043b\u0438\u0448\u043a\u043e\u043c \u043c\u043d\u043e\u0433\u043e \u043e\u0446\u0435\u043b\u043e\u0442\u043e\u0432.
 Taming.Summon.Fail.Ocelot=\u0412\u043e\u043a\u0440\u0443\u0433 \u0412\u0430\u0441 \u0441\u043b\u0438\u0448\u043a\u043e\u043c \u043c\u043d\u043e\u0433\u043e \u043e\u0446\u0435\u043b\u043e\u0442\u043e\u0432.
 Taming.Summon.Fail.Wolf=\u0412\u043e\u043a\u0440\u0443\u0433 \u0412\u0430\u0441 \u0441\u043b\u0438\u0448\u043a\u043e\u043c \u043c\u043d\u043e\u0433\u043e \u0432\u043e\u043b\u043a\u043e\u0432, \u0447\u0442\u043e\u0431\u044b \u043f\u0440\u0438\u0437\u0432\u0430\u0442\u044c \u0435\u0449\u0435.
 Taming.Summon.Fail.Wolf=\u0412\u043e\u043a\u0440\u0443\u0433 \u0412\u0430\u0441 \u0441\u043b\u0438\u0448\u043a\u043e\u043c \u043c\u043d\u043e\u0433\u043e \u0432\u043e\u043b\u043a\u043e\u0432, \u0447\u0442\u043e\u0431\u044b \u043f\u0440\u0438\u0437\u0432\u0430\u0442\u044c \u0435\u0449\u0435.
 Taming.Summon.Fail.Horse=\u0412\u043e\u043a\u0440\u0443\u0433 \u0432\u0430\u0441 \u0441\u043b\u0438\u0448\u043a\u043e\u043c \u043c\u043d\u043e\u0433\u043e \u043b\u043e\u0448\u0430\u0434\u0435\u0439 \u0447\u0442\u043e\u0431\u044b \u043f\u0440\u0438\u0437\u0432\u0430\u0442\u044c \u0435\u0449\u0435.
 Taming.Summon.Fail.Horse=\u0412\u043e\u043a\u0440\u0443\u0433 \u0432\u0430\u0441 \u0441\u043b\u0438\u0448\u043a\u043e\u043c \u043c\u043d\u043e\u0433\u043e \u043b\u043e\u0448\u0430\u0434\u0435\u0439 \u0447\u0442\u043e\u0431\u044b \u043f\u0440\u0438\u0437\u0432\u0430\u0442\u044c \u0435\u0449\u0435.
-Taming.Summon.Name.Format={0}s {1}
 Taming.Summon.COTW.Success.WithoutLifespan=[[GREEN]](\u0417\u043e\u0432 \u041f\u0440\u0435\u0434\u043a\u043e\u0432) [[GRAY]]\u0412\u044b \u043f\u0440\u0438\u0437\u0432\u0430\u043b\u0438 [[GOLD]]{0}[[GRAY]]
 Taming.Summon.COTW.Success.WithoutLifespan=[[GREEN]](\u0417\u043e\u0432 \u041f\u0440\u0435\u0434\u043a\u043e\u0432) [[GRAY]]\u0412\u044b \u043f\u0440\u0438\u0437\u0432\u0430\u043b\u0438 [[GOLD]]{0}[[GRAY]]
 Taming.Summon.COTW.Success.WithLifespan=[[GREEN]](\u0417\u043e\u0432 \u041f\u0440\u0435\u0434\u043a\u043e\u0432) [[GRAY]]\u0412\u044b \u043f\u0440\u0438\u0437\u0432\u0430\u043b\u0438 [[GOLD]]{0}[[GRAY]] \u043d\u0430 [[GOLD]]{1}[[GRAY]] \u0441\u0435\u043a.
 Taming.Summon.COTW.Success.WithLifespan=[[GREEN]](\u0417\u043e\u0432 \u041f\u0440\u0435\u0434\u043a\u043e\u0432) [[GRAY]]\u0412\u044b \u043f\u0440\u0438\u0437\u0432\u0430\u043b\u0438 [[GOLD]]{0}[[GRAY]] \u043d\u0430 [[GOLD]]{1}[[GRAY]] \u0441\u0435\u043a.
 Taming.Summon.COTW.Limit=[[GREEN]](\u0417\u043e\u0432 \u041f\u0440\u0435\u0434\u043a\u043e\u0432) [[GRAY]]\u0412\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u0438\u043c\u0435\u0442\u044c \u0442\u043e\u043b\u044c\u043a\u043e [[RED]]{0} [[GRAY]]\u043f\u0440\u0438\u0437\u0432\u0430\u043d\u043d\u044b\u0445 [[GRAY]]{1} \u0436\u0438\u0432\u043e\u0442\u043d\u044b\u0445 \u043e\u0434\u043d\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u043e.
 Taming.Summon.COTW.Limit=[[GREEN]](\u0417\u043e\u0432 \u041f\u0440\u0435\u0434\u043a\u043e\u0432) [[GRAY]]\u0412\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u0438\u043c\u0435\u0442\u044c \u0442\u043e\u043b\u044c\u043a\u043e [[RED]]{0} [[GRAY]]\u043f\u0440\u0438\u0437\u0432\u0430\u043d\u043d\u044b\u0445 [[GRAY]]{1} \u0436\u0438\u0432\u043e\u0442\u043d\u044b\u0445 \u043e\u0434\u043d\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u043e.