Решено [Проблема] Essentials usermap и хранение данных игроков

  • Автор темы Автор темы Bars
  • Дата начала Дата начала
Статус
Закрыто для дальнейших ответов.

Bars

Старожил
Девелопер
Пользователь
Баллы
173
Essentials хранит в usermap.csv карту ник-UUID, но если зайти с русским ником, то он записывается туда как Андрей -> ______ (тупо каждый "непонятный" символ записывается как подчёркивание и в таком же виде считывается). Соответственно, при входе под ником Ондрей получается:
[INFO] [Essentials] Found new UUID for Ондрей. Replacing ef4b3bdc-b8db-37ff-accc-40fe6b175e3c with d5667ab8-e185-3b43-acc4-e290c6ef1c93
[INFO] Создаю пустой конфигурационный файл: F:\1.7.10\plugins\Essentials\userdata\d5667ab8-e185-3b43-acc4-e290c6ef1c93.yml
И всё - теперь данные Андрея (флай, год, соушл спай, ласт локейшн, последний вход, анти-тп, афк статус и т.д.) принадлежат Ондрею!

Вопрос: как это исправить? Я думаю тут проблема в одном из двух мест:
1. Сама кодировка ника заведомо неверная (чисто при записи в файл)
2. Особенность CSV формата, не поддерживающего UTF-8 (однако фикс есть)

Помогите исправить проблему или хотя бы найти (или её саму, или файл(ы) в котором(-ых) происходит запись в тот самый usermap.csv).

PS: Остальные плагины работают безупречно! Даже Essentials (баг один, и то только лишь в юзермапке).
 
Последнее редактирование:
зачем тебе вообще русские ники?
Фф. Тяжко объяснить. Просто надо. Это и хороший + проекта, и свидетельство нашей всемогучести
К сожалению, на GitHub'е старые сырки для 1.7.2
А там нету файла* usermap.csv.
Я думаю нужно попробовать декомпилировать класс (если его найду) и подключить сам Essentials в качестве библиотеки, как я это делал с тем же Rei's Minimap (только там декомпил вонючий и не сработало убрать радар 🙂)
 
Скомпилить Ess с поддержкой UTF-8 и без привязки к языку (у него по всему коду размазано LOCALE.English).
 
О, нашёл исходники на Bitbucket md-5
Я конечно нуб в записи файлов специфических форматов, но как записать то, что я закомментировал (массив байтов в начало файла), без ошибок?

Eclipse:
The method write(int) in the type BufferedWriter is not applicable for the arguments (ByteArrayInputStream), что говорит нам о том, что ф-ция write не поддерживает такой тип данных. Но как это реализовать?
Java:
    private static class WriteRunner implements Runnable
    {
        private final File location;
        private final File endFile;
        private final ConcurrentSkipListMap<String, UUID> names;
        private final AtomicInteger pendingDiskWrites;

        private WriteRunner(final File location, final File endFile, final ConcurrentSkipListMap<String, UUID> names, final AtomicInteger pendingDiskWrites)
        {
            this.location = location;
            this.endFile = endFile;
            this.names = names;
            this.pendingDiskWrites = pendingDiskWrites;
        }

        @Override
        public void run()
        {
            synchronized (pendingDiskWrites)
            {
                if (pendingDiskWrites.get() > 1)
                {
                    pendingDiskWrites.decrementAndGet();
                    return;
                }

                File configFile = null;

                try
                {
                    //byte[] enc = new byte[] { (byte)0xEF, (byte)0xBB, (byte)0xBF };
                    configFile = File.createTempFile("usermap", ".tmp.csv", location);

                    final BufferedWriter bWriter = new BufferedWriter(new FileWriter(configFile));
                    //ByteArrayInputStream bais = new ByteArrayInputStream(enc);
                    //bWriter.write(bais);
                    for (Map.Entry<String, UUID> entry : names.entrySet())
                    {
                        bWriter.write(entry.getKey() + "," + entry.getValue().toString());
                        bWriter.newLine();
                    }

                    bWriter.close();
                    Files.move(configFile, endFile);
                }
                catch (IOException ex)
                {
                    try
                    {
                        if (configFile != null && configFile.exists())
                        {
                            Files.move(configFile, new File(endFile.getParentFile(), "usermap.bak.csv"));
                        }
                    }
                    catch (Exception ex2)
                    {
                        Bukkit.getLogger().log(Level.SEVERE, ex2.getMessage(), ex2);
                    }
                    Bukkit.getLogger().log(Level.WARNING, ex.getMessage(), ex);
                }
                finally
                {
                    pendingDiskWrites.decrementAndGet();
                }
            }
        }
    }

@Shevchik, @limito, @ql_Nik_lp, @Den_Abr, @BeYkeR
 
Собирайте на NetBeans. Он на нём собран. На Eclipse замучаетесь переделывать.
 
OutputStreamWriter и BufferedWriter имеют разные методы.
И да, ясен пень что ты не можешь записать ByteArrayInputStream в BufferedWriter, это вообще что-то за гранью добра и зла.
 
OutputStreamWriter и BufferedWriter имеют разные методы.
И да, ясен пень что ты не можешь записать ByteArrayInputStream в BufferedWriter, это вообще что-то за гранью добра и зла.
Я это тоже понял, но не знаю как их сопоставить, совместить, чтобы записать
 
Я просто nick ставлю себе и пишу спокойно с русским ником и в табе тоже с ним. Только руки недолши изменить пакет nick над головой через протоколлиб. Уж лучше фейковый русский ник, чем проходится напильником по кучи плагинам.
 
Я просто nick ставлю себе и пишу спокойно с русским ником и в табе тоже с ним. Только руки недолши изменить пакет nick над головой через протоколлиб. Уж лучше фейковый русский ник, чем проходится напильником по кучи плагинам.
И как, остальные плагины норм работают с эссовским nick?
А по плагинам я напильником не проходился, тут в разы всё проще. Единственная проблема только
Таки нашёл в чём дело:
Java:
String keyName = StringUtil.safeString(name);
Java:
/*    */   public static String safeString(String string)
/*    */   {
/* 22 */     return STRICTINVALIDCHARS.matcher(string.toLowerCase(java.util.Locale.ENGLISH)).replaceAll("_");
/*    */   }

Однако BOM-байты в usermap нашёл как записать (только оказалось дело не в кодировке самого usermap.csv):
Java:
                try
                {
                    byte[] enc = new byte[] { (byte)0xEF, (byte)0xBB, (byte)0xBF };
                    configFile = File.createTempFile("usermap", ".tmp.csv", location);

                    FileOutputStream fs = new FileOutputStream(configFile);
                    final BufferedWriter bWriter = new BufferedWriter(new OutputStreamWriter(fs, "UTF-8"));
                    fs.write(enc);
                    for (Map.Entry<String, UUID> entry : names.entrySet())
                    {
                        Bukkit.broadcastMessage("Player name: "+entry.getKey()); // Дебаг (вывел "Playername: ______" для Андрей, что говорит нам о неправильности самой String с именем игрока)
                        bWriter.write(entry.getKey() + "," + entry.getValue().toString());
                        bWriter.newLine();
                    }

                    bWriter.close();
                    fs.close();
                    Files.move(configFile, endFile);
                }

Всем спасибо за старания помочь
Вывод: оказалось дело в регулярке, из-за которой нужные символы не пропускались в файл, как раз поэтому была такая же проблема на 1.5.2 и теперь я понял что это был баг не самой винды, а тупой регулярки, по которой так с виду и не скажешь, что она имеет отношение к игрокам.
 
Статус
Закрыто для дальнейших ответов.
Назад
Верх Низ