Jump to content

Reliable check if on Server


Raycoms

Recommended Posts

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

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

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

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

This might be a stupid question, but where is the "scan" happening? Is there a way to determine a priori whether one is a source or recipient? Could mod versions contain the scans?

 

What I am suggesting is that there are many ways to skin such a cat, including custom resources located on external servers and fetched/updated at client load time. If you search these forums you should find similar file-distribution discussions within the past year.

The debugger is a powerful and necessary tool in any IDE, so learn how to use it. You'll be able to tell us more and get better help here if you investigate your runtime problems in the debugger before posting.

Link to comment
Share on other sites

@jeffryfisher I didn't really understand what you're trying to ask. The scan happens when the player right clicks with a tool a block.

It will then be stored on his local pc. But to be stored we require server side elements like the serverWorld etc.

 

@diesieben07:

 

I did it like this now:

 

@Override
    public void fromBytes(@NotNull final ByteBuf buf)
    {
        PacketBuffer pb = new PacketBuffer(buf);
        ByteBufInputStream stream = new ByteBufInputStream(pb);

        try
        {
            nbttagcompound = CompressedStreamTools.read(stream, new NBTSizeTracker(200097152L));
        }
        catch (RuntimeException e)
        {
            Log.getLogger().info("Structure too big to be processed", e);
        }
        catch (IOException e)
        {
            Log.getLogger().info("Problem at retrieving structure on server.", e);
        }
        finally
        {
            try
            {
                stream.close();
            }
            catch (IOException e)
            {
                Log.getLogger().info("Problem at retrieving structure on server.", e);
            }
        }

        storeLocation = ByteBufUtils.readUTF8String(buf);
    }

 

and when it get's quite big this now happens:

 

Jan 01, 2017 4:24:44 PM io.netty.channel.ChannelOutboundBuffer safeSuccess
WARNING: Failed to mark a promise as success because it is done already: DefaultChannelPromise@437402(success)
Jan 01, 2017 4:24:44 PM io.netty.channel.ChannelOutboundBuffer safeSuccess
WARNING: Failed to mark a promise as success because it is done already: DefaultChannelPromise@437402(success)
Jan 01, 2017 4:24:44 PM io.netty.channel.ChannelOutboundBuffer safeSuccess
WARNING: Failed to mark a promise as success because it is done already: DefaultChannelPromise@437402(success)
Jan 01, 2017 4:24:44 PM io.netty.channel.ChannelOutboundBuffer safeSuccess
WARNING: Failed to mark a promise as success because it is done already: DefaultChannelPromise@437402(success)
Jan 01, 2017 4:24:44 PM io.netty.channel.ChannelOutboundBuffer safeSuccess
WARNING: Failed to mark a promise as success because it is done already: DefaultChannelPromise@437402(success)
Jan 01, 2017 4:24:44 PM io.netty.channel.ChannelOutboundBuffer safeSuccess
WARNING: Failed to mark a promise as success because it is done already: DefaultChannelPromise@437402(success)
Jan 01, 2017 4:24:44 PM io.netty.channel.ChannelOutboundBuffer safeSuccess
WARNING: Failed to mark a promise as success because it is done already: DefaultChannelPromise@437402(success)
Jan 01, 2017 4:24:44 PM io.netty.channel.ChannelOutboundBuffer safeSuccess
WARNING: Failed to mark a promise as success because it is done already: DefaultChannelPromise@437402(success)
Jan 01, 2017 4:24:44 PM io.netty.channel.ChannelOutboundBuffer safeSuccess
WARNING: Failed to mark a promise as success because it is done already: DefaultChannelPromise@437402(success)
[16:24:44] [Netty Local Client IO #0/INFO] [Minecolonies:blockout]: Structure too big to be processed
java.lang.NullPointerException
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.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 com.minecolonies.coremod.network.messages.SaveScanMessage.fromBytes(SaveScanMessage.java:57) [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]
at io.netty.handler.codec.MessageToMessageCodec.channelRead(MessageToMessageCodec.java:111) [MessageToMessageCodec.class:4.0.23.Final]
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:333) [AbstractChannelHandlerContext.class:4.0.23.Final]
at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:319) [AbstractChannelHandlerContext.class:4.0.23.Final]
at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:787) [DefaultChannelPipeline.class:4.0.23.Final]
at io.netty.channel.embedded.EmbeddedChannel.writeInbound(EmbeddedChannel.java:169) [EmbeddedChannel.class:4.0.23.Final]
at net.minecraftforge.fml.common.network.internal.FMLProxyPacket.processPacket(FMLProxyPacket.java:109) [FMLProxyPacket.class:?]
at net.minecraft.network.NetworkManager.channelRead0(NetworkManager.java:156) [NetworkManager.class:?]
at net.minecraft.network.NetworkManager.channelRead0(NetworkManager.java:51) [NetworkManager.class:?]
at io.netty.channel.SimpleChannelInboundHandler.channelRead(SimpleChannelInboundHandler.java:105) [simpleChannelInboundHandler.class:4.0.23.Final]
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:333) [AbstractChannelHandlerContext.class:4.0.23.Final]
at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:319) [AbstractChannelHandlerContext.class:4.0.23.Final]
at net.minecraftforge.fml.common.network.handshake.NetworkDispatcher.handleClientSideCustomPacket(NetworkDispatcher.java:413) [NetworkDispatcher.class:?]
at net.minecraftforge.fml.common.network.handshake.NetworkDispatcher.channelRead0(NetworkDispatcher.java:278) [NetworkDispatcher.class:?]
at net.minecraftforge.fml.common.network.handshake.NetworkDispatcher.channelRead0(NetworkDispatcher.java:73) [NetworkDispatcher.class:?]
at io.netty.channel.SimpleChannelInboundHandler.channelRead(SimpleChannelInboundHandler.java:105) [simpleChannelInboundHandler.class:4.0.23.Final]
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:333) [AbstractChannelHandlerContext.class:4.0.23.Final]
at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:319) [AbstractChannelHandlerContext.class:4.0.23.Final]
at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:787) [DefaultChannelPipeline.class:4.0.23.Final]
at io.netty.channel.local.LocalChannel.finishPeerRead(LocalChannel.java:326) [LocalChannel.class:4.0.23.Final]
at io.netty.channel.local.LocalChannel.access$400(LocalChannel.java:45) [LocalChannel.class:4.0.23.Final]
at io.netty.channel.local.LocalChannel$5.run(LocalChannel.java:312) [LocalChannel$5.class:4.0.23.Final]
at io.netty.channel.local.LocalEventLoop.run(LocalEventLoop.java:33) [LocalEventLoop.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]

 

Using forge version:

 

forge_version=13.19.1.2189

 

 

 

Link to comment
Share on other sites

There is:         

 

 nbtbase.read(input, depth, sizeTracker);

 

and nbtbase is empty.

 

He creates nbtbase previously with:

        NBTBase nbtbase = NBTBase.createNewByType(id);

 

with the id: 9

 

 

I also removed the PacketBuffer, didn't change anything.

And we're closing the stream because we like to clean it up.

Link to comment
Share on other sites

Ouch still forgetting that try with exists =D.

 

    @Override
    public void fromBytes(@NotNull final ByteBuf buf)
    {
        try(ByteBufInputStream stream = new ByteBufInputStream(buf)
        {
            nbttagcompound = CompressedStreamTools.read(stream, new NBTSizeTracker(200097152L));
        }
        catch (RuntimeException e)
        {
            Log.getLogger().info("Structure too big to be processed", e);
        }
        catch (IOException e)
        {
            Log.getLogger().info("Problem at retrieving structure on server.", e);
        }
        //storeLocation = ByteBufUtils.readUTF8String(buf);
    }

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

 

I noticed that the problem is that I'm writing a string afterward. Therefore he is trying to create a tag out of the string during the execution and that's what nulls nbttag.

 

But how can I prevent that from happening?

Before isn't an option either.

 

The only option is sending two separate messages?

 

Link to comment
Share on other sites

@Override
    public void fromBytes(@NotNull final ByteBuf buf)
    {
        PacketBuffer buffer = new PacketBuffer(buf);
        int i =  buffer.readerIndex();
        byte b0 = buffer.readByte();
        if(b0 != 0)
        {
            buffer.readerIndex(i);
            try (ByteBufInputStream stream = new ByteBufInputStream(buffer)
            {
                nbttagcompound = CompressedStreamTools.read(stream, new NBTSizeTracker(200097152L));
            }
            catch (RuntimeException e)
            {
                Log.getLogger().info("Structure too big to be processed", e);
            }
            catch (IOException e)
            {
                Log.getLogger().info("Problem at retrieving structure on server.", e);
            }
        }
        storeLocation = ByteBufUtils.readUTF8String(buf);
    }

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

 

 

Did I forget anything? Still not working...

Link to comment
Share on other sites

You said I should do it like in the PacketBuffer, therefore, I moved everything whats happening there also into my method.

(I'd eventually rename these variables).

 

aand don't I have to create a big limit to make sure my structures are stored correctly? =D

 

2mb is the standard size but that wasn't enough obviously.

Link to comment
Share on other sites

You said I should do it like in the PacketBuffer, therefore, I moved everything whats happening there also into my method.

(I'd eventually rename these variables).

 

aand don't I have to create a big limit to make sure my structures are stored correctly? =D

 

2mb is the standard size but that wasn't enough obviously.

I want to say this imposes the limit.

NBTSizeTracker(200097152L))

VANILLA MINECRAFT CLASSES ARE THE BEST RESOURCES WHEN MODDING

I will be posting 1.15.2 modding tutorials on this channel. If you want to be notified of it do the normal YouTube stuff like subscribing, ect.

Forge and vanilla BlockState generator.

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
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
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.

Announcements



×
×
  • Create New...

Important Information

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