-
Notifications
You must be signed in to change notification settings - Fork 16
Basic usage
SpectatorInventory
s are at the heart at InvSee++. They provide access to the target player's items.
To obtain the spectator inventory for the target, regardless whether the player is online or not, you can use the following snippet:
package com.example;
import com.janboerman.invsee.spigot.api.InvseeAPI;
import com.janboerman.invsee.spigot.api.MainSpectatorInventory;
import com.janboerman.invsee.spigot.api.response.*;
public class MyClass {
private final MyPlugin myPlugin;
public MyClass(MyPlugin myPlugin) { this.myPlugin = myPlugin; }
public void createSpectatorInventory(InvseeAPI api, String targetPlayerName) {
CompletableFuture<SpectateResponse<MainSpectatorInventory>> future = api.mainSpectatorInventory(targetPlayerName);
future.whenComplete((response, error) -> {
// The future completes in the server's primary thread, so it's safe to use Bukkit API methods.
// Check whether an inventory could be created successfully:
if (error == null) {
if (response.isSuccess()) {
// Success!
MainSpectatorInventory spectatorInventory = response.getInventory();
// Now do whatever you want! :)
// For example, have an admin open it:
// org.bukkit.entity.Player adminPlayer = ...
// adminPlayer.openInventory(spectatorInventory);
} else {
// The spectator inventory could not be created - this has a reason:
NotCreatedReason reason = response.getReason();
// Might want to use this reason in your diagnostics, e.g. customise a reply to a CommandSender, or log it.
}
} else {
// A Java exception occurred when trying to create the inventory.
// This should not occur, but if it does, here is an example of how to handle it:
myPlugin.getLogger().log(Level.SEVERE, "Error when creating spectator inventory for: " + targetPlayerName, error);
}
}
}
}
Let's go over some of the types now. The API method mainSpectatorInventory
returns a CompletableFuture<SpectateResponse>. It returns a CompletableFuture because the API may need to perform some costly IO operations such as fetching the target's UUID from a Mojang's REST Api. This is too heavy to do on the server's primary thread.
Next up the SpectateResponse
is a sum type of two cases:
- The inventory could be created successfully, in which case
response.isSuccess()
returnstrue
and it is safe to callresponse.getInventory()
. - The inventory could not be created, in which case
response.isSuccess()
returnfalse
and it is safe to callresponse.getReason()
.
You can think of SpectateResponse as similar to java.util.Optional, but with some additional information, should the optional be empty (the NotCreatedReason). Functional programmers may also recognise SpectateResponse<MainSpectatorInventory>
as Either<NotCreatedReason, MainSpectatorInventory>
.
We can also see that SpectateResponse is parameterised over the SpectatorInventory type: SpectateResponse<SI extends SpectatorInventory<?>>
.
In this example we used a MainSpectatorInventory
, but there is another subtype of SpectatorInventory, which is EnderSpectatorInventory
. As the name suggests, this inventory is used to spectate the items that are in the target player's EnderChest.
In summary, we have the following type hierarchies:
SpectateResponse
+--Succeed (with SpectatorInventory)
+--Fail (with NotCreatedReason)
org.bukkit.inventory.Inventory
+--SpectatorInventory
+--MainSpectatorInventory
+--EnderSpectatorInventory
NotCreatedReason
+--TargetDoesNotExist
+--TargetHasExemptPermission
+--OfflineSupportDisabled
+--ImplementationFault
+--UnknownReason
This list of reasons can not be relied upon as being exhaustive. In the future more NotCreatedReason
s could be added.
InvSee++ responds with these reasons in the following cases:
-
TargetDoesNotExist
: If no player with the provided username or uuid exists. This reason hardly ever occurs since this only happens when the provided username is not registered to a Minecraft account at Mojang, or the plugin cannot connect to Mojang's REST Api. -
TargetHasExemptPermission
: If the target player is exempted from being spectated, i.e. they own the permission nodeinvseeplusplus.exempt.invsee
orinvseeplusplus.exempt.endersee
. -
OfflineSupportDisabled
: If offline-support is disabled in InvSee++'s config.yml (actually, it's more sophisticated than this, but we'll get to that later) -
ImplementationFault
: If for whatever reason the inventory provider failed (currently only happens for offline inventories from PerWorldInventory). -
UnknownReason
: This reason is currently used by theSpectateResponse#fromOptional(java.util.Optional)
factory method, but this is not currently used inside InvSee++ itself.
Instead of calling api.mainSpectatorInventory(targetName)
you simply call api.enderSpectatorInventory(targetName)
. Instead of a SpectateResponse<MainSpectatorInventory>
you now get a SpectateResponse<EnderSpectatorInventory>
. Easy as that! 😁