maruohon / litematica

A modern client-side schematic mod for Minecraft
GNU Lesser General Public License v3.0
730 stars 220 forks source link

Issue with easy place features #420

Open fsrastdyyf opened 3 years ago

fsrastdyyf commented 3 years ago

I'm having trouble with the easy place mod feature. Whenever I use it by placing some types of blocks (repeater, observer, etc.) the blocks are not placed on the server, and when exiting and re-entering the blocks there are no

maruohon commented 3 years ago

What type of server is it? If it's a Spigot or Paper based server, it might have anti-cheat which prevents clicking on air blocks, which is how the Easy Place mode works.

fsrastdyyf commented 3 years ago

Oh, yea... it's a Paper server.... Is there any method to disable it? until a few days ago this error did not occur. What can I recommend to the creator of the server, to make the Litematic usable?

maruohon commented 3 years ago

Only the 1.12.2 version currently has the improved Easy Place code which has an option to only click on existing adjacent blocks. So you can't disable that behavior in the 1.13+ versions yet. As for the server, I have no idea where and by what name the option would be. But it's some kind of check for how/where the player is clicking, that the vanilla game does not do/care about.

itsBeaco commented 3 years ago

I also have this issue. If you find the setting, please let me know :) I will do the same

cqjdzy commented 3 years ago

i also have this problem with the easy place feature,whenever i use it by placing blocks such as stairs,those blocks are not placed on the server,and they are not when i exit and re-enter them.

Tiypo1337 commented 3 years ago

Some mods on my Paper server have narrowed down the EasyPlace client desync (such as stairs not being placed) to this Paper commit. https://github.com/PaperMC/Paper/pull/6591

Litematica works fine on server versions before the commit and has issues with EasyPlace after.

maruohon commented 3 years ago

Oh yeah I had forgotten that I think the Easy Place mode currently uses a reach distance of 6 instead of the normal 4.5 that vanilla uses. I should make that an option you can toggle off.

mms0316 commented 3 years ago

Just adding a note here that even if you are 1 block away, the server rejects easyPlace's attempt to place some types of blocks (stairs, repeaters, observers). It also doesn't matter if the schematic block is in air or on the ground.

However, fiddling with some configurations, if Schematic Rendering is turned off (M + G) and easyPlaceFirst is configured to false, those blocks can be placed.

Also, in survival, it seems you can place stairs if you are 4 blocks away from the schematic block.

Looking at the Paper patch, it is now validating movingobjectpositionblock.getLocation(). I'm not sure, but I think this translates in Litematica to the BlockHitResult object that is passed to mc.interactionManager.interactBlock

maruohon commented 3 years ago

Oh yeah if it's checking the x coordinate of the hit vector, then it can be "out of reach" in many cases, especially with blocks that have a rotation, because the Easy Place mode uses the so-called "Accurate Block Placement protocol" that Carpet mod introduced around 1.11 or 1.12 or whatever. The protocol basically encodes the requested block rotation and possibly some other properties (such as placing a trapdoor in the open state) into the hit vector x coordinate (on the client this is done by a mod such as Carpet Client, Tweakeroo or Litematica). Normally the vanilla server does not use that relative x value for almost anything. The protocol is also implemented such that it is possible to still give the vanilla code the correct relative hit position, but that obviously would need a server-side mod to strip away that extra encoded information, which would not happen for example on a Paper server.

So I might then need to add an option to not apply the accurate placement protocol at all. But that would mean that none of the blocks would get auto-oriented. Then again on a Paper server where that option would be relevant that would not happen anyway...

mms0316 commented 3 years ago

I compiled Litematica commenting out the code block below and Paper stopped rejecting the blocks:

                // Carpet Accurate Placement protocol support, plus BlockSlab support
                if (Configs.Generic.EASY_PLACE_PROTOCOL_V3.getBooleanValue())
                {
                    hitPos = applyPlacementProtocolV3(pos, stateSchematic, hitPos);
                }
                else
                {
                    hitPos = applyCarpetProtocolHitVec(pos, stateSchematic, hitPos);
                }

Having an option to disable that extra encoding information would indeed be useful for Paper servers. Even before this patch, I know I had to disable easyPlace to be able to place certain doors and trapdoors to match the exact block state.

aria1th commented 3 years ago

by not applying protocol, so its just hitPos. I'll try some additional checks for paper, it would be just one option. It will be great if there's some way to know if server is using protocol or not tho.

aria1th commented 3 years ago
                if (!Objects.equals(mc.player.getServerBrand(), "fabric")){

                }
                else if (Configs.Generic.EASY_PLACE_PROTOCOL_V3.getBooleanValue())
                {
                    //System.out.println("applied v3");
                    hitPos = applyPlacementProtocolV3(pos, stateSchematic, hitPos);
                }
                else
                {
                    //System.out.println("applied v2");
                    hitPos = applyCarpetProtocolHitVec(pos, stateSchematic, hitPos);
                }

can do something like this, it will not apply protocol when its not fabric server. usually its performance difference is not really noticeable unless you're doing wierd stuff.

rozatoo commented 3 years ago

I compiled Litematica commenting out the code block below and Paper stopped rejecting the blocks:

                // Carpet Accurate Placement protocol support, plus BlockSlab support
                if (Configs.Generic.EASY_PLACE_PROTOCOL_V3.getBooleanValue())
                {
                    hitPos = applyPlacementProtocolV3(pos, stateSchematic, hitPos);
                }
                else
                {
                    hitPos = applyCarpetProtocolHitVec(pos, stateSchematic, hitPos);
                }

Having an option to disable that extra encoding information would indeed be useful for Paper servers. Even before this patch, I know I had to disable easyPlace to be able to place certain doors and trapdoors to match the exact block state.

In which file did you comment that out?

aria1th commented 3 years ago

its on utils/WorldUtils.java

rozatoo commented 3 years ago

its on utils/WorldUtils.java

In https://github.com/maruohon/litematica/blob/master/src/main/java/fi/dy/masa/litematica/util/WorldUtils.java? Can't find that code block in there? What am I doing wrong haha

aria1th commented 3 years ago

https://github.com/maruohon/litematica/blob/temp_1.17_update/src/main/java/fi/dy/masa/litematica/util/WorldUtils.java#L496

you're looking at wrong branch

rozatoo commented 3 years ago

I compiled Litematica commenting out the code block below and Paper stopped rejecting the blocks:

                // Carpet Accurate Placement protocol support, plus BlockSlab support
                if (Configs.Generic.EASY_PLACE_PROTOCOL_V3.getBooleanValue())
                {
                    hitPos = applyPlacementProtocolV3(pos, stateSchematic, hitPos);
                }
                else
                {
                    hitPos = applyCarpetProtocolHitVec(pos, stateSchematic, hitPos);
                }

Having an option to disable that extra encoding information would indeed be useful for Paper servers. Even before this patch, I know I had to disable easyPlace to be able to place certain doors and trapdoors to match the exact block state.

With this implemented Easy Place Mode still doesn't work when you're pressing shift and building. Is there a fix that might make it work when you're pressing shift as well?

mms0316 commented 3 years ago

With this implemented Easy Place Mode still doesn't work when you're pressing shift and building. Is there a fix that might make it work when you're pressing shift as well?

As of versions 0903+, something changed regarding extra keys. Go to Configuration menu > Hotkeys. In easyPlaceUseKey, click on the image button before 'RESET', and change Allow extra keys to true.

mms0316 commented 3 years ago

Oh yeah I had forgotten that I think the Easy Place mode currently uses a reach distance of 6 instead of the normal 4.5 that vanilla uses. I should make that an option you can toggle off.

I've tested and changing from 6 to 4.5 is also very helpful, as Paper also rejects blocks placed far (even before this patch).

mms0316 commented 3 years ago

I compiled Litematica commenting out the code block below and Paper stopped rejecting the blocks:

                // Carpet Accurate Placement protocol support, plus BlockSlab support
                if (Configs.Generic.EASY_PLACE_PROTOCOL_V3.getBooleanValue())
                {
                    hitPos = applyPlacementProtocolV3(pos, stateSchematic, hitPos);
                }
                else
                {
                    hitPos = applyCarpetProtocolHitVec(pos, stateSchematic, hitPos);
                }

Having an option to disable that extra encoding information would indeed be useful for Paper servers. Even before this patch, I know I had to disable easyPlace to be able to place certain doors and trapdoors to match the exact block state.

I've noted that placing top slabs from below become bottom slabs (therefore triggering wrong state). I suppose the code below from applyCarpetProtocolHitVec would be needed, as it only shifts 0.9 in the Y coordinate:

        else if (block instanceof SlabBlock && state.get(SlabBlock.TYPE) != SlabType.DOUBLE)
        {
            //x += 10; // Doesn't actually exist (yet?)

            // Do it via vanilla
            if (state.get(SlabBlock.TYPE) == SlabType.TOP)
            {
                y = pos.getY() + 0.9;
            }
            else
            {
                y = pos.getY();
            }
        }
mms0316 commented 3 years ago

I did a screw up on PR #422 (merging into master instead of the 1.17 branch), hopefully that can be fixed?

mms0316 commented 3 years ago

Could you please share an official link containing these fixes? Thanks

mms0316 commented 2 years ago

This issue is resolved, as of versions litematica-fabric-1.17.1-0.0.0-dev.20211201.000016.jar / litematica-fabric-1.17.1-0.0.0-dev.20211203.010230.jar