Updated API (markdown)

Jesse Boyd 2016-08-16 01:08:50 +10:00
parent e50a9dd508
commit 68ad4f616e

283
API.md

@ -1,265 +1,34 @@
Table of contents:
- [Minecraft + Async](#minecraft--async)
- [The FaweAPI class](#the-faweapi-class-has-some-various-methods-that-may-be-useful)
- [Wrappers for Bukkit API](#wrappers-for-bukkit-api)
- [WorldEdit Player/World](#worldedit-playerworld)
- [The EditSession](#the-editsession)
- [The FawePlayer](#the-faweplayer)
- [The FaweQueue](#the-fawequeue)
- [Tasks](#tasks)
- [Pasting a schematic](#pasting-a-schematic)
- [Undoing an EditSession](#undoing-an-editsession)
- [Streaming NBT files (e.g. Schematics)](#streaming-nbt-files-eg-schematics)
# Need help?
If you need help coding anything, feel free to hop on [IRC](http://webchat.esper.net/?nick=&channels=IntellectualCrafters&fg_color=000&fg_sec_color=000&bg_color=FFF).
# Note:
- Using the WE API will have the same behavior with FAWE (it would just be faster).
- Having FAWE installed allows most classes to be used from an async thread.
- The FAWE API offers some additional functionality not already present in WE.
- Learn about concurency if you haven't already.
# Porting WorldEdit API code to FAWE
Firstly, FAWE isn't meant to modify the behavior of the WorldEdit API. Existing code should run faster simply by having FAWE installed. Porting code (which is using the WorldEdit API) to work async is as easy as putting it in an async thread (e.g. With the bukkit scheduler).
### Minecraft + Async
The Minecraft server for the most part is single threaded and usually can't be modified or read async
- Setting a block async (if it weren't blocked) would likely crash the server
The FAWE API can abstract most things so that they can safely be used async.
- Requests will be made to the main thread when needed
That said, the FAWE API offers additional functionality not already available in WorldEdit. Below are some examples for WorldEdit and FAWE:
### The FaweAPI class has some various methods that may be useful:
- upload
- load
- getEditSessionBuilder
- getTaskManager
- wrapPlayer
- createQueue
- getWorld
- getMaskManagers
- isMemoryLimited
- getFastRandom
- getRegions
- cancelEdit
- addMaskManager
- getChangeSetFromFile
- getBDFiles
- getChangeSetFromDisk
- checkVersion
- fixLighting
- addTask
- addMemoryLimitedTask
- addMemoryPlentifulTask
- getTranslations
### Players
- [FawePlayer](https://github.com/boy0001/FastAsyncWorldedit/wiki/FawePlayer)
- [WorldEdit player](https://github.com/boy0001/FastAsyncWorldedit/wiki/WorldEdit-World-Player)
- [Player Job API](https://github.com/boy0001/FastAsyncWorldedit/wiki/Jobs-API)
- [Player Progress API](https://github.com/boy0001/FastAsyncWorldedit/wiki/Progress-API)
- [Player region restrictions](https://github.com/boy0001/FastAsyncWorldedit/wiki/Region-restriction-API)
Source: https://github.com/boy0001/FastAsyncWorldedit/blob/master/core/src/main/java/com/boydti/fawe/FaweAPI.java
### Modify the world Async (or load it)
- [WorldEdit world](https://github.com/boy0001/FastAsyncWorldedit/wiki/WorldEdit-World-Player)
- [EditSession](https://github.com/boy0001/FastAsyncWorldedit/wiki/WorldEdit-EditSession)
- [Bukkit API wrappers](https://github.com/boy0001/FastAsyncWorldedit/wiki/AsyncWorld)
- [FaweQueue](https://github.com/boy0001/FastAsyncWorldedit/wiki/FaweQueue)
### Wrappers for Bukkit API
FAWE offers some async wrappers for the Bukkit API:
```Java
TaskManager.IMP.async(new Runnable() {
@Override
public void run() {
AsyncWorld world = AsyncWorld.create(new WorldCreator("MyWorld"));
// AsyncWorld world = AsyncWorld.wrap(bukkitWorld); // Or wrap existing world
Block block = world.getBlockAt(0, 0, 0);
block.setType(Material.BEDROCK);
// When you are done
world.commit();
}
});
```
Source: https://github.com/boy0001/FastAsyncWorldedit/tree/master/bukkit0/src/main/java/com/boydti/fawe/bukkit/wrapper
### WorldEdit Player/World
WorldEdit has its own Player and World classes which will be needed for some methods.
### NBT and Formats
- [Schematic pasting](https://github.com/boy0001/FastAsyncWorldedit/wiki/Pasting-a-schematic)
- [NBT stream API](https://github.com/boy0001/FastAsyncWorldedit/wiki/NBT-stream-API)
Getting the WE World object:
```Java
WorldEdit.getInstance().getServer().getWorlds();
// Or for Bukkit specifically
BukkitUtil.getLocalWorld(bukkitWorld);
```
Getting the player
```Java
// Bukkit
WorldEditPlugin worldEdit = (WorldEditPlugin) Bukkit.getServer().getPluginManager().getPlugin("WorldEdit");
worldedit.wrapPlayer(bukkitPlayer);
// Forge
ForgeWorldEdit.inst.wrap(entityPlayer);
// Alternative with FAWE
FawePlayer.wrap(uuid or username or actor or player object here).getPlayer();
```
### NMS abstraction
- [Light API](https://github.com/boy0001/FastAsyncWorldedit/wiki/Light-API)
- [NMSMappedFaweQueue](https://github.com/boy0001/FastAsyncWorldedit/wiki/FaweQueue#nms-methods)
For use async see e.g. `PlayerWrapper.wrap(player)`
- [PlayerWrapper (WorldEdit Player)](https://github.com/boy0001/FastAsyncWorldedit/blob/master/core/src/main/java/com/boydti/fawe/wrappers/PlayerWrapper.java)
- [WorldWrapper (WorldEdit World)](https://github.com/boy0001/FastAsyncWorldedit/blob/master/core/src/main/java/com/boydti/fawe/wrappers/WorldWrapper.java)
### Web
- [Web API](https://github.com/boy0001/FastAsyncWorldedit/wiki/Web-API)
### The EditSession
The EditSession is used by WorldEdit to make and record changes to the World. The EditSessionBuilder gives you full control over it.
- A world must be provided, see `FaweAPI.getWorld(...)`
Example:
```Java
EditSession editSession = new EditSessionBuilder(world)
.fastmode(true)
.build;
```
Unset values will revert to their default:
- player: The player doing the edit (defaults to to null)
- limit: Block/Entity/Action limit (defaults to player limit or unlimited)
- changeSet: Stores changes (defaults to config.yml value)
- allowedRegions: Allowed editable regions (defaults to player's allowed regions, or everywhere)
- autoQueue: Changes can occur before flushQueue() (defaults true)
- fastmode: bypasses history (defaults to player fastmode or config.yml console history)
- checkMemory: If low memory checks are enabled (defaults to player's fastmode or true)
- combineStages: If history is combined with dispatching (defaults to config value)
- blockBag: The blockbag to use (defaults to null)
- eventBus: The eventBus to use (defaults to null)
- event: The event to call (defaults to null)
See: https://github.com/boy0001/FastAsyncWorldedit/blob/master/core/src/main/java/com/boydti/fawe/util/EditSessionBuilder.java
Here's a non FAWE example:
```Java
// If no player is doing the changes
EditSession editSession = WorldEdit.getInstance().getEditSessionFactory().getEditSession(worldEditWorld, -1);
// For a specific player
editSession = WorldEdit.getInstance().getEditSessionFactory().getEditSession(worldEditWorld, -1, actor);
// Do stuff with the EditSession
editSession.setBlock(new Vector(x, y, z), new BaseBlock(id, data));
// All changes will have been made once flushQueue is called
editSession.flushQueue();
```
### The FawePlayer
To get a new Player use `FawePlayer.wrap(player, uuid, username, etc)`
Here are the methods
- getWorld
- getLocation
- sendTitle
- resetTitle
- getLimit
- getName
- getUUID
- hasPermission
- setPermission
- sendMessage
- executeCommand
- getPlayer
- getSession
- getSelection
- setSelection
- getCurrentRegions
- getLargestRegion
- hasWorldEditBypass
- setMeta
- getMeta
- deleteMeta
- getNewEditSession
- runIfFree
- runAsyncIfFree
See: https://github.com/boy0001/FastAsyncWorldedit/blob/master/core/src/main/java/com/boydti/fawe/object/FawePlayer.java
### The FaweQueue
The FaweQueue is a basic queue for modifying the world from async threads
- Use it to modify whole chunks or individual blocks efficiently
- See EditSession or AsyncWorld which will be easier to use but slower
```Java
// Auto queuing will mean blocks start to place before it is flushed
FaweQueue queue = FaweAPI.createQueue(worldName, autoQueue);
queue.setBlock(0, 0, 0, id, data);
queue.setBiome(0, 0, biome);
// Set entire chunks
FaweChunk<?> chunk = queue.getFaweChunk(5, 5);
chunk.fill(id, data);
chunk.addToQueue();
// Repeat the same for position
chunk = chunk.copy(true);
chunk.setLoc(queue, 5, 6);
chunk.addToQueue();
```
### Tasks
With the FAWE TaskManager you can temporarily switch to the main thread to do something
```Java
// E.g. Get a player's inventory but you are currently on an async thread.
PlayerInventory inventory = TaskManager.IMP.sync(new RunnableVal<PlayerInventory>() {
@Override
public void run(PlayerInventory value) {
this.value = player.getInventory();
}
});
```
See: https://github.com/boy0001/FastAsyncWorldedit/blob/master/core/src/main/java/com/boydti/fawe/util/TaskManager.java
### Pasting a schematic
```Java
File file = new File("path/to/schematic");
boolean noAir = false;
boolean entities = true;
Vector position = new Vector(0, 0, 0);
SchematicFormat.getFormat(file).load(file).paste(editSession, position, noAir, entities);
editSession.flushQueue();
// If you have FAWE you could instead use this:
boolean allowUndo = true;
EditSession editSession = SCHEMATIC.load(file).paste(world, position, allowUndo, !noAir, (Transform) null);
```
### Undoing an EditSession
Where `editSession` is what you are undoing.
```Java
// Create a new EditSession however you want
EditSession newEditSession = WorldEdit.getInstance().getEditSessionFactory().getEditSession(editSession.getWorld(), -1, null, null);
// Undo it
editSession.undo(newEditSession);
editSession.flushQueue();
```
### Streaming NBT files (e.g. Schematics)
With FAWE you can stream a schematic, or any NBT stream without having to store the whole thing into memory.
- You have to do this if a file is too large to fit in memory
- Or if you just want to obtain some information from the stream
```Java
// Let's stream some info from a schematic file without having to load the whole thing into memory
// Schematics are compressed, so we need to use a GZIPInputStream before the NBTInputStream
File file = new File("blah.schematic");
NBTInputStream is = new NBTInputStream(new GZIPInputStream(new FileInputStream(file)));
NBTStreamer streamer = new NBTStreamer(is);
// Get the height,width,length
final Map<String, Short> dimensions = new HashMap<>();
// You need to know the structure of the NBT file, these specific values are all shorts
streamer.addReader(new NBTStreamer.NBTStreamReader<Integer, Short>() {
@Override
public void run(Integer index, Short value) {
// The index is unimportant for this, but for Lists, or Arrays it might be useful
dimensions.put(getNode(), value); // Put e.g. Schematic.Width -> 53
}
}, "Schematic.Width", "Schematic.Height", "Schematic.Length");
// Let's get the Entities, I know that they will be of type CompoundTag
streamer.addReader("Schematic.Entities.#", new NBTStreamer.NBTStreamReader<Integer, CompoundTag>() {
@Override
public void run(Integer index, CompoundTag entity) {
// For the .# and normal readers, it will always be Index, Value
// Here we can do something with each entitiy
}
});
// Get some info about the Blocks section (which contains the ids) (there's also AddBlocks, and Data)
streamer.addReader("Schematic.Blocks.?", new NBTStreamer.NBTStreamReader<Integer, Integer>() {
@Override
public void run(Integer length, Integer type) {
Class<? extends Tag> clazz = NBTConstants.getClassFromType(type);
// Here we can do something knowing the length of the section and its type
}
});
// Now that we have the readers we want, we can read through the file
streamer.readFully();
System.out.println("Dimensions are: " + dimensions);
```
See: https://github.com/boy0001/FastAsyncWorldedit/blob/master/core/src/main/java/com/boydti/fawe/jnbt/SchematicStreamer.java
## FaweAPI class:
https://github.com/boy0001/FastAsyncWorldedit/blob/master/core/src/main/java/com/boydti/fawe/FaweAPI.java