ycsm_1 测试引起的反思

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/xuruilin1993/article/details/81545558

1、lb收到外网有玩家击杀了帮会boss后,没有发放奖励的BUG。随后进一步查询,发现计算怪物掉落的接口RETURN_FALSE了。
伪代码如下:
1....    void ApiTranslateDropBag(UINT bagId,std::vector<DropItem>& dropItems)
2....    {
3....        CCopyDropSystem* pdrop = ApiGetCopySysytem();
4....        if(!drop){RETURN_FALSE;}
5....        pdrop->translateDropBag(bagId,dropItems);
6....    }
发现每次计算掉落的时候,都在第4行报错了。
很是奇怪,如果game正常初始化的话,那么 ApiGetCopySysytem()一定会返回掉落系统的指针的。
后面继续追踪,发现ApiGetCopySysytem()的代码如下:
1....static CCopyDropSystem* ApiGetCopySysytem()
2....{
3....    static CCopyDropSystem* psys = (CCopyDropSystem*)WorldFindSystem("copydrop");
4....    if(!psys){
5....        RETURN_NULL;
6....    }
7....    return psys;
8....}
第5行,只在game初始化的时候,报错过1次。随后虽然每次第4行都报错,但是第5行都不会报错。
原因是static CCopyDropSystem* psys这个指针被初始化了一次以后,再调用到ApiGetCopySysytem()接口,
就不会再执行(CCopyDropSystem*)WorldFindSystem("copydrop")这个函数了。
而是直接返回已经初始化好的psys。
后面继续追踪,第一次初始化失败是因为在定时器里,manager会向game同步【保底出金】信息。
而此时game的系统还没被初始化好,WorldFindSystem("copydrop")返回的是nullptr,并且赋值给了static变量:psys,
导致随后game启动完毕,杀怪走到掉落接口,都不能正常取到掉落系统指针。

2、一个测试时,引起的反思。在九州密藏活动完成后,提交奖励的接口中。
1    extern bool ApiKyushuPutItem(CPlayer& player,bool isloss)
2    {
3        .
4        .
5        CItemBag* itembag = PlayerGetItemBag(player);
6        if(!itembag){RETURN_FALSE;}
7        BagSubItem(itembag,tid);
8        if(!CallExpr(_kyushu_reward,&player,total_score)){RETURN_FALSE;}
9        .
10        .
11        return true;
12    }
这里我原本漏写了一行代码: SynItemGemDiff(player),同步背包中最新的信息到客户端。
但是第一遍测试的时候,没有问题。因为策划在奖励表达式_kyushu_reward中配置了道具奖励。
通过表达式PlayerAddItem()来发放奖励,这个表达式中有同步信息,所以测试没问题。
extern bool PlayerAddItem(CPlayer* player,UINT itemId,UINT count)
{
    if(!player){RETURN_FALSE;}
    CPlayerAddItem(*player,itemId,count);
    SynItemGemDiff(*player);
}
第二次测试的时候,策划关闭了道具奖励的投放,只奖励了经验和灵力。所以 ApiKyushuPutItem接口就有点问题了,
因为没有同步服务器最新的背包数据到客户端。
那么问题来了。
如果,我在第9行,加上了SynItemGemDiff(*player),那么自然没问题了。
但是如果策划在表格里又配置了道具奖励,那么道具奖励表达式PlayerAddItem会同步1次,
我的提交奖励接口ApiKyushuPutItem会同步1次。
那么就有点浪费效率了。
如果表格奖励多份道具,配置了多个表达式,那么同步次数线性增长;相当于O(n)的效率;
我看了一下项目中的实现,居然是用的及时同步。也就是确确实实同步了2次。— —!
忽然想起来,以前的实现是先打个【需要同步】的标记,然后在定时器中定时遍历标记,
如果是【需要同步】那么发包同步给客户端,然后将标记置为【已同步】。
那么如果同步间隔是1s,刚刚的两次SynItemGemDiff(*player),就可能只发了一次消息同步包到客户端。
但是不记得是不是遇到了什么坑,才改到了这个样子。(貌似还是jinhai让liyong修改的)
后来有一次,yj也问我,这里的同步是否不需要及时同步,可以改为在tick中。
我心里是赞同不需要及时同步的,但是项目已经稳定上线好久,我不敢随意去填坑(说不定就是挖坑),撰此文记之。


 

猜你喜欢

转载自blog.csdn.net/xuruilin1993/article/details/81545558