hxp
2023-01-12 063c37a60dfad1fad8e31ee235e0d69c3ae35481
9762 【BT8】【后端】藏宝阁(古宝特殊效果属性支持)

# Conflicts:
# ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Event/EventSrc/Operate_EquipEnchant.py
# ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Item/ChEquip.py
# ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerControl.py
7个文件已修改
781 ■■■■■ 已修改文件
PySysDB/PySysDBPY.h 25 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
PySysDB/生成IpyGameDataPY/config.ini 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Event/EventSrc/Operate_EquipWash.py 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/IpyGameDataPY.py 67 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerGubao.py 620 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerHorse.py 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerPet.py 38 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
PySysDB/PySysDBPY.h
@@ -429,6 +429,15 @@
    DWORD        SkinValidTime;    //有效时长秒
};
//坐骑表
struct tagHorse
{
    DWORD        _HorseID;    //坐骑ID
    DWORD        HorseSkinID;    //外观物品ID
    BYTE        Quality;    //坐骑品质
};
//古宝表
struct tagGubao
@@ -446,8 +455,20 @@
    WORD        _GubaoID;    //古宝ID
    BYTE        _GubaoStar;    //古宝星级
    list        StarUPNeedItemInfo;    //升星所需物品 [[物品ID,个数], ...]
    list        StarAttrTypeList;    //星级属性类型列表
    list        StarAttrValueList;    //星级属性值列表
    list        StarEffIDList;    //星级特殊效果ID列表
};
//古宝特殊效果表
struct tagGubaoEffAttr
{
    DWORD        _GubaoEffID;    //古宝特殊效果ID
    BYTE        GubaoEffType;    //效果类型
    DWORD        EffCond;    //条件
    BYTE        IsPer;    //是否百分比提升
    list        EffFuncAttrIDList;    //提升指定功能属性ID列表
    DWORD        EffAttrID;    //直接增加属性类型
    DWORD        EffAttrValue;    //提升属性值
};
//古宝品质升级表
PySysDB/Éú³ÉIpyGameDataPY/config.ini
@@ -1,5 +1,5 @@
[config]
; é¡¹ç›®æ ¹è·¯å¾„
CodeProjectPath = E:\Git\SnxxServerCode\ServerPython
CodeProjectPath = E:\SnxxServerCode\ServerPython
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Event/EventSrc/Operate_EquipWash.py
@@ -454,7 +454,7 @@
    playControl.RefreshPlayerAttrState()
    return
def CalcAttr_EquipWash(curPlayer, equipIndex, equipPlace, allAttrList):
def CalcAttr_EquipWash(curPlayer, equipIndex, equipPlace, baseAttrDictWash, allAttrList):
    ## è£…备位洗练属性
    washLV = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_EquipWashLV % equipIndex)
    maxWashLV = GetEquipWashMaxLV(curPlayer, equipIndex, equipPlace)
@@ -474,6 +474,7 @@
        #GameWorld.DebugLog("    attrNum=%s,attrID=%s, attrValue=%s" % (attrNum, attrID, attrValue))
        if attrValue:
            PlayerControl.CalcAttrDict_Type(attrID, attrValue, allAttrList)
            baseAttrDictWash[attrID] = baseAttrDictWash.get(attrID, 0) + attrValue
    return
def EquipWashSuccess(curPlayer, classLV):
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/IpyGameDataPY.py
@@ -357,6 +357,12 @@
                        ("DWORD", "SkinValidTime", 0),
                        ),
                "Horse":(
                        ("DWORD", "HorseID", 1),
                        ("DWORD", "HorseSkinID", 0),
                        ("BYTE", "Quality", 0),
                        ),
                "Gubao":(
                        ("WORD", "GubaoID", 1),
                        ("BYTE", "GubaoQuality", 0),
@@ -368,8 +374,17 @@
                        ("WORD", "GubaoID", 1),
                        ("BYTE", "GubaoStar", 1),
                        ("list", "StarUPNeedItemInfo", 0),
                        ("list", "StarAttrTypeList", 0),
                        ("list", "StarAttrValueList", 0),
                        ("list", "StarEffIDList", 0),
                        ),
                "GubaoEffAttr":(
                        ("DWORD", "GubaoEffID", 1),
                        ("BYTE", "GubaoEffType", 0),
                        ("DWORD", "EffCond", 0),
                        ("BYTE", "IsPer", 0),
                        ("list", "EffFuncAttrIDList", 0),
                        ("DWORD", "EffAttrID", 0),
                        ("DWORD", "EffAttrValue", 0),
                        ),
                "GubaoLV":(
@@ -2759,6 +2774,19 @@
    def GetHorseID(self): return self.HorseID # å¯¹åº”坐骑ID
    def GetSkinValidTime(self): return self.SkinValidTime # æœ‰æ•ˆæ—¶é•¿ç§’
# åéª‘表
class IPY_Horse():
    def __init__(self):
        self.HorseID = 0
        self.HorseSkinID = 0
        self.Quality = 0
        return
    def GetHorseID(self): return self.HorseID # åéª‘ID
    def GetHorseSkinID(self): return self.HorseSkinID # å¤–观物品ID
    def GetQuality(self): return self.Quality # åéª‘品质
# å¤å®è¡¨
class IPY_Gubao():
    
@@ -2781,15 +2809,34 @@
        self.GubaoID = 0
        self.GubaoStar = 0
        self.StarUPNeedItemInfo = []
        self.StarAttrTypeList = []
        self.StarAttrValueList = []
        self.StarEffIDList = []
        return
        
    def GetGubaoID(self): return self.GubaoID # å¤å®ID
    def GetGubaoStar(self): return self.GubaoStar # å¤å®æ˜Ÿçº§
    def GetStarUPNeedItemInfo(self): return self.StarUPNeedItemInfo # å‡æ˜Ÿæ‰€éœ€ç‰©å“ [[物品ID,个数], ...]
    def GetStarAttrTypeList(self): return self.StarAttrTypeList # æ˜Ÿçº§å±žæ€§ç±»åž‹åˆ—表
    def GetStarAttrValueList(self): return self.StarAttrValueList # æ˜Ÿçº§å±žæ€§å€¼åˆ—表
    def GetStarEffIDList(self): return self.StarEffIDList # æ˜Ÿçº§ç‰¹æ®Šæ•ˆæžœID列表
# å¤å®ç‰¹æ®Šæ•ˆæžœè¡¨
class IPY_GubaoEffAttr():
    def __init__(self):
        self.GubaoEffID = 0
        self.GubaoEffType = 0
        self.EffCond = 0
        self.IsPer = 0
        self.EffFuncAttrIDList = []
        self.EffAttrID = 0
        self.EffAttrValue = 0
        return
    def GetGubaoEffID(self): return self.GubaoEffID # å¤å®ç‰¹æ®Šæ•ˆæžœID
    def GetGubaoEffType(self): return self.GubaoEffType # æ•ˆæžœç±»åž‹
    def GetEffCond(self): return self.EffCond # æ¡ä»¶
    def GetIsPer(self): return self.IsPer # æ˜¯å¦ç™¾åˆ†æ¯”提升
    def GetEffFuncAttrIDList(self): return self.EffFuncAttrIDList # æå‡æŒ‡å®šåŠŸèƒ½å±žæ€§ID列表
    def GetEffAttrID(self): return self.EffAttrID # ç›´æŽ¥å¢žåŠ å±žæ€§ç±»åž‹
    def GetEffAttrValue(self): return self.EffAttrValue # æå‡å±žæ€§å€¼
# å¤å®å“è´¨å‡çº§è¡¨
class IPY_GubaoLV():
@@ -6461,10 +6508,14 @@
        self.ipyHorseTrainLen = len(self.ipyHorseTrainCache)
        self.ipyHorseSkinPlusCache = self.__LoadFileData("HorseSkinPlus", IPY_HorseSkinPlus)
        self.ipyHorseSkinPlusLen = len(self.ipyHorseSkinPlusCache)
        self.ipyHorseCache = self.__LoadFileData("Horse", IPY_Horse)
        self.ipyHorseLen = len(self.ipyHorseCache)
        self.ipyGubaoCache = self.__LoadFileData("Gubao", IPY_Gubao)
        self.ipyGubaoLen = len(self.ipyGubaoCache)
        self.ipyGubaoStarCache = self.__LoadFileData("GubaoStar", IPY_GubaoStar)
        self.ipyGubaoStarLen = len(self.ipyGubaoStarCache)
        self.ipyGubaoEffAttrCache = self.__LoadFileData("GubaoEffAttr", IPY_GubaoEffAttr)
        self.ipyGubaoEffAttrLen = len(self.ipyGubaoEffAttrCache)
        self.ipyGubaoLVCache = self.__LoadFileData("GubaoLV", IPY_GubaoLV)
        self.ipyGubaoLVLen = len(self.ipyGubaoLVCache)
        self.ipyShentongCache = self.__LoadFileData("Shentong", IPY_Shentong)
@@ -7049,10 +7100,14 @@
    def GetHorseTrainByIndex(self, index): return self.ipyHorseTrainCache[index]
    def GetHorseSkinPlusCount(self): return self.ipyHorseSkinPlusLen
    def GetHorseSkinPlusByIndex(self, index): return self.ipyHorseSkinPlusCache[index]
    def GetHorseCount(self): return self.ipyHorseLen
    def GetHorseByIndex(self, index): return self.ipyHorseCache[index]
    def GetGubaoCount(self): return self.ipyGubaoLen
    def GetGubaoByIndex(self, index): return self.ipyGubaoCache[index]
    def GetGubaoStarCount(self): return self.ipyGubaoStarLen
    def GetGubaoStarByIndex(self, index): return self.ipyGubaoStarCache[index]
    def GetGubaoEffAttrCount(self): return self.ipyGubaoEffAttrLen
    def GetGubaoEffAttrByIndex(self, index): return self.ipyGubaoEffAttrCache[index]
    def GetGubaoLVCount(self): return self.ipyGubaoLVLen
    def GetGubaoLVByIndex(self, index): return self.ipyGubaoLVCache[index]
    def GetShentongCount(self): return self.ipyShentongLen
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerGubao.py
@@ -1,238 +1,382 @@
#!/usr/bin/python
# -*- coding: GBK -*-
#-------------------------------------------------------------------------------
#
##@package Player.PlayerGubao
#
# @todo:古宝系统
# @author hxp
# @date 2023-01-05
# @version 1.0
#
# è¯¦ç»†æè¿°: å¤å®ç³»ç»Ÿ
#
#-------------------------------------------------------------------------------
#"""Version = 2023-01-05 15:30"""
#-------------------------------------------------------------------------------
import GameWorld
import ItemCommon
import PlayerControl
import IpyGameDataPY
import ChPyNetSendPack
import NetPackCommon
import IPY_GameWorld
import ChConfig
def GetGubaoLVInfo(curPlayer, gubaoID):
    lvInfo = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_GubaoLVInfo % gubaoID)
    lv = lvInfo / 100
    star = lvInfo % 100
    return lv, star
def SetGubaoLVInfo(curPlayer, gubaoID, lv, star):
    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_GubaoLVInfo % gubaoID, lv * 100 + star)
    return
def OnPlayerLogin(curPlayer):
    Sync_GubaoInfo(curPlayer)
    return
#// B2 16 å¤å®æ¿€æ´» #tagCMGubaoActivate
#
#struct    tagCMGubaoActivate
#{
#    tagHead         Head;
#    WORD        GubaoID;
#};
def OnGubaoActivate(index, curPackData, tick):
    curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
    playerID = curPlayer.GetPlayerID()
    gubaoID = curPackData.GubaoID
    ipyData = IpyGameDataPY.GetIpyGameData("Gubao", gubaoID)
    if not ipyData:
        return
    needItemID = ipyData.GetUnlockItemID()
    needItemCnt = ipyData.GetUnlockItemCnt()
    if not needItemID or not needItemCnt:
        return
    lv, star = GetGubaoLVInfo(curPlayer, gubaoID)
    if lv or star:
        GameWorld.DebugLog("古宝已经激活过! gubaoID=%s" % gubaoID, playerID)
        return
    itemPack = curPlayer.GetItemManager().GetPack(IPY_GameWorld.rptItem)
    hasEnough, itemList = ItemCommon.GetItem_FromPack_ByID(needItemID, itemPack, needItemCnt)
    if not hasEnough:
        GameWorld.DebugLog("激活古宝道具不足! needItemID=%s,needItemCnt=%s" % (needItemID, needItemCnt), playerID)
        return
    ItemCommon.ReduceItem(curPlayer, itemPack, itemList, needItemCnt, False, "Gubao")
    lv, star = 1, 1
    SetGubaoLVInfo(curPlayer, gubaoID, lv, star)
    GameWorld.Log("古宝激活成功! gubaoID=%s" % gubaoID, playerID)
    RefreshGubaoAttr(curPlayer)
    Sync_GubaoInfo(curPlayer, [gubaoID])
    return
#// B2 17 å¤å®å‡æ˜Ÿ #tagCMGubaoStarUp
#
#struct    tagCMGubaoStarUp
#{
#    tagHead         Head;
#    WORD        GubaoID;
#};
def OnGubaoStarUp(index, curPackData, tick):
    curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
    playerID = curPlayer.GetPlayerID()
    gubaoID = curPackData.GubaoID
    lv, star = GetGubaoLVInfo(curPlayer, gubaoID)
    if not star:
        GameWorld.DebugLog("古宝未激活,无法升星! gubaoID=%s" % gubaoID, playerID)
        return
    if not IpyGameDataPY.GetIpyGameDataNotLog("GubaoStar", gubaoID, star + 1):
        GameWorld.DebugLog("古宝已满星! gubaoID=%s,star=%s" % (gubaoID, star), playerID)
        return
    ipyData = IpyGameDataPY.GetIpyGameData("GubaoStar", gubaoID, star)
    if not ipyData:
        return
    needItemList = ipyData.GetStarUPNeedItemInfo()
    if not needItemList:
        return
    itemPack = curPlayer.GetItemManager().GetPack(IPY_GameWorld.rptItem)
    lackItemDict, delInfoDict = ItemCommon.GetCostItemIndexList(needItemList, itemPack)
    if lackItemDict:
        GameWorld.DebugLog("古宝升星所需物品不足! star=%s,needItemList=%s,lackItemDict=%s" % (star, needItemList, lackItemDict), playerID)
        return
    #扣消耗
    ItemCommon.DelCostItem(curPlayer, itemPack, delInfoDict, "Gubao")
    updStar = star + 1
    SetGubaoLVInfo(curPlayer, gubaoID, lv, updStar)
    GameWorld.Log("古宝升星: gubaoID=%s,updStar=%s" % (gubaoID, updStar), playerID)
    RefreshGubaoAttr(curPlayer)
    Sync_GubaoInfo(curPlayer, [gubaoID])
    return
#// B2 18 å¤å®å‡çº§ #tagCMGubaoLVUp
#
#struct    tagCMGubaoLVUp
#{
#    tagHead         Head;
#    WORD        GubaoID;
#};
def OnGubaoLVUp(index, curPackData, tick):
    curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
    playerID = curPlayer.GetPlayerID()
    gubaoID = curPackData.GubaoID
    lv, star = GetGubaoLVInfo(curPlayer, gubaoID)
    if not star:
        GameWorld.DebugLog("古宝未激活,无法升级! gubaoID=%s" % gubaoID, playerID)
        return
    ipyData = IpyGameDataPY.GetIpyGameData("Gubao", gubaoID)
    if not ipyData:
        return
    quality = ipyData.GetGubaoQuality()
    if not IpyGameDataPY.GetIpyGameDataNotLog("GubaoLV", quality, lv + 1):
        GameWorld.DebugLog("古宝已满级! gubaoID=%s,quality=%s,lv=%s" % (gubaoID, quality, lv), playerID)
        return
    lvIpyData = IpyGameDataPY.GetIpyGameData("GubaoLV", quality, lv)
    if not lvIpyData:
        return
    needItemList = lvIpyData.GetLVUPNeedItemInfo()
    if not needItemList:
        return
    itemPack = curPlayer.GetItemManager().GetPack(IPY_GameWorld.rptItem)
    lackItemDict, delInfoDict = ItemCommon.GetCostItemIndexList(needItemList, itemPack)
    if lackItemDict:
        GameWorld.DebugLog("古宝升级所需物品不足! quality=%s,lv=%s,needItemList=%s,lackItemDict=%s"
                           % (quality, lv, needItemList, lackItemDict), playerID)
        return
    #扣消耗
    ItemCommon.DelCostItem(curPlayer, itemPack, delInfoDict, "Gubao")
    updLV = lv + 1
    SetGubaoLVInfo(curPlayer, gubaoID, updLV, star)
    GameWorld.Log("古宝升级: gubaoID=%s,quality=%s,updLV=%s" % (gubaoID, quality, updLV), playerID)
    RefreshGubaoAttr(curPlayer)
    Sync_GubaoInfo(curPlayer, [gubaoID])
    return
def RefreshGubaoAttr(curPlayer):
    CalcGubaoAttr(curPlayer)
    PlayerControl.PlayerControl(curPlayer).RefreshPlayerAttrState()
    return
def CalcGubaoAttr(curPlayer):
    allAttrList = [{} for _ in range(4)]
    ipyDataMgr = IpyGameDataPY.IPY_Data()
    for index in xrange(ipyDataMgr.GetGubaoCount()):
        ipyData = ipyDataMgr.GetGubaoByIndex(index)
        gubaoID = ipyData.GetGubaoID()
        lv, star = GetGubaoLVInfo(curPlayer, gubaoID)
        if not star:
            continue
        quality = ipyData.GetGubaoQuality()
        lvIpyData = IpyGameDataPY.GetIpyGameData("GubaoLV", quality, lv)
        if lvIpyData:
            lvAttrTypeList = lvIpyData.GetLVAttrTypeList()
            lvAttrValueList = lvIpyData.GetLVAttrValueList()
            for i, attrID in enumerate(lvAttrTypeList):
                attrValue = lvAttrValueList[i]
                PlayerControl.CalcAttrDict_Type(attrID, attrValue, allAttrList)
        starIpyData = IpyGameDataPY.GetIpyGameData("GubaoStar", gubaoID, star)
        if starIpyData:
            starAttrTypeList = starIpyData.GetStarAttrTypeList()
            starAttrValueList = starIpyData.GetStarAttrValueList()
            for i, attrID in enumerate(starAttrTypeList):
                attrValue = starAttrValueList[i]
                PlayerControl.CalcAttrDict_Type(attrID, attrValue, allAttrList)
    # ä¿å­˜è®¡ç®—值
    PlayerControl.SetCalcAttrListValue(curPlayer, ChConfig.Def_CalcAttrFunc_Gubao, allAttrList)
    return
def Sync_GubaoInfo(curPlayer, gubaoIDList=None):
    if gubaoIDList == None:
        syncIDList = []
        ipyDataMgr = IpyGameDataPY.IPY_Data()
        for index in range(ipyDataMgr.GetGubaoCount()):
            ipyData = ipyDataMgr.GetGubaoByIndex(index)
            syncIDList.append(ipyData.GetGubaoID())
    else:
        syncIDList = gubaoIDList
    gubaoInfoList = []
    for gubaoID in syncIDList:
        lv, star = GetGubaoLVInfo(curPlayer, gubaoID)
        if not lv and not star and gubaoIDList == None:
            # æ²¡æœ‰æŒ‡å®šæ—¶åªåŒæ­¥æ¿€æ´»çš„
            continue
        gubao = ChPyNetSendPack.tagMCGubao()
        gubao.GubaoID = gubaoID
        gubao.GubaoLV = lv
        gubao.GubaoStar = star
        gubaoInfoList.append(gubao)
    if not gubaoInfoList:
        return
    clientPack = ChPyNetSendPack.tagMCGubaoInfo()
    clientPack.GubaoInfoList = gubaoInfoList
    clientPack.Count = len(clientPack.GubaoInfoList)
    NetPackCommon.SendFakePack(curPlayer, clientPack)
    return
#!/usr/bin/python
# -*- coding: GBK -*-
#-------------------------------------------------------------------------------
#
##@package Player.PlayerGubao
#
# @todo:古宝系统
# @author hxp
# @date 2023-01-05
# @version 1.0
#
# è¯¦ç»†æè¿°: å¤å®ç³»ç»Ÿ
#
#-------------------------------------------------------------------------------
#"""Version = 2023-01-05 15:30"""
#-------------------------------------------------------------------------------
import GameWorld
import ItemCommon
import PlayerControl
import IpyGameDataPY
import ChPyNetSendPack
import NetPackCommon
import IPY_GameWorld
import PlayerHorse
import PlayerDogz
import PlayerPet
import ChConfig
def GetGubaoLVInfo(curPlayer, gubaoID):
    lvInfo = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_GubaoLVInfo % gubaoID)
    lv = lvInfo / 100
    star = lvInfo % 100
    return lv, star
def SetGubaoLVInfo(curPlayer, gubaoID, lv, star):
    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_GubaoLVInfo % gubaoID, lv * 100 + star)
    return
def OnPlayerLogin(curPlayer):
    Sync_GubaoInfo(curPlayer)
    return
#// B2 16 å¤å®æ¿€æ´» #tagCMGubaoActivate
#
#struct    tagCMGubaoActivate
#{
#    tagHead         Head;
#    WORD        GubaoID;
#};
def OnGubaoActivate(index, curPackData, tick):
    curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
    playerID = curPlayer.GetPlayerID()
    gubaoID = curPackData.GubaoID
    ipyData = IpyGameDataPY.GetIpyGameData("Gubao", gubaoID)
    if not ipyData:
        return
    needItemID = ipyData.GetUnlockItemID()
    needItemCnt = ipyData.GetUnlockItemCnt()
    if not needItemID or not needItemCnt:
        return
    lv, star = GetGubaoLVInfo(curPlayer, gubaoID)
    if lv or star:
        GameWorld.DebugLog("古宝已经激活过! gubaoID=%s" % gubaoID, playerID)
        return
    itemPack = curPlayer.GetItemManager().GetPack(IPY_GameWorld.rptItem)
    hasEnough, itemList = ItemCommon.GetItem_FromPack_ByID(needItemID, itemPack, needItemCnt)
    if not hasEnough:
        GameWorld.DebugLog("激活古宝道具不足! needItemID=%s,needItemCnt=%s" % (needItemID, needItemCnt), playerID)
        return
    ItemCommon.ReduceItem(curPlayer, itemPack, itemList, needItemCnt, False, "Gubao")
    lv, star = 1, 1
    SetGubaoLVInfo(curPlayer, gubaoID, lv, star)
    GameWorld.Log("古宝激活成功! gubaoID=%s" % gubaoID, playerID)
    RefreshGubaoAttr(curPlayer)
    Sync_GubaoInfo(curPlayer, [gubaoID])
    return
#// B2 17 å¤å®å‡æ˜Ÿ #tagCMGubaoStarUp
#
#struct    tagCMGubaoStarUp
#{
#    tagHead         Head;
#    WORD        GubaoID;
#};
def OnGubaoStarUp(index, curPackData, tick):
    curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
    playerID = curPlayer.GetPlayerID()
    gubaoID = curPackData.GubaoID
    lv, star = GetGubaoLVInfo(curPlayer, gubaoID)
    if not star:
        GameWorld.DebugLog("古宝未激活,无法升星! gubaoID=%s" % gubaoID, playerID)
        return
    if not IpyGameDataPY.GetIpyGameDataNotLog("GubaoStar", gubaoID, star + 1):
        GameWorld.DebugLog("古宝已满星! gubaoID=%s,star=%s" % (gubaoID, star), playerID)
        return
    ipyData = IpyGameDataPY.GetIpyGameData("GubaoStar", gubaoID, star)
    if not ipyData:
        return
    needItemList = ipyData.GetStarUPNeedItemInfo()
    if not needItemList:
        return
    itemPack = curPlayer.GetItemManager().GetPack(IPY_GameWorld.rptItem)
    lackItemDict, delInfoDict = ItemCommon.GetCostItemIndexList(needItemList, itemPack)
    if lackItemDict:
        GameWorld.DebugLog("古宝升星所需物品不足! star=%s,needItemList=%s,lackItemDict=%s" % (star, needItemList, lackItemDict), playerID)
        return
    #扣消耗
    ItemCommon.DelCostItem(curPlayer, itemPack, delInfoDict, "Gubao")
    updStar = star + 1
    SetGubaoLVInfo(curPlayer, gubaoID, lv, updStar)
    GameWorld.Log("古宝升星: gubaoID=%s,updStar=%s" % (gubaoID, updStar), playerID)
    RefreshGubaoAttr(curPlayer)
    Sync_GubaoInfo(curPlayer, [gubaoID])
    return
#// B2 18 å¤å®å‡çº§ #tagCMGubaoLVUp
#
#struct    tagCMGubaoLVUp
#{
#    tagHead         Head;
#    WORD        GubaoID;
#};
def OnGubaoLVUp(index, curPackData, tick):
    curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
    playerID = curPlayer.GetPlayerID()
    gubaoID = curPackData.GubaoID
    lv, star = GetGubaoLVInfo(curPlayer, gubaoID)
    if not star:
        GameWorld.DebugLog("古宝未激活,无法升级! gubaoID=%s" % gubaoID, playerID)
        return
    ipyData = IpyGameDataPY.GetIpyGameData("Gubao", gubaoID)
    if not ipyData:
        return
    quality = ipyData.GetGubaoQuality()
    if not IpyGameDataPY.GetIpyGameDataNotLog("GubaoLV", quality, lv + 1):
        GameWorld.DebugLog("古宝已满级! gubaoID=%s,quality=%s,lv=%s" % (gubaoID, quality, lv), playerID)
        return
    lvIpyData = IpyGameDataPY.GetIpyGameData("GubaoLV", quality, lv)
    if not lvIpyData:
        return
    needItemList = lvIpyData.GetLVUPNeedItemInfo()
    if not needItemList:
        return
    itemPack = curPlayer.GetItemManager().GetPack(IPY_GameWorld.rptItem)
    lackItemDict, delInfoDict = ItemCommon.GetCostItemIndexList(needItemList, itemPack)
    if lackItemDict:
        GameWorld.DebugLog("古宝升级所需物品不足! quality=%s,lv=%s,needItemList=%s,lackItemDict=%s"
                           % (quality, lv, needItemList, lackItemDict), playerID)
        return
    #扣消耗
    ItemCommon.DelCostItem(curPlayer, itemPack, delInfoDict, "Gubao")
    updLV = lv + 1
    SetGubaoLVInfo(curPlayer, gubaoID, updLV, star)
    GameWorld.Log("古宝升级: gubaoID=%s,quality=%s,updLV=%s" % (gubaoID, quality, updLV), playerID)
    RefreshGubaoAttr(curPlayer)
    Sync_GubaoInfo(curPlayer, [gubaoID])
    return
def RefreshGubaoAttr(curPlayer):
    #CalcGubaoAttr(curPlayer)
    PlayerControl.PlayerControl(curPlayer).RefreshPlayerAttrState()
    return
def CalcGubaoAttr(curPlayer):
    allAttrList = [{} for _ in range(4)]
    ipyDataMgr = IpyGameDataPY.IPY_Data()
    for index in xrange(ipyDataMgr.GetGubaoCount()):
        ipyData = ipyDataMgr.GetGubaoByIndex(index)
        gubaoID = ipyData.GetGubaoID()
        lv, star = GetGubaoLVInfo(curPlayer, gubaoID)
        if not star:
            continue
        quality = ipyData.GetGubaoQuality()
        lvIpyData = IpyGameDataPY.GetIpyGameData("GubaoLV", quality, lv)
        if lvIpyData:
            lvAttrTypeList = lvIpyData.GetLVAttrTypeList()
            lvAttrValueList = lvIpyData.GetLVAttrValueList()
            for i, attrID in enumerate(lvAttrTypeList):
                attrValue = lvAttrValueList[i]
                PlayerControl.CalcAttrDict_Type(attrID, attrValue, allAttrList)
        starIpyData = IpyGameDataPY.GetIpyGameData("GubaoStar", gubaoID, star)
        if starIpyData:
            starEffIDList = starIpyData.GetStarEffIDList()
            effAttrInfo = {}
            #GameWorld.DebugLog("GubaoStar属性: gubaoID=%s,star=%s,starEffIDList=%s" % (gubaoID, star, starEffIDList))
            for effID in starEffIDList:
                __calcStarEffAttrByID(curPlayer, effID, effAttrInfo)
                #GameWorld.DebugLog("    effID=%s,effAttrInfo=%s" % (effID, effAttrInfo))
            for attrID, attrValue in effAttrInfo.items():
                PlayerControl.CalcAttrDict_Type(attrID, attrValue, allAttrList)
    # ä¿å­˜è®¡ç®—值
    #GameWorld.DebugLog("古宝属性: %s" % allAttrList)
    PlayerControl.SetCalcAttrListValue(curPlayer, ChConfig.Def_CalcAttrFunc_Gubao, allAttrList)
    return
def __calcStarEffAttrByID(curPlayer, effID, effAttrInfo):
    ''' è®¡ç®—古宝特殊效果ID对应提升属性
    '''
    ipyData = IpyGameDataPY.GetIpyGameData("GubaoEffAttr", effID)
    if not ipyData:
        return
    effType = ipyData.GetGubaoEffType()
    effCond = ipyData.GetEffCond()
    attrID = ipyData.GetEffAttrID()
    effAttrValue = ipyData.GetEffAttrValue()
    if effAttrValue <= 0:
        return
    #效果类型    ç±»åž‹è¯´æ˜Ž                                                    æ¡ä»¶
    # 10    x品质灵宠攻击属性提升x%      x品质
    if effType == 10:
        customAttrDictPet = PlayerControl.GetCalcAttrListValue(curPlayer, ChConfig.Def_CalcAttrFunc_Pet)[2]
        petQualityAttrInfo = customAttrDictPet.get("petQualityAttrInfo", {})
        quality = effCond
        #GameWorld.DebugLog("    effID=%s,effType=%s,quality=%s,petQualityAttrInfo=%s" % (effID, effType, quality, petQualityAttrInfo))
        if quality not in petQualityAttrInfo:
            return
        __addStarEffFuncAttr(ipyData, effAttrInfo, petQualityAttrInfo[quality], effAttrValue)
    # 11    çµå® æ€»ç­‰çº§æ¯x级+xx属性                   x级
    elif effType == 11:
        totalPetLV = PlayerPet.GetTotalPetLV(curPlayer)
        addAttrValue = int(totalPetLV / effCond * effAttrValue)
        #GameWorld.DebugLog("    effID=%s,effType=%s,effCond=%s,totalPetLV=%s,attrID=%s,addAttrValue=%s" % (effID, effType, effCond, totalPetLV, attrID, addAttrValue))
        if attrID > 0 and addAttrValue > 0:
            effAttrInfo[attrID] = effAttrInfo.get(attrID, 0) + addAttrValue
    # 12    çµå® æ¯æ¿€æ´»x只+xx属性                        x只
    elif effType == 12:
        totalPetCount = PlayerPet.GetTotalPetCount(curPlayer)
        addAttrValue = int(totalPetCount / effCond * effAttrValue)
        #GameWorld.DebugLog("    effID=%s,effType=%s,effCond=%s,totalPetCount=%s,attrID=%s,addAttrValue=%s" % (effID, effType, effCond, totalPetCount, attrID, addAttrValue))
        if attrID > 0 and addAttrValue > 0:
            effAttrInfo[attrID] = effAttrInfo.get(attrID, 0) + addAttrValue
    # 13    x品质坐骑幻化属性提升x%      x品质
    elif effType == 13:
        customAttrDictSkin = PlayerControl.GetCalcAttrListValue(curPlayer, ChConfig.Def_CalcAttrFunc_HorseSkin)[2]
        horseSkinQualityAttrInfo = customAttrDictSkin.get("horseSkinQualityAttrInfo", {})
        quality = effCond
        #GameWorld.DebugLog("    effID=%s,effType=%s,quality=%s,horseSkinQualityAttrInfo=%s" % (effID, effType, quality, horseSkinQualityAttrInfo))
        if quality not in horseSkinQualityAttrInfo:
            return
        __addStarEffFuncAttr(ipyData, effAttrInfo, horseSkinQualityAttrInfo[quality], effAttrValue)
    # 14    åéª‘幻化激活x只+xx属性                   x只
    elif effType == 14:
        horseSkinActCount = PlayerHorse.GetHorseSkinActCount(curPlayer)
        addAttrValue = int(horseSkinActCount / effCond * effAttrValue)
        #GameWorld.DebugLog("    effID=%s,effType=%s,effCond=%s,horseSkinActCount=%s,attrID=%s,addAttrValue=%s" % (effID, effType, effCond, horseSkinActCount, attrID, addAttrValue))
        if attrID > 0 and addAttrValue > 0:
            effAttrInfo[attrID] = effAttrInfo.get(attrID, 0) + addAttrValue
    # 15    æ¯åŸ¹å…»åéª‘x次+xx属性                        x次
    elif effType == 15:
        pass
    #16    x阶装备强化属性提升x%        x阶
    elif effType == 16:
        customAttrDictPlus = PlayerControl.GetCalcAttrListValue(curPlayer, ChConfig.Def_CalcAttrFunc_Plus)[2]
        classBaseAttrDictPlus = customAttrDictPlus.get("classBaseAttrDictPlus", {})
        classLV = effCond
        #GameWorld.DebugLog("    effID=%s,effType=%s,classLV=%s,classBaseAttrDictPlus=%s" % (effID, effType, classLV, classBaseAttrDictPlus))
        if classLV not in classBaseAttrDictPlus:
            return
        __addStarEffFuncAttr(ipyData, effAttrInfo, classBaseAttrDictPlus[classLV], effAttrValue)
    #17    x阶装备宝石属性提升x%        x阶
    elif effType == 17:
        customAttrDictStone = PlayerControl.GetCalcAttrListValue(curPlayer, ChConfig.Def_CalcAttrFunc_Stone)[2]
        classBaseAttrDictStone = customAttrDictStone.get("classBaseAttrDictStone", {})
        classLV = effCond
        #GameWorld.DebugLog("    effID=%s,effType=%s,classLV=%s,classBaseAttrDictStone=%s" % (effID, effType, classLV, classBaseAttrDictStone))
        if classLV not in classBaseAttrDictStone:
            return
        __addStarEffFuncAttr(ipyData, effAttrInfo, classBaseAttrDictStone[classLV], effAttrValue)
    #18    x阶装备升星属性提升x%        x阶
    elif effType == 18:
        customAttrDictStar = PlayerControl.GetCalcAttrListValue(curPlayer, ChConfig.Def_CalcAttrFunc_Star)[2]
        classBaseAttrDictStar = customAttrDictStar.get("classBaseAttrDictStar", {})
        classLV = effCond
        #GameWorld.DebugLog("    effID=%s,effType=%s,classLV=%s,classBaseAttrDictStar=%s" % (effID, effType, classLV, classBaseAttrDictStar))
        if classLV not in classBaseAttrDictStar:
            return
        __addStarEffFuncAttr(ipyData, effAttrInfo, classBaseAttrDictStar[classLV], effAttrValue)
    #19    x阶装备洗炼属性提升x%        x阶
    elif effType == 19:
        customAttrDictWash = PlayerControl.GetCalcAttrListValue(curPlayer, ChConfig.Def_CalcAttrFunc_Wash)[2]
        classBaseAttrDictWash = customAttrDictWash.get("classBaseAttrDictWash", {})
        classLV = effCond
        #GameWorld.DebugLog("    effID=%s,effType=%s,classLV=%s,classBaseAttrDictWash=%s" % (effID, effType, classLV, classBaseAttrDictWash))
        if classLV not in classBaseAttrDictWash:
            return
        __addStarEffFuncAttr(ipyData, effAttrInfo, classBaseAttrDictWash[classLV], effAttrValue)
    #20    x阶装备附魔属性提升x%        x阶
    elif effType == 20:
        customAttrDictEnchant = PlayerControl.GetCalcAttrListValue(curPlayer, ChConfig.Def_CalcAttrFunc_Enchant)[2]
        classBaseAttrDictEnchant = customAttrDictEnchant.get("classBaseAttrDictEnchant", {})
        classLV = effCond
        #GameWorld.DebugLog("    effID=%s,effType=%s,classLV=%s,classBaseAttrDictEnchant=%s" % (effID, effType, classLV, classBaseAttrDictEnchant))
        if classLV not in classBaseAttrDictEnchant:
            return
        __addStarEffFuncAttr(ipyData, effAttrInfo, classBaseAttrDictEnchant[classLV], effAttrValue)
    #21    å‡ºæˆ˜ç¥žå…½è£…备强化每x级+xx属性    x级
    elif effType == 21:
        fightDogzTotalPlusLv = PlayerDogz.GetFightDogzTotalPlusLv(curPlayer)
        addAttrValue = int(fightDogzTotalPlusLv / effCond * effAttrValue)
        #GameWorld.DebugLog("    effID=%s,effType=%s,effCond=%s,fightDogzTotalPlusLv=%s,attrID=%s,addAttrValue=%s" % (effID, effType, effCond, fightDogzTotalPlusLv, attrID, addAttrValue))
        if attrID > 0 and addAttrValue > 0:
            effAttrInfo[attrID] = effAttrInfo.get(attrID, 0) + addAttrValue
    return
def __addStarEffFuncAttr(ipyData, effAttrInfo, funcAttrInfo, effAttrValue):
    if not funcAttrInfo or effAttrValue <= 0:
        return
    isPer = ipyData.GetIsPer()
    effAttrIDList = ipyData.GetEffFuncAttrIDList() # æå‡æŒ‡å®šåŠŸèƒ½å±žæ€§ID列表
    for attrID, attrValue in funcAttrInfo.items():
        if effAttrIDList and attrID not in effAttrIDList:
            continue
        if isPer:
            addAttrValue = int(attrValue * effAttrValue / 100.0)
        else:
            addAttrValue = effAttrValue
        if attrID > 0 and addAttrValue > 0:
            effAttrInfo[attrID] = effAttrInfo.get(attrID, 0) + addAttrValue
    return
def Sync_GubaoInfo(curPlayer, gubaoIDList=None):
    if gubaoIDList == None:
        syncIDList = []
        ipyDataMgr = IpyGameDataPY.IPY_Data()
        for index in range(ipyDataMgr.GetGubaoCount()):
            ipyData = ipyDataMgr.GetGubaoByIndex(index)
            syncIDList.append(ipyData.GetGubaoID())
    else:
        syncIDList = gubaoIDList
    gubaoInfoList = []
    for gubaoID in syncIDList:
        lv, star = GetGubaoLVInfo(curPlayer, gubaoID)
        if not lv and not star and gubaoIDList == None:
            # æ²¡æœ‰æŒ‡å®šæ—¶åªåŒæ­¥æ¿€æ´»çš„
            continue
        gubao = ChPyNetSendPack.tagMCGubao()
        gubao.GubaoID = gubaoID
        gubao.GubaoLV = lv
        gubao.GubaoStar = star
        gubaoInfoList.append(gubao)
    if not gubaoInfoList:
        return
    clientPack = ChPyNetSendPack.tagMCGubaoInfo()
    clientPack.GubaoInfoList = gubaoInfoList
    clientPack.Count = len(clientPack.GubaoInfoList)
    NetPackCommon.SendFakePack(curPlayer, clientPack)
    return
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerHorse.py
@@ -404,6 +404,8 @@
    allAttrListSkin = [{} for _ in range(4)]
    allAttrListTrain = [{} for _ in range(4)]
    
    customAttrDictSkin = {}
    horseSpeed = 0 # åéª‘功能增加的速度值,骑乘时才有效果
    horseLV = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_HorserLV)
    # ç­‰é˜¶åŸ¹å…»å±žæ€§
@@ -436,6 +438,7 @@
        
    # å¹»åŒ–属性
    initFPAdd = 0 #初始战力
    horseSkinQualityAttrInfo = {}
    for index in xrange(ipyDataMgr.GetHorseSkinPlusCount()):
        skinPlusIpyData = ipyDataMgr.GetHorseSkinPlusByIndex(index)
        if not CheckHorseSkinState(curPlayer, skinPlusIpyData):
@@ -459,6 +462,17 @@
            for attrID, attrValue in skinIpyData.GetAttrInfo().items():
                PlayerControl.CalcAttrDict_Type(attrID, attrValue, allAttrListSkin)
                
        hIpyData = IpyGameDataPY.GetIpyGameData("Horse", horseID)
        if hIpyData:
            quality = hIpyData.GetQuality()
            if quality not in horseSkinQualityAttrInfo:
                horseSkinQualityAttrInfo[quality] = {}
            qualityAttrDict = horseSkinQualityAttrInfo[quality]
            for i, attrID in enumerate(attrTypeList):
                attrValue = attrValueList[i]
                qualityAttrDict[attrID] = qualityAttrDict.get(attrID, 0) + attrValue
    customAttrDictSkin["horseSkinQualityAttrInfo"] = horseSkinQualityAttrInfo
    # æ–°åŸ¹å…»å±žæ€§
    for index in xrange(ipyDataMgr.GetHorseTrainCount()):
        trainIpyData = ipyDataMgr.GetHorseTrainByIndex(index)
@@ -507,10 +521,20 @@
    # ä¿å­˜è®¡ç®—值
    PlayerControl.SetCalcAttrListValue(curPlayer, ChConfig.Def_CalcAttrFunc_Horse, allAttrList)
    PlayerControl.SetCalcAttrListValue(curPlayer, ChConfig.Def_CalcAttrFunc_HorseSoul, allAttrListHorseSoul)
    PlayerControl.SetCalcAttrListValue(curPlayer, ChConfig.Def_CalcAttrFunc_HorseSkin, allAttrListSkin)
    PlayerControl.SetCalcAttrListValue(curPlayer, ChConfig.Def_CalcAttrFunc_HorseSkin, allAttrListSkin, customAttrDict=customAttrDictSkin)
    PlayerControl.SetCalcAttrListValue(curPlayer, ChConfig.Def_CalcAttrFunc_HorseTarin, allAttrListTrain)
    return
def GetHorseSkinActCount(curPlayer):
    horseSkinActCount = 0
    ipyDataMgr = IpyGameDataPY.IPY_Data()
    for index in xrange(ipyDataMgr.GetHorseSkinPlusCount()):
        skinPlusIpyData = ipyDataMgr.GetHorseSkinPlusByIndex(index)
        if not CheckHorseSkinState(curPlayer, skinPlusIpyData):
            continue
        horseSkinActCount += 1
    return horseSkinActCount
#// A5 27 åéª‘提升 #tagCMHorseUp
#
#struct    tagCMHorseUp
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerPet.py
@@ -787,6 +787,21 @@
        totalPetLV += classLV
    return totalPetLV
def GetTotalPetCount(curPlayer):
    totalPetCount = 0
    petPackIndex = ShareDefine.rptPet
    petPack = curPlayer.GetItemManager().GetPack(petPackIndex)
    for i in range(petPack.GetCount()):
        petItem = petPack.GetAt(i)
        if petItem.IsEmpty():
            continue
        petItemNPCID = petItem.GetUserAttr(ShareDefine.Def_IudetPet_NPCID)
        petIpyData = GetPetIpydata(petItemNPCID)
        if not petIpyData:
            continue
        totalPetCount += 1
    return totalPetCount
def IsPetMaxLV(curPlayer, petNPCID):
    petItem = GetPetDataItemByNPCID(curPlayer, petNPCID)
    if not petItem:
@@ -858,7 +873,9 @@
    skillAttrList = [{} for _ in range(4)]
    allAttrListPetSkin = [{} for _ in range(4)]
    allAttrListTrain = [{} for _ in range(4)]
    totalMinAtk, totalMaxAtk = GetPetAtkValue(curPlayer)
    customAttrDictPet = {}
    totalMinAtk, totalMaxAtk, qualityAttrInfo = GetPetAtkValue(curPlayer)
    customAttrDictPet["petQualityAttrInfo"] = qualityAttrInfo
    PlayerControl.CalcAttrDict_Type(ShareDefine.Def_Effect_PetMinAtk, totalMinAtk, allAttrListPet)
    PlayerControl.CalcAttrDict_Type(ShareDefine.Def_Effect_PetMaxAtk, totalMaxAtk, allAttrListPet)
    totalSignNum = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_TotalSignNum) # æ€»ç­¾åˆ°å¤©æ•°
@@ -923,7 +940,7 @@
                
    PlayerControl.SetCalcAttrListValue(curPlayer, ChConfig.Def_CalcAttrFunc_PetTarin, allAttrListTrain)
    
    PlayerControl.SetCalcAttrListValue(curPlayer, ChConfig.Def_CalcAttrFunc_Pet, allAttrListPet)
    PlayerControl.SetCalcAttrListValue(curPlayer, ChConfig.Def_CalcAttrFunc_Pet, allAttrListPet, customAttrDict=customAttrDictPet)
    PlayerControl.SetCalcAttrListValue(curPlayer, ChConfig.Def_CalcAttrFunc_PetSoul, allAttrListPetSoul)
    PlayerControl.SetCalcAttrListValue(curPlayer, ChConfig.Def_CalcAttrFunc_PetSign, allAttrListPetSign)
    
@@ -962,9 +979,10 @@
## èŽ·å–çµå…½å‡ºæˆ˜æ—¶çš„æ”»å‡»åŠ›
def GetPetAtkValue(curPlayer):
    qualityAttrInfo = {}
    if not GameFuncComm.GetFuncCanUse(curPlayer, ShareDefine.GameFuncID_Pet):
        #GameWorld.DebugLog(' å® ç‰©åŠŸèƒ½æœªå¼€å¯')
        return 0, 0
        return 0, 0, qualityAttrInfo
    
    classAddAtk = 0
    petPackIndex = ShareDefine.rptPet
@@ -976,10 +994,20 @@
        petItemNPCID = packItem.GetUserAttr(ShareDefine.Def_IudetPet_NPCID)
        classlv = packItem.GetUserAttr(ShareDefine.Def_IudetPet_ClassLV)
        classIpyData = IpyGameDataPY.GetIpyGameData("PetClassCost", petItemNPCID, classlv + 1)
        classAddAtk += (classIpyData.GetAtkAdd() if classIpyData else 0)
        atkAdd = classIpyData.GetAtkAdd() if classIpyData else 0
        classAddAtk += atkAdd
        petIpyData = GetPetIpydata(petItemNPCID)
        if petIpyData:
            quality = petIpyData.GetQuality()
            if quality not in qualityAttrInfo:
                qualityAttrInfo[quality] = {}
            qualityAttrDict = qualityAttrInfo[quality]
            qualityAttrDict[ShareDefine.Def_Effect_PetAtk] = qualityAttrDict.get(ShareDefine.Def_Effect_PetAtk, 0) + atkAdd
    totalMinAtk = classAddAtk
    totalMaxAtk = classAddAtk
    return totalMinAtk, totalMaxAtk
    return totalMinAtk, totalMaxAtk, qualityAttrInfo
def OnPlayerPetLogin(curPlayer):
    ## ç™»å½•处理