Jump to content

Serializable: how to pass object to IMessage?


RareScrap

Recommended Posts

Good afternoon. I'm doing a mod for role-playing game and I want to transfer to the server an object that contains in itself all the necessary information for the dice roll: the number of dice faces, the name of the characteristic, additional modifiers to throw etc. I serialized my object and made sure that the same byte array was passed between toByte and fromByte. From these bytes in fromByte, I need to recreate the DiceRoll object, but for some reason o.readObject () returns null.

RollPacketToServer.java + inner handler

package ru.rarescrap.network.packets;

import cpw.mods.fml.common.network.ByteBufUtils;
import cpw.mods.fml.common.network.simpleimpl.IMessage;
import cpw.mods.fml.common.network.simpleimpl.IMessageHandler;
import cpw.mods.fml.common.network.simpleimpl.MessageContext;
import io.netty.buffer.ByteBuf;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.Random;
import java.util.logging.Level;
import java.util.logging.Logger;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.util.ChatComponentText;

import net.minecraft.util.StatCollector;
import ru.rarescrap.rsstats.utils.DiceRoll;
import ru.rarescrap.rsstats.utils.RollModificator;
       
/**
 * Этот пакет отсылается сервера
 * @author RareScrap
 */
public class RollPacketToServer implements IMessage {
    private DiceRoll diceRollMessage;
    
    /**
     * Необходимый конструктор по умолчанию. Он необходим для того, чтобы на
     * стороне-обработчике создать объект и распаковать в него буффер. 
     */
    public RollPacketToServer() {}

    public RollPacketToServer(DiceRoll message) {
        System.out.print("const");
        this.diceRollMessage = message;
    }
    
    @Override
    public void fromBytes(ByteBuf buf) {
        byte[] bytes = buf.array();
        ByteArrayInputStream b = new ByteArrayInputStream(bytes);
        ObjectInputStream o = null;
        try {
            o = new ObjectInputStream(b);
            this.diceRollMessage = (DiceRoll) o.readObject();
        } catch (IOException ex) {
            Logger.getLogger(RollPacketToServer.class.getName()).log(Level.SEVERE, null, ex);
        } catch (ClassNotFoundException ex) {
            Logger.getLogger(RollPacketToServer.class.getName()).log(Level.SEVERE, null, ex);
        }
        if (o != null)
            try {
                o.close();
        } catch (IOException ex) {
            Logger.getLogger(RollPacketToServer.class.getName()).log(Level.SEVERE, null, ex);
        }
        
        
        // ГОВНО
        FileOutputStream out = null;
        try {
            out = new FileOutputStream("D:\\Users\\rares\\Downloads\\checkstyle1.txt");
            out.write(bytes);
           
        } catch (FileNotFoundException ex) {
            Logger.getLogger(RollPacketToServer.class.getName()).log(Level.SEVERE, null, ex);
        } catch (IOException ex) {
            Logger.getLogger(RollPacketToServer.class.getName()).log(Level.SEVERE, null, ex);
        }
        if (out != null)
            try {
                out.close();
        } catch (IOException ex) {
            Logger.getLogger(RollPacketToServer.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    @Override
    public void toBytes(ByteBuf buf) {
        ByteArrayOutputStream b = new ByteArrayOutputStream();
        ObjectOutputStream o = null;
        try {
            o = new ObjectOutputStream(b);
            o.writeObject(diceRollMessage);
        } catch (IOException ex) {
             Logger.getLogger(RollPacketToServer.class.getName()).log(Level.SEVERE, null, ex);
        }
        if (o != null)
            try {
                o.close();
        } catch (IOException ex) {
            Logger.getLogger(RollPacketToServer.class.getName()).log(Level.SEVERE, null, ex);
        }
        //ByteBufUtils.writeUTF8String(buf, b.);
        buf.writeBytes(b.toByteArray());
               
        
        
        // ГОВНО
        FileOutputStream out = null;
        try {
            out = new FileOutputStream("D:\\Users\\rares\\Downloads\\checkstyle.txt");
            out.write(buf.array());
           
        } catch (FileNotFoundException ex) {
            Logger.getLogger(RollPacketToServer.class.getName()).log(Level.SEVERE, null, ex);
        } catch (IOException ex) {
            Logger.getLogger(RollPacketToServer.class.getName()).log(Level.SEVERE, null, ex);
        }
        if (out != null)
            try {
                out.close();
        } catch (IOException ex) {
            Logger.getLogger(RollPacketToServer.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
    
    /**
     * Этот внутренний класс обрабатывает пришедший пакет НА СТОРОНЕ СЕРВЕРА
     */
    public static class MessageHandler implements IMessageHandler<RollPacketToServer, IMessage> {
        // Do note that the default constructor is required, but implicitly defined in this case
        public MessageHandler() {}

        @Override
        public IMessage onMessage(RollPacketToServer message, MessageContext ctx) {
            // This is the player the packet was sent to the server from
            EntityPlayerMP serverPlayer = ctx.getServerHandler().playerEntity;
            
            System.out.print("onMessage");
            if (message.diceRollMessage == null)
                throw new NullPointerException("diceRollMessage is null");
            
            String result = message.diceRollMessage.roll();
            // и вывести его в чат
            serverPlayer.addChatComponentMessage(new ChatComponentText(result));
            
            
            /*
            String maxS = new String();
            String stat = new String();
            int i = 0;
            for (; amount.charAt(i) != '_'; i++) {
                maxS += amount.charAt(i);
            }
            i++;
            for (; i < amount.length(); i++) {
                stat += amount.charAt(i);
            }
            
            int min = 1;
            int max = Integer.parseInt(maxS);
            
            String result = StatCollector.translateToLocalFormatted("item.StatItem.rollChatMessage", stat) + ": ";
            int resultInt = 0;
            int randomNum = ThreadLocalRandom.current().nextInt(min, max + 1);
            resultInt += randomNum;
            while(randomNum == max) {
                result += String.valueOf(randomNum)+ "+";
                resultInt += randomNum;
                randomNum = ThreadLocalRandom.current().nextInt(min, max + 1);
                
            }
            result += String.valueOf(randomNum)+ "= " + resultInt+randomNum;
            resultInt += randomNum;
            
            
            // Заменить на нормальное вычисление
            serverPlayer.addChatComponentMessage(new ChatComponentText(result));
            */
            return null;
        }
    }

}


StatItem, which send a message by right click

@Override
    public ItemStack onItemRightClick(ItemStack itemstack, World world, EntityPlayer entityplayer) {
        // If нужен, чтобы броить бросок только один раз
        if (world.isRemote) { // TODO: На какой стороне вычисляется бросок?
            //String num = String.valueOf( basicRolls[ Integer.parseInt(itemstack.getIconIndex().toString()) ].dice );
            String statName = StatCollector.translateToLocalFormatted( localePrefix + ".name");
            int lvl = itemstack.getItemDamage();
            
            // TODO ХЗ зачем
            //String str = itemstack.getIconIndex().getIconName();
            //str = str.replaceAll("[^\\d.]", "");
            
            basicRolls.get(lvl).setStatName(statName);
            
            RollPacketToServer rp = new RollPacketToServer(basicRolls.get(lvl));
            INSTANCE.sendToServer(rp); // "123" // itemstack.getIconIndex(
            entityplayer.addChatComponentMessage(new ChatComponentText(basicRolls.get(lvl).dice + " " + statName));
        }
        //entityplayer.addChatComponentMessage(new ChatComponentText(this.roll()));
        
        return itemstack;
        //return super.onItemRightClick(itemstack, world, entityplayer); //To change body of generated methods, choose Tools | Templates.
    }


I am registering a message in CommonProxy.java
 

public void preInit(FMLPreInitializationEvent e, ArrayList<DiceRoll> dices) {
        // Регистрация сообщения о пробросе статы
        INSTANCE.registerMessage(RollPacketToServer.MessageHandler.class, RollPacketToServer.class, 0, Side.SERVER);
        ...
    }


I compared the byte array in toBytes() and fromBytes(). As you can see, they are almost the same:
toBytes output()

59a2961d5db79_(48).png.e6a71928a364fd656c8c883b1674a378.png
 

fromBytes() output:
59a296404a104_(49).png.9587b63d1e12152b14a68cc0e80a2801.png


When I want to run my mod on the server, I get an exception:

Spoiler

17:23:02] [Server thread/ERROR] [FML]: There was a critical exception handling a packet on channel rsstats
java.lang.NullPointerException: diceRollMessage is null
    at ru.rarescrap.network.packets.RollPacketToServer$MessageHandler.onMessage(RollPacketToServer.java:138) ~[RollPacketToServer$MessageHandler.class:?]
    at ru.rarescrap.network.packets.RollPacketToServer$MessageHandler.onMessage(RollPacketToServer.java:127) ~[RollPacketToServer$MessageHandler.class:?]
    at cpw.mods.fml.common.network.simpleimpl.SimpleChannelHandlerWrapper.channelRead0(SimpleChannelHandlerWrapper.java:37) ~[SimpleChannelHandlerWrapper.class:?]
    at cpw.mods.fml.common.network.simpleimpl.SimpleChannelHandlerWrapper.channelRead0(SimpleChannelHandlerWrapper.java:17) ~[SimpleChannelHandlerWrapper.class:?]
    at io.netty.channel.SimpleChannelInboundHandler.channelRead(SimpleChannelInboundHandler.java:98) ~[SimpleChannelInboundHandler.class:?]
    at io.netty.channel.DefaultChannelHandlerContext.invokeChannelRead(DefaultChannelHandlerContext.java:337) ~[DefaultChannelHandlerContext.class:?]
    at io.netty.channel.DefaultChannelHandlerContext.fireChannelRead(DefaultChannelHandlerContext.java:323) ~[DefaultChannelHandlerContext.class:?]
    at io.netty.handler.codec.MessageToMessageDecoder.channelRead(MessageToMessageDecoder.java:103) ~[MessageToMessageDecoder.class:?]
    at io.netty.handler.codec.MessageToMessageCodec.channelRead(MessageToMessageCodec.java:111) ~[MessageToMessageCodec.class:?]
    at io.netty.channel.DefaultChannelHandlerContext.invokeChannelRead(DefaultChannelHandlerContext.java:337) ~[DefaultChannelHandlerContext.class:?]
    at io.netty.channel.DefaultChannelHandlerContext.fireChannelRead(DefaultChannelHandlerContext.java:323) ~[DefaultChannelHandlerContext.class:?]
    at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:785) ~[DefaultChannelPipeline.class:?]
    at io.netty.channel.embedded.EmbeddedChannel.writeInbound(EmbeddedChannel.java:169) ~[EmbeddedChannel.class:?]
    at cpw.mods.fml.common.network.internal.FMLProxyPacket.func_148833_a(FMLProxyPacket.java:77) [FMLProxyPacket.class:?]
    at net.minecraft.network.NetworkManager.func_74428_b(NetworkManager.java:212) [ej.class:?]
    at net.minecraft.network.NetworkSystem.func_151269_c(NetworkSystem.java:165) [nc.class:?]
    at net.minecraft.server.MinecraftServer.func_71190_q(MinecraftServer.java:659) [MinecraftServer.class:?]
    at net.minecraft.server.dedicated.DedicatedServer.func_71190_q(DedicatedServer.java:334) [lt.class:?]
    at net.minecraft.server.MinecraftServer.func_71217_p(MinecraftServer.java:547) [MinecraftServer.class:?]
    at net.minecraft.server.MinecraftServer.run(MinecraftServer.java:427) [MinecraftServer.class:?]
    at net.minecraft.server.MinecraftServer$2.run(MinecraftServer.java:685) [li.class:?]
[17:23:02] [Server thread/INFO] [net.minecraft.network.NetHandlerPlayServer]: RareScrap lost connection: TextComponent{text='A fatal error has occured, this connection is terminated', siblings=[], style=Style{hasParent=false, color=null, bold=null, italic=null, underlined=null, obfuscated=null, clickEvent=null, hoverEvent=null}}
[17:23:02] [Server thread/INFO] [net.minecraft.server.MinecraftServer]: RareScrap left the game

 

 

What am I doing wrong? Why can not I re-create a file in fromBytes?

 

Valuable advice and recommendations are welcome
All files is avalable in my Githab: https://github.com/RareScrap/RSMod---RSBase/tree/RSStats_clickActions/RSStats

 

Link to comment
Share on other sites

  • Guest locked this topic
Guest
This topic is now closed to further replies.

Announcements



×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.