距离上次更新本文已经过去了 405 天,文章部分内容可能已经过时,请注意甄别

在开发阿狸的过程中,遇到了一个全局变量写错而导致的 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 点的皮肤提醒功能不能用,之前因为重启已经连续几天这样了(指普通用户因为没有登录信息,无法使用皮肤提醒功能)对普通用户也太不公平了!

感谢你看到了最后!!