[Решено]Странный баг

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

Ission

Старожил
Девелопер
Пользователь
Баллы
173
Есть код, который выдаёт нам экземпляр PlayerContent:
Java:
public static PlayerContent getContent(String name)
    {
        PlayerContent pc = players.get(name.toLowerCase());
        if(pc==null)
        {
            pc = new PlayerContent();
            players.put(name.toLowerCase(), pc);
        }
        return pc;
    }
И далее в слушателе выбивает NullPointerException:
Caused by: java.lang.NullPointerException
at lokiPlugin16.Listener.onPlayerAttack(Listener.java:77) ~[?:?]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.7.0
_07]
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) ~[?:1.7.0
_07]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) ~[?:1
.7.0_07]
at java.lang.reflect.Method.invoke(Unknown Source) ~[?:1.7.0_07]
at org.bukkit.plugin.java.JavaPluginLoader$1.execute(JavaPluginLoader.ja
va:292) ~[craftbukkit-1.7.5-R0.1.jar:git-Bukkit-1.7.2-R0.3-14-g8f8716c-b3042jnks
]
... 15 more
Фрагмент слушателя:
Java:
                Sign sign = (Sign) e.getClickedBlock().getState();
                PlayerContent c = PlayerContent.getContent(e.getPlayer());
                if(sign.getLine(0).equals("[join]"))
                {
                    if(c.arena!=null)//77 строка
                        c.arena.removePlayer(e.getPlayer());
В чём дело?
 
Не видел. Посмотрите отладчиком, какой объект хранится в мапе.
 
public static PlayerContent getContent(String name) {
блабла
}

PlayerContent c = PlayerContent.getContent(e.getPlayer());

Ничего не напрягает?


Используйте статические анализаторы, они реально помогают не сидеть над такими ошибками по 100 лет.
 
Не видел. Посмотрите отладчиком, какой объект хранится в мапе.
В том-то и дело, что всё в порядке(должно быть), ан нет.
public static PlayerContent getContent(String name) {
блабла
}

PlayerContent c = PlayerContent.getContent(e.getPlayer());

Ничего не напрягает?


Используйте статические анализаторы, они реально помогают не сидеть над такими ошибками по 100 лет.
Java:
    public static PlayerContent getContent(Player p)
    {
        return getContent(p.getName());
    }
 
В таком случае тут больше ошибок нет. Показывайте весь код, ошибка в другом месте где-то.
 
Показывайте весь код.
 
Показывайте весь код.
Java:
public class PlayerContent
{
    public Base arena = null;
    public SimpleBase base = null;
    public PlayerClass clazz = null;
    public static PlayerContent getContent(Player p)
    {
        return getContent(p.getName());
    }
    public static PlayerContent getContent(String name)
    {
        PlayerContent pc = players.get(name.toLowerCase());
        if(pc==null)
        {
            pc = new PlayerContent();
            players.put(name.toLowerCase(), pc);
        }
        return pc;
    }
    public static HashMap<String, PlayerContent> players = new HashMap<String, PlayerContent>();
}
Java:
public class Listener implements org.bukkit.event.Listener
{
    public Listener()
    {}
    @EventHandler
    public void onBlockBreak(BlockBreakEvent e)
    {
        PlayerContent c = PlayerContent.getContent(e.getPlayer());
        if(c.arena!=null)
        {
            if(e.getBlock().getType()==c.arena.arena.baseMaterial)
            {
                if(!c.base.contains(e.getBlock().getLocation()))
                    c.arena.baseAttack(e.getBlock().getLocation());
                else
                    e.getPlayer().sendMessage("Заглушка!");
                e.setCancelled(true);
            }
            else if(c.arena.arena.regeneration.containsKey(e.getBlock().getType()))
            {
                c.arena.timeTicker.addBlock(e.getBlock(), e.getBlock().getType());
            }
        }
    }
    @EventHandler
    public void onPlayerExit(PlayerQuitEvent e)
    {
        PlayerContent c = PlayerContent.getContent(e.getPlayer());
        if(c.arena!=null)
            c.arena.removePlayer(e.getPlayer());
        e.getPlayer().teleport(e.getPlayer().getWorld().getSpawnLocation());
    }
    @EventHandler
    public void onFoodChange(FoodLevelChangeEvent e)
    {
        if(e.getEntityType()==EntityType.PLAYER)
            if(PlayerContent.getContent((Player)e.getEntity()).arena!=null)
                e.setFoodLevel(100);
    }
    @EventHandler
    public void onPlayerAttack(PlayerInteractEvent e)
    {
        if(e.getAction()==Action.RIGHT_CLICK_BLOCK)
        {
            if(e.getClickedBlock().getType()==Material.WALL_SIGN||
                    e.getClickedBlock().getType()==Material.SIGN_POST)
            {
                Sign sign = (Sign) e.getClickedBlock().getState();
                PlayerContent c = PlayerContent.getContent(e.getPlayer());
                if(sign.getLine(0).equals("[exit]"))
                {
                    if(c.arena==null)
                        return;
                    c.arena.removePlayer(e.getPlayer());
                }
                else if(sign.getLine(0).equals("[join]"))
                {
                    if(c.arena!=null)
                        c.arena.removePlayer(e.getPlayer());
                    Base b = Main.getPlugin().arenas.get(sign.getLine(1));
                    if(b.start)
                    {
                        e.getPlayer().sendMessage("Заглушка!");
                        return;
                    }
                    if(b.queue.size()>=c.arena.arena.maxPlayers)
                    {
                        e.getPlayer().sendMessage("Заглушка!");
                        return;
                    }
                    b.addPlayer(e.getPlayer());
                }
            }
        }
    }
}
 
Унесите статик методы в отдельный класс. Я сейчас сильно хочу спать, но чую проблема где-то в этом.
У меня такой код примерно нормально работает, только что проверил.
С утра посмотрю, может что увижу.
 
Последнее редактирование:
Унесите статик методы в отдельный класс. Я сейчас сильно хочу спать, но чую проблема где-то в этом.
У меня такой код примерно нормально работает, только что проверил.
С утра посмотрю, может что увижу.
А он и должен нормально работать. Вот только у меня не желает. Может попробовать ядро сменить?
 
Хотя мне кажется тут всё куда проще.
Перекомпилируйте плагин и оставьте единственным на сервере
 
Он и так единственный(кроме WE). Но я попробую.
Значит вариант с 2мя классами с одинаковыми именами из разных джарников отпадает.
Тогда пройдитесь декомпайлером по джарнику потом, наверняка что-то не так с ним, а точнее с компайлером либо экспортером. А лучше байткод эдитором посмотрите байткод, так куда понятнее будет что не так.
 
Код:
public static PlayerContent getContent(String name){
        if(players.get(name.toLowerCase()) == null){
            PlayerContent pc = new PlayerContent();
            players.put(name.toLowerCase(), pc);
            return pc;
        }else{
       return players.get(name.toLowerCase());
        }
       return null;
    }
 
Код:
public static PlayerContent getContent(String name){
        if(players.get(name.toLowerCase()) == null){
            PlayerContent pc = new PlayerContent();
            players.put(name.toLowerCase(), pc);
            return pc;
        }else{
       return players.get(name.toLowerCase());
        }
       return null;
    }
... что? Можно хоть мааааленький комментарий к сообщению?
Сложившаяся ситуация мне напоминает fuse биты на ATmega328, из-за которых прошивка не работала верно. Но тут железа же нет...
 
Проблема решилась сама собой. Причины я так и не нашёл. Ночью лёг спать, выключил машину, сейчас запустил потестировать, проблемы как не бывало. Ничего не понимаю я в этом мире.
 
Статус
Закрыто для дальнейших ответов.
Назад
Верх