Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Question: How to load and paste a schematic using AWE from Java? #9

Closed
rlf opened this issue Sep 28, 2015 · 15 comments
Closed

Question: How to load and paste a schematic using AWE from Java? #9

rlf opened this issue Sep 28, 2015 · 15 comments

Comments

@rlf
Copy link

rlf commented Sep 28, 2015

I've been struggling with this for days now.

If I profile the application, and do a //schem load schematic followed by a //paste AWE correctly kicks in, and loads and pastes the schematic without causing the server grief.

When I do this programmatically (I have tried perhaps 7 different combinations of classes in play, this is the latest):

InjectorCore.getInstance().getClassFactory().getJobProcessor().executeJob(ConsolePlayer.getInstance(), new IJob() {
    @Override
    public String getName() {
        return "loadIslandSchematic";
    }

    @Override
    public void execute() {
        log.finer("Trying to load schematic " + file);
        try (InputStream in = new BufferedInputStream(new FileInputStream(file))) {
            BukkitWorld bukkitWorld = new BukkitWorld(origin.getWorld());
            ClipboardReader reader = ClipboardFormat.SCHEMATIC.getReader(in);

            WorldData worldData = bukkitWorld.getWorldData();
            Clipboard clipboard = reader.read(worldData);
            ClipboardHolder holder = new ClipboardHolder(clipboard, worldData);

            Player player = Bukkit.getPlayer(playerPerk.getPlayerInfo().getUniqueId());
            int maxBlocks = (255 * Settings.island_protectionRange * Settings.island_protectionRange);
            final EditSession editSession = AsyncWorldEditHandler.createEditSession(bukkitWorld, maxBlocks);
            editSession.enableQueue();
            editSession.setFastMode(true);
            Vector to = new Vector(origin.getBlockX(), origin.getBlockY(), origin.getBlockZ());
            final Operation operation = holder
                    .createPaste(editSession, worldData)
                    .to(to)
                    .ignoreAirBlocks(false)
                    .build();
            Operations.completeBlindly(operation);
            AsyncWorldEditHandler.registerCompletion(player);
            editSession.flushQueue();
        } catch (IOException e) {
            uSkyBlock.log(Level.WARNING, "Unable to load schematic " + file, e);
        }
    }
});

Everything but the Operations.completeBlindly() seems to be correctly AWEfied.

What is the proper procedure, to both read a schematic into a clipboard, and paste it in the world again utilizing AWEs capabilities (the above should work on both AWE 2.1.1 and AWE 3.1.1).

@SBPrime
Copy link
Owner

SBPrime commented Sep 29, 2015

BukkitWorld bukkitWorld = new BukkitWorld(origin.getWorld());
Player player = Bukkit.getPlayer(playerPerk.getPlayerInfo().getUniqueId());
int maxBlocks = (255 * Settings.island_protectionRange * Settings.island_protectionRange);
PlayerEntry playerEntry = PlayerManager.getPlayer(player);
ThreadSafeEditSession tsSession = ((AsyncEditSessionFactory)WorldEdit.getEditSession()).getThreadSafeEditSession(bukkitWorld, maxBlock, null, playerEntry);
FuncParamEx<Integer, CancelabeEditSession, MaxChangedBlocksException> action = new PasteAction();
BlockPlacer.performAsAsyncJob(tsSession, playerEntry, "loadIslandSchematic", action);

...

class PasteAction : extends FuncParamEx<Integer, CancelabeEditSession, MaxChangedBlocksException> {
    public Integer execute(CancelabeEditSession editSession) throws MaxChangedBlocksException {
        ClipboardReader reader = ClipboardFormat.SCHEMATIC.getReader(in);

        WorldData worldData = bukkitWorld.getWorldData();
        Clipboard clipboard = reader.read(worldData);
        ClipboardHolder holder = new ClipboardHolder(clipboard, worldData);

        editSession.enableQueue();
        editSession.setFastMode(true);
        Vector to = new Vector(origin.getBlockX(), origin.getBlockY(), origin.getBlockZ());
        final Operation operation = holder
                .createPaste(editSession, worldData)
                .to(to)
                .ignoreAirBlocks(false)
                .build();
        Operations.completeBlindly(operation);
        AsyncWorldEditHandler.registerCompletion(player);
        editSession.flushQueue();
    }
}

@rlf
Copy link
Author

rlf commented Sep 29, 2015

Thanks for the bump in the right direction.
What is the integer that should be returned by the PasteAction?

@rlf
Copy link
Author

rlf commented Sep 29, 2015

I think I guessed it, jobId?

Now to the next problem.
AWE 3.1.1 uses IPlayerEntry not PlayerEntry, and I need to do it as a plugin (i.e. either PlayerEntry.CONSOLE or PlayerEntry.UNKNOWN) - but how do I get hold of those values in AWE 3.1.1?

@SBPrime
Copy link
Owner

SBPrime commented Sep 29, 2015

The return is the number of changed blocks. Its used only to display a message to the player.

IPlayerManager.getConsolePlayer();
IPlayerManager.getUnknownPlayer();

I thought that you need to run it as a player not as a console, etc.

@rlf
Copy link
Author

rlf commented Sep 29, 2015

The problem with running it as a player is, that it then requires the player to have permissions.

As far as I have seen so far that is.
And we do not want to require all players of islands in uSkyBlock to have AWE or WE permissions.

@rlf
Copy link
Author

rlf commented Sep 29, 2015

Still struggling with AWE 3.1.1 - I managed to get some of it working, but I simply can't get the progressDisplay to kick in.

Won't even mention what I've tried, but reflection has been in play.

See the code here https://github.com/rlf/uSkyBlock/blob/master/uSkyBlock-AWE311/src/main/java/us/talabrek/ultimateskyblock/handler/asyncworldedit/AWE311Adaptor.java

It seems to work for AWE211 (https://github.com/rlf/uSkyBlock/tree/master/uSkyBlock-AWE211)

@SBPrime
Copy link
Owner

SBPrime commented Sep 30, 2015

Does the progress display show for regular actions?

@rlf
Copy link
Author

rlf commented Sep 30, 2015

It gets called yes, but not for "my" action.
All the other progressdisplays are shown on regular actions.

@SBPrime
Copy link
Owner

SBPrime commented Oct 2, 2015

Its probably because the progress bar is displayed only for "real" players. You would have to add your own method for rendering the progress bar.

@rlf
Copy link
Author

rlf commented Oct 2, 2015

Ok, so the IProgressDisplays are only in play in AWE 3.1.1 when it's an actual player performing the operation?

And I take it, you propose somehow making a timer, and keeping track of the progress of the job "manually"?

@SBPrime
Copy link
Owner

SBPrime commented Oct 3, 2015

You can look at:
BlockPlacer.getPlayerEvents(IPlayerEntry player).getQueue()

but this is not in the API + if you are not careful you can cause an exception.

@SBPrime
Copy link
Owner

SBPrime commented Oct 3, 2015

UPDATE: Please look at the latest update I cleaned up the API and added some stuff that you might need.

@SBPrime
Copy link
Owner

SBPrime commented Oct 16, 2015

If you don't have anything to add I'm closing the issue.

@rlf
Copy link
Author

rlf commented Oct 16, 2015

Sure, close it for now.
We are using the API for our AWE 3.2.1 integration.
Still haven't been able to track the progress - but haven't had time to dig deeper into that issue.

Thanks for the support m8!

@rlf rlf closed this as completed Oct 16, 2015
@SBPrime
Copy link
Owner

SBPrime commented Oct 16, 2015

Your welcome

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants