2015-10-26 08:57:00 +01:00
|
|
|
package mineplex.game.clans.items;
|
2015-05-05 21:33:42 +02:00
|
|
|
|
2015-06-01 18:25:20 +02:00
|
|
|
import java.util.ArrayList;
|
2015-05-05 21:33:42 +02:00
|
|
|
import java.util.HashMap;
|
2015-06-01 18:25:20 +02:00
|
|
|
import java.util.HashSet;
|
2015-08-26 21:26:27 +02:00
|
|
|
import java.util.Iterator;
|
2015-05-25 20:22:06 +02:00
|
|
|
import java.util.List;
|
2015-05-05 21:33:42 +02:00
|
|
|
import java.util.Map;
|
2015-06-01 18:25:20 +02:00
|
|
|
import java.util.Set;
|
2015-05-05 21:33:42 +02:00
|
|
|
|
2015-10-24 08:16:13 +02:00
|
|
|
import org.bukkit.GameMode;
|
|
|
|
import org.bukkit.Location;
|
|
|
|
import org.bukkit.Material;
|
|
|
|
import org.bukkit.craftbukkit.v1_7_R4.inventory.CraftItemStack;
|
|
|
|
import org.bukkit.entity.Player;
|
|
|
|
import org.bukkit.inventory.ItemStack;
|
|
|
|
import org.bukkit.inventory.meta.ItemMeta;
|
|
|
|
import org.bukkit.plugin.java.JavaPlugin;
|
|
|
|
|
|
|
|
import com.google.gson.Gson;
|
|
|
|
import com.google.gson.GsonBuilder;
|
|
|
|
|
2015-05-05 21:33:42 +02:00
|
|
|
import mineplex.core.MiniPlugin;
|
|
|
|
import mineplex.core.account.CoreClientManager;
|
2015-09-29 23:36:42 +02:00
|
|
|
import mineplex.core.common.util.F;
|
|
|
|
import mineplex.core.common.util.UtilPlayer;
|
2015-05-25 20:22:06 +02:00
|
|
|
import mineplex.core.common.util.UtilServer;
|
2015-10-24 08:16:13 +02:00
|
|
|
import mineplex.core.donation.DonationManager;
|
2015-05-25 20:22:06 +02:00
|
|
|
import mineplex.core.packethandler.IPacketHandler;
|
|
|
|
import mineplex.core.packethandler.PacketHandler;
|
|
|
|
import mineplex.core.packethandler.PacketInfo;
|
2015-06-22 22:20:20 +02:00
|
|
|
import mineplex.game.clans.items.attributes.AttributeContainer;
|
2015-06-29 22:38:51 +02:00
|
|
|
import mineplex.game.clans.items.attributes.AttributeType;
|
2015-05-25 20:22:06 +02:00
|
|
|
import mineplex.game.clans.items.attributes.ItemAttribute;
|
2015-10-24 08:16:13 +02:00
|
|
|
import mineplex.game.clans.items.attributes.armor.ConqueringArmorAttribute;
|
|
|
|
import mineplex.game.clans.items.attributes.armor.LavaAttribute;
|
|
|
|
import mineplex.game.clans.items.attributes.armor.PaddedAttribute;
|
|
|
|
import mineplex.game.clans.items.attributes.armor.ReinforcedAttribute;
|
|
|
|
import mineplex.game.clans.items.attributes.armor.SlantedAttribute;
|
|
|
|
import mineplex.game.clans.items.attributes.bow.HeavyArrowsAttribute;
|
|
|
|
import mineplex.game.clans.items.attributes.bow.HuntingAttribute;
|
|
|
|
import mineplex.game.clans.items.attributes.bow.InverseAttribute;
|
|
|
|
import mineplex.game.clans.items.attributes.bow.LeechingAttribute;
|
|
|
|
import mineplex.game.clans.items.attributes.bow.RecursiveAttribute;
|
|
|
|
import mineplex.game.clans.items.attributes.bow.ScorchingAttribute;
|
|
|
|
import mineplex.game.clans.items.attributes.bow.SlayingAttribute;
|
|
|
|
import mineplex.game.clans.items.attributes.weapon.ConqueringAttribute;
|
|
|
|
import mineplex.game.clans.items.attributes.weapon.FlamingAttribute;
|
|
|
|
import mineplex.game.clans.items.attributes.weapon.FrostedAttribute;
|
|
|
|
import mineplex.game.clans.items.attributes.weapon.HasteAttribute;
|
|
|
|
import mineplex.game.clans.items.attributes.weapon.JaggedAttribute;
|
|
|
|
import mineplex.game.clans.items.attributes.weapon.SharpAttribute;
|
2015-05-05 21:33:42 +02:00
|
|
|
import mineplex.game.clans.items.commands.GearCommand;
|
2015-06-06 01:18:06 +02:00
|
|
|
import mineplex.game.clans.items.economy.GoldToken;
|
2015-10-26 08:57:00 +01:00
|
|
|
import mineplex.game.clans.items.gear.GearShop;
|
2015-05-05 21:33:42 +02:00
|
|
|
import mineplex.game.clans.items.generation.Weight;
|
|
|
|
import mineplex.game.clans.items.generation.WeightSet;
|
2015-10-24 08:16:13 +02:00
|
|
|
import mineplex.game.clans.items.legendaries.AlligatorsTooth;
|
|
|
|
import mineplex.game.clans.items.legendaries.GiantsBroadsword;
|
|
|
|
import mineplex.game.clans.items.legendaries.HyperBlade;
|
|
|
|
import mineplex.game.clans.items.legendaries.LegendaryItem;
|
|
|
|
import mineplex.game.clans.items.legendaries.MagneticBlade;
|
|
|
|
import mineplex.game.clans.items.legendaries.WindBlade;
|
2015-05-25 20:22:06 +02:00
|
|
|
import mineplex.game.clans.items.smelting.SmeltingListener;
|
|
|
|
import mineplex.serverdata.serialization.RuntimeTypeAdapterFactory;
|
|
|
|
import net.minecraft.server.v1_7_R4.Packet;
|
|
|
|
import net.minecraft.server.v1_7_R4.PacketPlayOutSetSlot;
|
2015-10-24 08:16:13 +02:00
|
|
|
import net.minecraft.server.v1_7_R4.PacketPlayOutWindowItems;
|
2015-05-25 20:22:06 +02:00
|
|
|
|
2015-05-05 21:33:42 +02:00
|
|
|
/**
|
|
|
|
* Manages creation and retrieval of associated {@link PlayerGear}s with online players, as well
|
|
|
|
* as offering methods for parsing and handling {@link CustomItem}s.
|
|
|
|
* @author MrTwiggy
|
|
|
|
*
|
|
|
|
*/
|
2015-06-01 18:25:20 +02:00
|
|
|
public class GearManager extends MiniPlugin implements IPacketHandler, Runnable
|
2015-05-05 21:33:42 +02:00
|
|
|
{
|
2015-10-26 08:57:00 +01:00
|
|
|
private static final String ITEM_SERIALIZATION_TAG = "-JSON-";
|
|
|
|
private static Gson _gson;
|
|
|
|
private static GearManager _instance; // Singleton instance
|
2015-05-25 20:22:06 +02:00
|
|
|
|
2015-05-05 21:33:42 +02:00
|
|
|
|
2015-10-26 08:57:00 +01:00
|
|
|
private Map<String, PlayerGear> _playerGears; // Mapping of player names (key) to cached gear set (value).
|
|
|
|
private WeightSet<Integer> _attributeWeights; // Weightings for randomly selecting number of attributes (1, 2, 3)
|
|
|
|
private WeightSet<ItemType> _typeWeights; // Weightings for randomly selecting item type (legendary/weapon/armour/bow)
|
|
|
|
private Set<String> _creativePlayers; // Set of names for all players currently in Creative gamemode
|
2015-06-01 18:25:20 +02:00
|
|
|
|
|
|
|
// Legendary generation
|
2015-10-26 08:57:00 +01:00
|
|
|
private WeightSet<Class<? extends LegendaryItem>> _legendaryWeights;
|
2015-06-01 18:25:20 +02:00
|
|
|
|
|
|
|
// Weapon generation
|
2015-10-26 08:57:00 +01:00
|
|
|
private WeightSet<Material> _weaponTypes;
|
2015-06-01 18:25:20 +02:00
|
|
|
|
|
|
|
// Armour generation
|
2015-10-26 08:57:00 +01:00
|
|
|
private WeightSet<Material> _armourTypes;
|
2015-06-01 18:25:20 +02:00
|
|
|
|
|
|
|
// Attribute generation
|
2015-10-26 08:57:00 +01:00
|
|
|
private WeightSet<Class<? extends ItemAttribute>> _weaponAttributes;
|
|
|
|
private WeightSet<Class<? extends ItemAttribute>> _armourAttributes;
|
|
|
|
private WeightSet<Class<? extends ItemAttribute>> _bowAttributes;
|
2015-10-24 08:16:13 +02:00
|
|
|
|
2015-10-26 08:57:00 +01:00
|
|
|
private GearShop _shop;
|
2015-05-05 21:33:42 +02:00
|
|
|
|
2015-10-24 08:16:13 +02:00
|
|
|
public GearManager(JavaPlugin plugin, PacketHandler packetHandler, CoreClientManager clientManager, DonationManager donationManager)
|
2015-05-05 21:33:42 +02:00
|
|
|
{
|
|
|
|
super("CustomGear", plugin);
|
|
|
|
|
|
|
|
_instance = this;
|
|
|
|
|
2015-10-24 08:16:13 +02:00
|
|
|
_shop = new GearShop(this, clientManager, donationManager);
|
|
|
|
|
2015-08-31 02:05:45 +02:00
|
|
|
_creativePlayers = new HashSet<String>();
|
2015-06-01 18:25:20 +02:00
|
|
|
_playerGears = new HashMap<String, PlayerGear>();
|
2015-05-25 20:22:06 +02:00
|
|
|
// TODO: Introduce configurable non-hardcoded values for generation weights?
|
2015-06-03 02:01:42 +02:00
|
|
|
_attributeWeights = new WeightSet<Integer>(new Weight<Integer>(3, 3), new Weight<Integer>(20, 2), new Weight<Integer>(77, 1));
|
|
|
|
_typeWeights = new WeightSet<ItemType>(new Weight<ItemType>(10, ItemType.LEGENDARY),
|
2015-06-01 18:25:20 +02:00
|
|
|
new Weight<ItemType>(45, ItemType.ARMOUR),
|
2015-06-22 22:20:20 +02:00
|
|
|
new Weight<ItemType>(23, ItemType.WEAPON),
|
|
|
|
new Weight<ItemType>(22, ItemType.BOW));
|
2015-06-01 18:25:20 +02:00
|
|
|
|
|
|
|
// Weapon-based attributes
|
|
|
|
_weaponAttributes = new WeightSet<Class<? extends ItemAttribute>>(FrostedAttribute.class, SharpAttribute.class,
|
|
|
|
JaggedAttribute.class, HasteAttribute.class, FlamingAttribute.class, ConqueringAttribute.class);
|
|
|
|
|
|
|
|
// Armour-based attributes
|
|
|
|
_armourAttributes = new WeightSet<Class<? extends ItemAttribute>>(SlantedAttribute.class, ReinforcedAttribute.class,
|
2015-06-29 22:38:51 +02:00
|
|
|
ConqueringArmorAttribute.class, PaddedAttribute.class, LavaAttribute.class);
|
2015-05-16 18:58:58 +02:00
|
|
|
|
2015-06-01 18:25:20 +02:00
|
|
|
// Bow-based attributes
|
2015-06-22 22:20:20 +02:00
|
|
|
_bowAttributes = new WeightSet<Class<? extends ItemAttribute>>(HeavyArrowsAttribute.class, HuntingAttribute.class, InverseAttribute.class,
|
|
|
|
LeechingAttribute.class, RecursiveAttribute.class, ScorchingAttribute.class, SlayingAttribute.class);
|
2015-06-01 18:25:20 +02:00
|
|
|
|
|
|
|
// Weapon material types
|
|
|
|
_weaponTypes = new WeightSet<Material>(Material.DIAMOND_SWORD, Material.GOLD_SWORD, Material.IRON_SWORD, Material.STONE_SWORD,
|
|
|
|
Material.DIAMOND_AXE, Material.GOLD_AXE, Material.IRON_AXE, Material.STONE_AXE);
|
|
|
|
|
|
|
|
// Armour material types
|
|
|
|
_armourTypes = new WeightSet<Material>(Material.DIAMOND_HELMET, Material.DIAMOND_CHESTPLATE, Material.DIAMOND_LEGGINGS, Material.DIAMOND_BOOTS,
|
|
|
|
Material.IRON_HELMET, Material.IRON_CHESTPLATE, Material.IRON_LEGGINGS, Material.IRON_BOOTS,
|
|
|
|
Material.GOLD_HELMET, Material.GOLD_CHESTPLATE, Material.GOLD_LEGGINGS, Material.GOLD_BOOTS);
|
|
|
|
|
|
|
|
// TODO: Initialize list of attributes and types
|
|
|
|
|
|
|
|
// Initialize various LegendaryItem types
|
|
|
|
_legendaryWeights = new WeightSet<Class<? extends LegendaryItem>>(AlligatorsTooth.class, WindBlade.class,
|
|
|
|
GiantsBroadsword.class, HyperBlade.class, MagneticBlade.class);
|
|
|
|
// TODO: Add rest of legendaries, find better way?
|
2015-05-25 20:22:06 +02:00
|
|
|
|
|
|
|
// Register listeners
|
2015-06-22 22:20:20 +02:00
|
|
|
UtilServer.getServer().getPluginManager().registerEvents(new ItemListener(getPlugin()), getPlugin());
|
2015-05-25 20:22:06 +02:00
|
|
|
UtilServer.getServer().getPluginManager().registerEvents(new SmeltingListener(), getPlugin());
|
|
|
|
|
2015-06-01 18:25:20 +02:00
|
|
|
// Initialize attribute types factory for JSON handling of polymorphism.
|
|
|
|
RuntimeTypeAdapterFactory<ItemAttribute> attributeFactory = RuntimeTypeAdapterFactory
|
|
|
|
.of(ItemAttribute.class);
|
|
|
|
|
|
|
|
for (Class<? extends ItemAttribute> attributeType : _armourAttributes.elements())
|
|
|
|
{
|
|
|
|
attributeFactory.registerSubtype(attributeType);
|
|
|
|
}
|
|
|
|
for (Class<? extends ItemAttribute> attributeType : _weaponAttributes.elements())
|
|
|
|
{
|
|
|
|
attributeFactory.registerSubtype(attributeType);
|
|
|
|
}
|
2015-06-22 22:20:20 +02:00
|
|
|
for (Class<? extends ItemAttribute> attributeType : _bowAttributes.elements())
|
|
|
|
{
|
|
|
|
attributeFactory.registerSubtype(attributeType);
|
|
|
|
}
|
2015-05-25 20:22:06 +02:00
|
|
|
|
2015-06-01 18:25:20 +02:00
|
|
|
// Initialize legendary item type factory for JSON handling of polymorphism.
|
2015-05-25 20:22:06 +02:00
|
|
|
RuntimeTypeAdapterFactory<CustomItem> customItemType = RuntimeTypeAdapterFactory
|
2015-06-01 18:25:20 +02:00
|
|
|
.of(CustomItem.class);
|
|
|
|
customItemType.registerSubtype(CustomItem.class);
|
|
|
|
customItemType.registerSubtype(LegendaryItem.class);
|
2015-06-06 01:18:06 +02:00
|
|
|
customItemType.registerSubtype(GoldToken.class);
|
2015-06-01 18:25:20 +02:00
|
|
|
for (Class<? extends CustomItem> itemType : _legendaryWeights.elements())
|
|
|
|
{
|
|
|
|
customItemType.registerSubtype(itemType);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Build GSON instance off factories for future serialization of items.
|
|
|
|
_gson = new GsonBuilder()
|
|
|
|
.registerTypeAdapterFactory(attributeFactory)
|
|
|
|
.registerTypeAdapterFactory(customItemType)
|
|
|
|
.create();
|
2015-05-25 20:22:06 +02:00
|
|
|
|
|
|
|
packetHandler.addPacketHandler(this);
|
2015-06-01 18:25:20 +02:00
|
|
|
|
|
|
|
plugin.getServer().getScheduler().runTaskTimer(plugin, this, 1l, 1l);
|
2015-05-05 21:33:42 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void addCommands()
|
|
|
|
{
|
|
|
|
addCommand(new GearCommand(this));
|
|
|
|
}
|
|
|
|
|
2015-08-31 02:05:45 +02:00
|
|
|
public void addCreativePlayer(Player player)
|
|
|
|
{
|
|
|
|
_creativePlayers.add(player.getName());
|
|
|
|
player.updateInventory();
|
|
|
|
}
|
|
|
|
|
|
|
|
public void removeCreativePlayer(Player player)
|
|
|
|
{
|
|
|
|
_creativePlayers.remove(player.getName());
|
|
|
|
player.updateInventory();
|
|
|
|
}
|
|
|
|
|
2015-06-01 18:25:20 +02:00
|
|
|
/**
|
|
|
|
* Tick & update internal logic for {@link GearManager}. Called once per tick.
|
|
|
|
*/
|
|
|
|
@Override
|
|
|
|
public void run()
|
|
|
|
{
|
2015-08-26 21:26:27 +02:00
|
|
|
Iterator<PlayerGear> iterator = _playerGears.values().iterator();
|
|
|
|
while (iterator.hasNext())
|
2015-06-01 18:25:20 +02:00
|
|
|
{
|
2015-08-26 21:26:27 +02:00
|
|
|
PlayerGear gear = iterator.next();
|
2015-07-20 22:57:57 +02:00
|
|
|
if (gear.isOnline())
|
|
|
|
{
|
|
|
|
gear.update();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2015-08-26 21:26:27 +02:00
|
|
|
iterator.remove();
|
2015-07-20 22:57:57 +02:00
|
|
|
}
|
2015-06-01 18:25:20 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-05-05 21:33:42 +02:00
|
|
|
/**
|
|
|
|
* @param player - the player whose {@link PlayerGear} set is to be fetched.
|
|
|
|
* @return the cached or newly instantiated {@link PlayerGear} associated with {@code player}.
|
|
|
|
*/
|
|
|
|
public PlayerGear getPlayerGear(Player player)
|
|
|
|
{
|
|
|
|
String playerName = player.getName();
|
2015-06-01 18:25:20 +02:00
|
|
|
if (!_playerGears.containsKey(playerName))
|
2015-05-05 21:33:42 +02:00
|
|
|
{
|
|
|
|
PlayerGear gear = new PlayerGear(playerName);
|
2015-06-01 18:25:20 +02:00
|
|
|
_playerGears.put(playerName, gear);
|
2015-05-05 21:33:42 +02:00
|
|
|
}
|
|
|
|
|
2015-06-01 18:25:20 +02:00
|
|
|
return _playerGears.get(playerName);
|
2015-05-05 21:33:42 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
public CustomItem generateItem()
|
|
|
|
{
|
|
|
|
int attributeCount = _attributeWeights.generateRandom();
|
2015-10-24 21:36:53 +02:00
|
|
|
ItemType itemType = _typeWeights.generateRandom();
|
2015-06-01 18:25:20 +02:00
|
|
|
CustomItem item = generateItem(itemType);
|
|
|
|
|
|
|
|
if (itemType != ItemType.LEGENDARY) // Only non-legendaries have attributes
|
|
|
|
{
|
2015-06-29 22:38:51 +02:00
|
|
|
generateAttributes(item.getAttributes(), itemType, attributeCount);
|
2015-06-01 18:25:20 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
return item;
|
|
|
|
}
|
|
|
|
|
2015-10-26 08:57:00 +01:00
|
|
|
private CustomItem generateItem(ItemType itemType)
|
2015-06-01 18:25:20 +02:00
|
|
|
{
|
|
|
|
switch(itemType)
|
|
|
|
{
|
|
|
|
case LEGENDARY: // Legendary weapon
|
|
|
|
Class<? extends LegendaryItem> legendaryClass = _legendaryWeights.generateRandom();
|
|
|
|
System.out.println("Legendary: " + legendaryClass.getName());
|
|
|
|
return instantiate(legendaryClass);
|
|
|
|
case WEAPON: // Sword or axe
|
|
|
|
return new CustomItem(_weaponTypes.generateRandom());
|
|
|
|
case ARMOUR: // Helmet, chestplate, leggings, or boots
|
|
|
|
return new CustomItem(_armourTypes.generateRandom());
|
|
|
|
case BOW: // A bow
|
|
|
|
return new CustomItem(Material.BOW);
|
|
|
|
default:
|
|
|
|
return null;// Never reached, yet required for compilation purposes.
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-10-26 08:57:00 +01:00
|
|
|
private void generateAttributes(AttributeContainer container, ItemType type, int count)
|
2015-06-01 18:25:20 +02:00
|
|
|
{
|
|
|
|
for (int i = 0; i < count; i++)
|
|
|
|
{
|
2015-06-29 22:38:51 +02:00
|
|
|
int attempts = 0;
|
|
|
|
Set<AttributeType> remaining = container.getRemainingTypes();
|
|
|
|
ItemAttribute attribute = null;
|
|
|
|
|
|
|
|
while (remaining.size() > 0 && attempts < 10 && attribute == null)
|
2015-06-01 18:25:20 +02:00
|
|
|
{
|
2015-06-29 22:38:51 +02:00
|
|
|
ItemAttribute sampleAttribute = null;
|
|
|
|
|
|
|
|
switch (type)
|
|
|
|
{
|
|
|
|
case ARMOUR:
|
|
|
|
sampleAttribute = instantiate(_armourAttributes.generateRandom());
|
|
|
|
break;
|
|
|
|
case WEAPON:
|
|
|
|
sampleAttribute = instantiate(_weaponAttributes.generateRandom());
|
|
|
|
break;
|
|
|
|
case BOW:
|
|
|
|
sampleAttribute = instantiate(_bowAttributes.generateRandom());
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (sampleAttribute != null && remaining.contains(sampleAttribute.getType()))
|
|
|
|
{
|
|
|
|
attribute = sampleAttribute; // Select valid attribute to add
|
|
|
|
}
|
2015-06-01 18:25:20 +02:00
|
|
|
}
|
2015-06-29 22:38:51 +02:00
|
|
|
|
|
|
|
container.addAttribute(attribute);
|
2015-06-01 18:25:20 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public void spawnItem(Location location)
|
|
|
|
{
|
|
|
|
CustomItem item = generateItem();
|
|
|
|
location.getWorld().dropItem(location, item.toItemStack());
|
2015-05-05 21:33:42 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
public static CustomItem parseItem(ItemStack item)
|
|
|
|
{
|
2015-05-25 20:22:06 +02:00
|
|
|
String serialization = getItemSerialization(item);
|
|
|
|
|
|
|
|
if (serialization != null)
|
|
|
|
{
|
2015-07-16 08:26:38 +02:00
|
|
|
|
|
|
|
CustomItem customItem = null;
|
|
|
|
|
|
|
|
try
|
|
|
|
{
|
|
|
|
customItem = deserialize(serialization);
|
|
|
|
}
|
|
|
|
catch (Exception exception)
|
|
|
|
{
|
|
|
|
System.out.println("==========");
|
|
|
|
System.out.println("GearManager parse problem :");
|
|
|
|
System.out.println(serialization);
|
|
|
|
System.out.println("==========");
|
|
|
|
}
|
|
|
|
|
2015-05-25 20:22:06 +02:00
|
|
|
return customItem;
|
|
|
|
}
|
|
|
|
|
|
|
|
return null; // No serialization found in item's lore, not a custom item!
|
2015-05-05 21:33:42 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
public static boolean isCustomItem(ItemStack item)
|
|
|
|
{
|
2015-05-25 20:22:06 +02:00
|
|
|
return getItemSerialization(item) != null;
|
|
|
|
}
|
|
|
|
|
|
|
|
public static String getItemSerialization(CustomItem customItem)
|
|
|
|
{
|
2015-06-01 21:51:22 +02:00
|
|
|
String serialization = serialize(customItem);
|
2015-05-25 20:22:06 +02:00
|
|
|
|
2015-06-01 21:51:22 +02:00
|
|
|
return ITEM_SERIALIZATION_TAG + serialization;
|
2015-05-25 20:22:06 +02:00
|
|
|
}
|
|
|
|
|
2015-06-01 18:25:20 +02:00
|
|
|
/**
|
|
|
|
* @param type - the class-type of the object to be instantiated. (must have zero-argument constructor)
|
|
|
|
* @return a newly instantiated instance of {@code type} class-type. Instantied with zero argument constructor.
|
|
|
|
*/
|
2015-10-26 08:57:00 +01:00
|
|
|
private static <T> T instantiate(Class<T> type)
|
2015-06-01 18:25:20 +02:00
|
|
|
{
|
|
|
|
try
|
|
|
|
{
|
|
|
|
return type.newInstance();
|
|
|
|
}
|
|
|
|
catch (Exception e)
|
|
|
|
{
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-10-26 08:57:00 +01:00
|
|
|
private static String getItemSerialization(ItemStack item)
|
2015-05-25 20:22:06 +02:00
|
|
|
{
|
|
|
|
if (item == null || item.getItemMeta() == null
|
|
|
|
|| item.getItemMeta().getLore() == null) return null;
|
|
|
|
|
|
|
|
ItemMeta meta = item.getItemMeta();
|
|
|
|
|
2015-06-01 21:51:22 +02:00
|
|
|
for (String lore : meta.getLore())
|
2015-05-25 20:22:06 +02:00
|
|
|
{
|
|
|
|
if (lore.startsWith(ITEM_SERIALIZATION_TAG)) // Found serialization lore-line
|
|
|
|
{
|
|
|
|
int tagLength = ITEM_SERIALIZATION_TAG.length();
|
|
|
|
String serialization = lore.substring(tagLength);
|
|
|
|
|
|
|
|
return serialization;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return null; // Unable to find any serialized lore lines, hence not a CustomItem.
|
|
|
|
}
|
|
|
|
|
|
|
|
public static String serialize(CustomItem customItem)
|
|
|
|
{
|
2015-06-01 18:25:20 +02:00
|
|
|
return _gson.toJson(customItem, CustomItem.class);
|
2015-05-25 20:22:06 +02:00
|
|
|
}
|
|
|
|
|
2015-06-22 22:20:20 +02:00
|
|
|
public static String serialize(AttributeContainer attributes)
|
|
|
|
{
|
|
|
|
return _gson.toJson(attributes, AttributeContainer.class);
|
|
|
|
}
|
|
|
|
|
2015-05-25 20:22:06 +02:00
|
|
|
public static CustomItem deserialize(String serialization)
|
|
|
|
{
|
|
|
|
return _gson.fromJson(serialization, CustomItem.class);
|
2015-05-05 21:33:42 +02:00
|
|
|
}
|
|
|
|
|
2015-06-22 22:20:20 +02:00
|
|
|
public static <T> T deserialize(String serialization, Class<T> type)
|
|
|
|
{
|
|
|
|
return _gson.fromJson(serialization, type);
|
|
|
|
}
|
|
|
|
|
2015-05-05 21:33:42 +02:00
|
|
|
/**
|
|
|
|
* @return singleton instance of {@link GearManager}.
|
|
|
|
*/
|
2015-09-29 23:36:42 +02:00
|
|
|
public static GearManager getInstance()
|
2015-05-05 21:33:42 +02:00
|
|
|
{
|
|
|
|
return _instance;
|
|
|
|
}
|
2015-08-31 02:05:45 +02:00
|
|
|
|
2015-09-29 23:36:42 +02:00
|
|
|
public static void notify(Player player, String message)
|
|
|
|
{
|
|
|
|
UtilPlayer.message(player, F.main("Gear", message));
|
|
|
|
}
|
|
|
|
|
2015-08-31 02:05:45 +02:00
|
|
|
/**
|
|
|
|
* @param player - the player to see if they should have their out-going packets
|
|
|
|
* masked on CustomGear items.
|
|
|
|
* @return true, if the player should have their gear lore masked, false otherwise.
|
|
|
|
*/
|
2015-10-26 08:57:00 +01:00
|
|
|
private boolean maskGearPacket(Player player)
|
2015-08-31 02:05:45 +02:00
|
|
|
{
|
|
|
|
return player.getGameMode() != GameMode.CREATIVE && !_creativePlayers.contains(player.getName());
|
|
|
|
}
|
2015-05-25 20:22:06 +02:00
|
|
|
|
|
|
|
@Override
|
|
|
|
public void handle(PacketInfo packetInfo)
|
|
|
|
{
|
2015-08-31 02:05:45 +02:00
|
|
|
// Don't mask custom gear lore for creative players, as this will break them.
|
|
|
|
if (!maskGearPacket(packetInfo.getPlayer())) return;
|
|
|
|
|
2015-05-25 20:22:06 +02:00
|
|
|
Packet packet = packetInfo.getPacket();
|
|
|
|
|
|
|
|
if (packet instanceof PacketPlayOutSetSlot)
|
2015-10-02 20:30:39 +02:00
|
|
|
{
|
2015-05-25 20:22:06 +02:00
|
|
|
PacketPlayOutSetSlot slotPacket = (PacketPlayOutSetSlot) packet;
|
2015-10-02 19:57:46 +02:00
|
|
|
slotPacket.c = maskItem(slotPacket.c); // Mask all out-going item packets
|
|
|
|
}
|
|
|
|
else if (packet instanceof PacketPlayOutWindowItems)
|
|
|
|
{
|
|
|
|
PacketPlayOutWindowItems itemsPacket = (PacketPlayOutWindowItems) packet;
|
2015-06-01 21:51:22 +02:00
|
|
|
|
2015-10-02 19:57:46 +02:00
|
|
|
for (int i = 0; i < itemsPacket.b.length; i++)
|
2015-06-01 21:51:22 +02:00
|
|
|
{
|
2015-10-02 19:57:46 +02:00
|
|
|
itemsPacket.b[i] = maskItem(itemsPacket.b[i]); // Mask all out-going item packets
|
|
|
|
}
|
2015-10-02 20:30:39 +02:00
|
|
|
}
|
2015-10-02 19:57:46 +02:00
|
|
|
}
|
|
|
|
|
2015-10-26 08:57:00 +01:00
|
|
|
private net.minecraft.server.v1_7_R4.ItemStack maskItem(net.minecraft.server.v1_7_R4.ItemStack item)
|
2015-10-02 19:57:46 +02:00
|
|
|
{
|
|
|
|
if (item == null) return null; // Cannot mask a null item
|
|
|
|
|
|
|
|
CraftItemStack originalItem = CraftItemStack.asCraftMirror(item);
|
|
|
|
ItemMeta originalMeta = originalItem.getItemMeta();
|
|
|
|
|
|
|
|
if (originalMeta == null || originalMeta.getLore() == null) return item; // No need to modify item packets with no lore
|
|
|
|
|
|
|
|
List<String> lore = new ArrayList<String>();
|
|
|
|
|
|
|
|
for (String line : originalMeta.getLore())
|
|
|
|
{
|
|
|
|
if (!line.startsWith(ITEM_SERIALIZATION_TAG)) // Remove serialization lines from out-going lore
|
|
|
|
{
|
|
|
|
lore.add(line);
|
2015-06-01 21:51:22 +02:00
|
|
|
}
|
2015-05-25 20:22:06 +02:00
|
|
|
}
|
2015-10-02 19:57:46 +02:00
|
|
|
|
|
|
|
net.minecraft.server.v1_7_R4.ItemStack newItem = CraftItemStack.asNMSCopy(originalItem);
|
|
|
|
CraftItemStack newCopy = CraftItemStack.asCraftMirror(newItem);
|
|
|
|
ItemMeta newMeta = newCopy.getItemMeta();
|
|
|
|
newMeta.setLore(lore);
|
|
|
|
newCopy.setItemMeta(newMeta);
|
|
|
|
return newItem;
|
2015-05-25 20:22:06 +02:00
|
|
|
}
|
2015-10-24 08:16:13 +02:00
|
|
|
|
|
|
|
public void openShop(Player player)
|
|
|
|
{
|
|
|
|
_shop.attemptShopOpen(player);
|
|
|
|
}
|
2015-05-05 21:33:42 +02:00
|
|
|
}
|