Merge pull request #10 from cswhite2000/tokens

Add tokens and add shiny's gui library
This commit is contained in:
cswhite2000 2017-05-15 01:00:26 -07:00 committed by GitHub
commit 8220e90732
63 changed files with 2938 additions and 198 deletions

View File

@ -1,6 +1,5 @@
package tc.oc.api.docs.virtual;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Map;
@ -82,6 +81,8 @@ public interface UserDoc {
@Serialize
interface Login extends Identity, Locale, Trophies, License.Complete {
int raindrops();
int maptokens();
int mutationtokens();
String mc_last_sign_in_ip();
@Nullable Date trial_expires_at();
Map<String, Map<String, Boolean>> mc_permissions_by_realm();

View File

@ -0,0 +1,9 @@
package tc.oc.api.users;
import tc.oc.api.annotations.Serialize;
import tc.oc.api.docs.virtual.Document;
@Serialize
public interface CreditMaptokensRequest extends Document {
int maptokens();
}

View File

@ -0,0 +1,9 @@
package tc.oc.api.users;
import tc.oc.api.annotations.Serialize;
import tc.oc.api.docs.virtual.Document;
@Serialize
public interface CreditMutationtokensRequest extends Document {
int mutationtokens();
}

View File

@ -40,6 +40,16 @@ public class NullUserService extends NullModelService<User, UserDoc.Partial> imp
return Futures.immediateFailedFuture(new NotFound());
}
@Override
public ListenableFuture<UserUpdateResponse> creditMaptokens(UserId userId, CreditMaptokensRequest request) {
return Futures.immediateFuture(UserUpdateResponse.FAILURE);
}
@Override
public ListenableFuture<UserUpdateResponse> creditMutationtokens(UserId userId, CreditMutationtokensRequest request) {
return Futures.immediateFuture(UserUpdateResponse.FAILURE);
}
@Override
public <T extends UserDoc.Partial> ListenableFuture<User> update(UserId userId, T update) {
return Futures.immediateFailedFuture(new NotFound());

View File

@ -27,6 +27,18 @@ public interface UserService extends ModelService<User, UserDoc.Partial> {
ListenableFuture<User> purchaseGizmo(UserId userId, PurchaseGizmoRequest request);
default ListenableFuture<UserUpdateResponse> creditMaptokens(UserId userId, int maptokens) {
return creditMaptokens(userId, () -> maptokens);
}
ListenableFuture<UserUpdateResponse> creditMaptokens(UserId userId, CreditMaptokensRequest request);
default ListenableFuture<UserUpdateResponse> creditMutationtokens(UserId userId, int mutationtokens) {
return creditMutationtokens(userId, () -> mutationtokens);
}
ListenableFuture<UserUpdateResponse> creditMutationtokens(UserId userId, CreditMutationtokensRequest request);
<T extends UserDoc.Partial> ListenableFuture<User> update(UserId userId, T update);
ListenableFuture<User> changeSetting(UserId userId, ChangeSettingRequest request);

View File

@ -80,6 +80,16 @@ public class LocalUserDocument extends SimplePlayerId implements User {
return 0;
}
@Override
public int maptokens() {
return 0;
}
@Override
public int mutationtokens() {
return 0;
}
@Override
public String mc_last_sign_in_ip() {
return ip;

View File

@ -18,17 +18,7 @@ import tc.oc.api.docs.virtual.UserDoc;
import tc.oc.api.exceptions.NotFound;
import tc.oc.api.minecraft.sessions.LocalSessionFactory;
import tc.oc.api.model.NullModelService;
import tc.oc.api.users.ChangeClassRequest;
import tc.oc.api.users.ChangeSettingRequest;
import tc.oc.api.users.CreditRaindropsRequest;
import tc.oc.api.users.LoginRequest;
import tc.oc.api.users.LoginResponse;
import tc.oc.api.users.LogoutRequest;
import tc.oc.api.users.PurchaseGizmoRequest;
import tc.oc.api.users.UserSearchRequest;
import tc.oc.api.users.UserSearchResponse;
import tc.oc.api.users.UserService;
import tc.oc.api.users.UserUpdateResponse;
import tc.oc.api.users.*;
import tc.oc.commons.core.concurrent.FutureUtils;
import tc.oc.minecraft.api.user.UserFinder;
@ -138,6 +128,36 @@ class LocalUserService extends NullModelService<User, UserDoc.Partial> implement
return find(userId);
}
@Override
public ListenableFuture<UserUpdateResponse> creditMaptokens(UserId userId, CreditMaptokensRequest request) {
return FutureUtils.mapSync(find(userId), user -> new UserUpdateResponse() {
@Override
public boolean success() {
return true;
}
@Override
public User user() {
return user;
}
});
}
@Override
public ListenableFuture<UserUpdateResponse> creditMutationtokens(UserId userId, CreditMutationtokensRequest request) {
return FutureUtils.mapSync(find(userId), user -> new UserUpdateResponse() {
@Override
public boolean success() {
return true;
}
@Override
public User user() {
return user;
}
});
}
@Override
public <T extends UserDoc.Partial> ListenableFuture<User> update(UserId userId, T update) {
return find(userId);

View File

@ -15,17 +15,7 @@ import tc.oc.api.message.types.PlayerTeleportRequest;
import tc.oc.api.minecraft.users.UserStore;
import tc.oc.api.model.HttpModelService;
import tc.oc.api.queue.Exchange;
import tc.oc.api.users.ChangeClassRequest;
import tc.oc.api.users.ChangeSettingRequest;
import tc.oc.api.users.CreditRaindropsRequest;
import tc.oc.api.users.LoginRequest;
import tc.oc.api.users.LoginResponse;
import tc.oc.api.users.LogoutRequest;
import tc.oc.api.users.PurchaseGizmoRequest;
import tc.oc.api.users.UserSearchRequest;
import tc.oc.api.users.UserSearchResponse;
import tc.oc.api.users.UserService;
import tc.oc.api.users.UserUpdateResponse;
import tc.oc.api.users.*;
import tc.oc.commons.core.concurrent.FutureUtils;
import tc.oc.minecraft.api.entity.Player;
@ -91,6 +81,16 @@ class OCNUserService extends HttpModelService<User, UserDoc.Partial> implements
return handleUpdate(client().post(memberUri(userId, "purchase_gizmo"), request, User.class, HttpOption.INFINITE_RETRY));
}
@Override
public ListenableFuture<UserUpdateResponse> creditMaptokens(UserId userId, CreditMaptokensRequest request) {
return handleUserUpdate(client().post(memberUri(userId, "credit_maptokens"), request, UserUpdateResponse.class, HttpOption.INFINITE_RETRY));
}
@Override
public ListenableFuture<UserUpdateResponse> creditMutationtokens(UserId userId, CreditMutationtokensRequest request) {
return handleUserUpdate(client().post(memberUri(userId, "credit_mutationtokens"), request, UserUpdateResponse.class, HttpOption.INFINITE_RETRY));
}
@Override
public <T extends UserDoc.Partial> ListenableFuture<User> update(UserId userId, T update) {
return update(userId.player_id(), update);

View File

@ -80,6 +80,7 @@ import tc.oc.commons.bukkit.ticket.TicketBooth;
import tc.oc.commons.bukkit.ticket.TicketCommands;
import tc.oc.commons.bukkit.ticket.TicketDisplay;
import tc.oc.commons.bukkit.ticket.TicketListener;
import tc.oc.commons.bukkit.tokens.TokenManifest;
import tc.oc.commons.bukkit.trophies.TrophyCase;
import tc.oc.commons.bukkit.trophies.TrophyCommands;
import tc.oc.commons.bukkit.users.JoinMessageManifest;
@ -110,6 +111,7 @@ public final class CommonsBukkitManifest extends HybridManifest {
install(new LocalizationManifest());
install(new NavigatorManifest());
install(new RaindropManifest());
install(new TokenManifest());
install(new PunishmentManifest());
// These are already bound as facets, so they only need to be exposed

View File

@ -0,0 +1,36 @@
package tc.oc.commons.bukkit.event;
import org.bukkit.entity.Player;
import org.bukkit.event.Event;
import org.bukkit.event.HandlerList;
import tc.oc.commons.bukkit.gui.Interface;
public class InterfaceOpenEvent extends Event {
private static final HandlerList handlers = new HandlerList();
private final Interface gui;
private final Player player;
public InterfaceOpenEvent(Interface gui, Player player) {
this.gui = gui;
this.player = player;
}
public Interface getInterface() {
return this.gui;
}
public Player getPlayer() {
return this.player;
}
public HandlerList getHandlers() {
return handlers;
}
public static HandlerList getHandlerList() {
return handlers;
}
}

View File

@ -0,0 +1,75 @@
package tc.oc.commons.bukkit.gui;
import org.bukkit.entity.HumanEntity;
import org.bukkit.entity.Player;
import org.bukkit.inventory.Inventory;
import tc.oc.commons.bukkit.gui.buttons.Button;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class Interface {
private Player player;
private List<Button> buttons = new ArrayList<>();
private List<Object> data = new ArrayList<>();
public Interface(Player viewer, List<Button> buttons, Object... data) {
setData(data);
setPlayer(viewer);
setButtons(buttons);
}
public void setData(Object... data) {
this.data.clear();
Collections.addAll(this.data, data);
}
public List<Object> getData() {
return this.data;
}
public void setPlayer(Player player) {
this.player = player;
}
public Player getPlayer() {
return this.player;
}
public void setButtons(List<Button> buttons) {
this.buttons = buttons;
}
public List<Button> getButtons() {
return this.buttons;
}
public void updateButtons() {
updateInventory();
}
public void updateInventory() {
try {
long currentTime = System.currentTimeMillis();
for (Button button : getButtons()) {
getInventory().setItem(button.getSlot(), button.getIcon().create());
}
for (HumanEntity player : getInventory().getViewers()) {
player.getOpenInventory().getTopInventory().clear();
for (Button button : getButtons()) {
player.getOpenInventory().setItem(button.getSlot(), button.getIcon().create());
}
// player.openInventory(getInventory().getInventory());
}
} catch (Exception e) {
}
}
public Inventory getInventory() {
return null;
}
}

View File

@ -0,0 +1,12 @@
package tc.oc.commons.bukkit.gui;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.InventoryHolder;
public interface InterfaceHolder extends InventoryHolder {
Inventory getInventory();
Interface getInterface();
}

View File

@ -0,0 +1,68 @@
package tc.oc.commons.bukkit.gui;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.InventoryHolder;
import org.bukkit.inventory.InventoryView;
import org.bukkit.inventory.ItemStack;
import tc.oc.commons.bukkit.gui.buttons.Button;
import java.util.ArrayList;
import java.util.List;
public class InterfaceManager {
private static List<Interface> inventories = new ArrayList<>();
public static void registerInventory(Interface gui) {
inventories.add(gui);
}
public static void unregisterInventories() {
inventories.clear();
}
public static Interface getInterface(InventoryView inventory) {
if (inventory.getTopInventory().getHolder() instanceof SimpleInterfaceHolder) {
SimpleInterfaceHolder holder = (SimpleInterfaceHolder)inventory.getTopInventory().getHolder();
return holder.getInterface();
}
return null;
}
public static Interface getInterface(InventoryHolder holder) {
if (holder instanceof SimpleInterfaceHolder) {
SimpleInterfaceHolder interfaceHolder = (SimpleInterfaceHolder)holder;
return interfaceHolder.getInterface();
}
return null;
}
public static Interface getInterface(Inventory inventory) {
for (Interface gui : inventories) {
if (gui.getInventory().equals(inventory)) {
return gui;
}
}
return null;
}
public static List<Button> getButtons(Interface gui, int slot) {
List<Button> buttons = new ArrayList<>();
for (Button button : gui.getButtons()) {
if (button.getSlot() == slot) {
buttons.add(button);
}
}
return buttons;
}
public static Button getButton(Interface gui, ItemStack itemStack) {
for (Button button : gui.getButtons()) {
if (button.getIcon().create().equals(itemStack)) {
return button;
}
}
return null;
}
}

View File

@ -0,0 +1,32 @@
package tc.oc.commons.bukkit.gui;
import org.bukkit.World;
import org.bukkit.inventory.Inventory;
public class SimpleInterfaceHolder implements InterfaceHolder {
private Inventory inventory;
private Interface gui;
private World world;
public SimpleInterfaceHolder(Inventory inventory, Interface gui, World world) {
this.inventory = inventory;
this.gui = gui;
this.world = world;
}
@Override
public Inventory getInventory() {
return this.inventory;
}
@Override
public Interface getInterface() {
return this.gui;
}
@Override
public World getWorld() {
return world;
}
}

View File

@ -0,0 +1,62 @@
package tc.oc.commons.bukkit.gui.buttons;
import org.bukkit.entity.Player;
import tc.oc.commons.bukkit.util.ItemCreator;
/**
* Button's are used as a way to allow players to interact with inventories. Interfaces contain buttons. When a button
* is clicked, the function() method is fired, which can customized in special buttons to perform functions which the
* button defines.
*/
public class Button {
private ItemCreator icon;
private Integer slot = 0;
public Button(ItemCreator icon) {
setIcon(icon);
}
public Button(int slot) {
setSlot(slot);
}
public Button(ItemCreator icon, int slot) {
setIcon(icon);
setSlot(slot);
}
public void setIcon(ItemCreator icon) {
this.icon = icon;
}
/**
* This is what the button looks like in an interface.
* @return the item
*/
public ItemCreator getIcon() {
return this.icon;
}
public void setSlot(int slot) {
this.slot = slot;
}
/**
* If the page is looking for a specific slot for the item, this is where it will go.
* @return the slot
*/
public Integer getSlot() {
return this.slot;
}
/**
* This is an action that the button performs. Typically overrided with a new function to be used to carry out
* various actions.
*/
public void function(Player player) {
}
}

View File

@ -0,0 +1,13 @@
package tc.oc.commons.bukkit.gui.buttons.empty;
import tc.oc.commons.bukkit.gui.buttons.Button;
import tc.oc.commons.bukkit.util.ItemCreator;
import org.bukkit.Material;
public class EmptyButton extends Button {
public EmptyButton(int slot) {
super(new ItemCreator(Material.AIR), slot);
}
}

View File

@ -0,0 +1,72 @@
package tc.oc.commons.bukkit.gui.buttons.lastPage;
import tc.oc.commons.bukkit.gui.Interface;
import tc.oc.commons.bukkit.gui.InterfaceManager;
import tc.oc.commons.bukkit.gui.buttons.Button;
import tc.oc.commons.bukkit.gui.interfaces.ChestInterface;
import tc.oc.commons.bukkit.gui.interfaces.SinglePageInterface;
import tc.oc.commons.bukkit.util.Constants;
import tc.oc.commons.bukkit.util.ItemCreator;
import org.bukkit.Material;
import org.bukkit.entity.Player;
public class LastPageButton extends Button {
private SinglePageInterface page;
public LastPageButton(int slot) {
super(null, slot);
}
public LastPageButton(SinglePageInterface gui, int slot) {
super(null, slot);
this.page = gui;
}
public SinglePageInterface getPage() {
return this.page;
}
public Interface getLastPage(ChestInterface gui) {
if (this.page == null) {
return gui.getParent();
}
try {
int page = this.page.page;
Interface previousInterface = getPage().getParent() != null ? getPage().getParent() : gui;
try {
Interface gui1 = /*page != 0 ? new SinglePageInterface(this.page.rawButtons, this.page.getSize(), this.page.rawTitle, this.page.getParent(), this.page.page - 1) :*/ previousInterface;
if (gui1 instanceof SinglePageInterface) {
// ((SinglePageInterface)gui1).updateButtons();
}
return gui1;
} catch (Exception e) {
return previousInterface;
}
} catch (Exception e) {
return gui;
}
}
@Override
public ItemCreator getIcon() {
return new ItemCreator(Material.BARRIER)
.setName(Constants.PREFIX + "Previous");
}
@Override
public void function(Player player) {
Interface currentInterface = InterfaceManager.getInterface(player.getOpenInventory());
//Interface lastPage = getLastPage((ChestInterface)currentInterface);
//player.openInventory(lastPage.getInventory());
if (currentInterface instanceof SinglePageInterface) {
((SinglePageInterface)currentInterface).openLastPage(player);
} else {
Interface parent = ((ChestInterface) currentInterface).getParent();
player.openInventory(parent.getInventory());
//parent.updateButtons();
}
}
}

View File

@ -0,0 +1,57 @@
package tc.oc.commons.bukkit.gui.buttons.nextPage;
import tc.oc.commons.bukkit.gui.Interface;
import tc.oc.commons.bukkit.gui.InterfaceManager;
import tc.oc.commons.bukkit.gui.buttons.Button;
import tc.oc.commons.bukkit.gui.interfaces.ChestOptionsPageInterface;
import tc.oc.commons.bukkit.gui.interfaces.SinglePageInterface;
import tc.oc.commons.bukkit.util.Constants;
import tc.oc.commons.bukkit.util.ItemCreator;
import org.bukkit.Material;
import org.bukkit.entity.Player;
/**
* Created by ShinyDialga45 on 4/10/2015.
*/
public class NextPageButton extends Button {
private SinglePageInterface page;
public NextPageButton(int slot) {
super(null, slot);
}
public NextPageButton(SinglePageInterface gui, int slot) {
super(null, slot);
this.page = gui;
}
public SinglePageInterface getNextPage(SinglePageInterface chestInterface) {
try {
if (chestInterface instanceof ChestOptionsPageInterface) {
ChestOptionsPageInterface nextPage = new ChestOptionsPageInterface(this.page.rawButtons, this.page.getSize(), this.page.rawTitle, this.page, this.page.page + 1);
nextPage.update();
return nextPage != null ? nextPage : chestInterface;
}
SinglePageInterface nextPage = new SinglePageInterface(this.page.getPlayer(), this.page.rawButtons, this.page.getSize(), this.page.rawTitle, this.page, this.page.page + 1);
nextPage.update();
return nextPage != null ? nextPage : chestInterface;
} catch (Exception e) {
return chestInterface;
}
}
@Override
public ItemCreator getIcon() {
return new ItemCreator(Material.ARROW)
.setName(Constants.PREFIX + "Next");
}
@Override
public void function(Player player) {
Interface currentInterface = InterfaceManager.getInterface(player.getOpenInventory());
//Interface nextPage = getNextPage((SinglePageInterface) currentInterface);
((SinglePageInterface)currentInterface).openNextPage();
}
}

View File

@ -0,0 +1,27 @@
package tc.oc.commons.bukkit.gui.buttons.toggle;
import tc.oc.commons.bukkit.gui.buttons.Button;
import tc.oc.commons.bukkit.util.ItemCreator;
/**
* Created by ShinyDialga45 on 4/10/2015.
*/
public class ToggleButton extends Button {
private boolean state = false;
public ToggleButton(ItemCreator itemCreator, boolean state) {
super(itemCreator);
setState(state);
}
public boolean getState() {
return state;
}
public void setState(boolean state) {
this.state = state;
}
}

View File

@ -0,0 +1,4 @@
package tc.oc.commons.bukkit.gui.buttons.toggle.type;
public class BooleanToggleType {
}

View File

@ -0,0 +1,11 @@
package tc.oc.commons.bukkit.gui.buttons.toggle.type;
public class EnumToggleType extends ToggleType {
private int value;
public EnumToggleType() {
}
}

View File

@ -0,0 +1,4 @@
package tc.oc.commons.bukkit.gui.buttons.toggle.type;
public class ToggleType {
}

View File

@ -0,0 +1,63 @@
package tc.oc.commons.bukkit.gui.interfaces;
import tc.oc.commons.bukkit.gui.Interface;
import tc.oc.commons.bukkit.gui.SimpleInterfaceHolder;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.bukkit.inventory.Inventory;
import tc.oc.commons.bukkit.gui.buttons.Button;
import java.util.List;
public class ChestInterface extends Interface {
private int size;
public Interface parent;
private Inventory inventory;
private String title;
public ChestInterface(Player player, List<Button> buttons, int size, String title, Interface parent) {
super(player, buttons);
setSize(size);
setTitle(title);
setParent(parent);
this.inventory = Bukkit.createInventory(new SimpleInterfaceHolder(inventory, this, player.getWorld()), getSize(), getTitle());
//setInventory(new InterfaceInventory(this, inventory));
}
public void setSize(int size) {
//If the size isn't a multiple of 9, round it to the nearest multiple of 9.
if (size % 9 != 0) {
setSize(9*(Math.round(size / 9)));
} else {
this.size = size;
}
}
public int getSize() {
return this.size;
}
public void setTitle(String title) {
int titleSize = 32;
this.title = title.length() > titleSize ? title.substring(0, titleSize - 1) : title;
}
public String getTitle() {
return this.title;
}
public void setParent(Interface parent) {
this.parent = parent;
}
public Interface getParent() {
return this.parent;
}
@Override
public Inventory getInventory() {
return this.inventory;
}
}

View File

@ -0,0 +1,146 @@
package tc.oc.commons.bukkit.gui.interfaces;
import tc.oc.commons.bukkit.gui.Interface;
import tc.oc.commons.bukkit.gui.buttons.Button;
import tc.oc.commons.bukkit.gui.buttons.empty.EmptyButton;
import tc.oc.commons.bukkit.gui.buttons.toggle.ToggleButton;
import tc.oc.commons.bukkit.util.Constants;
import tc.oc.commons.bukkit.util.ItemCreator;
import tc.oc.commons.bukkit.util.ObjectUtils;
import org.bukkit.ChatColor;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import java.util.ArrayList;
import java.util.List;
/**
* MultiPageInterfaces are a special group of interfaces. They aren't a single interface, but a collection of
* SinglePageInterfaces. Given a set of buttons, it will add them to a page with default items in order. This can be
* used as a way to provide a list of non-hardcoded items without having to define their slots.
*/
public class ChestOptionsPageInterface extends SinglePageInterface {
public ChestOptionsPageInterface(List<Button> buttons, int size, String title, Interface parent) {
this(null, buttons, size, title, parent, 1);
}
public ChestOptionsPageInterface(List<Button> buttons, int size, String title, Interface parent, int i) {
this(null, buttons, size, title, parent, i);
}
public ChestOptionsPageInterface(Player player, List<Button> buttons, int size, String title, Interface parent) {
this(player, buttons, size, title, parent, 1);
}
public ChestOptionsPageInterface(Player player, List<Button> buttons, int size, String title, Interface parent, int i, Object... data) {
super(player, buttons, size, title + (i > 1 ? " - " + i : ""), parent, 1, data);
}
@Override
public void updateButtons() {
if (getButtons().size() == 0) {
List<Button> buttons = new ArrayList<>();
for (Button button : getDefaultButtons()) {
button.setSlot(getNextSlot(button.getSlot(), buttons));
if (button.getSlot() < getSize()) {
buttons.add(button);
}
}
Button empty = new Button(
new ItemCreator(Material.DEAD_BUSH)
.setName(Constants.PREFIX + "Nothing here..."));
empty.setSlot(getNextSlot(empty.getSlot(), buttons));
if (empty.getSlot() < getSize()) {
buttons.add(empty);
}
buttons.remove(this.nextPageButton);
setButtons(buttons);
updateInventory();
return;
}
int allButtons = getDefaultButtons().size() + getButtons().size()*2;
//This tells the plugin how many pages are needed to store all of the items.
int allPages = (int)((double) ((allButtons) / (getSize() - getDefaultButtons().size())));
if (((getButtons().size() + 1) % (getSize() - getDefaultButtons().size()) == 0) && allPages > 1) {
allPages = allPages - 1;
}
if (allButtons < getSize()) {
allPages = 1;
}
if (allPages >= 3) {
//allPages = allPages - 1;
}
//This gets the items for the page it is currently on.
List<Button> buttons = ObjectUtils.paginate(getButtons(), page, (getSize() - getDefaultButtons().size())/2);
try {
if (buttons.size() != 0) {
ArrayList<Button> currentButtons = new ArrayList<>();
for (Button button : getDefaultButtons()) {
if (button.equals(this.lastPageButton)) {
button.setIcon(button.getIcon().setSize(page - 1));
} else if (button.equals(this.nextPageButton)) {
button.setIcon(button.getIcon().setSize(page + 1));
}
button.setSlot(button.getSlot());
if (button.getSlot() > getSize()) {
break;
}
currentButtons.add(button);
}
int currentButton = 0;
for (Button button : buttons) {
if (buttons.indexOf(button) > 0 && buttons.get(buttons.size() - 1).equals(button) && page == (allPages)) {
// break;
}
final ToggleButton toggleButton = (ToggleButton) button;
toggleButton.setSlot(getNextSlot(currentButton, currentButtons));
ItemCreator dye = new ItemCreator(Material.INK_SACK)
.setData(toggleButton.getState() == true ? 10 : 8)
.setName((toggleButton.getState() == true ? ChatColor.GREEN : ChatColor.RED) + ChatColor.BOLD.toString() + (toggleButton.getState() == true ? "Enabled" : "Disabled"));
Button toggleDye = new Button(dye) {
@Override
public void function(Player player) {
toggleButton.function(player);
}
};
toggleDye.setSlot(toggleButton.getSlot() + 9);
if (button.getSlot() > getSize()) {
break;
}
currentButtons.add(toggleButton);
currentButtons.add(toggleDye);
currentButton = toggleButton.getSlot();
}
if (allPages == page) {
currentButtons.remove(this.nextPageButton);
}
setButtons(currentButtons);
updateInventory();
}
} catch (Exception e) {
if (page > 0) {
page = page - 1;
updateButtons();
}
}
}
@Override
public void setDefaultButtons() {
defaultButtons.clear();
for (Integer integer : new Integer[]{1, 2, 3, 4, 5, 6, 7, 9, 17, 18, 26, 27, 35, 36, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 11, 20, 29, 38, 13, 22, 31, 40, 15, 24, 33, 42}) {
if (integer > getSize()) {
break;
}
EmptyButton button = new EmptyButton(integer);
defaultButtons.add(button);
}
defaultButtons.add(this.lastPageButton);
defaultButtons.add(this.nextPageButton);
}
}

View File

@ -0,0 +1,172 @@
package tc.oc.commons.bukkit.gui.interfaces;
import tc.oc.commons.bukkit.gui.Interface;
import tc.oc.commons.bukkit.gui.buttons.Button;
import tc.oc.commons.bukkit.gui.buttons.empty.EmptyButton;
import tc.oc.commons.bukkit.util.Constants;
import tc.oc.commons.bukkit.util.ItemCreator;
import tc.oc.commons.bukkit.util.ObjectUtils;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.inventory.Inventory;
import java.util.ArrayList;
import java.util.List;
/**
* MultiPageInterfaces are a special group of interfaces. They aren't a single interface, but a collection of
* SinglePageInterfaces. Given a set of buttons, it will add them to a page with default items in order. This can be
* used as a way to provide a list of non-hardcoded items without having to define their slots.
*/
@Deprecated
public class ChestPageInterface extends ChestInterface {
private List<ChestInterface> pages = new ArrayList<>();
// public final LastPageButton lastPageButton = new LastPageButton(this, 0); TODO
//public final NextPageButton nextPageButton = new NextPageButton(this, 8);
public ChestPageInterface(List<Button> buttons, int size, String title, Interface parent) {
this(null, buttons, size, title, parent);
}
public ChestPageInterface(Player player, List<Button> buttons, int size, String title, Interface parent, Object... data) {
super(player, buttons, size, title, parent);
/*
MultiPageInterfaces must be contain necessary default items, if it cannot contain the next page item
(currently has the highest slot value of a necessary default item), it won't allow proper navagation.
*/
setData(data);
//setSize((size >= this.nextPageButton.getSlot() + 1 ? size : this.nextPageButton.getSlot() + 1));
}
public void setupInventory() {
pages.clear();
if (getButtons().size() == 0) {
List<Button> buttons = new ArrayList<>();
for (Button button : getDefaultButtons()) {
button.setSlot(getNextSlot(button.getSlot(), buttons));
if (button.getSlot() < getSize()) {
buttons.add(button);
}
}
Button empty = new Button(
new ItemCreator(Material.DEAD_BUSH)
.setName(Constants.PREFIX + "Nothing here..."));
empty.setSlot(getNextSlot(empty.getSlot(), buttons));
if (empty.getSlot() < getSize()) {
buttons.add(empty);
}
pages.add(new ChestInterface(null, buttons, getSize(), getTitle(), getParent()));
return;
}
int allButtons = getDefaultButtons().size() + getButtons().size();
//This tells the plugin how many pages are needed to store all of the items.
int allPages = (int) Math.round((double) (allButtons) / (getSize() - getDefaultButtons().size()));
if (((getButtons().size() + 1) % (getSize() - getDefaultButtons().size()) == 0) && allPages > 1) {
allPages = allPages - 1;
}
if (allPages >= 3) {
allPages = allPages - 1;
}
for (int i = 1; i <= allPages; i++) {
//This gets the items for the page it is currently on.
List<Button> buttons = ObjectUtils.paginate(getButtons(), i, getSize() - getDefaultButtons().size());
if (allButtons < getSize()) {
allPages = 1;
}
if (buttons.size() != 0) {
ArrayList<Button> currentButtons = new ArrayList<>();
for (Button button : getDefaultButtons()) {
button.setSlot(button.getSlot());
if (button.getSlot() > getSize()) {
break;
}
currentButtons.add(button);
}
int currentButton = 0;
for (Button button : buttons) {
button.setSlot(getNextSlot(currentButton, currentButtons));
if (button.getSlot() > getSize()) {
break;
}
currentButtons.add(button);
currentButton++;
}
if (allPages == i) {
// currentButtons.remove(this.nextPageButton);
}
String suffix = i > 1 ? " - " + i : "";
ChestInterface gui = new ChestInterface(null, currentButtons, getSize(), getTitle() + suffix, getParent());
gui.updateInventory();
pages.add(gui);
}
}
}
public void setPages(List<ChestInterface> pages) {
this.pages = pages;
}
public List<ChestInterface> getPages() {
return this.pages;
}
public int getNextSlot(int slot, List<Button> buttons) {
for (Button button : buttons) {
if (button.getSlot() == slot) {
return getNextSlot(slot + 1, buttons);
}
}
return slot;
}
/*
Inventory guide.
00 01 02 03 04 05 06 07 08
09 10 11 12 13 14 15 16 17
18 19 20 21 22 23 24 25 26
27 28 29 30 31 32 33 34 35
36 37 38 39 40 41 42 43 44
45 46 47 48 49 50 51 52 53
Key:
p = Page arrow
x = Empty space
o = Paginated item
Current inventory layout
p x x x x x x x p
x o o o o o o o x
x o o o o o o o x
x o o o o o o o x
x o o o o o o o x
x x x x x x x x x
Everything is easily customizable. The methods take currently taken slots into consideration.
*/
public List<Button> getDefaultButtons() {
List<Button> buttons = new ArrayList<>();
for (Integer integer : new Integer[]{1, 2, 3, 4, 5, 6, 7, 9, 17, 18, 26, 27, 35, 36, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53}) {
if (integer > getSize()) {
break;
}
EmptyButton button = new EmptyButton(integer);
buttons.add(button);
}
//buttons.add(this.lastPageButton); TODO
// buttons.add(this.nextPageButton);
//if (this.nextPageButton.getSlot() < getSize()) {
//}
return buttons;
}
@Override
public Inventory getInventory() {
return getPages().get(0).getInventory();
}
}

View File

@ -0,0 +1,54 @@
package tc.oc.commons.bukkit.gui.interfaces;
import tc.oc.commons.bukkit.gui.Interface;
import tc.oc.commons.bukkit.gui.SimpleInterfaceHolder;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.bukkit.event.inventory.InventoryType;
import org.bukkit.inventory.Inventory;
import tc.oc.commons.bukkit.gui.buttons.Button;
import java.util.List;
public class HopperInterface extends Interface {
private int size;
private Interface parent;
private Inventory inventory;
private String title;
public HopperInterface(Player player, List<Button> buttons, String title, Interface parent) {
super(player, buttons);
setTitle(title);
setParent(parent);
this.inventory = Bukkit.createInventory(new SimpleInterfaceHolder(inventory, this, player.getWorld()), InventoryType.HOPPER, getTitle());
/*//this.inventory = player.getInventory();
//inventory = Bukkit.createInventory(new SimpleInterfaceHolder(inventory, this), InventoryType.valueOf(args), getTitle());
//setInventory(new InterfaceInventory(this, inventory));
updateButtons();
updateInventory();*/
}
public void setTitle(String title) {
int titleSize = 32;
this.title = title.length() > titleSize ? title.substring(0, titleSize - 1) : title;
}
public String getTitle() {
return this.title;
}
public void setParent(Interface parent) {
this.parent = parent;
}
public Interface getParent() {
return this.parent;
}
@Override
public Inventory getInventory() {
return this.inventory;
}
}

View File

@ -0,0 +1,25 @@
package tc.oc.commons.bukkit.gui.interfaces;
import org.bukkit.inventory.Inventory;
import tc.oc.commons.bukkit.gui.Interface;
public class InterfaceInventory {
private Interface gui;
private Inventory inventory;
public InterfaceInventory(Interface gui, Inventory inventory) {
//InterfaceManager.registerInventory(this);
this.gui = gui;
this.inventory = inventory;
}
public Interface getInterface() {
return this.gui;
}
public Inventory getInventory() {
return this.inventory;
}
}

View File

@ -0,0 +1,201 @@
package tc.oc.commons.bukkit.gui.interfaces;
import tc.oc.commons.bukkit.gui.Interface;
import tc.oc.commons.bukkit.gui.buttons.Button;
import tc.oc.commons.bukkit.gui.buttons.empty.EmptyButton;
import tc.oc.commons.bukkit.gui.buttons.lastPage.LastPageButton;
import tc.oc.commons.bukkit.gui.buttons.nextPage.NextPageButton;
import tc.oc.commons.bukkit.util.Constants;
import tc.oc.commons.bukkit.util.ItemCreator;
import tc.oc.commons.bukkit.util.ObjectUtils;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import java.util.ArrayList;
import java.util.List;
/**
* MultiPageInterfaces are a special group of interfaces. They aren't a single interface, but a collection of
* SinglePageInterfaces. Given a set of buttons, it will add them to a page with default items in order. This can be
* used as a way to provide a list of non-hardcoded items without having to define their slots.
*/
public class SinglePageInterface extends ChestInterface {
public List<Button> defaultButtons = new ArrayList<>();
public int page;
public String rawTitle;
public List<Button> rawButtons = new ArrayList<>();
public final LastPageButton lastPageButton = new LastPageButton(this, 0);
public final NextPageButton nextPageButton = new NextPageButton(this, 8);
public SinglePageInterface(Player player, List<Button> buttons, int size, String title, Interface parent) {
this(player, buttons, size, title, parent, 1);
}
public SinglePageInterface(Player player, List<Button> buttons, int size, String title, Interface parent, int page, Object... data) {
super(player, buttons, size, title + (page > 1 ? " - " + page : ""), parent);
this.rawTitle = title;
this.rawButtons = buttons;
/*
MultiPageInterfaces must be contain necessary default items, if it cannot contain the next page item
(currently has the highest slot value of a necessary default item), it won't allow proper navagation.
*/
setData(data);
this.page = page;
setSize((size >= this.nextPageButton.getSlot() + 1 ? size : this.nextPageButton.getSlot() + 1));
}
public void openLastPage(Player player) {
page = page - 1;
if (page > 0) {
update();
} else {
player.openInventory(getParent().getInventory());
//getParent().updateButtons();
}
}
public void openNextPage() {
page = page + 1;
update();
}
public void update() {
setButtons();
rawButtons = getButtons();
setDefaultButtons();
updateButtons();
}
public void setButtons() {
setButtons(getButtons());
}
@Override
public void updateButtons() {
if (getButtons().size() == 0) {
List<Button> buttons = new ArrayList<>();
for (Button button : getDefaultButtons()) {
button.setSlot(getNextSlot(button.getSlot(), buttons));
if (button.getSlot() < getSize()) {
buttons.add(button);
}
}
Button empty = new Button(
new ItemCreator(Material.DEAD_BUSH)
.setName(Constants.PREFIX + "Nothing here..."));
empty.setSlot(getNextSlot(empty.getSlot(), buttons));
if (empty.getSlot() < getSize()) {
buttons.add(empty);
}
buttons.remove(this.nextPageButton);
setButtons(buttons);
updateInventory();
return;
}
int allButtons = getDefaultButtons().size() + getButtons().size();
//This tells the plugin how many pages are needed to store all of the items.
int allPages = (int) Math.round((double) (allButtons) / (getSize() - getDefaultButtons().size()));
if (((getButtons().size() + 1) % (getSize() - getDefaultButtons().size()) == 0) && allPages > 1) {
allPages = allPages - 1;
}
if (allPages >= 3) {
// allPages = allPages - 1;
}
//This gets the items for the page it is currently on.
List<Button> buttons = ObjectUtils.paginate(getButtons(), page, getSize() - getDefaultButtons().size());
if (allButtons < getSize()) {
allPages = 1;
}
try {
if (buttons.size() != 0) {
ArrayList<Button> currentButtons = new ArrayList<>();
for (Button button : getDefaultButtons()) {
button.setSlot(button.getSlot());
if (button.getSlot() > getSize()) {
break;
}
currentButtons.add(button);
}
int currentButton = 0;
for (Button button : buttons) {
button.setSlot(getNextSlot(currentButton, currentButtons));
if (button.getSlot() > getSize()) {
break;
}
currentButtons.add(button);
currentButton++;
}
if (allPages == page) {
currentButtons.remove(this.nextPageButton);
}
setButtons(currentButtons);
updateInventory();
}
} catch (Exception e) {
if (page > 0) {
page = page - 1;
updateButtons();
}
}
}
public int getNextSlot(int slot, List<Button> buttons) {
for (Button button : buttons) {
if (button.getSlot() == slot) {
return getNextSlot(slot + 1, buttons);
}
}
return slot;
}
public void setDefaultButtons() {
defaultButtons.clear();
defaultButtons.add(this.lastPageButton);
defaultButtons.add(this.nextPageButton);
for (Integer integer : new Integer[]{1, 2, 3, 4, 5, 6, 7, 9, 17, 18, 26, 27, 35, 36, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53}) {
if (integer > getSize()) {
break;
}
EmptyButton button = new EmptyButton(integer);
defaultButtons.add(button);
}
//if (this.nextPageButton.getSlot() < getSize()) {
//}
}
/*
Inventory guide.
00 01 02 03 04 05 06 07 08
09 10 11 12 13 14 15 16 17
18 19 20 21 22 23 24 25 26
27 28 29 30 31 32 33 34 35
36 37 38 39 40 41 42 43 44
45 46 47 48 49 50 51 52 53
Key:
p = Page arrow
x = Empty space
o = Paginated item
Current inventory layout
p x x x x x x x p
x o o o o o o o x
x o o o o o o o x
x o o o o o o o x
x o o o o o o o x
x x x x x x x x x
Everything is easily customizable. The methods take currently taken slots into consideration.
*/
public List<Button> getDefaultButtons() {
return this.defaultButtons;
}
}

View File

@ -0,0 +1,111 @@
package tc.oc.commons.bukkit.gui.interfaces.render;
import tc.oc.commons.bukkit.gui.Interface;
import tc.oc.commons.bukkit.gui.buttons.Button;
import tc.oc.commons.bukkit.gui.interfaces.ChestInterface;
import tc.oc.commons.bukkit.util.ItemCreator;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import java.util.ArrayList;
import java.util.List;
public class ChestRenderInterface extends ChestInterface {
private Coordinate origin;
public ChestRenderInterface(Player player, List<Button> buttons, int size, String title, Interface parent) {
super(player, buttons, size, title, parent);
this.origin = new Coordinate(0, 0);
}
public int getRenderSlot(Coordinate index) {
double currentX = getOrigin().getX();
double currentY = getOrigin().getY();
for (int i = 0; i < getSize(); i++) {
Coordinate coordinate = new Coordinate(currentX, currentY);
//Bukkit.broadcastMessage(index.getX() + " " + coordinate.getX() + " " + getOrigin().getX());
//Bukkit.broadcastMessage(index.getY() + " " + coordinate.getY() + " " + getOrigin().getY());
if (index.getX() == coordinate.getX() && index.getY() == coordinate.getY()) {
return i;
}
if (((i + 1) % 9) == 0) {
currentX = getOrigin().getX();
currentY--;
} else {
currentX++;
}
}
return -1;
}
public Coordinate getOrigin() {
return this.origin != null ? this.origin : new Coordinate(0, 0);
}
public void setOrigin(Coordinate origin) {
this.origin = origin;
}
@Override
public void updateButtons() {
List<Button> buttons = new ArrayList<>();
List<Coordinate> coordinates = new ArrayList<>();
for (final Coordinate coordinate : coordinates) {
int renderSlot = getRenderSlot(coordinate);
if (renderSlot >= 0) {
Button button = new Button(new ItemCreator(Material.DIRT).setName(coordinate.getX() + " " + coordinate.getY()), renderSlot) {
@Override
public void function(Player player) {
Bukkit.broadcastMessage(coordinate.getX() + " " + coordinate.getY());
}
};
buttons.add(button);
}
}
Button up = new Button(new ItemCreator(Material.ARROW)
.setName(ChatColor.GREEN + "Move Up"), 7) {
@Override
public void function(Player player) {
setOrigin(new Coordinate(getOrigin().getX(), getOrigin().getY() + 1));
updateButtons();
}
};
buttons.add(up);
Button down = new Button(new ItemCreator(Material.ARROW)
.setName(ChatColor.GREEN + "Move Down"), 25) {
@Override
public void function(Player player) {
setOrigin(new Coordinate(getOrigin().getX(), getOrigin().getY() - 1));
updateButtons();
}
};
buttons.add(down);
Button left = new Button(new ItemCreator(Material.ARROW)
.setName(ChatColor.GREEN + "Move Left"), 15) {
@Override
public void function(Player player) {
setOrigin(new Coordinate(getOrigin().getX() - 1, getOrigin().getY()));
updateButtons();
}
};
buttons.add(left);
Button right = new Button(new ItemCreator(Material.ARROW)
.setName(ChatColor.GREEN + "Move Right"), 17) {
@Override
public void function(Player player) {
setOrigin(new Coordinate(getOrigin().getX() + 1, getOrigin().getY()));
updateButtons();
}
};
buttons.add(right);
Button compass = new Button(new ItemCreator(Material.COMPASS)
.setName(ChatColor.GREEN + "Use these to move!"), 16);
buttons.add(compass);
setButtons(buttons);
updateInventory();
}
}

View File

@ -0,0 +1,29 @@
package tc.oc.commons.bukkit.gui.interfaces.render;
public class Coordinate {
private double x = 0;
private double y = 0;
public Coordinate(double x, double y) {
setX(x);
setY(y);
}
public double getX() {
return this.x;
}
public void setX(double x) {
this.x = x;
}
public double getY() {
return this.y;
}
public void setY(double y) {
this.y = y;
}
}

View File

@ -0,0 +1,431 @@
package tc.oc.commons.bukkit.gui.interfaces.render.text;
import tc.oc.commons.bukkit.gui.Interface;
import tc.oc.commons.bukkit.gui.buttons.Button;
import tc.oc.commons.bukkit.gui.interfaces.render.ChestRenderInterface;
import tc.oc.commons.bukkit.gui.interfaces.render.Coordinate;
import tc.oc.commons.bukkit.util.ItemCreator;
import org.bukkit.ChatColor;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import java.util.*;
public class GridTextRenderInterface extends ChestRenderInterface {
private String text;
public GridTextRenderInterface(Player player, List<Button> buttons, int size, String title, Interface parent, String text) {
super(player, buttons, size, title, parent);
this.text = text;
}
public String getText() {
return this.text;
}
@Override
public void updateButtons() {
List<Button> buttons = new ArrayList<>();
List<Letter> letters = new ArrayList<>();
for (char c : getText().toCharArray()) {
letters.add(Letter.getLetter(c));
}
double totalX = 0;
for (Letter letter : letters) {
for (final Coordinate coordinate : letter.getCoordinates().keySet()) {
Coordinate newCoordinate = new Coordinate(coordinate.getX(), coordinate.getY());
newCoordinate.setX(coordinate.getX() + totalX);
int renderSlot = getRenderSlot(newCoordinate);
if (renderSlot >= 0) {
ItemCreator itemCreator = letter.getCoordinates().get(coordinate) != null ? letter.getCoordinates().get(coordinate) : new ItemCreator(Material.WOOL).setData(6);
Button button = new Button(itemCreator.setName(newCoordinate.getX() + " " + newCoordinate.getY()), renderSlot);
buttons.add(button);
}
}
totalX = totalX + letter.getLength() + 1;
}
Button up = new Button(new ItemCreator(Material.ARROW)
.setName(ChatColor.GREEN + "Move Up"), 7) {
@Override
public void function(Player player) {
setOrigin(new Coordinate(getOrigin().getX(), getOrigin().getY() + 1));
updateButtons();
}
};
buttons.add(up);
Button down = new Button(new ItemCreator(Material.ARROW)
.setName(ChatColor.GREEN + "Move Down"), 25) {
@Override
public void function(Player player) {
setOrigin(new Coordinate(getOrigin().getX(), getOrigin().getY() - 1));
updateButtons();
}
};
buttons.add(down);
Button left = new Button(new ItemCreator(Material.ARROW)
.setName(ChatColor.GREEN + "Move Left"), 15) {
@Override
public void function(Player player) {
setOrigin(new Coordinate(getOrigin().getX() - 1, getOrigin().getY()));
updateButtons();
}
};
buttons.add(left);
Button right = new Button(new ItemCreator(Material.ARROW)
.setName(ChatColor.GREEN + "Move Right"), 17) {
@Override
public void function(Player player) {
setOrigin(new Coordinate(getOrigin().getX() + 1, getOrigin().getY()));
updateButtons();
}
};
buttons.add(right);
Button compass = new Button(new ItemCreator(Material.COMPASS)
.setName(ChatColor.GREEN + "Use these to move!"), 16);
buttons.add(compass);
setButtons(buttons);
updateInventory();
}
public enum Letter {
A(
'A',
Arrays.asList(
"_X_",
"X_X",
"X_X",
"XXX",
"X_X")),
B(
'B',
Arrays.asList(
"XX_",
"X_X",
"XX_",
"X_X",
"XX_")),
C(
'C',
Arrays.asList(
"_XX",
"X__",
"X__",
"X__",
"_XX")),
D(
'D',
Arrays.asList(
"XX_",
"X_X",
"X_X",
"X_X",
"XX_")),
E(
'E',
Arrays.asList(
"XXX",
"X__",
"XX_",
"X__",
"XXX")),
F(
'F',
Arrays.asList(
"XXX",
"X__",
"XX_",
"X__",
"X__")),
G(
'G',
Arrays.asList(
"XXX",
"X__",
"X__",
"X_X",
"XXX")),
H(
'H',
Arrays.asList(
"X_X",
"X_X",
"XXX",
"X_X",
"X_X")),
I(
'I',
Arrays.asList(
"XXX",
"_X_",
"_X_",
"_X_",
"XXX")),
J(
'J',
Arrays.asList(
"__X",
"__X",
"__X",
"X_X",
"XXX")),
K(
'K',
Arrays.asList(
"X_X",
"X_X",
"XX_",
"X_X",
"X_X")),
L(
'L',
Arrays.asList(
"X__",
"X__",
"X__",
"X__",
"XXX")),
M(
'M',
Arrays.asList(
"X_X",
"XXX",
"X_X",
"X_X",
"X_X")),
N(
'N',
Arrays.asList(
"X__X",
"XX_X",
"X_XX",
"X__X",
"X__X")),
O(
'O',
Arrays.asList(
"XXX",
"X_X",
"X_X",
"X_X",
"XXX")),
P(
'P',
Arrays.asList(
"XXX",
"X_X",
"XXX",
"X__",
"X__")),
Q(
'Q',
Arrays.asList(
"XXX",
"X_X",
"X_X",
"XX_",
"__X")),
R(
'R',
Arrays.asList(
"XXX",
"X_X",
"XX_",
"X_X",
"X_X")),
S(
'S',
Arrays.asList(
"XXX",
"X__",
"XXX",
"__X",
"XXX")),
T(
'T',
Arrays.asList(
"XXX",
"_X_",
"_X_",
"_X_",
"_X_")),
U(
'U',
Arrays.asList(
"X_X",
"X_X",
"X_X",
"X_X",
"XXX")),
V(
'V',
Arrays.asList(
"X_X",
"X_X",
"X_X",
"X_X",
"_X_")),
W(
'W',
Arrays.asList(
"X_X",
"X_X",
"XXX",
"XXX",
"X_X")),
X(
'X',
Arrays.asList(
"X_X",
"X_X",
"_X_",
"X_X",
"X_X")),
Y(
'Y',
Arrays.asList(
"X_X",
"X_X",
"_X_",
"_X_",
"_X_")),
Z(
'Z',
Arrays.asList(
"XXX",
"__X",
"_X_",
"X__",
"XXX")),
SPACE(
' ',
Arrays.asList(
"_",
"_",
"_",
"_",
"_")),
COLON(
':',
Arrays.asList(
"_",
"X",
"_",
"X",
"_")),
RIGHT_PARENTHESIS(
')',
Arrays.asList(
"X_",
"_X",
"_X",
"_X",
"X_"));
private char letter;
private List<String> lines = new ArrayList<>();
private HashMap<Coordinate, ItemCreator> coordinates = new HashMap<>();
private ItemCreator itemCreator;
Letter(char letter, List<String> lines) {
this.letter = letter;
this.lines = lines;
this.coordinates = draw();
}
Letter(char letter, List<String> lines, ItemCreator itemCreator) {
this.letter = letter;
this.lines = lines;
this.itemCreator = itemCreator;
this.coordinates = draw();
}
public static Letter getLetter(char c) {
for (Letter letter : values()) {
if (letter.getLetter() == c) {
return letter;
}
}
return A;
}
public static double getLength(String text) {
double length = 0;
for (char c : text.toCharArray()) {
length = length + Letter.getLetter(c).getLength();
if (c != ' ') {
length = length + 1;
} else {
length = length + 2;
}
}
return length;
}
public HashMap<Coordinate, ItemCreator> draw() {
HashMap<Coordinate, ItemCreator> map = new HashMap<>();
int currentX = 0;
int currentY = 0;
for (String line : getLines()) {
for (char c : line.toCharArray()) {
Coordinate coordinate = new Coordinate(currentX, currentY);
ItemCreator itemCreator = c == '_' ? new ItemCreator(Material.AIR) : getItemCreator();
map.put(coordinate, itemCreator);
currentX++;
}
currentX = 0;
currentY--;
}
return map;
}
public HashMap<Coordinate, ItemCreator> getCoordinates() {
return this.coordinates;
}
public char getLetter() {
return this.letter;
}
public List<String> getLines() {
return this.lines;
}
public ItemCreator getItemCreator() {
return this.itemCreator;
}
public double getHeight() {
return getLines().size();
/*double lowestPoint = 0;
double highestPoint = 0;
for (Coordinate coordinate : getCoordinates().keySet()) {
if (coordinate.getY() < lowestPoint) {
lowestPoint = coordinate.getY();
} else if (coordinate.getY() > highestPoint) {
highestPoint = coordinate.getY();
}
}
return Math.abs(highestPoint - lowestPoint) + 1;*/
}
public double getLength() {
return getLines().get(0).length();
/*double leftmostPoint = 0;
double rightmostPoint = 0;
for (Coordinate coordinate : getCoordinates().keySet()) {
if (coordinate.getX() <= leftmostPoint) {
leftmostPoint = coordinate.getX();
} else if (coordinate.getX() >= rightmostPoint) {
rightmostPoint = coordinate.getX();
}
}
return Math.abs(leftmostPoint - rightmostPoint) + 1;*/
}
}
}

View File

@ -0,0 +1,94 @@
package tc.oc.commons.bukkit.tokens;
import com.sk89q.minecraft.util.commands.*;
import net.md_5.bungee.api.ChatColor;
import net.md_5.bungee.api.chat.TranslatableComponent;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import tc.oc.commons.bukkit.chat.Audiences;
import tc.oc.commons.bukkit.chat.PlayerComponent;
import tc.oc.commons.bukkit.commands.UserFinder;
import tc.oc.commons.bukkit.nick.IdentityProvider;
import tc.oc.commons.bukkit.raindrops.RaindropUtil;
import tc.oc.commons.core.chat.Component;
import tc.oc.commons.core.commands.CommandFutureCallback;
import tc.oc.commons.core.commands.Commands;
import tc.oc.minecraft.scheduler.SyncExecutor;
import javax.inject.Inject;
public class TokenCommands implements Commands {
private final UserFinder userFinder;
private final SyncExecutor executor;
private final Audiences audiences;
private final IdentityProvider identityProvider;
@Inject
TokenCommands(UserFinder userFinder, SyncExecutor executor, Audiences audiences, IdentityProvider identityProvider) {
this.userFinder = userFinder;
this.executor = executor;
this.audiences = audiences;
this.identityProvider = identityProvider;
}
@Command(
aliases = {"tokens"},
usage = "[player]",
desc = "Shows the amount of tokens that you have",
min = 0,
max = 1
)
public void tokens(final CommandContext args, final CommandSender sender) throws CommandException {
executor.callback(
userFinder.findUser(sender, args, 0, UserFinder.Default.SENDER),
CommandFutureCallback.onSuccess(sender, args, result -> {
final boolean self = sender instanceof Player && ((Player) sender).getUniqueId().equals(result.user.uuid());
final int mapTokens = result.user.maptokens();
audiences.get(sender).sendMessage(
new Component(ChatColor.WHITE)
.translate(self ? "maptokens.balance.self" : "maptokens.balance.other",
new PlayerComponent(identityProvider.createIdentity(result)),
new Component(String.format("%,d", mapTokens), ChatColor.AQUA),
new TranslatableComponent(Math.abs(mapTokens) == 1 ? "maptokens.singular" : "maptokens.plural"))
);
final int mutationTokens = result.user.mutationtokens();
audiences.get(sender).sendMessage(
new Component(ChatColor.WHITE)
.translate(self ? "mutationtokens.balance.self" : "mutationtokens.balance.other",
new PlayerComponent(identityProvider.createIdentity(result)),
new Component(String.format("%,d", mutationTokens), ChatColor.AQUA),
new TranslatableComponent(Math.abs(mutationTokens) == 1 ? "mutationtokens.singular" : "mutationtokens.plural"))
);
})
);
}
@Command(
aliases = {"givetokens"},
usage = "[player] [setnext|mutation] [count]",
desc = "gives a player tokens",
min = 3,
max = 3
)
@CommandPermissions("tokens.give")
public void givetokens(final CommandContext args, final CommandSender sender) throws CommandException {
int numberOfTokens = args.getInteger(2);
executor.callback(
userFinder.findUser(sender, args, 0, UserFinder.Default.SENDER),
CommandFutureCallback.onSuccess(sender, args, result -> {
result.user.player_id();
String type = args.getString(1).toLowerCase();
if (type.equals("setnext") || type.equals("map")) {
TokenUtil.giveMapTokens(result.user, numberOfTokens);
} else if (type.equals("mutation") || type.equals("mt")) {
TokenUtil.giveMutationTokens(result.user, numberOfTokens);
} else if (type.equals("raindrops")) {
RaindropUtil.giveRaindrops(result.user, numberOfTokens, null);
} else {
throw new CommandUsageException(ChatColor.RED + "/givetokens [player] [map|mutation] [count]");
}
})
);
}
}

View File

@ -0,0 +1,14 @@
package tc.oc.commons.bukkit.tokens;
import tc.oc.commons.core.inject.HybridManifest;
import tc.oc.commons.core.plugin.PluginFacetBinder;
public class TokenManifest extends HybridManifest {
@Override
protected void configure() {
requestStaticInjection(TokenUtil.class);
new PluginFacetBinder(binder())
.register(TokenCommands.class);
}
}

View File

@ -0,0 +1,40 @@
package tc.oc.commons.bukkit.tokens;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import tc.oc.api.bukkit.users.BukkitUserStore;
import tc.oc.api.docs.PlayerId;
import tc.oc.api.users.UserService;
import tc.oc.commons.bukkit.util.SyncPlayerExecutorFactory;
import tc.oc.api.docs.User;
import javax.inject.Inject;
public class TokenUtil {
@Inject
private static BukkitUserStore userStore;
@Inject
private static UserService userService;
@Inject
private static SyncPlayerExecutorFactory playerExecutorFactory;
public static User getUser(Player player) {
return userStore.getUser(player);
}
public static void giveMapTokens(PlayerId playerId, int count) {
playerExecutorFactory.queued(playerId).callback(
userService.creditMaptokens(playerId, count),
(player, update) -> {}
);
}
public static void giveMutationTokens(PlayerId playerId, int count) {
playerExecutorFactory.queued(playerId).callback(
userService.creditMutationtokens(playerId, count),
(player, update) -> {}
);
}
}

View File

@ -0,0 +1,23 @@
package tc.oc.commons.bukkit.util;
import org.bukkit.ChatColor;
public enum Constants {
PREFIX(ChatColor.GOLD.toString() + ChatColor.BOLD),
SUBTEXT(ChatColor.AQUA.toString()),
CLICK(ChatColor.RED.toString() + ChatColor.BOLD),
ERROR(ChatColor.RED.toString());
private final String location;
Constants(String location) {
this.location = location;
}
@Override
public String toString() {
return location;
}
}

View File

@ -0,0 +1,183 @@
package tc.oc.commons.bukkit.util;
import net.minecraft.server.NBTTagCompound;
import org.bukkit.Color;
import org.bukkit.Material;
import org.bukkit.craftbukkit.inventory.CraftItemStack;
import org.bukkit.enchantments.Enchantment;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.inventory.meta.LeatherArmorMeta;
import org.bukkit.inventory.meta.PotionMeta;
import org.bukkit.potion.PotionEffect;
import java.util.*;
public class ItemCreator {
private Material material;
private String name;
private int size = 1;
private int data = 0;
private List<String> lore = new ArrayList<>();
private Map<Enchantment, Integer> enchantments = new HashMap<>();
private Color armorColor;
private String skullOwner;
private PotionEffect potionEffect;
private boolean hideFlags;
private boolean unbreakable;
public ItemCreator(Material material) {
setMaterial(material);
setName(material.toString());
}
public Material getMaterial() {
return material;
}
public ItemCreator setMaterial(Material material) {
this.material = material;
return this;
}
public String getName() {
return name;
}
public ItemCreator setName(String name) {
this.name = name;
return this;
}
public int getSize() {
return size;
}
public ItemCreator setSize(int size) {
this.size = size;
return this;
}
public int getData() {
return data;
}
public ItemCreator setData(int data) {
this.data = data;
return this;
}
public List<String> getLore() {
return lore;
}
public ItemCreator setLore(String... lore) {
this.lore.clear();
this.lore.addAll(Arrays.asList(lore));
return this;
}
public ItemCreator addLore(String... lore) {
this.lore.addAll(Arrays.asList(lore));
return this;
}
public ItemCreator clearLore() {
this.lore.clear();
return this;
}
public Map<Enchantment, Integer> getEnchantments() {
return enchantments;
}
public ItemCreator addEnchantment(Enchantment enchantment, int level) {
this.enchantments.put(enchantment, level);
return this;
}
public ItemCreator removeEnchantments() {
this.enchantments.clear();
return this;
}
public Color getArmorColor() {
return armorColor;
}
public ItemCreator setArmorColor(Color armorColor) {
this.armorColor = armorColor;
return this;
}
public String getSkullOwner() {
return skullOwner;
}
public ItemCreator setSkullOwner(String owner) {
this.skullOwner = owner;
return this;
}
public PotionEffect getPotionEffect() {
return potionEffect;
}
public ItemCreator setPotionEffect(PotionEffect potionEffect) {
this.potionEffect = potionEffect;
return this;
}
public boolean getUnbreakable() {
return unbreakable;
}
public ItemCreator setUnbreakable(boolean unbreakable) {
this.unbreakable = unbreakable;
return this;
}
public boolean getHideFlags() {
return hideFlags;
}
public ItemCreator setHideFlags(boolean hideFlags) {
this.hideFlags = hideFlags;
return this;
}
public ItemStack create() {
ItemStack item = new ItemStack(material, size, (short)data);
if (!item.getType().equals(Material.AIR)) {
net.minecraft.server.ItemStack nmsStack = CraftItemStack.asNMSCopy(item);
NBTTagCompound tag = new NBTTagCompound();
if (hideFlags) {
tag.setInt("HideFlags", 63);
}
if (skullOwner != null) {
tag.setString("SkullOwner", skullOwner);
}
nmsStack.setTag(tag);
item = CraftItemStack.asBukkitCopy(nmsStack);
ItemMeta meta = item.getItemMeta();
meta.setDisplayName(name);
meta.setLore(lore);
item.setItemMeta(meta);
item.addUnsafeEnchantments(enchantments);
if (armorColor != null) {
LeatherArmorMeta armorMeta = (LeatherArmorMeta) item.getItemMeta();
armorMeta.setColor(armorColor);
item.setItemMeta(armorMeta);
}
if (potionEffect != null) {
PotionMeta potionMeta = (PotionMeta) item.getItemMeta();
potionMeta.setMainEffect(potionEffect.getType());
potionMeta.addCustomEffect(potionEffect, false);
item.setItemMeta(potionMeta);
}
}
return item;
}
}

View File

@ -0,0 +1,20 @@
package tc.oc.commons.bukkit.util;
import java.util.List;
public class ObjectUtils {
public static <T> List<T> paginate(List<T> objects, int page, int pageLength) {
if (objects.size() <= ((page - 1) * pageLength)) {
return null;
}
int firstItem = ((page * pageLength) - pageLength);
int lastItem = (firstItem + pageLength);
int max = objects.size() <= lastItem ? objects.size() : lastItem;
if (max < firstItem) {
firstItem = max - 1;
}
return objects.subList(firstItem, max);
}
}

View File

@ -9,6 +9,9 @@ isolate: true
depend: [API, BukkitSettings, Channels]
permissions:
tokens.give:
description: Allows the player to give other players tokens
default: op
nick.see-through-all:
description: See the real names of all nicked players
default: op

View File

@ -187,6 +187,22 @@ raindrops.balance.other = {0} has {1} {2}
raindrops.singular = droplet
raindrops.plural = droplets
# {0} = player name
# {1} = number of SetNext tokens
# {2} = "SetNext token/SetNext tokens"
maptokens.balance.self = You have {1} {2}
maptokens.balance.other = {0} has {1} {2}
maptokens.singular = SetNext Token
maptokens.plural = SetNext Tokens
# {0} = player name
# {1} = number of Mutation tokens
# {2} = "Mutation token/Mutation tokens"
mutationtokens.balance.self = You have {1} {2}
mutationtokens.balance.other = {0} has {1} {2}
mutationtokens.singular = Mutation Token
mutationtokens.plural = Mutation Tokens
material.Iron = Iron
material.gold = Gold
material.quartz = Quartz

View File

@ -150,6 +150,9 @@ rating.update.notify = Someone on {0} re-rated this map from {2} to {1}
rating.create.notify.ffa = Someone rated this map {0}
rating.update.notify.ffa = Someone re-rated this map from {1} to {0}
tokens.map.fail = You do not have enough Map tokens
tokens.mutation.fail = You do not have enough Mutation tokens
shop.plug.neverKicked = Premium users are never kicked off teams!
shop.plug.neverSwitched = Premium users are never forced to switch teams!
shop.plug.joinFull = Premium users can join full teams!
@ -249,6 +252,8 @@ item.locked = This item cannot be removed from its slot
stats.hotbar = {0} kills ({1} streak) {2} deaths {3} K/D
poll.map.alreadyset = A map has already been set!
poll.map.notallowed = You are not allowed to set that map!
announce.online = Announced server as online
announce.offline = Announced server as offline

View File

@ -16,6 +16,8 @@ command.map.mapInfo.proto = Proto
command.map.mapInfo.source = Source
command.map.mapInfo.folder = Folder
command.map.pollablemaps = Maps
command.map.currentRotation.title = Current Rotation
command.map.rotationList.title = Loaded Rotations

View File

@ -40,7 +40,6 @@
<version>1.9-SNAPSHOT</version>
</dependency>
<!-- Testing -->
<dependency>

View File

@ -8,6 +8,9 @@ import org.bukkit.configuration.InvalidConfigurationException;
import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.time.Duration;
import tc.oc.commons.bukkit.configuration.ConfigUtils;
import tc.oc.commons.core.util.TimeUtils;
@ -23,6 +26,12 @@ public class Config {
}
}
public static Path getPollAbleMapPath() {
Path pollPath = Paths.get(getConfiguration().getString("poll.maps.path", "default.txt"));
if(!pollPath.isAbsolute()) pollPath = PGM.getMatchManager().getPluginDataFolder().resolve(pollPath);
return pollPath;
}
public static int minimumPlayers() {
return getConfiguration().getInt("minimum-players", 1);
}

View File

@ -38,11 +38,13 @@ import tc.oc.pgm.match.Match;
import tc.oc.pgm.match.MatchLoader;
import tc.oc.pgm.match.MatchManager;
import tc.oc.pgm.match.MatchPlayer;
import tc.oc.pgm.pollablemaps.PollableMaps;
import tc.oc.pgm.polls.PollListener;
import tc.oc.pgm.polls.PollManager;
import tc.oc.pgm.start.StartCommands;
import tc.oc.pgm.tablist.MatchTabManager;
import tc.oc.pgm.timelimit.TimeLimitCommands;
import tc.oc.pgm.tokens.gui.MainTokenButton;
import static com.google.common.base.Preconditions.checkState;
@ -92,6 +94,12 @@ public final class PGM extends JavaPlugin {
return pgm == null ? null : pgm.pollManager;
}
private PollableMaps pollableMaps;
public static PollableMaps getPollableMaps() {
return pgm == null ? null : pgm.pollableMaps;
}
public MapLibrary getMapLibrary() {
return mapLibrary;
}
@ -129,6 +137,7 @@ public final class PGM extends JavaPlugin {
}
this.pollManager = new PollManager(this);
this.pollableMaps = new PollableMaps();
this.registerListeners();
@ -162,6 +171,8 @@ public final class PGM extends JavaPlugin {
// Would rather configure this with a Guice binding, but we can't as long as
// PGM modules are installed on lobby servers, because the bindings will conflict.
navigatorInterface.setOpenButtonSlot(Slot.Hotbar.forPosition(7));
new MainTokenButton();
}
@Override

View File

@ -18,6 +18,7 @@ import tc.oc.pgm.development.MapErrorTracker;
import tc.oc.pgm.freeze.FreezeCommands;
import tc.oc.pgm.freeze.FreezeListener;
import tc.oc.pgm.listeners.BlockTransformListener;
import tc.oc.pgm.listeners.InterfaceListener;
import tc.oc.pgm.listeners.MatchAnnouncer;
import tc.oc.pgm.listeners.PGMListener;
import tc.oc.pgm.listing.ListingManifest;
@ -97,6 +98,7 @@ public final class PGMManifest extends HybridManifest {
facets.register(DefuseListener.class);
facets.register(FreezeCommands.class);
facets.register(FreezeListener.class);
facets.register(InterfaceListener.class);
requestStaticInjection(State.class);
}

View File

@ -25,6 +25,7 @@ import tc.oc.pgm.structure.StructureManifest;
import tc.oc.pgm.teams.TeamManifest;
import tc.oc.pgm.terrain.TerrainManifest;
import tc.oc.pgm.tnt.TNTManifest;
import tc.oc.pgm.tokens.TokenManifest;
import tc.oc.pgm.tracker.TrackerManifest;
import tc.oc.pgm.tutorial.TutorialManifest;
import tc.oc.pgm.wool.WoolManifest;
@ -62,6 +63,7 @@ public class PGMModulesManifest extends HybridManifest {
install(new BroadcastManifest());
install(new StatsManifest());
install(new RaindropManifest());
install(new TokenManifest());
install(new ObjectiveModeManifest());
install(new BlitzManifest());
}

View File

@ -1,16 +1,31 @@
package tc.oc.pgm.commands;
import com.google.common.collect.Sets;
import com.google.inject.Inject;
import net.md_5.bungee.api.chat.TranslatableComponent;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import tc.oc.api.bukkit.users.BukkitUserStore;
import tc.oc.api.docs.PlayerId;
import tc.oc.commons.bukkit.commands.UserFinder;
import tc.oc.commons.bukkit.tokens.TokenUtil;
import tc.oc.commons.core.formatting.StringUtils;
import tc.oc.pgm.PGM;
import tc.oc.pgm.map.PGMMap;
import tc.oc.pgm.mutation.Mutation;
import tc.oc.pgm.mutation.MutationMatchModule;
import tc.oc.pgm.mutation.command.MutationCommands;
import tc.oc.pgm.polls.*;
import com.sk89q.minecraft.util.commands.*;
import java.util.Collection;
import static tc.oc.commons.bukkit.commands.CommandUtils.newCommandException;
public class PollCommands {
@Command(
aliases = {"poll"},
@ -102,12 +117,59 @@ public class PollCommands {
)
@CommandPermissions("poll.next")
public static void pollNext(CommandContext args, CommandSender sender) throws CommandException {
if (PGM.getMatchManager().hasMapSet()) {
throw newCommandException(sender, new TranslatableComponent("poll.map.alreadyset"));
}
if (sender instanceof Player) {
Player player = (Player) sender;
if (TokenUtil.getUser(player).maptokens() < 1) {
throw newCommandException(sender, new TranslatableComponent("tokens.map.fail"));
}
}
Player initiator = tc.oc.commons.bukkit.commands.CommandUtils.senderToPlayer(sender);
PGMMap nextMap = CommandUtils.getMap(args.getJoinedStrings(0), sender);
startPoll(new PollNextMap(PGM.getPollManager(), Bukkit.getServer(), initiator.getName(), PGM.getMatchManager(), nextMap));
if (!PGM.getPollableMaps().isAllowed(nextMap)) {
throw newCommandException(sender, new TranslatableComponent("poll.map.notallowed"));
}
startPoll(new PollNextMap(PGM.getPollManager(), Bukkit.getServer(), sender, initiator.getName(), PGM.getMatchManager(), nextMap));
}
private static void startPoll(Poll poll) throws CommandException {
@Command(
aliases = {"mutation", "mt"},
desc = "Start a poll to set a mutation",
usage = "[mutation name]",
min = 1,
max = -1
)
@CommandPermissions("poll.mutation")
public static void pollMutation(CommandContext args, CommandSender sender) throws CommandException {
if (sender instanceof Player) {
Player player = (Player) sender;
if (TokenUtil.getUser(player).mutationtokens() < 1) {
throw newCommandException(sender, new TranslatableComponent("tokens.mutation.fail"));
}
}
String mutationString = args.getString(0);
MutationMatchModule module = PGM.getMatchManager().getCurrentMatch(sender).getMatchModule(MutationMatchModule.class);
Mutation mutation = StringUtils.bestFuzzyMatch(mutationString, Sets.newHashSet(Mutation.values()), 0.9);
if(mutation == null) {
throw newCommandException(sender, new TranslatableComponent("command.mutation.error.find", mutationString));
} else if(MutationCommands.getInstance().getMutationQueue().mutations().contains(mutation)) {
throw newCommandException(sender, new TranslatableComponent(true ? "command.mutation.error.enabled" : "command.mutation.error.disabled", mutation.getComponent(net.md_5.bungee.api.ChatColor.RED)));
}
startPoll(new PollMutation(PGM.getPollManager(), Bukkit.getServer(), sender, mutation, module));
}
public static void startPoll(Poll poll) throws CommandException {
PollManager pollManager = PGM.getPollManager();
if(pollManager.isPollRunning()) {
throw new CommandException("Another poll is already running.");

View File

@ -0,0 +1,86 @@
package tc.oc.pgm.listeners;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.event.EventBus;
import org.bukkit.event.inventory.ClickType;
import org.bukkit.inventory.ItemStack;
import tc.oc.commons.bukkit.event.InterfaceOpenEvent;
import tc.oc.commons.bukkit.gui.Interface;
import tc.oc.commons.bukkit.gui.InterfaceManager;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.block.Action;
import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.event.inventory.InventoryOpenEvent;
import org.bukkit.event.player.PlayerInteractEvent;
import tc.oc.commons.bukkit.gui.buttons.Button;
import tc.oc.commons.core.plugin.PluginFacet;
import tc.oc.pgm.events.ObserverInteractEvent;
import tc.oc.pgm.tokens.gui.MainTokenButton;
import javax.inject.Inject;
import javax.inject.Singleton;
@Singleton
public class InterfaceListener implements Listener, PluginFacet {
private final EventBus eventBus;
@Inject
InterfaceListener(EventBus eventBus) {
this.eventBus = eventBus;
}
@EventHandler
public void onPlayerClick(InventoryClickEvent event) {
Interface gui = InterfaceManager.getInterface(event.getView());
Player player = ((Player) event.getWhoClicked());
try {
Interface playergui = InterfaceManager.getInterface(player.getInventory());
if (playergui != null) {
for (Button button : InterfaceManager.getButtons(playergui, event.getSlot())) {
if (button != null) {
event.setCancelled(true);
button.function(player);
return;
}
}
}
} catch (Exception e) {
}
if (gui != null) {
event.setCancelled(true);
for (Button button : InterfaceManager.getButtons(gui, event.getRawSlot())) {
if (button != null) {
button.function(player);
player.updateInventory();
}
}
}
}
@EventHandler
public void onInventoryOpen(InventoryOpenEvent event) {
Interface gui = InterfaceManager.getInterface(event.getInventory().getHolder());
if (gui != null) {
eventBus.callEvent(new InterfaceOpenEvent(gui, (Player) event.getPlayer()));
}
}
@EventHandler
public void onObserverInteract(ObserverInteractEvent event) {
if (event.getClickType() == ClickType.RIGHT) {
Interface gui = InterfaceManager.getInterface(event.getPlayer().getInventory());
if (gui != null) {
Button button = InterfaceManager.getButton(gui, event.getPlayer().getBukkit().getItemInHand());
if (button != null) {
event.setCancelled(true);
button.function(event.getPlayer().getBukkit());
}
}
}
}
}

View File

@ -22,6 +22,7 @@ import org.bukkit.configuration.Configuration;
import org.bukkit.event.EventBus;
import tc.oc.api.util.Permissions;
import tc.oc.commons.core.logging.Loggers;
import tc.oc.pgm.PGM;
import tc.oc.pgm.development.MapErrorTracker;
import tc.oc.pgm.events.SetNextMapEvent;
import tc.oc.pgm.map.MapLibrary;
@ -113,9 +114,14 @@ public class MatchManager implements MatchFinder {
public Set<PGMMap> loadMapsAndRotations() throws MapNotFoundException {
Set<PGMMap> maps = loadNewMaps();
loadRotations();
PGM.getPollableMaps().loadPollableMaps();
return maps;
}
public Path getPluginDataFolder() {
return pluginDataFolder;
}
public RotationManager getRotationManager() {
if(rotationManager == null) {
rotationManager = new RotationManager(
@ -235,6 +241,10 @@ public class MatchManager implements MatchFinder {
return null;
}
public boolean hasMapSet() {
return this.nextMap != null;
}
private @Nullable Match cycleTo(@Nullable Match oldMatch, PGMMap map) {
try {
mapErrorTracker.clearErrors(map);

View File

@ -42,6 +42,8 @@ public class MutationCommands implements NestedCommands {
public static final String PERMISSION_SET = "mutation.set";
public static final String PERMISSION_LIST = "mutation.list";
private static MutationCommands instance;
public static class Parent implements Commands {
@Command(
aliases = {"mutation", "mutations", "mutate", "mt"},
@ -64,6 +66,7 @@ public class MutationCommands implements NestedCommands {
this.audiences = audiences;
this.mutationQueue = mutationQueue;
this.identityProvider = identityProvider;
this.instance = this;
}
@Command(
@ -215,4 +218,12 @@ public class MutationCommands implements NestedCommands {
}
}
public static MutationCommands getInstance() {
return instance;
}
public MutationQueue getMutationQueue() {
return mutationQueue;
}
}

View File

@ -0,0 +1,60 @@
package tc.oc.pgm.pollablemaps;
import com.google.common.base.Charsets;
import com.google.common.collect.ImmutableList;
import tc.oc.pgm.Config;
import tc.oc.pgm.PGM;
import tc.oc.pgm.map.PGMMap;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
public class PollableMaps {
private List<PGMMap> maps;
public PollableMaps() {
maps = new ArrayList<PGMMap>();
loadPollableMaps();
}
public List<PGMMap> getMaps() {
return maps;
}
public void loadPollableMaps() {
Path filepath = Config.getPollAbleMapPath();
if (filepath == null) return;
List<String> lines = null;
try {
lines = Files.readAllLines(filepath, Charsets.UTF_8);
} catch (IOException e) {
PGM.get().getLogger().severe("Error in reading pollable maps from file!");
}
if (lines == null) return;
ImmutableList.Builder<PGMMap> maps = ImmutableList.builder();
for(String line : lines) {
line = line.trim();
if(line.isEmpty()) {
continue;
}
Optional<PGMMap> map = PGM.get().getMapLibrary().getMapByNameOrId(line);
if(map.isPresent()) {
maps.add(map.get());
} else {
PGM.get().getMapLibrary().getLogger().severe("Unknown map '" + line
+ "' when parsing " + filepath.toString());
}
}
this.maps = maps.build();
}
public boolean isAllowed(PGMMap map) {
return !maps.contains(map);
}
}

View File

@ -12,12 +12,14 @@ public abstract class Poll implements Runnable {
protected final PollManager pollManager;
protected final Server server;
protected String initiator;
protected int timeLeftSeconds;
public Poll(PollManager pollManager, Server server, String initiator) {
this.pollManager = pollManager;
this.server = server;
this.initiator = initiator;
this.voteFor(initiator);
timeLeftSeconds = 60;
}
public String getInitiator() {
@ -48,16 +50,12 @@ public abstract class Poll implements Runnable {
return this.startTime;
}
public long getTimeElapsed() {
return System.currentTimeMillis() - this.startTime;
}
public long getTimeLeft() {
return 60*1000 - this.getTimeElapsed();
}
public int getTimeLeftSeconds() {
return Math.round(this.getTimeLeft() / 1000F);
return timeLeftSeconds;
}
private void decrementTimeLeft() {
timeLeftSeconds -= 5;
}
public boolean isSuccessful() {
@ -92,10 +90,11 @@ public abstract class Poll implements Runnable {
@Override
public void run() {
int timeLeftSeconds = this.getTimeLeftSeconds();
if(timeLeftSeconds == 0) {
if(timeLeftSeconds <= 0) {
this.pollManager.endPoll(PollEndReason.Completed);
} else if(timeLeftSeconds % 15 == 0 || (timeLeftSeconds < 15 && timeLeftSeconds % 5 == 0)) {
this.server.broadcastMessage(this.getStatusMessage());
}
this.decrementTimeLeft();
}
}

View File

@ -0,0 +1,44 @@
package tc.oc.pgm.polls;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.Server;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import tc.oc.commons.bukkit.tokens.TokenUtil;
import tc.oc.pgm.mutation.Mutation;
import tc.oc.pgm.mutation.MutationMatchModule;
public class PollMutation extends Poll {
private Mutation mutation;
private CommandSender sender;
private MutationMatchModule module;
private String mutationName;
public PollMutation(PollManager pollManager, Server server, CommandSender sender, Mutation mutation,
MutationMatchModule module) {
super(pollManager, server, sender.getName());
this.mutation = mutation;
this.sender = sender;
this.module = module;
this.mutationName = mutationName;
}
@Override
public void executeAction() {
Bukkit.getServer().dispatchCommand(Bukkit.getConsoleSender(),
"mutation enable -q " + mutation.name().toLowerCase());
if (sender instanceof Player) {
Player player = (Player) sender;
TokenUtil.giveMutationTokens(TokenUtil.getUser(player), -1);
}
}
@Override
public String getActionString(ChatColor neutral) {
return "to add the mutation " + ChatColor.GOLD + mutation.name().substring(0,1)
+ mutation.name().toLowerCase().substring(1);
}
}

View File

@ -2,7 +2,9 @@ package tc.oc.pgm.polls;
import org.bukkit.ChatColor;
import org.bukkit.Server;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import tc.oc.commons.bukkit.tokens.TokenUtil;
import tc.oc.pgm.map.PGMMap;
import tc.oc.pgm.match.MatchManager;
@ -10,16 +12,22 @@ import tc.oc.pgm.match.MatchManager;
public class PollNextMap extends Poll {
private final MatchManager mm;
private final PGMMap nextMap;
private CommandSender sender;
public PollNextMap(PollManager pollManager, Server server, String initiator, MatchManager mm, PGMMap nextMap) {
public PollNextMap(PollManager pollManager, Server server, CommandSender sender, String initiator, MatchManager mm, PGMMap nextMap) {
super(pollManager, server, initiator);
this.mm = mm;
this.nextMap = nextMap;
this.sender = sender;
}
@Override
public void executeAction() {
this.mm.setNextMap(this.nextMap);
if (sender instanceof Player) {
Player player = (Player) sender;
TokenUtil.giveMapTokens(TokenUtil.getUser(player), -1);
}
}
@Override

View File

@ -0,0 +1,89 @@
package tc.oc.pgm.tokens;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.inventory.ClickType;
import org.bukkit.inventory.ItemStack;
import tc.oc.commons.bukkit.event.ObserverKitApplyEvent;
import tc.oc.commons.bukkit.gui.Interface;
import tc.oc.commons.bukkit.gui.InterfaceManager;
import tc.oc.commons.bukkit.gui.buttons.Button;
import tc.oc.commons.bukkit.raindrops.RaindropConstants;
import tc.oc.commons.bukkit.tokens.TokenUtil;
import tc.oc.commons.core.util.Comparables;
import tc.oc.pgm.events.MatchEndEvent;
import tc.oc.pgm.events.ObserverInteractEvent;
import tc.oc.pgm.match.Competitor;
import tc.oc.pgm.match.Match;
import tc.oc.pgm.match.MatchPlayer;
import tc.oc.pgm.teams.Team;
import tc.oc.pgm.tokens.gui.MainTokenButton;
import tc.oc.pgm.victory.VictoryMatchModule;
import java.time.Duration;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
public class TokenListener implements Listener {
@EventHandler
public void onObserverInteract(ObserverInteractEvent event) {
if (event.getClickType() == ClickType.RIGHT) {
ItemStack main = MainTokenButton.getInstance().getIcon().create();
//isSimilar so that stacks of the item will still open the menu
if (event.getPlayer().getBukkit().getItemInHand().isSimilar(main)) {
MainTokenButton.getInstance().function(event.getPlayer().getBukkit());
}
}
}
@EventHandler
public void giveKitToObservers(ObserverKitApplyEvent event) {
ItemStack main = MainTokenButton.getInstance().getIcon().create();
Player player = event.getPlayer();
player.getInventory().setItem(5, main);
}
@EventHandler(priority = EventPriority.MONITOR)
public void handleMatchEndEvent(final MatchEndEvent event) {
//1 percent chance of happening
if (Math.random() > 0.01) {
return;
}
final Set<Competitor> winners = event.getMatch().needMatchModule(VictoryMatchModule.class).winners();
Match match = event.getMatch();
List<MatchPlayer> playersOnWinningTeam = new ArrayList<MatchPlayer>();
//use the same playtime rules as raindrops
boolean applyCutoff = Comparables.greaterThan(match.getLength(), RaindropConstants.TEAM_REWARD_CUTOFF);
for(MatchPlayer player : match.getParticipatingPlayers()) {
if(player.getParty() instanceof Team) {
Team team = (Team) player.getParty();
Duration teamTime = team.getCumulativeParticipation(player.getPlayerId());
if(!(applyCutoff && Comparables.lessThan(teamTime, RaindropConstants.TEAM_REWARD_CUTOFF))) {
Competitor playerTeam = player.getCompetitor();
assert playerTeam != null;
if(winners.contains(playerTeam)) {
playersOnWinningTeam.add(player);
}
}
}
}
if (!playersOnWinningTeam.isEmpty()) {
MatchPlayer player = playersOnWinningTeam.get((int)(playersOnWinningTeam.size() * Math.random()));
if (Math.random() > 0.5) {
Bukkit.broadcastMessage(player.getDisplayName() + ChatColor.AQUA + " has won a Mutation Token!");
TokenUtil.giveMutationTokens(TokenUtil.getUser(player.getBukkit()), 1);
} else {
Bukkit.broadcastMessage(player.getDisplayName() + ChatColor.AQUA + " has won a SetNext Token!");
TokenUtil.giveMapTokens(TokenUtil.getUser(player.getBukkit()), 1);
}
}
}
}

View File

@ -0,0 +1,13 @@
package tc.oc.pgm.tokens;
import tc.oc.commons.core.inject.HybridManifest;
import tc.oc.pgm.match.inject.MatchBinders;
import tc.oc.pgm.match.inject.MatchScoped;
public class TokenManifest extends HybridManifest implements MatchBinders {
@Override
protected void configure() {
bind(TokenListener.class).in(MatchScoped.class);
matchListener(TokenListener.class);
}
}

View File

@ -0,0 +1,33 @@
package tc.oc.pgm.tokens.gui;
import tc.oc.commons.bukkit.gui.buttons.Button;
import tc.oc.commons.bukkit.util.Constants;
import tc.oc.commons.bukkit.util.ItemCreator;
import org.bukkit.Material;
import org.bukkit.entity.Player;
public class MainTokenButton extends Button {
private static MainTokenButton instance;
public MainTokenButton() {
super(null);
instance = this;
}
public static MainTokenButton getInstance() {
return instance;
}
@Override
public ItemCreator getIcon() {
return new ItemCreator(Material.DOUBLE_PLANT)
.setName(Constants.PREFIX + "Tokens")
.addLore(Constants.SUBTEXT + "Open the Token Menu",
Constants.CLICK + "Right Click");
}
@Override
public void function(Player player) {
player.openInventory(new MainTokenMenu(player).getInventory());
}
}

View File

@ -0,0 +1,74 @@
package tc.oc.pgm.tokens.gui;
import org.bukkit.ChatColor;
import tc.oc.commons.bukkit.gui.buttons.Button;
import tc.oc.commons.bukkit.gui.interfaces.ChestInterface;
import tc.oc.commons.bukkit.tokens.TokenUtil;
import tc.oc.commons.bukkit.util.Constants;
import tc.oc.commons.bukkit.util.ItemCreator;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import java.util.ArrayList;
import java.util.List;
public class MainTokenMenu extends ChestInterface {
private static MainTokenMenu instance;
private Player player;
public MainTokenMenu(Player player) {
super(player, new ArrayList<Button>(), 27, "Token Menu", getInstance());
this.player = player;
updateButtons();
instance = this;
}
@Override
public ChestInterface getParent() {
return getInstance();
}
public static MainTokenMenu getInstance() {
return instance;
}
@Override
public void updateButtons() {
List<Button> buttons = new ArrayList<>();
int numTokens = TokenUtil.getUser(player).maptokens();
buttons.add(new Button(
new ItemCreator(Material.MAP)
.setName(Constants.PREFIX + "SetNext Tokens")
.addLore(Constants.SUBTEXT + "You have "
+ Integer.valueOf(numTokens) + " SetNext Token" + (numTokens == 1 ? "" : "s" ))
, 11) {
@Override
public void function(Player player) {
player.closeInventory();
if (TokenUtil.getUser(player).maptokens() < 1) {
player.sendMessage(ChatColor.RED + "You do not have enough SetNext Tokens to set a map!");
} else {
player.sendMessage(ChatColor.AQUA + "Use /poll next [mapname] to set a map.");
}
}
});
numTokens = TokenUtil.getUser(player).mutationtokens();
buttons.add(new Button(
new ItemCreator(Material.ELYTRA)
.setName(Constants.PREFIX + "Mutation Tokens")
.addLore(Constants.SUBTEXT + "You have "
+ Integer.valueOf(numTokens) + " Mutation Token" + (numTokens == 1 ? "" : "s" ))
, 15) {
@Override
public void function(Player player) {
player.openInventory(new MutationTokenInterface(player).getInventory());
}
});
setButtons(buttons);
updateInventory();
}
}

View File

@ -0,0 +1,77 @@
package tc.oc.pgm.tokens.gui;
import com.sk89q.minecraft.util.commands.CommandException;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.Material;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import tc.oc.commons.bukkit.gui.buttons.Button;
import tc.oc.commons.bukkit.gui.interfaces.ChestInterface;
import tc.oc.commons.bukkit.util.ItemCreator;
import tc.oc.pgm.PGM;
import tc.oc.pgm.commands.PollCommands;
import tc.oc.pgm.mutation.Mutation;
import tc.oc.pgm.mutation.MutationMatchModule;
import tc.oc.pgm.polls.PollMutation;
import java.util.ArrayList;
import java.util.List;
public class MutationConfirmInterface extends ChestInterface {
private static MutationConfirmInterface instance;
private Player player;
private Mutation mutation;
public MutationConfirmInterface(Player player, Mutation mutation) {
super(player, new ArrayList<Button>(), 27, "Confirmation Menu", getInstance());
this.player = player;
updateButtons();
instance = this;
this.mutation = mutation;
}
@Override
public ChestInterface getParent() {
return getInstance();
}
public static MutationConfirmInterface getInstance() {
return instance;
}
@Override
public void updateButtons() {
List<Button> buttons = new ArrayList<>();
buttons.add(new Button(new ItemCreator(Material.WOOL)
.setData(5)
.setName( ChatColor.GREEN + "Confirm" ), 12){
@Override
public void function(Player player) {
MutationMatchModule module = PGM.getMatchManager().getCurrentMatch(player).getMatchModule(MutationMatchModule.class);
try {
PollCommands.PollSubCommands.startPoll(new PollMutation(PGM.getPollManager(), Bukkit.getServer(), (CommandSender)player, mutation, module));
player.closeInventory();
} catch (CommandException e) {
player.sendMessage(ChatColor.RED + "Another poll is already running.");
player.closeInventory();
}
}
});
buttons.add(new Button(new ItemCreator(Material.WOOL)
.setData(14)
.setName( ChatColor.GREEN + "Cancel" ), 14){
@Override
public void function(Player player) {
player.openInventory(new MutationTokenInterface(player).getInventory());
}
});
setButtons(buttons);
updateInventory();
}
}

View File

@ -0,0 +1,124 @@
package tc.oc.pgm.tokens.gui;
import org.bukkit.ChatColor;
import org.bukkit.Material;
import org.bukkit.enchantments.Enchantment;
import org.bukkit.entity.Player;
import tc.oc.commons.bukkit.gui.buttons.Button;
import tc.oc.commons.bukkit.gui.interfaces.ChestInterface;
import tc.oc.commons.bukkit.tokens.TokenUtil;
import tc.oc.commons.bukkit.util.Constants;
import tc.oc.commons.bukkit.util.ItemCreator;
import tc.oc.pgm.PGM;
import tc.oc.pgm.PGMTranslations;
import tc.oc.pgm.mutation.Mutation;
import tc.oc.pgm.mutation.MutationMatchModule;
import tc.oc.pgm.mutation.command.MutationCommands;
import java.util.ArrayList;
import java.util.List;
public class MutationTokenInterface extends ChestInterface {
private static MutationTokenInterface instance;
private Player player;
public MutationTokenInterface(Player player) {
super(player, new ArrayList<Button>(), 54, "Token Menu", getInstance());
this.player = player;
updateButtons();
instance = this;
}
@Override
public ChestInterface getParent() {
return getInstance();
}
public static MutationTokenInterface getInstance() {
return instance;
}
@Override
public void updateButtons() {
List<Button> buttons = new ArrayList<>();
buttons.add(getMutationButton(Mutation.EQUESTRIAN, Material.SADDLE, 10));
buttons.add(getMutationButton(Mutation.POTION, Material.POTION, 11));
buttons.add(getMutationButton(Mutation.ELYTRA, Material.ELYTRA, 12));
buttons.add(getMutationButton(Mutation.PROJECTILE, Material.TIPPED_ARROW, 13));
buttons.add(getMutationButton(Mutation.MOBS, Material.MONSTER_EGG, 14));
buttons.add(getMutationButton(Mutation.HARDCORE, Material.GOLDEN_APPLE, 15));
buttons.add(getMutationButton(Mutation.GLOW, Material.GLOWSTONE_DUST, 16));
buttons.add(getMutationButton(Mutation.ENCHANTMENT, Material.ENCHANTMENT_TABLE, 19));
buttons.add(getMutationButton(Mutation.JUMP, Material.FEATHER, 20));
buttons.add(getMutationButton(Mutation.EXPLOSIVE, Material.FLINT_AND_STEEL, 21));
buttons.add(getMutationButton(Mutation.HEALTH, Material.COOKED_BEEF, 22));
buttons.add(getMutationButton(Mutation.ARMOR, Material.DIAMOND_CHESTPLATE, 23));
buttons.add(getMutationButton(Mutation.LIGHTNING, Material.JACK_O_LANTERN, 24));
buttons.add(getMutationButton(Mutation.APOCALYPSE, Material.NETHER_STAR, 25));
buttons.add(getMutationButton(Mutation.BLITZ, Material.IRON_FENCE, 28));
buttons.add(getMutationButton(Mutation.STEALTH, Material.THIN_GLASS, 29));
buttons.add(getMutationButton(Mutation.BOMBER, Material.TNT, 30));
buttons.add(new Button(new ItemCreator(Material.WOOL)
.setData(14)
.setName( ChatColor.GREEN + "Go Back" ), 49){
@Override
public void function(Player player) {
player.openInventory(new MainTokenMenu(player).getInventory());
}
});
setButtons(buttons);
updateInventory();
}
private Button getMutationButton(Mutation mutation, Material material, int slot) {
ItemCreator itemCreator = new ItemCreator(material)
.setName(Constants.PREFIX + getMutationName(mutation))
.addLore(Constants.SUBTEXT + getMutationDescription(mutation));
if (MutationCommands.getInstance().getMutationQueue().mutations().contains(mutation)) {
itemCreator.addEnchantment(Enchantment.DURABILITY, 1);
}
return new Button(itemCreator, slot) {
@Override
public void function(Player player) {
if (hasEnoughTokens()) {
player.closeInventory();
MutationMatchModule module = PGM.getMatchManager().getCurrentMatch(player).getMatchModule(MutationMatchModule.class);
if (MutationCommands.getInstance().getMutationQueue().mutations().contains(mutation)) {
player.sendMessage(ChatColor.RED + "The " + getMutationName(mutation)
+ " mutation is already enabled!");
} else if (PGM.getMatchManager().getCurrentMatch(player).isStarting()) {
if (module.mutationsActive().contains(mutation)) {
player.sendMessage(ChatColor.RED + "The " + getMutationName(mutation)
+ " mutation is already enabled!");
}
} else {
player.openInventory(new MutationConfirmInterface(player, mutation).getInventory());
}
} else {
player.closeInventory();
player.sendMessage(ChatColor.RED + "You do not have enough Mutation Tokens!");
}
}
};
}
private String getMutationName(Mutation mutation) {
return PGMTranslations.get().t(mutation.getName(), player);
}
private String getMutationDescription(Mutation mutation) {
return PGMTranslations.get().t(mutation.getDescription(), player);
}
private boolean hasEnoughTokens() {
return TokenUtil.getUser(player).mutationtokens() > 0;
}
}

View File

@ -84,6 +84,10 @@ rotation:
initial-wait: 20000
providers: {}
poll:
maps:
path:
map:
sources: {}
# public:

View File

@ -28,6 +28,9 @@ permissions:
pgm.mapnext:
description: Allows access to the /mapnext command.
default: true
pgm.pollablemaps:
description: Allows access to the /pollablemaps command.
default: true
map.rating.rate:
description: Allows players to rate maps
@ -163,6 +166,8 @@ permissions:
description: Allows the player to poll kick an exempt player.
poll.next:
description: Allows the player to start a poll to set the next map.
poll.mutation:
description: Allows the player to start a poll to set a mutation.
# rotation editing
pgm.rotation.reload:

View File

@ -1,160 +0,0 @@
package tc.oc.pgm.filter;
import org.bukkit.CraftBukkitRuntime;
import org.bukkit.DyeColor;
import org.bukkit.Material;
import org.bukkit.craftbukkit.inventory.CraftItemStack;
import org.bukkit.inventory.ImItemStack;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.PotionMeta;
import org.bukkit.material.Wool;
import org.bukkit.potion.PotionData;
import org.bukkit.potion.PotionType;
import org.junit.Before;
import org.junit.Test;
import tc.oc.pgm.filters.ItemMatcher;
import tc.oc.pgm.kits.tag.ItemTags;
import tc.oc.pgm.projectile.Projectiles;
import static org.junit.Assert.*;
public class ItemMatcherTest {
@Before
public void setUp() throws Exception {
CraftBukkitRuntime.load();
}
private void assertMatches(ItemStack item, ItemStack query) {
final ItemMatcher matcher = new ItemMatcher(item);
if(!matcher.test(query)) {
fail("Item should match: reference=" + item + " query=" + query);
}
final CraftItemStack nms = CraftItemStack.asCraftMirror(CraftItemStack.asNMSCopy(query));
if(!matcher.test(nms)) {
fail("Converted item should match: reference=" + item + " query=" + query);
}
}
private void refuteMatches(ItemStack item, ItemStack query) {
final ItemMatcher matcher = new ItemMatcher(item);
if(matcher.test(query)) {
fail("Item should not match: reference=" + item + " query=" + query);
}
final CraftItemStack nms = CraftItemStack.asCraftMirror(CraftItemStack.asNMSCopy(query));
if(matcher.test(nms)) {
fail("Converted item should not match: reference=" + item + " query=" + query);
}
}
@Test
public void simpleItemMatches() throws Throwable {
ImItemStack item = ItemStack.builder(Material.BEDROCK)
.immutable();
assertMatches(item, item);
}
@Test
public void itemWithDataMatches() throws Throwable {
ImItemStack item = ItemStack.builder(new Wool(DyeColor.PINK))
.immutable();
assertMatches(item, item);
}
@Test
public void itemWithMetaMatches() throws Throwable {
ImItemStack item = ItemStack.builder(Material.BEDROCK)
.meta(meta -> meta.setDisplayName("Hi!"))
.immutable();
assertMatches(item, item);
}
@Test
public void itemWithTypedMetaMatches() throws Throwable {
ImItemStack item = ItemStack.builder(Material.POTION)
.meta(PotionMeta.class, meta -> meta.setBasePotionData(new PotionData(PotionType.LUCK, false, false)))
.immutable();
assertMatches(item, item);
}
@Test
public void itemWithCustomProjectileMatches() throws Throwable {
ImItemStack item = ItemStack.builder(Material.STICK)
.meta(meta -> Projectiles.setProjectileId(meta, "woot"))
.immutable();
assertMatches(item, item);
}
@Test
public void differentMaterialsDontMatch() throws Throwable {
refuteMatches(new ItemStack(Material.BEDROCK),
new ItemStack(Material.APPLE));
}
@Test
public void differentDataDoesntMatch() throws Throwable {
refuteMatches(new ItemStack(new Wool(DyeColor.PINK)),
new ItemStack(new Wool(DyeColor.BLUE)));
}
@Test
public void differentMetaDoesntMatch() throws Throwable {
refuteMatches(ItemStack.builder(Material.BEDROCK).meta(meta -> meta.setDisplayName("Hi!")).immutable(),
ItemStack.builder(Material.BEDROCK).meta(meta -> meta.setDisplayName("Bye!")).immutable());
}
@Test
public void differentProjectileDoesntMatch() throws Throwable {
refuteMatches(ItemStack.builder(Material.STICK).meta(meta -> Projectiles.setProjectileId(meta, "woot")).immutable(),
ItemStack.builder(Material.STICK).meta(meta -> Projectiles.setProjectileId(meta, "doink")).immutable());
}
@Test
public void nullDoesntMatch() throws Throwable {
assertFalse(new ItemMatcher(new ItemStack(Material.BEDROCK)).test(null));
}
@Test
public void biggerStackMatches() throws Throwable {
assertMatches(new ItemStack(Material.BEDROCK, 3),
new ItemStack(Material.BEDROCK, 4));
}
@Test
public void smallerStackDoesNotMatch() throws Throwable {
refuteMatches(new ItemStack(Material.BEDROCK, 3),
new ItemStack(Material.BEDROCK, 2));
}
@Test
public void durabilityIgnoredOnDamageableItem() throws Throwable {
assertMatches(new ItemStack(Material.STONE_SWORD, 1, (short) 123),
new ItemStack(Material.STONE_SWORD, 1, (short) 456));
}
@Test
public void durabilityMattersOnDataItem() throws Throwable {
refuteMatches(new ItemStack(Material.WOOL, 1, (short) 1),
new ItemStack(Material.WOOL, 1, (short) 2));
}
@Test
public void lockFlagIgnored() throws Throwable {
ItemStack ref = new ItemStack(Material.BEDROCK);
ItemStack query = ref.clone();
ItemTags.LOCKED.set(query, true);
assertMatches(ref, query);
}
@Test
public void preventSharingFlagIgnored() throws Throwable {
ItemStack ref = new ItemStack(Material.BEDROCK);
ItemStack query = ref.clone();
ItemTags.PREVENT_SHARING.set(query, true);
assertMatches(ref, query);
}
}