Luohuayu / CatServer

高性能和高兼容性的1.12.2/1.16.5/1.18.2版本Forge+Bukkit+Spigot服务端 (A high performance and high compatibility 1.12.2/1.16.5/1.18.2 version Forge+Bukkit+Spigot server)
https://catmc.org
GNU Lesser General Public License v3.0
1.98k stars 211 forks source link

[1.18.2]修复导致生存模式下栓绳从栅栏上取下后不掉落的bug #842

Closed CalenXwX closed 9 months ago

CalenXwX commented 9 months ago

CatServer在net.minecraft.world.entity.decoration.LeashFenceKnotEntity(栅栏上的栓绳结)类的interact方法(m6096)中插入了发布Bukkit事件的代码,但没有删除原版创造模式脱离绳结(m21455/dropLeash)的代码,在生存模式玩家右击栅栏上的绳结、生成掉落物时,重复执行的m21455/dropLeash被跳过,导致栓绳无法掉落为物品

Forge:

LeashFenceKnotEntity::m6096/interact

绳结.设为removed // 会使 this.leashHolder.isAlive() = false
if (创造模式)
{
    遍历生物
    {
        脱离绳结不掉落 { 生物.f_21359_/leashHolder=null }
    }
}

Mob::m6119/tickLeash

// if (生物.绳结 != null && (生物挂了 || 绳结被移除))
// if (this.leashHolder != null && (!this.isAlive() || !this.leashHolder.isAlive())
this.f_21357_ != null && (!this.m_6084_() || !this.f_21357_.m_6084_())
{
    掉落
}

// 创造模式:右击绳结时直接清除 // 生存模式:右击绳结时设为移除 tick生物时掉落

CatServer:

LeashFenceKnotEntity::m6096/interact

die = true
遍历生物
{
    脱离绳结不掉落m_21455_/dropLeash{生物.f_21359_/leashHolder=null} // 这里应该删去 dropLeash只能执行一次 此方法中判断f_21357_/leashHolder==null并设置f_21357_/leashHolder=null的语句会阻止后续再次执行
    if (Bukkit取消)
    {
        die=false
    }
    else
    {
        // 真正掉落栓绳实体的地方
        根据是否为创造模式掉落m_21455_/dropLeash
        {
            if (生物.f_21357_/leashHolder != null) // 前面执行dropLeash时已将leashHolder 设为null 这次dropLeash会被跳过
            {
                生物.f_21359_/leashHolder=null
                ...
            }
        }
    }
}
if (die==true)
{
    // 只有连接绳结的所有生物发布的Bukkit事件未被取消 这里才会执行
    绳结.设为removed // 会使 this.leashHolder.isAlive() = false
}

// 对一个生物来说 不会出现 this.leashHolder != null 且 this.leashHolder.isAlive() == false 的情况 // tick生物时 (this.leashHolder != null) 和 (!this.leashHolder.isAlive()) 不会同时为true 只有生物死亡时才会执行dropLeash

所以……这样修改还原了Bukkit中的写法 看起来大概是不会带来其他问题的w