在开发阿狸的过程中,遇到了一个全局变量写错而导致的bug……

问题引出

如果你最近几天有用过shop查询功能,可能会遇到下面的情况

img

上图为普通用户的商店用了vip用户16-9的图片;

下图为vip用户的商店用了普通用户1-1的图片

img

img

简单说来,vip的商店返回值是16-9的图片,而普通用户的商店是1-1的图片。

在上面的三个每日商店返回值中,就出现了vip用户的商店用了1-1的图,或者普通用户的商店用了16-9的图。

这个bug昨天(22.09.12)我就发现了,是一位vip用户的商店返回值里面用了普通用户的图片。而我昨天定位bug的时候,测试bot保存了画出来的4个小图,没有问题;然后再使用/shop命令,发现测试bot没有出现这个问题。于是我就把阿狸重启了一下,问题也消失了!于是就秉持“遇事不决,重启解决”的错误心态,没有打理这个问题。

而今天(22.09.13)早上,这个问题又出现了,这次是普通用户的商店返回值里面用了vip的图片。于是我又把bot重启了一下,果然,问题又消失了。哈哈!解决了——个锤子!


代码逻辑介绍

这里先说明一下,阿狸的商店返回值逻辑如下:

  • 通过api获取玩家商店,api返回的是4个武器的uuid
  • 遍历所有武器,找到这4个武器名字+皮肤图片+价格+皮肤等级,将它们组合起来,画出一个小图
  • 再把画出来的4个小图,通过坐标映射,全部粘贴到最终的大图上面。也就是大家获取道的返回结果

今天晚上,我自己获取商店的时候又双遇到了这个bug,于是再次认真看了一边代码。这下可算是发现这个问题的位置了~且听我细细道来(看下面的图片)

img

weapon_icon_temp(就叫它抽屉吧)是一个全局变量,里面存放了画好的单个武器的图片(武器名字+武器图片+价格+皮肤等级)下图是画好的单图示例

img

除了抽屉(weapon_icon_temp),阿狸还会把这个图片存放到本地路径里面(仓库)这样在阿狸重启之后(抽屉会被清空)本地路径(仓库)里面的图片还在,可以从仓库里面拿出来,也节省了画图的时间。

逻辑大概是这样的

  • 用户A获取商店,阿狸画出了4个皮肤的图片,并把它们存了起来(抽屉和仓库都存了);
  • 用户B获取商店,阿狸发现这两个用户的商店皮肤有重合,这时候就没必要再画一张图了,于是阿狸就从抽屉里(weapon_icon_temp)拿出了之前给用户A画好的相同皮肤的图片,直接粘贴到用户B最后的大图上。

下图为普通用户的画图逻辑

img


现在,vip的商店图片是16-9,普通用户的商店图片是1-1。所以阿狸会单独处理两种用户,并画出不同的图片,存放在不同的本地路径(仓库)中。

普通用户存放在img_temp本地路径中,vip用户存放在img_temp_vip本地路径中

img

可是,本地路径(仓库)的位置变啦,但是全局变量(抽屉)用的还是同一个啊!

阿狸画图的时候,肯定是先从抽屉里面拿图片。因为抽屉顺手就能拿到,干嘛跑仓库里面去呢?(指全局变量访问比本地路径更快)

这就导致了如果某个皮肤A先被普通用户张三查询到,而vip用户李四在之后查询的时候,也获取到相同的皮肤A,那么阿狸就从抽屉里面掏出了一张应该给普通用户用的图片,贴在了vip用户李四的返回值上,于是李四就获取到了下面这一张图片

img

解决

解决办法很简单,把vip和普通用户的抽屉分开就行了

那为什么这个问题,重启阿狸就好了呢?

前面提到过,抽屉会在阿狸关机的时候清除(因为全局变量是写在内存里面的,会在使用完毕后释放,类似于你划掉手机的后台应用来释放手机的运存一样)

这样一来,抽屉里面没有之前画好的图片,那么阿狸就会去仓库里面(仓库是分开的)找出了正确的图片,测试就看不出来有bug了!(因为这个bug的触发必须要普通用户和vip用户使用阿狸查询商店,而他们同时刷出了一个皮肤。我的测试没有这种环境)

咳咳,说了这么多,不知道大家看明白了没有


结语

阿狸会在22.09.14的早8点后重启,以修复这个bug。为啥现在不弄呢?因为重启会把普通用户的登录信息清空。导致普通用户明天8点的皮肤提醒功能不能用,之前因为重启已经连续几天这样了(指普通用户因为没有登录信息,无法使用皮肤提醒功能)对普通用户也太不公平了!

感谢你看到了最后!!