Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

捡取普通物品时错误作为经验资源处理 #20

Closed
UsryK opened this issue Jul 30, 2022 · 11 comments
Closed

捡取普通物品时错误作为经验资源处理 #20

UsryK opened this issue Jul 30, 2022 · 11 comments
Labels
Priority: High Solve it as soon as possible Status: Done We have solved this issue Type: Bug Something went wrong

Comments

@UsryK
Copy link

UsryK commented Jul 30, 2022

摧毁玩家放置的方块时不会生成掉落物
可能的原因:经验拾取系统默认拾取掉落物时进行判定,并清除所被拾取的物品,而摧毁的方块也被进行了经验值判定,所以会无法捡起掉落物

@SakuraKoi
Copy link
Owner

SakuraKoi commented Jul 30, 2022

该情况不可能,插件不干涉方块摧毁,也不会删除挖掘方块的掉落物, 建议仅保留bwxp bwrel及必要插件测试能否复现

@SakuraKoi SakuraKoi added the Status: Invalid This issue seems not exists label Jul 30, 2022
@SakuraKoi
Copy link
Owner

另外到底是挖了不掉还是掉了一捡就没,这两种情况都不太可能是本插件导致的

@UsryK
Copy link
Author

UsryK commented Aug 7, 2022

的确是插件导致的,我在EventListener文件里面加了一个拾取经验判定,只对金,铁等物品进行经验值转化,就修好了捡方块消失的问题

@SakuraKoi
Copy link
Owner

SakuraKoi commented Aug 8, 2022

情况是一检就没对吧, 服务端及版本?

@SakuraKoi SakuraKoi added Type: Bug Something went wrong and removed Status: Invalid This issue seems not exists labels Aug 8, 2022
@SakuraKoi
Copy link
Owner

SakuraKoi commented Aug 8, 2022

以及贴一下如下内容

  1. 启动服务端时bwxp在后台输出的加载日志
  2. bedwarsrel的配置文件中资源部分
  3. bedwarsxp的配置文件

@SakuraKoi
Copy link
Owner

SakuraKoi commented Aug 8, 2022

问题点可能是 EventListeners.java:61
奇怪, 咱当初是怎么写出这代码的, 以及这代码是怎么稳定跑了这么久没出问题的 (挠头

TODO: ResourceUtils.convertResToXP() 后检查是否有效

@SakuraKoi SakuraKoi changed the title A bug 捡取普通物品时错误作为经验资源处理 Aug 8, 2022
@UsryK
Copy link
Author

UsryK commented Aug 8, 2022

`package ldcr.BedwarsXP;

import io.github.bedwarsrel.BedwarsRel;
import io.github.bedwarsrel.events.BedwarsGameEndEvent;
import io.github.bedwarsrel.events.BedwarsGameStartEvent;
import io.github.bedwarsrel.game.Game;
import ldcr.BedwarsXP.XPShop.ShopReplacer;
import ldcr.BedwarsXP.api.XPManager;
import ldcr.BedwarsXP.api.events.BedwarsXPDeathDropXPEvent;
import ldcr.BedwarsXP.utils.ResourceUtils;
import ldcr.BedwarsXP.utils.SoundMachine;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.enchantments.Enchantment;
import org.bukkit.entity.Item;
import org.bukkit.entity.Player;
import org.bukkit.entity.Projectile;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.entity.EntityDamageByEntityEvent;
import org.bukkit.event.entity.EntityDamageEvent;
import org.bukkit.event.entity.PlayerDeathEvent;
import org.bukkit.event.inventory.InventoryOpenEvent;
import org.bukkit.event.inventory.InventoryType;
import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.event.player.PlayerPickupItemEvent;
import org.bukkit.event.player.PlayerTeleportEvent;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;

import java.util.Collections;

public class EventListeners implements Listener {
@SuppressWarnings("deprecation")
@eventhandler
public void onItemPickup(PlayerPickupItemEvent e) {
Player p = e.getPlayer();
Game bw = checkGame(p);
if (bw == null)
return;

    Item entity = e.getItem();
    ItemStack stack = entity.getItemStack();
    if (stack == null)
        return;
    int count;
    if (stack.hasItemMeta() && stack.getItemMeta().getDisplayName() != null
            && stack.getItemMeta().getDisplayName().equals("§b§l&BedwarsXP_DroppedXP")) {
        count = Integer.parseInt(stack.getItemMeta().getLore().get(0));
    } else {
        count = ResourceUtils.convertResToXP(stack);
    }

    if (pickupXP(bw, p, count)) {
        if (stack.getType() == Material.DIAMOND
                || stack.getType() == Material.IRON_INGOT
                || stack.getType() == Material.GOLD_INGOT
                || stack.getType() == Material.CLAY_BRICK) {
            e.setCancelled(true);
            entity.remove();
            // p.kickPlayer("你在起床战争中捡起了[钻石/铁锭/金锭/红砖]");
        } else {
            e.setCancelled(false);
        }
    } else {
        e.setCancelled(true);
        entity.setPickupDelay(5);
    }
}

private boolean pickupXP(Game bw, Player player, int count) {
    if (count <= 0)
        return true;

    XPManager xpman = XPManager.getXPManager(bw.getName());
    // if current XP > maxXP -> deny pickup
    if (Config.maxXP != 0 && xpman.getXP(player) >= Config.maxXP) {
        xpman.sendMaxXPMessage(player);
        return false;
    }
    int added = xpman.getXP(player) + count;
    int leftXP = 0;
    // if after pickup XP>maxXP -> set XP = maxXP
    if (Config.maxXP != 0 && added > Config.maxXP) {
        leftXP = added - Config.maxXP;
        added = Config.maxXP;
    }
    xpman.setXP(player, added);
    player.playSound(player.getLocation(), SoundMachine.get("ORB_PICKUP", "ENTITY_EXPERIENCE_ORB_PICKUP"), 0.2F,
            1.5F);
    xpman.sendXPMessage(player, count);
    if (leftXP > 0) {
        dropXPBottle(player, leftXP);
    }
    return true;
}

private void dropXPBottle(Player player, int xp) {
    ItemStack dropStack = new ItemStack(Material.EXP_BOTTLE, 16);
    ItemMeta meta = dropStack.getItemMeta();
    meta.setDisplayName("§b§l&BedwarsXP_DroppedXP");
    meta.setLore(Collections.singletonList(String.valueOf(xp)));
    meta.addEnchant(Enchantment.LOOT_BONUS_MOBS, 1, true);
    dropStack.setItemMeta(meta);
    Item droppedItem = player.getWorld().dropItemNaturally(player.getLocation().add(0, 1, 0), dropStack);
    droppedItem.setPickupDelay(40);
}

@EventHandler
public void onAnvilOpen(InventoryOpenEvent e) {
    if (e.getPlayer() == null)
        return;
    if (e.getInventory() == null)
        return;
    Game bw = checkGame((Player) e.getPlayer());
    if (bw == null)
        return;
    if (e.getInventory().getType().equals(InventoryType.ANVIL)) {
        e.setCancelled(true);
    }
}

@EventHandler
public void onPlayerDeath(PlayerDeathEvent e) {
    Player p = e.getEntity();
    Game bw = checkGame(p);
    if (bw == null)
        return;

    XPManager xpman = XPManager.getXPManager(bw.getName());
    // 计算死亡扣除经验值
    int costed = (int) (xpman.getXP(p) * Config.deathCost);
    // 计算死亡掉落经验值
    int dropped = 0;
    if (Config.deathDrop > 0) {
        dropped = (int) (costed * Config.deathDrop);
    }
    BedwarsXPDeathDropXPEvent event = new BedwarsXPDeathDropXPEvent(bw.getName(), p, dropped, costed);
    Bukkit.getPluginManager().callEvent(event);
    costed = event.getXPCost();
    dropped = event.getXPDropped();
    // 扣除经验
    int to = xpman.getXP(p) - costed;
    if (to < 0) {
        to = 0;
    }
    e.setNewLevel(to);
    xpman.setXP(p, to);
    // 掉落经验
    if (dropped < 1)
        return;
    if (Config.dontDropExpBottle) {
        EntityDamageEvent ev = p.getLastDamageCause();
        if (ev instanceof EntityDamageByEntityEvent) {
            Object killer = ((EntityDamageByEntityEvent) ev).getDamager();
            if (killer instanceof Projectile) {
                killer = ((Projectile) killer).getShooter();
            }
            if (killer instanceof Player) {
                pickupXP(bw, (Player) killer, dropped);
                return;
            }
        }
    }
    dropXPBottle(p, dropped);
}

@EventHandler
public void onBedWarsStart(BedwarsGameStartEvent e) {
    if (e.isCancelled())
        return;
    if (!Config.isGameEnabledXP(e.getGame().getName()))
        return;
    ShopReplacer.replaceShop(e.getGame().getName(), BedwarsXP.getConsoleSender());
}

@EventHandler
public void onBedWarsEnd(BedwarsGameEndEvent e) {
    if (!Config.isGameEnabledXP(e.getGame().getName()))
        return;
    XPManager.reset(e.getGame().getName());
}

@EventHandler
public void onPlayerTeleport(PlayerTeleportEvent e) { // 在玩家传送后更新经验条
    Player p = e.getPlayer();
    Game bw = checkGame(p);
    if (bw == null)
        return;
    Bukkit.getScheduler().runTaskLater(BedwarsXP.getInstance(),
            () -> XPManager.getXPManager(bw.getName()).updateXPBar(p), 5);

}

@EventHandler
public void onPlayerInteract(PlayerInteractEvent e) {
    Game bw = checkGame(e.getPlayer());
    if (bw == null)
        return;
    XPManager.getXPManager(bw.getName()).updateXPBar(e.getPlayer());
}

@EventHandler
public void onPlayerJoin(PlayerJoinEvent e) {
    if (BedwarsXP.getUpdateUrl() != null && e.getPlayer().hasPermission("bedwarsxp.admin")) {
        Bukkit.getScheduler().runTaskLater(BedwarsXP.getInstance(), () -> {
            if (e.getPlayer().isOnline())
                e.getPlayer().sendMessage(
                        "§6§lBedwarsXP §7>> §b" + BedwarsXP.l18n("HAS_UPDATE", "%link%", BedwarsXP.getUpdateUrl()));
        }, 30);
    }
}

private Game checkGame(Player player) {
    Game bw = BedwarsRel.getInstance().getGameManager().getGameOfPlayer(player);
    if (bw == null)
        return null;
    if (!Config.isGameEnabledXP(bw.getName()))
        return null;
    return bw;
}

}
`

@UsryK
Copy link
Author

UsryK commented Aug 8, 2022

这是改过的EventListener.java,服务器使用的1.8.9游戏版本,因为我只是帮修一下bug,服不是我开的,日志可能不太方便,见谅

@UsryK
Copy link
Author

UsryK commented Aug 8, 2022

问题已经解决,服务器及BedWar可以正常运行,没有对其他文件进行修改

@SakuraKoi
Copy link
Owner

你这改的代码不具有普适性, 并不是所有服务器的资源都是这几种物品
新版本已发, 理论上bug已于Release 2.1.2中解决
如发现问题仍然存在请reopen

@SakuraKoi SakuraKoi added Priority: High Solve it as soon as possible Status: Done We have solved this issue labels Aug 8, 2022
@UsryK
Copy link
Author

UsryK commented Aug 11, 2022

嘛,有需要手动改一下不就好了嘛,关键是思维难度小啊你说对不对 [手动狗头]

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Priority: High Solve it as soon as possible Status: Done We have solved this issue Type: Bug Something went wrong
Projects
None yet
Development

No branches or pull requests

2 participants