Root of setBlock()

Hey,
today I tried to place some blocks with sponge.
Example:

Location location = new Location(world, block.getX(), block.getY(), block.getZ());
location.setBlock(Sponge.getRegistry().getType(BlockType.class, "minecraft:air").get().getDefaultState());

this code sets a new minecraft:air block in at x,y,z cords → works fine.

An unwanted effect is, that the root / cause of this action is a player. How can I change this? I don’t want to fire following method / event when I do this:

public void onBlockBreak(ChangeBlockEvent event, @Root Player player)

Edit: I don’t know, if it’s important, but setBlock() gets called when a player executes a command. Is the player the cause because of this?

Thanks :slight_smile:

That’s probably why. Sponge makes the assumption that because a player ran a command then actions that occur during the command execution is caused due to the player running the command (which makes sense right?).

New methods have been added to Extent to allow overriding the default cause
https://github.com/SpongePowered/SpongeAPI/blob/master/src/main/java/org/spongepowered/api/world/extent/Extent.java#L146-L148

Though it looks like they haven’t been added to Location so you’ll have to get the extent from the location and use the methods there.

1 Like

I just updated the version of my api (maven) to version 3.0.0 / imported it again, but I can’t find this method…

Oh yeah it was added in one of the 3.1 snapshots, change your dependency to 3.1.0-SNAPSHOT

1 Like

is there a official source, where I can see, whats the latest api version?

I suppose you could watch the github repo and see when the version gets bumped in the build.gradle
https://github.com/SpongePowered/SpongeAPI/blob/master/build.gradle#L23
You could also see what version the latest builds are on https://repo.spongepowered.org/maven/org/spongepowered/spongeapi/

ok, thats great, thanks :slightly_smiling:

Is there a builder for a cause? I want to use it like i call it from console (or some other cause, that has permissions / is not a player).

Just use Cause.of() and give it the objects involved. The first object is always the root.

So when I want to use the console as cause, i have to use Cause.of(0)?

No, Cause.of(Sponge.getServer().getConsole())

1 Like

Don’t know why, but it seems like there is a little problem:

[16:34:31] [Normalize User Plot (Hitzk0pf)/INFO] [STDERR]: [java.lang.ThreadGroup:uncaughtException:1052]: java.lang.IllegalArgumentException: PluginContainer must be at the ROOT of a cause!
[16:34:31] [Normalize User Plot (Hitzk0pf)/INFO] [STDERR]: [java.lang.ThreadGroup:uncaughtException:1052]: at com.google.common.base.Preconditions.checkArgument(Preconditions.java:125)
[16:34:31] [Normalize User Plot (Hitzk0pf)/INFO] [STDERR]: [java.lang.ThreadGroup:uncaughtException:1052]: at net.minecraft.world.World.setBlock(World.java:1706)
[16:34:31] [Normalize User Plot (Hitzk0pf)/INFO] [STDERR]: [java.lang.ThreadGroup:uncaughtException:1052]: at me.Hitzk0pf.CaveCore.UserPlotRollbackTool.(UserPlotRollbackTool.java:69)
[16:34:31] [Normalize User Plot (Hitzk0pf)/INFO] [STDERR]: [java.lang.ThreadGroup:uncaughtException:1052]: at me.Hitzk0pf.CaveCore.commands.Cave.BlockInfo$1.run(BlockInfo.java:87)
[16:34:31] [Normalize User Plot (Hitzk0pf)/INFO] [STDERR]: [java.lang.ThreadGroup:uncaughtException:1052]: at java.lang.Thread.run(Thread.java:745)

Line:
location.getExtent().setBlock(x, y, z, Sponge.getRegistry().getType(BlockType.class, "minecraft:air").get().getDefaultState(), false, Cause.of(Sponge.getServer().getConsole()));

Oh OK I didn’t realize there was that restriction.
You need to put your plugin’s PluginContainer as the root object

So I found out, that I can call the PluginContainer by using Cause.of(Sponge.getServiceManager().provide(PluginContainer.class).get())

I got: java.util.NoSuchElementException: No value present

It doesn’t work like that. PluginContainer is not a service, it’s the object that houses your plugin.
The easiest way to get it is to put @Inject private PluginContainer container; in your main plugin class, then pass that instance around.

1 Like

If you have either your Plugin class or your plugins ID, you can use

    Sponge.getPluginManager().fromInstance(myPlugin).get();

or

    Sponge.getPluginManager().getPlugin(pluginId).get();

See also https://jd.spongepowered.org/3.0.0/org/spongepowered/api/plugin/PluginManager.html

1 Like