Подключение к серверу

Версия Minecraft
1.7.10
API
Forge
48
2
9
Пытаюсь подключиться к серверу из мультиплеера. Вот мой код:
Java:
ServerData server_data = new ServerData("Server", "localhost");
FMLClientHandler.instance().connectToServer(new GuiMainMenu(), server_data);
В итоге выдает следующую ошибку. Что я делаю не так?
 
Краш-лог
java.lang.NullPointerException: Unexpected error
at net.minecraft.client.Minecraft.runTick(Minecraft.java:2005)
at net.minecraft.client.Minecraft.runGameLoop(Minecraft.java:1039)
at net.minecraft.client.Minecraft.run(Minecraft.java:962)
at net.minecraft.client.main.Main.main(Main.java:164)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at net.minecraft.launchwrapper.Launch.launch(Launch.java:135)
at net.minecraft.launchwrapper.Launch.main(Launch.java:28)
at net.minecraftforge.gradle.GradleStartCommon.launch(Unknown Source)
at GradleStart.main(Unknown Source)
Краш-лог:
java.lang.NullPointerException: Unexpected error
	at net.minecraft.client.Minecraft.runTick(Minecraft.java:2005)
	at net.minecraft.client.Minecraft.runGameLoop(Minecraft.java:1039)
	at net.minecraft.client.Minecraft.run(Minecraft.java:962)
	at net.minecraft.client.main.Main.main(Main.java:164)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at net.minecraft.launchwrapper.Launch.launch(Launch.java:135)
	at net.minecraft.launchwrapper.Launch.main(Launch.java:28)
	at net.minecraftforge.gradle.GradleStartCommon.launch(Unknown Source)
	at GradleStart.main(Unknown Source)
Последнее редактирование:
Решение
В общем по непонятным лично мне причинам подключение к серверу может работать только внутри какого-либо класса Gui (как в примерах выше). Лично мне надо было 2 сценария подключения к другому серверу: через gui и при получении пакета от сервера. Если с первым все ясно (есть примеры выше), то со вторым все сложнее. Для того чтобы подключиться к серверу при получении пакета нам необходимо открыть окно gui, которое подключит нас. Выглядить оно будет примерно так:
Java:
public class GuiConnectingScreen extends GuiScreen {
    public void drawScreen(int p_73863_1_, int p_73863_2_, float p_73863_3_) {
        FMLClientHandler.instance().connectToServer(new GuiMultiplayer(new GuiScreen()), new ServerData("Server", "localhost:25566"));
    }
}
...
210
1
19
выдает следующую ошибку
Если прочитать текст ошибки, то искать её источник нужно в 2005 строке класса Minecraft.java. Там содержится следующая строка:
Java:
if (this.thePlayer.isUsingItem())
Я не утверждаю, но получается, что у тебя thePlayer равен null.
 
210
1
19
Возможно нужно сделать еще что-то перед тем как подключаться к серверу?
Правильно заданный вопрос содержит в себе половину ответа на него.

Специально для того, чтобы проверить, как это работает, сделал у себя кнопку, к ней такой код:
Java:
        if (button.id == 2004) // fast join
        {
            ServerData server_data = new ServerData("название_сервера", "адрес_или_айпи:порт");
            FMLClientHandler.instance().connectToServer(new GuiMultiplayer(this), server_data);
        }

Результат положительный, всё работает. Сможешь сам сравнить свой и мой код, и найти отличие?
 
48
2
9
Специально для того, чтобы проверить, как это работает, сделал у себя кнопку, к ней такой код:
Сделал, так как ты написал, но ошибка все еще есть. Вижу, что этот пример сделан под подключение из какого-то гуи (возможно когда игрок еще не находиться на сервере), я же хочу подключиться к серверу, уже находясь при этом на каком-то сервере (типо просто переход с одного сервера на другой). Нужно ли для этого подключаться как-то по-другому? Вот мой код сейчас:
Java:
ServerData server_data = new ServerData("Minecraft server", "localhost:25565");
FMLClientHandler.instance().connectToServer(new GuiMultiplayer(new GuiScreen()), server_data);

Попробовал так же выйти с текущего сервера перед тем, как войти в новый, но выдает все ту же самую ошибку (на mc.loadWorld). Код для выхода (взял из GuiIngameMenu):
Java:
Minecraft minecraft = Minecraft.getMinecraft();
minecraft.theWorld.sendQuittingDisconnectingPacket();
minecraft.loadWorld((WorldClient)null);
minecraft.displayGuiScreen(new GuiMainMenu());

Я все еще не доганяю, что я тут делаю не так 👀
 
210
1
19
48
2
9
Ты задаешь null и получаешь ошибку nullpointer. Разве не логично?
Ок, согласен. Тут и правда логично все. Но в коде подключения к серверу вроде же нету null. Почему там тогда выкидываеться NullPointer? В логах сервера вижу, что была попытка подключения, значит server_data указана правильно. Gui тоже должен работать нормально (попробовал отрисовать его отдельно, все было ок). Возможно я пихаю код выхода в не правильно место? У меня он находиться в обработчике событий при нажатии на F. Я просто не вижу где еще может быть проблема
 
48
2
9
Скинул бы полностью класс с кодом, может быть тебе бы уже помогли.
Вот класс с одним единственным хендлером. Больше к клиенту никаких хэндлеров не подключено
Java:
public class EventsHandler {
    @SubscribeEvent
    public void onKeyPress(InputEvent.KeyInputEvent event) {
        if (ModKeybinds.button.getIsKeyPressed()) {
            ServerData server_data = new ServerData("Minecraft server", "localhost:25566");
            FMLClientHandler.instance().connectToServer(new GuiMultiplayer(new GuiScreen()), server_data);
        }
    }
}
 
210
1
19
Вот класс с одним единственным хендлером.
Потратил в эти дни часа три, не меньше, на то, чтобы решить твою проблему, ковырял код, пробовал и так, и сяк, но у меня с твоим кодом та же проблема - thePlayer всегда равен null. Просто знай, что я не отступился, а моё сообщение пусть бампнет тему - надеюсь, тебе помогут заслуженные участники форума. Если снова возьмусь и что-то сдвинется - отпишу дополнительно.
 
  • Like
Реакции: klas
48
2
9
thePlayer всегда равен null
Поковырялся еще в методе подключения к миру и вот что обнаружил. При начале подключения к серверу нам показывается GuiConnecting. В его конструкторе имеется p_i1181_2_.loadWorld((WorldClient)null); Тоже самое из-за чего у меня при попытке отключиться от сервера вылетал этот exception. Смотрим теперь его. В самом конце он делает this.thePlayer = null; если мы переданый нами мир равен null, что происходит в любом случае при вызове FMLClientHandler.instance().connectToServer.
Вопрос теперь только зачем он это делает? Скорее всего если этот код лежит в исходниках - значит он для чего-то нужен. Тогда вопрос другой - должны ли мы что-то сделать чтобы у нас не выполнялась та часть кода с this.thePlayer.isUsingItem(). Если посмотреть выше, то увидим в методе Minecraft.runTick, что данный код выполняется только при условии if (this.currentScreen == null || this.currentScreen.allowUserInput). Возможно нужно сделать так чтобы данное условие не выполнялось? Тут уже не знаю, ибо нам постоянно же пихается gui с подключением к серверу
 
48
2
9
В общем по непонятным лично мне причинам подключение к серверу может работать только внутри какого-либо класса Gui (как в примерах выше). Лично мне надо было 2 сценария подключения к другому серверу: через gui и при получении пакета от сервера. Если с первым все ясно (есть примеры выше), то со вторым все сложнее. Для того чтобы подключиться к серверу при получении пакета нам необходимо открыть окно gui, которое подключит нас. Выглядить оно будет примерно так:
Java:
public class GuiConnectingScreen extends GuiScreen {
    public void drawScreen(int p_73863_1_, int p_73863_2_, float p_73863_3_) {
        FMLClientHandler.instance().connectToServer(new GuiMultiplayer(new GuiScreen()), new ServerData("Server", "localhost:25566"));
    }
}
Потом при получении пакета просто вызываем
Java:
mc.currentScreen = new GuiConnectingScreen();
Да, выглядит очень костыльно, но к другому решению я прийти не смог. Если у кого-то есть идея лучше, то с радостью готов выслушать
 
Сверху