147 lines
5.1 KiB
Java
147 lines
5.1 KiB
Java
package games.dmg.spigottyrant;
|
|
|
|
import java.util.Map;
|
|
import java.util.Optional;
|
|
import java.util.UUID;
|
|
import org.bukkit.ChatColor;
|
|
import org.bukkit.Material;
|
|
import org.bukkit.NamespacedKey;
|
|
import org.bukkit.entity.Player;
|
|
import org.bukkit.inventory.ItemStack;
|
|
import org.bukkit.inventory.meta.ItemMeta;
|
|
import org.bukkit.persistence.PersistentDataType;
|
|
import org.bukkit.plugin.Plugin;
|
|
|
|
public final class BukkitRoleControlItemService implements RoleControlItemService {
|
|
private final NamespacedKey roleKey;
|
|
private final NamespacedKey ownerKey;
|
|
private final PluginSettings settings;
|
|
|
|
public BukkitRoleControlItemService(Plugin plugin, PluginSettings settings) {
|
|
roleKey = new NamespacedKey(plugin, "role-control");
|
|
ownerKey = new NamespacedKey(plugin, "role-control-owner");
|
|
this.settings = settings;
|
|
}
|
|
|
|
@Override
|
|
public void recover(Player player, GameState game) {
|
|
Optional<RoleControl> required = RoleControlItemPolicy.requiredRole(
|
|
game, player.getUniqueId()
|
|
);
|
|
if (required.isEmpty() || contains(player, required.orElseThrow())) {
|
|
return;
|
|
}
|
|
Map<Integer, ItemStack> leftovers = player.getInventory().addItem(
|
|
create(player.getUniqueId(), required.orElseThrow())
|
|
);
|
|
if (!leftovers.isEmpty()) {
|
|
String command = required.orElseThrow() == RoleControl.TYRANT
|
|
? "/tyrant item" : "/vigilante item";
|
|
player.sendMessage(ChatColor.RED
|
|
+ "Your inventory is full. Make room and use " + command + ".");
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public boolean isBoundRoleControlItem(ItemStack item) {
|
|
return role(item).isPresent() && owner(item).isPresent();
|
|
}
|
|
|
|
@Override
|
|
public Optional<RoleControl> role(ItemStack item) {
|
|
String value = metadata(item, roleKey);
|
|
if (value == null) {
|
|
return Optional.empty();
|
|
}
|
|
try {
|
|
return Optional.of(RoleControl.valueOf(value));
|
|
} catch (IllegalArgumentException exception) {
|
|
return Optional.empty();
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public Optional<UUID> owner(ItemStack item) {
|
|
String value = metadata(item, ownerKey);
|
|
if (value == null) {
|
|
return Optional.empty();
|
|
}
|
|
try {
|
|
return Optional.of(UUID.fromString(value));
|
|
} catch (IllegalArgumentException exception) {
|
|
return Optional.empty();
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public void removeInvalid(Player player, GameState game) {
|
|
Optional<RoleControl> required = RoleControlItemPolicy.requiredRole(
|
|
game, player.getUniqueId()
|
|
);
|
|
boolean retained = false;
|
|
ItemStack[] contents = player.getInventory().getContents();
|
|
for (int index = 0; index < contents.length; index++) {
|
|
ItemStack item = contents[index];
|
|
if (!isBoundRoleControlItem(item)) {
|
|
continue;
|
|
}
|
|
boolean valid = !retained
|
|
&& owner(item).filter(player.getUniqueId()::equals).isPresent()
|
|
&& role(item).equals(required);
|
|
if (valid) {
|
|
retained = true;
|
|
} else {
|
|
player.getInventory().setItem(index, null);
|
|
}
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public void removeAll(Player player) {
|
|
ItemStack[] contents = player.getInventory().getContents();
|
|
for (int index = 0; index < contents.length; index++) {
|
|
if (isBoundRoleControlItem(contents[index])) {
|
|
player.getInventory().setItem(index, null);
|
|
}
|
|
}
|
|
}
|
|
|
|
private ItemStack create(UUID ownerId, RoleControl role) {
|
|
PluginSettings.AbilityItemSettings configured = role == RoleControl.TYRANT
|
|
? settings.tyrantControlItem() : settings.vigilanteControlItem();
|
|
Material material = Material.matchMaterial(configured.material());
|
|
if (material == null) {
|
|
throw new IllegalStateException("Configured role control material is unavailable");
|
|
}
|
|
ItemStack item = new ItemStack(material);
|
|
ItemMeta meta = item.getItemMeta();
|
|
meta.setDisplayName(ChatColor.GOLD + configured.name());
|
|
meta.getPersistentDataContainer().set(
|
|
roleKey, PersistentDataType.STRING, role.name()
|
|
);
|
|
meta.getPersistentDataContainer().set(
|
|
ownerKey, PersistentDataType.STRING, ownerId.toString()
|
|
);
|
|
item.setItemMeta(meta);
|
|
return item;
|
|
}
|
|
|
|
private boolean contains(Player player, RoleControl role) {
|
|
for (ItemStack item : player.getInventory().getContents()) {
|
|
if (owner(item).filter(player.getUniqueId()::equals).isPresent()
|
|
&& role(item).filter(role::equals).isPresent()) {
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
private static String metadata(ItemStack item, NamespacedKey key) {
|
|
if (item == null || !item.hasItemMeta()) {
|
|
return null;
|
|
}
|
|
return item.getItemMeta().getPersistentDataContainer()
|
|
.get(key, PersistentDataType.STRING);
|
|
}
|
|
}
|