我正在为在线动态游戏创建机器人。在这种情况下,动态意味着英雄可以在游戏中移动并且移动时背景也在变化。像monsters
这样的全局变量在移动时也会动态变化。
我的机器人正在使用puppeteer。因为我需要这个怪物对象,所以我具有每2-3秒从页面上下文中获取这些怪物的功能(随机进行反检测)。
此解决方案远非完美。两个主要缺点是:
要解决第一个问题,我可以执行一次杀死怪物后每次下载怪物的功能。另一方面,第二个缺点将更加强大,因为我将获得更多已经很慢的怪物。
第二个问题就是性能。您可能会问,我怎么知道性能不好?
当英雄移动时,它相对平稳,但是当下载怪物时,我看到微小的滞后,例如第二次英雄停顿的一部分。也许实际上是100毫秒的延迟,但是我可以用肉眼看到它,如果我能更频繁地表演怪物,这种延迟会变得更强(请注意-延迟不会更长,但会更频繁)。
从全局窗口下载对象很长。原因是游戏维护者开发了它,使得monsters
位于大对象npc
中,该大对象包含仪表板中的所有内容,甚至包含空元素,因此该npc
对象的总量介于100k-200k元素。为了获得最终的怪物数据,我正在做很多过滤器。
我将展示如何真正获得这些怪物。所以我执行了3个异步函数:
const allNpc = await getAllNpc(page);
let monsters = await filterMonsters(page, allNpc, monstersToHunt);
monsters.hunt = await deleteAvoidedMonsters(page, monsters.hunt, monstersToOmit);
第一个getAllNpc
仅获得整个npc对象(我上面提到的这个大对象)
return await page.evaluate(() => {
if(window.g) return g.npc;
});
第二个功能过滤实际的怪物和我想从NPC杀死的怪物:
return new Promise((resolve, reject) => {
const validNpc = allNpc.filter(el => !!el);
const allMonsters = validNpc.filter(e => e.lvl !== 0);
const names = new Set(monstersNames);
const huntMonsters = validNpc
.filter(it => names.has(it.nick))
.map(({ nick, x, y, grp, id }) => ({ nick, x, y, grp, id }));
resolve({all: allMonsters, hunt: huntMonsters});
});
我在这里使用Set
来摆脱O(n)/ O(n ^ 2)算法,我认为这是我可以用javascript实现的最快的速度。第三个功能与此功能相同,但额外过滤了我要避免的特殊怪物。
现在我的问题是:
worker_threads
,它可以帮助摆脱这种微小的滞后或其他问题吗?集群吗?答案 0 :(得分:0)
一段时间后,我意识到该机器人在“滞后”,因为我将这个巨大的#include <iostream>
#include <cstring>
#include <string>
using namespace std;
int main() {
string alphabet {"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"};
string key {"XZNLWEBGJHQDYVTKFUOMPCIASRxznlwebgjhqdyvtkfuompciasr"};
string word_to_encrypt {};
getline (cin,word_to_encrypt);
for (int i=0;i<word_to_encrypt.size();i++){
word_to_encrypt.replace(i, 1, key, (
alphabet.find(word_to_encrypt.c_str(), i, 1)),1);
}
cout<< word_to_encrypt;
}
数组作为函数的参数进行传递。我的意思是说我正在从g.npc
解析它,然后将其传递给getAllNpc
。
当我对其进行更改时,我在页面上下文内的受评估脚本中的filterMonsters
中执行.filter
,然后解析并传递具有数百个而不是数百万个元素的数组,它的速度要快得多,并且不会导致任何滞后或冻结