Jump to content

Recommended Posts

Posted

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:

  Reveal hidden contents

 

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

 

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

Announcements



  • Recently Browsing

    • No registered users viewing this page.
  • Posts

    • Hello , when I try to launch the forge installer it just crash with a message for 0,5 secondes. I'm using java 17 to launch it. Here's the link of the error :https://cdn.corenexis.com/view/?img=d/ma24/qs7u4U.jpg  
    • You will find the crash-report or log in your minecraft directory (crash-report or logs folder)
    • Use a modpack which is using these 2 mods as working base:   https://www.curseforge.com/minecraft/modpacks/life-in-the-village-3
    • inicie un mundo donde instale Croptopia y Farmer's Delight, entonces instale el addon Croptopia Delight pero no funciona. es la version 1.18.2
    • Hello all. I'm currently grappling with the updateShape method in a custom class extending Block.  My code currently looks like this: The conditionals in CheckState are there to switch blockstate properties, which is working fine, as it functions correctly every time in getStateForPlacement.  The problem I'm running into is that when I update a state, the blocks seem to call CheckState with the position of the block which was changed updated last.  If I build a wall I can see the same change propagate across. My question thus is this: is updateShape sending its return to the neighbouring block?  Is each block not independently executing the updateShape method, thus inserting its own current position?  The first statement appears to be true, and the second false (each block is not independently executing the method). I have tried to fix this by saving the block's own position to a variable myPos at inception, and then feeding this in as CheckState(myPos) but this causes a worse outcome, where all blocks take the update of the first modified block, rather than just their neighbour.  This raises more questions than it answers, obviously: how is a different instance's variable propagating here?  I also tried changing it so that CheckState did not take a BlockPos, but had myPos built into the body - same problem. I have previously looked at neighbourUpdate and onNeighbourUpdate, but could not find a way to get this to work at all.  One post on here about updatePostPlacement and other methods has proven itself long superceded.  All other sources on the net seem to be out of date. Many thanks in advance for any help you might offer me, it's been several days now of trying to get this work and several weeks of generally trying to get round this roadblock.  - Sandermall
  • Topics

×
×
  • Create New...

Important Information

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