Jump to content

Recommended Posts

Posted

That way I only know the side, I don't know if it's running on the "server side" of the client or on the "server itself".

I also don't have a world object at the code line I need it.

Posted

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.

Posted

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.

Posted

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?

Posted

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.

Posted

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]

Posted

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?

Posted

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]

Posted

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.

Posted

@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

 

 

 

Posted

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.

Posted

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?

 

Posted

@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...

Posted

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.

Posted

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.

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



  • Recently Browsing

    • No registered users viewing this page.
  • Posts

    • Version 1.19 - Forge 41.0.63 I want to create a wolf entity that I can ride, so far it seems to be working, but the problem is that when I get on the wolf, I can’t control it. I then discovered that the issue is that the server doesn’t detect that I’m riding the wolf, so I’m struggling with synchronization. However, it seems to not be working properly. As I understand it, the server receives the packet but doesn’t register it correctly. I’m a bit new to Java, and I’ll try to provide all the relevant code and prints *The comments and prints are translated by chatgpt since they were originally in Spanish* Thank you very much in advance No player is mounted, or the passenger is not a player. No player is mounted, or the passenger is not a player. No player is mounted, or the passenger is not a player. No player is mounted, or the passenger is not a player. No player is mounted, or the passenger is not a player. MountableWolfEntity package com.vals.valscraft.entity; import com.vals.valscraft.network.MountSyncPacket; import com.vals.valscraft.network.NetworkHandler; import net.minecraft.client.Minecraft; import net.minecraft.network.syncher.EntityDataAccessor; import net.minecraft.network.syncher.EntityDataSerializers; import net.minecraft.network.syncher.SynchedEntityData; import net.minecraft.server.MinecraftServer; import net.minecraft.server.level.ServerPlayer; import net.minecraft.world.entity.EntityType; import net.minecraft.world.entity.Mob; import net.minecraft.world.entity.ai.attributes.AttributeSupplier; import net.minecraft.world.entity.ai.attributes.Attributes; import net.minecraft.world.entity.animal.Wolf; import net.minecraft.world.entity.player.Player; import net.minecraft.world.entity.Entity; import net.minecraft.world.InteractionHand; import net.minecraft.world.InteractionResult; import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.Items; import net.minecraft.world.level.Level; import net.minecraft.world.phys.Vec3; import net.minecraftforge.event.TickEvent; import net.minecraftforge.eventbus.api.SubscribeEvent; import net.minecraftforge.network.PacketDistributor; public class MountableWolfEntity extends Wolf { private boolean hasSaddle; private static final EntityDataAccessor<Byte> DATA_ID_FLAGS = SynchedEntityData.defineId(MountableWolfEntity.class, EntityDataSerializers.BYTE); public MountableWolfEntity(EntityType<? extends Wolf> type, Level level) { super(type, level); this.hasSaddle = false; } @Override protected void defineSynchedData() { super.defineSynchedData(); this.entityData.define(DATA_ID_FLAGS, (byte)0); } public static AttributeSupplier.Builder createAttributes() { return Wolf.createAttributes() .add(Attributes.MAX_HEALTH, 20.0) .add(Attributes.MOVEMENT_SPEED, 0.3); } @Override public InteractionResult mobInteract(Player player, InteractionHand hand) { ItemStack itemstack = player.getItemInHand(hand); if (itemstack.getItem() == Items.SADDLE && !this.hasSaddle()) { if (!player.isCreative()) { itemstack.shrink(1); } this.setSaddle(true); return InteractionResult.SUCCESS; } else if (!level.isClientSide && this.hasSaddle()) { player.startRiding(this); MountSyncPacket packet = new MountSyncPacket(true); // 'true' means the player is mounted NetworkHandler.CHANNEL.sendToServer(packet); // Ensure the server handles the packet return InteractionResult.SUCCESS; } return InteractionResult.PASS; } @Override public void travel(Vec3 travelVector) { if (this.isVehicle() && this.getControllingPassenger() instanceof Player) { System.out.println("The wolf has a passenger."); System.out.println("The passenger is a player."); Player player = (Player) this.getControllingPassenger(); // Ensure the player is the controller this.setYRot(player.getYRot()); this.yRotO = this.getYRot(); this.setXRot(player.getXRot() * 0.5F); this.setRot(this.getYRot(), this.getXRot()); this.yBodyRot = this.getYRot(); this.yHeadRot = this.yBodyRot; float forward = player.zza; float strafe = player.xxa; if (forward <= 0.0F) { forward *= 0.25F; } this.flyingSpeed = this.getSpeed() * 0.1F; this.setSpeed((float) this.getAttributeValue(Attributes.MOVEMENT_SPEED) * 1.5F); this.setDeltaMovement(new Vec3(strafe, travelVector.y, forward).scale(this.getSpeed())); this.calculateEntityAnimation(this, false); } else { // The wolf does not have a passenger or the passenger is not a player System.out.println("No player is mounted, or the passenger is not a player."); super.travel(travelVector); } } public boolean hasSaddle() { return this.hasSaddle; } public void setSaddle(boolean hasSaddle) { this.hasSaddle = hasSaddle; } @Override protected void dropEquipment() { super.dropEquipment(); if (this.hasSaddle()) { this.spawnAtLocation(Items.SADDLE); this.setSaddle(false); } } @SubscribeEvent public static void onServerTick(TickEvent.ServerTickEvent event) { if (event.phase == TickEvent.Phase.START) { MinecraftServer server = net.minecraftforge.server.ServerLifecycleHooks.getCurrentServer(); if (server != null) { for (ServerPlayer player : server.getPlayerList().getPlayers()) { if (player.isPassenger() && player.getVehicle() instanceof MountableWolfEntity) { MountableWolfEntity wolf = (MountableWolfEntity) player.getVehicle(); System.out.println("Tick: " + player.getName().getString() + " is correctly mounted on " + wolf); } } } } } private boolean lastMountedState = false; @Override public void tick() { super.tick(); if (!this.level.isClientSide) { // Only on the server boolean isMounted = this.isVehicle() && this.getControllingPassenger() instanceof Player; // Only print if the state changed if (isMounted != lastMountedState) { if (isMounted) { Player player = (Player) this.getControllingPassenger(); // Verify the passenger is a player System.out.println("Server: Player " + player.getName().getString() + " is now mounted."); } else { System.out.println("Server: The wolf no longer has a passenger."); } lastMountedState = isMounted; } } } @Override public void addPassenger(Entity passenger) { super.addPassenger(passenger); if (passenger instanceof Player) { Player player = (Player) passenger; if (!this.level.isClientSide && player instanceof ServerPlayer) { // Send the packet to the server to indicate the player is mounted NetworkHandler.CHANNEL.send(PacketDistributor.PLAYER.with(() -> (ServerPlayer) player), new MountSyncPacket(true)); } } } @Override public void removePassenger(Entity passenger) { super.removePassenger(passenger); if (passenger instanceof Player) { Player player = (Player) passenger; if (!this.level.isClientSide && player instanceof ServerPlayer) { // Send the packet to the server to indicate the player is no longer mounted NetworkHandler.CHANNEL.send(PacketDistributor.PLAYER.with(() -> (ServerPlayer) player), new MountSyncPacket(false)); } } } @Override public boolean isControlledByLocalInstance() { Entity entity = this.getControllingPassenger(); return entity instanceof Player; } @Override public void positionRider(Entity passenger) { if (this.hasPassenger(passenger)) { double xOffset = Math.cos(Math.toRadians(this.getYRot() + 90)) * 0.4; double zOffset = Math.sin(Math.toRadians(this.getYRot() + 90)) * 0.4; passenger.setPos(this.getX() + xOffset, this.getY() + this.getPassengersRidingOffset() + passenger.getMyRidingOffset(), this.getZ() + zOffset); } } } MountSyncPacket package com.vals.valscraft.network; import com.vals.valscraft.entity.MountableWolfEntity; import net.minecraft.network.FriendlyByteBuf; import net.minecraft.server.level.ServerLevel; import net.minecraft.server.level.ServerPlayer; import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.player.Player; import net.minecraftforge.network.NetworkEvent; import java.util.function.Supplier; public class MountSyncPacket { private final boolean isMounted; public MountSyncPacket(boolean isMounted) { this.isMounted = isMounted; } public void encode(FriendlyByteBuf buffer) { buffer.writeBoolean(isMounted); } public static MountSyncPacket decode(FriendlyByteBuf buffer) { return new MountSyncPacket(buffer.readBoolean()); } public void handle(NetworkEvent.Context context) { context.enqueueWork(() -> { ServerPlayer player = context.getSender(); // Get the player from the context if (player != null) { // Verifies if the player has dismounted if (!isMounted) { Entity vehicle = player.getVehicle(); if (vehicle instanceof MountableWolfEntity wolf) { // Logic to remove the player as a passenger wolf.removePassenger(player); System.out.println("Server: Player " + player.getName().getString() + " is no longer mounted."); } } } }); context.setPacketHandled(true); // Marks the packet as handled } } networkHandler package com.vals.valscraft.network; import com.vals.valscraft.valscraft; import net.minecraft.resources.ResourceLocation; import net.minecraftforge.network.NetworkRegistry; import net.minecraftforge.network.simple.SimpleChannel; import net.minecraftforge.network.NetworkEvent; import java.util.function.Supplier; public class NetworkHandler { private static final String PROTOCOL_VERSION = "1"; public static final SimpleChannel CHANNEL = NetworkRegistry.newSimpleChannel( new ResourceLocation(valscraft.MODID, "main"), () -> PROTOCOL_VERSION, PROTOCOL_VERSION::equals, PROTOCOL_VERSION::equals ); public static void init() { int packetId = 0; // Register the mount synchronization packet CHANNEL.registerMessage( packetId++, MountSyncPacket.class, MountSyncPacket::encode, MountSyncPacket::decode, (msg, context) -> msg.handle(context.get()) // Get the context with context.get() ); } }  
    • Do you use features of inventory profiles next (ipnext) or is there a change without it?
    • Remove rubidium - you are already using embeddium, which is a fork of rubidium
  • Topics

×
×
  • Create New...

Important Information

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