1. Вы находитесь в сообществе Rubukkit. Мы - администраторы серверов Minecraft, разрабатываем собственные плагины и переводим на различные языки плагины наших коллег из других стран.
    Скрыть объявление
Скрыть объявление
В преддверии глобального обновления, мы проводим исследования, которые помогут нам сделать опыт пользования форумом ещё удобнее. Помогите нам, примите участие!

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

Тема в разделе "Помощь", создана пользователем Bars, 4 фев 2015.

Статус темы:
Закрыта.
  1. Автор темы
    Bars

    Bars Старожил Девелопер Пользователь

    Баллы:
    173
    Essentials хранит в usermap.csv карту ник-UUID, но если зайти с русским ником, то он записывается туда как Андрей -> ______ (тупо каждый "непонятный" символ записывается как подчёркивание и в таком же виде считывается). Соответственно, при входе под ником Ондрей получается:
    И всё - теперь данные Андрея (флай, год, соушл спай, ласт локейшн, последний вход, анти-тп, афк статус и т.д.) принадлежат Ондрею!

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

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

    PS: Остальные плагины работают безупречно! Даже Essentials (баг один, и то только лишь в юзермапке).
     
    Последнее редактирование: 4 фев 2015
  2. Автор темы
    Bars

    Bars Старожил Девелопер Пользователь

    Баллы:
    173
    Ссылка на плагин: 2.14.1.3pre
    К сожалению, на GitHub'е старые сырки для 1.7.2
     
  3. Автор темы
    Bars

    Bars Старожил Девелопер Пользователь

    Баллы:
    173
    Фф. Тяжко объяснить. Просто надо. Это и хороший + проекта, и свидетельство нашей всемогучести
    А там нету файла* usermap.csv.
    Я думаю нужно попробовать декомпилировать класс (если его найду) и подключить сам Essentials в качестве библиотеки, как я это делал с тем же Rei's Minimap (только там декомпил вонючий и не сработало убрать радар :))
     
  4. deadanykey

    deadanykey Активный участник Пользователь

    Баллы:
    96
    Скомпилить Ess с поддержкой UTF-8 и без привязки к языку (у него по всему коду размазано LOCALE.English).
     
  5. Автор темы
    Bars

    Bars Старожил Девелопер Пользователь

    Баллы:
    173
    О, нашёл исходники на Bitbucket md-5
    Я конечно нуб в записи файлов специфических форматов, но как записать то, что я закомментировал (массив байтов в начало файла), без ошибок?

    Eclipse:
    The method write(int) in the type BufferedWriter is not applicable for the arguments (ByteArrayInputStream), что говорит нам о том, что ф-ция write не поддерживает такой тип данных. Но как это реализовать?
    Код:
        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
     
  6. deadanykey

    deadanykey Активный участник Пользователь

    Баллы:
    96
    Собирайте на NetBeans. Он на нём собран. На Eclipse замучаетесь переделывать.
     
  7. Shevchik

    Shevchik Старожил Пользователь

    Баллы:
    173
    Имя в Minecraft:
    _Shevchik_
    OutputStreamWriter и BufferedWriter имеют разные методы.
    И да, ясен пень что ты не можешь записать ByteArrayInputStream в BufferedWriter, это вообще что-то за гранью добра и зла.
     
  8. Автор темы
    Bars

    Bars Старожил Девелопер Пользователь

    Баллы:
    173
    Я это тоже понял, но не знаю как их сопоставить, совместить, чтобы записать
     
  9. alexandrage

    alexandrage Старожил Пользователь

    Баллы:
    173
    Я просто nick ставлю себе и пишу спокойно с русским ником и в табе тоже с ним. Только руки недолши изменить пакет nick над головой через протоколлиб. Уж лучше фейковый русский ник, чем проходится напильником по кучи плагинам.
     
  10. Автор темы
    Bars

    Bars Старожил Девелопер Пользователь

    Баллы:
    173
    И как, остальные плагины норм работают с эссовским nick?
    А по плагинам я напильником не проходился, тут в разы всё проще. Единственная проблема только
    Таки нашёл в чём дело:
    Код:
    String keyName = StringUtil.safeString(name);
    Код:
    /*    */   public static String safeString(String string)
    /*    */   {
    /* 22 */     return STRICTINVALIDCHARS.matcher(string.toLowerCase(java.util.Locale.ENGLISH)).replaceAll("_");
    /*    */   }
    Однако BOM-байты в usermap нашёл как записать (только оказалось дело не в кодировке самого usermap.csv):
    Код:
                    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 и теперь я понял что это был баг не самой винды, а тупой регулярки, по которой так с виду и не скажешь, что она имеет отношение к игрокам.
     
Статус темы:
Закрыта.

Поделиться этой страницей