Jump to content
Search In
  • More options...
Find results that contain...
Find results in...

Reliable check if on Server


Raycoms
 Share

Recommended Posts

  • Replies 62
  • Created
  • Last Reply

Top Posters In This Topic

The question is: why?

Apparently I'm a complete and utter jerk and come to this forum just like to make fun of people, be confrontational, and make your personal life miserable.  If you think this is the case, JUST REPORT ME.  Otherwise you're just going to get reported when you reply to my posts and point it out, because odds are, I was trying to be nice.

 

Exception: If you do not understand Java, I WILL NOT HELP YOU and your thread will get locked.

 

DO NOT PM ME WITH PROBLEMS. No help will be given.

Link to comment
Share on other sites

We're storing scanned buildings and structures to the client.

If the player plays on the server -> store in client directory. (Requires messaging and messages have a max size).

If the players plays in ssp -> No need to send a message, store directly, no max size.

Link to comment
Share on other sites

Note that if you do this your storage needs to be threadsafe, as there both client and server accessing it. You really need to know what you are doing if you do this. Most of the time you want separate storage for client and server, even in single player.

 

If you really want to, you can check if the player is the player hosting the single player server using

EntityPlayer::getName().equals(FMLCommonHandler.instance().getMinecraftServerInstance().getServerOwner())

.

Link to comment
Share on other sites

The Problem is that the max message size is pretty small if I want to send the big structures.

But I really only need to send the scanned structure from the server to the client if the client plays on a server.

Else I can store it on disk directly from the server thread in "on item use".

It's important that on the server these files don't get stored on the server (Could litter the server).

 

What does this "getServerOwner" return when the client plays on a real server?

Link to comment
Share on other sites

The Problem is that the max message size is pretty small if I want to send the big structures.
The maximum packet size for server to client packets is roughly 267 Megabytes. Why is this not enough for you? :o

 

What does this "getServerOwner" return when the client plays on a real server?
This has nothing to do with the client. This method is entirely serverside. For a server that is not an integrated server this method will return
null

.

Link to comment
Share on other sites

Hmm the message shouldn't be even close to this size.

But it always crashes during execution when the size reaches a certain limit:

 

private static void saveStructure(@Nullable final World world, @Nullable final BlockPos from, @Nullable final BlockPos to, @NotNull final EntityPlayer player)
    {
        if (world == null || from == null || to == null)
        {
            throw new IllegalArgumentException("Invalid method call, arguments can't be null. Contact a developer.");
        }

        final BlockPos blockpos =
          new BlockPos(Math.min(from.getX(), to.getX()), Math.min(from.getY(), to.getY()), Math.min(from.getZ(), to.getZ()));
        final BlockPos blockpos1 =
          new BlockPos(Math.max(from.getX(), to.getX()), Math.max(from.getY(), to.getY()), Math.max(from.getZ(), to.getZ()));
        final BlockPos size = blockpos1.subtract(blockpos).add(1, 1, 1);

        final WorldServer worldserver = (WorldServer) world;
        final MinecraftServer minecraftserver = world.getMinecraftServer();
        final TemplateManager templatemanager = worldserver.getStructureTemplateManager();

        final String currentMillis = Long.toString(System.currentTimeMillis());
        final String fileName = "/minecolonies/scans/" + LanguageHandler.format("item.scepterSteel.scanFormat", "", currentMillis + ".nbt");

        final Template template = templatemanager.getTemplate(minecraftserver, new ResourceLocation(fileName));
        template.takeBlocksFromWorld(world, blockpos, size, true, Blocks.STRUCTURE_VOID);
        template.setAuthor(Constants.MOD_ID);
        
        MineColonies.getNetwork().sendTo(new SaveScanMessage(template.writeToNBT(new NBTTagCompound()), fileName), (EntityPlayerMP) player);
    }

 

 

/**
* Handles sendScanMessages.
*/
public class SaveScanMessage implements IMessage, IMessageHandler<SaveScanMessage, IMessage>
{
    private NBTTagCompound nbttagcompound;
    private String         storeLocation;

    /**
     * Public standard constructor.
     */
    public SaveScanMessage()
    {
        super();
    }

    /**
     * Send a scan compound to the client.
     *
     * @param nbttagcompound the stream.
     * @param storeAt        string describing where to store the scan.
     */
    public SaveScanMessage(final NBTTagCompound nbttagcompound, final String storeAt)
    {
        this.nbttagcompound = nbttagcompound;
        this.storeLocation = storeAt;
    }

    @Override
    public void fromBytes(@NotNull final ByteBuf buf)
    {
        nbttagcompound = ByteBufUtils.readTag(buf);
        storeLocation = ByteBufUtils.readUTF8String(buf);
    }

    @Override
    public void toBytes(@NotNull final ByteBuf buf)
    {
        ByteBufUtils.writeTag(buf, nbttagcompound);
        ByteBufUtils.writeUTF8String(buf, storeLocation);
    }

    @Nullable
    @Override
    public IMessage onMessage(@NotNull final SaveScanMessage message, final MessageContext ctx)
    {
        ClientStructureWrapper.handleSaveScanMessage(message.nbttagcompound, message.storeLocation);
        return null;
    }

 

 

/**
     * Handles the save message of scans.
     *
     * @param nbttagcompound compound to store.
     * @param storeLocation  where to store it at.
     */
    public static void handleSaveScanMessage(final NBTTagCompound nbttagcompound, final String storeLocation)
    {
        final File file = new File(Minecraft.getMinecraft().mcDataDir, storeLocation);
        createScanDirectory(Minecraft.getMinecraft().world);

        try (OutputStream outputstream = new FileOutputStream(file))
        {
            CompressedStreamTools.writeCompressed(nbttagcompound, outputstream);
        }
        catch (final IOException e)
        {
            LanguageHandler.sendPlayerLocalizedMessage(Minecraft.getMinecraft().player, LanguageHandler.format("item.scepterSteel.scanFailure"));
            Log.getLogger().warn("Exception while trying to scan.", e);
            return;
        }

        LanguageHandler.sendPlayerLocalizedMessage(Minecraft.getMinecraft().player,
          LanguageHandler.format("item.scepterSteel.scanSuccess", storeLocation));
    }

 

It usually seems to crash during the message sending because it can't be backtracked to any of our code. (In the exception our code doesn't appear).

 

I will try to reproduce the exception in a moment.

Link to comment
Share on other sites

Now it worked. Problem seems to be the "readTag"

 

Caused by: java.lang.RuntimeException: Tried to read NBT tag that was too big; tried to allocate: 2097156bytes where max allowed: 2097152
at net.minecraft.nbt.NBTSizeTracker.read(NBTSizeTracker.java:31) ~[NBTSizeTracker.class:?]
at net.minecraft.nbt.NBTTagCompound.read(NBTTagCompound.java:51) ~[NBTTagCompound.class:?]
at net.minecraft.nbt.NBTTagList.read(NBTTagList.java:66) ~[NBTTagList.class:?]
at net.minecraft.nbt.NBTTagCompound.readNBT(NBTTagCompound.java:578) ~[NBTTagCompound.class:?]
at net.minecraft.nbt.NBTTagCompound.read(NBTTagCompound.java:52) ~[NBTTagCompound.class:?]
at net.minecraft.nbt.CompressedStreamTools.read(CompressedStreamTools.java:147) ~[CompressedStreamTools.class:?]
at net.minecraft.nbt.CompressedStreamTools.read(CompressedStreamTools.java:102) ~[CompressedStreamTools.class:?]
at net.minecraft.network.PacketBuffer.readCompoundTag(PacketBuffer.java:341) ~[PacketBuffer.class:?]
at net.minecraftforge.fml.common.network.ByteBufUtils.readTag(ByteBufUtils.java:211) ~[byteBufUtils.class:?]
at com.minecolonies.coremod.network.messages.SaveScanMessage.fromBytes(SaveScanMessage.java:44) ~[saveScanMessage.class:?]
at net.minecraftforge.fml.common.network.simpleimpl.SimpleIndexedCodec.decodeInto(SimpleIndexedCodec.java:36) ~[simpleIndexedCodec.class:?]
at net.minecraftforge.fml.common.network.simpleimpl.SimpleIndexedCodec.decodeInto(SimpleIndexedCodec.java:26) ~[simpleIndexedCodec.class:?]
at net.minecraftforge.fml.common.network.FMLIndexedMessageToMessageCodec.decode(FMLIndexedMessageToMessageCodec.java:103) ~[FMLIndexedMessageToMessageCodec.class:?]
at net.minecraftforge.fml.common.network.FMLIndexedMessageToMessageCodec.decode(FMLIndexedMessageToMessageCodec.java:40) ~[FMLIndexedMessageToMessageCodec.class:?]
at io.netty.handler.codec.MessageToMessageCodec$2.decode(MessageToMessageCodec.java:81) ~[MessageToMessageCodec$2.class:4.0.23.Final]
at io.netty.handler.codec.MessageToMessageDecoder.channelRead(MessageToMessageDecoder.java:89) ~[MessageToMessageDecoder.class:4.0.23.Final]

Link to comment
Share on other sites

Your problem is not the message size limit, your problem is that you are trying to read an

NBTTagCompound

, which is limited to about 2 megabytes per compound when using

ByteBufUtils.readTag

(resp.

PacketBuffer::readCompoundTag

).

Either do it yourself (check the code in

PacketBuffer

for how) or use a different format than a giant

NBTTagCompound

.

Link to comment
Share on other sites

The Problem is that I have the Minecraft "Template" object which is, as far as I know, not serializable in a normal way, only through the nbttagcompound.

and I didn't understand. I will have to copy the "NBTTAGCompound to byte code" and make it usable for sizes > 2mb?

Link to comment
Share on other sites

I thought I have fixed it but now:

 

[21:28:25] [Netty Server IO #1/ERROR] [FML]: NetworkDispatcher exception
java.lang.IllegalArgumentException: Payload may not be larger than 1048576 bytes
at net.minecraft.network.play.server.SPacketCustomPayload.<init>(SPacketCustomPayload.java:27) ~[sPacketCustomPayload.class:?]
at net.minecraftforge.fml.common.network.internal.FMLProxyPacket.toS3FPackets(FMLProxyPacket.java:165) ~[FMLProxyPacket.class:?]
at net.minecraftforge.fml.common.network.handshake.NetworkDispatcher.write(NetworkDispatcher.java:534) ~[NetworkDispatcher.class:?]
at io.netty.channel.AbstractChannelHandlerContext.invokeWrite(AbstractChannelHandlerContext.java:658) ~[AbstractChannelHandlerContext.class:4.0.23.Final]
at io.netty.channel.AbstractChannelHandlerContext.write(AbstractChannelHandlerContext.java:716) ~[AbstractChannelHandlerContext.class:4.0.23.Final]
at io.netty.channel.AbstractChannelHandlerContext.writeAndFlush(AbstractChannelHandlerContext.java:706) ~[AbstractChannelHandlerContext.class:4.0.23.Final]
at io.netty.channel.AbstractChannelHandlerContext.writeAndFlush(AbstractChannelHandlerContext.java:741) ~[AbstractChannelHandlerContext.class:4.0.23.Final]
at io.netty.channel.DefaultChannelPipeline.writeAndFlush(DefaultChannelPipeline.java:895) ~[DefaultChannelPipeline.class:4.0.23.Final]
at io.netty.channel.AbstractChannel.writeAndFlush(AbstractChannel.java:240) ~[AbstractChannel.class:4.0.23.Final]
at net.minecraft.network.NetworkManager$4.run(NetworkManager.java:262) [NetworkManager$4.class:?]
at io.netty.util.concurrent.SingleThreadEventExecutor.runAllTasks(SingleThreadEventExecutor.java:380) [singleThreadEventExecutor.class:4.0.23.Final]
at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:357) [NioEventLoop.class:4.0.23.Final]
at io.netty.util.concurrent.SingleThreadEventExecutor$2.run(SingleThreadEventExecutor.java:116) [singleThreadEventExecutor$2.class:4.0.23.Final]
at java.lang.Thread.run(Thread.java:745) [?:1.8.0_112]

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

 Share

×
×
  • Create New...

Important Information

By using this site, you agree to our Privacy Policy.