本帖最后由 longlongz 于 2018-11-20 04:13 编辑
BossShopPro
Item Comparison | 物品对比
字数统计: 2744字


如何接入API
首先你需要添加BossShopPro.jar 到你的Libraries里.
你可以使用下方方法来获取:
  1. import org.black_ixx.bossshop.BossShop;
  2. import org.black_ixx.bossshop.api.BossShopAPI;
  3. import org.bukkit.Bukkit;
  4. import org.bukkit.plugin.Plugin;

  5. public class BSPHook {

  6.     private BossShop bs; //BossShopPro 插件实例

  7.     public BSPHook(){
  8.         Plugin plugin = Bukkit.getPluginManager().getPlugin("BossShopPro"); //获取BossShopPro 插件

  9.        if(plugin==null){ //Not installed?
  10.            System.out.print("[BSP Hook] BossShopPro was not found... you can download it here: https://www.spigotmc.org/resources/25699/");
  11.             return;
  12.         }

  13.         bs = (BossShop) plugin; //Success :)

  14.     }


  15.     public BossShopAPI getBSPAPI(){
  16.         return bs.getAPI(); //Returns BossShopPro API
  17.     }

  18. }
复制代码


打开一个商店
  1. public boolean openShop(Player p, String shop_name){

  2.         BSShop shop = bs.getAPI().getShop(shop_name);
  3.        if(shop==null){
  4.            p.sendMessage(ChatColor.RED+"Shop "+shop_name+" not found...");
  5.             return false;
  6.         }

  7.        bs.getAPI().openShop(p, shop);

  8.         return true;
  9.     }
复制代码

检查一个物品是否属于BossShopPro
  1.    //例子:物品事件
  2.        if(bs.getAPI().isValidShop(event.getInventory())){
  3.             //商店物品动作
  4.         }else{
  5.             //其余
  6.         }
复制代码

将一个商店物品添加到商店中
  1.         //创建一个自定义BSBuy (商店物品)
  2.                 BSBuy buy = bs.getAPI().createBSBuy(BSRewardType.Shop, BSPriceType.Nothing, "item_shop", null, null, 1, "OpenShop.Item_Shop");

  3.                 //获取商店信息
  4.                 BSShop shop = bs.getAPI().getShop("menu");

  5.                 //将物品添加到商店
  6.                ItemStack menu_item = [...]
  7.                bs.getAPI().addItemToShop(menu_item, buy, shop);
复制代码

注册一个自定义点数插件
你的插件必须要在BossShopPro之前载入
Plugin.yml
  1. loadbefore: [BossShop]
复制代码

拓展BSPointsPlugin class
  1. [暂无]
复制代码

然后onEnable,示例你的class,然后注册使用方法
  1. new Points().register();
复制代码

如何创建一个附属插件
首先添加BossShopPro.jar 到你的libraries里。正常来说Bukkit插件的main class需要拓展org.bukkit.plugin.java.JavaPlugin,然而当你创建一个BossShopPro 附属插件时你需要导入以下的拓展之一:
· org.black_ixx.bossshop.api.BossShopAddon – 简易版附属
· org.black_ixx.bossshop.api.BossShopAddonConfigurable – 提供额外的对config文件的帮助,会在"plugins/BossShopPro/Addons/<名称>/" 中创建文件
  1. import org.black_ixx.bossshop.api.BSAddonStorage;
  2. import org.black_ixx.bossshop.api.BossShopAddon;
  3. import org.bukkit.command.CommandSender;

  4. public class BSPAddon extends BossShopAddon{

  5.     @Override
  6.     public String getAddonName() {
  7.         return "ExampleAddon"; //在这里放你想要的附属插件名字
  8.     }
  9.     @Override
  10.     public String getRequiredBossShopVersion() {
  11.         return "1.1.7"; //这里放你的插件所支持的最老版本的BSP插件build版本(只需要数字和点;不需要"v"前缀)
  12.     }

  13.     @Override
  14.     public void enableAddon() {
  15.         //这个方法在附属插件加载后执行(会在BossShopPro被加载时执行;商店,商店物品,奖励类型等还暂时缺失)

  16.         //使用的方法:创建自定义储存文件到附属插件文件夹内
  17.         //这些储存文件类型暂时被限制到一组方法之中并无法直接获得Bukkit FileConfiguration 例子的权限,
  18.         //因为在未来会有其他新的储存类型可能会被告知
  19.         //下方的例子显示了你可以操作的部分。当然,储存class组不止是有下方例子的选项
  20.        BSAddonStorage storage = this.createStorage(this, "StorageFileName"); //创建并装载一个储存文件

  21.        storage.set("Number", 2); //设置一个整数数值
  22.        storage.set("Text", "This is some text"); //设置一个字符数值

  23.         int number = storage.getInt("Value", -1); //读取数值(如果没有找到数值, 基础数值“-1”会被返回)
  24.         String text = storage.getString("Text", null); //读取数值,自失败的情况下返回无数值

  25.         storage.save(); //储存文件
  26.        storage.saveAsync(); //异步存储文件
  27.     }

  28.     @Override
  29.     public void disableAddon() {
  30.         //当附加插件被禁用时执行
  31.     }

  32.     @Override
  33.     public void bossShopFinishedLoading() {
  34.         //当BSP被完全执行时执行(包括但不限于商店,商品和奖励类型)
  35.     }

  36.     @Override
  37.     public void bossShopReloaded(CommandSender sender) {
  38.         //当BSP被手动重新装载之后执行("/bossshop reload")
  39.     }


  40. }
复制代码
  1. import org.black_ixx.bossshop.api.BSAddonConfig;
  2. import org.black_ixx.bossshop.api.BossShopAddonConfigurable;
  3. import org.black_ixx.bossshop.managers.config.FileHandler;
  4. import org.bukkit.command.CommandSender;
  5. import org.bukkit.configuration.file.FileConfiguration;

  6. public class BSPAddonConfigurable extends BossShopAddonConfigurable{

  7.     @Override
  8.     public String getAddonName() {
  9.         return "ExampleAddonConfigurable"; //在这里选择附加插件的名字
  10.     }
  11.     @Override
  12.     public String getRequiredBossShopVersion() {
  13.         return "1.1.7"; //在这里放入最老能支持附加插件的BSP版本(只有数字和小数点; 没有"v" 前缀)
  14.     }

  15.     @Override
  16.     public void enableAddon() {
  17.         //当附加插件被允许时执行 当BSP核心被装载时发生, 商品,奖励类型和更多都处于缺失状态)

  18.         //设置文件方法A:
  19.        if(!getAddonConfig().getFile().exists()){
  20.             new FileHandler().copyFromJar(this, "config.yml"); //这个文件处理器允许复制并完成addon.jar 文件里的设置文件
  21.         }

  22.         //设置文件方法B:
  23.         getConfig().options().copyDefaults(true);
  24.        getConfig().addDefault("PointsPlugin", "TokenEnchant");
  25.        getConfig().addDefault("Message.NotEnoughPoints", "&cYou don't have enough Tokens!");
  26.        getConfig().addDefault("Placeholder.DisplayPoints", "%points2% Tokens");
  27.        getConfig().addDefault("PointsDisplay.Enabled", false);
  28.         saveConfig(); //从v1.2.1. 开始运作,在使用"getAddonConfig().save();"之前


  29.         //你可以访问文件设置,并为所欲为:
  30.        FileConfiguration config = getConfig();

  31.         //或者你可以访问 BSAddonConfig, 以提供更多的方法
  32.         BSAddonConfig addonconfig = getAddonConfig();
  33.        addonconfig.saveAsync(); //Saves file asynchronously
  34.        addonconfig.deleteAll("Key"); //删除全部"Key."打头的设置访问记录

  35.     }

  36.     @Override
  37.     public void disableAddon() {
  38.         //当附加插件被禁用时执行
  39.     }

  40.     @Override
  41.     public void bossShopFinishedLoading() {
  42.         /当BSP被完全装载执行
  43.     }

  44.     @Override
  45.     public void bossShopReloaded(CommandSender sender) {
  46.         //当BSP被手动重新装载时执行("/bossshop reload")
  47.     }

  48.     @Override
  49.     public boolean saveConfigOnDisable() {
  50.         return false; //如果设置为真,设置文件每次附加文件被禁用会重新保存    }


  51. }
复制代码

如何创建一个自定义奖励类型
首先你需要创建一个奖励class
  1. import java.util.List;

  2. import org.black_ixx.bossshop.core.BSBuy;
  3. import org.black_ixx.bossshop.core.rewards.BSRewardType;
  4. import org.black_ixx.bossshop.managers.ClassManager;
  5. import org.black_ixx.bossshop.managers.misc.InputReader;
  6. import org.black_ixx.bossshop.managers.misc.StringManipulationLib;
  7. import org.bukkit.entity.Player;
  8. import org.bukkit.event.inventory.ClickType;

  9. import net.milkbowl.vault.permission.Permission;

  10. public class BSRewardTypePermission extends BSRewardType{


  11.     public Object createObject(Object o, boolean force_final_state){ //force_final_state 总会是真,除非用BossShopProConfigure 访问
  12.         return InputReader.readStringList(o); //你可以把设置文件里的物品变成任何物品. 物品会被返回到这里.在以后会有用
  13.     }

  14.     public boolean validityCheck(String item_name, Object o){ //当"createObject" 被召唤之后执行. 在这里你可以查看物品的真实性.
  15.         if(o!=null){
  16.             return true;
  17.         }
  18.         ClassManager.manager.getBugFinder().severe("Was not able to create ShopItem "+item_name+"! The reward object needs to be a list of permissions (text lines).");
  19.         return false;
  20.     }

  21.     public void enableType(){ //如果你的奖励类型有任何特殊性质,在这里开启
  22.         ClassManager.manager.getSettings().setPermissionsEnabled(true);
  23.        ClassManager.manager.getSettings().setVaultEnabled(true);
  24.     }

  25.     @Override
  26. public boolean canBuy(Player p, BSBuy buy, boolean message_if_no_success, Object reward, ClickType clickType) { //在这里同意、拒绝玩家购买商品
  27.         for (String s : (List<String>) reward){
  28.             if (!p.hasPermission(s)) {
  29.                 return true; //玩家缺少权限?可以买!
  30.             }
  31.         }
  32.        if(message_if_no_success){
  33.            ClassManager.manager.getMessageHandler().sendMessage("Main.AlreadyBought", p); //如果玩家有以下全部的权限可以禁止玩家购买
  34.         }
  35.         return false;
  36.     }

  37.     @Override
  38.     public void giveReward(Player p, BSBuy buy, Object reward, ClickType clickType) { //如果所有都成功玩家在这里拿到奖励
  39.        List<String> permissions = (List<String>) reward;

  40.         Permission per = ClassManager.manager.getVaultHandler().getPermission();
  41.         for (String s : permissions) {
  42.            per.playerAdd(p, s);
  43.         }
  44.     }

  45.     @Override
  46.     public String getDisplayReward(Player p, BSBuy buy, Object reward, ClickType clickType) { //在这里定义"%reward%" 定位符怎么展示        List<String> permissions = (List<String>) reward;
  47.         String permissions_formatted = StringManipulationLib.formatList(permissions);
  48.         return ClassManager.manager.getMessageHandler().get("Display.Permission").replace("%permissions%", permissions_formatted);
  49.     }

  50.     @Override
  51.     public String[] createNames() { //在这里定义引导奖励的所有名称, 第一个入口是主要名称.
  52.         return new String[]{"permission", "permissions"};
  53.     }

  54.     @Override
  55.     public boolean mightNeedShopUpdate() { //在这里决定物品被购买之后商店是否刷新
  56.         return true;
  57.     }

  58.     //以下是可选择的:

  59.     @Override
  60.     public boolean logTransaction(){
  61.         return false; //默认设置为真. 如果你不希望购买被记录,把这个设置为假
  62.     }


  63. }
复制代码
如果你的奖励是数字类型的然后你想要完全支持所有BossShopPro 的功能项"ItemAll" pricetype, 则拓展BSRewardTypeNumber

  1. import org.black_ixx.bossshop.core.BSBuy;
  2. import org.black_ixx.bossshop.core.rewards.BSRewardTypeNumber;
  3. import org.black_ixx.bossshop.managers.ClassManager;
  4. import org.black_ixx.bossshop.managers.misc.InputReader;
  5. import org.bukkit.entity.Player;
  6. import org.bukkit.event.inventory.ClickType;


  7. public class BSRewardTypeExp extends BSRewardTypeNumber{


  8.     public Object createObject(Object o, boolean force_final_state){ //force_final_state 总会是真除非被BossShopProConfigure 工具访问
  9.         return InputReader.getInt(o, -1); //尝试读取设置内奖励的数字; 失败返回-1
  10.     }

  11.     public boolean validityCheck(String item_name, Object o){ //这个方法当"createObject" 被召唤时执行. 这里你可以查看物品真实性.
  12.        if((Integer)o!=-1){
  13.             return true;
  14.         }
  15.        ClassManager.manager.getBugFinder().severe("Was not able to create ShopItem "+item_name+"! The reward object needs to be a valid Integer number. Example: '7' or '12'.");
  16.         return false;
  17.     }

  18.     public void enableType(){ //你过你的奖励类型有任何特殊性质,在这里开启
  19.     }

  20.     @Override
  21.     public boolean canBuy(Player p, BSBuy buy, boolean message_if_no_success, Object reward, ClickType clickType) { //这里你可以同意、拒绝玩家购买
  22.         return true;
  23.     }

  24.     @Override
  25.     public void giveReward(Player p, BSBuy buy, Object reward, ClickType clickType) { //如果全部过程顺利玩家在这里拿到奖励
  26.         int exp = (int) ClassManager.manager.getMultiplierHandler().calculateRewardWithMultiplier(p, buy, clickType, ((Integer) reward), false); //如果你想要倍数被兼容的话,请使用倍数处理程序.重要: 在这种情况下你的pricetype必须和rewardtype一样
  27.        p.setLevel(p.getLevel() + exp);
  28.     }

  29.     @Override
  30.     public String getDisplayReward(Player p, BSBuy buy, Object reward, ClickType clickType) { //这里你决定了"%reward%" 占位符怎么展示这种奖励
  31.         int exp = (int) ClassManager.manager.getMultiplierHandler().calculateRewardWithMultiplier(p, buy, clickType, ((Integer) reward), true);
  32.         return ClassManager.manager.getMessageHandler().get("Display.Exp").replace("%levels%", String.valueOf(exp));
  33.     }

  34.     @Override
  35.     public String[] createNames() { //这里你决定所有指向奖励的名称,第一个入口是主要名称.
  36.         return new String[]{"exp", "xp", "level", "levels"};
  37.     }


  38.     @Override
  39.     public boolean mightNeedShopUpdate() { //这里你决定在奖励被购买之后商店是否刷新
  40.         return true;
  41.     }

  42.     @Override
  43.     public boolean isIntegerValue() { //这里你决定奖励要么是integer价格要么是double价格
  44.         return true;
  45.     }


  46. }
复制代码

自定义价格类型例子
  1. import org.black_ixx.bossshop.core.BSBuy;
  2. import org.black_ixx.bossshop.core.prices.BSPriceTypeNumber;
  3. import org.black_ixx.bossshop.managers.ClassManager;
  4. import org.black_ixx.bossshop.managers.misc.InputReader;
  5. import org.black_ixx.bossshop.misc.MathTools;
  6. import org.bukkit.entity.Player;
  7. import org.bukkit.event.inventory.ClickType;

  8. public class BSPriceTypeThirdCurrencyVariable extends BSPriceTypeNumber{

  9.     private CustomPoints cp;

  10.     public BSPriceTypeThirdCurrencyVariable(CustomPoints points){
  11.         this.cp = points;
  12.         updateNames(); //更新进入商店设置需要的名称从而使用这种价格类型: 现在自定义点数被设置为点数的名称(看#createNames())
  13.     }


  14.     /从设置接受价格物品并把它变成以后会用得到的物品
  15.     public Object createObject(Object o, boolean force_final_state){
  16.         return InputReader.getDouble(o, -1);
  17.     }

  18.     public boolean validityCheck(String item_name, Object o){ //验证价格物品
  19.        if((Double)o!=-1){
  20.             return true;
  21.         }
  22.         ClassManager.manager.getBugFinder().severe("Was not able to create ShopItem "+item_name+"! The price object needs to be a valid number. Example: '7' or '12'.");
  23.         return false;
  24.     }

  25.     public void enableType(){ //当价格类型在商店被使用时当BSP开始时执行一次
  26.     //可以被用来注册Vault的文件
  27.     }


  28.     @Override
  29.     public boolean hasPrice(Player p, BSBuy buy, Object price, ClickType clickType, int multiplier, boolean messageOnFailure) {
  30.         double points = ClassManager.manager.getMultiplierHandler().calculatePriceWithMultiplier(p, buy, clickType, (Double) price) * multiplier;
  31.         if (cp.getPointsManager().getPoints(p) < points) {
  32.             String message = cp.getMessageNotEnoughPoints();
  33.             if(message != null && messageOnFailure){
  34.                p.sendMessage(ClassManager.manager.getStringManager().transform(message, buy, buy.getShop(), null, p));
  35.             }
  36.             return false;
  37.         }
  38.         return true;
  39.     }

  40.     @Override
  41.     public String takePrice(Player p, BSBuy buy, Object price, ClickType clickType, int multiplier) {
  42.         double points = ClassManager.manager.getMultiplierHandler().calculatePriceWithMultiplier(p, buy, clickType, (Double) price) * multiplier;

  43.        cp.getPointsManager().takePoints(p, points);
  44.         return getDisplayBalance(p, buy, price, clickType);
  45.     }

  46.     @Override
  47.     public String getDisplayBalance(Player p, BSBuy buy, Object price, ClickType clickType) {
  48.         double balance_points = cp.getPointsManager().getPoints(p);
  49.         return cp.getPlaceholderPoints().replace("%"+cp.getName()+"%", MathTools.displayNumber(balance_points, cp.getSpecialDisplayFormatting(), !cp.getPointsManager().usesDoubleValues()));
  50.     }

  51.     @Override
  52.     public String getDisplayPrice(Player p, BSBuy buy, Object price, ClickType clickType) {
  53.         return ClassManager.manager.getMultiplierHandler().calculatePriceDisplayWithMultiplier(p, buy, clickType, (Double) price, cp.getPlaceholderPoints().replace("%"+cp.getName()+"%", "%number%"), cp.getSpecialDisplayFormatting(), true);
  54.     }


  55.     @Override
  56.     public String[] createNames() { //价格类型用户的名称可以被用于进入设置
  57.         if(cp == null){
  58.         return new String[]{"thirdcurrency", "points2", "point2"};
  59.         }else{
  60.             return new String[]{cp.getName()};
  61.         }
  62.     }

  63.     public boolean supportsMultipliers(){
  64.         return true; //makes RewardTypes like BuyAll possible
  65.     }

  66.     @Override
  67.     public boolean mightNeedShopUpdate() {
  68.         return true; //这个价格类型是否执行取决于是否更新(比如占位符的变化)
  69.     }

  70.     @Override
  71.     public boolean isIntegerValue() {
  72.         return false; //needs to be defined because the class extends BSPriceTypeNumber
  73.     }
复制代码

如何创建自己的物品数据(itemdata)部分

1.    伸展BossShopPro class "ItemDataPart"
2.    执行所有授予的方案all given methods
3.    创建一个监听器来监听"BSRegisterTypesEvent" 然后创建一个你的自定义ItemDataPart 的例子. 另外使用"register" 方法注册例子.

ItemDataPart例子
  1. public class ItemDataPartMaterial extends ItemDataPart{
  2.   public ItemStack transform(ItemStack item, String used_name, String argument)  {
  3.     short durability = 0;
  4.     Material m = Material.STONE;

  5.     if (argument.contains(":")) {
  6.       String[] parts = argument.split(":");
  7.       if (parts.length > 1) {
  8.         durability = (short)InputReader.getInt(parts[1].trim(), 0);
  9.       }
  10.       argument = parts[0].trim();
  11.     }

  12.     m = InputReader.readMaterial(argument);

  13.     if (m == null) {
  14.      ClassManager.manager.getBugFinder().severe("Mistake in Config: '" + argument + "' is not a valid '" + used_name + "'. Unable to find a fitting material.");
  15.       return item;
  16.     }

  17.     item.setType(m);
  18.    item.setDurability(durability);
  19.     return item;
  20.   }

  21.   public int getPriority()  {
  22.     return PRIORITY_MOST_EARLY;
  23.   }

  24.   public boolean removeSpaces()  {
  25.     return true;
  26.   }

  27.   public String[] createNames()  {
  28.     return new String[] { "type", "id", "material" };
  29.   }

  30.   public List<String> read(ItemStack i, List<String> output)  {
  31.    output.add("type:" + i.getType().name());
  32.     return output;
  33.   }

  34.   public boolean isSimilar(ItemStack shop_item, ItemStack player_item, BSBuy buy, Player p)  {
  35.     return shop_item.getType() == player_item.getType();
  36.   }
  37. }
复制代码


监听器例子
  1.   @EventHandler
  2.   public void onRegister(BSRegisterTypesEvent event)  {
  3.     new ItemDataPartMaterial().register();
  4.   }
复制代码