MightyPirates / OpenComputers

Home of the OpenComputers mod for Minecraft.
https://oc.cil.li
Other
1.59k stars 432 forks source link

Debug Cards' runCommand doesn't work with WorldEdit #892

Closed fnuecke closed 9 years ago

fnuecke commented 9 years ago

Currently the debug card's runCommand method doesn't work with WorldEdit - at least the Forge variant, didn't test the other. This is because WE requires an actual player to issue the command; it'll just silently ignore commands from ICommandSenders, which is what the debug card implements, to easily capture text output generated by commands.

There are two workarounds I tried, but both were unsatisfactory:

If anyone has an idea how to solve this, I'm all ears.

Eunomiac commented 9 years ago

Wow, you're awesome --- I've considered posting this as a feature request for a while, but figured I was asking too much from OC's adventure map support. Instead, I went over to the WorldEdit forums and started a thread titled "WorldEdit Commands w/Fake Players: How to Make Them Work?", with the intent of returning here when I'd gleaned some insights.

Unfortunately, we were sidetracked by another issue I was having, and I let the issue drop... but I've just gone and undropped it with a new reply, in which I quote this issue. Hopefully sk89q will have some answers for us.

In the meantime, have you looked at the Bukkit plugin CBWrapper? It enabled WorldEdit commands via Command Blocks, by creating a fake player. Admittedly, it's old, and it's for the Bukkit implementation of WorldEdit, but perhaps knowing how it went about getting the job done would be instructive (code is available on GitHub)? From the documentation page:

When the command /cw is run from a command block, it will create a dummy player where the command block is and run the command specified in the command parameters ... ● The dummy player's username, by default, is "@" ● The dummy player's position is the position of the command block it was run from, unless you use the -o flag ● The dummy players isn't actually registered as a player, so you can't teleport people to it or anything ● The dummy player is an op with all permissions. The only bit of security is that the dummy player is only created by command blocks, which can only be edited by ops in creative mode

Hopefully one of these two avenues bears fruit (mixed metaphors FTW!). I am so enamoured with the landmark revolution Lua-controlled craftscripts would bring to adventure map design, expect me to be championing this issue until someone files a restraining order ;)

Eunomiac commented 9 years ago

wizjany, over at the WorldEdit forums, has responded to my question (where I quoted your issue). He basically confirmed that an actual player is required to issue WE commands, but does expand on things a little:

The forge code currently only supports EntityPlayerMP command senders. This is an issue with worldedit, and we should eventually expand to allow any command sender (wrapped into a class implementing Actor). The main issue is actually supporting things like location, and so on, which require worldedit to be aware of the class and wrap it correctly into an Actor that supports things like that. Command blocks, for instance, are just treated as a console command sender since we don't support that yet. Also at the moment, most commands are hardcoded to take a player because getWorld() is specific to our player class. This probably isn't a big deal to change though.

I'm not sure how helpful this is to you, since you seemed to already know of this restriction and were looking for a work-around, but there's a bit more information there all the same. If you want to pursue options for a work-around, I'm sure they'd be happy to help---I'm afraid I'm a little out of my depth when it comes to java programming, so someone more knowledgeable than I should probably ask those questions.

But, ever the annoying obsessive incessant tenacious champion of adventure map awesomeness, I've asked whether it might be possible to implement an interim solution whereby craftscripts alone could be opened up to alternate command senders---and simply fail if they attempt to call an unsupported WorldEdit class, like Player. (I mention scripts specifically, because they allow more control over which classes are being called, and can be written so they don't need to directly access a player object.)

There's still the last hurdle wizjany describes (i.e. most commands being hardcoded to require a Player). But, he did say this probably wasn't a big deal to change, so fingers crossed.

fnuecke commented 9 years ago

OK, thanks for keeping track of this! I'll need to grab a copy of the WE sources to properly dig into where it fails authentication when using a fake player. I'll try to have a look at that over the week.

Eunomiac commented 9 years ago

Actually, it turns out this may be a bug on WorldEdit's side---they've opened an issue of their own, discussing OpenComputers specifically.

From the discussion on that issue post:

After looking into it, FakePlayer extends EntityPlayerMP, so this should work. Do you have a mod that doesn't work? OpenComputers, yea? Yeah, OpenComputers FakePlayer doesn't work. Not sure why. Pretty sure the ComputerCraft version doesn't either.

fnuecke commented 9 years ago

Cool; I'll push a version with the debug card using a fake player as a test-case where it doesn't work, gimme a bit.

fnuecke commented 9 years ago

Aaaand it appears I screwed up last time I tested it, because now it seems to work, at least partially. So I feel like an idiot \o/

fnuecke commented 9 years ago

One remaining issue you'll somehow have to solve if you want to use it in singleplayer based adventure maps is giving the OC fake player the appropriate permissions somehow, since you can't use a card bound to a player. And I have no idea how you'd go about that I'm afraid.

fnuecke commented 9 years ago

Oh, but as a little bonus runCommand now alternatively also takes a table so you can run multiple commands in one tick, e.g.: d.runCommand({"//pos1", "//pos2", "//shift 10 up", "//set glowstone"})

Eunomiac commented 9 years ago

One remaining issue you'll somehow have to solve if you want to use it in singleplayer based adventure maps is giving the OC fake player the appropriate permissions somehow, since you can't use a card bound to a player. And I have no idea how you'd go about that I'm afraid.

In case this is something you'd like to include in the documentation, I've figured out the "trick"/"workaround"/"maybe-solution": Opening a SSP game to LAN (via the "Open to LAN" button in the options menu) and enabling cheats allows the OC fake player to run WorldEdit commands.

AND IT IS AWESOME.

I just finished coding the part of my control facility that lets players change the biome of an entire city district with a button press---including filling (or clearing) the area with appropriate foliage and ground cover (snow, sand, grass w/ flowers). And that was basically a test; I haven't even started with craftscripts yet.

This is the Holy Grail of map-making, I shite you not :D

fnuecke commented 9 years ago

Cool! Would you mind adding that info to the wiki (component and/or item page of the debug card)? That'd be great, thanks :-)