Пакетная система

Версия Minecraft
1.7.10
Доброго времени суток. Хотелось бы сделать так, чтобы за наигранное время давалось что-нибудь (чтоб что-то получить, надо нажать на кнопку в гуи). Для этого в серверную часть добавил ивент, который считает наигранное время(тут еще хотел бы узнать, можно ли вытащить как-нибудь EntityPlayerMP, а то получилось только ники в стринг)
код на подсчет наигранного времени:
@SubscribeEvent
    public void onTick(TickEvent.ServerTickEvent e) {
        if (e.phase == TickEvent.Phase.END) {
            if (tick % 20 == 0) {
                String arr[] = MinecraftServer.getServer().getAllUsernames();
                for (String name : arr) {
                    PlayerData data = DiverseThings.instance.serverUtils.getPlayerData(name);
                    if (data == null) {
                        data = new PlayerData(name, 0, true);
                        DiverseThings.instance.serverUtils.toCache(data);
                    }
                    data.setTime(data.getTime() + 20);
                }
            }
            tick++;
            if (tick == Integer.MAX_VALUE - 1) {
                tick = 0;
            }
        }
    }

Далее... есть гуи, где можно нажать на кнопку(чтобы получить вознаграждение). Тут я хочу отправить пакет на сервер с игроком, который нажал по кнопке

Код при нажатии на кнопку в гуи:
@Override
    protected void actionPerformed(GuiButton button) {
        switch (button.id) {
            case 1:
                CPacket cPacket = new CPacket();
                cPacket.client(Minecraft.getMinecraft().thePlayer);
                break;
        }
        super.actionPerformed(button);
    }

Класс клиентского пакета:
public class CPacket extends SimplePacket {

    private long time;
    private EntityPlayer playerMP;

    public CPacket() {
        time = 0;
    }

    public CPacket(long time) {
        this.time = time;
    }

    @Override
    public void client(EntityPlayer player) {
        playerMP = player;
        PacketNetwork.sendToServer(this);
    }
}
}

Далее мне надо просто обработать данный пакет и вернуть в ответ число, но, я пока даже не могу нормально принять пакет на стороне сервера
Логи:
io.netty.handler.codec.EncoderException: java.lang.NullPointerException
    at io.netty.handler.codec.MessageToMessageEncoder.write(MessageToMessageEncoder.java:107) ~[MessageToMessageEncoder.class:?]
    at io.netty.handler.codec.MessageToMessageCodec.write(MessageToMessageCodec.java:116) ~[MessageToMessageCodec.class:?]
    at io.netty.channel.DefaultChannelHandlerContext.invokeWrite(DefaultChannelHandlerContext.java:644) ~[DefaultChannelHandlerContext.class:?]
    at io.netty.channel.DefaultChannelHandlerContext.write(DefaultChannelHandlerContext.java:698) ~[DefaultChannelHandlerContext.class:?]
    at io.netty.channel.DefaultChannelHandlerContext.writeAndFlush(DefaultChannelHandlerContext.java:688) ~[DefaultChannelHandlerContext.class:?]
    at io.netty.channel.DefaultChannelHandlerContext.writeAndFlush(DefaultChannelHandlerContext.java:717) ~[DefaultChannelHandlerContext.class:?]
    at io.netty.channel.DefaultChannelPipeline.writeAndFlush(DefaultChannelPipeline.java:893) ~[DefaultChannelPipeline.class:?]
    at io.netty.channel.AbstractChannel.writeAndFlush(AbstractChannel.java:239) ~[AbstractChannel.class:?]
    at cpw.mods.fml.common.network.simpleimpl.SimpleNetworkWrapper.sendToServer(SimpleNetworkWrapper.java:236) [SimpleNetworkWrapper.class:?]
    at me.Sa1ZeR_.DiverseThings.utils.packets.PacketNetwork.sendToServer(PacketNetwork.java:27) [PacketNetwork.class:?]
    at me.Sa1ZeR_.DiverseThings.utils.packets.client.CPacket.client(CPacket.java:25) [CPacket.class:?]
    at me.Sa1ZeR_.DiverseThings.GUI.WandererScreen.actionPerformed(WandererScreen.java:51) [WandererScreen.class:?]
    at net.minecraft.client.gui.GuiScreen.mouseClicked(GuiScreen.java:252) [GuiScreen.class:?]
    at net.minecraft.client.gui.GuiScreen.handleMouseInput(GuiScreen.java:344) [GuiScreen.class:?]
    at net.minecraft.client.gui.GuiScreen.handleInput(GuiScreen.java:313) [GuiScreen.class:?]
    at net.minecraft.client.Minecraft.runTick(Minecraft.java:1731) [Minecraft.class:?]
    at net.minecraft.client.Minecraft.runGameLoop(Minecraft.java:1039) [Minecraft.class:?]
    at net.minecraft.client.Minecraft.run(Minecraft.java:962) [Minecraft.class:?]
    at net.minecraft.client.main.Main.main(Main.java:164) [Main.class:?]
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.8.0_231]
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[?:1.8.0_231]
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:1.8.0_231]
    at java.lang.reflect.Method.invoke(Method.java:498) ~[?:1.8.0_231]
    at net.minecraft.launchwrapper.Launch.launch(Launch.java:135) [launchwrapper-1.12.jar:?]
    at net.minecraft.launchwrapper.Launch.main(Launch.java:28) [launchwrapper-1.12.jar:?]
    at net.minecraftforge.gradle.GradleStartCommon.launch(Unknown Source) [start/:?]
    at GradleStart.main(Unknown Source) [start/:?]
Caused by: java.lang.NullPointerException
    at io.netty.buffer.AbstractByteBuf.writeBytes(AbstractByteBuf.java:824) ~[AbstractByteBuf.class:?]
    at me.Sa1ZeR_.DiverseThings.utils.packets.SimplePacket.toBytes(SimplePacket.java:35) ~[SimplePacket.class:?]
    at cpw.mods.fml.common.network.simpleimpl.SimpleIndexedCodec.encodeInto(SimpleIndexedCodec.java:11) ~[SimpleIndexedCodec.class:?]
    at cpw.mods.fml.common.network.simpleimpl.SimpleIndexedCodec.encodeInto(SimpleIndexedCodec.java:7) ~[SimpleIndexedCodec.class:?]
    at cpw.mods.fml.common.network.FMLIndexedMessageToMessageCodec.encode(FMLIndexedMessageToMessageCodec.java:51) ~[FMLIndexedMessageToMessageCodec.class:?]
    at io.netty.handler.codec.MessageToMessageCodec$1.encode(MessageToMessageCodec.java:67) ~[MessageToMessageCodec$1.class:?]
    at io.netty.handler.codec.MessageToMessageEncoder.write(MessageToMessageEncoder.java:89) ~[MessageToMessageEncoder.class:?]
    ... 26 more
[17:56:01] [Client thread/ERROR] [FML]: SimpleChannelHandlerWrapper exception
io.netty.handler.codec.EncoderException: java.lang.NullPointerException
    at io.netty.handler.codec.MessageToMessageEncoder.write(MessageToMessageEncoder.java:107) ~[MessageToMessageEncoder.class:?]
    at io.netty.handler.codec.MessageToMessageCodec.write(MessageToMessageCodec.java:116) ~[MessageToMessageCodec.class:?]
    at io.netty.channel.DefaultChannelHandlerContext.invokeWrite(DefaultChannelHandlerContext.java:644) ~[DefaultChannelHandlerContext.class:?]
    at io.netty.channel.DefaultChannelHandlerContext.write(DefaultChannelHandlerContext.java:698) ~[DefaultChannelHandlerContext.class:?]
    at io.netty.channel.DefaultChannelHandlerContext.writeAndFlush(DefaultChannelHandlerContext.java:688) ~[DefaultChannelHandlerContext.class:?]
    at io.netty.channel.DefaultChannelHandlerContext.writeAndFlush(DefaultChannelHandlerContext.java:717) ~[DefaultChannelHandlerContext.class:?]
    at io.netty.channel.DefaultChannelPipeline.writeAndFlush(DefaultChannelPipeline.java:893) ~[DefaultChannelPipeline.class:?]
    at io.netty.channel.AbstractChannel.writeAndFlush(AbstractChannel.java:239) ~[AbstractChannel.class:?]
    at cpw.mods.fml.common.network.simpleimpl.SimpleNetworkWrapper.sendToServer(SimpleNetworkWrapper.java:236) [SimpleNetworkWrapper.class:?]
    at me.Sa1ZeR_.DiverseThings.utils.packets.PacketNetwork.sendToServer(PacketNetwork.java:27) [PacketNetwork.class:?]
    at me.Sa1ZeR_.DiverseThings.utils.packets.client.CPacket.client(CPacket.java:25) [CPacket.class:?]
    at me.Sa1ZeR_.DiverseThings.GUI.WandererScreen.actionPerformed(WandererScreen.java:51) [WandererScreen.class:?]
    at net.minecraft.client.gui.GuiScreen.mouseClicked(GuiScreen.java:252) [GuiScreen.class:?]
    at net.minecraft.client.gui.GuiScreen.handleMouseInput(GuiScreen.java:344) [GuiScreen.class:?]
    at net.minecraft.client.gui.GuiScreen.handleInput(GuiScreen.java:313) [GuiScreen.class:?]
    at net.minecraft.client.Minecraft.runTick(Minecraft.java:1731) [Minecraft.class:?]
    at net.minecraft.client.Minecraft.runGameLoop(Minecraft.java:1039) [Minecraft.class:?]
    at net.minecraft.client.Minecraft.run(Minecraft.java:962) [Minecraft.class:?]
    at net.minecraft.client.main.Main.main(Main.java:164) [Main.class:?]
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.8.0_231]
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[?:1.8.0_231]
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:1.8.0_231]
    at java.lang.reflect.Method.invoke(Method.java:498) ~[?:1.8.0_231]
    at net.minecraft.launchwrapper.Launch.launch(Launch.java:135) [launchwrapper-1.12.jar:?]
    at net.minecraft.launchwrapper.Launch.main(Launch.java:28) [launchwrapper-1.12.jar:?]
    at net.minecraftforge.gradle.GradleStartCommon.launch(Unknown Source) [start/:?]
    at GradleStart.main(Unknown Source) [start/:?]
Caused by: java.lang.NullPointerException
    at io.netty.buffer.AbstractByteBuf.writeBytes(AbstractByteBuf.java:824) ~[AbstractByteBuf.class:?]
    at me.Sa1ZeR_.DiverseThings.utils.packets.SimplePacket.toBytes(SimplePacket.java:35) ~[SimplePacket.class:?]
    at cpw.mods.fml.common.network.simpleimpl.SimpleIndexedCodec.encodeInto(SimpleIndexedCodec.java:11) ~[SimpleIndexedCodec.class:?]
    at cpw.mods.fml.common.network.simpleimpl.SimpleIndexedCodec.encodeInto(SimpleIndexedCodec.java:7) ~[SimpleIndexedCodec.class:?]
    at cpw.mods.fml.common.network.FMLIndexedMessageToMessageCodec.encode(FMLIndexedMessageToMessageCodec.java:51) ~[FMLIndexedMessageToMessageCodec.class:?]
    at io.netty.handler.codec.MessageToMessageCodec$1.encode(MessageToMessageCodec.java:67) ~[MessageToMessageCodec$1.class:?]
    at io.netty.handler.codec.MessageToMessageEncoder.write(MessageToMessageEncoder.java:89) ~[MessageToMessageEncoder.class:?]
    ... 26 more

Подскажите, пожалуйста. где ошибка.
PacketNetwork:
public class PacketNetwork {

    private short id;

    public static final SimpleNetworkWrapper NETWORK = NetworkRegistry.INSTANCE.newSimpleChannel("testpacket");

    public PacketNetwork() {
        register(CPacket.class, Side.CLIENT);
        register(SPacket.class, Side.SERVER);
    }

    public static void sendToAllAround(SimplePacket packet, World world, double x, double y, double z, double distance) {
        NETWORK.sendToAllAround(packet, new NetworkRegistry.TargetPoint(world.provider.dimensionId, x, y, z, distance));
    }

    public static void sendToServer(SimplePacket packet) {
        NETWORK.sendToServer(packet);
    }

    public static void sendToClient(SimplePacket packet, EntityPlayerMP player) {
        NETWORK.sendTo(packet, player);
    }

    private void register(Class<? extends SimplePacket> packet, Side side) {
        try {
            NETWORK.registerMessage(packet.newInstance(), packet, id++, side);
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        }
    }

}

SimplePacket:
public class SimplePacket implements IMessage, IMessageHandler<SimplePacket, SimplePacket> {

    private ByteBuf buf;

    public void client(EntityPlayer player) {}
    public void server(EntityPlayerMP player) {}
    public void server(PlayerData data) {}

    protected ByteBuf getBuf() {
        return  buf != null ? buf : (buf = Unpooled.buffer());
    }

    @Override
    public void fromBytes(ByteBuf buf) {
        this.buf = buf;
    }

    @Override
    public void toBytes(ByteBuf buf) {
        if(buf != null) {
            buf.writeBytes(this.buf);
        }
    }

    @Override
    public SimplePacket onMessage(SimplePacket message, MessageContext ctx) {
        System.out.println("Я принял пакет");
        if(ctx.side.isServer()) {
            message.server(ctx.getServerHandler().playerEntity);
        } else {
            message.client(clientPlayer());
        }
        return null;
    }

    @SideOnly(Side.CLIENT)
    private EntityPlayer clientPlayer() {
        return Minecraft.getMinecraft().thePlayer;
    }

}
 
Последнее редактирование:

tox1cozZ

aka Agravaine
8,456
598
2,892
Ну, наигранное время Майн и так считает, зачем ещё свое городить, достань стату и юзай.
А с пакетами ты чото непонятное делаешь
Тебе нужно отправить пакет на сервер, в методе server его обработать. А что делаешь ты? И да, игрок там есть и не надо своего тыкать, тем более он у тебя нулл и ты нигде не инициализируешь его
 
7,099
324
1,510
Можно сделать на плагине Essentials кит daily_reward раз в 23 часа 30 минут. Сделать гуи с контейнером и кнопкой. В контейнере переопределить enchantItem, чекать в нем серверную сторону и вызывать от имени игрока /kit daily_reward
 
Разве таким образом я не отправлю пакет на сервер?
Java:
protected void actionPerformed(GuiButton button) {
        switch (button.id) {
            case 1:
                CPacket cPacket = new CPacket();
                cPacket.client(Minecraft.getMinecraft().thePlayer);
                break;
        }
        super.actionPerformed(button);
 
Последнее редактирование модератором:
Да знаю. что игрок есть в аргументах, просто выбивало NPE, решил протестить по другому, к сожалению. безуспешно. До этого выглядело вот так
Java:
@Override
    public void client(EntityPlayer player) {
        playerMP = player;
        PacketNetwork.sendToServer(this);
    }
На счет всего остального... Разве я не должен переопределять метод server в пакете сервера ? В методе client я как раз таки и использую sendToServer(выбиывает в конечном итоге NPE), можно меня тыкнуть носом, где неправильно ?)
 

tox1cozZ

aka Agravaine
8,456
598
2,892
Ты чушь делаешь, я уже объяснил алгоритм...
В своем гуи при нажатии кнопки делаешь PacketNetwork.sendToServer(new Packet(...));
В классе Packet переопределяешь метод server и там уже делаешь чото.
В методах fromBytes и toBytes читаешь и пишешь данные пакета в buf.
 
Такс. Вроде я разобрался. NPE вылетало из-за того, что я забыл записать данные в буфер. Теперь проблема в том, что метод onMessage не отрабатывает вообще. Все заканчивается на том, что отрабатывает метод toBytes().
Измененный код:
Кнопка:
@Override
    protected void actionPerformed(GuiButton button) {
        switch (button.id) {
            case 1:
                PacketNetwork.sendToServer(new SPacket(mc.thePlayer.getGameProfile().getName()));
                break;
        }
        super.actionPerformed(button);
    }

SPacket:
public class SPacket extends SimplePacket {

    public SPacket(String name) {
        ByteBufUtils.writeUTF8String(getBuf(), name);
    }

    @Override
    public void server(EntityPlayerMP player) {
        String name =  ByteBufUtils.readUTF8String(getBuf());
        System.out.println(name);
    }
}

PacketNetwork:
public class PacketNetwork {

    private short id;

    public static final SimpleNetworkWrapper NETWORK = NetworkRegistry.INSTANCE.newSimpleChannel("testpacket");

    public PacketNetwork() {
        register(CPacket.class, Side.CLIENT);
        register(SPacket.class, Side.SERVER);
    }

    public static void sendToAllAround(SimplePacket packet, World world, double x, double y, double z, double distance) {
        NETWORK.sendToAllAround(packet, new NetworkRegistry.TargetPoint(world.provider.dimensionId, x, y, z, distance));
    }

    public static void sendToServer(SimplePacket packet) {
        NETWORK.sendToServer(packet);
    }

    public static void sendToClient(SimplePacket packet, EntityPlayerMP player) {
        NETWORK.sendTo(packet, player);
    }

    private void register(Class<? extends SimplePacket> packet, Side side) {
        try {
            NETWORK.registerMessage(packet.newInstance(), packet, id++, side);
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        }
    }

}

SimplePacket:
public class SimplePacket implements IMessage, IMessageHandler<SimplePacket, SimplePacket> {

    private ByteBuf buf;

    public void client(EntityPlayer player) {}
    public void server(EntityPlayerMP player) {}

    protected ByteBuf getBuf() {
        return  buf != null ? buf : (buf = Unpooled.buffer());
    }

    @Override
    public void fromBytes(ByteBuf buf) {
        System.out.println("Отработал");
        this.buf = buf;
    }

    @Override
    public void toBytes(ByteBuf buf) {
        if(buf != null) {
            buf.writeBytes(this.buf);
            System.out.println("Отработалвфцв");
        }
    }

    @Override
    public SimplePacket onMessage(SimplePacket message, MessageContext ctx) {
        if(ctx.side.isServer()) {
            System.out.println("qq");
            message.server(ctx.getServerHandler().playerEntity);
        } else {
            System.out.println("qqq");
            message.client(clientPlayer());
        }
        System.out.println("qqqqqqqq");
        return null;
    }

    @SideOnly(Side.CLIENT)
    private EntityPlayer clientPlayer() {
        return Minecraft.getMinecraft().thePlayer;
    }

}
 
7,099
324
1,510
78
3
10
Все еще актуально, прошу помощи.
Распиши окружение.
Версия маина, тип сервера (forge, bukkit, spigot, thermos, ...), если поддерживаются плагины - какие плагины стоят.
Пробежался глазами по ветке, и складывается ощущение, что ты реально изобретаешь вундерваффель. А на таких изобретениях юные программисты обычно и прогорают. Одно из первых правил программирования: "преждевременные оптимизации - корень всех бед". Изобрети сначала костыльное решение, которые бы работало, а уже затем смотри на реакцию пользователей и придумывай более правильное. Вариант с китами - один из самых простых и понятных. Затем ты можешь на спавне сделать сундук/раздатчик с кнопкой, и по нажатию на кнопку выдавать содержимое кита. И вот так, итерациями, довести функ до желаемого.
 
Распиши окружение.
Версия маина, тип сервера (forge, bukkit, spigot, thermos, ...), если поддерживаются плагины - какие плагины стоят.
Пробежался глазами по ветке, и складывается ощущение, что ты реально изобретаешь вундерваффель. А на таких изобретениях юные программисты обычно и прогорают. Одно из первых правил программирования: "преждевременные оптимизации - корень всех бед". Изобрети сначала костыльное решение, которые бы работало, а уже затем смотри на реакцию пользователей и придумывай более правильное. Вариант с китами - один из самых простых и понятных. Затем ты можешь на спавне сделать сундук/раздатчик с кнопкой, и по нажатию на кнопку выдавать содержимое кита. И вот так, итерациями, довести функ до желаемого.
Версия указана в шапке. Я пишу это для себя, хочу научиться работать с клиент-серверными модами. А значит идея с командой точно не для меня. Отправить ее в чат я уж точно смогу.
 
7,099
324
1,510
Как минимум из-за того, что если выйти из игры, то время все равно будет идти.
А, вот оно что. Тогда имеет смысл опираться на статистику игрока
наигранное время Майн и так считает
Вот так ее можно получить:
Scala:
entityPlayer.asInstanceOf[EntityPlayerMP].func_147099_x.writeStat(StatList.minutesPlayedStat)
Java:
return ((EntityPlayerMP)entityPlayer).func_147099_x().writeStat(StatList.minutesPlayedStat);
 
Сверху