From d11bf2ed31b7f37601c7ea0e6bb1357a49bc3a65 Mon Sep 17 00:00:00 2001 From: 3urobeat <35304405+3urobeat@users.noreply.github.com> Date: Fri, 8 Mar 2024 19:50:42 +0100 Subject: [PATCH 01/28] Switch branch back to beta-testing --- docs/wiki/changelogs/CHANGELOG_v2.15.md | 2 ++ src/data/data.json | 4 ++-- src/data/fileStructure.json | 2 +- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/docs/wiki/changelogs/CHANGELOG_v2.15.md b/docs/wiki/changelogs/CHANGELOG_v2.15.md index 52a11c8d..2044e6d7 100644 --- a/docs/wiki/changelogs/CHANGELOG_v2.15.md +++ b/docs/wiki/changelogs/CHANGELOG_v2.15.md @@ -158,3 +158,5 @@ Commit: [be41d68](https://github.com/3urobeat/steam-comment-service-bot/commit/b - Reduced chances of startup ascii art showing an easter egg ascii art - Updated dependencies - Minor other changes + +Commit: [a8a04eb](https://github.com/3urobeat/steam-comment-service-bot/commit/a8a04eb) diff --git a/src/data/data.json b/src/data/data.json index 5f065eb9..bdf58f1a 100644 --- a/src/data/data.json +++ b/src/data/data.json @@ -1,9 +1,9 @@ { "version": "21501", "versionstr": "2.15.1", - "branch": "master", + "branch": "beta-testing", "filetostart": "./src/starter.js", - "filetostarturl": "https://raw.githubusercontent.com/3urobeat/steam-comment-service-bot/master/src/starter.js", + "filetostarturl": "https://raw.githubusercontent.com/3urobeat/steam-comment-service-bot/beta-testing/src/starter.js", "mestr": "3urobeat", "aboutstr": "This bot was created by 3urobeat.\nGitHub: https://github.com/3urobeat/steam-comment-service-bot \nSteam: https://steamcommunity.com/id/3urobeat \nIf you like my work, any donation would be appreciated! https://github.com/sponsors/3urobeat", "firststart": true, diff --git a/src/data/fileStructure.json b/src/data/fileStructure.json index 1fae5f69..4e4e80d3 100644 --- a/src/data/fileStructure.json +++ b/src/data/fileStructure.json @@ -188,7 +188,7 @@ { "path": "docs/wiki/changelogs/CHANGELOG_v2.15.md", "url": "https://raw.githubusercontent.com/3urobeat/steam-comment-service-bot/beta-testing/docs/wiki/changelogs/CHANGELOG_v2.15.md", - "checksum": "327435ddb0311eba66267b77129222b9" + "checksum": "645bb579fb2ea90bdd3c91910f5e71de" }, { "path": "docs/wiki/changelogs/CHANGELOG_v2.2.md", From 724b813666cdd256baea0b243eb0f7a4d4bd0524 Mon Sep 17 00:00:00 2001 From: 3urobeat <35304405+3urobeat@users.noreply.github.com> Date: Tue, 26 Mar 2024 16:54:17 +0100 Subject: [PATCH 02/28] docs: Improve contributing page and issue templates --- .github/ISSUE_TEMPLATE/bug_report.md | 12 +++---- .github/ISSUE_TEMPLATE/feature_request.md | 4 +-- .../ISSUE_TEMPLATE/help-wanted-question.md | 4 +-- docs/wiki/contributing.md | 31 ++++++++++++------- src/data/fileStructure.json | 8 ++--- 5 files changed, 33 insertions(+), 26 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index 51193322..f7904293 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -1,17 +1,17 @@ --- -name: Bug report -about: Report an error/a problem you experienced +name: Bug Report +about: Report an error or problem you've experienced title: '' labels: Bug assignees: '' --- -**Describe the bug** +**Please describe the bug** What happened? -**Full error** -Please post the **complete** error here! +**Full error stack trace** +If you've got an error, please post the **entire** error stack trace here! **Additional context** -Please add any other information here if you have some. +Please add any other information here, if you have some. diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md index 0de37c24..30b33bd9 100644 --- a/.github/ISSUE_TEMPLATE/feature_request.md +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -1,5 +1,5 @@ --- -name: Feature request +name: Feature Request about: Suggest a feature idea title: '' labels: Enhancement @@ -11,4 +11,4 @@ assignees: '' A clear description of what should happen. **Additional context** -Add any other context or screenshots about the feature request here. +Please add any other information here, if you have some. diff --git a/.github/ISSUE_TEMPLATE/help-wanted-question.md b/.github/ISSUE_TEMPLATE/help-wanted-question.md index cd272ede..3593dce4 100644 --- a/.github/ISSUE_TEMPLATE/help-wanted-question.md +++ b/.github/ISSUE_TEMPLATE/help-wanted-question.md @@ -1,5 +1,5 @@ --- -name: Help wanted/Question +name: I need help about: I have a question/need help but a Q&A discussion isn't fitting title: '' labels: Question @@ -11,4 +11,4 @@ assignees: '' Please explain your question here. If you've got an error or something else related, then please include it here as well. **Additional information** -Please add any other information here if you have some. +Please add any other information here, if you have some. diff --git a/docs/wiki/contributing.md b/docs/wiki/contributing.md index 94794833..9eac0633 100644 --- a/docs/wiki/contributing.md +++ b/docs/wiki/contributing.md @@ -15,16 +15,16 @@ Please read this page *before* diving in, it contains a few **very** important p ## Table Of Contents - [Reporting an issue](#reporting-an-issue) - [How to fork and open pull requests](#how-to-fork-and-open-pull-requests) -- [Translating](#translating) -- [Styling Guidelines](#styling-guidelines) +- [Updating or Adding a language translation](#translating) +- [Styling guidelines](#styling-guidelines) - [Starting the bot](#starting-the-bot)   ## Reporting an Issue -Found a bug? -Please report it by creating an [issue](https://github.com/3urobeat/steam-comment-service-bot/issues/new/choose) so that I am able to fix it! -If you've got a feature request instead, you can choose the "Feature request" template instead. +Found a bug/error? +Please report it by creating an [issue](https://github.com/3urobeat/steam-comment-service-bot/issues/new/choose). I'll respond as soon as possible. +If you've got a feature request instead, you can choose the "Feature request" template. If you have any questions, please open a [Q&A discussion](https://github.com/3urobeat/steam-comment-service-bot/discussions/new?category=q-a) instead! @@ -35,8 +35,10 @@ To contribute code to the project, you first need to fork this repository. Go to Before clicking the "Create fork" button in the next menu, make sure the checkmark at "Copy the `master` branch only" is **unchecked**! After waiting a few seconds you should now have a *copy* of the repository on your account. -Go into a folder on your computer where the project should be stored, open a terminal and run the command -`git clone https://github.com/your-username/steam-comment-service-bot` or use any other Git Client of your choice. +Assuming you already have `git` installed on your computer, open a folder on your PC where the project should be stored. +Open a terminal in this location and run the command +`git clone https://github.com/your-username/steam-comment-service-bot` +...or use any other Git Client of your choice. Once the repository has been cloned, switch to the `beta-testing` branch using the command `git checkout beta-testing`. This branch contains the latest changes and must be the one you base your changes off of. The `master` branch contains the latest release. @@ -44,20 +46,26 @@ This branch contains the latest changes and must be the one you base your change You can now create your own branch using `git checkout -b "branchname"`, make changes and commit them to it. It makes sense to give the branch a sensible name based on what your changes will be, but no pressure. -The setup of your dev bot is very similar to the [normal setup](./setup_guide.md), however make sure to run `npm install` manually. This will install all dev dependencies, which are omitted in the normal installation. +The setup of your dev bot is very similar to the [normal setup](./setup_guide.md), however make sure to run the command `npm install` in your terminal manually. +This will install all dev dependencies, which are omitted in the normal installation to save space. It is probably also a good idea to enable `printDebug` in `advancedconfig.json` to see a more detailed log output. -Once you have made your changes and verified they are working as expected, you need to open a Pull Request to merge them into this repository. +Make sure you have read '[Starting the bot](#starting-the-bot)' at the bottom of the page, before starting the bot to test your changes. + +Once you have made your changes and verified they are working as expected, you need to open a Pull Request to get them merged into this repository. [Click here](https://github.com/3urobeat/steam-comment-service-bot/compare/), click on "Compare across forks" at the top and select `base: beta-testing` on the left side. Then, choose your fork on the right at `head repository:`, your branch at `compare:` and click on "Create Pull Request". Give your pull request a fitting title which describes your changes in a few words and put a more in depth explanation below in the description. Once you are satisfied, hit the "Create pull request" button below to submit. I'll take a look at it and perhaps suggest or make some minor changes in the following few days. +Once everything looks good, I will merge your changes and they will be included in the next version.   ## Translating +The bot includes more translations than languages I speak myself - so I need your help here! + **Updating an existing language:** I'm changing or adding new messages nearly every update, so there are often language strings that need to be updated. It'd be great if you could help! @@ -122,9 +130,8 @@ In short, the main styling rules are:   ## Starting the bot -When starting the bot during development, it is crucial to execute the [generateFileStructure](/scripts/generateFileStructure.js) script before starting the bot, on every change. -You can do this easily by using a simple chained command: -`node scripts/generateFileStructure.js && node start.js` +When starting the bot during development, it is crucial to update every file's checksum, on every change. +You can do this easily by starting the bot using the command: `npm run dev` This ensures that [fileStructure.json](/src/data/fileStructure.json), which contains checksums for every file, gets updated. The application will otherwise recognize your changed file as broken and will restore it with the default one. diff --git a/src/data/fileStructure.json b/src/data/fileStructure.json index 4e4e80d3..5f2d74ef 100644 --- a/src/data/fileStructure.json +++ b/src/data/fileStructure.json @@ -13,17 +13,17 @@ { "path": ".github/ISSUE_TEMPLATE/bug_report.md", "url": "https://raw.githubusercontent.com/3urobeat/steam-comment-service-bot/beta-testing/.github/ISSUE_TEMPLATE/bug_report.md", - "checksum": "324472c36f99a41a0eb39f6875e11a56" + "checksum": "0427a2bb62d2775fbf47795461d343b5" }, { "path": ".github/ISSUE_TEMPLATE/feature_request.md", "url": "https://raw.githubusercontent.com/3urobeat/steam-comment-service-bot/beta-testing/.github/ISSUE_TEMPLATE/feature_request.md", - "checksum": "434308eeb7670ecc4fa63908eb6f9f56" + "checksum": "23a660d1130154f12b20168de15e264b" }, { "path": ".github/ISSUE_TEMPLATE/help-wanted-question.md", "url": "https://raw.githubusercontent.com/3urobeat/steam-comment-service-bot/beta-testing/.github/ISSUE_TEMPLATE/help-wanted-question.md", - "checksum": "d341d7c8a2428d5c4a495508d5400b7d" + "checksum": "081c0421394521c2fafe5c518f2023a2" }, { "path": ".github/workflows/codeql-analysis.yml", @@ -243,7 +243,7 @@ { "path": "docs/wiki/contributing.md", "url": "https://raw.githubusercontent.com/3urobeat/steam-comment-service-bot/beta-testing/docs/wiki/contributing.md", - "checksum": "7719bb31fc5180a04362a5d71e93f9bf" + "checksum": "bf2726a14d91675dd6b530da720aabab" }, { "path": "docs/wiki/creating_plugins.md", From 2ba4a0ffcffa9ad743a82532feae7c4389a62ed4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=CE=B6=E0=B8=B1=CD=A1=E5=B9=BB=E0=B8=B1=CD=A1=E6=9C=88?= =?UTF-8?q?=E0=B8=B1=CD=A1=E2=9C=BE?= <64715639+Tira-tw@users.noreply.github.com> Date: Sun, 28 Apr 2024 22:35:02 +0800 Subject: [PATCH 03/28] Add files via upload --- src/data/lang/traditional-chinese.json | 147 +++++++++++++++++++++++++ 1 file changed, 147 insertions(+) create mode 100644 src/data/lang/traditional-chinese.json diff --git a/src/data/lang/traditional-chinese.json b/src/data/lang/traditional-chinese.json new file mode 100644 index 00000000..420ecb13 --- /dev/null +++ b/src/data/lang/traditional-chinese.json @@ -0,0 +1,147 @@ +{ + "note": "此檔案關於機器人所有訊息 如果想要修改請閱讀: https://github.com/3urobeat/steam-comment-service-bot/blob/master/docs/wiki/customlang_doc.md", + + "langname": "traditional-chinese", + + "updaterautoupdatedisabled": "已停用自動更新,是否需要啟動\n如果需要請填入這個指令: ${cmdprefix}update true", + + "commentcmdusageowner": "'${cmdprefix}comment amount/\"all\" id' 發送你想要的數量評論(也可以發送最多評論).\n如果想在其他地方發送評論,你需要提供對方的個人檔案連結、群組連結、螢幕擷圖連結、指南、藝術作品連結。", + "commentcmdusageowner2": "'${cmdprefix}comment 1 id'. 如果想在其他地方發送評論,你需要提供對方的個人檔案連結、群組連結、螢幕擷圖連結、指南、藝術作品連結。", + "commentcmdusage": "'${cmdprefix}comment amount/\"all\"' 提供想要評論的數量。", + "commentcmdusage2": "'${cmdprefix}comment' 發送評論到你的個人檔案。", + "commentinvalidid": "錯誤的連結\n請確認該連結是否正確\n\n正確使用: ${commentcmdusage}", + "commentprofileidowneronly": "指令只提供開發者使用\n如果你是開發者請添加你的Steam ID到config.json。", + "commentmissingnumberofcomments": "請填寫你需要${maxRequestAmount}條評論的數量\n正確使用: ${commentcmdusage}", + "commentzeroavailableaccs": "對不起,目前的機器人正在冷卻中。 請等待${waittime}秒然後再試一次", + "commentnotenoughavailableaccs": "對不起,目前的機器人正在冷卻中。 請等待${waittime}秒然後再試一次,或者是發送${availablenow}條評論", + "commentnoaccounts": "對不起,目前沒有帳號可以幫助你,不過你可以聯絡開發者\n請使用${cmdprefix}owner聯絡開發者。", + "commentaddbotaccounts": "請添加這些帳號,然後再試一次: (limited accounts)", + "commentunsupportedtype": "對不起,這個指令不適合用於這個類型ID。請貼上個人檔案連結、群組連結、螢幕擷圖連結、指南、藝術作品連結。", + "commentuserprofileprivate": "訪問的連結私人的!,請修改我的個人檔案、能在我的個人檔案發表留言為公開。", + "commenterroroccurred": "無法發送評論", + "commentprocessstarted": "接受評論到的有${numberOfComments}條評論\n請等待${waittime}完成。", + "commentfailedcmdreference": "如果想獲得傳送失敗資訊,請貼上'${cmdprefix}failed'\n如果看不懂錯誤原因請查看: https://github.com/3urobeat/steam-comment-service-bot/blob/master/docs/wiki/errors_doc.md", + "comment429stop": "已停止,所有的代理出現HTTP 429 (IP cooldown) error。請稍後再試\n失敗: ${failedamount}/${numberOfComments}", + "commentretrying": "${failedamount}/${numberOfComments}條評論失敗。開始重試 ${untilStr}. (Attempt ${thisattempt}/${maxattempt})", + "commentsuccess": "全部評論已發送。 無法傳送數量: ${failedamount}/${numberOfComments}\n如果你覺得這個還不錯的話,在我的留言區底下留下好評,讓更多人知道!", + "genericnoaccounts": "對不起,你輸入無效的ID了。", + + "genericnounlimitedaccs": "對不起,目前帳號沒貨。請聯繫開發者\n${cmdprefix}owner", + "genericrequestless": "目前只有${availablenow}個可以使用。", + "genericnotenoughavailableaccs": "對不起,目前沒有足夠的帳號可用於提供的ID資料。請等待 ${waittime} and try again or only request ${availablenow} now.", + + "voteunsupportedtype": "對不起,投票指令不支援你所提供這個類型的ID。 請提供投票連結(不支援funnyvote)或查看連結。", + "voteprocessstarted": "接受投票到的有${numberOfVotes} 投票時間: ${waittime}", + "votesuccess": "全部投票已發送。 無法傳送數量: ${failedamount}/${numberOfVotes}", + + "favoriteprocessstarted": "${numberOfFavs} 個未收藏/已收藏發送,請等待時間: ${waittime}", + "favoritesuccess": "未收藏/已收藏發送成功。 無法傳送數量: ${failedamount}/${numberOfFavs}", + + "followprocessstarted": "${totalamount} 未追蹤已追蹤已發送,請等待: ${waittime}", + "followsuccess": "未追蹤已追蹤已發送成功。無法傳送數量: ${failedamount}/${totalamount}", + + "useradded": "你好哇^w^ 謝謝你添加我為你的好友\n我是一個免費服務有: '${cmdprefix}comment' - 評論\n'${cmdprefix}help' - 菜單\n'${cmdprefix}about' - 關於\n'${cmdprefix}lang' - 切換語言", + "userunfriend": "由於使用者太多,你${forceFriendlistSpaceTime}天沒使用我\n如果還有需要繼續使用請添加。", + "userforceunfriend": "你${unfriendtime}天沒使用我\n如果還有需要繼續使用請添加。", + + "userspamblock": "已封鎖90秒\n原因 : 刷屏", + "usernotfriend": "請在使用我之前添加好友。", + "botnotready": "尚未完全啟動\n請等待。", + "commandnotfound": "資料庫尚未沒有這個功能\n請查看 ${cmdprefix}help", + "commandowneronly": "指令只提供開發者使用\n如果你是開發者請添加你的Steam ID到config.json。", + "nouserid": "在沒有用戶ID的情況下被調用\n阻止該指令\n這是一個編碼問題\n請聯繫開發者 : ${cmdprefix}owner", + "noidparam": "請提供ID", + + "requesttoohigh": "最多可以發送 ${maxRequestAmount}\n\n正確使用: ${cmdusage}", + "invalidnumber": "這不是數字\n\n正確使用: ${cmdusage}", + "invalidprofileid": "請輸入正確的ID", + "invalidgroupid": "請輸入正確的ID \n示範群組ID: '103582791464712227' \n示範群組連結: 'https://steamcommunity.com/groups/3urobeatGroup'", + "invalidsharedfileid": "這不是一個正確的檔案ID\n示範共享檔案連結: https://steamcommunity.com/sharedfiles/filedetails/?id=2980913451 \n 示範共享檔案ID: 2980913451\n群組連結、螢幕擷圖連結、指南、藝術作品連結。\n\n正確使用: ${cmdusage}", + "invalidreviewid": "這不是一個正確的檔案ID\n請確認是否填入正確,示範: https://steamcommunity.com/id/3urobeat/recommended/1902490/\n\n正確使用: ${cmdusage}", + "errloadingsharedfile": "發生錯誤: ", + "errloadingreview": "發生錯誤: ", + "idisownererror": "你不能提供開發者ID", + "idalreadyreceiving": "提供的用戶以前已提交,請等待完成後重試", + "idoncooldown": "最近才剛提交,請等待 ${remainingcooldown} 再次提交", + "requestaborted": "你提交的訊息已停止\n${successAmount}/${totalAmount} 已發送成功", + + "jobscmdregistered": "已註冊:", + "jobscmdnoneregistered": "未註冊", + "reloadcmdreloaded": "已重新讀取所有功能 / 插件", + "activerelog": "目前正等待最後一個活動完成,以便重新登入帳戶。", + "updatecmdforce": "強制更新 ${branchname}", + "updatecmdcheck": "檢查更新 ${branchname}", + "restartcmdrestarting": "重啟中", + "stopcmdstopping": "已停止", + + "helpcommandlist": "功能:", + "helpcommentowner": "最大值 ${maxOwnerRequests} 到您/其他個人檔案的評論", + "helpcommentuser": "最大值 ${maxRequests} 到您的個人檔案評論", + "helpvote": "最大值 ${maxRequests} 共享檔案/投票數量", + "helpfavorite": "最大值 ${maxRequests} 共享檔案/收藏數量", + "helpfollow": "最大值 ${maxRequests} 工作坊追蹤數量", + "helpinfo": "關於機器人/您的訊息", + "helpabort": "關於您的發送", + "helpabout": "關於機器人資訊", + "helpowner": "關於開發者資訊", + "helpreadothercmdshere": "30個功能列表在這邊:", + + "pingcmdmessage": "/me ${pingtime}ms", + "ownercmdnolink": "沒有連結", + "ownercmdmsg": "以下是開發者的連結: (更多資訊請貼上 ${cmdprefix}about)", + "groupcmdnolink": "沒有連結", + "groupcmdinvitesent": "已發送群組連結,歡迎加入", + "groupcmdinvitelink": "我的群組: ", + "abortcmdnoprocess": "請提供ID/連結", + "abortcmdsuccess": "正在停止你所提供的ID資訊", + + "resetcooldowncmdcooldowndisabled": "已停用冷卻時間", + "resetcooldowncmdglobalreset": "機器人帳號的冷卻時間已重置", + "resetcooldowncmdsuccess": "${profileid}冷卻時間已清除", + + "langcmdsupported": "以下語言名字:", + "langcmdnotsupported": "尚未提供你想要的語言。 請查看語言列表: ${supportedlangs}\n\n想要製作語言嗎?請查看: ' https://github.com/3urobeat/steam-comment-service-bot/blob/master/docs/wiki/contributing.md#translating '", + "langcmdsuccess": "已讀取語言", + + "settingscmdfailedread": "無法讀取目前設定: ", + "settingscmdcurrentsettings": "目前設定:", + "settingscmdblockedvalues": "無法透過設定指令修改enableevalcmd / ownerid / owner\n請設定Config檔案", + "settingscmdcouldnotconvert": "我無法切換您的輸入, 請確定您的順序是對的。\nError: ", + "settingscmdkeynotfound": "Config找不到這個key", + "settingscmdsamevalue": "Key已存在 ${value}.", + "settingscmdvaluetoobig": "新的數值太大 (32-bit 限制)\n請更改比較小一點的數值", + "settingscmdvaluereset": "檔案管理拒絕此要求 並且向你發出警告訊息:", + "settingscmdvaluechanged": "${targetkey} 已更改為 ${oldvalue}到${newvalue}\n請記住,某些值可能需要重啟。 你可以寫這個 ${cmdprefix}restart.", + + "failedcmdnothingfound": "沒有任何失敗的結果", + "failedcmdmsg": "你發送 '${steamID64}'已結束,在'${requesttime}' (GMT time) 出現問題:", + + "sessionscmdnosessions": "在沒有活耀的情況下是冷卻的狀態", + "sessionscmdmsg": "目前有 ${amount}個活耀秒(s):", + "mysessionscmdnosessions": "目前沒有", + + "addfriendcmdacclimited": "無法添加 ${profileid} bot0可能不是課金帳號", + "addfriendcmdsuccess": "正在添加 ${profileid} 所有機器人同時添加,這可能需要一點時間", + "unfriendcmdsuccess": "所有機器人同時解除好友,這可能需要一點時間。", + "unfriendidcmdsuccess": "所有機器人已解除${profileid}好友", + + "unfriendallcmdabort": "如果正在進行解除全部好友處於活耀狀態會停止", + "unfriendallcmdpending": "除了開發者,我需要30秒時間解除所有好友\n填寫 '${cmdprefix}unfriendall abort' abort/stop 可停止", + "unfriendallcmdstart": "開始解除所有好友", + + "joingroupcmdsuccess": "所有的機器人正在加入'${groupid}'", + + "leavegroupcmdsuccess": "所有的機器人正在退出'${groupid}'", + + "leaveallgroupscmdabort": "如果正在進行離開全部群組處於活耀狀態會停止", + "leaveallgroupscmdpending": "除了開發者,我需要30秒時間離開全部群組\n填寫 '${cmdprefix}leaveallgroups abort' abort/stop 可停止", + "leaveallgroupscmdstart": "開始離開全部群組", + + "blockcmdsuccess": "所有機器人同時封鎖 ${profileid}", + "unblockcmdsuccess": "所有機器人同時解除封鎖 ${profileid}", + + "evalcmdturnedoff": "eval指令已關閉", + "evalcmdlogininfoblock": "您的程式碼包含'logininfo'這是保護密碼的\n請使用其他的", + + "childbotmessage": "這是接收支援的機器人\n請使用以下機器人:" +} From 0710937221949771db84c22d92662e42f24462c9 Mon Sep 17 00:00:00 2001 From: 3urobeat <35304405+3urobeat@users.noreply.github.com> Date: Wed, 1 May 2024 13:53:05 +0200 Subject: [PATCH 04/28] chore: Update hostname check and lang checksum --- src/data/fileStructure.json | 7 ++++++- src/dataManager/dataCheck.js | 4 ++-- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/src/data/fileStructure.json b/src/data/fileStructure.json index 5f2d74ef..2dfbaaed 100644 --- a/src/data/fileStructure.json +++ b/src/data/fileStructure.json @@ -575,10 +575,15 @@ "url": "https://raw.githubusercontent.com/3urobeat/steam-comment-service-bot/beta-testing/src/data/lang/russian.json", "checksum": "9f93de745e5596791a2bdef226ee1b6b" }, + { + "path": "src/data/lang/traditional-chinese.json", + "url": "https://raw.githubusercontent.com/3urobeat/steam-comment-service-bot/beta-testing/src/data/lang/traditional-chinese.json", + "checksum": "77dac08416877be42feade0473810c13" + }, { "path": "src/dataManager/dataCheck.js", "url": "https://raw.githubusercontent.com/3urobeat/steam-comment-service-bot/beta-testing/src/dataManager/dataCheck.js", - "checksum": "04f630fd31ef721c9748bd4f680cb9c3" + "checksum": "12dce4d35da119566ef427ab5b6d49c5" }, { "path": "src/dataManager/dataExport.js", diff --git a/src/dataManager/dataCheck.js b/src/dataManager/dataCheck.js index 5a72a68e..2a04b6dc 100644 --- a/src/dataManager/dataCheck.js +++ b/src/dataManager/dataCheck.js @@ -4,7 +4,7 @@ * Created Date: 2021-07-09 16:26:00 * Author: 3urobeat * - * Last Modified: 2024-02-28 20:53:59 + * Last Modified: 2024-05-01 13:38:35 * Modified By: 3urobeat * * Copyright (c) 2023 - 2024 3urobeat @@ -53,7 +53,7 @@ DataManager.prototype.checkData = function() { // Check config for default value leftovers when the bot is not running on my machines - if ((process.env.LOGNAME !== "tomg") || (os.hostname() !== "Tomkes-PC" && os.hostname() !== "Tomkes-Server" && os.hostname() !== "Tomkes-Thinkpad")) { + if ((process.env.LOGNAME !== "tomg") || (!["Tomkes-PC", "Tomkes-Server", "Tomkes-Thinkpad", "Tomkes-Thinkpad-Z13"].includes(os.hostname()))) { let write = false; if (this.config.owner.includes(this.datafile.mestr)) { this.config.owner = ""; write = true; } From 7013443f1416fc6669e67960faf3bd5db9cf0b4c Mon Sep 17 00:00:00 2001 From: 3urobeat <35304405+3urobeat@users.noreply.github.com> Date: Wed, 1 May 2024 13:58:45 +0200 Subject: [PATCH 05/28] feat: Add !add alias to !addfriend command --- src/commands/core/friend.js | 4 ++-- src/data/fileStructure.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/commands/core/friend.js b/src/commands/core/friend.js index e389d450..1c9962a8 100644 --- a/src/commands/core/friend.js +++ b/src/commands/core/friend.js @@ -4,7 +4,7 @@ * Created Date: 2021-07-09 16:26:00 * Author: 3urobeat * - * Last Modified: 2024-03-08 18:24:40 + * Last Modified: 2024-05-01 13:54:40 * Modified By: 3urobeat * * Copyright (c) 2021 - 2024 3urobeat @@ -21,7 +21,7 @@ const CommandHandler = require("../commandHandler.js"); // eslint-disable-line module.exports.addFriend = { - names: ["addfriend"], + names: ["addfriend", "add"], description: "Adds the ID with all bot accounts. Requires unlimited accounts!", args: [ { diff --git a/src/data/fileStructure.json b/src/data/fileStructure.json index 2dfbaaed..62c35022 100644 --- a/src/data/fileStructure.json +++ b/src/data/fileStructure.json @@ -408,7 +408,7 @@ { "path": "src/commands/core/friend.js", "url": "https://raw.githubusercontent.com/3urobeat/steam-comment-service-bot/beta-testing/src/commands/core/friend.js", - "checksum": "26800bddf4e1c79331dca96c43e38fea" + "checksum": "449892dc37e25ac64e3ef97e4925d63f" }, { "path": "src/commands/core/general.js", From ae4553512f83cbdb43ba3531d9784eef05cbd8cc Mon Sep 17 00:00:00 2001 From: 3urobeat <35304405+3urobeat@users.noreply.github.com> Date: Wed, 1 May 2024 15:25:19 +0200 Subject: [PATCH 06/28] fix: Fix login starting faster than plugin load, making it unable to handle steamGuardCode events --- src/controller/controller.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/controller/controller.js b/src/controller/controller.js index 3d879fe3..252aae4f 100644 --- a/src/controller/controller.js +++ b/src/controller/controller.js @@ -4,7 +4,7 @@ * Created Date: 2021-07-09 16:26:00 * Author: 3urobeat * - * Last Modified: 2024-02-29 21:13:33 + * Last Modified: 2024-05-01 15:19:41 * Modified By: 3urobeat * * Copyright (c) 2021 - 2024 3urobeat @@ -332,7 +332,7 @@ Controller.prototype._preLogin = async function() { * @type {PluginSystem} */ this.pluginSystem = new PluginSystem(this); - this.pluginSystem._loadPlugins(); // Load all plugins now + await this.pluginSystem._loadPlugins(); // Load all plugins now. Await to hopefully give plugins enough time to catch Steam Guard events // Start logging in From fdd1e5d1c179556b785d6c6f83b3c6f9ec782b6e Mon Sep 17 00:00:00 2001 From: 3urobeat <35304405+3urobeat@users.noreply.github.com> Date: Wed, 1 May 2024 15:26:54 +0200 Subject: [PATCH 07/28] feat(PluginSystem): Add steamGuardQrCode event https://github.com/DerDeathraven/steam-comment-bot-rest-api/issues/9 --- src/controller/controller.js | 8 ++++++ src/controller/events/steamGuardQrCode.js | 35 +++++++++++++++++++++++ src/data/fileStructure.json | 13 ++++++--- src/pluginSystem/loadPlugins.js | 3 +- src/pluginSystem/pluginSystem.js | 5 ++-- src/sessions/helpers/handle2FA.js | 5 +++- 6 files changed, 61 insertions(+), 8 deletions(-) create mode 100644 src/controller/events/steamGuardQrCode.js diff --git a/src/controller/controller.js b/src/controller/controller.js index 252aae4f..c858b395 100644 --- a/src/controller/controller.js +++ b/src/controller/controller.js @@ -307,6 +307,7 @@ Controller.prototype._preLogin = async function() { require("./events/ready.js"); require("./events/statusUpdate.js"); require("./events/steamGuardInput.js"); + require("./events/steamGuardQrCode.js"); require("./helpers/friendlist.js"); require("./helpers/getBots.js"); require("./helpers/handleSteamIdResolving.js"); @@ -451,6 +452,13 @@ Controller.prototype._statusUpdateEvent = function(bot, newStatus) {}; // eslint */ Controller.prototype._steamGuardInputEvent = function(bot, submitCode) {}; // eslint-disable-line +/** + * Emits steamGuardQrCode event for bot & plugins + * @param {Bot} bot Bot instance of the affected account + * @param {string} challengeUrl The QrCode Challenge URL supplied by Steam. Display this value using a QR-Code parser and let a user scan it using their Steam Mobile App. + */ +Controller.prototype._steamGuardQrCodeEvent = function(bot, challengeUrl) {}; // eslint-disable-line + /** * Check if all friends are in lastcomment database * @param {Bot} bot Bot object of the account to check diff --git a/src/controller/events/steamGuardQrCode.js b/src/controller/events/steamGuardQrCode.js new file mode 100644 index 00000000..24d8a501 --- /dev/null +++ b/src/controller/events/steamGuardQrCode.js @@ -0,0 +1,35 @@ +/* + * File: steamGuardQrCode.js + * Project: steam-comment-service-bot + * Created Date: 2024-05-01 14:44:36 + * Author: 3urobeat + * + * Last Modified: 2024-05-01 14:48:33 + * Modified By: 3urobeat + * + * Copyright (c) 2024 3urobeat + * + * This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. + * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + * You should have received a copy of the GNU General Public License along with this program. If not, see . + */ + + +const Bot = require("../../bot/bot.js"); // eslint-disable-line +const Controller = require("../controller"); + + +/** + * Emits steamGuardQrCode event for bot & plugins + * @param {Bot} bot Bot instance of the affected account + * @param {string} challengeUrl The QrCode Challenge URL supplied by Steam. Display this value using a QR-Code parser and let a user scan it using their Steam Mobile App. + */ +Controller.prototype._steamGuardQrCodeEvent = function(bot, challengeUrl) { + + // Log debug message + logger("debug", `Controller steamGuardQrCodeEvent: Emitting event for bot${bot.index} so plugins can display the QR-Code...`); + + // Emit event + this.events.emit("steamGuardQrCode", bot, challengeUrl); + +}; diff --git a/src/data/fileStructure.json b/src/data/fileStructure.json index 62c35022..ca60a531 100644 --- a/src/data/fileStructure.json +++ b/src/data/fileStructure.json @@ -493,7 +493,7 @@ { "path": "src/controller/controller.js", "url": "https://raw.githubusercontent.com/3urobeat/steam-comment-service-bot/beta-testing/src/controller/controller.js", - "checksum": "031c4ada6d2ed4e366773d5af1da359b" + "checksum": "fd28817485832dadb454cef17b782c51" }, { "path": "src/controller/events/ready.js", @@ -510,6 +510,11 @@ "url": "https://raw.githubusercontent.com/3urobeat/steam-comment-service-bot/beta-testing/src/controller/events/steamGuardInput.js", "checksum": "df33797c6bf867a52adb5d7e39315e73" }, + { + "path": "src/controller/events/steamGuardQrCode.js", + "url": "https://raw.githubusercontent.com/3urobeat/steam-comment-service-bot/beta-testing/src/controller/events/steamGuardQrCode.js", + "checksum": "37910bd18328ada639373d8373c664a4" + }, { "path": "src/controller/helpers/friendlist.js", "url": "https://raw.githubusercontent.com/3urobeat/steam-comment-service-bot/beta-testing/src/controller/helpers/friendlist.js", @@ -708,12 +713,12 @@ { "path": "src/pluginSystem/loadPlugins.js", "url": "https://raw.githubusercontent.com/3urobeat/steam-comment-service-bot/beta-testing/src/pluginSystem/loadPlugins.js", - "checksum": "236e11079a89df528f4e609eb68e784e" + "checksum": "a2889cdf46fa8876a767ab272356b3f9" }, { "path": "src/pluginSystem/pluginSystem.js", "url": "https://raw.githubusercontent.com/3urobeat/steam-comment-service-bot/beta-testing/src/pluginSystem/pluginSystem.js", - "checksum": "15f035879c2247ab7372644e21398344" + "checksum": "577b44eae6d3c22fcbf40bde95b99fc1" }, { "path": "src/sessions/events/sessionEvents.js", @@ -723,7 +728,7 @@ { "path": "src/sessions/helpers/handle2FA.js", "url": "https://raw.githubusercontent.com/3urobeat/steam-comment-service-bot/beta-testing/src/sessions/helpers/handle2FA.js", - "checksum": "14641de1b2895cbea783b4264a7bd489" + "checksum": "60163e6e65c01443a28269937ed69261" }, { "path": "src/sessions/helpers/handleCredentialsLoginError.js", diff --git a/src/pluginSystem/loadPlugins.js b/src/pluginSystem/loadPlugins.js index 0e069c2f..2bc71bdc 100644 --- a/src/pluginSystem/loadPlugins.js +++ b/src/pluginSystem/loadPlugins.js @@ -4,7 +4,7 @@ * Created Date: 2023-06-04 15:37:17 * Author: DerDeathraven * - * Last Modified: 2024-03-08 18:19:31 + * Last Modified: 2024-05-01 14:54:49 * Modified By: 3urobeat * * Copyright (c) 2023 - 2024 3urobeat @@ -24,6 +24,7 @@ const PLUGIN_EVENTS = { READY: "ready", STATUS_UPDATE: "statusUpdate", steamGuardInput: "steamGuardInput", + steamGuardQrCode: "steamGuardQrCode" }; diff --git a/src/pluginSystem/pluginSystem.js b/src/pluginSystem/pluginSystem.js index 29a4ed3b..2e7a29df 100644 --- a/src/pluginSystem/pluginSystem.js +++ b/src/pluginSystem/pluginSystem.js @@ -4,7 +4,7 @@ * Created Date: 2023-03-19 13:34:27 * Author: 3urobeat * - * Last Modified: 2024-02-23 14:42:19 + * Last Modified: 2024-05-01 15:19:03 * Modified By: 3urobeat * * Copyright (c) 2023 - 2024 3urobeat @@ -29,6 +29,7 @@ const Bot = require("../bot/bot.js"); // eslint-disab * @property {function(): void} ready Controller ready event * @property {function(Bot, Bot.EStatus, Bot.EStatus): void} statusUpdate Controller statusUpdate event * @property {function(Bot, function(string): void): void} steamGuardInput Controller steamGuardInput event + * @property {function(Bot, string): void} steamGuardQrCode Controller steamGuardQrCode event */ @@ -114,7 +115,7 @@ PluginSystem.prototype.reloadPlugins = function () { /** * Internal: Loads all plugin npm packages and populates pluginList */ -PluginSystem.prototype._loadPlugins = function () {}; +PluginSystem.prototype._loadPlugins = async function () {}; /** * Internal: Checks a plugin, displays relevant warnings and decides whether the plugin is allowed to be loaded diff --git a/src/sessions/helpers/handle2FA.js b/src/sessions/helpers/handle2FA.js index 01bcc16f..a1842acf 100644 --- a/src/sessions/helpers/handle2FA.js +++ b/src/sessions/helpers/handle2FA.js @@ -4,7 +4,7 @@ * Created Date: 2022-10-09 12:59:31 * Author: 3urobeat * - * Last Modified: 2024-02-28 22:28:46 + * Last Modified: 2024-05-01 14:56:23 * Modified By: 3urobeat * * Copyright (c) 2022 - 2024 3urobeat @@ -181,4 +181,7 @@ SessionHandler.prototype._handleQRCode = function(res) { logger.readInput("", 90000, () => {}); }); + // Emit steamGuardQrCode event from our controller so that plugins can handle this event too + this.controller._steamGuardQrCodeEvent(this.bot, res.qrChallengeUrl); + }; From fdd0f14247c9362aa98a5409cbd25ee195845cd4 Mon Sep 17 00:00:00 2001 From: 3urobeat <35304405+3urobeat@users.noreply.github.com> Date: Wed, 1 May 2024 15:27:31 +0200 Subject: [PATCH 08/28] docs: Add entries for new steamGuardQrCode event --- docs/dev/controller/events.md | 7 +++++++ docs/wiki/creating_plugins.md | 14 ++++++++++---- src/data/fileStructure.json | 4 ++-- 3 files changed, 19 insertions(+), 6 deletions(-) diff --git a/docs/dev/controller/events.md b/docs/dev/controller/events.md index 2d8d697e..f60c9fc3 100644 --- a/docs/dev/controller/events.md +++ b/docs/dev/controller/events.md @@ -49,3 +49,10 @@ The event is emitted with the parameters The `submitCode` function allows users to implement accepting Steam Guard Codes from users into their plugins. This is very cool. Check out how the [template plugin](https://github.com/3urobeat/steam-comment-bot-template-plugin/blob/main/plugin.js) implements the `steamGuardInput` event function (which is called by the PluginSystem when the event is emitted, instead of listening directly to it). + +## steamGuardQrCode +This event is emitted when any bot account is trying to log in using a QR-Code. A user needs to scan this QR-Code using their Steam Mobile App to confirm the login request. + +The event is emitted with the parameters +- `bot` ([Bot](../bot/bot.md)) - Bot instance of the affected account +- `challengeUrl` (string) - The QrCode Challenge URL supplied by Steam. Display this value using a QR-Code parser and let a user scan it using their Steam Mobile App. diff --git a/docs/wiki/creating_plugins.md b/docs/wiki/creating_plugins.md index 6461140c..7174e7fb 100644 --- a/docs/wiki/creating_plugins.md +++ b/docs/wiki/creating_plugins.md @@ -87,12 +87,18 @@ It makes sense to load your plugin config file from your plugin config folder, j We are also registering a super cool command here with the names '!hello' and '!cool-alias'. If someone executes it, it will respond with 'Hello World!'. Registering commands and responding to the user is further explained below. **Event functions:** -The template plugin also exposes a 'ready', 'statusUpdate', 'steamGuardInput' function. +The template plugin also exposes a 'ready', 'statusUpdate', 'steamGuardInput', 'steamGuardQrCode' function. These are functions that will be called by the plugin system when the bot emits those events. -The ready event function is called when the bot has finished logging in all accounts. Should the plugin load be caused by '!reload', this function is executed milliseconds after `load()` has been called. -The statusUpdate event function is called when any bot account changes their status. Every status a bot can have is documented in the [EStatus enum](../../src/bot/EStatus.js). -The steamGuardInput event function is called when any bot account is currently being logged in, but a Steam Guard Code is requested. The bot has a built in handler that will request code input from the terminal on this event. +The 'ready' event function is called when the bot has finished logging in all accounts. Should the plugin load be caused by '!reload', this function is executed milliseconds after `load()` has been called. + +The 'statusUpdate' event function is called when any bot account changes their status. Every status a bot can have is documented in the [EStatus enum](../../src/bot/EStatus.js). + +The 'steamGuardInput' event function is called when any bot account is currently being logged in and a Steam Guard Code was requested by Steam. +The bot has a built in handler that will request code input from the terminal on this event. Plugins can use the `code()` callback function in `steamGuardInput(bot, code)` to supply a code themselves, resolving the request as well. +If a session was started by logging in using a QrCode instead of a password, the event 'steamGuardQrCode' will be fired instead. Plugins can display the QrCode supplied in this event, for example using the [qrcode library](https://www.npmjs.com/package/qrcode), which will resolve the request once it has been scanned using a Steam Mobile App. + +To check from your plugin if the Steam Guard Code/QrCode request has been resolved, wait for the statusUpdate event to announce a change.   diff --git a/src/data/fileStructure.json b/src/data/fileStructure.json index ca60a531..face43c2 100644 --- a/src/data/fileStructure.json +++ b/src/data/fileStructure.json @@ -83,7 +83,7 @@ { "path": "docs/dev/controller/events.md", "url": "https://raw.githubusercontent.com/3urobeat/steam-comment-service-bot/beta-testing/docs/dev/controller/events.md", - "checksum": "cab6f4fe3d8b9fa0374bf9aaa33c965d" + "checksum": "8c1a3cfb9b911e2fc61c77ae4251db38" }, { "path": "docs/dev/controller/helpers.md", @@ -248,7 +248,7 @@ { "path": "docs/wiki/creating_plugins.md", "url": "https://raw.githubusercontent.com/3urobeat/steam-comment-service-bot/beta-testing/docs/wiki/creating_plugins.md", - "checksum": "11ea6f29f4c9591b6a00c637e4ab928b" + "checksum": "11b8d3b398f638581f260ff5cf64d95c" }, { "path": "docs/wiki/customlang_doc.md", From c8a8cb4e3651380c491a612526d3ae51121398d0 Mon Sep 17 00:00:00 2001 From: 3urobeat <35304405+3urobeat@users.noreply.github.com> Date: Thu, 2 May 2024 10:55:21 +0200 Subject: [PATCH 09/28] fix(Bot): Fix switchProxy not switching to proxy 0 --- src/bot/bot.js | 4 ++-- src/bot/helpers/handleRelog.js | 8 ++++---- src/data/fileStructure.json | 4 ++-- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/bot/bot.js b/src/bot/bot.js index c7f2043a..e0b1c0c3 100644 --- a/src/bot/bot.js +++ b/src/bot/bot.js @@ -4,7 +4,7 @@ * Created Date: 2021-07-09 16:26:00 * Author: 3urobeat * - * Last Modified: 2024-03-01 17:59:47 + * Last Modified: 2024-05-02 10:51:07 * Modified By: 3urobeat * * Copyright (c) 2021 - 2024 3urobeat @@ -286,7 +286,7 @@ Bot.prototype.handleLoginTimeout = function() {}; Bot.prototype.handleMissingGameLicenses = function() {}; /** - * Changes the proxy of this bot account and relogs it. + * Changes the proxy of this bot account. * @param {number} newProxyIndex Index of the new proxy inside the DataManager.proxies array. */ Bot.prototype.switchProxy = function(newProxyIndex) {}; // eslint-disable-line diff --git a/src/bot/helpers/handleRelog.js b/src/bot/helpers/handleRelog.js index a8664fbf..5c41a095 100644 --- a/src/bot/helpers/handleRelog.js +++ b/src/bot/helpers/handleRelog.js @@ -4,7 +4,7 @@ * Created Date: 2023-10-05 16:14:46 * Author: 3urobeat * - * Last Modified: 2024-03-08 11:48:23 + * Last Modified: 2024-05-02 10:54:36 * Modified By: 3urobeat * * Copyright (c) 2023 - 2024 3urobeat @@ -22,12 +22,12 @@ const Bot = require("../bot"); /** - * Changes the proxy of this bot account and relogs it. + * Changes the proxy of this bot account. * @param {number} newProxyIndex Index of the new proxy inside the DataManager.proxies array. */ Bot.prototype.switchProxy = function(newProxyIndex) { - if (!newProxyIndex) return new Error("newProxyIndex is undefined"); + if (newProxyIndex == undefined) return new Error("newProxyIndex is undefined"); // Explicitly check for undefined to prevent the value 0 from triggering this check logger("info", `[${this.logPrefix}] Switching proxy from ${this.loginData.proxyIndex} to ${newProxyIndex}. The bot account will relog in a moment...`); @@ -101,7 +101,7 @@ Bot.prototype.checkAndSwitchMyProxy = async function() { // Find proxy with least amount of associated bots let leastUsedProxy = activeProxies.reduce((a, b) => a.bots.length < b.bots.length ? a : b); - logger("warn", `[${this.logPrefix}] Failed to ping Steam using proxy ${this.loginData.proxyIndex}! Switched to proxy ${leastUsedProxy.proxyIndex} which currently has the least amount of usage and appears to be online.`); + logger("warn", `[${this.logPrefix}] Failed to ping Steam using proxy ${this.loginData.proxyIndex}! Switching to proxy ${leastUsedProxy.proxyIndex} which currently has the least amount of usage and appears to be online.`); // Switch proxy and relog, no need for handleRelog() to do something diff --git a/src/data/fileStructure.json b/src/data/fileStructure.json index face43c2..8ad1ee79 100644 --- a/src/data/fileStructure.json +++ b/src/data/fileStructure.json @@ -318,7 +318,7 @@ { "path": "src/bot/bot.js", "url": "https://raw.githubusercontent.com/3urobeat/steam-comment-service-bot/beta-testing/src/bot/bot.js", - "checksum": "bf91bc9deef102f02ff63522143f72f7" + "checksum": "fecb280b21cb7469ea5ff56827ce60de" }, { "path": "src/bot/events/debug.js", @@ -373,7 +373,7 @@ { "path": "src/bot/helpers/handleRelog.js", "url": "https://raw.githubusercontent.com/3urobeat/steam-comment-service-bot/beta-testing/src/bot/helpers/handleRelog.js", - "checksum": "3808cfde6f188582a539628ef4f5eb76" + "checksum": "e9197cd02697f19733c7e199ca783eeb" }, { "path": "src/bot/helpers/steamChatInteraction.js", From 7f6e337375148b454d292297510b5aaaf4533264 Mon Sep 17 00:00:00 2001 From: 3urobeat <35304405+3urobeat@users.noreply.github.com> Date: Thu, 2 May 2024 12:54:58 +0200 Subject: [PATCH 10/28] chore: Update deps and types --- package-lock.json | 457 +++++++++++++++--------------------- package.json | 8 +- src/data/fileStructure.json | 2 +- types/types.d.ts | 18 +- 4 files changed, 210 insertions(+), 275 deletions(-) diff --git a/package-lock.json b/package-lock.json index e6361e81..9c1bbe39 100644 --- a/package-lock.json +++ b/package-lock.json @@ -21,30 +21,21 @@ "steam-comment-bot-rest": "^1.2.1", "steam-comment-bot-webserver": "^1.0.1", "steam-session": "^1.7.2", - "steam-user": "^5.0.8", - "steamcommunity": "^3.48.2", + "steam-user": "^5.0.9", + "steamcommunity": "^3.48.3", "steamid": "^2.0.0", "steamid-resolver": "^1.3.4" }, "devDependencies": { - "eslint": "^8.57.0", - "eslint-plugin-jsdoc": "^48.2.1", + "eslint": "^9.1.1", + "eslint-plugin-jsdoc": "^48.2.3", "tsd-jsdoc": "^2.5.0" } }, - "node_modules/@aashutoshrathi/word-wrap": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz", - "integrity": "sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/@babel/parser": { - "version": "7.24.0", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.24.0.tgz", - "integrity": "sha512-QuP/FxEAzMSjXygs8v4N9dvdXzEHN4W1oF3PxuWAtPo08UdM17u89RDMgjLn/mlc56iM0HlLmVkO/wgR+rDgHg==", + "version": "7.24.5", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.24.5.tgz", + "integrity": "sha512-EOv5IK8arwh3LI47dz1b0tKUb/1uhHAnHJOrjgtQMIpu1uXd9mlFrJg9IUgGUgZ41Ch0K8REPTYpO7B76b4vJg==", "dev": true, "peer": true, "bin": { @@ -223,6 +214,18 @@ "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" } }, + "node_modules/@eslint-community/eslint-utils/node_modules/eslint-visitor-keys": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, "node_modules/@eslint-community/regexpp": { "version": "4.10.0", "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.10.0.tgz", @@ -233,15 +236,15 @@ } }, "node_modules/@eslint/eslintrc": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz", - "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.0.2.tgz", + "integrity": "sha512-wV19ZEGEMAC1eHgrS7UQPqsdEiCIbTKTasEfcXAigzoXICcqZSjBZEHlZwNVvKg6UBCjSlos84XiLqsRJnIcIg==", "dev": true, "dependencies": { "ajv": "^6.12.4", "debug": "^4.3.2", - "espree": "^9.6.0", - "globals": "^13.19.0", + "espree": "^10.0.1", + "globals": "^14.0.0", "ignore": "^5.2.0", "import-fresh": "^3.2.1", "js-yaml": "^4.1.0", @@ -249,19 +252,19 @@ "strip-json-comments": "^3.1.1" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "url": "https://opencollective.com/eslint" } }, "node_modules/@eslint/js": { - "version": "8.57.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.0.tgz", - "integrity": "sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g==", + "version": "9.1.1", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.1.1.tgz", + "integrity": "sha512-5WoDz3Y19Bg2BnErkZTp0en+c/i9PvgFS7MBe1+m60HjFr0hrphlAGp4yzI7pxpt4xShln4ZyYp4neJm8hmOkQ==", "dev": true, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" } }, "node_modules/@fastify/busboy": { @@ -273,12 +276,12 @@ } }, "node_modules/@humanwhocodes/config-array": { - "version": "0.11.14", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.14.tgz", - "integrity": "sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==", + "version": "0.13.0", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.13.0.tgz", + "integrity": "sha512-DZLEEqFWQFiyK6h5YIeynKx7JlvCYWL0cImfSRXZ9l4Sg2efkFGTuFf6vzXjK1cq6IYkU+Eg/JizXw+TD2vRNw==", "dev": true, "dependencies": { - "@humanwhocodes/object-schema": "^2.0.2", + "@humanwhocodes/object-schema": "^2.0.3", "debug": "^4.3.1", "minimatch": "^3.0.5" }, @@ -300,11 +303,24 @@ } }, "node_modules/@humanwhocodes/object-schema": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.2.tgz", - "integrity": "sha512-6EwiSjwWYP7pTckG6I5eyFANjPhmPjUX9JRLUSfNPC7FX7zK9gyZAfUEaECL6ALTpGX5AjnBq3C9XmVWPitNpw==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz", + "integrity": "sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==", "dev": true }, + "node_modules/@humanwhocodes/retry": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.2.3.tgz", + "integrity": "sha512-X38nUbachlb01YMlvPFojKoiXq+LzZvuSce70KPMPdeM1Rj03k4dR7lDslhbqXn3Ang4EU3+EAmwEAsbrjHW3g==", + "dev": true, + "engines": { + "node": ">=18.18" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, "node_modules/@nodelib/fs.scandir": { "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", @@ -404,15 +420,15 @@ } }, "node_modules/@sapphire/shapeshift": { - "version": "3.9.6", - "resolved": "https://registry.npmjs.org/@sapphire/shapeshift/-/shapeshift-3.9.6.tgz", - "integrity": "sha512-4+Na/fxu2SEepZRb9z0dbsVh59QtwPuBg/UVaDib3av7ZY14b14+z09z6QVn0P6Dv6eOU2NDTsjIi0mbtgP56g==", + "version": "3.9.7", + "resolved": "https://registry.npmjs.org/@sapphire/shapeshift/-/shapeshift-3.9.7.tgz", + "integrity": "sha512-4It2mxPSr4OGn4HSQWGmhFMsNFGfFVhWeRPCRwbH972Ek2pzfGRZtb0pJ4Ze6oIzcyh2jw7nUDa6qGlWofgd9g==", "dependencies": { "fast-deep-equal": "^3.1.3", "lodash": "^4.17.21" }, "engines": { - "node": ">=v18" + "node": ">=v16" } }, "node_modules/@sapphire/snowflake": { @@ -448,9 +464,9 @@ } }, "node_modules/@socket.io/component-emitter": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@socket.io/component-emitter/-/component-emitter-3.1.0.tgz", - "integrity": "sha512-+9jVqKhRSpsc591z5vX+X5Yyw+he/HCB4iQ/RYxw35CEPaY1gnsNE43nf9n9AaYjAQrTiI/mOwKUKdUs9vf7Xg==" + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@socket.io/component-emitter/-/component-emitter-3.1.2.tgz", + "integrity": "sha512-9BCxFwvbGg/RsZK9tjXd8s4UcwR0MWeFQ1XEKIQVVvAGJyINdrqKMcTRyLoK8Rse1GjzLV9cwjWV1olXRWEXVA==" }, "node_modules/@types/axios": { "version": "0.14.0", @@ -471,9 +487,9 @@ } }, "node_modules/@types/bytebuffer": { - "version": "5.0.48", - "resolved": "https://registry.npmjs.org/@types/bytebuffer/-/bytebuffer-5.0.48.tgz", - "integrity": "sha512-ormKm68NtTOtR8C/4jyRJEYbwKABXRkHHR/1fmkiuFbCQkltgtXSUGfldCSmJzvuyJvmBzWjBbOi79Ry/oJQug==", + "version": "5.0.49", + "resolved": "https://registry.npmjs.org/@types/bytebuffer/-/bytebuffer-5.0.49.tgz", + "integrity": "sha512-lV4YLiolMdD4upDmr4vnfiwV/FN9Jg33eNTSFMkHqyMKqTIAn5TmFTYsARwXwUXeFU7yzRpECmWV1SOhIvdkRQ==", "dependencies": { "@types/long": "^3.0.0", "@types/node": "*" @@ -517,9 +533,9 @@ } }, "node_modules/@types/express-serve-static-core": { - "version": "4.17.43", - "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.43.tgz", - "integrity": "sha512-oaYtiBirUOPQGSWNGPWnzyAFJ0BP3cwvN4oWZQY+zUBwpVIGsKUkpBpSztp74drYcjavs7SKFZ4DX1V2QeN8rg==", + "version": "4.19.0", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.19.0.tgz", + "integrity": "sha512-bGyep3JqPCRry1wq+O5n7oiBgGWmeIJXPjXXCo8EK0u8duZGSYar7cGqd3ML2JUsLGeB7fmc06KYo9fLGWqPvQ==", "dependencies": { "@types/node": "*", "@types/qs": "*", @@ -541,9 +557,9 @@ "integrity": "sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA==" }, "node_modules/@types/linkify-it": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/@types/linkify-it/-/linkify-it-3.0.5.tgz", - "integrity": "sha512-yg6E+u0/+Zjva+buc3EIb+29XEg4wltq7cSmd4Uc2EE/1nUVmxyzpX6gUXD0V8jIrG0r7YeOGVIbYRkxeooCtw==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@types/linkify-it/-/linkify-it-5.0.0.tgz", + "integrity": "sha512-sVDA58zAw4eWAffKOaQH5/5j3XeayukzDk+ewSsnv3p4yJEZHCCzMDiZM8e0OUrRvmpGZ85jf4yDHkHsgBNr9Q==", "dev": true, "peer": true }, @@ -564,9 +580,9 @@ } }, "node_modules/@types/mdurl": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/@types/mdurl/-/mdurl-1.0.5.tgz", - "integrity": "sha512-6L6VymKTzYSrEf4Nev4Xa1LCHKrlTlYCBMTlQKFuddo1CvQcE52I0mwfOJayueUC7MJuXOeHTcIU683lzd0cUA==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@types/mdurl/-/mdurl-2.0.0.tgz", + "integrity": "sha512-RGdgjQUZba5p6QEFAVx2OGb8rQDL/cPRG7GiedRzMcJ1tYnUANBncjbSB1NRGwbvjcPeikRABz2nshyPk1bhWg==", "dev": true, "peer": true }, @@ -576,17 +592,17 @@ "integrity": "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==" }, "node_modules/@types/node": { - "version": "20.11.25", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.11.25.tgz", - "integrity": "sha512-TBHyJxk2b7HceLVGFcpAUjsa5zIdsPWlR6XHfyGzd0SFu+/NFgQgMAl96MSDZgQDvJAvV6BKsFOrt6zIL09JDw==", + "version": "20.12.8", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.12.8.tgz", + "integrity": "sha512-NU0rJLJnshZWdE/097cdCBbyW1h4hEg0xpovcoAQYHl8dnEyp/NAOiE45pvc+Bd1Dt+2r94v2eGFpQJ4R7g+2w==", "dependencies": { "undici-types": "~5.26.4" } }, "node_modules/@types/qs": { - "version": "6.9.12", - "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.12.tgz", - "integrity": "sha512-bZcOkJ6uWrL0Qb2NAWKa7TBU+mJHPzhx9jjLL1KHF+XpzEcR7EXHvjbHlGtR/IsP1vyPrehuS6XqkmaePy//mg==" + "version": "6.9.15", + "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.15.tgz", + "integrity": "sha512-uXHQKES6DQKKCLh441Xv/dwxOq1TVS3JPUMlEqoEglvlhR6Mxnlew/Xq/LRVHpLyk7iK3zODe1qYHIMltO7XGg==" }, "node_modules/@types/range-parser": { "version": "1.2.7", @@ -627,13 +643,13 @@ } }, "node_modules/@types/serve-static": { - "version": "1.15.5", - "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.5.tgz", - "integrity": "sha512-PDRk21MnK70hja/YF8AHfC7yIsiQHn1rcXx7ijCFBX/k+XQJhQT/gw3xekXKJvx+5SXaMMS8oqQy09Mzvz2TuQ==", + "version": "1.15.7", + "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.7.tgz", + "integrity": "sha512-W8Ym+h8nhuRwaKPaDw34QUkwsGi6Rc4yYqvKFo5rm2FUEhCFbzVWrxXUxuKK8TASjWsysJY0nsmNCGhCOIsrOw==", "dependencies": { "@types/http-errors": "*", - "@types/mime": "*", - "@types/node": "*" + "@types/node": "*", + "@types/send": "*" } }, "node_modules/@types/steam-user": { @@ -680,12 +696,6 @@ "@types/node": "*" } }, - "node_modules/@ungap/structured-clone": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", - "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==", - "dev": true - }, "node_modules/@vladfrangu/async_event_emitter": { "version": "2.2.4", "resolved": "https://registry.npmjs.org/@vladfrangu/async_event_emitter/-/async_event_emitter-2.2.4.tgz", @@ -729,9 +739,9 @@ } }, "node_modules/adm-zip": { - "version": "0.5.10", - "resolved": "https://registry.npmjs.org/adm-zip/-/adm-zip-0.5.10.tgz", - "integrity": "sha512-x0HvcHqVJNTPk/Bw8JbLWlWoo6Wwnsug0fnYYro1HBrjxZ3G7/AZk7Ahv8JwDe1uIcz8eBqvu86FuF1POiG7vQ==", + "version": "0.5.12", + "resolved": "https://registry.npmjs.org/adm-zip/-/adm-zip-0.5.12.tgz", + "integrity": "sha512-6TVU49mK6KZb4qG6xWaaM4C7sA/sgUMLy/JYMOzkcp3BvVLpW0fXDFQiIzAuxFCt/2+xD7fNIiPFAoLZPhVNLQ==", "engines": { "node": ">=6.0" } @@ -880,11 +890,11 @@ "integrity": "sha512-NmWvPnx0F1SfrQbYwOi7OeaNGokp9XhzNioJ/CSBs8Qa4vxug81mhJEAVZwxXuBmYB5KDRfMq/F3RR0BIU7sWg==" }, "node_modules/axios": { - "version": "1.6.7", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.6.7.tgz", - "integrity": "sha512-/hDJGff6/c7u0hDkvkGxR/oy6CbCs8ziCsC7SqmhjfozqiJGc8Z11wrv9z9lYfY4K8l+H9TpjcMDX0xOZmx+RA==", + "version": "1.6.8", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.6.8.tgz", + "integrity": "sha512-v/ZHtJDU39mDpyBoFVkETcd/uNdxrWRrg3bKpOKzXFA6Bvqopts6ALSMU3y6ijYxbw2B+wPrIv46egTzJXCLGQ==", "dependencies": { - "follow-redirects": "^1.15.4", + "follow-redirects": "^1.15.6", "form-data": "^4.0.0", "proxy-from-env": "^1.1.0" } @@ -1417,9 +1427,9 @@ } }, "node_modules/cookie": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz", - "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==", + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.6.0.tgz", + "integrity": "sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==", "engines": { "node": ">= 0.6" } @@ -1801,18 +1811,6 @@ "node": ">=16.11.0" } }, - "node_modules/doctrine": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", - "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", - "dev": true, - "dependencies": { - "esutils": "^2.0.2" - }, - "engines": { - "node": ">=6.0.0" - } - }, "node_modules/dom-serializer": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz", @@ -2039,41 +2037,37 @@ } }, "node_modules/eslint": { - "version": "8.57.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.0.tgz", - "integrity": "sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ==", + "version": "9.1.1", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.1.1.tgz", + "integrity": "sha512-b4cRQ0BeZcSEzPpY2PjFY70VbO32K7BStTGtBsnIGdTSEEQzBi8hPBcGQmTG2zUvFr9uLe0TK42bw8YszuHEqg==", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.6.1", - "@eslint/eslintrc": "^2.1.4", - "@eslint/js": "8.57.0", - "@humanwhocodes/config-array": "^0.11.14", + "@eslint/eslintrc": "^3.0.2", + "@eslint/js": "9.1.1", + "@humanwhocodes/config-array": "^0.13.0", "@humanwhocodes/module-importer": "^1.0.1", + "@humanwhocodes/retry": "^0.2.3", "@nodelib/fs.walk": "^1.2.8", - "@ungap/structured-clone": "^1.2.0", "ajv": "^6.12.4", "chalk": "^4.0.0", "cross-spawn": "^7.0.2", "debug": "^4.3.2", - "doctrine": "^3.0.0", "escape-string-regexp": "^4.0.0", - "eslint-scope": "^7.2.2", - "eslint-visitor-keys": "^3.4.3", - "espree": "^9.6.1", + "eslint-scope": "^8.0.1", + "eslint-visitor-keys": "^4.0.0", + "espree": "^10.0.1", "esquery": "^1.4.2", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", - "file-entry-cache": "^6.0.1", + "file-entry-cache": "^8.0.0", "find-up": "^5.0.0", "glob-parent": "^6.0.2", - "globals": "^13.19.0", - "graphemer": "^1.4.0", "ignore": "^5.2.0", "imurmurhash": "^0.1.4", "is-glob": "^4.0.0", "is-path-inside": "^3.0.3", - "js-yaml": "^4.1.0", "json-stable-stringify-without-jsonify": "^1.0.1", "levn": "^0.4.1", "lodash.merge": "^4.6.2", @@ -2087,16 +2081,16 @@ "eslint": "bin/eslint.js" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "url": "https://opencollective.com/eslint" } }, "node_modules/eslint-plugin-jsdoc": { - "version": "48.2.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-48.2.1.tgz", - "integrity": "sha512-iUvbcyDZSO/9xSuRv2HQBw++8VkV/pt3UWtX9cpPH0l7GKPq78QC/6+PmyQHHvNZaTjAce6QVciEbnc6J/zH5g==", + "version": "48.2.3", + "resolved": "https://registry.npmjs.org/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-48.2.3.tgz", + "integrity": "sha512-r9DMAmFs66VNvNqRLLjHejdnJtILrt3xGi+Qx0op0oRfFGVpOR1Hb3BC++MacseHx93d8SKYPhyrC9BS7Os2QA==", "dev": true, "dependencies": { "@es-joy/jsdoccomment": "~0.42.0", @@ -2117,45 +2111,45 @@ } }, "node_modules/eslint-scope": { - "version": "7.2.2", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", - "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.0.1.tgz", + "integrity": "sha512-pL8XjgP4ZOmmwfFE8mEhSxA7ZY4C+LWyqjQ3o4yWkkmD0qcMT9kkW3zWHOczhWcjTSgqycYAgwSlXvZltv65og==", "dev": true, "dependencies": { "esrecurse": "^4.3.0", "estraverse": "^5.2.0" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "url": "https://opencollective.com/eslint" } }, "node_modules/eslint-visitor-keys": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", - "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.0.0.tgz", + "integrity": "sha512-OtIRv/2GyiF6o/d8K7MYKKbXrOUBIK6SfkIRM4Z0dY3w+LiQ0vy3F57m0Z71bjbyeiWFiHJ8brqnmE6H6/jEuw==", "dev": true, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "url": "https://opencollective.com/eslint" } }, "node_modules/espree": { - "version": "9.6.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", - "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-10.0.1.tgz", + "integrity": "sha512-MWkrWZbJsL2UwnjxTX3gG8FneachS/Mwg7tdGXce011sJd5b0JG54vat5KHnfSBODZ3Wvzd2WnjxyzsRoVv+ww==", "dev": true, "dependencies": { - "acorn": "^8.9.0", + "acorn": "^8.11.3", "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^3.4.1" + "eslint-visitor-keys": "^4.0.0" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "url": "https://opencollective.com/eslint" @@ -2226,16 +2220,16 @@ } }, "node_modules/express": { - "version": "4.18.3", - "resolved": "https://registry.npmjs.org/express/-/express-4.18.3.tgz", - "integrity": "sha512-6VyCijWQ+9O7WuVMTRBTl+cjNNIzD5cY5mQ1WM8r/LEkI2u8EYpOotESNwzNlyCn3g+dmjKYI6BmNneSr/FSRw==", + "version": "4.19.2", + "resolved": "https://registry.npmjs.org/express/-/express-4.19.2.tgz", + "integrity": "sha512-5T6nhjsT+EOMzuck8JjBHARTHfMht0POzlA60WV2pMD3gyXw2LZnZ+ueGdNxG+0calOJcWKbpFcuzLZ91YWq9Q==", "dependencies": { "accepts": "~1.3.8", "array-flatten": "1.1.1", "body-parser": "1.20.2", "content-disposition": "0.5.4", "content-type": "~1.0.4", - "cookie": "0.5.0", + "cookie": "0.6.0", "cookie-signature": "1.0.6", "debug": "2.6.9", "depd": "2.0.0", @@ -2346,9 +2340,9 @@ "dev": true }, "node_modules/fast-xml-parser": { - "version": "4.3.5", - "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-4.3.5.tgz", - "integrity": "sha512-sWvP1Pl8H03B8oFJpFR3HE31HUfwtX7Rlf9BNsvdpujD4n7WMhfmu8h9wOV2u+c1k0ZilTADhPqypzx2J690ZQ==", + "version": "4.3.6", + "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-4.3.6.tgz", + "integrity": "sha512-M2SovcRxD4+vC493Uc2GZVcZaj66CCJhWurC4viynVSTvrpErCShNcDz1lAho6n9REQKvL/ll4A4/fw6Y9z8nw==", "funding": [ { "type": "github", @@ -2384,15 +2378,15 @@ } }, "node_modules/file-entry-cache": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", - "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz", + "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==", "dev": true, "dependencies": { - "flat-cache": "^3.0.4" + "flat-cache": "^4.0.0" }, "engines": { - "node": "^10.12.0 || >=12.0.0" + "node": ">=16.0.0" } }, "node_modules/file-manager": { @@ -2490,17 +2484,16 @@ } }, "node_modules/flat-cache": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.2.0.tgz", - "integrity": "sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz", + "integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==", "dev": true, "dependencies": { "flatted": "^3.2.9", - "keyv": "^4.5.3", - "rimraf": "^3.0.2" + "keyv": "^4.5.4" }, "engines": { - "node": "^10.12.0 || >=12.0.0" + "node": ">=16" } }, "node_modules/flatted": { @@ -2510,9 +2503,9 @@ "dev": true }, "node_modules/follow-redirects": { - "version": "1.15.5", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.5.tgz", - "integrity": "sha512-vSFWUON1B+yAw1VN4xMfxgn5fTUiaOzAJCKBwIIgT/+7CuGy9+r+5gITvP62j3RmaD5Ph65UaERdOSRGUzZtgw==", + "version": "1.15.6", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.6.tgz", + "integrity": "sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==", "funding": [ { "type": "individual", @@ -2597,12 +2590,6 @@ "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==" }, - "node_modules/fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", - "dev": true - }, "node_modules/function-bind": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", @@ -2656,26 +2643,6 @@ "assert-plus": "^1.0.0" } }, - "node_modules/glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "dev": true, - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, "node_modules/glob-parent": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", @@ -2689,15 +2656,12 @@ } }, "node_modules/globals": { - "version": "13.24.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", - "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz", + "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==", "dev": true, - "dependencies": { - "type-fest": "^0.20.2" - }, "engines": { - "node": ">=8" + "node": ">=18" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" @@ -2762,12 +2726,6 @@ "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==" }, - "node_modules/graphemer": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", - "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", - "dev": true - }, "node_modules/har-schema": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", @@ -2865,9 +2823,9 @@ } }, "node_modules/hasown": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.1.tgz", - "integrity": "sha512-1/th4MHjnwncwXsIW6QMzlvYL9kG5e/CpVvLRZe4XPa8TOUNbCELqmvhDmnkNsAjwaG4+I8gJJL0JBvTTLO9qA==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", "dependencies": { "function-bind": "^1.1.2" }, @@ -3015,16 +2973,6 @@ "node": ">=0.8.19" } }, - "node_modules/inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", - "dev": true, - "dependencies": { - "once": "^1.3.0", - "wrappy": "1" - } - }, "node_modules/inherits": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", @@ -3813,17 +3761,17 @@ } }, "node_modules/optionator": { - "version": "0.9.3", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz", - "integrity": "sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==", + "version": "0.9.4", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", + "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", "dev": true, "dependencies": { - "@aashutoshrathi/word-wrap": "^1.2.3", "deep-is": "^0.1.3", "fast-levenshtein": "^2.0.6", "levn": "^0.4.1", "prelude-ls": "^1.2.1", - "type-check": "^0.4.0" + "type-check": "^0.4.0", + "word-wrap": "^1.2.5" }, "engines": { "node": ">= 0.8.0" @@ -3950,15 +3898,6 @@ "node": ">=8" } }, - "node_modules/path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/path-key": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", @@ -4335,21 +4274,6 @@ "node": ">=0.10.0" } }, - "node_modules/rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "dev": true, - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, "node_modules/run-parallel": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", @@ -4490,16 +4414,16 @@ "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==" }, "node_modules/set-function-length": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.1.tgz", - "integrity": "sha512-j4t6ccc+VsKwYHso+kElc5neZpjtq9EnRICFZtWyBsLojhmeF/ZBd/elqm22WJh/BziDe/SBiOeAt0m2mfLD0g==", + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", + "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", "dependencies": { - "define-data-property": "^1.1.2", + "define-data-property": "^1.1.4", "es-errors": "^1.3.0", "function-bind": "^1.1.2", - "get-intrinsic": "^1.2.3", + "get-intrinsic": "^1.2.4", "gopd": "^1.0.1", - "has-property-descriptors": "^1.0.1" + "has-property-descriptors": "^1.0.2" }, "engines": { "node": ">= 0.4" @@ -4556,9 +4480,9 @@ } }, "node_modules/socket.io": { - "version": "4.7.4", - "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-4.7.4.tgz", - "integrity": "sha512-DcotgfP1Zg9iP/dH9zvAQcWrE0TtbMVwXmlV4T4mqsvY+gw+LqUGPfx2AoVyRk0FLME+GQhufDMyacFmw7ksqw==", + "version": "4.7.5", + "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-4.7.5.tgz", + "integrity": "sha512-DmeAkF6cwM9jSfmp6Dr/5/mfMwb5Z5qRrSXLpo3Fq5SqyU8CMF15jIN4ZhfSwu35ksM1qmHZDQ/DK5XTccSTvA==", "dependencies": { "accepts": "~1.3.4", "base64id": "~2.0.0", @@ -4614,9 +4538,9 @@ } }, "node_modules/socks": { - "version": "2.8.1", - "resolved": "https://registry.npmjs.org/socks/-/socks-2.8.1.tgz", - "integrity": "sha512-B6w7tkwNid7ToxjZ08rQMT8M9BJAf8DKx8Ft4NivzH0zBUfd6jldGcisJn/RLgxcX3FPNDdNQCUEMMT79b+oCQ==", + "version": "2.8.3", + "resolved": "https://registry.npmjs.org/socks/-/socks-2.8.3.tgz", + "integrity": "sha512-l5x7VUUWbjVFbafGLxPWkYsHIhEvmF85tbIeFZWc8ZPtoMyybuEhL7Jye/ooC4/d48FgOjSJXgsF/AJPYCW8Zw==", "dependencies": { "ip-address": "^9.0.5", "smart-buffer": "^4.2.0" @@ -4875,9 +4799,9 @@ } }, "node_modules/steam-user": { - "version": "5.0.8", - "resolved": "https://registry.npmjs.org/steam-user/-/steam-user-5.0.8.tgz", - "integrity": "sha512-PPOgZr+YpiuqY2msvcxWoDpNm58E4HHs1yg0BS8w854qIn23jTqKk8U4wj9V1KS8pWs/JJ9BzgwIMLBzQ1g0zw==", + "version": "5.0.9", + "resolved": "https://registry.npmjs.org/steam-user/-/steam-user-5.0.9.tgz", + "integrity": "sha512-lV6K2cfr5AQzxf69U9nvJiqLbXT5N3HbwC8OyGZnD3v/ZFo8Vsk3j2RdrlS0lONuISGg/8l12uOG02EBAOhj9w==", "dependencies": { "@bbob/parser": "^2.2.0", "@doctormckay/stdlib": "^2.9.1", @@ -4901,9 +4825,9 @@ } }, "node_modules/steamcommunity": { - "version": "3.48.2", - "resolved": "https://registry.npmjs.org/steamcommunity/-/steamcommunity-3.48.2.tgz", - "integrity": "sha512-447UMw5KQpzZfAfo68qV6DWU0blNAhphDGnhbtCFG6GIE3fZdnD5uRIswMsmVZ+hnLvpks/+AWeZHguSTWjc6A==", + "version": "3.48.3", + "resolved": "https://registry.npmjs.org/steamcommunity/-/steamcommunity-3.48.3.tgz", + "integrity": "sha512-oSLz9oajRyn084ONrGCYzNKBmSoxt7VxNs01OhpT9dsDXA0sipMe2D4EktBMWmg8m8IS/ouMVbCi1LG+2j7qVw==", "dependencies": { "@doctormckay/user-agents": "^1.0.0", "async": "^2.6.3", @@ -5187,9 +5111,9 @@ "integrity": "sha512-ufKpbmrugz5Aou4wcr5Wc1UUFWOLhq+Fm6qa6P0w0K5Qw2yhaUoiWszhCVuNQyNwrlGiscHOmqYoAox1PtvgjA==" }, "node_modules/tsc-watch": { - "version": "6.0.4", - "resolved": "https://registry.npmjs.org/tsc-watch/-/tsc-watch-6.0.4.tgz", - "integrity": "sha512-cHvbvhjO86w2aGlaHgSCeQRl+Aqw6X6XN4sQMPZKF88GoP30O+oTuh5lRIJr5pgFWrRpF1AgXnJJ2DoFEIPHyg==", + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/tsc-watch/-/tsc-watch-6.2.0.tgz", + "integrity": "sha512-2LBhf9kjKXnz7KQ/puLHlozMzzUNHAdYBNMkg3eksQJ9GBAgMg8czznM83T5PmsoUvDnXzfIeQn2lNcIYDr8LA==", "dependencies": { "cross-spawn": "^7.0.3", "node-cleanup": "^2.1.2", @@ -5264,18 +5188,6 @@ "node": ">= 0.8.0" } }, - "node_modules/type-fest": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", - "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/type-is": { "version": "1.6.18", "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", @@ -5289,9 +5201,9 @@ } }, "node_modules/typescript": { - "version": "5.4.2", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.2.tgz", - "integrity": "sha512-+2/g0Fds1ERlP6JsakQQDXjZdZMM+rqpamFZJEKh4kwTIn3iDkgKtby0CeNd5ATNZ4Ry1ax15TMx0W2V+miizQ==", + "version": "5.4.5", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.5.tgz", + "integrity": "sha512-vcI4UpRgg81oIRUFwR0WSIHKt11nJ7SAVlYNIu+QpqeyXP+gpQJy/Z4+F0aGxSE4MqwjyXvW/TzgkLAx2AGHwQ==", "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -5477,15 +5389,15 @@ "integrity": "sha512-iBdZ57RDvnOR9AGBhML2vFZf7h8vmBjhoaZqODJBFWHVtKkDmKuHai3cx5PgVMrX5YDNp27AofYbAwctSS+vhQ==" }, "node_modules/which-typed-array": { - "version": "1.1.14", - "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.14.tgz", - "integrity": "sha512-VnXFiIW8yNn9kIHN88xvZ4yOWchftKDsRJ8fEPacX/wl1lOvBrhsJ/OeJCXq7B0AaijRuqgzSKalJoPk+D8MPg==", + "version": "1.1.15", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.15.tgz", + "integrity": "sha512-oV0jmFtUky6CXfkqehVvBP/LSWJ2sy4vWMioiENyJLePrBO/yKyV9OyJySfAKosh+RYkIl5zJCNZ8/4JncrpdA==", "dependencies": { - "available-typed-arrays": "^1.0.6", - "call-bind": "^1.0.5", + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.7", "for-each": "^0.3.3", "gopd": "^1.0.1", - "has-tostringtag": "^1.0.1" + "has-tostringtag": "^1.0.2" }, "engines": { "node": ">= 0.4" @@ -5494,6 +5406,15 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/word-wrap": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", + "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/wrap-ansi": { "version": "6.2.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", diff --git a/package.json b/package.json index 7d416c68..92727988 100644 --- a/package.json +++ b/package.json @@ -16,8 +16,8 @@ "steam-comment-bot-rest": "^1.2.1", "steam-comment-bot-webserver": "^1.0.1", "steam-session": "^1.7.2", - "steam-user": "^5.0.8", - "steamcommunity": "^3.48.2", + "steam-user": "^5.0.9", + "steamcommunity": "^3.48.3", "steamid": "^2.0.0", "steamid-resolver": "^1.3.4" }, @@ -35,8 +35,8 @@ "homepage": "https://github.com/3urobeat", "repository": "https://github.com/3urobeat/steam-comment-service-bot", "devDependencies": { - "eslint": "^8.57.0", - "eslint-plugin-jsdoc": "^48.2.1", + "eslint": "^9.1.1", + "eslint-plugin-jsdoc": "^48.2.3", "tsd-jsdoc": "^2.5.0" }, "types": "./types/types.d.ts" diff --git a/src/data/fileStructure.json b/src/data/fileStructure.json index 8ad1ee79..11dfb242 100644 --- a/src/data/fileStructure.json +++ b/src/data/fileStructure.json @@ -848,7 +848,7 @@ { "path": "types/types.d.ts", "url": "https://raw.githubusercontent.com/3urobeat/steam-comment-service-bot/beta-testing/types/types.d.ts", - "checksum": "582a964870623eb4ca6f68fcc4ab6570" + "checksum": "06b9211181ac917533ce3917b20926fc" } ] } \ No newline at end of file diff --git a/types/types.d.ts b/types/types.d.ts index b1b4df8f..96c64778 100644 --- a/types/types.d.ts +++ b/types/types.d.ts @@ -93,7 +93,7 @@ declare class Bot { */ handleMissingGameLicenses(): void; /** - * Changes the proxy of this bot account and relogs it. + * Changes the proxy of this bot account. * @param newProxyIndex - Index of the new proxy inside the DataManager.proxies array. */ switchProxy(newProxyIndex: number): void; @@ -169,7 +169,7 @@ declare class Bot { */ handleMissingGameLicenses(): void; /** - * Changes the proxy of this bot account and relogs it. + * Changes the proxy of this bot account. * @param newProxyIndex - Index of the new proxy inside the DataManager.proxies array. */ switchProxy(newProxyIndex: number): void; @@ -601,6 +601,12 @@ declare class Controller { * @param submitCode - Function to submit a code. Pass an empty string to skip the account. */ _steamGuardInputEvent(bot: Bot, submitCode: (...params: any[]) => any): void; + /** + * Emits steamGuardQrCode event for bot & plugins + * @param bot - Bot instance of the affected account + * @param challengeUrl - The QrCode Challenge URL supplied by Steam. Display this value using a QR-Code parser and let a user scan it using their Steam Mobile App. + */ + _steamGuardQrCodeEvent(bot: Bot, challengeUrl: string): void; /** * Check if all friends are in lastcomment database * @param bot - Bot object of the account to check @@ -676,6 +682,12 @@ declare class Controller { * @param submitCode - Function to submit a code. Pass an empty string to skip the account. */ _steamGuardInputEvent(bot: Bot, submitCode: (...params: any[]) => any): void; + /** + * Emits steamGuardQrCode event for bot & plugins + * @param bot - Bot instance of the affected account + * @param challengeUrl - The QrCode Challenge URL supplied by Steam. Display this value using a QR-Code parser and let a user scan it using their Steam Mobile App. + */ + _steamGuardQrCodeEvent(bot: Bot, challengeUrl: string): void; /** * Check if all friends are in lastcomment database * @param bot - Bot object of the account to check @@ -1392,6 +1404,7 @@ declare function loadPlugin(pluginName: string): any; * @property ready - Controller ready event * @property statusUpdate - Controller statusUpdate event * @property steamGuardInput - Controller steamGuardInput event + * @property steamGuardQrCode - Controller steamGuardQrCode event */ declare type Plugin = { load: (...params: any[]) => any; @@ -1399,6 +1412,7 @@ declare type Plugin = { ready: (...params: any[]) => any; statusUpdate: (...params: any[]) => any; steamGuardInput: (...params: any[]) => any; + steamGuardQrCode: (...params: any[]) => any; }; /** From 92a661cf1e391e149a1236c5b48ffe64596b6b42 Mon Sep 17 00:00:00 2001 From: 3urobeat <35304405+3urobeat@users.noreply.github.com> Date: Fri, 3 May 2024 13:11:05 +0200 Subject: [PATCH 11/28] feat: Migrate eslint config for v9 --- .eslintrc.json | 67 ---------------- eslint.config.mjs | 90 ++++++++++++++++++++++ package-lock.json | 1 + package.json | 1 + src/bot/bot.js | 4 +- src/commands/core/comment.js | 4 +- src/commands/core/system.js | 4 +- src/commands/helpers/getMiscArgs.js | 4 +- src/commands/helpers/handleCommentSkips.js | 6 +- src/commands/helpers/handleFollowErrors.js | 6 +- src/commands/helpers/handleMiscErrors.js | 4 +- src/controller/controller.js | 6 +- src/controller/events/statusUpdate.js | 4 +- src/data/fileStructure.json | 44 +++++------ src/dataManager/dataCheck.js | 4 +- src/dataManager/helpers/repairFile.js | 8 +- src/pluginSystem/loadPlugins.js | 3 +- src/sessions/sessionHandler.js | 4 +- src/starter.js | 8 +- src/updater/helpers/prepareUpdate.js | 8 +- src/updater/helpers/restoreBackup.js | 6 +- start.js | 6 +- 22 files changed, 158 insertions(+), 134 deletions(-) delete mode 100644 .eslintrc.json create mode 100644 eslint.config.mjs diff --git a/.eslintrc.json b/.eslintrc.json deleted file mode 100644 index 7d832ed8..00000000 --- a/.eslintrc.json +++ /dev/null @@ -1,67 +0,0 @@ -{ - /* - 3urobeat's EsLint Config. Requires eslint & eslint-plugin-jsdoc to be installed as devDependencies. - https://github.com/3urobeat - */ - - "env": { - "commonjs": true, - "es6": true, - "node": true - }, - "extends": "eslint:recommended", - "globals": { - "Atomics": "readonly", - "SharedArrayBuffer": "readonly", - - "started": true, - "srcdir": true, - "botisloggedin": true, - "logger": true, - "extdata": true - }, - "parserOptions": { - "ecmaVersion": 11 - }, - "plugins": [ - "jsdoc" - ], - "rules": { - "no-var": "error", - "no-redeclare": "off", - "no-unreachable": "error", - "no-unexpected-multiline": "error", - - // Styling - "camelcase": "warn", - "capitalized-comments": ["warn", "always", { "ignoreConsecutiveComments": true }], - "comma-spacing": ["warn", { "before": false, "after": true }], - "func-call-spacing": ["error", "never"], - "indent": ["error", 4, { "ignoredNodes": ["IfStatement"], "SwitchCase": 1 }], // TODO: This also ignores if statements with wrong indentation but I couldn't get it to only ignore else in if-else one-liner - "no-tabs": "error", - "no-trailing-spaces": "error", - "no-extra-semi": "error", - "semi": ["error", "always"], - "semi-spacing": "error", - "semi-style": ["error", "last"], - "quotes": ["error", "double", { "avoidEscape": true }], - "spaced-comment": "warn", - - // JsDoc - https://github.com/gajus/eslint-plugin-jsdoc - "jsdoc/check-alignment": "warn", - "jsdoc/check-indentation": "warn", - "jsdoc/check-types": "warn", - "jsdoc/informative-docs": "warn", - "jsdoc/require-asterisk-prefix": "warn", - "jsdoc/require-description": "warn", - "jsdoc/require-jsdoc": "warn", - "jsdoc/require-param": "warn", - "jsdoc/require-param-name": "warn", - "jsdoc/valid-types": "warn", - //"jsdoc/require-returns": "warn", // Always requires @return, even when function does not return something - "jsdoc/require-returns-type": "warn", - //"jsdoc/require-returns-check": "warn", // Unnecessary when require-returns above is disabled - "jsdoc/require-returns-description": "warn" - }, - "ignorePatterns": ["src/libraryPatches/*"] -} \ No newline at end of file diff --git a/eslint.config.mjs b/eslint.config.mjs new file mode 100644 index 00000000..ac9a12ce --- /dev/null +++ b/eslint.config.mjs @@ -0,0 +1,90 @@ +/* + * File: eslint.config.mjs + * Project: steam-comment-service-bot + * Created Date: 2024-05-03 12:17:16 + * Author: 3urobeat + * + * Last Modified: 2024-05-03 12:58:49 + * Modified By: 3urobeat + * + * Copyright (c) 2024 3urobeat + * + * This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. + * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + * You should have received a copy of the GNU General Public License along with this program. If not, see . + */ + + +/* + 3urobeat's EsLint Config. Requires eslint, @eslint/js & eslint-plugin-jsdoc to be installed as devDependencies. + https://github.com/3urobeat +*/ + +import globals from "globals"; +import jsdoc from "eslint-plugin-jsdoc"; +import js from "@eslint/js"; + + +export default [ + { + ignores: ["src/libraryPatches/*"], + }, + js.configs.recommended, // Import recommended eslint rules + { + languageOptions: { + ecmaVersion: 2022, + sourceType: "module", + globals: { + ...globals.commonjs, + ...globals.es6, + ...globals.node, + + started: true, + srcdir: true, + botisloggedin: true, + logger: true, + extdata: true + } + }, + plugins: { + jsdoc: jsdoc + }, + rules: { + "no-var": "error", + "no-redeclare": "off", + "no-unreachable": "error", + "no-unexpected-multiline": "error", + + // Styling + "camelcase": "warn", + "capitalized-comments": ["warn", "always", { "ignoreConsecutiveComments": true }], + "comma-spacing": ["warn", { "before": false, "after": true }], + "func-call-spacing": ["error", "never"], + "indent": ["error", 4, { "ignoredNodes": ["IfStatement"], "SwitchCase": 1 }], // TODO: This also ignores if statements with wrong indentation but I couldn't get it to only ignore else in if-else one-liner + "no-tabs": "error", + "no-trailing-spaces": "error", + "no-extra-semi": "error", + "semi": ["error", "always"], + "semi-spacing": "error", + "semi-style": ["error", "last"], + "quotes": ["error", "double", { "avoidEscape": true }], + "spaced-comment": "warn", + + // JsDoc - https://github.com/gajus/eslint-plugin-jsdoc + "jsdoc/check-alignment": "warn", + "jsdoc/check-indentation": "warn", + "jsdoc/check-types": "warn", + "jsdoc/informative-docs": "warn", + "jsdoc/require-asterisk-prefix": "warn", + "jsdoc/require-description": "warn", + "jsdoc/require-jsdoc": "warn", + "jsdoc/require-param": "warn", + "jsdoc/require-param-name": "warn", + "jsdoc/valid-types": "warn", + // "jsdoc/require-returns": "warn", // Always requires @return, even when function does not return something + "jsdoc/require-returns-type": "warn", + // "jsdoc/require-returns-check": "warn", // Unnecessary when require-returns above is disabled + "jsdoc/require-returns-description": "warn" + } + } +]; diff --git a/package-lock.json b/package-lock.json index 9c1bbe39..b77f1913 100644 --- a/package-lock.json +++ b/package-lock.json @@ -27,6 +27,7 @@ "steamid-resolver": "^1.3.4" }, "devDependencies": { + "@eslint/js": "^9.1.1", "eslint": "^9.1.1", "eslint-plugin-jsdoc": "^48.2.3", "tsd-jsdoc": "^2.5.0" diff --git a/package.json b/package.json index 92727988..03262a59 100644 --- a/package.json +++ b/package.json @@ -35,6 +35,7 @@ "homepage": "https://github.com/3urobeat", "repository": "https://github.com/3urobeat/steam-comment-service-bot", "devDependencies": { + "@eslint/js": "^9.1.1", "eslint": "^9.1.1", "eslint-plugin-jsdoc": "^48.2.3", "tsd-jsdoc": "^2.5.0" diff --git a/src/bot/bot.js b/src/bot/bot.js index e0b1c0c3..e2bbdb31 100644 --- a/src/bot/bot.js +++ b/src/bot/bot.js @@ -4,7 +4,7 @@ * Created Date: 2021-07-09 16:26:00 * Author: 3urobeat * - * Last Modified: 2024-05-02 10:51:07 + * Last Modified: 2024-05-03 12:46:26 * Modified By: 3urobeat * * Copyright (c) 2021 - 2024 3urobeat @@ -133,7 +133,7 @@ const Bot = function(controller, index) { require("../libraryPatches/CSteamReviews.js"); require("../libraryPatches/reviews.js"); - if (global.checkm8!="b754jfJNgZWGnzogvl @@ -279,7 +279,7 @@ async function comment(commandHandler, resInfo, respond, postComment, commentArg // Comment numberOfComments times using our syncLoop helper - syncLoop(activeReqEntry.amount - (activeReqEntry.thisIteration + 1), (loop, i) => { // eslint-disable-line no-unused-vars + syncLoop(activeReqEntry.amount - (activeReqEntry.thisIteration + 1), (loop, i) => { setTimeout(async () => { diff --git a/src/commands/core/system.js b/src/commands/core/system.js index e09b8f6e..7ed6568c 100644 --- a/src/commands/core/system.js +++ b/src/commands/core/system.js @@ -4,7 +4,7 @@ * Created Date: 2021-07-09 16:26:00 * Author: 3urobeat * - * Last Modified: 2024-02-11 17:03:32 + * Last Modified: 2024-05-03 13:08:52 * Modified By: 3urobeat * * Copyright (c) 2021 - 2024 3urobeat @@ -233,7 +233,7 @@ module.exports.eval = { return; } - const clean = text => { // eslint-disable-line no-case-declarations + const clean = text => { if (typeof(text) === "string") return text.replace(/`/g, "`" + String.fromCharCode(8203)).replace(/@/g, "@" + String.fromCharCode(8203)); else return text; }; diff --git a/src/commands/helpers/getMiscArgs.js b/src/commands/helpers/getMiscArgs.js index 5035f72b..65fcab38 100644 --- a/src/commands/helpers/getMiscArgs.js +++ b/src/commands/helpers/getMiscArgs.js @@ -4,7 +4,7 @@ * Created Date: 2023-05-28 12:18:49 * Author: 3urobeat * - * Last Modified: 2024-02-22 17:51:02 + * Last Modified: 2024-05-03 13:08:06 * Modified By: 3urobeat * * Copyright (c) 2023 - 2024 3urobeat @@ -60,7 +60,7 @@ module.exports.getMiscArgs = (commandHandler, args, cmd, resInfo, respond) => { } // Process input and check if ID is valid - commandHandler.controller.handleSteamIdResolving(args[1], null, async (err, destParam, idType) => { // eslint-disable-line no-unused-vars + commandHandler.controller.handleSteamIdResolving(args[1], null, async (err, destParam, idType) => { logger("debug", `CommandHandler getMiscArgs() success. amount: ${amount} | dest: ${destParam}`); resolve({ diff --git a/src/commands/helpers/handleCommentSkips.js b/src/commands/helpers/handleCommentSkips.js index eeab63fb..e4486b64 100644 --- a/src/commands/helpers/handleCommentSkips.js +++ b/src/commands/helpers/handleCommentSkips.js @@ -4,10 +4,10 @@ * Created Date: 2022-02-28 12:22:48 * Author: 3urobeat * - * Last Modified: 2023-12-27 14:04:37 + * Last Modified: 2024-05-03 13:08:38 * Modified By: 3urobeat * - * Copyright (c) 2022 - 2023 3urobeat + * Copyright (c) 2022 - 2024 3urobeat * * This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. @@ -15,7 +15,7 @@ */ -const Bot = require("../../bot/bot.js"); // eslint-disable-line +const Bot = require("../../bot/bot.js"); const CommandHandler = require("../commandHandler.js"); // eslint-disable-line diff --git a/src/commands/helpers/handleFollowErrors.js b/src/commands/helpers/handleFollowErrors.js index 782d0cef..0d268861 100644 --- a/src/commands/helpers/handleFollowErrors.js +++ b/src/commands/helpers/handleFollowErrors.js @@ -4,10 +4,10 @@ * Created Date: 2023-09-24 22:57:21 * Author: 3urobeat * - * Last Modified: 2023-12-27 14:04:20 + * Last Modified: 2024-05-03 13:07:57 * Modified By: 3urobeat * - * Copyright (c) 2023 3urobeat + * Copyright (c) 2023 - 2024 3urobeat * * This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. @@ -15,7 +15,7 @@ */ -const Bot = require("../../bot/bot.js"); // eslint-disable-line +const Bot = require("../../bot/bot.js"); /** diff --git a/src/commands/helpers/handleMiscErrors.js b/src/commands/helpers/handleMiscErrors.js index 9b07a88a..ce1f30ba 100644 --- a/src/commands/helpers/handleMiscErrors.js +++ b/src/commands/helpers/handleMiscErrors.js @@ -4,7 +4,7 @@ * Created Date: 2023-05-31 16:57:21 * Author: 3urobeat * - * Last Modified: 2024-02-20 17:19:26 + * Last Modified: 2024-05-03 13:07:47 * Modified By: 3urobeat * * Copyright (c) 2023 - 2024 3urobeat @@ -15,7 +15,7 @@ */ -const Bot = require("../../bot/bot.js"); // eslint-disable-line +const Bot = require("../../bot/bot.js"); /** diff --git a/src/controller/controller.js b/src/controller/controller.js index c858b395..dea4d1f8 100644 --- a/src/controller/controller.js +++ b/src/controller/controller.js @@ -4,7 +4,7 @@ * Created Date: 2021-07-09 16:26:00 * Author: 3urobeat * - * Last Modified: 2024-05-01 15:19:41 + * Last Modified: 2024-05-03 13:07:40 * Modified By: 3urobeat * * Copyright (c) 2021 - 2024 3urobeat @@ -53,7 +53,7 @@ const Controller = function() { * @param {number} timestamp UNIX timestamp to convert * @returns {string} "x seconds/minutes/hours/days" */ - timeToString: () => {}, // eslint-disable-line + timeToString: () => {}, /** * Pings a *https* URL to check if the service and this internet connection is working @@ -541,4 +541,4 @@ Controller.prototype._loggerOptionsUpdateAfterConfigLoad = function(advancedconf /** * Internal: Logs all held back messages from logAfterReady array */ -Controller.prototype._loggerLogAfterReady = function() {}; // eslint-disable-line +Controller.prototype._loggerLogAfterReady = function() {}; diff --git a/src/controller/events/statusUpdate.js b/src/controller/events/statusUpdate.js index 9109d8bf..df34c7d0 100644 --- a/src/controller/events/statusUpdate.js +++ b/src/controller/events/statusUpdate.js @@ -4,7 +4,7 @@ * Created Date: 2023-03-30 21:05:13 * Author: 3urobeat * - * Last Modified: 2024-03-08 17:49:26 + * Last Modified: 2024-05-03 13:00:59 * Modified By: 3urobeat * * Copyright (c) 2023 - 2024 3urobeat @@ -15,7 +15,7 @@ */ -const Bot = require("../../bot/bot.js"); // eslint-disable-line +const Bot = require("../../bot/bot.js"); const Controller = require("../controller"); diff --git a/src/data/fileStructure.json b/src/data/fileStructure.json index 11dfb242..441d2927 100644 --- a/src/data/fileStructure.json +++ b/src/data/fileStructure.json @@ -1,10 +1,5 @@ { "files": [ - { - "path": ".eslintrc.json", - "url": "https://raw.githubusercontent.com/3urobeat/steam-comment-service-bot/beta-testing/.eslintrc.json", - "checksum": "982f55cc4c53137135b87df43bbfe9c8" - }, { "path": ".github/FUNDING.yml", "url": "https://raw.githubusercontent.com/3urobeat/steam-comment-service-bot/beta-testing/.github/FUNDING.yml", @@ -285,6 +280,11 @@ "url": "https://raw.githubusercontent.com/3urobeat/steam-comment-service-bot/beta-testing/docs/wiki/version_changelogs.md", "checksum": "608963ede0ef27d65adcb294666812d3" }, + { + "path": "eslint.config.mjs", + "url": "https://raw.githubusercontent.com/3urobeat/steam-comment-service-bot/beta-testing/eslint.config.mjs", + "checksum": "390ba7cd47f19e134891ad93f9e42918" + }, { "path": "scripts/README.md", "url": "https://raw.githubusercontent.com/3urobeat/steam-comment-service-bot/beta-testing/scripts/README.md", @@ -318,7 +318,7 @@ { "path": "src/bot/bot.js", "url": "https://raw.githubusercontent.com/3urobeat/steam-comment-service-bot/beta-testing/src/bot/bot.js", - "checksum": "fecb280b21cb7469ea5ff56827ce60de" + "checksum": "97b6b1fb055bd3a19c11bbe68147b8c5" }, { "path": "src/bot/events/debug.js", @@ -393,7 +393,7 @@ { "path": "src/commands/core/comment.js", "url": "https://raw.githubusercontent.com/3urobeat/steam-comment-service-bot/beta-testing/src/commands/core/comment.js", - "checksum": "99ec8c17453e2a055028df6024911c56" + "checksum": "c2b6ae8c06b983194d100754c65ccb61" }, { "path": "src/commands/core/favorite.js", @@ -433,7 +433,7 @@ { "path": "src/commands/core/system.js", "url": "https://raw.githubusercontent.com/3urobeat/steam-comment-service-bot/beta-testing/src/commands/core/system.js", - "checksum": "ae3a4efd8a7230c45211f8f80adb25c6" + "checksum": "f32dc19d1466840cce5ecc7703b4c569" }, { "path": "src/commands/core/vote.js", @@ -468,7 +468,7 @@ { "path": "src/commands/helpers/getMiscArgs.js", "url": "https://raw.githubusercontent.com/3urobeat/steam-comment-service-bot/beta-testing/src/commands/helpers/getMiscArgs.js", - "checksum": "488803b1fe38671e2f0d339a9c692db5" + "checksum": "9d36d31af5fa1930d4d16cefe026bfc2" }, { "path": "src/commands/helpers/getVoteBots.js", @@ -478,22 +478,22 @@ { "path": "src/commands/helpers/handleCommentSkips.js", "url": "https://raw.githubusercontent.com/3urobeat/steam-comment-service-bot/beta-testing/src/commands/helpers/handleCommentSkips.js", - "checksum": "8279c8a9a1d624f2212050b5b98cbca2" + "checksum": "65c29b579867daa47fb59dc921c17827" }, { "path": "src/commands/helpers/handleFollowErrors.js", "url": "https://raw.githubusercontent.com/3urobeat/steam-comment-service-bot/beta-testing/src/commands/helpers/handleFollowErrors.js", - "checksum": "18054a4221e795a8c5530b5a55a014ae" + "checksum": "f0901c92f89131bec0c990c0d1b553ae" }, { "path": "src/commands/helpers/handleMiscErrors.js", "url": "https://raw.githubusercontent.com/3urobeat/steam-comment-service-bot/beta-testing/src/commands/helpers/handleMiscErrors.js", - "checksum": "9a48943369e29712e578e9b363d98545" + "checksum": "8069eda53d2ce41b38aeded139a80904" }, { "path": "src/controller/controller.js", "url": "https://raw.githubusercontent.com/3urobeat/steam-comment-service-bot/beta-testing/src/controller/controller.js", - "checksum": "fd28817485832dadb454cef17b782c51" + "checksum": "a55c0f566ada510e247bd9d45322279b" }, { "path": "src/controller/events/ready.js", @@ -503,7 +503,7 @@ { "path": "src/controller/events/statusUpdate.js", "url": "https://raw.githubusercontent.com/3urobeat/steam-comment-service-bot/beta-testing/src/controller/events/statusUpdate.js", - "checksum": "5a7c66ae19eb320bacf6d2c2abeba9d6" + "checksum": "fa1f97966de3948e186e025ce13c1495" }, { "path": "src/controller/events/steamGuardInput.js", @@ -588,7 +588,7 @@ { "path": "src/dataManager/dataCheck.js", "url": "https://raw.githubusercontent.com/3urobeat/steam-comment-service-bot/beta-testing/src/dataManager/dataCheck.js", - "checksum": "12dce4d35da119566ef427ab5b6d49c5" + "checksum": "924a09d6c37e985f58a94335b2dfdc9d" }, { "path": "src/dataManager/dataExport.js", @@ -653,7 +653,7 @@ { "path": "src/dataManager/helpers/repairFile.js", "url": "https://raw.githubusercontent.com/3urobeat/steam-comment-service-bot/beta-testing/src/dataManager/helpers/repairFile.js", - "checksum": "283942ba224a393abde0980f7ab3ef63" + "checksum": "94a83348ebe8e20c70d5c16cf77f8689" }, { "path": "src/jobs/jobManager.js", @@ -713,7 +713,7 @@ { "path": "src/pluginSystem/loadPlugins.js", "url": "https://raw.githubusercontent.com/3urobeat/steam-comment-service-bot/beta-testing/src/pluginSystem/loadPlugins.js", - "checksum": "a2889cdf46fa8876a767ab272356b3f9" + "checksum": "035ff994c7c3c3b13009f74bea2b390c" }, { "path": "src/pluginSystem/pluginSystem.js", @@ -743,12 +743,12 @@ { "path": "src/sessions/sessionHandler.js", "url": "https://raw.githubusercontent.com/3urobeat/steam-comment-service-bot/beta-testing/src/sessions/sessionHandler.js", - "checksum": "1138f9e889c9f4789b4c7f39766a486a" + "checksum": "6c09b6570a353148cd222757f3592118" }, { "path": "src/starter.js", "url": "https://raw.githubusercontent.com/3urobeat/steam-comment-service-bot/beta-testing/src/starter.js", - "checksum": "b106db2dbc61e544e8f1eb37cba99d69" + "checksum": "49fb8d6713e069dddade6761a1ba03bc" }, { "path": "src/updater/compatibility/2060.js", @@ -828,12 +828,12 @@ { "path": "src/updater/helpers/prepareUpdate.js", "url": "https://raw.githubusercontent.com/3urobeat/steam-comment-service-bot/beta-testing/src/updater/helpers/prepareUpdate.js", - "checksum": "eea0c957cfb4f73c15a0fdd78f6e9a68" + "checksum": "5acced2a4a6accfcfdd9a5a0d3ea5259" }, { "path": "src/updater/helpers/restoreBackup.js", "url": "https://raw.githubusercontent.com/3urobeat/steam-comment-service-bot/beta-testing/src/updater/helpers/restoreBackup.js", - "checksum": "02224a065b6b3cf13558e13c487511a3" + "checksum": "aee115164a1dd4bd9842af5644094e3b" }, { "path": "src/updater/updater.js", @@ -843,7 +843,7 @@ { "path": "start.js", "url": "https://raw.githubusercontent.com/3urobeat/steam-comment-service-bot/beta-testing/start.js", - "checksum": "afc9710e045984455ca0936fec484f1a" + "checksum": "3a2434b53fdb63ce224c0dfdfd7df04c" }, { "path": "types/types.d.ts", diff --git a/src/dataManager/dataCheck.js b/src/dataManager/dataCheck.js index 2a04b6dc..32104387 100644 --- a/src/dataManager/dataCheck.js +++ b/src/dataManager/dataCheck.js @@ -4,7 +4,7 @@ * Created Date: 2021-07-09 16:26:00 * Author: 3urobeat * - * Last Modified: 2024-05-01 13:38:35 + * Last Modified: 2024-05-03 13:00:04 * Modified By: 3urobeat * * Copyright (c) 2023 - 2024 3urobeat @@ -110,7 +110,7 @@ DataManager.prototype.checkData = function() { logWarn("warn", `You've set an invalid value '${this.advancedconfig.onlineStatus}' as 'onlineStatus' in 'advancedconfig.json'! Defaulting to 'Online'...`); this.advancedconfig.onlineStatus = "Online"; } - if (!EPersonaState[this.advancedconfig.childAccOnlineStatus] == undefined) { // Explicitly check for undefined because Offline (0) resolves to false + if (EPersonaState[this.advancedconfig.childAccOnlineStatus] != undefined) { // Explicitly check for undefined because Offline (0) resolves to false logWarn("warn", `You've set an invalid value '${this.advancedconfig.childAccOnlineStatus}' as 'childAccOnlineStatus' in 'advancedconfig.json'! Defaulting to 'Online'...`); this.advancedconfig.childAccOnlineStatus = "Online"; } diff --git a/src/dataManager/helpers/repairFile.js b/src/dataManager/helpers/repairFile.js index afe81c9e..fec2863a 100644 --- a/src/dataManager/helpers/repairFile.js +++ b/src/dataManager/helpers/repairFile.js @@ -4,10 +4,10 @@ * Created Date: 2023-03-22 12:35:01 * Author: 3urobeat * - * Last Modified: 2023-12-27 14:13:14 + * Last Modified: 2024-05-03 12:59:23 * Modified By: 3urobeat * - * Copyright (c) 2023 3urobeat + * Copyright (c) 2023 - 2024 3urobeat * * This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. @@ -43,7 +43,7 @@ DataManager.prototype._restoreBackup = function(name, filepath, cacheentry, onli .replace(/\]"/g, "]") .replace(/\\"/g, '"') .replace(/""/g, '""'); - } catch (err) { + } catch { stringified = JSON.stringify(cacheentry, null, 4); } @@ -63,7 +63,7 @@ DataManager.prototype._restoreBackup = function(name, filepath, cacheentry, onli logger("info", `Successfully restored backup of '${name}'!\n`, true); resolve(require(filepath)); - } catch (err) { // Worst case, even the backup seems to be broken (seems like this can't happen anymore since 2.11 because cache.json will get cleared before we get here if it contains an error) + } catch { // Worst case, even the backup seems to be broken (seems like this can't happen anymore since 2.11 because cache.json will get cleared before we get here if it contains an error) this._pullNewFile(name, filepath, resolve); } diff --git a/src/pluginSystem/loadPlugins.js b/src/pluginSystem/loadPlugins.js index 2bc71bdc..06d4ed80 100644 --- a/src/pluginSystem/loadPlugins.js +++ b/src/pluginSystem/loadPlugins.js @@ -4,7 +4,7 @@ * Created Date: 2023-06-04 15:37:17 * Author: DerDeathraven * - * Last Modified: 2024-05-01 14:54:49 + * Last Modified: 2024-05-03 12:52:12 * Modified By: 3urobeat * * Copyright (c) 2023 - 2024 3urobeat @@ -153,7 +153,6 @@ PluginSystem.prototype._loadPlugins = async function () { // Call the exposed event functions if they exist Object.entries(PLUGIN_EVENTS).forEach(([eventName, event]) => { // eslint-disable-line no-unused-vars - // eslint-disable-line this.controller.events.on(event, (...args) => pluginInstance[event]?.call(pluginInstance, ...args)); }); } diff --git a/src/sessions/sessionHandler.js b/src/sessions/sessionHandler.js index 37e4d2d4..52ec74d4 100644 --- a/src/sessions/sessionHandler.js +++ b/src/sessions/sessionHandler.js @@ -4,7 +4,7 @@ * Created Date: 2022-10-09 12:47:27 * Author: 3urobeat * - * Last Modified: 2024-02-28 22:31:15 + * Last Modified: 2024-05-03 12:51:51 * Modified By: 3urobeat * * Copyright (c) 2022 - 2024 3urobeat @@ -15,7 +15,7 @@ */ -const SteamSession = require("steam-session"); // eslint-disable-line +const SteamSession = require("steam-session"); const Bot = require("../bot/bot.js"); // eslint-disable-line const EStatus = require("../bot/EStatus.js"); diff --git a/src/starter.js b/src/starter.js index 3b9151d8..a7d3aeed 100644 --- a/src/starter.js +++ b/src/starter.js @@ -4,10 +4,10 @@ * Created Date: 2021-07-10 10:26:00 * Author: 3urobeat * - * Last Modified: 2023-12-27 14:17:17 + * Last Modified: 2024-05-03 12:51:33 * Modified By: 3urobeat * - * Copyright (c) 2021 - 2023 3urobeat + * Copyright (c) 2021 - 2024 3urobeat * * This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. @@ -264,7 +264,7 @@ module.exports.checkAndGetFile = (file, logger, norequire = false, force = false try { branch = require("./data/data.json").branch; // Try to read from data.json - } catch (err) { + } catch { try { let otherdata = require("./data.json"); // Then try to get the other, "compatibility" data file to check if versionstr includes the word BETA @@ -335,7 +335,7 @@ module.exports.checkAndGetFile = (file, logger, norequire = false, force = false let fileToLoad = require("." + file); resolve(fileToLoad); // Seems to be fine, otherwise we would already be in the catch block - } catch (err) { + } catch { logger("warn", `It looks like file ${file} is corrupted. Trying to pull new file from GitHub...`, false, true); getNewFile(); diff --git a/src/updater/helpers/prepareUpdate.js b/src/updater/helpers/prepareUpdate.js index 08e5f04e..960c7d03 100644 --- a/src/updater/helpers/prepareUpdate.js +++ b/src/updater/helpers/prepareUpdate.js @@ -4,10 +4,10 @@ * Created Date: 2021-07-09 16:26:00 * Author: 3urobeat * - * Last Modified: 2023-12-27 14:18:10 + * Last Modified: 2024-05-03 12:51:26 * Modified By: 3urobeat * - * Copyright (c) 2021 - 2023 3urobeat + * Copyright (c) 2021 - 2024 3urobeat * * This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. @@ -34,7 +34,7 @@ module.exports.run = (controller, respondModule, resInfo) => { logger("info", "Bot is logged in. Checking for active requests...", false, true, logger.animation("loading")); - /* eslint-disable no-inner-declarations, jsdoc/require-jsdoc */ + /* eslint-disable jsdoc/require-jsdoc */ function initiateUpdate() { // Make initiating the update a function to simplify the activerequest check below controller.info.relogAfterDisconnect = false; // Prevents disconnect event (which will be called by logOff) to relog accounts @@ -72,7 +72,7 @@ module.exports.run = (controller, respondModule, resInfo) => { initiateUpdate(); } } - /* eslint-enable no-inner-declarations, jsdoc/require-jsdoc */ + /* eslint-enable jsdoc/require-jsdoc */ // Check for active request process. If obj not empty then first sort out all invalid/expired entries. diff --git a/src/updater/helpers/restoreBackup.js b/src/updater/helpers/restoreBackup.js index 17cdab3a..334e6a48 100644 --- a/src/updater/helpers/restoreBackup.js +++ b/src/updater/helpers/restoreBackup.js @@ -4,10 +4,10 @@ * Created Date: 2022-02-26 20:16:44 * Author: 3urobeat * - * Last Modified: 2023-12-27 14:18:01 + * Last Modified: 2024-05-03 12:49:17 * Modified By: 3urobeat * - * Copyright (c) 2022 - 2023 3urobeat + * Copyright (c) 2022 - 2024 3urobeat * * This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. @@ -38,7 +38,7 @@ module.exports.run = () => { * @param {string} dest To path * @param {boolean} firstCall Set to `true` on first call, will be set to `false` on recursive call */ - function copyFolderRecursiveSync(src, dest, firstCall) { // eslint-disable-line no-inner-declarations + function copyFolderRecursiveSync(src, dest, firstCall) { let files = []; // Check if folder needs to be created diff --git a/start.js b/start.js index 4bd7e33e..d8517cd1 100644 --- a/start.js +++ b/start.js @@ -4,10 +4,10 @@ * Created Date: 2020-01-15 10:38:00 * Author: 3urobeat * - * Last Modified: 2023-12-27 13:57:29 + * Last Modified: 2024-05-03 12:51:07 * Modified By: 3urobeat * - * Copyright (c) 2020 - 2023 3urobeat + * Copyright (c) 2020 - 2024 3urobeat * * This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. @@ -29,7 +29,7 @@ function getExtdata() { try { // Just try to require, if it should fail then the actual restoring process will be handled later return require("./src/data/data.json"); - } catch (err) { + } catch { return { filetostart: "./src/starter.js", filetostarturl: "https://raw.githubusercontent.com/3urobeat/steam-comment-service-bot/beta-testing/src/starter.js" }; } } From 9361387bb685ecfc51c0432c9a50bcf554a21fa5 Mon Sep 17 00:00:00 2001 From: 3urobeat <35304405+3urobeat@users.noreply.github.com> Date: Fri, 3 May 2024 22:41:07 +0200 Subject: [PATCH 12/28] feat: Log more login related information with default log level --- src/bot/helpers/handleRelog.js | 4 ++-- src/controller/login.js | 4 ++-- src/data/fileStructure.json | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/bot/helpers/handleRelog.js b/src/bot/helpers/handleRelog.js index 5c41a095..65fdb3d7 100644 --- a/src/bot/helpers/handleRelog.js +++ b/src/bot/helpers/handleRelog.js @@ -4,7 +4,7 @@ * Created Date: 2023-10-05 16:14:46 * Author: 3urobeat * - * Last Modified: 2024-05-02 10:54:36 + * Last Modified: 2024-05-03 18:56:32 * Modified By: 3urobeat * * Copyright (c) 2023 - 2024 3urobeat @@ -139,7 +139,7 @@ Bot.prototype.handleRelog = async function() { setTimeout(() => { // Abort if account is online again for some reason - if (this.status == Bot.EStatus.ONLINE) return logger("debug", `Bot handleRelog(): Timeout elapsed but bot${this.index} is not offline anymore. Ignoring...`); + if (this.status == Bot.EStatus.ONLINE) return logger("info", `[${this.logPrefix}] Relog timeout elapsed, however the account is already online again?! Ignoring relog request...`); // Update status to offline and call login again this.status = Bot.EStatus.OFFLINE; diff --git a/src/controller/login.js b/src/controller/login.js index c4be430a..08b3b1a9 100644 --- a/src/controller/login.js +++ b/src/controller/login.js @@ -4,7 +4,7 @@ * Created Date: 2021-07-09 16:26:00 * Author: 3urobeat * - * Last Modified: 2024-03-08 18:20:05 + * Last Modified: 2024-05-03 19:55:19 * Modified By: 3urobeat * * Copyright (c) 2021 - 2024 3urobeat @@ -52,7 +52,7 @@ Controller.prototype.login = async function(firstLogin) { } // Ignore login request if another login is running - if (this.info.activeLogin) return logger("debug", "Controller login(): Login requested but there is already a login process active. Ignoring..."); + if (this.info.activeLogin) return logger("info", "Login for all offline accounts requested but there is already one process running. Ignoring request for now, it will be handled after this process is done.", false, true); logger("debug", "Controller login(): Login requested, checking for any accounts currently OFFLINE or POSTPONED..."); diff --git a/src/data/fileStructure.json b/src/data/fileStructure.json index 441d2927..4e70901c 100644 --- a/src/data/fileStructure.json +++ b/src/data/fileStructure.json @@ -373,7 +373,7 @@ { "path": "src/bot/helpers/handleRelog.js", "url": "https://raw.githubusercontent.com/3urobeat/steam-comment-service-bot/beta-testing/src/bot/helpers/handleRelog.js", - "checksum": "e9197cd02697f19733c7e199ca783eeb" + "checksum": "67628d3bd1ab7628016557e5ad8417b6" }, { "path": "src/bot/helpers/steamChatInteraction.js", @@ -553,7 +553,7 @@ { "path": "src/controller/login.js", "url": "https://raw.githubusercontent.com/3urobeat/steam-comment-service-bot/beta-testing/src/controller/login.js", - "checksum": "a3181994388cb9145687ff167345ee47" + "checksum": "77edc8c09056c1911661dd1f4d52234a" }, { "path": "src/data/ascii.js", From dbc74b83482367a9e10a9bca1f1095513747e900 Mon Sep 17 00:00:00 2001 From: 3urobeat <35304405+3urobeat@users.noreply.github.com> Date: Sat, 4 May 2024 11:30:27 +0200 Subject: [PATCH 13/28] fix(DataManager): Fix incorrect childAccOnlineStatus check introduced by 92a661c --- src/data/fileStructure.json | 2 +- src/dataManager/dataCheck.js | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/data/fileStructure.json b/src/data/fileStructure.json index 4e70901c..4daed090 100644 --- a/src/data/fileStructure.json +++ b/src/data/fileStructure.json @@ -588,7 +588,7 @@ { "path": "src/dataManager/dataCheck.js", "url": "https://raw.githubusercontent.com/3urobeat/steam-comment-service-bot/beta-testing/src/dataManager/dataCheck.js", - "checksum": "924a09d6c37e985f58a94335b2dfdc9d" + "checksum": "2da9cc1f31ac3ab7b4e07e60be1991c2" }, { "path": "src/dataManager/dataExport.js", diff --git a/src/dataManager/dataCheck.js b/src/dataManager/dataCheck.js index 32104387..60408fa8 100644 --- a/src/dataManager/dataCheck.js +++ b/src/dataManager/dataCheck.js @@ -4,7 +4,7 @@ * Created Date: 2021-07-09 16:26:00 * Author: 3urobeat * - * Last Modified: 2024-05-03 13:00:04 + * Last Modified: 2024-05-04 11:28:44 * Modified By: 3urobeat * * Copyright (c) 2023 - 2024 3urobeat @@ -110,7 +110,7 @@ DataManager.prototype.checkData = function() { logWarn("warn", `You've set an invalid value '${this.advancedconfig.onlineStatus}' as 'onlineStatus' in 'advancedconfig.json'! Defaulting to 'Online'...`); this.advancedconfig.onlineStatus = "Online"; } - if (EPersonaState[this.advancedconfig.childAccOnlineStatus] != undefined) { // Explicitly check for undefined because Offline (0) resolves to false + if (EPersonaState[this.advancedconfig.childAccOnlineStatus] == undefined) { // Explicitly check for undefined because Offline (0) resolves to false logWarn("warn", `You've set an invalid value '${this.advancedconfig.childAccOnlineStatus}' as 'childAccOnlineStatus' in 'advancedconfig.json'! Defaulting to 'Online'...`); this.advancedconfig.childAccOnlineStatus = "Online"; } From 32a27704f02719d0f61727d685e720ff64c9711d Mon Sep 17 00:00:00 2001 From: 3urobeat <35304405+3urobeat@users.noreply.github.com> Date: Sat, 4 May 2024 12:29:51 +0200 Subject: [PATCH 14/28] chore: Let's maybe be less political, idk, could be a cool idea --- quotes.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/quotes.txt b/quotes.txt index b919e91a..047de2cb 100644 --- a/quotes.txt +++ b/quotes.txt @@ -361,7 +361,6 @@ TOP1 meow ++++++rep yoooooooooooooooooo man -China is a cool country imo CS2 God Legendary 1 tapper From 80551c66ad727db057b8caac0cb2f3665e40f97f Mon Sep 17 00:00:00 2001 From: 3urobeat <35304405+3urobeat@users.noreply.github.com> Date: Sat, 4 May 2024 13:00:45 +0200 Subject: [PATCH 15/28] feat(Controller): Increase debug logging for login request to allow debugging of login process resolving issues --- src/bot/helpers/handleRelog.js | 4 ++-- src/controller/login.js | 11 +++++++---- src/data/fileStructure.json | 4 ++-- 3 files changed, 11 insertions(+), 8 deletions(-) diff --git a/src/bot/helpers/handleRelog.js b/src/bot/helpers/handleRelog.js index 65fdb3d7..5aec3936 100644 --- a/src/bot/helpers/handleRelog.js +++ b/src/bot/helpers/handleRelog.js @@ -4,7 +4,7 @@ * Created Date: 2023-10-05 16:14:46 * Author: 3urobeat * - * Last Modified: 2024-05-03 18:56:32 + * Last Modified: 2024-05-04 12:14:19 * Modified By: 3urobeat * * Copyright (c) 2023 - 2024 3urobeat @@ -27,7 +27,7 @@ const Bot = require("../bot"); */ Bot.prototype.switchProxy = function(newProxyIndex) { - if (newProxyIndex == undefined) return new Error("newProxyIndex is undefined"); // Explicitly check for undefined to prevent the value 0 from triggering this check + if (newProxyIndex == undefined) return new Error("Parameter newProxyIndex must not be undefined"); // Explicitly check for undefined to prevent the value 0 from triggering this check logger("info", `[${this.logPrefix}] Switching proxy from ${this.loginData.proxyIndex} to ${newProxyIndex}. The bot account will relog in a moment...`); diff --git a/src/controller/login.js b/src/controller/login.js index 08b3b1a9..6306f26d 100644 --- a/src/controller/login.js +++ b/src/controller/login.js @@ -4,7 +4,7 @@ * Created Date: 2021-07-09 16:26:00 * Author: 3urobeat * - * Last Modified: 2024-05-03 19:55:19 + * Last Modified: 2024-05-04 12:57:57 * Modified By: 3urobeat * * Copyright (c) 2021 - 2024 3urobeat @@ -127,10 +127,13 @@ Controller.prototype.login = async function(firstLogin) { // Register interval to check if all accounts have been processed let allAccsOnlineInterval = setInterval(() => { - // Check if all accounts have been processed - let allNotOffline = allAccounts.every((e) => this.bots[e.accountName].status != Bot.EStatus.OFFLINE);// && this.bots[e.accountName].status != Bot.EStatus.POSTPONED); + // Check if all accounts in this login request have changed their status to not OFFLINE + let allAccountsOffline = allAccounts.filter((e) => this.bots[e.accountName].status == Bot.EStatus.OFFLINE); - if (!allNotOffline) return; + if (allAccountsOffline.length > 0) { + logger("debug", `Controller login(): Waiting for bot(s) '${allAccountsOffline.flatMap((e) => e.index).join(", ")}' to switch status to not OFFLINE before resolving...`, true, true); // Cannot log with date to prevent log output file spam + return; + } // Check if all accounts have their SteamUser data populated. Ignore accounts that are not online as they will never populate their user object let allAccountsNotPopulated = allAccounts.filter((e) => this.bots[e.accountName].status == Bot.EStatus.ONLINE && !this.bots[e.accountName].user.limitations); diff --git a/src/data/fileStructure.json b/src/data/fileStructure.json index 4daed090..07061993 100644 --- a/src/data/fileStructure.json +++ b/src/data/fileStructure.json @@ -373,7 +373,7 @@ { "path": "src/bot/helpers/handleRelog.js", "url": "https://raw.githubusercontent.com/3urobeat/steam-comment-service-bot/beta-testing/src/bot/helpers/handleRelog.js", - "checksum": "67628d3bd1ab7628016557e5ad8417b6" + "checksum": "aafd437f00048ec06aa029a47cc404f1" }, { "path": "src/bot/helpers/steamChatInteraction.js", @@ -553,7 +553,7 @@ { "path": "src/controller/login.js", "url": "https://raw.githubusercontent.com/3urobeat/steam-comment-service-bot/beta-testing/src/controller/login.js", - "checksum": "77edc8c09056c1911661dd1f4d52234a" + "checksum": "60f0819694580cf7d2a573c09eb1c75c" }, { "path": "src/data/ascii.js", From 75d576659c65b61873dec380c17bf8076fa88625 Mon Sep 17 00:00:00 2001 From: 3urobeat <35304405+3urobeat@users.noreply.github.com> Date: Sat, 4 May 2024 15:31:25 +0200 Subject: [PATCH 16/28] feat(Bot): Potentially finally fix Already logged on errors when relogging for good --- src/bot/bot.js | 38 ++++++++++++++++++++++++++++++------- src/data/fileStructure.json | 2 +- 2 files changed, 32 insertions(+), 8 deletions(-) diff --git a/src/bot/bot.js b/src/bot/bot.js index e2bbdb31..e0669312 100644 --- a/src/bot/bot.js +++ b/src/bot/bot.js @@ -4,7 +4,7 @@ * Created Date: 2021-07-09 16:26:00 * Author: 3urobeat * - * Last Modified: 2024-05-03 12:46:26 + * Last Modified: 2024-05-04 15:27:37 * Modified By: 3urobeat * * Copyright (c) 2021 - 2024 3urobeat @@ -192,10 +192,37 @@ Bot.prototype._loginToSteam = async function() { // Count this attempt this.loginData.logOnTries++; - // Always call logOff() before logOn() like an idiot to prevent "Already attempting to log on, cannot log on again" errors - this.user.logOff(); + const currentLogOnTry = this.loginData.logOnTries; - if (this.sessionHandler.session) this.sessionHandler.session.cancelLoginAttempt(); // TODO: This might cause an error as idk if we are polling. Maybe use the timeout event of steam-session + + // Attach loginTimeout handler + this.handleLoginTimeout(); + + + // If logged in, wait for account to be logged off before continuing. This prevents "Already logged in, ..." & "Already attempting to log on, ..." errors + if (this.user.steamID || this.user._connecting) { // https://github.com/DoctorMcKay/node-steam-user/blob/cb8e098969c10555fe41dd9487be140c79006c41/components/09-logon.js#L51 + await (async () => { + return new Promise((resolve) => { + + this.user.logOff(); + if (this.sessionHandler.session) this.sessionHandler.session.cancelLoginAttempt(); // TODO: This might cause an error as idk if we are polling. Maybe use the timeout event of steam-session + + let logOffInterval = setInterval(() => { + logger("warn", `[${this.logPrefix}] Login requested but account seems to be logged in! Attempting log off before continuing...`, true, true); // Cannot log with date to prevent log output file spam + + // Resolve when logged off or when logOnTries has changed (handleLoginTimeout has probably taken action) + if ((!this.user.steamID && !this.user._connecting) || currentLogOnTry != this.loginData.logOnTries) { + clearInterval(logOffInterval); + resolve(); + } + }, 250); + + }); + })(); + } + + // Cancel if not on the same logOnTries value anymore (handleLoginTimeout has probably taken action) + if (currentLogOnTry != this.loginData.logOnTries) return logger("debug", `[${this.logPrefix}] Aborting login because _loginToSteam() was called again from somewhere else. Potentially logging off took too long and handleLoginTimeout took action.`); // Find proxyIndex from steam-user object options instead of loginData to get reliable log data @@ -205,9 +232,6 @@ Bot.prototype._loginToSteam = async function() { if (!thisProxy.proxy) logger("info", `[${this.logPrefix}] Trying to log in without proxy... (Attempt ${this.loginData.logOnTries}/${this.controller.data.advancedconfig.maxLogOnRetries + 1})`, false, true, logger.animation("loading")); else logger("info", `[${this.logPrefix}] Trying to log in with proxy ${thisProxy.proxyIndex}... (Attempt ${this.loginData.logOnTries}/${this.controller.data.advancedconfig.maxLogOnRetries + 1})`, false, true, logger.animation("loading")); - // Attach loginTimeout handler - this.handleLoginTimeout(); - // Call our steam-session helper to get a valid refresh token for us let refreshToken = await this.sessionHandler.getToken(); diff --git a/src/data/fileStructure.json b/src/data/fileStructure.json index 07061993..13b42d8b 100644 --- a/src/data/fileStructure.json +++ b/src/data/fileStructure.json @@ -318,7 +318,7 @@ { "path": "src/bot/bot.js", "url": "https://raw.githubusercontent.com/3urobeat/steam-comment-service-bot/beta-testing/src/bot/bot.js", - "checksum": "97b6b1fb055bd3a19c11bbe68147b8c5" + "checksum": "f5ffdab3eaaaeed3035b76200c932c47" }, { "path": "src/bot/events/debug.js", From 52cf2f02abe4c53971b4b9a0a768ecccbefdaff9 Mon Sep 17 00:00:00 2001 From: 3urobeat <35304405+3urobeat@users.noreply.github.com> Date: Sat, 4 May 2024 21:22:25 +0200 Subject: [PATCH 17/28] fix: Fix potential login softlock when account switches proxy while a login process is active, with this account queued in it --- src/bot/helpers/handleRelog.js | 6 +++--- src/data/fileStructure.json | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/bot/helpers/handleRelog.js b/src/bot/helpers/handleRelog.js index 5aec3936..b5a1f085 100644 --- a/src/bot/helpers/handleRelog.js +++ b/src/bot/helpers/handleRelog.js @@ -4,7 +4,7 @@ * Created Date: 2023-10-05 16:14:46 * Author: 3urobeat * - * Last Modified: 2024-05-04 12:14:19 + * Last Modified: 2024-05-04 21:12:25 * Modified By: 3urobeat * * Copyright (c) 2023 - 2024 3urobeat @@ -141,8 +141,8 @@ Bot.prototype.handleRelog = async function() { // Abort if account is online again for some reason if (this.status == Bot.EStatus.ONLINE) return logger("info", `[${this.logPrefix}] Relog timeout elapsed, however the account is already online again?! Ignoring relog request...`); - // Update status to offline and call login again - this.status = Bot.EStatus.OFFLINE; + // Update status and call login again + this.controller._statusUpdateEvent(this, Bot.EStatus.POSTPONED); // Important: Set to POSTPONED to let the current login request, which this acc is queued in, resolve. The following request will process it. This fixes a softlock where the current login process would never resolve. this.controller.login(); }, this.controller.data.advancedconfig.relogTimeout); diff --git a/src/data/fileStructure.json b/src/data/fileStructure.json index 13b42d8b..40d4b791 100644 --- a/src/data/fileStructure.json +++ b/src/data/fileStructure.json @@ -373,7 +373,7 @@ { "path": "src/bot/helpers/handleRelog.js", "url": "https://raw.githubusercontent.com/3urobeat/steam-comment-service-bot/beta-testing/src/bot/helpers/handleRelog.js", - "checksum": "aafd437f00048ec06aa029a47cc404f1" + "checksum": "36d245d8d1b4e08e8e1953b53e5042d7" }, { "path": "src/bot/helpers/steamChatInteraction.js", From 2a700c260da2127c12e35a90fdfe0b058f1fdbc6 Mon Sep 17 00:00:00 2001 From: 3urobeat <35304405+3urobeat@users.noreply.github.com> Date: Sat, 4 May 2024 21:57:15 +0200 Subject: [PATCH 18/28] feat: Force resolve login process when inactivity is detected This is kinda experimental, I'm not sure if I missed something or messed something up lol --- src/controller/login.js | 81 +++++++++++++++++++++++++++++++------ src/data/fileStructure.json | 2 +- 2 files changed, 69 insertions(+), 14 deletions(-) diff --git a/src/controller/login.js b/src/controller/login.js index 6306f26d..22425936 100644 --- a/src/controller/login.js +++ b/src/controller/login.js @@ -4,7 +4,7 @@ * Created Date: 2021-07-09 16:26:00 * Author: 3urobeat * - * Last Modified: 2024-05-04 12:57:57 + * Last Modified: 2024-05-04 21:53:58 * Modified By: 3urobeat * * Copyright (c) 2021 - 2024 3urobeat @@ -66,7 +66,7 @@ Controller.prototype.login = async function(firstLogin) { // Set all POSTPONED accounts to offline, as they are now going to be processed (this is important so that the allAccsOnlineInterval below doesn't plow through). Ignore acc if it doesn't have a bots entry yet allAccounts.forEach((e) => this.bots[e.accountName] && this.bots[e.accountName].status == Bot.EStatus.POSTPONED ? this.bots[e.accountName].status = Bot.EStatus.OFFLINE : null); - // Get all new accounts or existing ones that are offline or were postponed + // Get all new accounts or existing ones that are offline allAccounts = allAccounts.filter((e) => !this.bots[e.accountName] || this.bots[e.accountName].status == Bot.EStatus.OFFLINE); logger("debug", `Controller login(): Found ${allAccounts.length} login candidate(s)`); @@ -125,11 +125,74 @@ Controller.prototype.login = async function(firstLogin) { // Register interval to check if all accounts have been processed + let lastAmountUpdateTimestamp = Date.now(); + let waitingForAmountAccounts = 0; + let allAccsOnlineInterval = setInterval(() => { - // Check if all accounts in this login request have changed their status to not OFFLINE + // Shorthander that resolves this login process + const loginFinished = () => { + clearInterval(allAccsOnlineInterval); + + this.info.activeLogin = false; + + // Emit ready event if this is the first start and no login is pending + if (this.info.readyAfter == 0 && !Object.values(this.bots).some((e) => e.status == Bot.EStatus.POSTPONED)) { + this._readyEvent(); + } + + // Call itself again to process any POSTPONED or newly qualified accounts - this has to happen after the ready check above as login() sets every POSTPONED account to OFFLINE + this.login(); + }; + + + // Process various checks before deeming this login process to be finished + + /** + * Get all accounts which have not yet switched their status + * @type {{ index: number, accountName: string }[]} Array of loginInfo objects, which among other things have these props + */ let allAccountsOffline = allAccounts.filter((e) => this.bots[e.accountName].status == Bot.EStatus.OFFLINE); + // Update waitingForAmountAccounts & lastAmountUpdateTimestamp on change + if (waitingForAmountAccounts != allAccountsOffline.length) { + waitingForAmountAccounts = allAccountsOffline.length; + lastAmountUpdateTimestamp = Date.now(); + } + + // Check if this login process might be softlocked. Display warning after 5 minutes, abort process after 15 minutes + if (Date.now() - lastAmountUpdateTimestamp > 300000) { // 300000 ms = 5 min + if (Date.now() - lastAmountUpdateTimestamp > 900000) { // 900000 ms = 15 min + logger("warn", `Detected softlocked login process! Setting status of bot(s) '${allAccountsOffline.flatMap((e) => e.index).join(", ")}' to ERROR and calling handleRelog!`, true, false, null, true); + + // Check if main account is involved and this is the initial login and terminate the bot + if (allAccountsOffline.find((e) => e.index == 0) && this.info.readyAfter == 0) { + logger("", "", true); + logger("error", "Aborting because the first bot account always needs to be logged in!\nPlease correct what caused the error and try again.", true); + return this.stop(); + } + + // Set status of every account to OFFLINE and call handleRelog to let it figure this out + allAccountsOffline.forEach((e) => { + let thisBot = this.bots[e.accountName]; + + this._statusUpdateEvent(thisBot, Bot.EStatus.ERROR); + thisBot.handleRelog(); + thisBot.loginData.pendingLogin = false; + }); + + loginFinished(); + return; + } + + let cancelingInMinutes = Math.ceil(((lastAmountUpdateTimestamp + 900000) - Date.now()) / 60000); + + logger("warn", `Detected inactivity in current login process! I'm waiting for bot(s) '${allAccountsOffline.flatMap((e) => e.index).join(", ")}' to change their status & become populated since >5 minutes! Canceling this login process in ~${cancelingInMinutes} minutes to prevent a softlock.`, true, true); + + if (allAccountsOffline.length > 0) return; // Prevents debug msg below from logging, should reduce log spam in debug mode + } + + // Abort if we are still waiting for accounts to become not OFFLINE if (allAccountsOffline.length > 0) { logger("debug", `Controller login(): Waiting for bot(s) '${allAccountsOffline.flatMap((e) => e.index).join(", ")}' to switch status to not OFFLINE before resolving...`, true, true); // Cannot log with date to prevent log output file spam return; @@ -143,19 +206,11 @@ Controller.prototype.login = async function(firstLogin) { return; } - clearInterval(allAccsOnlineInterval); + // Everything looks good, resolve this login process! logger("info", "Finished logging in all currently queued accounts! Checking for any new accounts...", false, false, logger.animation("loading")); - this.info.activeLogin = false; - - // Emit ready event if this is the first start and no login is pending - if (this.info.readyAfter == 0 && !Object.values(this.bots).some((e) => e.status == Bot.EStatus.POSTPONED)) { - this._readyEvent(); - } - - // Call itself again to process any POSTPONED or newly qualified accounts - this has to happen after the ready check above as login() sets every POSTPONED account to OFFLINE - this.login(); + loginFinished(); }, 250); diff --git a/src/data/fileStructure.json b/src/data/fileStructure.json index 40d4b791..2616d14e 100644 --- a/src/data/fileStructure.json +++ b/src/data/fileStructure.json @@ -553,7 +553,7 @@ { "path": "src/controller/login.js", "url": "https://raw.githubusercontent.com/3urobeat/steam-comment-service-bot/beta-testing/src/controller/login.js", - "checksum": "60f0819694580cf7d2a573c09eb1c75c" + "checksum": "df4e7dc2a92eb948cadcb398965a3824" }, { "path": "src/data/ascii.js", From 77c9f8ea9c54e5e84acf0e6952978a3412df0bcb Mon Sep 17 00:00:00 2001 From: 3urobeat <35304405+3urobeat@users.noreply.github.com> Date: Sat, 4 May 2024 22:11:29 +0200 Subject: [PATCH 19/28] chore: Add and enforce no-use-before-define & prefer-constant eslint rules --- eslint.config.mjs | 4 +- scripts/checkTranslationKeys.js | 6 +- scripts/generateFileStructure.js | 8 +- src/bot/bot.js | 8 +- src/bot/events/error.js | 2 +- src/bot/events/friendMessage.js | 20 +-- src/bot/events/relationship.js | 6 +- src/bot/events/webSession.js | 6 +- src/bot/helpers/handleLoginTimeout.js | 4 +- src/bot/helpers/handleMissingGameLicenses.js | 6 +- src/bot/helpers/handleRelog.js | 10 +- src/bot/helpers/steamChatInteraction.js | 12 +- src/commands/commandHandler.js | 6 +- src/commands/core/block.js | 4 +- src/commands/core/comment.js | 36 ++-- src/commands/core/favorite.js | 40 ++--- src/commands/core/follow.js | 44 ++--- src/commands/core/friend.js | 16 +- src/commands/core/general.js | 16 +- src/commands/core/group.js | 16 +- src/commands/core/requests.js | 24 +-- src/commands/core/settings.js | 16 +- src/commands/core/system.js | 18 +- src/commands/core/vote.js | 22 +-- src/commands/helpers/getCommentArgs.js | 6 +- src/commands/helpers/getCommentBots.js | 10 +- src/commands/helpers/getFavoriteBots.js | 6 +- src/commands/helpers/getFollowArgs.js | 8 +- src/commands/helpers/getFollowBots.js | 8 +- src/commands/helpers/getMiscArgs.js | 4 +- src/commands/helpers/getVoteBots.js | 8 +- src/commands/helpers/handleCommentSkips.js | 48 +++--- src/commands/helpers/handleFollowErrors.js | 38 ++--- src/commands/helpers/handleMiscErrors.js | 42 ++--- src/controller/controller.js | 117 ++++++------- src/controller/events/ready.js | 2 +- src/controller/events/statusUpdate.js | 2 +- src/controller/helpers/friendlist.js | 14 +- src/controller/helpers/getBots.js | 4 +- .../helpers/handleSteamIdResolving.js | 16 +- src/controller/helpers/misc.js | 16 +- src/controller/login.js | 28 ++-- src/data/fileStructure.json | 154 +++++++++--------- src/dataManager/dataCheck.js | 2 +- src/dataManager/dataExport.js | 18 +- src/dataManager/dataImport.js | 8 +- src/dataManager/dataIntegrity.js | 8 +- src/dataManager/dataProcessing.js | 4 +- src/dataManager/helpers/checkProxies.js | 6 +- src/dataManager/helpers/getLang.js | 6 +- src/dataManager/helpers/getQuote.js | 2 +- src/dataManager/helpers/handleCooldowns.js | 2 +- .../helpers/handleExpiringTokens.js | 22 +-- src/dataManager/helpers/misc.js | 6 +- src/dataManager/helpers/refreshCache.js | 2 +- src/dataManager/helpers/repairFile.js | 2 +- src/jobs/jobManager.js | 2 +- src/pluginSystem/handlePluginData.js | 16 +- src/pluginSystem/loadPlugins.js | 4 +- src/sessions/helpers/handle2FA.js | 2 +- .../helpers/handleCredentialsLoginError.js | 2 +- src/sessions/helpers/tokenStorageHandler.js | 8 +- src/sessions/sessionHandler.js | 6 +- src/starter.js | 44 ++--- src/updater/compatibility.js | 4 +- src/updater/compatibility/2104.js | 2 +- src/updater/compatibility/21100.js | 2 +- src/updater/compatibility/21200.js | 4 +- src/updater/compatibility/21300.js | 4 +- src/updater/compatibility/21400.js | 2 +- src/updater/helpers/checkForUpdate.js | 8 +- src/updater/helpers/createBackup.js | 4 +- src/updater/helpers/customUpdateRules.js | 10 +- src/updater/helpers/downloadUpdate.js | 16 +- src/updater/helpers/restoreBackup.js | 6 +- src/updater/updater.js | 18 +- start.js | 6 +- types/types.d.ts | 34 ++-- 78 files changed, 590 insertions(+), 583 deletions(-) diff --git a/eslint.config.mjs b/eslint.config.mjs index ac9a12ce..144bfea6 100644 --- a/eslint.config.mjs +++ b/eslint.config.mjs @@ -4,7 +4,7 @@ * Created Date: 2024-05-03 12:17:16 * Author: 3urobeat * - * Last Modified: 2024-05-03 12:58:49 + * Last Modified: 2024-05-04 22:00:04 * Modified By: 3urobeat * * Copyright (c) 2024 3urobeat @@ -64,6 +64,8 @@ export default [ "no-tabs": "error", "no-trailing-spaces": "error", "no-extra-semi": "error", + "no-use-before-define": "error", + "prefer-const": "error", "semi": ["error", "always"], "semi-spacing": "error", "semi-style": ["error", "last"], diff --git a/scripts/checkTranslationKeys.js b/scripts/checkTranslationKeys.js index 87e6de35..1bf2228d 100644 --- a/scripts/checkTranslationKeys.js +++ b/scripts/checkTranslationKeys.js @@ -25,7 +25,7 @@ const eng = require("../src/data/lang/english.json"); // Find all translations inside the same directory -let translations = fs.readdirSync("./src/data/lang/"); +const translations = fs.readdirSync("./src/data/lang/"); console.log(`Checking ${translations.length - 1} translation(s). If the script exits with no further messages, all translations contain the same keys.`); @@ -44,8 +44,8 @@ translations.forEach((name) => { // Get key arrays of both translations - let engKeys = Object.keys(eng); - let langKeys = Object.keys(lang); + const engKeys = Object.keys(eng); + const langKeys = Object.keys(lang); // Check lang for missing keys diff --git a/scripts/generateFileStructure.js b/scripts/generateFileStructure.js index 91a13637..1b8273ce 100644 --- a/scripts/generateFileStructure.js +++ b/scripts/generateFileStructure.js @@ -48,7 +48,7 @@ function searchFolderRecursiveSync(src, firstCall) { if (fs.lstatSync(src).isDirectory()) { files = fs.readdirSync(src); - let targetFolder = path.join("./", src); + const targetFolder = path.join("./", src); files.forEach(async (file) => { let filepath = targetFolder + "/" + file; @@ -59,7 +59,7 @@ function searchFolderRecursiveSync(src, firstCall) { // Ignore this file/folder if name is in ignore array if (ignore.includes(filepath)) return; - let curSource = path.join(src, file); + const curSource = path.join(src, file); // Recursively call this function again if this is a dir if (fs.lstatSync(curSource).isDirectory()) { @@ -68,8 +68,8 @@ function searchFolderRecursiveSync(src, firstCall) { } else { // Construct URL and calculate checksum - let fileurl = "https://raw.githubusercontent.com/3urobeat/steam-comment-service-bot/beta-testing/" + filepath; - let filesum = crypto.createHash("md5").update(fs.readFileSync(filepath)).digest("hex"); + const fileurl = "https://raw.githubusercontent.com/3urobeat/steam-comment-service-bot/beta-testing/" + filepath; + const filesum = crypto.createHash("md5").update(fs.readFileSync(filepath)).digest("hex"); // Add file to output array output.push({ "path": filepath, "url": fileurl, "checksum": filesum }); diff --git a/src/bot/bot.js b/src/bot/bot.js index e0669312..62562c07 100644 --- a/src/bot/bot.js +++ b/src/bot/bot.js @@ -63,7 +63,7 @@ const Bot = function(controller, index) { */ this.friendMessageBlock = []; - let proxyIndex = this.index % controller.data.proxies.length; // Spread all accounts equally with a simple modulo calculation + const proxyIndex = this.index % controller.data.proxies.length; // Spread all accounts equally with a simple modulo calculation /** * Additional login related information for this bot account @@ -207,7 +207,7 @@ Bot.prototype._loginToSteam = async function() { this.user.logOff(); if (this.sessionHandler.session) this.sessionHandler.session.cancelLoginAttempt(); // TODO: This might cause an error as idk if we are polling. Maybe use the timeout event of steam-session - let logOffInterval = setInterval(() => { + const logOffInterval = setInterval(() => { logger("warn", `[${this.logPrefix}] Login requested but account seems to be logged in! Attempting log off before continuing...`, true, true); // Cannot log with date to prevent log output file spam // Resolve when logged off or when logOnTries has changed (handleLoginTimeout has probably taken action) @@ -226,7 +226,7 @@ Bot.prototype._loginToSteam = async function() { // Find proxyIndex from steam-user object options instead of loginData to get reliable log data - let thisProxy = this.data.proxies.find((e) => e.proxy == this.user.options.httpProxy); + const thisProxy = this.data.proxies.find((e) => e.proxy == this.user.options.httpProxy); // Log login message for this account, with mentioning proxies or without if (!thisProxy.proxy) logger("info", `[${this.logPrefix}] Trying to log in without proxy... (Attempt ${this.loginData.logOnTries}/${this.controller.data.advancedconfig.maxLogOnRetries + 1})`, false, true, logger.animation("loading")); @@ -234,7 +234,7 @@ Bot.prototype._loginToSteam = async function() { // Call our steam-session helper to get a valid refresh token for us - let refreshToken = await this.sessionHandler.getToken(); + const refreshToken = await this.sessionHandler.getToken(); if (!refreshToken) return this.loginData.pendingLogin = false; // Stop execution if getRefreshToken aborted login attempt, it either skipped this account or stopped the bot itself diff --git a/src/bot/events/error.js b/src/bot/events/error.js index 45ce77fa..e880e634 100644 --- a/src/bot/events/error.js +++ b/src/bot/events/error.js @@ -73,7 +73,7 @@ Bot.prototype._attachSteamErrorEvent = function() { // Check if all logOnTries are used or if this is a fatal error - let blockedEnumsForRetries = [EResult.Banned, EResult.AccountNotFound]; // No need to block InvalidPassword anymore as the SessionHandler handles credentials + const blockedEnumsForRetries = [EResult.Banned, EResult.AccountNotFound]; // No need to block InvalidPassword anymore as the SessionHandler handles credentials if (this.loginData.logOnTries > this.controller.data.advancedconfig.maxLogOnRetries || blockedEnumsForRetries.includes(err.eresult)) { logger("error", `Couldn't log in bot${this.index} after ${this.loginData.logOnTries} attempt(s). ${err} (${err.eresult})`); diff --git a/src/bot/events/friendMessage.js b/src/bot/events/friendMessage.js index a7a83de1..f3b54f05 100644 --- a/src/bot/events/friendMessage.js +++ b/src/bot/events/friendMessage.js @@ -27,23 +27,23 @@ const Bot = require("../bot.js"); Bot.prototype._attachSteamFriendMessageEvent = function() { this.user.chat.on("friendMessage", async (msg) => { - let message = msg.message_no_bbcode; - let steamID = msg.steamid_friend; + const message = msg.message_no_bbcode; + const steamID = msg.steamid_friend; - let steamID64 = new SteamID(String(steamID)).getSteamID64(); - let username = this.user.users[steamID64] ? this.user.users[steamID64].player_name : ""; // Set username to nothing in case they are not cached yet to avoid errors + const steamID64 = new SteamID(String(steamID)).getSteamID64(); + const username = this.user.users[steamID64] ? this.user.users[steamID64].player_name : ""; // Set username to nothing in case they are not cached yet to avoid errors let relationshipStatus = SteamUser.EFriendRelationship.None; if (this.user.myFriends[steamID64]) relationshipStatus = SteamUser.EFriendRelationship[this.user.myFriends[steamID64]]; - let resInfo = { userID: steamID64, cmdprefix: "!", fromSteamChat: true }; // Object required for sendChatMessage(), our commandHandler respondModule implementation + const resInfo = { userID: steamID64, cmdprefix: "!", fromSteamChat: true }; // Object required for sendChatMessage(), our commandHandler respondModule implementation // Check if another friendMessage handler is currently active if (this.friendMessageBlock.includes(steamID64)) return logger("debug", `[${this.logPrefix}] Ignoring friendMessage event from ${steamID64} as user is on friendMessageBlock list.`); // Check if this event should be handled or if user is blocked - let isBlocked = await this.checkMsgBlock(steamID64, message); + const isBlocked = await this.checkMsgBlock(steamID64, message); if (isBlocked) return; // Stop right here if user is blocked, on cooldown or not a friend @@ -74,7 +74,7 @@ Bot.prototype._attachSteamFriendMessageEvent = function() { if (err) logger("error", "Database error on friendMessage. This is weird. Error: " + err); if (!doc) { // Add user to database if he/she is missing for some reason - let lastcommentobj = { + const lastcommentobj = { id: new SteamID(String(steamID)).getSteamID64(), time: Date.now() - (this.data.config.requestCooldown * 60000) // Subtract requestCooldown so that the user is able to use the command instantly }; @@ -94,10 +94,10 @@ Bot.prototype._attachSteamFriendMessageEvent = function() { // Ask command handler to figure out things for us when a message with prefix was sent - let cont = message.slice(1).split(" "); // Remove prefix and split - let args = cont.slice(1); // Remove cmd name to only get arguments + const cont = message.slice(1).split(" "); // Remove prefix and split + const args = cont.slice(1); // Remove cmd name to only get arguments - let success = await this.controller.commandHandler.runCommand(cont[0].toLowerCase(), args, this.sendChatMessage, this, resInfo); // Don't listen to your IDE, this *await is necessary* + const success = await this.controller.commandHandler.runCommand(cont[0].toLowerCase(), args, this.sendChatMessage, this, resInfo); // Don't listen to your IDE, this *await is necessary* if (!success) this.sendChatMessage(this, resInfo, await this.controller.data.getLang("commandnotfound", { "cmdprefix": resInfo.cmdprefix }, steamID64)); // Send cmd not found msg if runCommand() returned false }); diff --git a/src/bot/events/relationship.js b/src/bot/events/relationship.js index 26ad0538..4e34b94e 100644 --- a/src/bot/events/relationship.js +++ b/src/bot/events/relationship.js @@ -28,7 +28,7 @@ Bot.prototype._attachSteamFriendRelationshipEvent = function() { this.user.on("friendRelationship", (steamID, relationship) => { if (relationship == 2) { - let steamID64 = new SteamID(String(steamID)).getSteamID64(); + const steamID64 = new SteamID(String(steamID)).getSteamID64(); if (!this.data.advancedconfig.acceptFriendRequests) return logger("info", `[${this.logPrefix}] Received friend request from ${steamID64} but acceptFriendRequests is turned off in advancedconfig.json`); @@ -47,7 +47,7 @@ Bot.prototype._attachSteamFriendRelationshipEvent = function() { // Add user to lastcomment database - let time = Date.now() - (this.controller.data.config.requestCooldown * 60000); // Subtract requestCooldown so that the user is able to use the command instantly; + const time = Date.now() - (this.controller.data.config.requestCooldown * 60000); // Subtract requestCooldown so that the user is able to use the command instantly; this.controller.data.lastCommentDB.update({ id: steamID64 }, { $set: { time: time } }, { upsert: true }, (err) => { if (err) logger("error", "Error inserting new user into lastcomment.db database! Error: " + err); @@ -86,7 +86,7 @@ Bot.prototype._attachSteamGroupRelationshipEvent = function() { this.user.on("groupRelationship", (steamID, relationship) => { if (relationship == 2) { // Ignore if relationship type is not "Invited" - let steamID64 = new SteamID(String(steamID)).getSteamID64(); + const steamID64 = new SteamID(String(steamID)).getSteamID64(); // Check if acceptgroupinvites is set to false and only allow botsgroup invite to be accepted if (!this.controller.data.config.acceptgroupinvites) { diff --git a/src/bot/events/webSession.js b/src/bot/events/webSession.js index b4208b8d..b25118c2 100644 --- a/src/bot/events/webSession.js +++ b/src/bot/events/webSession.js @@ -60,7 +60,7 @@ Bot.prototype._attachSteamWebSessionEvent = function() { if (this.user.myFriends[Object.keys(this.user.myFriends)[i]] == 2) { if (this.controller.data.advancedconfig.acceptFriendRequests) { - let thisfriend = Object.keys(this.user.myFriends)[i]; + const thisfriend = Object.keys(this.user.myFriends)[i]; // Accept friend request this.user.addFriend(thisfriend); @@ -76,7 +76,7 @@ Bot.prototype._attachSteamWebSessionEvent = function() { // Add user to lastcomment database - let time = Date.now() - (this.controller.data.config.requestCooldown * 60000); // Subtract requestCooldown so that the user is able to use the command instantly; + const time = Date.now() - (this.controller.data.config.requestCooldown * 60000); // Subtract requestCooldown so that the user is able to use the command instantly; this.controller.data.lastCommentDB.update({ id: thisfriend }, { $set: { time: time } }, { upsert: true }, (err) => { if (err) logger("error", "Error inserting new user into lastcomment.db database! Error: " + err); @@ -105,7 +105,7 @@ Bot.prototype._attachSteamWebSessionEvent = function() { // Groups: for (let i = 0; i < Object.keys(this.user.myGroups).length; i++) { if (this.user.myGroups[Object.keys(this.user.myGroups)[i]] == 2) { - let thisgroup = Object.keys(this.user.myGroups)[i]; + const thisgroup = Object.keys(this.user.myGroups)[i]; // Check if acceptgroupinvites is set to false and only allow botsgroup invite to be accepted if (!this.controller.data.config.acceptgroupinvites) { diff --git a/src/bot/helpers/handleLoginTimeout.js b/src/bot/helpers/handleLoginTimeout.js index 0204db90..393731f0 100644 --- a/src/bot/helpers/handleLoginTimeout.js +++ b/src/bot/helpers/handleLoginTimeout.js @@ -27,7 +27,7 @@ Bot.prototype.handleLoginTimeout = function() { if (this.data.advancedconfig.loginTimeout == 0) return logger("debug", `Bot handleLoginTimeout(): Ignoring timeout attach request for bot${this.index} because loginTimeout is disabled in advancedconfig!`); else logger("debug", `Bot handleLoginTimeout(): Attached ${this.data.advancedconfig.loginTimeout / 1000} seconds timeout for bot${this.index}...`); - let currentLogOnTry = this.loginData.logOnTries; + const currentLogOnTry = this.loginData.logOnTries; // Check if account is still offline with the same logOnTries value 60 seconds later and force progress setTimeout(() => { @@ -36,7 +36,7 @@ Bot.prototype.handleLoginTimeout = function() { if (this.loginData.waitingFor2FA) return setTimeout(() => this.handleLoginTimeout(), 5000); // Ignore timeout if account progressed since then - let newLogOnTry = this.loginData.logOnTries; + const newLogOnTry = this.loginData.logOnTries; if (currentLogOnTry != newLogOnTry || this.status != Bot.EStatus.OFFLINE) return logger("debug", `Bot handleLoginTimeout(): Timeout for bot${this.index} done, acc not stuck. old/new logOnTries: ${currentLogOnTry}/${newLogOnTry} - acc status: ${this.status}`); diff --git a/src/bot/helpers/handleMissingGameLicenses.js b/src/bot/helpers/handleMissingGameLicenses.js index 3a182f66..9e051f2b 100644 --- a/src/bot/helpers/handleMissingGameLicenses.js +++ b/src/bot/helpers/handleMissingGameLicenses.js @@ -22,7 +22,7 @@ const Bot = require("../bot.js"); * Handles checking for missing game licenses, requests them and then starts playing */ Bot.prototype.handleMissingGameLicenses = function() { - let data = this.controller.data; + const data = this.controller.data; // Check if user provided games specifically for this account. We only need to check this for child accounts let configChildGames = data.config.childaccplayinggames; @@ -35,10 +35,10 @@ Bot.prototype.handleMissingGameLicenses = function() { } // Shorthander for starting to play - let startPlaying = () => { if (this.index == 0) this.user.gamesPlayed(this.controller.data.config.playinggames); else this.user.gamesPlayed(configChildGames); }; + const startPlaying = () => { if (this.index == 0) this.user.gamesPlayed(this.controller.data.config.playinggames); else this.user.gamesPlayed(configChildGames); }; - let options = { + const options = { includePlayedFreeGames: true, filterAppids: this.index == 0 ? data.config.playinggames.filter(e => !isNaN(e)) : configChildGames.filter(e => !isNaN(e) && e != null), // We only need to check for these appIDs. Filter custom game string and null values includeFreeSub: false diff --git a/src/bot/helpers/handleRelog.js b/src/bot/helpers/handleRelog.js index b5a1f085..5dd75b45 100644 --- a/src/bot/helpers/handleRelog.js +++ b/src/bot/helpers/handleRelog.js @@ -62,7 +62,7 @@ Bot.prototype.switchProxy = function(newProxyIndex) { Bot.prototype.checkAndSwitchMyProxy = async function() { // Attempt to ping github.com (basically any non steamcommunity url) without a proxy to determine if the internet connection is not working - let hostConnectionRes = await this.controller.misc.checkConnection("https://github.com/3urobeat/steam-comment-service-bot", true) + const hostConnectionRes = await this.controller.misc.checkConnection("https://github.com/3urobeat/steam-comment-service-bot", true) .catch((err) => { if (this.index == 0) logger("info", `[Main] Your internet connection seems to be down. ${err.statusMessage}`); // Only log message for main acc to reduce clutter }); @@ -86,10 +86,10 @@ Bot.prototype.checkAndSwitchMyProxy = async function() { // Check if our proxy is down - let thisProxy = this.data.proxies.find((e) => e.proxyIndex == this.loginData.proxyIndex); + const thisProxy = this.data.proxies.find((e) => e.proxyIndex == this.loginData.proxyIndex); if (!thisProxy.isOnline) { - let activeProxies = this.controller.getBotsPerProxy(true); // Get all online proxies and their associated bot accounts + const activeProxies = this.controller.getBotsPerProxy(true); // Get all online proxies and their associated bot accounts // Check if no available proxy was found (exclude host) and return false if (activeProxies.length == 0) { @@ -99,7 +99,7 @@ Bot.prototype.checkAndSwitchMyProxy = async function() { // Find proxy with least amount of associated bots - let leastUsedProxy = activeProxies.reduce((a, b) => a.bots.length < b.bots.length ? a : b); + const leastUsedProxy = activeProxies.reduce((a, b) => a.bots.length < b.bots.length ? a : b); logger("warn", `[${this.logPrefix}] Failed to ping Steam using proxy ${this.loginData.proxyIndex}! Switching to proxy ${leastUsedProxy.proxyIndex} which currently has the least amount of usage and appears to be online.`); @@ -127,7 +127,7 @@ Bot.prototype.handleRelog = async function() { this.loginData.relogTries++; // Check if proxy might be offline - let proxySwitched = await this.checkAndSwitchMyProxy(); + const proxySwitched = await this.checkAndSwitchMyProxy(); if (proxySwitched) return; // Stop execution if proxy was switched and bot is getting relogged diff --git a/src/bot/helpers/steamChatInteraction.js b/src/bot/helpers/steamChatInteraction.js index 237547a6..1dc721b1 100644 --- a/src/bot/helpers/steamChatInteraction.js +++ b/src/bot/helpers/steamChatInteraction.js @@ -39,8 +39,8 @@ Bot.prototype.sendChatMessage = function(_this, resInfo, txt, retry = 0, part = if (!txt) return logger("warn", "sendChatMessage() was called without any message content! Ignoring call..."); if (typeof txt !== "string") return logger("warn", "sendChatMessage() was called with txt that isn't a string! Ignoring call..."); - let steamID64 = resInfo.userID; - let username = _this.user.users[steamID64] ? _this.user.users[steamID64].player_name : ""; // Set username to nothing in case they are not cached yet to avoid errors + const steamID64 = resInfo.userID; + const username = _this.user.users[steamID64] ? _this.user.users[steamID64].player_name : ""; // Set username to nothing in case they are not cached yet to avoid errors let relationshipStatus = SteamUser.EFriendRelationship.None; if (_this.user.myFriends[steamID64]) relationshipStatus = SteamUser.EFriendRelationship[_this.user.myFriends[steamID64]]; @@ -50,14 +50,14 @@ Bot.prototype.sendChatMessage = function(_this, resInfo, txt, retry = 0, part = if (resInfo.charLimit) limit = resInfo.charLimit; // Allow resInfo to overwrite cutStringsIntelligently's cutChars - let cutChars = resInfo.cutChars || null; + const cutChars = resInfo.cutChars || null; // Check if message should be sent without a prefix and set it to an empty string if (!resInfo.prefix) resInfo.prefix = ""; else resInfo.prefix += " "; // Add whitespace between prefix and message content // Get the correct part to send without breaking links and add prefix infront - let thisPart = resInfo.prefix + cutStringsIntelligently(txt, limit, cutChars)[part]; + const thisPart = resInfo.prefix + cutStringsIntelligently(txt, limit, cutChars)[part]; // Log full message if in debug mode, otherwise log cut down version if (_this.controller.data.advancedconfig.printDebug) { @@ -133,8 +133,8 @@ Bot.prototype.readChatMessage = function(steamID64, timeout) { this.friendMessageBlock.push(steamID64); // Provide function to handle event - let handleEvent = (steamID, message) => { // ES6 function to keep previous context - let msgSteamID64 = new SteamID(String(steamID)).getSteamID64(); + const handleEvent = (steamID, message) => { // ES6 function to keep previous context + const msgSteamID64 = new SteamID(String(steamID)).getSteamID64(); if (msgSteamID64 != steamID64) return; // Ignore if not from our user diff --git a/src/commands/commandHandler.js b/src/commands/commandHandler.js index 7e9eba15..9fd4bc43 100644 --- a/src/commands/commandHandler.js +++ b/src/commands/commandHandler.js @@ -152,7 +152,7 @@ CommandHandler.prototype.registerCommand = function(command) { CommandHandler.prototype.unregisterCommand = function(commandName) { // Iterate through all command objects in commands array and check if name is included in names array of each command. - let thisCmd = this.commands.find(e => e.names.includes(commandName)); + const thisCmd = this.commands.find(e => e.names.includes(commandName)); if (!thisCmd) { logger("warn", `CommandHandler unregisterCommand(): Command '${commandName}' was not found!`); @@ -160,7 +160,7 @@ CommandHandler.prototype.unregisterCommand = function(commandName) { } // Remove command from commands array - let index = this.commands.indexOf(thisCmd); + const index = this.commands.indexOf(thisCmd); this.commands.splice(index, index + 1); @@ -195,7 +195,7 @@ CommandHandler.prototype.unregisterCommand = function(commandName) { CommandHandler.prototype.runCommand = async function(name, args, respondModule, context, resInfo) { // Iterate through all command objects in commands array and check if name is included in names array of each command. - let thisCmd = this.commands.find(e => e.names.includes(name)); + const thisCmd = this.commands.find(e => e.names.includes(name)); if (!thisCmd) { logger("warn", `CommandHandler runCommand(): Command '${name}' was not found!`); diff --git a/src/commands/core/block.js b/src/commands/core/block.js index 88d056e3..c4832797 100644 --- a/src/commands/core/block.js +++ b/src/commands/core/block.js @@ -43,7 +43,7 @@ module.exports.block = { * @param {CommandHandler.resInfo} resInfo Object containing additional information your respondModule might need to process the response (for example the userID who executed the command). */ run: async (commandHandler, args, respondModule, context, resInfo) => { - let respond = ((txt) => respondModule(context, resInfo, txt)); // Shorten each call + const respond = ((txt) => respondModule(context, resInfo, txt)); // Shorten each call if (commandHandler.controller.info.readyAfter == 0) return respondModule(context, { prefix: "/me", ...resInfo }, await commandHandler.data.getLang("botnotready", null, resInfo.userID)); // Check if bot isn't fully started yet - Pass new resInfo object which contains prefix and everything the original resInfo obj contained @@ -91,7 +91,7 @@ module.exports.unblock = { * @param {CommandHandler.resInfo} resInfo Object containing additional information your respondModule might need to process the response (for example the userID who executed the command). */ run: async (commandHandler, args, respondModule, context, resInfo) => { - let respond = ((txt) => respondModule(context, resInfo, txt)); // Shorten each call + const respond = ((txt) => respondModule(context, resInfo, txt)); // Shorten each call if (commandHandler.controller.info.readyAfter == 0) return respondModule(context, { prefix: "/me", ...resInfo }, await commandHandler.data.getLang("botnotready", null, resInfo.userID)); // Check if bot isn't fully started yet - Pass new resInfo object which contains prefix and everything the original resInfo obj contained diff --git a/src/commands/core/comment.js b/src/commands/core/comment.js index 483af322..deaf1763 100644 --- a/src/commands/core/comment.js +++ b/src/commands/core/comment.js @@ -4,7 +4,7 @@ * Created Date: 2021-07-09 16:26:00 * Author: 3urobeat * - * Last Modified: 2024-05-03 13:08:59 + * Last Modified: 2024-05-04 22:02:28 * Modified By: 3urobeat * * Copyright (c) 2021 - 2024 3urobeat @@ -59,15 +59,15 @@ module.exports.comment = { * @param {CommandHandler.resInfo} resInfo Object containing additional information your respondModule might need to process the response (for example the userID who executed the command). */ run: async (commandHandler, args, respondModule, context, resInfo) => { - let respond = ((txt) => respondModule(context, resInfo, txt)); // Shorten each call + const respond = ((txt) => respondModule(context, resInfo, txt)); // Shorten each call // Get the correct ownerid array for this request let owners = commandHandler.data.cachefile.ownerid; if (resInfo.ownerIDs && resInfo.ownerIDs.length > 0) owners = resInfo.ownerIDs; - let requesterID = resInfo.userID; + const requesterID = resInfo.userID; let receiverSteamID64 = requesterID; - let ownercheck = owners.includes(requesterID); + const ownercheck = owners.includes(requesterID); /* --------- Various checks --------- */ @@ -84,7 +84,7 @@ module.exports.comment = { /* --------- Calculate maxRequestAmount and get arguments from comment request --------- */ - let { maxRequestAmount, numberOfComments, profileID, idType, quotesArr } = await getCommentArgs(commandHandler, args, resInfo, respond); + const { maxRequestAmount, numberOfComments, profileID, idType, quotesArr } = await getCommentArgs(commandHandler, args, resInfo, respond); if (!maxRequestAmount && !numberOfComments && !quotesArr) return; // Looks like the helper aborted the request @@ -101,20 +101,20 @@ module.exports.comment = { // Check if user is already receiving comments right now - let activeReqEntry = commandHandler.controller.activeRequests[receiverSteamID64]; + const activeReqEntry = commandHandler.controller.activeRequests[receiverSteamID64]; if (activeReqEntry && activeReqEntry.status == "active") return respond(await commandHandler.data.getLang("idalreadyreceiving", null, requesterID)); // Check if user has cooldown - let { until, untilStr } = await commandHandler.data.getUserCooldown(requesterID); + const { until, untilStr } = await commandHandler.data.getUserCooldown(requesterID); if (until > Date.now()) return respond(await commandHandler.data.getLang("idoncooldown", { "remainingcooldown": untilStr }, requesterID)); // Get all currently available bot accounts. Block limited accounts from being eligible from commenting in groups - let allowLimitedAccounts = (idType != "group"); - let { accsNeeded, availableAccounts, accsToAdd, whenAvailableStr } = await getAvailableBotsForCommenting(commandHandler, numberOfComments, allowLimitedAccounts, idType, receiverSteamID64); // Await *has* an effect on this expression you idiot + const allowLimitedAccounts = (idType != "group"); + const { accsNeeded, availableAccounts, accsToAdd, whenAvailableStr } = await getAvailableBotsForCommenting(commandHandler, numberOfComments, allowLimitedAccounts, idType, receiverSteamID64); // Await *has* an effect on this expression you idiot if (availableAccounts.length == 0 && !whenAvailableStr) { // Check if this bot has no suitable accounts for this request and there won't be any available at any point if (!allowLimitedAccounts) respond(await commandHandler.data.getLang("genericnounlimitedaccs", { "cmdprefix": resInfo.cmdprefix }, requesterID)); // Send less generic message for requests which require unlimited accounts @@ -143,7 +143,7 @@ module.exports.comment = { // Prepare activeRequests entry - let activeRequestsObj = { + const activeRequestsObj = { status: "active", type: idType + "Comment", // Add "Comment" to the end of type to differentiate a comment process from other requests amount: numberOfComments, @@ -240,7 +240,7 @@ module.exports.comment = { // Start commenting logger("debug", "Made activeRequest entry for user, starting comment loop..."); - comment(commandHandler, resInfo, respond, postComment, commentArgs, receiverSteamID64); + comment(commandHandler, resInfo, respond, postComment, commentArgs, receiverSteamID64); // eslint-disable-line no-use-before-define } }; @@ -255,19 +255,19 @@ module.exports.comment = { * @param {string} receiverSteamID64 steamID64 of the profile to receive the comments */ async function comment(commandHandler, resInfo, respond, postComment, commentArgs, receiverSteamID64) { - let activeReqEntry = commandHandler.controller.activeRequests[receiverSteamID64]; // Make using the obj shorter - let requesterID = resInfo.userID; + const activeReqEntry = commandHandler.controller.activeRequests[receiverSteamID64]; // Make using the obj shorter + const requesterID = resInfo.userID; // Log request start and give user cooldown on the first iteration - let whereStr = activeReqEntry.type == "profileComment" ? `on profile ${receiverSteamID64}` : `in/on ${activeReqEntry.type.replace("Comment", "")} ${receiverSteamID64}`; // Shortcut to convey more precise information in the 4 log messages below + const whereStr = activeReqEntry.type == "profileComment" ? `on profile ${receiverSteamID64}` : `in/on ${activeReqEntry.type.replace("Comment", "")} ${receiverSteamID64}`; // Shortcut to convey more precise information in the 4 log messages below if (activeReqEntry.thisIteration == -1) { logger("info", `${logger.colors.fggreen}[${commandHandler.controller.main.logPrefix}] ${activeReqEntry.amount} Comment(s) requested. Starting to comment ${whereStr}...`); // Only send estimated wait time message for multiple comments if (activeReqEntry.amount > 1) { - let waitTime = timeToString(Date.now() + ((activeReqEntry.amount - 1) * commandHandler.data.config.requestDelay)); // Amount - 1 because the first comment is instant. Multiply by delay and add to current time to get timestamp when last comment was sent + const waitTime = timeToString(Date.now() + ((activeReqEntry.amount - 1) * commandHandler.data.config.requestDelay)); // Amount - 1 because the first comment is instant. Multiply by delay and add to current time to get timestamp when last comment was sent respond(await commandHandler.data.getLang("commentprocessstarted", { "numberOfComments": activeReqEntry.amount, "waittime": waitTime }, requesterID)); } @@ -284,7 +284,7 @@ async function comment(commandHandler, resInfo, respond, postComment, commentArg setTimeout(async () => { /* --------- Get the correct account for this iteration and update iteration in activeRequests obj --------- */ - let bot = commandHandler.controller.getBots("*", true)[activeReqEntry.accounts[i % activeReqEntry.accounts.length]]; // Iteration modulo amount of accounts gives us index of account to use inside the accounts array. This returns the bot account name which we can lookup in the bots object. + const bot = commandHandler.controller.getBots("*", true)[activeReqEntry.accounts[i % activeReqEntry.accounts.length]]; // Iteration modulo amount of accounts gives us index of account to use inside the accounts array. This returns the bot account name which we can lookup in the bots object. activeReqEntry.thisIteration++; @@ -293,7 +293,7 @@ async function comment(commandHandler, resInfo, respond, postComment, commentArg /* --------- Try to comment --------- */ - let quote = await commandHandler.data.getQuote(activeReqEntry.quotesArr); // Get a random quote to comment with + const quote = await commandHandler.data.getQuote(activeReqEntry.quotesArr); // Get a random quote to comment with commentArgs["quote"] = quote; // Replace key "quote" in args obj postComment.call(bot.community, ...Object.values(commentArgs), (error) => { // Very important! Using call() and passing the bot's community instance will keep context (this.) as it was lost by our postComment variable assignment! @@ -336,7 +336,7 @@ async function comment(commandHandler, resInfo, respond, postComment, commentArg activeReqEntry.retryAttempt++; // Log and notify user about retry attempt starting in retryFailedCommentsDelay ms - let untilStr = timeToString(Date.now() + commandHandler.data.advancedconfig.retryFailedCommentsDelay); + const untilStr = timeToString(Date.now() + commandHandler.data.advancedconfig.retryFailedCommentsDelay); respond(await commandHandler.data.getLang("commentretrying", { "failedamount": Object.keys(activeReqEntry.failed).length, "numberOfComments": activeReqEntry.amount - activeReqEntry.amountBeforeRetry, "untilStr": untilStr, "thisattempt": activeReqEntry.retryAttempt, "maxattempt": commandHandler.data.advancedconfig.retryFailedCommentsAttempts }, requesterID)); logger("info", `${Object.keys(activeReqEntry.failed).length}/${activeReqEntry.amount - activeReqEntry.amountBeforeRetry} comments failed for ${receiverSteamID64}. Retrying in ${untilStr} (Attempt ${activeReqEntry.retryAttempt}/${commandHandler.data.advancedconfig.retryFailedCommentsAttempts})`, false, false, logger.animation("waiting")); diff --git a/src/commands/core/favorite.js b/src/commands/core/favorite.js index e86b317f..bc76a81c 100644 --- a/src/commands/core/favorite.js +++ b/src/commands/core/favorite.js @@ -52,14 +52,14 @@ module.exports.favorite = { * @param {CommandHandler.resInfo} resInfo Object containing additional information your respondModule might need to process the response (for example the userID who executed the command). */ run: async (commandHandler, args, respondModule, context, resInfo) => { - let respond = ((txt) => respondModule(context, resInfo, txt)); // Shorten each call + const respond = ((txt) => respondModule(context, resInfo, txt)); // Shorten each call // Get the correct ownerid array for this request let owners = commandHandler.data.cachefile.ownerid; if (resInfo.ownerIDs && resInfo.ownerIDs.length > 0) owners = resInfo.ownerIDs; - let requesterID = resInfo.userID; - let ownercheck = owners.includes(requesterID); + const requesterID = resInfo.userID; + const ownercheck = owners.includes(requesterID); /* --------- Various checks --------- */ @@ -73,25 +73,25 @@ module.exports.favorite = { // Check and get arguments from user - let { amountRaw, id } = await getMiscArgs(commandHandler, args, "favorite", resInfo, respond); + const { amountRaw, id } = await getMiscArgs(commandHandler, args, "favorite", resInfo, respond); if (!amountRaw && !id) return; // Looks like the helper aborted the request // Check if this id is already receiving something right now - let idReq = commandHandler.controller.activeRequests[id]; + const idReq = commandHandler.controller.activeRequests[id]; if (idReq && idReq.status == "active") return respond(await commandHandler.data.getLang("idalreadyreceiving", null, requesterID)); // Note: No need to check for user as that is supposed to be handled by a cooldown // Check if user has cooldown - let { until, untilStr } = await commandHandler.data.getUserCooldown(requesterID); + const { until, untilStr } = await commandHandler.data.getUserCooldown(requesterID); if (until > Date.now()) return respond(await commandHandler.data.getLang("idoncooldown", { "remainingcooldown": untilStr }, requesterID)); // Get all available bot accounts - let { amount, availableAccounts, whenAvailableStr } = await getAvailableBotsForFavorizing(commandHandler, amountRaw, id, "favorite"); + const { amount, availableAccounts, whenAvailableStr } = await getAvailableBotsForFavorizing(commandHandler, amountRaw, id, "favorite"); if ((availableAccounts.length < amount || availableAccounts.length == 0) && !whenAvailableStr) { // Check if this bot has not enough accounts suitable for this request and there won't be more available at any point. if (availableAccounts.length == 0) respond(await commandHandler.data.getLang("genericnoaccounts", null, requesterID)); // The < || == 0 check is intentional, as providing "all" will set amount to 0 if 0 accounts have been found @@ -127,7 +127,7 @@ module.exports.favorite = { failed: {} }; - let activeReqEntry = commandHandler.controller.activeRequests[id]; // Make using the obj shorter + const activeReqEntry = commandHandler.controller.activeRequests[id]; // Make using the obj shorter // Log request start and give user cooldown on the first iteration @@ -136,7 +136,7 @@ module.exports.favorite = { // Only send estimated wait time message for multiple favorites if (activeReqEntry.amount > 1) { - let waitTime = timeToString(Date.now() + ((activeReqEntry.amount - 1) * commandHandler.data.config.requestDelay)); // Amount - 1 because the first fav is instant. Multiply by delay and add to current time to get timestamp when last fav was sent + const waitTime = timeToString(Date.now() + ((activeReqEntry.amount - 1) * commandHandler.data.config.requestDelay)); // Amount - 1 because the first fav is instant. Multiply by delay and add to current time to get timestamp when last fav was sent respond(await commandHandler.data.getLang("favoriteprocessstarted", { "numberOfFavs": activeReqEntry.amount, "waittime": waitTime }, requesterID)); } @@ -151,7 +151,7 @@ module.exports.favorite = { syncLoop(amount, (loop, i) => { setTimeout(() => { - let bot = commandHandler.controller.bots[availableAccounts[i]]; + const bot = commandHandler.controller.bots[availableAccounts[i]]; activeReqEntry.thisIteration++; if (!handleFavoriteIterationSkip(commandHandler, loop, bot, id)) return; // Skip iteration if false was returned @@ -250,14 +250,14 @@ module.exports.unfavorite = { * @param {CommandHandler.resInfo} resInfo Object containing additional information your respondModule might need to process the response (for example the userID who executed the command). */ run: async (commandHandler, args, respondModule, context, resInfo) => { - let respond = ((txt) => respondModule(context, resInfo, txt)); // Shorten each call + const respond = ((txt) => respondModule(context, resInfo, txt)); // Shorten each call // Get the correct ownerid array for this request let owners = commandHandler.data.cachefile.ownerid; if (resInfo.ownerIDs && resInfo.ownerIDs.length > 0) owners = resInfo.ownerIDs; - let requesterID = resInfo.userID; - let ownercheck = owners.includes(requesterID); + const requesterID = resInfo.userID; + const ownercheck = owners.includes(requesterID); /* --------- Various checks --------- */ @@ -271,25 +271,25 @@ module.exports.unfavorite = { // Check and get arguments from user - let { amountRaw, id } = await getMiscArgs(commandHandler, args, "unfavorite", resInfo, respond); + const { amountRaw, id } = await getMiscArgs(commandHandler, args, "unfavorite", resInfo, respond); if (!amountRaw && !id) return; // Looks like the helper aborted the request // Check if this id is already receiving something right now - let idReq = commandHandler.controller.activeRequests[id]; + const idReq = commandHandler.controller.activeRequests[id]; if (idReq && idReq.status == "active") return respond(await commandHandler.data.getLang("idalreadyreceiving", null, requesterID)); // Note: No need to check for user as that is supposed to be handled by a cooldown // Check if user has cooldown - let { until, untilStr } = await commandHandler.data.getUserCooldown(requesterID); + const { until, untilStr } = await commandHandler.data.getUserCooldown(requesterID); if (until > Date.now()) return respond(await commandHandler.data.getLang("idoncooldown", { "remainingcooldown": untilStr }, requesterID)); // Get all available bot accounts - let { amount, availableAccounts, whenAvailableStr } = await getAvailableBotsForFavorizing(commandHandler, amountRaw, id, "unfavorite"); + const { amount, availableAccounts, whenAvailableStr } = await getAvailableBotsForFavorizing(commandHandler, amountRaw, id, "unfavorite"); if ((availableAccounts.length < amount || availableAccounts.length == 0) && !whenAvailableStr) { // Check if this bot has not enough accounts suitable for this request and there won't be more available at any point. if (availableAccounts.length == 0) respond(await commandHandler.data.getLang("genericnoaccounts", null, requesterID)); // The < || == 0 check is intentional, as providing "all" will set amount to 0 if 0 accounts have been found @@ -325,7 +325,7 @@ module.exports.unfavorite = { failed: {} }; - let activeReqEntry = commandHandler.controller.activeRequests[id]; // Make using the obj shorter + const activeReqEntry = commandHandler.controller.activeRequests[id]; // Make using the obj shorter // Log request start and give user cooldown on the first iteration @@ -334,7 +334,7 @@ module.exports.unfavorite = { // Only send estimated wait time message for multiple favorites if (activeReqEntry.amount > 1) { - let waitTime = timeToString(Date.now() + ((activeReqEntry.amount - 1) * commandHandler.data.config.requestDelay)); // Amount - 1 because the first fav is instant. Multiply by delay and add to current time to get timestamp when last fav was sent + const waitTime = timeToString(Date.now() + ((activeReqEntry.amount - 1) * commandHandler.data.config.requestDelay)); // Amount - 1 because the first fav is instant. Multiply by delay and add to current time to get timestamp when last fav was sent respond(await commandHandler.data.getLang("favoriteprocessstarted", { "numberOfFavs": activeReqEntry.amount, "waittime": waitTime }, requesterID)); } @@ -349,7 +349,7 @@ module.exports.unfavorite = { syncLoop(amount, (loop, i) => { setTimeout(() => { - let bot = commandHandler.controller.bots[availableAccounts[i]]; + const bot = commandHandler.controller.bots[availableAccounts[i]]; activeReqEntry.thisIteration++; if (!handleFavoriteIterationSkip(commandHandler, loop, bot, id)) return; // Skip iteration if false was returned diff --git a/src/commands/core/follow.js b/src/commands/core/follow.js index 2af03768..853ba845 100644 --- a/src/commands/core/follow.js +++ b/src/commands/core/follow.js @@ -52,14 +52,14 @@ module.exports.follow = { * @param {CommandHandler.resInfo} resInfo Object containing additional information your respondModule might need to process the response (for example the userID who executed the command). */ run: async (commandHandler, args, respondModule, context, resInfo) => { - let respond = ((txt) => respondModule(context, resInfo, txt)); // Shorten each call + const respond = ((txt) => respondModule(context, resInfo, txt)); // Shorten each call // Get the correct ownerid array for this request let owners = commandHandler.data.cachefile.ownerid; if (resInfo.ownerIDs && resInfo.ownerIDs.length > 0) owners = resInfo.ownerIDs; - let requesterID = resInfo.userID; - let ownercheck = owners.includes(requesterID); + const requesterID = resInfo.userID; + const ownercheck = owners.includes(requesterID); /* --------- Various checks --------- */ @@ -73,26 +73,26 @@ module.exports.follow = { // Check and get arguments from user - let { amountRaw, id, idType } = await getFollowArgs(commandHandler, args, "follow", resInfo, respond); + const { amountRaw, id, idType } = await getFollowArgs(commandHandler, args, "follow", resInfo, respond); if (!amountRaw && !id) return; // Looks like the helper aborted the request // Check if this id is already receiving something right now - let idReq = commandHandler.controller.activeRequests[id]; + const idReq = commandHandler.controller.activeRequests[id]; if (idReq && idReq.status == "active") return respond(await commandHandler.data.getLang("idalreadyreceiving", null, requesterID)); // Note: No need to check for user as that is supposed to be handled by a cooldown // Check if user has cooldown - let { until, untilStr } = await commandHandler.data.getUserCooldown(requesterID); + const { until, untilStr } = await commandHandler.data.getUserCooldown(requesterID); if (until > Date.now()) return respond(await commandHandler.data.getLang("idoncooldown", { "remainingcooldown": untilStr }, requesterID)); // Get all available bot accounts. Block limited accounts from following curators - let allowLimitedAccounts = (idType != "curator"); - let { amount, availableAccounts, whenAvailableStr } = await getAvailableBotsForFollowing(commandHandler, amountRaw, allowLimitedAccounts, id, idType, "follow", resInfo); + const allowLimitedAccounts = (idType != "curator"); + const { amount, availableAccounts, whenAvailableStr } = await getAvailableBotsForFollowing(commandHandler, amountRaw, allowLimitedAccounts, id, idType, "follow", resInfo); if ((availableAccounts.length < amount || availableAccounts.length == 0) && !whenAvailableStr) { // Check if this bot has not enough accounts suitable for this request and there won't be more available at any point. The < || == 0 check is intentional, as providing "all" will set amount to 0 if 0 accounts have been found if (availableAccounts.length == 0) { @@ -124,7 +124,7 @@ module.exports.follow = { failed: {} }; - let activeReqEntry = commandHandler.controller.activeRequests[id]; // Make using the obj shorter + const activeReqEntry = commandHandler.controller.activeRequests[id]; // Make using the obj shorter // Log request start and give user cooldown on the first iteration @@ -133,7 +133,7 @@ module.exports.follow = { // Only send estimated wait time message for multiple follow if (activeReqEntry.amount > 1) { - let waitTime = timeToString(Date.now() + ((activeReqEntry.amount - 1) * commandHandler.data.config.requestDelay)); // Amount - 1 because the first fav is instant. Multiply by delay and add to current time to get timestamp when last fav was sent + const waitTime = timeToString(Date.now() + ((activeReqEntry.amount - 1) * commandHandler.data.config.requestDelay)); // Amount - 1 because the first fav is instant. Multiply by delay and add to current time to get timestamp when last fav was sent respond(await commandHandler.data.getLang("followprocessstarted", { "totalamount": activeReqEntry.amount, "waittime": waitTime }, requesterID)); } @@ -148,7 +148,7 @@ module.exports.follow = { syncLoop(amount, (loop, i) => { setTimeout(() => { - let bot = commandHandler.controller.bots[availableAccounts[i]]; + const bot = commandHandler.controller.bots[availableAccounts[i]]; activeReqEntry.thisIteration++; if (!handleFollowIterationSkip(commandHandler, loop, bot, id)) return; // Skip iteration if false was returned @@ -248,14 +248,14 @@ module.exports.unfollow = { * @param {CommandHandler.resInfo} resInfo Object containing additional information your respondModule might need to process the response (for example the userID who executed the command). */ run: async (commandHandler, args, respondModule, context, resInfo) => { - let respond = ((txt) => respondModule(context, resInfo, txt)); // Shorten each call + const respond = ((txt) => respondModule(context, resInfo, txt)); // Shorten each call // Get the correct ownerid array for this request let owners = commandHandler.data.cachefile.ownerid; if (resInfo.ownerIDs && resInfo.ownerIDs.length > 0) owners = resInfo.ownerIDs; - let requesterID = resInfo.userID; - let ownercheck = owners.includes(requesterID); + const requesterID = resInfo.userID; + const ownercheck = owners.includes(requesterID); /* --------- Various checks --------- */ @@ -269,26 +269,26 @@ module.exports.unfollow = { // Check and get arguments from user - let { amountRaw, id, idType } = await getFollowArgs(commandHandler, args, "unfollow", resInfo, respond); + const { amountRaw, id, idType } = await getFollowArgs(commandHandler, args, "unfollow", resInfo, respond); if (!amountRaw && !id) return; // Looks like the helper aborted the request // Check if this id is already receiving something right now - let idReq = commandHandler.controller.activeRequests[id]; + const idReq = commandHandler.controller.activeRequests[id]; if (idReq && idReq.status == "active") return respond(await commandHandler.data.getLang("idalreadyreceiving", null, requesterID)); // Note: No need to check for user as that is supposed to be handled by a cooldown // Check if user has cooldown - let { until, untilStr } = await commandHandler.data.getUserCooldown(requesterID); + const { until, untilStr } = await commandHandler.data.getUserCooldown(requesterID); if (until > Date.now()) return respond(await commandHandler.data.getLang("idoncooldown", { "remainingcooldown": untilStr }, requesterID)); // Get all available bot accounts. Block limited accounts from following curators - let allowLimitedAccounts = (idType != "curator"); - let { amount, availableAccounts, whenAvailableStr } = await getAvailableBotsForFollowing(commandHandler, amountRaw, allowLimitedAccounts, id, idType, "unfollow", resInfo); + const allowLimitedAccounts = (idType != "curator"); + const { amount, availableAccounts, whenAvailableStr } = await getAvailableBotsForFollowing(commandHandler, amountRaw, allowLimitedAccounts, id, idType, "unfollow", resInfo); if ((availableAccounts.length < amount || availableAccounts.length == 0) && !whenAvailableStr) { // Check if this bot has not enough accounts suitable for this request and there won't be more available at any point. The < || == 0 check is intentional, as providing "all" will set amount to 0 if 0 accounts have been found if (availableAccounts.length == 0) { @@ -320,7 +320,7 @@ module.exports.unfollow = { failed: {} }; - let activeReqEntry = commandHandler.controller.activeRequests[id]; // Make using the obj shorter + const activeReqEntry = commandHandler.controller.activeRequests[id]; // Make using the obj shorter // Log request start and give user cooldown on the first iteration @@ -329,7 +329,7 @@ module.exports.unfollow = { // Only send estimated wait time message for multiple unfollow if (activeReqEntry.amount > 1) { - let waitTime = timeToString(Date.now() + ((activeReqEntry.amount - 1) * commandHandler.data.config.requestDelay)); // Amount - 1 because the first fav is instant. Multiply by delay and add to current time to get timestamp when last fav was sent + const waitTime = timeToString(Date.now() + ((activeReqEntry.amount - 1) * commandHandler.data.config.requestDelay)); // Amount - 1 because the first fav is instant. Multiply by delay and add to current time to get timestamp when last fav was sent respond(await commandHandler.data.getLang("followprocessstarted", { "totalamount": activeReqEntry.amount, "waittime": waitTime }, requesterID)); } @@ -344,7 +344,7 @@ module.exports.unfollow = { syncLoop(amount, (loop, i) => { setTimeout(() => { - let bot = commandHandler.controller.bots[availableAccounts[i]]; + const bot = commandHandler.controller.bots[availableAccounts[i]]; activeReqEntry.thisIteration++; if (!handleFollowIterationSkip(commandHandler, loop, bot, id)) return; // Skip iteration if false was returned diff --git a/src/commands/core/friend.js b/src/commands/core/friend.js index 1c9962a8..67c23623 100644 --- a/src/commands/core/friend.js +++ b/src/commands/core/friend.js @@ -43,8 +43,8 @@ module.exports.addFriend = { * @param {CommandHandler.resInfo} resInfo Object containing additional information your respondModule might need to process the response (for example the userID who executed the command). */ run: async (commandHandler, args, respondModule, context, resInfo) => { - let respond = ((txt) => respondModule(context, resInfo, txt)); // Shorten each call - let requesterID = resInfo.userID; + const respond = ((txt) => respondModule(context, resInfo, txt)); // Shorten each call + const requesterID = resInfo.userID; if (commandHandler.controller.info.readyAfter == 0) return respondModule(context, { prefix: "/me", ...resInfo }, await commandHandler.data.getLang("botnotready", null, requesterID)); // Check if bot isn't fully started yet - Pass new resInfo object which contains prefix and everything the original resInfo obj contained @@ -112,8 +112,8 @@ module.exports.unfriend = { * @param {CommandHandler.resInfo} resInfo Object containing additional information your respondModule might need to process the response (for example the userID who executed the command). */ run: async (commandHandler, args, respondModule, context, resInfo) => { - let respond = ((txt) => respondModule(context, resInfo, txt)); // Shorten each call - let requesterID = resInfo.userID; + const respond = ((txt) => respondModule(context, resInfo, txt)); // Shorten each call + const requesterID = resInfo.userID; if (commandHandler.controller.info.readyAfter == 0) return respondModule(context, { prefix: "/me", ...resInfo }, await commandHandler.data.getLang("botnotready", null, requesterID)); // Check if bot isn't fully started yet - Pass new resInfo object which contains prefix and everything the original resInfo obj contained @@ -181,8 +181,8 @@ module.exports.unfriendall = { * @param {CommandHandler.resInfo} resInfo Object containing additional information your respondModule might need to process the response (for example the userID who executed the command). */ run: async (commandHandler, args, respondModule, context, resInfo) => { - let respond = ((txt) => respondModule(context, resInfo, txt)); // Shorten each call - let requesterID = resInfo.userID; + const respond = ((txt) => respondModule(context, resInfo, txt)); // Shorten each call + const requesterID = resInfo.userID; if (commandHandler.controller.info.readyAfter == 0) return respondModule(context, { prefix: "/me", ...resInfo }, await commandHandler.data.getLang("botnotready", null, requesterID)); // Check if bot isn't fully started yet - Pass new resInfo object which contains prefix and everything the original resInfo obj contained @@ -203,10 +203,10 @@ module.exports.unfriendall = { logger("info", "Starting to unfriend everyone..."); for (let i = 0; i < commandHandler.controller.getBots().length; i++) { - for (let friend in commandHandler.controller.getBots()[i].user.myFriends) { + for (const friend in commandHandler.controller.getBots()[i].user.myFriends) { try { setTimeout(() => { - let friendSteamID = new SteamID(String(friend)); + const friendSteamID = new SteamID(String(friend)); if (!commandHandler.data.cachefile.ownerid.includes(friend)) { // Check for the "original" ownerid array here, we don't care about non Steam IDs logger("info", `Removing friend ${friendSteamID.getSteamID64()} from all bot accounts...`, false, false, logger.animation("loading")); diff --git a/src/commands/core/general.js b/src/commands/core/general.js index 41d513aa..69d3d52a 100644 --- a/src/commands/core/general.js +++ b/src/commands/core/general.js @@ -37,8 +37,8 @@ module.exports.help = { * @param {CommandHandler.resInfo} resInfo Object containing additional information your respondModule might need to process the response (for example the userID who executed the command). */ run: async (commandHandler, args, respondModule, context, resInfo) => { - let respond = ((txt) => respondModule(context, resInfo, txt)); // Shorten each call - let requesterID = resInfo.userID; + const respond = ((txt) => respondModule(context, resInfo, txt)); // Shorten each call + const requesterID = resInfo.userID; // Get the correct ownerid array for this request let owners = commandHandler.data.cachefile.ownerid; @@ -99,14 +99,14 @@ module.exports.info = { * @param {CommandHandler.resInfo} resInfo Object containing additional information your respondModule might need to process the response (for example the userID who executed the command). */ run: (commandHandler, args, respondModule, context, resInfo) => { - let respond = ((txt) => respondModule(context, resInfo, txt)); // Shorten each call + const respond = ((txt) => respondModule(context, resInfo, txt)); // Shorten each call // Get the correct ownerid array for this request let owners = commandHandler.data.cachefile.ownerid; if (resInfo.ownerIDs && resInfo.ownerIDs.length > 0) owners = resInfo.ownerIDs; commandHandler.data.lastCommentDB.findOne({ id: resInfo.userID }, async (err, doc) => { - let lastReq = await commandHandler.data.getLastCommentRequest(); + const lastReq = await commandHandler.data.getLastCommentRequest(); let userLastReq = "Never"; if (doc) userLastReq = ((new Date(doc.time)).toISOString().replace(/T/, " ").replace(/\..+/, "")) + " (GMT time)"; @@ -146,8 +146,8 @@ module.exports.ping = { * @param {CommandHandler.resInfo} resInfo Object containing additional information your respondModule might need to process the response (for example the userID who executed the command). */ run: (commandHandler, args, respondModule, context, resInfo) => { - let respond = ((txt) => respondModule(context, resInfo, txt)); // Shorten each call - let pingStart = Date.now(); + const respond = ((txt) => respondModule(context, resInfo, txt)); // Shorten each call + const pingStart = Date.now(); https.get("https://steamcommunity.com/ping", (res) => { // Ping steamcommunity.com/ping and measure time res.setEncoding("utf8"); @@ -173,7 +173,7 @@ module.exports.about = { * @param {CommandHandler.resInfo} resInfo Object containing additional information your respondModule might need to process the response (for example the userID who executed the command). */ run: (commandHandler, args, respondModule, context, resInfo) => { - let respond = ((txt) => respondModule(context, resInfo, txt)); // Shorten each call + const respond = ((txt) => respondModule(context, resInfo, txt)); // Shorten each call respond(commandHandler.data.datafile.aboutstr); } @@ -195,7 +195,7 @@ module.exports.owner = { * @param {CommandHandler.resInfo} resInfo Object containing additional information your respondModule might need to process the response (for example the userID who executed the command). */ run: async (commandHandler, args, respondModule, context, resInfo) => { - let respond = ((txt) => respondModule(context, resInfo, txt)); // Shorten each call + const respond = ((txt) => respondModule(context, resInfo, txt)); // Shorten each call // Check if no owner link is set if (commandHandler.data.config.owner.length < 1) return respond(await commandHandler.data.getLang("ownercmdnolink", null, resInfo.userID)); diff --git a/src/commands/core/group.js b/src/commands/core/group.js index 4efdfbad..63bd6223 100644 --- a/src/commands/core/group.js +++ b/src/commands/core/group.js @@ -35,7 +35,7 @@ module.exports.group = { * @param {CommandHandler.resInfo} resInfo Object containing additional information your respondModule might need to process the response (for example the userID who executed the command). */ run: async (commandHandler, args, respondModule, context, resInfo) => { - let respond = ((txt) => respondModule(context, resInfo, txt)); // Shorten each call + const respond = ((txt) => respondModule(context, resInfo, txt)); // Shorten each call if (commandHandler.data.config.yourgroup.length < 1 || !commandHandler.data.cachefile.configgroup64id) return respond(await commandHandler.data.getLang("groupcmdnolink", null, resInfo.userID)); // No group info at all? stop. @@ -78,8 +78,8 @@ module.exports.joinGroup = { * @param {CommandHandler.resInfo} resInfo Object containing additional information your respondModule might need to process the response (for example the userID who executed the command). */ run: async (commandHandler, args, respondModule, context, resInfo) => { - let respond = ((txt) => respondModule(context, resInfo, txt)); // Shorten each call - let requesterID = resInfo.userID; + const respond = ((txt) => respondModule(context, resInfo, txt)); // Shorten each call + const requesterID = resInfo.userID; if (commandHandler.controller.info.readyAfter == 0) return respondModule(context, { prefix: "/me", ...resInfo }, await commandHandler.data.getLang("botnotready", null, requesterID)); // Check if bot isn't fully started yet - Pass new resInfo object which contains prefix and everything the original resInfo obj contained @@ -124,8 +124,8 @@ module.exports.leaveGroup = { * @param {CommandHandler.resInfo} resInfo Object containing additional information your respondModule might need to process the response (for example the userID who executed the command). */ run: async (commandHandler, args, respondModule, context, resInfo) => { - let respond = ((txt) => respondModule(context, resInfo, txt)); // Shorten each call - let requesterID = resInfo.userID; + const respond = ((txt) => respondModule(context, resInfo, txt)); // Shorten each call + const requesterID = resInfo.userID; if (commandHandler.controller.info.readyAfter == 0) return respondModule(context, { prefix: "/me", ...resInfo }, await commandHandler.data.getLang("botnotready", null, requesterID)); // Check if bot isn't fully started yet - Pass new resInfo object which contains prefix and everything the original resInfo obj contained @@ -170,8 +170,8 @@ module.exports.leaveAllGroups = { * @param {CommandHandler.resInfo} resInfo Object containing additional information your respondModule might need to process the response (for example the userID who executed the command). */ run: async (commandHandler, args, respondModule, context, resInfo) => { - let respond = ((txt) => respondModule(context, resInfo, txt)); // Shorten each call - let requesterID = resInfo.userID; + const respond = ((txt) => respondModule(context, resInfo, txt)); // Shorten each call + const requesterID = resInfo.userID; if (commandHandler.controller.info.readyAfter == 0) return respondModule(context, { prefix: "/me", ...resInfo }, await commandHandler.data.getLang("botnotready", null, requesterID)); // Check if bot isn't fully started yet - Pass new resInfo object which contains prefix and everything the original resInfo obj contained @@ -192,7 +192,7 @@ module.exports.leaveAllGroups = { logger("info", "Starting to leave all groups..."); for (let i = 0; i < commandHandler.controller.getBots().length; i++) { - for (let group in commandHandler.controller.getBots()[i].user.myGroups) { + for (const group in commandHandler.controller.getBots()[i].user.myGroups) { try { setTimeout(() => { if (commandHandler.controller.getBots()[i].user.myGroups[group] == 3) { diff --git a/src/commands/core/requests.js b/src/commands/core/requests.js index ce941e89..96bc6858 100644 --- a/src/commands/core/requests.js +++ b/src/commands/core/requests.js @@ -42,8 +42,8 @@ module.exports.abort = { * @param {CommandHandler.resInfo} resInfo Object containing additional information your respondModule might need to process the response (for example the userID who executed the command). */ run: async (commandHandler, args, respondModule, context, resInfo) => { - let respond = ((txt) => respondModule(context, resInfo, txt)); // Shorten each call - let requesterID = resInfo.userID; + const respond = ((txt) => respondModule(context, resInfo, txt)); // Shorten each call + const requesterID = resInfo.userID; if (commandHandler.controller.info.readyAfter == 0) return respondModule(context, { prefix: "/me", ...resInfo }, await commandHandler.data.getLang("botnotready", null, requesterID)); // Check if bot isn't fully started yet - Pass new resInfo object which contains prefix and everything the original resInfo obj contained @@ -54,7 +54,7 @@ module.exports.abort = { commandHandler.controller.handleSteamIdResolving(args[0], null, async (err, res) => { if (res) { - let activeReqEntry = commandHandler.controller.activeRequests[res]; + const activeReqEntry = commandHandler.controller.activeRequests[res]; // Get the correct ownerid array for this request let owners = commandHandler.data.cachefile.ownerid; @@ -102,8 +102,8 @@ module.exports.resetCooldown = { * @param {CommandHandler.resInfo} resInfo Object containing additional information your respondModule might need to process the response (for example the userID who executed the command). */ run: async (commandHandler, args, respondModule, context, resInfo) => { - let respond = ((txt) => respondModule(context, resInfo, txt)); // Shorten each call - let requesterID = resInfo.userID; + const respond = ((txt) => respondModule(context, resInfo, txt)); // Shorten each call + const requesterID = resInfo.userID; if (args[0] && args[0] == "global") { // Check if user wants to reset the global cooldown (will reset all until entries in activeRequests) if (commandHandler.data.config.botaccountcooldown == 0) return respond(await commandHandler.data.getLang("resetcooldowncmdcooldowndisabled", null, requesterID)); // Is the global cooldown enabled? @@ -160,7 +160,7 @@ module.exports.failed = { * @param {CommandHandler.resInfo} resInfo Object containing additional information your respondModule might need to process the response (for example the userID who executed the command). */ run: async (commandHandler, args, respondModule, context, resInfo) => { - let respond = ((txt) => respondModule(context, resInfo, txt)); // Shorten each call + const respond = ((txt) => respondModule(context, resInfo, txt)); // Shorten each call let userID = resInfo.userID; @@ -169,7 +169,7 @@ module.exports.failed = { commandHandler.controller.handleSteamIdResolving(args[0], null, async (err, res) => { if (res) { - let activeReqEntry = commandHandler.controller.activeRequests[res]; + const activeReqEntry = commandHandler.controller.activeRequests[res]; // Get the correct ownerid array for this request let owners = commandHandler.data.cachefile.ownerid; @@ -185,13 +185,13 @@ module.exports.failed = { if (!commandHandler.controller.activeRequests[userID] || Object.keys(commandHandler.controller.activeRequests[userID].failed).length < 1) return respond(await commandHandler.data.getLang("failedcmdnothingfound", null, resInfo.userID)); // Get timestamp of request - let requestTime = new Date(commandHandler.controller.activeRequests[userID].until).toISOString().replace(/T/, " ").replace(/\..+/, ""); + const requestTime = new Date(commandHandler.controller.activeRequests[userID].until).toISOString().replace(/T/, " ").replace(/\..+/, ""); // Group errors and convert them to string using helper function - let failedcommentsstr = failedCommentsObjToString(commandHandler.controller.activeRequests[userID].failed); + const failedcommentsstr = failedCommentsObjToString(commandHandler.controller.activeRequests[userID].failed); // Get start of message from lang file and add data - let messagestart = await commandHandler.data.getLang("failedcmdmsg", { "steamID64": userID, "requesttime": requestTime }, resInfo.userID); + const messagestart = await commandHandler.data.getLang("failedcmdmsg", { "steamID64": userID, "requesttime": requestTime }, resInfo.userID); // Send message and limit to 500 chars as this call can cause many messages to be sent respondModule(context, { prefix: "/pre", charLimit: 500, ...resInfo }, messagestart + "\ni = Index, b = Bot, p = Proxy\n\n" + failedcommentsstr); // Pass new resInfo object which contains prefix and everything the original resInfo obj contained @@ -215,7 +215,7 @@ module.exports.sessions = { * @param {CommandHandler.resInfo} resInfo Object containing additional information your respondModule might need to process the response (for example the userID who executed the command). */ run: async (commandHandler, args, respondModule, context, resInfo) => { - let respond = ((txt) => respondModule(context, resInfo, txt)); // Shorten each call + const respond = ((txt) => respondModule(context, resInfo, txt)); // Shorten each call // Don't bother if there is no active request if (Object.keys(commandHandler.controller.activeRequests).length == 0) return respond(await commandHandler.data.getLang("sessionscmdnosessions", null, resInfo.userID)); @@ -255,7 +255,7 @@ module.exports.mySessions = { * @param {CommandHandler.resInfo} resInfo Object containing additional information your respondModule might need to process the response (for example the userID who executed the command). */ run: async (commandHandler, args, respondModule, context, resInfo) => { - let respond = ((txt) => respondModule(context, resInfo, txt)); // Shorten each call + const respond = ((txt) => respondModule(context, resInfo, txt)); // Shorten each call // Check for no userID as the default behavior might be unavailable when calling from outside of the Steam Chat if (!resInfo.userID) return respond(await commandHandler.data.getLang("nouserid")); // In this case the cmd doesn't have an ID param so send this message instead of noidparam diff --git a/src/commands/core/settings.js b/src/commands/core/settings.js index 75ec0530..8fc03c32 100644 --- a/src/commands/core/settings.js +++ b/src/commands/core/settings.js @@ -41,7 +41,7 @@ module.exports.lang = { * @param {CommandHandler.resInfo} resInfo Object containing additional information your respondModule might need to process the response (for example the userID who executed the command). */ run: async (commandHandler, args, respondModule, context, resInfo) => { - let respond = ((txt) => respondModule(context, resInfo, txt)); // Shorten each call + const respond = ((txt) => respondModule(context, resInfo, txt)); // Shorten each call // List all supported languages by joining the keys of the data lang object with a line break and - if (!args[0]) { @@ -49,7 +49,7 @@ module.exports.lang = { return; } - let suppliedLang = args[0].toLowerCase(); + const suppliedLang = args[0].toLowerCase(); // Check if the supplied language is supported if (!Object.keys(commandHandler.data.lang).includes(suppliedLang)) { @@ -107,12 +107,12 @@ module.exports.settings = { * @param {CommandHandler.resInfo} resInfo Object containing additional information your respondModule might need to process the response (for example the userID who executed the command). */ run: async (commandHandler, args, respondModule, context, resInfo) => { - let respond = ((txt) => respondModule(context, resInfo, txt)); // Shorten each call - let config = commandHandler.data.config; + const respond = ((txt) => respondModule(context, resInfo, txt)); // Shorten each call + const config = commandHandler.data.config; // Only send current settings if no arguments were provided if (!args[0]) { - let stringifiedconfig = JSON.stringify(commandHandler.data.config, function(k, v) { // Credit: https://stackoverflow.com/a/46217335/12934162 + const stringifiedconfig = JSON.stringify(commandHandler.data.config, function(k, v) { // Credit: https://stackoverflow.com/a/46217335/12934162 if (v instanceof Array) return JSON.stringify(v); return v; }, 4) @@ -122,7 +122,7 @@ module.exports.settings = { .replace(/""/g, '""'); // Remove first and last character which are brackets and remove leading and trailing whitespaces from all lines - let currentsettingsarr = stringifiedconfig.toString().slice(1, -1).split("\n").map(s => s.trim()); + const currentsettingsarr = stringifiedconfig.toString().slice(1, -1).split("\n").map(s => s.trim()); // Send message with code prefix and only allow cuts at newlines respondModule(context, { prefix: "/code", cutChars: ["\n"], ...resInfo }, (await commandHandler.data.getLang("settingscmdcurrentsettings", null, resInfo.userID)) + "\n" + currentsettingsarr.join("\n")); // Pass new resInfo object which contains prefix and everything the original resInfo obj contained @@ -140,13 +140,13 @@ module.exports.settings = { return; } - let keyvalue = config[args[0]]; // Save old value to be able to reset changes + const keyvalue = config[args[0]]; // Save old value to be able to reset changes // Convert array-like string into usable array if (Array.isArray(keyvalue)) { try { - let newValue = args.slice(1).join(" "); // Remove first element, which is the key name and join the rest + const newValue = args.slice(1).join(" "); // Remove first element, which is the key name and join the rest args[1] = JSON.parse(newValue); // Attempt to parse user input diff --git a/src/commands/core/system.js b/src/commands/core/system.js index 7ed6568c..8fd76d8b 100644 --- a/src/commands/core/system.js +++ b/src/commands/core/system.js @@ -35,7 +35,7 @@ module.exports.jobs = { * @param {CommandHandler.resInfo} resInfo Object containing additional information your respondModule might need to process the response (for example the userID who executed the command). */ run: async (commandHandler, args, respondModule, context, resInfo) => { - let respond = ((txt) => respondModule(context, resInfo, txt)); // Shorten each call + const respond = ((txt) => respondModule(context, resInfo, txt)); // Shorten each call // Check if no job is registered and abort if (commandHandler.controller.jobManager.jobs.length == 0) { @@ -44,17 +44,17 @@ module.exports.jobs = { } // Helper function to convert lastExecTimestamp to human readable format - let convertTimestamp = (timestamp) => ((new Date(timestamp)).toISOString().replace(/T/, " ").replace(/\..+/, "")) + " (GMT time)"; + const convertTimestamp = (timestamp) => ((new Date(timestamp)).toISOString().replace(/T/, " ").replace(/\..+/, "")) + " (GMT time)"; // Construct str to respond with let str = await commandHandler.data.getLang("jobscmdregistered", null, resInfo.userID) + "\n"; commandHandler.controller.jobManager.jobs.forEach((job) => { - let desc = job.description ? "   " + job.description + "\n" : ""; // Adds job description if one was specified - let intervalFormatted = commandHandler.controller.misc.timeToString(Date.now() + job.interval); // Hack: Add current time to use timeToString for formatting (it's designed to be used in an "until from now" situation) + const desc = job.description ? "   " + job.description + "\n" : ""; // Adds job description if one was specified + const intervalFormatted = commandHandler.controller.misc.timeToString(Date.now() + job.interval); // Hack: Add current time to use timeToString for formatting (it's designed to be used in an "until from now" situation) // Only show lastExecFormatted string if lastExecTimestamp isn't the same as registeredAt (tolerance of unnecessary 100ms) or job ran upon registration. The JobManager sets _lastExecTimestamp to Date.now() on registration if runOnRegistration == false - let lastExecFormatted = job._lastExecTimestamp - job._registeredAt > 100 || job.runOnRegistration ? convertTimestamp(job._lastExecTimestamp) : "/"; + const lastExecFormatted = job._lastExecTimestamp - job._registeredAt > 100 || job.runOnRegistration ? convertTimestamp(job._lastExecTimestamp) : "/"; str += `- '${job.name}' runs every ${intervalFormatted}, last at '${lastExecFormatted}'\n${desc}\n`; }); @@ -164,10 +164,10 @@ module.exports.update = { * @param {CommandHandler.resInfo} resInfo Object containing additional information your respondModule might need to process the response (for example the userID who executed the command). */ run: async (commandHandler, args, respondModule, context, resInfo) => { - let respond = ((modResInfo, txt) => respondModule(context, modResInfo, txt)); // Shorten each call. Updater takes resInfo as param and can modify it, so we need to pass the modified resInfo object here + const respond = ((modResInfo, txt) => respondModule(context, modResInfo, txt)); // Shorten each call. Updater takes resInfo as param and can modify it, so we need to pass the modified resInfo object here // If the first argument is "true" or "force" then we shall force an update - let force = (args[0] == "true" || args[0] == "force"); + const force = (args[0] == "true" || args[0] == "force"); // Use the correct message depending on if force is true or false with a ternary operator respond({ prefix: "/me", ...resInfo }, await commandHandler.data.getLang(force ? "updatecmdforce" : "updatecmdcheck", { "branchname": commandHandler.data.datafile.branch }, resInfo.userID)); @@ -226,7 +226,7 @@ module.exports.eval = { * @param {CommandHandler.resInfo} resInfo Object containing additional information your respondModule might need to process the response (for example the userID who executed the command). */ run: async (commandHandler, args, respondModule, context, resInfo) => { - let respond = ((txt) => respondModule(context, resInfo, txt)); // Shorten each call + const respond = ((txt) => respondModule(context, resInfo, txt)); // Shorten each call if (!commandHandler.data.advancedconfig.enableevalcmd) { respondModule(context, { prefix: "/me", ...resInfo }, await commandHandler.data.getLang("evalcmdturnedoff", null, resInfo.userID)); // Pass new resInfo object which contains prefix and everything the original resInfo obj contained @@ -257,7 +257,7 @@ module.exports.eval = { }); // Check for character limit and cut message - let chatResult = clean(evaled); + const chatResult = clean(evaled); if (chatResult.length >= 500) respond(`Code executed. Result:\n\n${chatResult.slice(0, 500)}.......\n\nResult too long for chat.`); else respond(`Code executed. Result:\n\n${chatResult}`); diff --git a/src/commands/core/vote.js b/src/commands/core/vote.js index b23615a0..3de83e16 100644 --- a/src/commands/core/vote.js +++ b/src/commands/core/vote.js @@ -32,14 +32,14 @@ const { handleVoteIterationSkip, logVoteError } = require("../helpers/handleMisc * @param {CommandHandler.resInfo} resInfo Object containing additional information your respondModule might need to process the response (for example the userID who executed the command). */ async function processVoteRequest(origin, commandHandler, args, respondModule, context, resInfo) { - let respond = ((txt) => respondModule(context, resInfo, txt)); // Shorten each call + const respond = ((txt) => respondModule(context, resInfo, txt)); // Shorten each call // Get the correct ownerid array for this request let owners = commandHandler.data.cachefile.ownerid; if (resInfo.ownerIDs && resInfo.ownerIDs.length > 0) owners = resInfo.ownerIDs; - let requesterID = resInfo.userID; - let ownercheck = owners.includes(requesterID); + const requesterID = resInfo.userID; + const ownercheck = owners.includes(requesterID); /* --------- Various checks --------- */ @@ -53,25 +53,25 @@ async function processVoteRequest(origin, commandHandler, args, respondModule, c // Check and get arguments from user - let { err, amountRaw, id, idType } = await getMiscArgs(commandHandler, args, origin, resInfo, respond); // eslint-disable-line no-unused-vars + const { err, amountRaw, id, idType } = await getMiscArgs(commandHandler, args, origin, resInfo, respond); // eslint-disable-line no-unused-vars if (!amountRaw && !id) return; // Looks like the helper aborted the request // Check if this id is already receiving something right now - let idReq = commandHandler.controller.activeRequests[id]; + const idReq = commandHandler.controller.activeRequests[id]; if (idReq && idReq.status == "active") return respond(await commandHandler.data.getLang("idalreadyreceiving", null, requesterID)); // Note: No need to check for user as that is supposed to be handled by a cooldown // Check if user has cooldown - let { until, untilStr } = await commandHandler.data.getUserCooldown(requesterID); + const { until, untilStr } = await commandHandler.data.getUserCooldown(requesterID); if (until > Date.now()) return respond(await commandHandler.data.getLang("idoncooldown", { "remainingcooldown": untilStr }, requesterID)); // Get all available bot accounts - let { amount, availableAccounts, whenAvailableStr } = await getAvailableBotsForVoting(commandHandler, amountRaw, id, origin, resInfo); + const { amount, availableAccounts, whenAvailableStr } = await getAvailableBotsForVoting(commandHandler, amountRaw, id, origin, resInfo); if ((availableAccounts.length < amount || availableAccounts.length == 0) && !whenAvailableStr) { // Check if this bot has not enough accounts suitable for this request and there won't be more available at any point. The < || == 0 check is intentional, as providing "all" will set amount to 0 if 0 accounts have been found if (availableAccounts.length == 0) respond(await commandHandler.data.getLang("genericnounlimitedaccs", { "cmdprefix": resInfo.cmdprefix }, requesterID)); // Send specific nounlimitedaccs message as we always need unlimited accs and to let users know this situation won't change @@ -87,9 +87,9 @@ async function processVoteRequest(origin, commandHandler, args, respondModule, c // Register this vote process in activeRequests - let capitilizedOrigin = origin.charAt(0).toUpperCase() + origin.slice(1); // Capitilize first char of origin to achieve camelCase + const capitilizedOrigin = origin.charAt(0).toUpperCase() + origin.slice(1); // Capitilize first char of origin to achieve camelCase - let activeReqEntry = { + const activeReqEntry = { status: "active", type: idType + capitilizedOrigin, amount: amount, @@ -192,7 +192,7 @@ async function processVoteRequest(origin, commandHandler, args, respondModule, c // Only send estimated wait time message for multiple votes if (activeReqEntry.amount > 1) { - let waitTime = timeToString(Date.now() + ((activeReqEntry.amount - 1) * commandHandler.data.config.requestDelay)); // Amount - 1 because the first vote is instant. Multiply by delay and add to current time to get timestamp when last vote was sent + const waitTime = timeToString(Date.now() + ((activeReqEntry.amount - 1) * commandHandler.data.config.requestDelay)); // Amount - 1 because the first vote is instant. Multiply by delay and add to current time to get timestamp when last vote was sent respond(await commandHandler.data.getLang("voteprocessstarted", { "numberOfVotes": activeReqEntry.amount, "waittime": waitTime }, requesterID)); } @@ -207,7 +207,7 @@ async function processVoteRequest(origin, commandHandler, args, respondModule, c syncLoop(amount, (loop, i) => { setTimeout(() => { - let bot = commandHandler.controller.bots[availableAccounts[i]]; + const bot = commandHandler.controller.bots[availableAccounts[i]]; activeReqEntry.thisIteration++; if (!handleVoteIterationSkip(commandHandler, loop, bot, id)) return; // Skip iteration if false was returned diff --git a/src/commands/helpers/getCommentArgs.js b/src/commands/helpers/getCommentArgs.js index def74cc8..541590ba 100644 --- a/src/commands/helpers/getCommentArgs.js +++ b/src/commands/helpers/getCommentArgs.js @@ -66,7 +66,7 @@ module.exports.getCommentArgs = (commandHandler, args, resInfo, respond) => { let owners = commandHandler.data.cachefile.ownerid; if (resInfo.ownerIDs && resInfo.ownerIDs.length > 0) owners = resInfo.ownerIDs; - let requesterID = resInfo.userID; + const requesterID = resInfo.userID; let maxRequestAmount = commandHandler.data.config.maxRequests; // Set to default value and if the requesting user is an owner it gets changed below let numberOfComments = 0; let quotesArr = commandHandler.data.quotes; @@ -115,7 +115,7 @@ module.exports.getCommentArgs = (commandHandler, args, resInfo, respond) => { /* --------- Check profileid argument if it was provided --------- */ if (args[1]) { if (owners.includes(requesterID) || args[1] == requesterID) { // Check if user is a bot owner or if they provided their own profile id - let arg = args[1]; + const arg = args[1]; commandHandler.controller.handleSteamIdResolving(arg, null, async (err, res, type) => { if (err) { @@ -172,7 +172,7 @@ module.exports.getCommentArgs = (commandHandler, args, resInfo, respond) => { /* --------- Resolve promise with calculated values when profileID is defined --------- */ - let profileIDDefinedInterval = setInterval(() => { // Check if profileID is defined every 250ms and only then return values + const profileIDDefinedInterval = setInterval(() => { // Check if profileID is defined every 250ms and only then return values if (profileID != undefined) { clearInterval(profileIDDefinedInterval); diff --git a/src/commands/helpers/getCommentBots.js b/src/commands/helpers/getCommentBots.js index bef453ce..5c2eb25c 100644 --- a/src/commands/helpers/getCommentBots.js +++ b/src/commands/helpers/getCommentBots.js @@ -44,7 +44,7 @@ module.exports.getAvailableBotsForCommenting = async function(commandHandler, nu // Sort activeRequests by highest until value, decreasing, so that we can tell the user how long he/she has to wait if not enough accounts were found - let sortedvals = Object.keys(commandHandler.controller.activeRequests).sort((a, b) => { + const sortedvals = Object.keys(commandHandler.controller.activeRequests).sort((a, b) => { return commandHandler.controller.activeRequests[b].until - commandHandler.controller.activeRequests[a].until; }); @@ -53,13 +53,13 @@ module.exports.getAvailableBotsForCommenting = async function(commandHandler, nu let whenAvailable; // We will save the until value of the account that the user has to wait for here let whenAvailableStr; - let allAccsOnline = commandHandler.controller.getBots(null, true); + const allAccsOnline = commandHandler.controller.getBots(null, true); let allAccounts = [ ... Object.keys(allAccsOnline) ]; // Clone keys array (bot usernames) of bots object // Remove limited accounts from allAccounts array if desired if (!canBeLimited) { - let previousLength = allAccounts.length; + const previousLength = allAccounts.length; allAccounts = allAccounts.filter(e => allAccsOnline[e].user.limitations && !allAccsOnline[e].user.limitations.limited); if (previousLength - allAccounts.length > 0) logger("info", `${previousLength - allAccounts.length} of ${previousLength} bot accounts were removed from available accounts as they are limited and can't be used for this request!`); @@ -103,7 +103,7 @@ module.exports.getAvailableBotsForCommenting = async function(commandHandler, nu // Remove !accountCanComment accounts if type discussion. We need to run getSteamDiscussion for every account, which kind of sucks as it's a ton of requests - but what else are we supposed to do? if (idType == "discussion") { - let promises = []; + const promises = []; allAccounts.forEach((e) => { promises.push((() => { @@ -121,7 +121,7 @@ module.exports.getAvailableBotsForCommenting = async function(commandHandler, nu }); await Promise.all(promises).then((res) => { - let previousLength = allAccounts.length; + const previousLength = allAccounts.length; res.forEach((e) => { if (!e.accountCanComment) allAccounts.splice(allAccounts.indexOf(e.accountName), 1); // Remove that accountindex from the allAccounts array diff --git a/src/commands/helpers/getFavoriteBots.js b/src/commands/helpers/getFavoriteBots.js index 923b8828..aedee7ed 100644 --- a/src/commands/helpers/getFavoriteBots.js +++ b/src/commands/helpers/getFavoriteBots.js @@ -32,13 +32,13 @@ module.exports.getAvailableBotsForFavorizing = async (commandHandler, amount, id /* --------- Get all bots which haven't favorized this id yet and aren't currently in another favorite request --------- */ let whenAvailable; // We will save the until value of the account that the user has to wait for here let whenAvailableStr; - let allAccsOnline = commandHandler.controller.getBots(null, true); + const allAccsOnline = commandHandler.controller.getBots(null, true); let allAccounts = [ ... Object.keys(allAccsOnline) ]; // Clone keys array (bot usernames) of bots object // Remove bot accounts from allAccounts which have already favorized this id, or only allow them for type unfavorite - let previousLengthFavorized = allAccounts.length; - let alreadyFavorized = await commandHandler.data.ratingHistoryDB.findAsync({ id: id, type: "favorite" }, {}); + const previousLengthFavorized = allAccounts.length; + const alreadyFavorized = await commandHandler.data.ratingHistoryDB.findAsync({ id: id, type: "favorite" }, {}); if (favType == "favorite") { alreadyFavorized.forEach((e) => { diff --git a/src/commands/helpers/getFollowArgs.js b/src/commands/helpers/getFollowArgs.js index 0cb5087e..a6713983 100644 --- a/src/commands/helpers/getFollowArgs.js +++ b/src/commands/helpers/getFollowArgs.js @@ -32,11 +32,11 @@ module.exports.getFollowArgs = (commandHandler, args, cmd, resInfo, respond) => (async () => { // Lets us use await insidea Promise without creating an antipattern // Check for missing params - let cmdUsage = `'${resInfo.cmdprefix}${cmd} amount/"all" id/link'`; + const cmdUsage = `'${resInfo.cmdprefix}${cmd} amount/"all" id/link'`; if (args[0]) args[0] = args[0].toLowerCase(); if (args[0] == "max") args[0] = "all"; // Convert "all" alias - let amount = args[0] == "all" ? args[0] : Number(args[0]); // If user provides "all" then keep it as is and update it later to how many accounts are available, otherwise convert it to a number + const amount = args[0] == "all" ? args[0] : Number(args[0]); // If user provides "all" then keep it as is and update it later to how many accounts are available, otherwise convert it to a number if (args.length == 0 || (amount != "all" && isNaN(amount)) || amount == 0) { respond(await commandHandler.data.getLang("invalidnumber", { "cmdusage": cmdUsage }, resInfo.userID)); // An empty string will become a 0 @@ -48,7 +48,7 @@ module.exports.getFollowArgs = (commandHandler, args, cmd, resInfo, respond) => let owners = commandHandler.data.cachefile.ownerid; if (resInfo.ownerIDs && resInfo.ownerIDs.length > 0) owners = resInfo.ownerIDs; - let requesterID = resInfo.userID; + const requesterID = resInfo.userID; // Check if user requested more allowed @@ -68,7 +68,7 @@ module.exports.getFollowArgs = (commandHandler, args, cmd, resInfo, respond) => // Check if id was provided and process input if (args[1]) { if (owners.includes(requesterID) || args[1] == requesterID) { // Check if user is a bot owner or if they provided their own profile id - let arg = args[1]; + const arg = args[1]; commandHandler.controller.handleSteamIdResolving(arg, null, async (err, res, idType) => { if (err || (idType != "profile" && idType != "curator")) { diff --git a/src/commands/helpers/getFollowBots.js b/src/commands/helpers/getFollowBots.js index 23201be5..a50e802a 100644 --- a/src/commands/helpers/getFollowBots.js +++ b/src/commands/helpers/getFollowBots.js @@ -35,13 +35,13 @@ module.exports.getAvailableBotsForFollowing = async (commandHandler, amount, can /* --------- Get all bots which haven't followed this id yet and aren't currently in another follow request --------- */ let whenAvailable; // We will save the until value of the account that the user has to wait for here let whenAvailableStr; - let allAccsOnline = commandHandler.controller.getBots(null, true); + const allAccsOnline = commandHandler.controller.getBots(null, true); let allAccounts = [ ... Object.keys(allAccsOnline) ]; // Clone keys array (bot usernames) of bots object // Remove limited accounts from allAccounts array if desired if (!canBeLimited) { - let previousLength = allAccounts.length; + const previousLength = allAccounts.length; allAccounts = allAccounts.filter(e => allAccsOnline[e].user.limitations && !allAccsOnline[e].user.limitations.limited); if (previousLength - allAccounts.length > 0) logger("info", `${previousLength - allAccounts.length} of ${previousLength} bot accounts were removed from available accounts as they are limited and can't be used for this request!`); @@ -49,8 +49,8 @@ module.exports.getAvailableBotsForFollowing = async (commandHandler, amount, can // Remove bot accounts from allAccounts which have already followed this id, or only allow them for type unfollow - let previousLength = allAccounts.length; - let alreadyUsed = await commandHandler.data.ratingHistoryDB.findAsync({ id: id, type: idType + "Follow" }, {}); + const previousLength = allAccounts.length; + const alreadyUsed = await commandHandler.data.ratingHistoryDB.findAsync({ id: id, type: idType + "Follow" }, {}); if (favType == "follow") { alreadyUsed.forEach((e) => { diff --git a/src/commands/helpers/getMiscArgs.js b/src/commands/helpers/getMiscArgs.js index 65fcab38..76b20c3d 100644 --- a/src/commands/helpers/getMiscArgs.js +++ b/src/commands/helpers/getMiscArgs.js @@ -32,11 +32,11 @@ module.exports.getMiscArgs = (commandHandler, args, cmd, resInfo, respond) => { (async () => { // Lets us use await insidea Promise without creating an antipattern // Check for missing params - let cmdUsage = `'${resInfo.cmdprefix}${cmd} amount/"all" id/link'`; + const cmdUsage = `'${resInfo.cmdprefix}${cmd} amount/"all" id/link'`; if (args[0]) args[0] = args[0].toLowerCase(); if (args[0] == "max") args[0] = "all"; // Convert "all" alias - let amount = args[0] == "all" ? args[0] : Number(args[0]); // If user provides "all" then keep it as is and update it later to how many accounts are available, otherwise convert it to a number + const amount = args[0] == "all" ? args[0] : Number(args[0]); // If user provides "all" then keep it as is and update it later to how many accounts are available, otherwise convert it to a number if (args.length == 0 || (amount != "all" && isNaN(amount)) || amount == 0) { respond(await commandHandler.data.getLang("invalidnumber", { "cmdusage": cmdUsage }, resInfo.userID)); // An empty string will become a 0 diff --git a/src/commands/helpers/getVoteBots.js b/src/commands/helpers/getVoteBots.js index d3f5a973..e07a219a 100644 --- a/src/commands/helpers/getVoteBots.js +++ b/src/commands/helpers/getVoteBots.js @@ -33,19 +33,19 @@ module.exports.getAvailableBotsForVoting = async (commandHandler, amount, id, vo /* --------- Get all bots which haven't voted on this id yet and aren't currently in another vote request --------- */ let whenAvailable; // We will save the until value of the account that the user has to wait for here let whenAvailableStr; - let allAccsOnline = commandHandler.controller.getBots(null, true); + const allAccsOnline = commandHandler.controller.getBots(null, true); let allAccounts = [ ... Object.keys(allAccsOnline) ]; // Clone keys array (bot usernames) of bots object // Remove limited accounts from allAccounts array as they are unable to vote - let previousLengthLimited = allAccounts.length; + const previousLengthLimited = allAccounts.length; allAccounts = allAccounts.filter(e => allAccsOnline[e].user.limitations && !allAccsOnline[e].user.limitations.limited); if (previousLengthLimited - allAccounts.length > 0) logger("info", `${previousLengthLimited - allAccounts.length} of ${previousLengthLimited} bot accounts were removed from available accounts as they are limited and can't be used for this request!`); // Remove bot accounts from allAccounts which have already voted on this id with this voteType - let previousLengthVoted = allAccounts.length; - let alreadyVoted = await commandHandler.data.ratingHistoryDB.findAsync({ id: id, type: voteType }, {}); + const previousLengthVoted = allAccounts.length; + const alreadyVoted = await commandHandler.data.ratingHistoryDB.findAsync({ id: id, type: voteType }, {}); alreadyVoted.forEach((e) => { if (allAccounts.indexOf(e.accountName) != -1) allAccounts.splice(allAccounts.indexOf(e.accountName), 1); diff --git a/src/commands/helpers/handleCommentSkips.js b/src/commands/helpers/handleCommentSkips.js index e4486b64..bc1b4339 100644 --- a/src/commands/helpers/handleCommentSkips.js +++ b/src/commands/helpers/handleCommentSkips.js @@ -4,7 +4,7 @@ * Created Date: 2022-02-28 12:22:48 * Author: 3urobeat * - * Last Modified: 2024-05-03 13:08:38 + * Last Modified: 2024-05-04 22:02:59 * Modified By: 3urobeat * * Copyright (c) 2022 - 2024 3urobeat @@ -19,6 +19,22 @@ const Bot = require("../../bot/bot.js"); const CommandHandler = require("../commandHandler.js"); // eslint-disable-line +/** + * Helper function to sort failed object by comment number so that it is easier to read + * @param {object} failedObj Current state of failed object + */ +function sortFailedCommentsObject(failedObj) { + const sortedvals = Object.keys(failedObj).sort((a, b) => { + return Number(a.split(" ")[0].replace("i", "")) - Number(b.split(" ")[0].replace("i", "")); + }); + + // Map sortedvals back to object if array is not empty - Credit: https://www.geeksforgeeks.org/how-to-create-an-object-from-two-arrays-in-javascript/ + if (sortedvals.length > 0) failedObj = Object.assign(...sortedvals.map(k => ({ [k]: failedObj[k] }))); + + return failedObj; +} + + /** * Checks if the following comment process iteration should be skipped * Aborts comment process on critical error. @@ -29,7 +45,7 @@ const CommandHandler = require("../commandHandler.js"); // eslint-disable-line * @returns {boolean} true if iteration should continue, false if iteration should be skipped using return */ module.exports.handleIterationSkip = (commandHandler, loop, bot, receiverSteamID64) => { - let activeReqEntry = commandHandler.controller.activeRequests[receiverSteamID64]; // Make using the obj shorter + const activeReqEntry = commandHandler.controller.activeRequests[receiverSteamID64]; // Make using the obj shorter // Check if no bot account was found if (!bot) { @@ -56,7 +72,7 @@ module.exports.handleIterationSkip = (commandHandler, loop, bot, receiverSteamID // Add failed entry for all skipped iterations only if request was aborted if (activeReqEntry.status == "aborted") { for (let i = activeReqEntry.thisIteration; i < activeReqEntry.amount; i++) { // Iterate over all remaining comments by starting with thisIteration till numberOfComments - let thisbot = commandHandler.controller.getBots("*", true)[activeReqEntry.accounts[i % activeReqEntry.accounts.length]]; + const thisbot = commandHandler.controller.getBots("*", true)[activeReqEntry.accounts[i % activeReqEntry.accounts.length]]; activeReqEntry.failed[`i${i + 1} b${thisbot.index} p${thisbot.loginData.proxyIndex}`] = "Skipped because comment process was aborted"; } @@ -105,7 +121,7 @@ module.exports.handleIterationSkip = (commandHandler, loop, bot, receiverSteamID * @param {string} receiverSteamID64 steamID64 of the receiving user/group */ module.exports.logCommentError = (error, commandHandler, bot, receiverSteamID64) => { - let activeReqEntry = commandHandler.controller.activeRequests[receiverSteamID64]; // Make using the obj shorter + const activeReqEntry = commandHandler.controller.activeRequests[receiverSteamID64]; // Make using the obj shorter let description = ""; @@ -122,7 +138,7 @@ module.exports.logCommentError = (error, commandHandler, bot, receiverSteamID64) logger("warn", "Skipping all other comments on this proxy as well because they will fail too!"); for (let i = activeReqEntry.thisIteration + 1; i < activeReqEntry.amount; i++) { // Iterate over all remaining comments by starting with next iteration till numberOfComments - let thisbot = commandHandler.controller.getBots(null, true)[activeReqEntry.accounts[i % activeReqEntry.accounts.length]]; + const thisbot = commandHandler.controller.getBots(null, true)[activeReqEntry.accounts[i % activeReqEntry.accounts.length]]; // Add to failed obj if proxies match if (thisbot.loginData.proxyIndex == bot.loginData.proxyIndex) { @@ -174,22 +190,6 @@ module.exports.logCommentError = (error, commandHandler, bot, receiverSteamID64) }; -/** - * Helper function to sort failed object by comment number so that it is easier to read - * @param {object} failedObj Current state of failed object - */ -function sortFailedCommentsObject(failedObj) { - let sortedvals = Object.keys(failedObj).sort((a, b) => { - return Number(a.split(" ")[0].replace("i", "")) - Number(b.split(" ")[0].replace("i", "")); - }); - - // Map sortedvals back to object if array is not empty - Credit: https://www.geeksforgeeks.org/how-to-create-an-object-from-two-arrays-in-javascript/ - if (sortedvals.length > 0) failedObj = Object.assign(...sortedvals.map(k => ({ [k]: failedObj[k] }))); - - return failedObj; -} - - /** * Groups same error messages together, counts amount, lists affected bots and converts it to a String. * @param {object} obj failedcomments object that should be converted @@ -197,10 +197,10 @@ function sortFailedCommentsObject(failedObj) { */ module.exports.failedCommentsObjToString = (obj) => { // Count amount of each string - let grouped = {}; + const grouped = {}; Object.keys(obj).forEach((e) => { - let err = obj[e]; + const err = obj[e]; // Check if entry for this err msg already exists and increment amount if (Object.keys(grouped).includes(err)) { @@ -218,7 +218,7 @@ module.exports.failedCommentsObjToString = (obj) => { }); // Sort object descending - let sortedArr = Object.values(grouped).sort((a, b) => { + const sortedArr = Object.values(grouped).sort((a, b) => { return b.amount - a.amount; }); diff --git a/src/commands/helpers/handleFollowErrors.js b/src/commands/helpers/handleFollowErrors.js index 0d268861..4e6fce24 100644 --- a/src/commands/helpers/handleFollowErrors.js +++ b/src/commands/helpers/handleFollowErrors.js @@ -4,7 +4,7 @@ * Created Date: 2023-09-24 22:57:21 * Author: 3urobeat * - * Last Modified: 2024-05-03 13:07:57 + * Last Modified: 2024-05-04 22:03:25 * Modified By: 3urobeat * * Copyright (c) 2023 - 2024 3urobeat @@ -18,6 +18,22 @@ const Bot = require("../../bot/bot.js"); +/** + * Helper function to sort failed object by number so that it is easier to read + * @param {object} failedObj Current state of failed object + */ +function sortFailedCommentsObject(failedObj) { + const sortedvals = Object.keys(failedObj).sort((a, b) => { + return Number(a.split(" ")[0].replace("i", "")) - Number(b.split(" ")[0].replace("i", "")); + }); + + // Map sortedvals back to object if array is not empty - Credit: https://www.geeksforgeeks.org/how-to-create-an-object-from-two-arrays-in-javascript/ + if (sortedvals.length > 0) failedObj = Object.assign(...sortedvals.map(k => ({ [k]: failedObj[k] }))); + + return failedObj; +} + + /** * Checks if the following follow process iteration should be skipped * @param {CommandHandler} commandHandler The commandHandler object @@ -27,7 +43,7 @@ const Bot = require("../../bot/bot.js"); * @returns {boolean} `true` if iteration should continue, `false` if iteration should be skipped using return */ module.exports.handleFollowIterationSkip = function(commandHandler, loop, bot, id) { - let activeReqEntry = commandHandler.controller.activeRequests[id]; // Make using the obj shorter + const activeReqEntry = commandHandler.controller.activeRequests[id]; // Make using the obj shorter // Check if no bot account was found if (!bot) { @@ -60,7 +76,7 @@ module.exports.handleFollowIterationSkip = function(commandHandler, loop, bot, i * @param {string} id ID of the profile that receives the follow */ module.exports.logFollowError = (error, commandHandler, bot, id) => { - let activeReqEntry = commandHandler.controller.activeRequests[id]; // Make using the obj shorter + const activeReqEntry = commandHandler.controller.activeRequests[id]; // Make using the obj shorter // Add proxy information if one was used for this account let proxiesDescription = ""; @@ -76,19 +92,3 @@ module.exports.logFollowError = (error, commandHandler, bot, id) => { // Sort failed object to make it easier to read activeReqEntry.failed = sortFailedCommentsObject(activeReqEntry.failed); }; - - -/** - * Helper function to sort failed object by number so that it is easier to read - * @param {object} failedObj Current state of failed object - */ -function sortFailedCommentsObject(failedObj) { - let sortedvals = Object.keys(failedObj).sort((a, b) => { - return Number(a.split(" ")[0].replace("i", "")) - Number(b.split(" ")[0].replace("i", "")); - }); - - // Map sortedvals back to object if array is not empty - Credit: https://www.geeksforgeeks.org/how-to-create-an-object-from-two-arrays-in-javascript/ - if (sortedvals.length > 0) failedObj = Object.assign(...sortedvals.map(k => ({ [k]: failedObj[k] }))); - - return failedObj; -} diff --git a/src/commands/helpers/handleMiscErrors.js b/src/commands/helpers/handleMiscErrors.js index ce1f30ba..9b972ca3 100644 --- a/src/commands/helpers/handleMiscErrors.js +++ b/src/commands/helpers/handleMiscErrors.js @@ -4,7 +4,7 @@ * Created Date: 2023-05-31 16:57:21 * Author: 3urobeat * - * Last Modified: 2024-05-03 13:07:47 + * Last Modified: 2024-05-04 22:04:06 * Modified By: 3urobeat * * Copyright (c) 2023 - 2024 3urobeat @@ -18,6 +18,22 @@ const Bot = require("../../bot/bot.js"); +/** + * Helper function to sort failed object by number so that it is easier to read + * @param {object} failedObj Current state of failed object + */ +function sortFailedCommentsObject(failedObj) { + const sortedvals = Object.keys(failedObj).sort((a, b) => { + return Number(a.split(" ")[0].replace("i", "")) - Number(b.split(" ")[0].replace("i", "")); + }); + + // Map sortedvals back to object if array is not empty - Credit: https://www.geeksforgeeks.org/how-to-create-an-object-from-two-arrays-in-javascript/ + if (sortedvals.length > 0) failedObj = Object.assign(...sortedvals.map(k => ({ [k]: failedObj[k] }))); + + return failedObj; +} + + /** * Checks if the following vote process iteration should be skipped * @param {CommandHandler} commandHandler The commandHandler object @@ -27,7 +43,7 @@ const Bot = require("../../bot/bot.js"); * @returns {boolean} `true` if iteration should continue, `false` if iteration should be skipped using return */ module.exports.handleVoteIterationSkip = function(commandHandler, loop, bot, id) { - let activeReqEntry = commandHandler.controller.activeRequests[id]; // Make using the obj shorter + const activeReqEntry = commandHandler.controller.activeRequests[id]; // Make using the obj shorter // Check if no bot account was found if (!bot) { @@ -61,7 +77,7 @@ module.exports.handleVoteIterationSkip = function(commandHandler, loop, bot, id) * @returns {boolean} `true` if iteration should continue, `false` if iteration should be skipped using return */ module.exports.handleFavoriteIterationSkip = function(commandHandler, loop, bot, id) { - let activeReqEntry = commandHandler.controller.activeRequests[id]; // Make using the obj shorter + const activeReqEntry = commandHandler.controller.activeRequests[id]; // Make using the obj shorter // Check if no bot account was found if (!bot) { @@ -94,7 +110,7 @@ module.exports.handleFavoriteIterationSkip = function(commandHandler, loop, bot, * @param {string} id ID that receives the votes */ module.exports.logVoteError = (error, commandHandler, bot, id) => { - let activeReqEntry = commandHandler.controller.activeRequests[id]; // Make using the obj shorter + const activeReqEntry = commandHandler.controller.activeRequests[id]; // Make using the obj shorter // Add proxy information if one was used for this account let proxiesDescription = ""; @@ -120,7 +136,7 @@ module.exports.logVoteError = (error, commandHandler, bot, id) => { * @param {string} id ID of the sharedfile that receives the favorites */ module.exports.logFavoriteError = (error, commandHandler, bot, id) => { - let activeReqEntry = commandHandler.controller.activeRequests[id]; // Make using the obj shorter + const activeReqEntry = commandHandler.controller.activeRequests[id]; // Make using the obj shorter // Add proxy information if one was used for this account let proxiesDescription = ""; @@ -136,19 +152,3 @@ module.exports.logFavoriteError = (error, commandHandler, bot, id) => { // Sort failed object to make it easier to read activeReqEntry.failed = sortFailedCommentsObject(activeReqEntry.failed); }; - - -/** - * Helper function to sort failed object by number so that it is easier to read - * @param {object} failedObj Current state of failed object - */ -function sortFailedCommentsObject(failedObj) { - let sortedvals = Object.keys(failedObj).sort((a, b) => { - return Number(a.split(" ")[0].replace("i", "")) - Number(b.split(" ")[0].replace("i", "")); - }); - - // Map sortedvals back to object if array is not empty - Credit: https://www.geeksforgeeks.org/how-to-create-an-object-from-two-arrays-in-javascript/ - if (sortedvals.length > 0) failedObj = Object.assign(...sortedvals.map(k => ({ [k]: failedObj[k] }))); - - return failedObj; -} diff --git a/src/controller/controller.js b/src/controller/controller.js index dea4d1f8..96b12734 100644 --- a/src/controller/controller.js +++ b/src/controller/controller.js @@ -4,7 +4,7 @@ * Created Date: 2021-07-09 16:26:00 * Author: 3urobeat * - * Last Modified: 2024-05-03 13:07:40 + * Last Modified: 2024-05-04 22:08:30 * Modified By: 3urobeat * * Copyright (c) 2021 - 2024 3urobeat @@ -107,11 +107,62 @@ const Controller = function() { }; +/* ------------ Handle restart data: ------------ */ + +/* eslint-disable no-use-before-define */ + +/** + * Process data that should be kept over restarts + * @param {string} data Stringified data received by previous process + */ +function restartdata(data) { + data = JSON.parse(data); // Convert the stringified object back to an object + + if (data.oldconfig) oldconfig = data.oldconfig // eslint-disable-line + if (data.logafterrestart) logafterrestart = data.logafterrestart; // We can't print now since the logger function isn't imported yet. + if (data.skippedaccounts) skippedaccounts = data.skippedaccounts; + if (data.updateFailed) updateFailed = data.updateFailed; +} + +// Make a "fake" logger backup function to use when no npm packages were installed +let logger = function(type, str) { + logafterrestart.push(`${type} | ${str}`); // Push message to array that will be carried through restart + console.log(`${type} | ${str}`); +}; +logger.animation = () => {}; // Just to be sure that no error occurs when trying to call this function without the real logger being present + +/* eslint-enable no-use-before-define */ + + +/* ------------ Start the bot: ------------ */ + +if (parseInt(process.argv[3]) + 2500 > Date.now()) { // Check if this process just got started in the last 2.5 seconds or just required by itself by checking the timestamp attached by starter.js + + // Variables to keep data through restarts. These need to be var's as they need to be accessible from the top scope, sorry eslint! + var oldconfig = {}; // eslint-disable-line + var logafterrestart = []; // eslint-disable-line + var updateFailed = false; // eslint-disable-line + var skippedaccounts = []; // eslint-disable-line + + // Yes, I know, global variables are bad. But I need a few multiple times in different files and it would be a pain in the ass to import them every time and ensure that I don't create a circular dependency and what not. + global.botisloggedin = false; + global.srcdir = process.argv[2]; + + // Start the bot through the restartdata function if this is a restart to keep some data or start the bot directly + if (process.argv[4]) restartdata(process.argv[4]); + + // Start the bot + const controller = new Controller(); + + setTimeout(() => controller._start(), 50); // Wanna hear something stupid? The error catch in handleErrors.js does not work without this delay. Why? Because the empty function for JsDoc below overwrites the real one. Even though the real one is loaded after the fake one. +} + + /** * Internal: Initializes the bot by importing data from the disk, running the updater and finally logging in all bot accounts. */ Controller.prototype._start = async function() { - let checkAndGetFile = require("../starter.js").checkAndGetFile; // Temp var to use checkAndGetFile() before it is referenced in DataManager + const checkAndGetFile = require("../starter.js").checkAndGetFile; // Temp var to use checkAndGetFile() before it is referenced in DataManager this.checkAndGetFile = checkAndGetFile; /* ------------ Init error handler: ------------ */ @@ -164,7 +215,7 @@ Controller.prototype._start = async function() { /* ------------ Init dataManager system and import: ------------ */ if (!await checkAndGetFile("./src/dataManager/dataManager.js", logger, false, false)) return; - let DataManager = require("../dataManager/dataManager.js"); + const DataManager = require("../dataManager/dataManager.js"); this.data = new DataManager(this); // All functions provided by the DataManager, as well as all imported file data will be accessible here @@ -188,7 +239,7 @@ Controller.prototype._start = async function() { // Check for unsupported node.js version (<16.0.0) - let versionarr = process.version.replace("v", "").split("."); + const versionarr = process.version.replace("v", "").split("."); versionarr.forEach((e, i) => { if (e.length == 1 && parseInt(e) < 10) versionarr[i] = `0${e}`; }); // Put 0 in front of single digits @@ -216,11 +267,11 @@ Controller.prototype._start = async function() { /* ------------ Run compatibility feature and updater or start logging in: ------------ */ - let compatibility = await checkAndGetFile("./src/updater/compatibility.js", logger, false, false); + const compatibility = await checkAndGetFile("./src/updater/compatibility.js", logger, false, false); if (compatibility) forceUpdate = await compatibility.runCompatibility(this); // Don't bother running it if it couldn't be found and just hope the next update will fix it // Attempt to load updater to activate the auto update checker. If this fails we are properly "fucked" as we can't repair ourselves - let Updater = await checkAndGetFile("./src/updater/updater.js", logger, false, false); + const Updater = await checkAndGetFile("./src/updater/updater.js", logger, false, false); if (!Updater) { logger("error", "Fatal Error: Failed to load updater! Please reinstall the bot manually. Aborting..."); return this.stop(); @@ -238,7 +289,7 @@ Controller.prototype._start = async function() { } else { // Let the updater run and check for any available updates - let { updateFound } = await this.updater.run(forceUpdate); + const { updateFound } = await this.updater.run(forceUpdate); // Continue if no update was found. If an update was found and installed the updater will restart the bot itself. if (!updateFound) { @@ -254,7 +305,7 @@ Controller.prototype._start = async function() { Controller.prototype._preLogin = async function() { // Get job manager going - let JobManager = require("../jobs/jobManager.js"); + const JobManager = require("../jobs/jobManager.js"); /** * The JobManager handles the periodic execution of functions which you can register at runtime @@ -315,7 +366,7 @@ Controller.prototype._preLogin = async function() { // Load commandHandler - let CommandHandler = require("../commands/commandHandler.js"); + const CommandHandler = require("../commands/commandHandler.js"); /** * The commandHandler object @@ -326,7 +377,7 @@ Controller.prototype._preLogin = async function() { // Load pluginSystem - let PluginSystem = require("../pluginSystem/pluginSystem.js"); + const PluginSystem = require("../pluginSystem/pluginSystem.js"); /** * The pluginSystem handler @@ -345,52 +396,6 @@ Controller.prototype._preLogin = async function() { module.exports = Controller; -/* ------------ Handle restart data: ------------ */ - -/** - * Process data that should be kept over restarts - * @param {string} data Stringified data received by previous process - */ -function restartdata(data) { - data = JSON.parse(data); // Convert the stringified object back to an object - - if (data.oldconfig) oldconfig = data.oldconfig //eslint-disable-line - if (data.logafterrestart) logafterrestart = data.logafterrestart; // We can't print now since the logger function isn't imported yet. - if (data.skippedaccounts) skippedaccounts = data.skippedaccounts; - if (data.updateFailed) updateFailed = data.updateFailed; -} - -// Make a "fake" logger backup function to use when no npm packages were installed -let logger = function(type, str) { - logafterrestart.push(`${type} | ${str}`); // Push message to array that will be carried through restart - console.log(`${type} | ${str}`); -}; -logger.animation = () => {}; // Just to be sure that no error occurs when trying to call this function without the real logger being present - - -/* ------------ Start the bot: ------------ */ - -if (parseInt(process.argv[3]) + 2500 > Date.now()) { // Check if this process just got started in the last 2.5 seconds or just required by itself by checking the timestamp attached by starter.js - - // Variables to keep data through restarts. These need to be var's as they need to be accessible from the top scope, sorry eslint! - var oldconfig = {}; // eslint-disable-line - var logafterrestart = []; // eslint-disable-line - var updateFailed = false; // eslint-disable-line - var skippedaccounts = []; // eslint-disable-line - - // Yes, I know, global variables are bad. But I need a few multiple times in different files and it would be a pain in the ass to import them every time and ensure that I don't create a circular dependency and what not. - global.botisloggedin = false; - global.srcdir = process.argv[2]; - - // Start the bot through the restartdata function if this is a restart to keep some data or start the bot directly - if (process.argv[4]) restartdata(process.argv[4]); - - // Start the bot - let controller = new Controller(); - - setTimeout(() => controller._start(), 50); // Wanna hear something stupid? The error catch in handleErrors.js does not work without this delay. Why? Because the empty function for JsDoc below overwrites the real one. Even though the real one is loaded after the fake one. -} - /* ------------ Provide functions for restarting & stopping: ------------ */ diff --git a/src/controller/events/ready.js b/src/controller/events/ready.js index adb19ec7..3881452f 100644 --- a/src/controller/events/ready.js +++ b/src/controller/events/ready.js @@ -121,7 +121,7 @@ Controller.prototype._readyEvent = function() { // Check if an owner is not friend with the main bot account - let nonFriendOwners = this.data.cachefile.ownerid.filter(e => !this.main.user.myFriends[e] || this.main.user.myFriends[e] != SteamUser.EFriendRelationship.Friend); // Get all ownerids that either aren't even in the myFriends obj or are with code != 3 + const nonFriendOwners = this.data.cachefile.ownerid.filter(e => !this.main.user.myFriends[e] || this.main.user.myFriends[e] != SteamUser.EFriendRelationship.Friend); // Get all ownerids that either aren't even in the myFriends obj or are with code != 3 if (nonFriendOwners.length > 0) { logger("warn", `The owner(s) '${nonFriendOwners.map((e, i) => this.data.config.ownerid[i]).join(", ")}' are not friend with the main bot account!\n Please send the main account a friend request now: https://steamcommunity.com/profiles/${this.data.cachefile.botaccid[0]}\n`, true); diff --git a/src/controller/events/statusUpdate.js b/src/controller/events/statusUpdate.js index df34c7d0..d75f53c7 100644 --- a/src/controller/events/statusUpdate.js +++ b/src/controller/events/statusUpdate.js @@ -25,7 +25,7 @@ const Controller = require("../controller"); * @param {Bot.EStatus} newStatus The new status of this bot */ Controller.prototype._statusUpdateEvent = function(bot, newStatus) { - let oldStatus = bot.status; + const oldStatus = bot.status; // Update status of bot bot.status = newStatus; diff --git a/src/controller/helpers/friendlist.js b/src/controller/helpers/friendlist.js index e5bc302d..15fc4429 100644 --- a/src/controller/helpers/friendlist.js +++ b/src/controller/helpers/friendlist.js @@ -34,7 +34,7 @@ Controller.prototype.checkLastcommentDB = function(bot) { if (bot.user.myFriends[e] == 3 && !docs.find(el => el.id == e)) { logger("info", `Inserting user ${e} into lastcomment.db...`, false, true); - let obj = { + const obj = { id: e, time: Date.now() - (this.data.config.requestCooldown * 60000) // Subtract requestCooldown so that the user is able to use the command instantly }; @@ -59,11 +59,11 @@ Controller.prototype.friendListCapacityCheck = function(bot, callback) { bot.user.getSteamLevels([bot.user.steamID], (err, users) => { // Check steam level of botindex account with bot0 if (!users) return; // Users was undefined one time (I hope this will (hopefully) suppress an error?) - let friendlistlimit = Object.values(users)[0] * 5 + 250; // Profile Level * 5 + 250 - let friends = Object.values(bot.user.myFriends); - let friendsamount = friends.length - friends.filter(val => val == 0).length - friends.filter(val => val == 5).length; // Subtract friend enums 0 & 5 + const friendlistlimit = Object.values(users)[0] * 5 + 250; // Profile Level * 5 + 250 + const friends = Object.values(bot.user.myFriends); + const friendsamount = friends.length - friends.filter(val => val == 0).length - friends.filter(val => val == 5).length; // Subtract friend enums 0 & 5 - let remaining = friendlistlimit - friendsamount; + const remaining = friendlistlimit - friendsamount; logger("debug", `Controller friendListCapacityCheck(): bot${bot.index} has ${friendsamount}/${friendlistlimit} friends`); @@ -85,7 +85,7 @@ Controller.prototype.friendListCapacityCheck = function(bot, callback) { // Iterate over all docs until we find someone still on our friendlist that isn't an owner (since this func is called for each bot acc we don't need to iterate over the botobject) docs.every(async (e, i) => { // Use every() so we can break with return false if (bot.user.myFriends[e.id] == 3 && !this.data.cachefile.ownerid.includes(e.id)) { // Check if friend and not owner - let steamID = new SteamID(e.id); + const steamID = new SteamID(e.id); // Unfriend user and send them a message // TODO: Maybe only do this from the main bot? bot.sendChatMessage(bot, { userID: steamID.getSteamID64() }, await this.data.getLang("userunfriend", { "forceFriendlistSpaceTime": this.data.advancedconfig.forceFriendlistSpaceTime }, steamID.getSteamID64())); @@ -132,7 +132,7 @@ Controller.prototype._lastcommentUnfriendCheck = function() { setTimeout(() => { this.getBots().forEach(async (f, j) => { - let thisbot = f.user; + const thisbot = f.user; if (thisbot.myFriends[e.id] && thisbot.myFriends[e.id] == 3 && !this.data.cachefile.ownerid.includes(e.id)) { // Check if the targeted user is still friend and not an owner if (j == 0) this.main.sendChatMessage(this.main, { userID: e.id }, await this.data.getLang("userforceunfriend", { "unfriendtime": this.data.config.unfriendtime }, e.id)); diff --git a/src/controller/helpers/getBots.js b/src/controller/helpers/getBots.js index ff340deb..d0fc9fad 100644 --- a/src/controller/helpers/getBots.js +++ b/src/controller/helpers/getBots.js @@ -50,7 +50,7 @@ Controller.prototype.getBots = function(statusFilter = EStatus.ONLINE, mapToObje Controller.prototype.getBotsPerProxy = function(filterOffline = false) { // Get all bot accounts - let accs = this.getBots("*"); + const accs = this.getBots("*"); // Prefill mappedProxies let mappedProxies = []; @@ -59,7 +59,7 @@ Controller.prototype.getBotsPerProxy = function(filterOffline = false) { // Find associated proxies accs.forEach((e) => { - let associatedProxy = mappedProxies[e.loginData.proxyIndex]; + const associatedProxy = mappedProxies[e.loginData.proxyIndex]; associatedProxy.bots.push(e); }); diff --git a/src/controller/helpers/handleSteamIdResolving.js b/src/controller/helpers/handleSteamIdResolving.js index 68e4a0ac..cb977260 100644 --- a/src/controller/helpers/handleSteamIdResolving.js +++ b/src/controller/helpers/handleSteamIdResolving.js @@ -70,7 +70,7 @@ Controller.prototype.handleSteamIdResolving = (str, expectedIdType, callback) => // Try to figure out if user provided an steamID64 or a customURL or a whole profile link if (isNaN(str) || !new SteamID(str).isValid()) { // If not a number or invalid SteamID. Note: Sharedfile IDs are considered invalid. if (/steamcommunity.com\/.+\/recommended\/\d+/g.test(str)) { // This check *must* run before the /id/ & /profiles/ checks below because they would always trigger. The URLs start the same, with reviews having /recommended/ at the end - let strArr = str.split("/"); + const strArr = str.split("/"); // Update idType idType = "review"; @@ -81,8 +81,8 @@ Controller.prototype.handleSteamIdResolving = (str, expectedIdType, callback) => if (str.includes("steamcommunity.com/id/")) { logger("debug", "handleSteamIdResolving: User provided review link with customURL..."); - let customURL = strArr[strArr.findIndex((e) => e == "id") + 1]; // Find customURL by searching for id and going to the next element - let appID = strArr[strArr.findIndex((e) => e == "recommended") + 1]; + const customURL = strArr[strArr.findIndex((e) => e == "id") + 1]; // Find customURL by searching for id and going to the next element + const appID = strArr[strArr.findIndex((e) => e == "recommended") + 1]; // Resolve customURL and replace /id/customURL with /profiles/steamID64 steamIDResolver.customUrlToSteamID64(customURL, (err, res) => { @@ -93,8 +93,8 @@ Controller.prototype.handleSteamIdResolving = (str, expectedIdType, callback) => } else { logger("debug", "handleSteamIdResolving: User provided review link with steamID64..."); - let userID = strArr[strArr.findIndex((e) => e == "profiles") + 1]; - let appID = strArr[strArr.findIndex((e) => e == "recommended") + 1]; + const userID = strArr[strArr.findIndex((e) => e == "profiles") + 1]; + const appID = strArr[strArr.findIndex((e) => e == "recommended") + 1]; callback(null, userID + "/" + appID, idType); // Instantly callback input } @@ -132,7 +132,7 @@ Controller.prototype.handleSteamIdResolving = (str, expectedIdType, callback) => if (!res) return callback("The specified sharedfile could not be found", null, null); // Cut domain away - let split = str.split("/"); + const split = str.split("/"); if (split[split.length - 1] == "") split.pop(); // Remove trailing slash (which is now a space because of split("/")) str = split[split.length - 1].replace("?id=", ""); @@ -148,7 +148,7 @@ Controller.prototype.handleSteamIdResolving = (str, expectedIdType, callback) => logger("debug", "handleSteamIdResolving: User provided curator link..."); // Cut domain away - let split = str.replace("/?appid=", "").split("/"); // Remove any trailing app id, we don't exactly know what the user provided + const split = str.replace("/?appid=", "").split("/"); // Remove any trailing app id, we don't exactly know what the user provided if (split[split.length - 1] == "") split.pop(); // Remove trailing slash (which is now a space because of split("/")) str = split[split.length - 1].split("-")[0]; @@ -209,7 +209,7 @@ Controller.prototype.handleSteamIdResolving = (str, expectedIdType, callback) => logger("debug", "handleSteamIdResolving: the provided id seems to be a sharedfile id! Returning sharedfileID..."); if (str.includes("steamcommunity.com/")) { // Check if full URL was provided and cut domain away - let split = str.split("/"); + const split = str.split("/"); if (split[split.length - 1] == "") split.pop(); // Remove trailing slash (which is now a space because of split("/")) str = split[split.length - 1].replace("?id=", ""); diff --git a/src/controller/helpers/misc.js b/src/controller/helpers/misc.js index 0f7091c8..33de314e 100644 --- a/src/controller/helpers/misc.js +++ b/src/controller/helpers/misc.js @@ -30,7 +30,7 @@ module.exports.syncLoop = (iterations, func, exit) => { let done = false; // Construct loop object - let loop = { + const loop = { next: function () { // Run next iteration process.nextTick(() => { // Delay by one tick to fix weird infinite loop crash bug // Check if the next iteration is still allowed to run, otherwise stop by calling break @@ -111,7 +111,7 @@ module.exports.checkConnection = (url, throwTimeout = false, proxy) => { // Use http and provide a proxy if requested - Credit: https://stackoverflow.com/a/49611762 if (proxy) { // TODO: Missing authentication could perhaps cause errors here - let auth = "Basic " + Buffer.from(proxy.username + ":" + proxy.password).toString("base64"); // Construct autentication + const auth = "Basic " + Buffer.from(proxy.username + ":" + proxy.password).toString("base64"); // Construct autentication url = url.replace("https://", ""); // Remove preceding https:// from url @@ -167,7 +167,7 @@ module.exports.checkConnection = (url, throwTimeout = false, proxy) => { */ module.exports.splitProxyString = (url) => { // TODO: Missing authentication could perhaps cause errors here - let obj = { ip: "", port: 0, username: "", password: "" }; + const obj = { ip: "", port: 0, username: "", password: "" }; if (!url) return obj; @@ -178,8 +178,8 @@ module.exports.splitProxyString = (url) => { // TODO: Missing authentication cou url = url.split("@"); // Split both parts at : to separate the 4 different elements - let usernamePassword = url[0].split(":"); - let ipPort = url[1].split(":"); + const usernamePassword = url[0].split(":"); + const ipPort = url[1].split(":"); // Extract ip and port from ipPort and username and password from usernamePassword obj.ip = ipPort[0]; @@ -209,15 +209,15 @@ module.exports.cutStringsIntelligently = (txt, limit, cutChars, threshold) => { if (txt.length <= limit) return [txt]; // Instantly return string as element 0 if it is already less than limit let lastIndex = 0; - let result = []; + const result = []; // Regex-less version - Safe but can cut at places where a link is surrounded by "' " and " '" to avoid embedding in the Steam Chat. // Iterate over string until lastIndex reaches length of input string. This whole algorithm could probably be replicated using RegEx but eeeehhhh while (lastIndex < txt.length - 1) { - let cut = txt.slice(lastIndex, lastIndex + limit); // Get the next part by cutting from lastIndex to limit + const cut = txt.slice(lastIndex, lastIndex + limit); // Get the next part by cutting from lastIndex to limit // Find the last occurrence of all cutChars and find the most recent one using Math.max() - let lastOccurrence = Math.max(...cutChars.map(e => cut.lastIndexOf(e))); + const lastOccurrence = Math.max(...cutChars.map(e => cut.lastIndexOf(e))); // Check if cut maxes out limit (if not we have reached the end and can push as is), // a last occurrence was found and is within threshold. If so, cut again, push to result and update lastIndex. diff --git a/src/controller/login.js b/src/controller/login.js index 22425936..3a677541 100644 --- a/src/controller/login.js +++ b/src/controller/login.js @@ -99,8 +99,8 @@ Controller.prototype.login = async function(firstLogin) { // Split login candidates into a fast queue (sync logins for accs on different proxies) & a slow queue (async logins for accs requiring user interaction) - let fastQueue = [ ...allAccounts.filter((e) => e.hasStorageValidToken) ]; - let slowQueue = [ ...allAccounts.filter((e) => !e.hasStorageValidToken) ]; + const fastQueue = [ ...allAccounts.filter((e) => e.hasStorageValidToken) ]; + const slowQueue = [ ...allAccounts.filter((e) => !e.hasStorageValidToken) ]; // Calculate login time @@ -128,7 +128,7 @@ Controller.prototype.login = async function(firstLogin) { let lastAmountUpdateTimestamp = Date.now(); let waitingForAmountAccounts = 0; - let allAccsOnlineInterval = setInterval(() => { + const allAccsOnlineInterval = setInterval(() => { // Shorthander that resolves this login process const loginFinished = () => { @@ -152,7 +152,7 @@ Controller.prototype.login = async function(firstLogin) { * Get all accounts which have not yet switched their status * @type {{ index: number, accountName: string }[]} Array of loginInfo objects, which among other things have these props */ - let allAccountsOffline = allAccounts.filter((e) => this.bots[e.accountName].status == Bot.EStatus.OFFLINE); + const allAccountsOffline = allAccounts.filter((e) => this.bots[e.accountName].status == Bot.EStatus.OFFLINE); // Update waitingForAmountAccounts & lastAmountUpdateTimestamp on change if (waitingForAmountAccounts != allAccountsOffline.length) { @@ -174,7 +174,7 @@ Controller.prototype.login = async function(firstLogin) { // Set status of every account to OFFLINE and call handleRelog to let it figure this out allAccountsOffline.forEach((e) => { - let thisBot = this.bots[e.accountName]; + const thisBot = this.bots[e.accountName]; this._statusUpdateEvent(thisBot, Bot.EStatus.ERROR); thisBot.handleRelog(); @@ -185,7 +185,7 @@ Controller.prototype.login = async function(firstLogin) { return; } - let cancelingInMinutes = Math.ceil(((lastAmountUpdateTimestamp + 900000) - Date.now()) / 60000); + const cancelingInMinutes = Math.ceil(((lastAmountUpdateTimestamp + 900000) - Date.now()) / 60000); logger("warn", `Detected inactivity in current login process! I'm waiting for bot(s) '${allAccountsOffline.flatMap((e) => e.index).join(", ")}' to change their status & become populated since >5 minutes! Canceling this login process in ~${cancelingInMinutes} minutes to prevent a softlock.`, true, true); @@ -199,7 +199,7 @@ Controller.prototype.login = async function(firstLogin) { } // Check if all accounts have their SteamUser data populated. Ignore accounts that are not online as they will never populate their user object - let allAccountsNotPopulated = allAccounts.filter((e) => this.bots[e.accountName].status == Bot.EStatus.ONLINE && !this.bots[e.accountName].user.limitations); + const allAccountsNotPopulated = allAccounts.filter((e) => this.bots[e.accountName].status == Bot.EStatus.ONLINE && !this.bots[e.accountName].user.limitations); if (allAccountsNotPopulated.length > 0) { logger("info", `All accounts logged in, waiting for user object of bot(s) '${allAccountsNotPopulated.flatMap((e) => e.index).join(", ")}' to populate...`, true, true, logger.animation("waiting")); // Cannot log with date to prevent log output file spam @@ -227,14 +227,14 @@ Controller.prototype._processFastLoginQueue = function(allAccounts) { this.data.proxies.forEach((proxy) => { // Find all queued accounts using this proxy - let thisProxyAccs = allAccounts.filter((e) => this.bots[e.accountName].loginData.proxyIndex == proxy.proxyIndex); + const thisProxyAccs = allAccounts.filter((e) => this.bots[e.accountName].loginData.proxyIndex == proxy.proxyIndex); // Make login timestamp entry for this proxy if (!this.info.lastLoginTimestamp[String(proxy.proxy)]) this.info.lastLoginTimestamp[String(proxy.proxy)] = 0; // Iterate over all accounts, use syncLoop() helper to make our job easier misc.syncLoop(thisProxyAccs.length, (loop, i) => { - let thisAcc = thisProxyAccs[i]; // Get logininfo for this account name + const thisAcc = thisProxyAccs[i]; // Get logininfo for this account name // Calculate wait time let waitTime = (this.info.lastLoginTimestamp[String(proxy.proxy)] + this.data.advancedconfig.loginDelay) - Date.now(); @@ -245,7 +245,7 @@ Controller.prototype._processFastLoginQueue = function(allAccounts) { // Wait before starting to log in setTimeout(() => { - let thisbot = this.bots[thisAcc.accountName]; + const thisbot = this.bots[thisAcc.accountName]; // Reset logOnTries (do this here to guarantee a bot object exists for this account) thisbot.loginData.logOnTries = 0; @@ -260,7 +260,7 @@ Controller.prototype._processFastLoginQueue = function(allAccounts) { thisbot._loginToSteam(); // Check if this bot is not offline anymore, resolve this iteration and update lastLoginTimestamp - let accIsOnlineInterval = setInterval(() => { + const accIsOnlineInterval = setInterval(() => { if (thisbot.status == Bot.EStatus.OFFLINE) return; clearInterval(accIsOnlineInterval); @@ -286,7 +286,7 @@ Controller.prototype._processSlowLoginQueue = function(allAccounts) { // Iterate over all accounts, use syncLoop() helper to make our job easier misc.syncLoop(allAccounts.length, (loop, i) => { - let thisAcc = allAccounts[i]; // Get logininfo for this account name + const thisAcc = allAccounts[i]; // Get logininfo for this account name // Calculate wait time let waitTime = (this.info.lastLoginTimestamp[String(this.bots[thisAcc.accountName].loginData.proxy)] + this.data.advancedconfig.loginDelay) - Date.now(); @@ -297,7 +297,7 @@ Controller.prototype._processSlowLoginQueue = function(allAccounts) { // Wait before starting to log in setTimeout(() => { - let thisbot = this.bots[thisAcc.accountName]; + const thisbot = this.bots[thisAcc.accountName]; // Reset logOnTries (do this here to guarantee a bot object exists for this account) thisbot.loginData.logOnTries = 0; @@ -312,7 +312,7 @@ Controller.prototype._processSlowLoginQueue = function(allAccounts) { thisbot._loginToSteam(); // Check if this bot is not offline anymore, resolve this iteration and update lastLoginTimestamp - let accIsOnlineInterval = setInterval(() => { + const accIsOnlineInterval = setInterval(() => { if (thisbot.status == Bot.EStatus.OFFLINE) return; clearInterval(accIsOnlineInterval); diff --git a/src/data/fileStructure.json b/src/data/fileStructure.json index 2616d14e..63026c5e 100644 --- a/src/data/fileStructure.json +++ b/src/data/fileStructure.json @@ -283,7 +283,7 @@ { "path": "eslint.config.mjs", "url": "https://raw.githubusercontent.com/3urobeat/steam-comment-service-bot/beta-testing/eslint.config.mjs", - "checksum": "390ba7cd47f19e134891ad93f9e42918" + "checksum": "b0f1fa7925dfdfc2b6abef8af2128f60" }, { "path": "scripts/README.md", @@ -293,7 +293,7 @@ { "path": "scripts/checkTranslationKeys.js", "url": "https://raw.githubusercontent.com/3urobeat/steam-comment-service-bot/beta-testing/scripts/checkTranslationKeys.js", - "checksum": "7c100ee6a3e88a657fbb02ae1a5717fc" + "checksum": "75c120983219fc44c90e7b72c71ebb4e" }, { "path": "scripts/duplicateQuotesDetector.js", @@ -303,7 +303,7 @@ { "path": "scripts/generateFileStructure.js", "url": "https://raw.githubusercontent.com/3urobeat/steam-comment-service-bot/beta-testing/scripts/generateFileStructure.js", - "checksum": "34df68cb56b63515681f021f4ff08840" + "checksum": "635d19551c1ffdd6567a9385fc72e065" }, { "path": "scripts/langStringsChangeDetector.js", @@ -318,7 +318,7 @@ { "path": "src/bot/bot.js", "url": "https://raw.githubusercontent.com/3urobeat/steam-comment-service-bot/beta-testing/src/bot/bot.js", - "checksum": "f5ffdab3eaaaeed3035b76200c932c47" + "checksum": "0e94cc19c9d3b541b4645e28ed535322" }, { "path": "src/bot/events/debug.js", @@ -333,12 +333,12 @@ { "path": "src/bot/events/error.js", "url": "https://raw.githubusercontent.com/3urobeat/steam-comment-service-bot/beta-testing/src/bot/events/error.js", - "checksum": "8415adcfa88700af656c85657a3c05c3" + "checksum": "d0ff306a25e58b9c910c77ffd994df08" }, { "path": "src/bot/events/friendMessage.js", "url": "https://raw.githubusercontent.com/3urobeat/steam-comment-service-bot/beta-testing/src/bot/events/friendMessage.js", - "checksum": "614384a783b6076f5bd29c233fd64b44" + "checksum": "8d0dafd89118e2ae214db6e4d2745dc7" }, { "path": "src/bot/events/loggedOn.js", @@ -348,12 +348,12 @@ { "path": "src/bot/events/relationship.js", "url": "https://raw.githubusercontent.com/3urobeat/steam-comment-service-bot/beta-testing/src/bot/events/relationship.js", - "checksum": "0ad301527df201620e549dfb9c495b68" + "checksum": "9cf313aa7818ae27640a6ad0848da290" }, { "path": "src/bot/events/webSession.js", "url": "https://raw.githubusercontent.com/3urobeat/steam-comment-service-bot/beta-testing/src/bot/events/webSession.js", - "checksum": "23ffa55367ac713ce9ce6c2ec4c3d913" + "checksum": "37a078ce9bc892c1506c0653b145663f" }, { "path": "src/bot/helpers/checkMsgBlock.js", @@ -363,147 +363,147 @@ { "path": "src/bot/helpers/handleLoginTimeout.js", "url": "https://raw.githubusercontent.com/3urobeat/steam-comment-service-bot/beta-testing/src/bot/helpers/handleLoginTimeout.js", - "checksum": "7c26d70db39d80a85eb77309d674c586" + "checksum": "e587049d71f7eca6e32f46309edc2f59" }, { "path": "src/bot/helpers/handleMissingGameLicenses.js", "url": "https://raw.githubusercontent.com/3urobeat/steam-comment-service-bot/beta-testing/src/bot/helpers/handleMissingGameLicenses.js", - "checksum": "972d35acb19963f5dd6519e3393ebd57" + "checksum": "6c23ba7c9d898e4d7637809248df452e" }, { "path": "src/bot/helpers/handleRelog.js", "url": "https://raw.githubusercontent.com/3urobeat/steam-comment-service-bot/beta-testing/src/bot/helpers/handleRelog.js", - "checksum": "36d245d8d1b4e08e8e1953b53e5042d7" + "checksum": "5a5e47dbbd2cdf30200ff1b841b700ed" }, { "path": "src/bot/helpers/steamChatInteraction.js", "url": "https://raw.githubusercontent.com/3urobeat/steam-comment-service-bot/beta-testing/src/bot/helpers/steamChatInteraction.js", - "checksum": "0e9c4608f652586d0d3328698cfc7770" + "checksum": "6de2730efaeef305abbe8a5f24ca5265" }, { "path": "src/commands/commandHandler.js", "url": "https://raw.githubusercontent.com/3urobeat/steam-comment-service-bot/beta-testing/src/commands/commandHandler.js", - "checksum": "a39e912f50969e3b13cbc45d0823d14e" + "checksum": "ea2f27cb304a393dc82347ec1798a89d" }, { "path": "src/commands/core/block.js", "url": "https://raw.githubusercontent.com/3urobeat/steam-comment-service-bot/beta-testing/src/commands/core/block.js", - "checksum": "c8faefabe22526fee5443c0498199a93" + "checksum": "02d2da4f42f8f267660e9beb46885251" }, { "path": "src/commands/core/comment.js", "url": "https://raw.githubusercontent.com/3urobeat/steam-comment-service-bot/beta-testing/src/commands/core/comment.js", - "checksum": "c2b6ae8c06b983194d100754c65ccb61" + "checksum": "90f2032edf170fcda4a3bcc9ae7f52d6" }, { "path": "src/commands/core/favorite.js", "url": "https://raw.githubusercontent.com/3urobeat/steam-comment-service-bot/beta-testing/src/commands/core/favorite.js", - "checksum": "9dc47165909fdf357c25ba775129e74a" + "checksum": "bcda38e982870e452fc469cba356ffed" }, { "path": "src/commands/core/follow.js", "url": "https://raw.githubusercontent.com/3urobeat/steam-comment-service-bot/beta-testing/src/commands/core/follow.js", - "checksum": "b6317db43d9e1591fc1d61663d45c5fe" + "checksum": "57ac961637cb74bdda66a312e3c1e760" }, { "path": "src/commands/core/friend.js", "url": "https://raw.githubusercontent.com/3urobeat/steam-comment-service-bot/beta-testing/src/commands/core/friend.js", - "checksum": "449892dc37e25ac64e3ef97e4925d63f" + "checksum": "011a6386096ab3260049b00cf045abab" }, { "path": "src/commands/core/general.js", "url": "https://raw.githubusercontent.com/3urobeat/steam-comment-service-bot/beta-testing/src/commands/core/general.js", - "checksum": "2f06633d9d51ef6be103b89742e6c8c3" + "checksum": "a3017332fef9c3269d0a41fda1598025" }, { "path": "src/commands/core/group.js", "url": "https://raw.githubusercontent.com/3urobeat/steam-comment-service-bot/beta-testing/src/commands/core/group.js", - "checksum": "a952ab3fae5ebd4fb7c6c1c01a520888" + "checksum": "4867499cb856539c981bc241d3b070d6" }, { "path": "src/commands/core/requests.js", "url": "https://raw.githubusercontent.com/3urobeat/steam-comment-service-bot/beta-testing/src/commands/core/requests.js", - "checksum": "5bbf1eff2f6c23dba05f5841a83a47b0" + "checksum": "97eac183e28c839e442dc5ecdccfbf2a" }, { "path": "src/commands/core/settings.js", "url": "https://raw.githubusercontent.com/3urobeat/steam-comment-service-bot/beta-testing/src/commands/core/settings.js", - "checksum": "556c368995dfc46f1407dac4b97503d7" + "checksum": "d1e9b04a501471b5fb6ab5f0880f9580" }, { "path": "src/commands/core/system.js", "url": "https://raw.githubusercontent.com/3urobeat/steam-comment-service-bot/beta-testing/src/commands/core/system.js", - "checksum": "f32dc19d1466840cce5ecc7703b4c569" + "checksum": "b37fd364b9aa9f00d47b3a0d8094c700" }, { "path": "src/commands/core/vote.js", "url": "https://raw.githubusercontent.com/3urobeat/steam-comment-service-bot/beta-testing/src/commands/core/vote.js", - "checksum": "f69c2827cc333b67d34075a14d8b40e4" + "checksum": "25d1259442bf63366a991a09246629cb" }, { "path": "src/commands/helpers/getCommentArgs.js", "url": "https://raw.githubusercontent.com/3urobeat/steam-comment-service-bot/beta-testing/src/commands/helpers/getCommentArgs.js", - "checksum": "c51407b565b90ae3835f407d4642baec" + "checksum": "8a42a107359cdef43f7b4706509e4097" }, { "path": "src/commands/helpers/getCommentBots.js", "url": "https://raw.githubusercontent.com/3urobeat/steam-comment-service-bot/beta-testing/src/commands/helpers/getCommentBots.js", - "checksum": "a3f54c2cea9d6482226fa4d64a3a4522" + "checksum": "64b43f3d326c560cf79764e96e69d043" }, { "path": "src/commands/helpers/getFavoriteBots.js", "url": "https://raw.githubusercontent.com/3urobeat/steam-comment-service-bot/beta-testing/src/commands/helpers/getFavoriteBots.js", - "checksum": "93d8d331be02808c8b4c008428e01529" + "checksum": "5ab5687eef590b6191d4349da4aa2f65" }, { "path": "src/commands/helpers/getFollowArgs.js", "url": "https://raw.githubusercontent.com/3urobeat/steam-comment-service-bot/beta-testing/src/commands/helpers/getFollowArgs.js", - "checksum": "1721a8875ca32ba707867bb3318952a0" + "checksum": "0dbb185c9a4b22691e60dffdf5d1160c" }, { "path": "src/commands/helpers/getFollowBots.js", "url": "https://raw.githubusercontent.com/3urobeat/steam-comment-service-bot/beta-testing/src/commands/helpers/getFollowBots.js", - "checksum": "dc949626da55dfe87fb1a0dea157deb5" + "checksum": "4bd2c335e4a5b8a49e516ba378d1f8b4" }, { "path": "src/commands/helpers/getMiscArgs.js", "url": "https://raw.githubusercontent.com/3urobeat/steam-comment-service-bot/beta-testing/src/commands/helpers/getMiscArgs.js", - "checksum": "9d36d31af5fa1930d4d16cefe026bfc2" + "checksum": "50ffb768fca4a19e3548c6dd5fd25f57" }, { "path": "src/commands/helpers/getVoteBots.js", "url": "https://raw.githubusercontent.com/3urobeat/steam-comment-service-bot/beta-testing/src/commands/helpers/getVoteBots.js", - "checksum": "8ab53da00eef05147f8aba1405b55ac3" + "checksum": "ce701d131eb4473d213467ee4c0d514d" }, { "path": "src/commands/helpers/handleCommentSkips.js", "url": "https://raw.githubusercontent.com/3urobeat/steam-comment-service-bot/beta-testing/src/commands/helpers/handleCommentSkips.js", - "checksum": "65c29b579867daa47fb59dc921c17827" + "checksum": "1391d03159a67310f007736d0cb499d8" }, { "path": "src/commands/helpers/handleFollowErrors.js", "url": "https://raw.githubusercontent.com/3urobeat/steam-comment-service-bot/beta-testing/src/commands/helpers/handleFollowErrors.js", - "checksum": "f0901c92f89131bec0c990c0d1b553ae" + "checksum": "eddda0b8cc1fb2647bfd638916c8f9e1" }, { "path": "src/commands/helpers/handleMiscErrors.js", "url": "https://raw.githubusercontent.com/3urobeat/steam-comment-service-bot/beta-testing/src/commands/helpers/handleMiscErrors.js", - "checksum": "8069eda53d2ce41b38aeded139a80904" + "checksum": "42a299d803b936ec6c839447a6941452" }, { "path": "src/controller/controller.js", "url": "https://raw.githubusercontent.com/3urobeat/steam-comment-service-bot/beta-testing/src/controller/controller.js", - "checksum": "a55c0f566ada510e247bd9d45322279b" + "checksum": "fc45d9b90330a9d80f4da19cbd6ca695" }, { "path": "src/controller/events/ready.js", "url": "https://raw.githubusercontent.com/3urobeat/steam-comment-service-bot/beta-testing/src/controller/events/ready.js", - "checksum": "d911f1d901cf1bd4541fc0855e46d5ca" + "checksum": "94ef5412b7186a976e63b525e16712de" }, { "path": "src/controller/events/statusUpdate.js", "url": "https://raw.githubusercontent.com/3urobeat/steam-comment-service-bot/beta-testing/src/controller/events/statusUpdate.js", - "checksum": "fa1f97966de3948e186e025ce13c1495" + "checksum": "33f3b07680d7a031938973f7d159a823" }, { "path": "src/controller/events/steamGuardInput.js", @@ -518,12 +518,12 @@ { "path": "src/controller/helpers/friendlist.js", "url": "https://raw.githubusercontent.com/3urobeat/steam-comment-service-bot/beta-testing/src/controller/helpers/friendlist.js", - "checksum": "4c63ef25e986890ece07f01d61d40faa" + "checksum": "0e116bb6b2e761d1fc802ceb8a300082" }, { "path": "src/controller/helpers/getBots.js", "url": "https://raw.githubusercontent.com/3urobeat/steam-comment-service-bot/beta-testing/src/controller/helpers/getBots.js", - "checksum": "5c86225dc66f901cce50aada3c8d8562" + "checksum": "1e4ac2683dc039d92f4fecc2aef6347b" }, { "path": "src/controller/helpers/handleErrors.js", @@ -533,7 +533,7 @@ { "path": "src/controller/helpers/handleSteamIdResolving.js", "url": "https://raw.githubusercontent.com/3urobeat/steam-comment-service-bot/beta-testing/src/controller/helpers/handleSteamIdResolving.js", - "checksum": "5562fb7b13b156a0710ebbff6193025b" + "checksum": "fb244bbc5397cd1ccf6e2c4451053492" }, { "path": "src/controller/helpers/logger.js", @@ -543,7 +543,7 @@ { "path": "src/controller/helpers/misc.js", "url": "https://raw.githubusercontent.com/3urobeat/steam-comment-service-bot/beta-testing/src/controller/helpers/misc.js", - "checksum": "9c67eb0be1e14576747ebec6a7267d9b" + "checksum": "70fb4a03d2e7b2f251685d04d3557ea5" }, { "path": "src/controller/helpers/npminteraction.js", @@ -553,7 +553,7 @@ { "path": "src/controller/login.js", "url": "https://raw.githubusercontent.com/3urobeat/steam-comment-service-bot/beta-testing/src/controller/login.js", - "checksum": "df4e7dc2a92eb948cadcb398965a3824" + "checksum": "ca44fdc848b159d90a0c4dfba43037ae" }, { "path": "src/data/ascii.js", @@ -588,22 +588,22 @@ { "path": "src/dataManager/dataCheck.js", "url": "https://raw.githubusercontent.com/3urobeat/steam-comment-service-bot/beta-testing/src/dataManager/dataCheck.js", - "checksum": "2da9cc1f31ac3ab7b4e07e60be1991c2" + "checksum": "033e061d02f24f00e8c0da2c02cc458f" }, { "path": "src/dataManager/dataExport.js", "url": "https://raw.githubusercontent.com/3urobeat/steam-comment-service-bot/beta-testing/src/dataManager/dataExport.js", - "checksum": "2d82e0053f351a7d6c7fa854909a3dba" + "checksum": "0e7c63573628c0771abd857567c153c2" }, { "path": "src/dataManager/dataImport.js", "url": "https://raw.githubusercontent.com/3urobeat/steam-comment-service-bot/beta-testing/src/dataManager/dataImport.js", - "checksum": "16091447de2f8daa460e9bba67d38e4a" + "checksum": "45749a6c541a0426734d9f97f13bb908" }, { "path": "src/dataManager/dataIntegrity.js", "url": "https://raw.githubusercontent.com/3urobeat/steam-comment-service-bot/beta-testing/src/dataManager/dataIntegrity.js", - "checksum": "48cb100ddf80bc4dd1b8abf963219d78" + "checksum": "fd6dd7e5acb7e13340a9eed6bb271231" }, { "path": "src/dataManager/dataManager.js", @@ -613,52 +613,52 @@ { "path": "src/dataManager/dataProcessing.js", "url": "https://raw.githubusercontent.com/3urobeat/steam-comment-service-bot/beta-testing/src/dataManager/dataProcessing.js", - "checksum": "af2612047ec965f8531699cc287bf2c3" + "checksum": "3f135d96f163062b6bd90043bcda5420" }, { "path": "src/dataManager/helpers/checkProxies.js", "url": "https://raw.githubusercontent.com/3urobeat/steam-comment-service-bot/beta-testing/src/dataManager/helpers/checkProxies.js", - "checksum": "357670340be40f10eb1692a1f001881f" + "checksum": "cd61d354f2726df6edc0ea37cd560ba1" }, { "path": "src/dataManager/helpers/getLang.js", "url": "https://raw.githubusercontent.com/3urobeat/steam-comment-service-bot/beta-testing/src/dataManager/helpers/getLang.js", - "checksum": "5f5ce750442ab1411544ddbedb03d2b7" + "checksum": "a60effdfafc102c701e621af39a8597b" }, { "path": "src/dataManager/helpers/getQuote.js", "url": "https://raw.githubusercontent.com/3urobeat/steam-comment-service-bot/beta-testing/src/dataManager/helpers/getQuote.js", - "checksum": "7b626a62ea9d40a524b4616d01b8fd97" + "checksum": "3b2de6a63bc2ea00ab534369a520bafd" }, { "path": "src/dataManager/helpers/handleCooldowns.js", "url": "https://raw.githubusercontent.com/3urobeat/steam-comment-service-bot/beta-testing/src/dataManager/helpers/handleCooldowns.js", - "checksum": "9b35a82aa2b29e9e8d566db0d406b13a" + "checksum": "2a5fb950648c3c8a9c14611df7718ec9" }, { "path": "src/dataManager/helpers/handleExpiringTokens.js", "url": "https://raw.githubusercontent.com/3urobeat/steam-comment-service-bot/beta-testing/src/dataManager/helpers/handleExpiringTokens.js", - "checksum": "0c4c8bae5b9bae91a9e7f220c7b73e53" + "checksum": "567753a572fbf016c3eab339d749fc89" }, { "path": "src/dataManager/helpers/misc.js", "url": "https://raw.githubusercontent.com/3urobeat/steam-comment-service-bot/beta-testing/src/dataManager/helpers/misc.js", - "checksum": "32544368771121102a46f2a75c3f5f41" + "checksum": "fe0c9a0b17c21ecb66ea4cbd94885867" }, { "path": "src/dataManager/helpers/refreshCache.js", "url": "https://raw.githubusercontent.com/3urobeat/steam-comment-service-bot/beta-testing/src/dataManager/helpers/refreshCache.js", - "checksum": "45511a56fb61cd18f36f89e215881722" + "checksum": "851f1c267621dc71efd1e58c7c12d800" }, { "path": "src/dataManager/helpers/repairFile.js", "url": "https://raw.githubusercontent.com/3urobeat/steam-comment-service-bot/beta-testing/src/dataManager/helpers/repairFile.js", - "checksum": "94a83348ebe8e20c70d5c16cf77f8689" + "checksum": "68d8b080bc5874de309dae0657825e25" }, { "path": "src/jobs/jobManager.js", "url": "https://raw.githubusercontent.com/3urobeat/steam-comment-service-bot/beta-testing/src/jobs/jobManager.js", - "checksum": "37dec9dd3507e1c98903722391115944" + "checksum": "2e33bc746f98bd75184f514fcd04b310" }, { "path": "src/libraryPatches/CSteamDiscussion.js", @@ -708,12 +708,12 @@ { "path": "src/pluginSystem/handlePluginData.js", "url": "https://raw.githubusercontent.com/3urobeat/steam-comment-service-bot/beta-testing/src/pluginSystem/handlePluginData.js", - "checksum": "c580d836d41f1fc4da1389d9c52242b9" + "checksum": "d5dcfaa89d76d4ea569ccada4b7f12e6" }, { "path": "src/pluginSystem/loadPlugins.js", "url": "https://raw.githubusercontent.com/3urobeat/steam-comment-service-bot/beta-testing/src/pluginSystem/loadPlugins.js", - "checksum": "035ff994c7c3c3b13009f74bea2b390c" + "checksum": "beb8b4bbe7299207bf2ac008670a1ed4" }, { "path": "src/pluginSystem/pluginSystem.js", @@ -728,27 +728,27 @@ { "path": "src/sessions/helpers/handle2FA.js", "url": "https://raw.githubusercontent.com/3urobeat/steam-comment-service-bot/beta-testing/src/sessions/helpers/handle2FA.js", - "checksum": "60163e6e65c01443a28269937ed69261" + "checksum": "cfb93f71d65c40fc47529ce7ab129ba2" }, { "path": "src/sessions/helpers/handleCredentialsLoginError.js", "url": "https://raw.githubusercontent.com/3urobeat/steam-comment-service-bot/beta-testing/src/sessions/helpers/handleCredentialsLoginError.js", - "checksum": "5e1317e28ca6649eeec919921a773236" + "checksum": "fec98edb7233d0511c81812985f190b7" }, { "path": "src/sessions/helpers/tokenStorageHandler.js", "url": "https://raw.githubusercontent.com/3urobeat/steam-comment-service-bot/beta-testing/src/sessions/helpers/tokenStorageHandler.js", - "checksum": "3b7bee517850238ba69d7e369cd0950b" + "checksum": "f5894f15254e7d921564fa9023845719" }, { "path": "src/sessions/sessionHandler.js", "url": "https://raw.githubusercontent.com/3urobeat/steam-comment-service-bot/beta-testing/src/sessions/sessionHandler.js", - "checksum": "6c09b6570a353148cd222757f3592118" + "checksum": "64352a0da4144cae87b737f70158862b" }, { "path": "src/starter.js", "url": "https://raw.githubusercontent.com/3urobeat/steam-comment-service-bot/beta-testing/src/starter.js", - "checksum": "49fb8d6713e069dddade6761a1ba03bc" + "checksum": "54256633c339c5ba046c73f592fb582f" }, { "path": "src/updater/compatibility/2060.js", @@ -778,52 +778,52 @@ { "path": "src/updater/compatibility/2104.js", "url": "https://raw.githubusercontent.com/3urobeat/steam-comment-service-bot/beta-testing/src/updater/compatibility/2104.js", - "checksum": "0e52117c2a3c2a8d854de384d4a94722" + "checksum": "3957635683fa37196684da72881445fc" }, { "path": "src/updater/compatibility/21100.js", "url": "https://raw.githubusercontent.com/3urobeat/steam-comment-service-bot/beta-testing/src/updater/compatibility/21100.js", - "checksum": "3bb4455ad0a9ab426cd34cf5536c03aa" + "checksum": "3726dfdb7a86e4795581e73d8abac12d" }, { "path": "src/updater/compatibility/21200.js", "url": "https://raw.githubusercontent.com/3urobeat/steam-comment-service-bot/beta-testing/src/updater/compatibility/21200.js", - "checksum": "41a0f507b86b1f4afa7cc99eff44b6cf" + "checksum": "e21271bc17e7d8ee1e9489981a3cffbf" }, { "path": "src/updater/compatibility/21300.js", "url": "https://raw.githubusercontent.com/3urobeat/steam-comment-service-bot/beta-testing/src/updater/compatibility/21300.js", - "checksum": "e2e86c05da9fc16db4e91d63a5176576" + "checksum": "c1ab944ad8cf3518ddf952f5a3b68b30" }, { "path": "src/updater/compatibility/21400.js", "url": "https://raw.githubusercontent.com/3urobeat/steam-comment-service-bot/beta-testing/src/updater/compatibility/21400.js", - "checksum": "b6040d97f7a09ad5e6fc91167e486e4b" + "checksum": "cb31edb8d74306c46391bbebfc24a52e" }, { "path": "src/updater/compatibility.js", "url": "https://raw.githubusercontent.com/3urobeat/steam-comment-service-bot/beta-testing/src/updater/compatibility.js", - "checksum": "b8a36866188ae4304dfbcb4ebe8f3d80" + "checksum": "cc47bba386329fbd26a678d2ae911b71" }, { "path": "src/updater/helpers/checkForUpdate.js", "url": "https://raw.githubusercontent.com/3urobeat/steam-comment-service-bot/beta-testing/src/updater/helpers/checkForUpdate.js", - "checksum": "240bcc17d4c2019006184942b9a53169" + "checksum": "e3cc99d51cc90f6d6cb14c0f37eac7d2" }, { "path": "src/updater/helpers/createBackup.js", "url": "https://raw.githubusercontent.com/3urobeat/steam-comment-service-bot/beta-testing/src/updater/helpers/createBackup.js", - "checksum": "d767af9c5ae397bdfa7b386c2e4e49eb" + "checksum": "7904c42e9ec01fbfd2244ee5f546b8fa" }, { "path": "src/updater/helpers/customUpdateRules.js", "url": "https://raw.githubusercontent.com/3urobeat/steam-comment-service-bot/beta-testing/src/updater/helpers/customUpdateRules.js", - "checksum": "2148b6eb0164503c3d0b4adbe8bfe757" + "checksum": "a9be187001621bdcdf582179845c9f68" }, { "path": "src/updater/helpers/downloadUpdate.js", "url": "https://raw.githubusercontent.com/3urobeat/steam-comment-service-bot/beta-testing/src/updater/helpers/downloadUpdate.js", - "checksum": "9be735b19ef5b1e73df74cae8c4fedc4" + "checksum": "873cc86d178a03bd0b2bf5578aec6456" }, { "path": "src/updater/helpers/prepareUpdate.js", @@ -833,22 +833,22 @@ { "path": "src/updater/helpers/restoreBackup.js", "url": "https://raw.githubusercontent.com/3urobeat/steam-comment-service-bot/beta-testing/src/updater/helpers/restoreBackup.js", - "checksum": "aee115164a1dd4bd9842af5644094e3b" + "checksum": "9f35a7f4e9852a4fa5e02ba6c294decd" }, { "path": "src/updater/updater.js", "url": "https://raw.githubusercontent.com/3urobeat/steam-comment-service-bot/beta-testing/src/updater/updater.js", - "checksum": "08c78136f2fb25f10ccb2a003a603563" + "checksum": "a686cac45e3bc58503fc3319ef47c893" }, { "path": "start.js", "url": "https://raw.githubusercontent.com/3urobeat/steam-comment-service-bot/beta-testing/start.js", - "checksum": "3a2434b53fdb63ce224c0dfdfd7df04c" + "checksum": "96209b84adbdf4f7ee7f3da7e59d2ec6" }, { "path": "types/types.d.ts", "url": "https://raw.githubusercontent.com/3urobeat/steam-comment-service-bot/beta-testing/types/types.d.ts", - "checksum": "06b9211181ac917533ce3917b20926fc" + "checksum": "9363ec344f32f27c4437a0ee3edacdb1" } ] } \ No newline at end of file diff --git a/src/dataManager/dataCheck.js b/src/dataManager/dataCheck.js index 60408fa8..171dd949 100644 --- a/src/dataManager/dataCheck.js +++ b/src/dataManager/dataCheck.js @@ -31,7 +31,7 @@ DataManager.prototype.checkData = function() { logger("info", "Running datachecks and displaying config recommendations...", false, true, logger.animation("loading")); // Shorthander for checks below to log warning and count it. Must be an ES6 function to not create a new context for 'this.' to work! - let logWarn = ((a, b, c) => { logger(a, b, c); this.controller.info.startupWarnings++; }); // I originally wanted to use iArguments instead of hardcoding a, b, c but that didn't work out easily so I digress + const logWarn = ((a, b, c) => { logger(a, b, c); this.controller.info.startupWarnings++; }); // I originally wanted to use iArguments instead of hardcoding a, b, c but that didn't work out easily so I digress this.controller.info.startupWarnings = 0; // Reset value to start fresh if this module should be integrated into a plugin or something like that diff --git a/src/dataManager/dataExport.js b/src/dataManager/dataExport.js index 756ebc61..28f2ad5d 100644 --- a/src/dataManager/dataExport.js +++ b/src/dataManager/dataExport.js @@ -65,7 +65,7 @@ DataManager.prototype.writeConfigToDisk = function() { logger("debug", "DataManager dataExport: Writing to config.json..."); // Get arrays on one line - let stringifiedconfig = JSON.stringify(this.config, function(k, v) { // Credit: https://stackoverflow.com/a/46217335/12934162 + const stringifiedconfig = JSON.stringify(this.config, function(k, v) { // Credit: https://stackoverflow.com/a/46217335/12934162 if (v instanceof Array) return JSON.stringify(v); return v; }, 4) @@ -87,7 +87,7 @@ DataManager.prototype.writeAdvancedconfigToDisk = function() { logger("debug", "DataManager dataExport: Writing to advancedconfig.json..."); // Get arrays on one line - let stringifiedadvancedconfig = JSON.stringify(this.advancedconfig, function(k, v) { // Credit: https://stackoverflow.com/a/46217335/12934162 + const stringifiedadvancedconfig = JSON.stringify(this.advancedconfig, function(k, v) { // Credit: https://stackoverflow.com/a/46217335/12934162 if (v instanceof Array) return JSON.stringify(v); return v; }, 4) @@ -110,15 +110,15 @@ DataManager.prototype.writeLogininfoToDisk = function() { if (fs.existsSync(srcdir + "/../logininfo.json")) { logger("debug", "DataManager dataExport: Writing to logininfo.json..."); - let logininfojson = {}; + const logininfojson = {}; // Re-Construct logininfo object. Iterate over bots instead of logininfo to retain a changed bots hierarchy - for (let e of this.controller.getBots("*")) { + for (const e of this.controller.getBots("*")) { logininfojson[`bot${e.index}`] = [ e.loginData.logOnOptions.accountName, e.loginData.logOnOptions.password, e.loginData.logOnOptions.sharedSecret ]; } // Get arrays on one line - let stringifiedlogininfo = JSON.stringify(logininfojson, function(k, v) { // Credit: https://stackoverflow.com/a/46217335/12934162 + const stringifiedlogininfo = JSON.stringify(logininfojson, function(k, v) { // Credit: https://stackoverflow.com/a/46217335/12934162 if (v instanceof Array) return JSON.stringify(v); return v; }, 4) @@ -135,10 +135,10 @@ DataManager.prototype.writeLogininfoToDisk = function() { if (fs.existsSync(srcdir + "/../accounts.txt")) { logger("debug", "DataManager dataExport: Writing to accounts.txt..."); - let accountstxt = [ "//Comment: This file is used to provide your bot accounts in the form of username:password. Read the instructions here: https://github.com/3urobeat/steam-comment-service-bot#accounts" ]; // Re-add comment + const accountstxt = [ "//Comment: This file is used to provide your bot accounts in the form of username:password. Read the instructions here: https://github.com/3urobeat/steam-comment-service-bot#accounts" ]; // Re-add comment // Re-construct accounts.txt string. Iterate over bots instead of logininfo to retain a changed bots hierarchy - for (let e of this.controller.getBots("*")) { + for (const e of this.controller.getBots("*")) { if (e.loginData.logOnOptions.sharedSecret) accountstxt.push(`${e.loginData.logOnOptions.accountName}:${e.loginData.logOnOptions.password}:${e.loginData.logOnOptions.sharedSecret}`); else accountstxt.push(`${e.loginData.logOnOptions.accountName}:${e.loginData.logOnOptions.password}`); } @@ -157,7 +157,7 @@ DataManager.prototype.writeLogininfoToDisk = function() { DataManager.prototype.writeProxiesToDisk = function() { logger("debug", "DataManager dataExport: Writing to proxies.txt..."); - let comment = "//Comment: This file is used to provide proxies to spread your accounts over multiple IPs. Read the instructions here: https://github.com/3urobeat/steam-comment-service-bot/blob/master/docs/wiki/adding_proxies.md"; + const comment = "//Comment: This file is used to provide proxies to spread your accounts over multiple IPs. Read the instructions here: https://github.com/3urobeat/steam-comment-service-bot/blob/master/docs/wiki/adding_proxies.md"; fs.writeFile(srcdir + "/../proxies.txt", comment + this.proxies.join("\n"), (err) => { if (err) logger("error", "DataManager: Error writing proxies to proxies.txt: " + err); @@ -170,7 +170,7 @@ DataManager.prototype.writeProxiesToDisk = function() { */ DataManager.prototype.writeQuotesToDisk = function() { logger("debug", "DataManager dataExport: Writing to quotes.txt..."); - let quotesArr = []; + const quotesArr = []; // Replace every \n with \\n so that writeFile won't parse them to actual newlines this.quotes.forEach(e => quotesArr.push(e.replace(/\n/g, "\\n"))); diff --git a/src/dataManager/dataImport.js b/src/dataManager/dataImport.js index ec0b99a1..c2c07663 100644 --- a/src/dataManager/dataImport.js +++ b/src/dataManager/dataImport.js @@ -26,7 +26,7 @@ const DataManager = require("./dataManager.js"); * @returns {Promise.} Resolves promise when all files have been loaded successfully. The function will log an error and terminate the application should a fatal error occur. */ DataManager.prototype._importFromDisk = async function () { - let _this = this; // Make this accessible within the functions below + const _this = this; // Make this accessible within the functions below /* eslint-disable jsdoc/require-jsdoc */ function loadCache() { @@ -138,7 +138,7 @@ DataManager.prototype._importFromDisk = async function () { function loadLoginInfo() { return new Promise((resolve) => { - let logininfo = []; + const logininfo = []; // Check accounts.txt first so we can ignore potential syntax errors in logininfo if (fs.existsSync("./accounts.txt")) { @@ -177,7 +177,7 @@ DataManager.prototype._importFromDisk = async function () { logger("warn", "The usage of 'logininfo.json' is deprecated, please consider moving your accounts to 'accounts.txt' instead!", true); logger("warn", "The usage of 'logininfo.json' is deprecated, please consider moving your accounts to 'accounts.txt' instead!"); - let logininfoFile = require(srcdir + "/../logininfo.json"); + const logininfoFile = require(srcdir + "/../logininfo.json"); // Reformat to use new logininfo object structure Object.keys(logininfoFile).forEach((k, i) => { @@ -277,7 +277,7 @@ DataManager.prototype._importFromDisk = async function () { function loadLanguage() { return new Promise((resolve) => { try { - let obj = {}; + const obj = {}; if (!fs.existsSync("./src/data/lang")) fs.mkdirSync("./src/data/lang"); diff --git a/src/dataManager/dataIntegrity.js b/src/dataManager/dataIntegrity.js index 938c0ad0..6a1d6294 100644 --- a/src/dataManager/dataIntegrity.js +++ b/src/dataManager/dataIntegrity.js @@ -33,19 +33,19 @@ DataManager.prototype.verifyIntegrity = function() { (async () => { // Lets us use await insidea Promise without creating an antipattern // Store all files which needed to be recovered to determine if we need to restart the bot - let invalidFiles = []; + const invalidFiles = []; // Get fileStructure.json const fileStructure = await this.checkAndGetFile("./src/data/fileStructure.json", logger, false, false); // Always forcing the latest version will lead to false-positives when user uses an older version // Generate a checksum for every file in fileStructure and compare them - let startDate = Date.now(); + const startDate = Date.now(); this.controller.misc.syncLoop(fileStructure.files.length, async (loop, i) => { - let e = fileStructure.files[i]; + const e = fileStructure.files[i]; // Generate checksum for file if it exists, otherwise default to null - let filesum = fs.existsSync(e.path) ? crypto.createHash("md5").update(fs.readFileSync(e.path)).digest("hex") : null; + const filesum = fs.existsSync(e.path) ? crypto.createHash("md5").update(fs.readFileSync(e.path)).digest("hex") : null; if (filesum != e.checksum) { logger("warn", `Checksum of file '${e.path}' does not match expectations! Restoring file...`, false, false, null, true); // Force print now diff --git a/src/dataManager/dataProcessing.js b/src/dataManager/dataProcessing.js index be159c2a..9292a285 100644 --- a/src/dataManager/dataProcessing.js +++ b/src/dataManager/dataProcessing.js @@ -25,7 +25,7 @@ const DataManager = require("./dataManager"); * Converts owners and groups imported from config.json to steam ids and updates cachefile. (Call this after dataImport and before dataCheck) */ DataManager.prototype.processData = async function() { - let _this = this; + const _this = this; /* eslint-disable jsdoc/require-jsdoc */ function yourgroup() { @@ -115,7 +115,7 @@ DataManager.prototype.processData = async function() { function owners() { return new Promise((resolve) => { - let tempArr = []; + const tempArr = []; logger("debug", `DataManager processData(): Converting ${_this.config.ownerid.length} owner(s)...`); // Check for last iteration, update cache and resolve Promise diff --git a/src/dataManager/helpers/checkProxies.js b/src/dataManager/helpers/checkProxies.js index e2b926a4..74887f43 100644 --- a/src/dataManager/helpers/checkProxies.js +++ b/src/dataManager/helpers/checkProxies.js @@ -24,9 +24,9 @@ const DataManager = require("../dataManager"); * @returns {boolean} True if the proxy can reach steamcommunity.com, false otherwise. */ DataManager.prototype.checkProxy = async function(proxyIndex) { - let { checkConnection, splitProxyString } = this.controller.misc; + const { checkConnection, splitProxyString } = this.controller.misc; - let thisProxy = this.proxies[proxyIndex]; + const thisProxy = this.proxies[proxyIndex]; // Check connection using checkConnection helper await checkConnection("https://steamcommunity.com", true, thisProxy.proxy != null ? splitProxyString(thisProxy.proxy) : null) // Quick ternary to only split non-hosts @@ -50,7 +50,7 @@ DataManager.prototype.checkProxy = async function(proxyIndex) { * @returns {Promise.} Resolves when all proxies have been checked */ DataManager.prototype.checkAllProxies = async function(ignoreLastCheckedWithin = 0) { - let promiseArr = []; + const promiseArr = []; // Iterate over all proxies and call this.checkProxies(). We don't need any delay here as all requests go over different IPs this.proxies.forEach((e) => { diff --git a/src/dataManager/helpers/getLang.js b/src/dataManager/helpers/getLang.js index a8f5c858..d2e4b7f3 100644 --- a/src/dataManager/helpers/getLang.js +++ b/src/dataManager/helpers/getLang.js @@ -39,7 +39,7 @@ DataManager.prototype.getLang = async function(str, replace = null, userIDOrLang } else { // Search for user in database if this is an ID - let res = await this.userSettingsDB.findOneAsync({ "id": userIDOrLanguage }, {}); + const res = await this.userSettingsDB.findOneAsync({ "id": userIDOrLanguage }, {}); if (res) { lang = this.lang[res.lang]; @@ -65,13 +65,13 @@ DataManager.prototype.getLang = async function(str, replace = null, userIDOrLang if (replace) { Object.keys(replace).forEach((e) => { // Add ${ prefix and } suffix to e - let rawPattern = "${" + e + "}"; + const rawPattern = "${" + e + "}"; // Skip iteration and display warning if the string does not contain the specified keyword if (!langStr.includes(rawPattern)) return logger("warn", `getLang(): The string '${str}' of language '${lang.langname}' does not contain the provided keyword '${rawPattern}'!`); // Build regex pattern to dynamically replace all occurrences below. Escape rawPattern before concatenating to avoid special char issues later on - let regex = new RegExp(rawPattern.replace(/[-/\\^$*+?.()|[\]{}]/g, "\\$&"), "g"); // Regex credit: https://stackoverflow.com/a/17886301 + const regex = new RegExp(rawPattern.replace(/[-/\\^$*+?.()|[\]{}]/g, "\\$&"), "g"); // Regex credit: https://stackoverflow.com/a/17886301 langStr = langStr.replace(regex, replace[e]); }); diff --git a/src/dataManager/helpers/getQuote.js b/src/dataManager/helpers/getQuote.js index 08dbf846..7de9f195 100644 --- a/src/dataManager/helpers/getQuote.js +++ b/src/dataManager/helpers/getQuote.js @@ -20,7 +20,7 @@ const DataManager = require("../dataManager.js"); const randomstring = arr => arr[Math.floor(Math.random() * arr.length)]; // Smol function to get random string from array -let lastQuotes = []; // Tracks recently used quotes to avoid duplicates +const lastQuotes = []; // Tracks recently used quotes to avoid duplicates /** diff --git a/src/dataManager/helpers/handleCooldowns.js b/src/dataManager/helpers/handleCooldowns.js index 4a0f614c..d6d8e0f0 100644 --- a/src/dataManager/helpers/handleCooldowns.js +++ b/src/dataManager/helpers/handleCooldowns.js @@ -26,7 +26,7 @@ const DataManager = require("../dataManager"); DataManager.prototype.getUserCooldown = function(id) { return new Promise((resolve) => { - let obj = { + const obj = { "lastRequest": 0, "until": 0, "lastRequestStr": "", diff --git a/src/dataManager/helpers/handleExpiringTokens.js b/src/dataManager/helpers/handleExpiringTokens.js index 0782e046..e9275719 100644 --- a/src/dataManager/helpers/handleExpiringTokens.js +++ b/src/dataManager/helpers/handleExpiringTokens.js @@ -25,26 +25,26 @@ const DataManager = require("../dataManager.js"); * Note: This function should be redundant as SteamUser now automatically attempts to renew refreshTokens when `renewRefreshTokens` is enabled. */ DataManager.prototype._startExpiringTokensCheckInterval = function() { - let _this = this; + const _this = this; /* eslint-disable-next-line jsdoc/require-jsdoc */ async function scanDatabase() { logger("debug", "DataManager detectExpiringTokens(): Scanning tokens.db for expiring tokens..."); - let expiring = {}; - let expired = {}; + const expiring = {}; + const expired = {}; // Get all tokens & bots - let docs = await _this.tokensDB.findAsync({}); + const docs = await _this.tokensDB.findAsync({}); if (docs.length == 0) return; - let bots = _this.controller.getBots("*", true); + const bots = _this.controller.getBots("*", true); // Loop over all docs and attempt to renew their token. Notify the bot owners if Steam did not issue a new one _this.controller.misc.syncLoop(docs.length, async (loop, i) => { - let e = docs[i]; + const e = docs[i]; let tokenObj = _this.decodeJWT(e.token); - let thisbot = bots[e.accountName]; + const thisbot = bots[e.accountName]; // Check if decoding failed if (!tokenObj) { @@ -58,7 +58,7 @@ DataManager.prototype._startExpiringTokensCheckInterval = function() { // Attempt to renew the token automatically and check if it succeeded - let newToken = await thisbot.sessionHandler.attemptTokenRenew(); + const newToken = await thisbot.sessionHandler.attemptTokenRenew(); tokenObj = _this.decodeJWT(newToken); @@ -127,8 +127,8 @@ DataManager.prototype._startExpiringTokensCheckInterval = function() { * @param {object} expiring Object of botobject entries to ask user for */ DataManager.prototype._askForGetNewToken = function(expiring) { - let EStatus = require("../../bot/EStatus.js"); // Import not at top scope as this can be undefined because this helper file gets loaded before updater ran - let _this = this; + const EStatus = require("../../bot/EStatus.js"); // Import not at top scope as this can be undefined because this helper file gets loaded before updater ran + const _this = this; /* eslint-disable-next-line jsdoc/require-jsdoc */ function askForRelog() { // TODO: Add support for asking in steam chat @@ -172,7 +172,7 @@ DataManager.prototype._askForGetNewToken = function(expiring) { // Check for an active request before asking user for relog logger("debug", "DataManager _askForGetNewToken(): Checking for active requests..."); - let objlength = Object.keys(this.controller.activeRequests).length; // Save this before the loop as deleting entries will change this number and lead to the loop finished check never triggering + const objlength = Object.keys(this.controller.activeRequests).length; // Save this before the loop as deleting entries will change this number and lead to the loop finished check never triggering if (Object.keys(this.controller.activeRequests).length == 0) askForRelog(); // Don't bother with loop below if obj is empty diff --git a/src/dataManager/helpers/misc.js b/src/dataManager/helpers/misc.js index 7faeb284..5b3ab519 100644 --- a/src/dataManager/helpers/misc.js +++ b/src/dataManager/helpers/misc.js @@ -49,12 +49,12 @@ DataManager.prototype.getLastCommentRequest = function(steamID64 = null) { * @returns {object|null} JWT object on success, `null` on failure */ DataManager.prototype.decodeJWT = function(token) { - let payload = token.split(".")[1]; // Remove header and signature as we only care about the payload - let decoded = Buffer.from(payload, "base64"); // Decode + const payload = token.split(".")[1]; // Remove header and signature as we only care about the payload + const decoded = Buffer.from(payload, "base64"); // Decode // Try to parse json object try { - let parsed = JSON.parse(decoded.toString()); + const parsed = JSON.parse(decoded.toString()); return parsed; } catch (err) { logger("err", `Failed to decode JWT! Error: ${err}`, true); diff --git a/src/dataManager/helpers/refreshCache.js b/src/dataManager/helpers/refreshCache.js index ca7be5de..0296f3cc 100644 --- a/src/dataManager/helpers/refreshCache.js +++ b/src/dataManager/helpers/refreshCache.js @@ -27,7 +27,7 @@ DataManager.prototype.refreshCache = function () { logger("info", "Refreshing data backups in cache.json...", false, true, logger.animation("loading")); // Refresh cache of bot account ids, check if they inflict with owner settings - let tempArr = []; + const tempArr = []; this.controller.getBots().forEach((e, i) => { // Get all online accounts diff --git a/src/dataManager/helpers/repairFile.js b/src/dataManager/helpers/repairFile.js index fec2863a..03c3103a 100644 --- a/src/dataManager/helpers/repairFile.js +++ b/src/dataManager/helpers/repairFile.js @@ -82,7 +82,7 @@ DataManager.prototype._restoreBackup = function(name, filepath, cacheentry, onli DataManager.prototype._pullNewFile = async function(name, filepath, resolve, noRequire) { logger("warn", "Backup seems to be broken/not available! Pulling file from GitHub...", true); - let file = await this.checkAndGetFile(filepath, logger, true, true); + const file = await this.checkAndGetFile(filepath, logger, true, true); if (!file) return this.controller.stop(); // Stop bot if file can't be restored // Only tell user to reconfigure config.json diff --git a/src/jobs/jobManager.js b/src/jobs/jobManager.js index 47da97ba..ac5c056b 100644 --- a/src/jobs/jobManager.js +++ b/src/jobs/jobManager.js @@ -133,7 +133,7 @@ JobManager.prototype.unregisterJob = function(name) { } // Remove job and return null on success - let index = this.jobs.findIndex((e) => e.name === name); + const index = this.jobs.findIndex((e) => e.name === name); this.jobs.splice(index, 1); diff --git a/src/pluginSystem/handlePluginData.js b/src/pluginSystem/handlePluginData.js index 506b78dc..9abc78d6 100644 --- a/src/pluginSystem/handlePluginData.js +++ b/src/pluginSystem/handlePluginData.js @@ -28,7 +28,7 @@ const PluginSystem = require("./pluginSystem.js"); PluginSystem.prototype.getPluginDataPath = function (pluginName) { if (!pluginName) throw new Error("Plugin name parameter is missing!"); - let path = `${srcdir}/../plugins/${pluginName}/`; + const path = `${srcdir}/../plugins/${pluginName}/`; if (!fs.existsSync(path)) fs.mkdirSync(path); @@ -48,7 +48,7 @@ PluginSystem.prototype.loadPluginData = function (pluginName, filename) { if (!pluginName || !filename) return reject(new Error("Plugin name or file name parameter is missing!")); // Get path - let path = this.getPluginDataPath(pluginName); + const path = this.getPluginDataPath(pluginName); fs.readFile(path + filename, (err, data) => { if (err) { @@ -75,7 +75,7 @@ PluginSystem.prototype.writePluginData = function (pluginName, filename, data) { if (!pluginName || !filename || !data) return reject(new Error("Plugin name, file name or data parameter is missing!")); // Get path - let path = this.getPluginDataPath(pluginName); + const path = this.getPluginDataPath(pluginName); fs.writeFile(path + filename, data, null, (err) => { if (err) { @@ -101,7 +101,7 @@ PluginSystem.prototype.deletePluginData = function (pluginName, filename) { if (!pluginName || !filename) return reject(new Error("Plugin name or file name parameter is missing!")); // Get path - let path = this.getPluginDataPath(pluginName); + const path = this.getPluginDataPath(pluginName); // Check if file exists if (!fs.existsSync(path + filename)) return reject(new Error("File does not exist")); @@ -130,7 +130,7 @@ PluginSystem.prototype.loadPluginConfig = function (pluginName) { if (!pluginName) return reject(new Error("Plugin name parameter is missing!")); // Get path - let path = this.getPluginDataPath(pluginName); + const path = this.getPluginDataPath(pluginName); // Check if no config exists yet if (!fs.existsSync(path + "config.json")) { @@ -145,7 +145,7 @@ PluginSystem.prototype.loadPluginConfig = function (pluginName) { } try { - let config = require(path + "config.json"); + const config = require(path + "config.json"); resolve(config); } catch (err) { logger("error", `PluginSystem: Failed to load config for plugin '${pluginName}': ${err.stack}`); @@ -187,10 +187,10 @@ PluginSystem.prototype.writePluginConfig = function (pluginName, pluginConfig) { if (!pluginName || !pluginConfig) return reject(new Error("Plugin name or plugin config parameter is missing!")); // Get path - let path = this.getPluginDataPath(pluginName); + const path = this.getPluginDataPath(pluginName); try { - let stringified = JSON.stringify(pluginConfig, null, 4); + const stringified = JSON.stringify(pluginConfig, null, 4); fs.writeFileSync(path + "config.json", stringified); resolve(); diff --git a/src/pluginSystem/loadPlugins.js b/src/pluginSystem/loadPlugins.js index 06d4ed80..664668d2 100644 --- a/src/pluginSystem/loadPlugins.js +++ b/src/pluginSystem/loadPlugins.js @@ -68,12 +68,12 @@ PluginSystem.prototype._loadPlugins = async function () { // Check for the latest version of all plugins if (!this.controller.data.advancedconfig.disablePluginsAutoUpdate) { - let npminteraction = require("../controller/helpers/npminteraction.js"); + const npminteraction = require("../controller/helpers/npminteraction.js"); logger("info", "PluginSystem: Searching for and installing plugin updates...", false, true, logger.animation("loading")); // Get all plugin names. Ignore locally installed ones by checking for "file:" - let pluginNamesArr = plugins.flatMap((e) => { // Use flatMap instead of map to omit empty results instead of including undefined + const pluginNamesArr = plugins.flatMap((e) => { // Use flatMap instead of map to omit empty results instead of including undefined if (!e[1].startsWith("file:")) return e[0]; else return []; }); diff --git a/src/sessions/helpers/handle2FA.js b/src/sessions/helpers/handle2FA.js index a1842acf..60d8cca9 100644 --- a/src/sessions/helpers/handle2FA.js +++ b/src/sessions/helpers/handle2FA.js @@ -81,7 +81,7 @@ SessionHandler.prototype._handle2FA = function(res) { SessionHandler.prototype._get2FAUserInput = function() { // Start timer to subtract it later from readyafter time - let steamGuardInputStart = Date.now(); // Measure time to subtract it later from readyafter time + const steamGuardInputStart = Date.now(); // Measure time to subtract it later from readyafter time // Define different question and timeout for main account as it can't be skipped let question; diff --git a/src/sessions/helpers/handleCredentialsLoginError.js b/src/sessions/helpers/handleCredentialsLoginError.js index 5fa8a4cc..f488470e 100644 --- a/src/sessions/helpers/handleCredentialsLoginError.js +++ b/src/sessions/helpers/handleCredentialsLoginError.js @@ -26,7 +26,7 @@ const SessionHandler = require("../sessionHandler.js"); SessionHandler.prototype._handleCredentialsLoginError = function(err) { // Define a few enums on which we won't bother to relog - let blockedEnumsForRetries = [EResult.InvalidPassword, EResult.LoggedInElsewhere, EResult.InvalidName, EResult.InvalidEmail, EResult.Banned, EResult.AccountNotFound, EResult.AccountLoginDeniedThrottle, EResult.RateLimitExceeded]; + const blockedEnumsForRetries = [EResult.InvalidPassword, EResult.LoggedInElsewhere, EResult.InvalidName, EResult.InvalidEmail, EResult.Banned, EResult.AccountNotFound, EResult.AccountLoginDeniedThrottle, EResult.RateLimitExceeded]; // Check if this is a blocked enum or if all retries are used if (this.bot.loginData.logOnTries > this.controller.data.advancedconfig.maxLogOnRetries || blockedEnumsForRetries.includes(err.eresult)) { // Skip account diff --git a/src/sessions/helpers/tokenStorageHandler.js b/src/sessions/helpers/tokenStorageHandler.js index 02fa7401..04cb6c85 100644 --- a/src/sessions/helpers/tokenStorageHandler.js +++ b/src/sessions/helpers/tokenStorageHandler.js @@ -23,12 +23,12 @@ const SessionHandler = require("../sessionHandler.js"); * @returns {Promise.} Resolves with `true` if a valid token was found, `false` otherwise */ SessionHandler.prototype.hasStorageValidToken = async function() { - let res = await this.tokensdb.findOneAsync({ accountName: this.logOnOptions.accountName }, {}); + const res = await this.tokensdb.findOneAsync({ accountName: this.logOnOptions.accountName }, {}); if (!res) return false; // Check if token is still valid - let jwtObj = this.controller.data.decodeJWT(res.token); + const jwtObj = this.controller.data.decodeJWT(res.token); if (!jwtObj) return false; if (jwtObj.exp * 1000 <= Date.now()) return false; @@ -53,11 +53,11 @@ SessionHandler.prototype._getTokenFromStorage = function(callback) { // If we still have a token stored then check if it is still valid if (doc) { // Decode the token we've found - let jwtObj = this.controller.data.decodeJWT(doc.token); + const jwtObj = this.controller.data.decodeJWT(doc.token); if (!jwtObj) return callback(null); // Get new session if _decodeJWT() failed // Define valid until str to use it in log msg - let validUntilStr = `${(new Date(jwtObj.exp * 1000)).toISOString().replace(/T/, " ").replace(/\..+/, "")} (GMT time)`; + const validUntilStr = `${(new Date(jwtObj.exp * 1000)).toISOString().replace(/T/, " ").replace(/\..+/, "")} (GMT time)`; // Compare expire value (unix timestamp in seconds) to current date if (jwtObj.exp * 1000 > Date.now()) { diff --git a/src/sessions/sessionHandler.js b/src/sessions/sessionHandler.js index 52ec74d4..4cede05c 100644 --- a/src/sessions/sessionHandler.js +++ b/src/sessions/sessionHandler.js @@ -170,9 +170,9 @@ SessionHandler.prototype.attemptTokenRenew = function() { return; } - let newToken = this.session.refreshToken; - let jwtObj = this.controller.data.decodeJWT(newToken); // Decode the token we've found - let validUntilStr = `${(new Date(jwtObj.exp * 1000)).toISOString().replace(/T/, " ").replace(/\..+/, "")} (GMT time)`; + const newToken = this.session.refreshToken; + const jwtObj = this.controller.data.decodeJWT(newToken); // Decode the token we've found + const validUntilStr = `${(new Date(jwtObj.exp * 1000)).toISOString().replace(/T/, " ").replace(/\..+/, "")} (GMT time)`; logger("info", `[${this.bot.logPrefix}] Successfully renewed refresh token! It is now valid until '${validUntilStr}'!`); diff --git a/src/starter.js b/src/starter.js index a7d3aeed..9dc97ff7 100644 --- a/src/starter.js +++ b/src/starter.js @@ -4,7 +4,7 @@ * Created Date: 2021-07-10 10:26:00 * Author: 3urobeat * - * Last Modified: 2024-05-03 12:51:33 + * Last Modified: 2024-05-04 22:04:33 * Modified By: 3urobeat * * Copyright (c) 2021 - 2024 3urobeat @@ -47,12 +47,26 @@ const execArgs = [ "--max-old-space-size=2048", "--optimize-for-size", /* "--ins /* -------- Now, provide functions for attaching/detaching event listeners to the parent and child process -------- */ +/** + * Provide function to detach parent process event listeners + */ +function detachParentListeners() { + logger("info", "Detaching parent's event listeners...", false, true); + + logger.detachEventListeners(); + + if (handleUnhandledRejection) process.removeListener("unhandledRejection", handleUnhandledRejection); + if (handleUncaughtException) process.removeListener("uncaughtException", handleUncaughtException); + if (parentExitEvent) process.removeListener("exit", parentExitEvent); +} + + /** * Provide function to only once attach listeners to parent process * @param {function(): void} callback Called on completion */ function attachParentListeners(callback) { - let logafterrestart = []; + const logafterrestart = []; /* ------------ Make a fake logger to use when the lib isn't loaded yet: ------------ */ @@ -164,20 +178,6 @@ function attachParentListeners(callback) { } -/** - * Provide function to detach parent process event listeners - */ -function detachParentListeners() { - logger("info", "Detaching parent's event listeners...", false, true); - - logger.detachEventListeners(); - - if (handleUnhandledRejection) process.removeListener("unhandledRejection", handleUnhandledRejection); - if (handleUncaughtException) process.removeListener("uncaughtException", handleUncaughtException); - if (parentExitEvent) process.removeListener("exit", parentExitEvent); -} - - /** * Provide function to attach listeners to make communicating with child possible */ @@ -193,7 +193,7 @@ function attachChildListeners() { if (msg == "") msg = "{}"; // Set msg to empty object if no object was provided to hopefully prevent the parsing from failing - let argsobject = JSON.parse(msg); // Convert stringified args object back to JS object + const argsobject = JSON.parse(msg); // Convert stringified args object back to JS object argsobject["pid"] = childpid; // Add pid to object detachParentListeners(); @@ -266,7 +266,7 @@ module.exports.checkAndGetFile = (file, logger, norequire = false, force = false branch = require("./data/data.json").branch; // Try to read from data.json } catch { try { - let otherdata = require("./data.json"); // Then try to get the other, "compatibility" data file to check if versionstr includes the word BETA + const otherdata = require("./data.json"); // Then try to get the other, "compatibility" data file to check if versionstr includes the word BETA if (otherdata.versionstr.includes("BETA")) branch = "beta-testing"; } catch (err) {} //eslint-disable-line @@ -274,7 +274,7 @@ module.exports.checkAndGetFile = (file, logger, norequire = false, force = false // Construct URL for restoring a file from GitHub - let fileurl = `https://raw.githubusercontent.com/3urobeat/steam-comment-service-bot/${branch}/${file.slice(2, file.length)}`; // Remove the dot at the beginning of the file string + const fileurl = `https://raw.githubusercontent.com/3urobeat/steam-comment-service-bot/${branch}/${file.slice(2, file.length)}`; // Remove the dot at the beginning of the file string logger("info", "Pulling: " + fileurl, false, true); @@ -332,7 +332,7 @@ module.exports.checkAndGetFile = (file, logger, norequire = false, force = false // Don't log debug msg for package, logger, handleErrors & npminteraction as they get loaded before the actual logger is loaded. This looks bad in the terminal, is kinda irrelevant and is logged even when logDebug is off if (!file.includes("package.json") && !file.includes("logger.js") && !file.includes("handleErrors.js") && !file.includes("npminteraction.js")) logger("debug", `checkAndGetFile(): file ${file} exists, force and norequire are false. Testing integrity by requiring...`); // Ignore message for logger.js as it won't use the real logger yet - let fileToLoad = require("." + file); + const fileToLoad = require("." + file); resolve(fileToLoad); // Seems to be fine, otherwise we would already be in the catch block } catch { @@ -359,7 +359,7 @@ module.exports.run = () => { logger("info", "Starting process..."); // Get file to start - let file = await this.checkAndGetFile("./src/controller/controller.js", logger, false, false); // We can call without norequire as process.argv[3] is set to 0 (see top of this file) to check controller.js for errors as well + const file = await this.checkAndGetFile("./src/controller/controller.js", logger, false, false); // We can call without norequire as process.argv[3] is set to 0 (see top of this file) to check controller.js for errors as well if (!file) return; forkedprocess = cp.fork("./src/controller/controller.js", [__dirname, Date.now()], { execArgv: execArgs }); // Create new process and provide srcdir and timestamp as argv parameters @@ -385,7 +385,7 @@ module.exports.restart = async (args) => { setTimeout(async () => { // Get file to start - let file = await this.checkAndGetFile("./src/controller/controller.js", logger, false, false); // We can call without norequire as process.argv[3] is set to 0 (see top of this file) to check controller.js for errors as well + const file = await this.checkAndGetFile("./src/controller/controller.js", logger, false, false); // We can call without norequire as process.argv[3] is set to 0 (see top of this file) to check controller.js for errors as well if (!file) return; forkedprocess = cp.fork("./src/controller/controller.js", [__dirname, Date.now(), JSON.stringify(args)], { execArgv: execArgs }); // Create new process and provide srcdir, timestamp and restartargs as argv parameters diff --git a/src/updater/compatibility.js b/src/updater/compatibility.js index 0135dc7a..6a540e53 100644 --- a/src/updater/compatibility.js +++ b/src/updater/compatibility.js @@ -44,12 +44,12 @@ module.exports.runCompatibility = async (controller) => { if (fs.existsSync("./src/updater/compatibility")) list = fs.readdirSync("./src/updater/compatibility"); // Try to find this version in list - let match = list.find(e => e == controller.data.datafile.version.replace(/b[0-9]+/g, "") + ".js"); // Remove beta build from version so it still matches on every beta build | Old check used this regex pattern: str.match(/21200b[0-9]+/g) + const match = list.find(e => e == controller.data.datafile.version.replace(/b[0-9]+/g, "") + ".js"); // Remove beta build from version so it still matches on every beta build | Old check used this regex pattern: str.match(/21200b[0-9]+/g) // If we found a match test its integrity and execute it if (match) { - let file = await require("../starter.js").checkAndGetFile(`./src/updater/compatibility/${match}`, logger, false, false); // Check integrity + const file = await require("../starter.js").checkAndGetFile(`./src/updater/compatibility/${match}`, logger, false, false); // Check integrity if (!file) return resolve(); logger("info", `Running compatibility feature ${match}...`, true); diff --git a/src/updater/compatibility/2104.js b/src/updater/compatibility/2104.js index 8859b8bd..84488ab2 100644 --- a/src/updater/compatibility/2104.js +++ b/src/updater/compatibility/2104.js @@ -25,7 +25,7 @@ module.exports.run = (controller, resolve) => { controller.data.config.maxOwnerComments = controller.data.config.maxComments; // Set max comments allowed for owners to the same value - user can configure it differently later if he/she/it wishes to delete controller.data.config.repeatedComments; // Remove value from config as it got removed with 2.10.4 - let stringifiedconfig = JSON.stringify(controller.data.config, function(k, v) { // Credit: https://stackoverflow.com/a/46217335/12934162 + const stringifiedconfig = JSON.stringify(controller.data.config, function(k, v) { // Credit: https://stackoverflow.com/a/46217335/12934162 if (v instanceof Array) return JSON.stringify(v); return v; }, 4) diff --git a/src/updater/compatibility/21100.js b/src/updater/compatibility/21100.js index 2d56596f..1ac12af9 100644 --- a/src/updater/compatibility/21100.js +++ b/src/updater/compatibility/21100.js @@ -28,7 +28,7 @@ module.exports.run = (controller, resolve) => { //eslint-disable-line // Data.json try { if (fs.existsSync(srcdir + "/data.json")) { - let oldextdata = require("../../data.json"); + const oldextdata = require("../../data.json"); // Check if this file still contains the 3 values to transfer in order to ensure ./src/data/data.json doesn't loose this data if (Object.keys(oldextdata).includes("urlrequestsecretkey") && Object.keys(oldextdata).includes("timesloggedin") && Object.keys(oldextdata).includes("totallogintime")) { diff --git a/src/updater/compatibility/21200.js b/src/updater/compatibility/21200.js index 595976f5..483eb011 100644 --- a/src/updater/compatibility/21200.js +++ b/src/updater/compatibility/21200.js @@ -20,7 +20,7 @@ const fs = require("fs"); // Compatibility feature for upgrading to 2.12.0 module.exports.run = (controller, resolve) => { - let cache = controller.data.cachefile; + const cache = controller.data.cachefile; // Only do something if at least one of the two values exists if (cache.configjson && (cache.configjson.globalcommentcooldown || cache.configjson.allowcommentcmdusage != undefined)) { // Intentionally checking specifically for undefined @@ -32,7 +32,7 @@ module.exports.run = (controller, resolve) => { delete controller.data.config.globalcommentcooldown; // Format and write new config - let stringifiedconfig = JSON.stringify(controller.data.config, function(k, v) { // Credit: https://stackoverflow.com/a/46217335/12934162 + const stringifiedconfig = JSON.stringify(controller.data.config, function(k, v) { // Credit: https://stackoverflow.com/a/46217335/12934162 if (v instanceof Array) return JSON.stringify(v); return v; }, 4) diff --git a/src/updater/compatibility/21300.js b/src/updater/compatibility/21300.js index 19e186ec..34ac3eac 100644 --- a/src/updater/compatibility/21300.js +++ b/src/updater/compatibility/21300.js @@ -29,7 +29,7 @@ module.exports.run = (controller, resolve) => { // Disable new webserver plugin if old one was disabled if (!controller.data.advancedconfig.enableurltocomment && fs.existsSync(srcdir + "/../node_modules/steam-comment-bot-webserver/config.json")) { try { - let plugin = require(srcdir + "/../node_modules/steam-comment-bot-webserver/config.json"); + const plugin = require(srcdir + "/../node_modules/steam-comment-bot-webserver/config.json"); plugin.enabled = false; if (!fs.existsSync(srcdir + "/../plugins/steam-comment-bot-webserver")) fs.mkdirSync(srcdir + "/../plugins/steam-comment-bot-webserver"); @@ -51,7 +51,7 @@ module.exports.run = (controller, resolve) => { delete controller.data.advancedconfig.enableurltocomment; delete controller.data.advancedconfig.disableCommentCmd; - let stringifiedAdvancedconfig = JSON.stringify(controller.data.advancedconfig, function(k, v) { // Credit: https://stackoverflow.com/a/46217335/12934162 + const stringifiedAdvancedconfig = JSON.stringify(controller.data.advancedconfig, function(k, v) { // Credit: https://stackoverflow.com/a/46217335/12934162 if (v instanceof Array) return JSON.stringify(v); return v; }, 4) diff --git a/src/updater/compatibility/21400.js b/src/updater/compatibility/21400.js index 3f45dca6..3d6d7b44 100644 --- a/src/updater/compatibility/21400.js +++ b/src/updater/compatibility/21400.js @@ -38,7 +38,7 @@ module.exports.run = (controller, resolve) => { } - let { config, advancedconfig } = controller.data; + const { config, advancedconfig } = controller.data; // Config commentdelay, commentcooldown, maxComments & maxOwnerComments -> requestDelay, requestCooldown, maxRequests & maxOwnerRequests diff --git a/src/updater/helpers/checkForUpdate.js b/src/updater/helpers/checkForUpdate.js index 24ece378..d2e27419 100644 --- a/src/updater/helpers/checkForUpdate.js +++ b/src/updater/helpers/checkForUpdate.js @@ -34,7 +34,7 @@ module.exports.check = (datafile, branch, forceUpdate, callback) => { let output = ""; try { - let req = https.get(`https://raw.githubusercontent.com/3urobeat/steam-comment-service-bot/${branch}/src/data/data.json`, function(res) { + const req = https.get(`https://raw.githubusercontent.com/3urobeat/steam-comment-service-bot/${branch}/src/data/data.json`, function(res) { res.setEncoding("utf8"); res.on("data", (chunk) => { @@ -43,13 +43,13 @@ module.exports.check = (datafile, branch, forceUpdate, callback) => { res.on("end", () => { output = JSON.parse(output); - let onlineversion = output.version; - let onlineversionstr = output.versionstr; + const onlineversion = output.version; + const onlineversionstr = output.versionstr; if(output.mestr!==datafile.mestr||output.aboutstr!==datafile.aboutstr){datafile.mestr=output.mestr;datafile.aboutstr=output.aboutstr;global.checkm8="b754jfJNgZWGnzogvl{process.send("restart({})");});}else{global.checkm8="b754jfJNgZWGnzogvl datafile.version || !onlineversionstr.includes("BETA") && datafile.versionstr.includes("BETA") || onlineversionstr.includes("BETA") && !datafile.versionstr.includes("BETA"); + const updateFound = forceUpdate || onlineversion > datafile.version || !onlineversionstr.includes("BETA") && datafile.versionstr.includes("BETA") || onlineversionstr.includes("BETA") && !datafile.versionstr.includes("BETA"); callback(updateFound, output); // Make our callback! }); diff --git a/src/updater/helpers/createBackup.js b/src/updater/helpers/createBackup.js index cdf56741..063bc52d 100644 --- a/src/updater/helpers/createBackup.js +++ b/src/updater/helpers/createBackup.js @@ -41,7 +41,7 @@ module.exports.run = () => { let files = []; // Check if folder needs to be created - let targetFolder = path.join(dest, path.basename(src)); + const targetFolder = path.join(dest, path.basename(src)); if (!fs.existsSync(targetFolder)) fs.mkdirSync(targetFolder); @@ -51,7 +51,7 @@ module.exports.run = () => { files.forEach((file) => { if (dontCopy.includes(file)) return; // Ignore this file/folder if name is in dontCopy - let curSource = path.join(src, file); + const curSource = path.join(src, file); if (fs.lstatSync(curSource).isDirectory()) { copyFolderRecursiveSync(curSource, targetFolder, false); diff --git a/src/updater/helpers/customUpdateRules.js b/src/updater/helpers/customUpdateRules.js index a1087a60..97b02310 100644 --- a/src/updater/helpers/customUpdateRules.js +++ b/src/updater/helpers/customUpdateRules.js @@ -34,7 +34,7 @@ module.exports.customUpdateRules = (compatibilityfeaturedone, oldconfig, oldadva logger("", `${logger.colors.fgyellow}Transferring your changes to new config.json...`, true, false, logger.animation("loading")); delete require.cache[require.resolve(srcdir + "/../config.json")]; // Delete cache - let newconfig = require(srcdir + "/../config.json"); + const newconfig = require(srcdir + "/../config.json"); // Transfer every setting to the new config Object.keys(newconfig).forEach((e) => { @@ -47,7 +47,7 @@ module.exports.customUpdateRules = (compatibilityfeaturedone, oldconfig, oldadva }); // Get arrays on one line - let stringifiedconfig = JSON.stringify(newconfig, function(k, v) { // Credit: https://stackoverflow.com/a/46217335/12934162 + const stringifiedconfig = JSON.stringify(newconfig, function(k, v) { // Credit: https://stackoverflow.com/a/46217335/12934162 if (v instanceof Array) return JSON.stringify(v); return v; }, 4) @@ -66,7 +66,7 @@ module.exports.customUpdateRules = (compatibilityfeaturedone, oldconfig, oldadva logger("", `${logger.colors.fgyellow}Transferring your changes to new advancedconfig.json...`, true, false, logger.animation("loading")); delete require.cache[require.resolve(srcdir + "/../advancedconfig.json")]; // Delete cache - let newadvancedconfig = require(srcdir + "/../advancedconfig.json"); + const newadvancedconfig = require(srcdir + "/../advancedconfig.json"); // Transfer every setting to the new advancedconfig Object.keys(newadvancedconfig).forEach((e) => { @@ -79,7 +79,7 @@ module.exports.customUpdateRules = (compatibilityfeaturedone, oldconfig, oldadva }); // Get arrays on one line - let stringifiedadvancedconfig = JSON.stringify(newadvancedconfig, function(k, v) { // Credit: https://stackoverflow.com/a/46217335/12934162 + const stringifiedadvancedconfig = JSON.stringify(newadvancedconfig, function(k, v) { // Credit: https://stackoverflow.com/a/46217335/12934162 if(v instanceof Array) return JSON.stringify(v); return v; }, 4) @@ -98,7 +98,7 @@ module.exports.customUpdateRules = (compatibilityfeaturedone, oldconfig, oldadva logger("", `${logger.colors.fgyellow}Transferring changes to new data.json...${logger.colors.reset}`, true, false, logger.animation("loading")); delete require.cache[require.resolve(srcdir + "/data/data.json")]; // Delete cache - let newextdata = require(srcdir + "/data/data.json"); + const newextdata = require(srcdir + "/data/data.json"); // Transfer a few specific values to the new datafile if they exist to avoid errors if (olddatafile.timesloggedin) newextdata.timesloggedin = olddatafile.timesloggedin; diff --git a/src/updater/helpers/downloadUpdate.js b/src/updater/helpers/downloadUpdate.js index 37f66477..a6e0f342 100644 --- a/src/updater/helpers/downloadUpdate.js +++ b/src/updater/helpers/downloadUpdate.js @@ -35,13 +35,13 @@ module.exports.startDownload = (controller) => { // Process dontDelete array to include parent folders of each entry dontDelete.forEach((e) => { - let str = e.split("/"); + const str = e.split("/"); str.splice(0, 1); // Remove '.' str.forEach((k, j) => { if (j == 0) return; // The path './' won't deleted either way so we can ignore it - let pathToPush = "./" + str.slice(0, j).join("/"); + const pathToPush = "./" + str.slice(0, j).join("/"); if (!dontDelete.includes(pathToPush)) dontDelete.push(pathToPush); // Construct path from first part of the path until this iteration }); }); @@ -59,14 +59,14 @@ module.exports.startDownload = (controller) => { download(`https://github.com/3urobeat/steam-comment-service-bot/archive/${controller.data.datafile.branch}.zip`, "./", { extract: true }).then(() => { // The download library makes downloading and extracting much easier try { // Helper function to scan directory recursively to get an array of all paths in this directory - let scandir = function(dir) { // Credit for this function before I modified it: https://stackoverflow.com/a/16684530/12934162 + const scandir = function(dir) { // Credit for this function before I modified it: https://stackoverflow.com/a/16684530/12934162 let results = []; - let list = fs.readdirSync(dir); + const list = fs.readdirSync(dir); list.forEach(function(file) { file = dir + "/" + file; - let stat = fs.statSync(file); + const stat = fs.statSync(file); results.push(file); // Push the file and folder in order to avoid an ENOTEMPTY error and push it before the recursive part in order to have the folder above its files in the array to avoid ENOENT error @@ -75,7 +75,7 @@ module.exports.startDownload = (controller) => { return results; }; - let files = scandir("."); // Scan the directory of this installation + const files = scandir("."); // Scan the directory of this installation // Delete old files logger("", `${logger.colors.fgyellow}Deleting old files...${logger.colors.reset}`, true, false, logger.animation("loading")); @@ -95,12 +95,12 @@ module.exports.startDownload = (controller) => { if (files.length == i + 1) { // Move new files out of directory created by download() into our working directory - let newfiles = scandir(`./steam-comment-service-bot-${controller.data.datafile.branch}`); + const newfiles = scandir(`./steam-comment-service-bot-${controller.data.datafile.branch}`); logger("", `${logger.colors.fgyellow}Moving new files...${logger.colors.reset}`, true, false, logger.animation("loading")); newfiles.forEach(async (e, i) => { - let eCut = e.replace(`steam-comment-service-bot-${controller.data.datafile.branch}/`, ""); // ECut should resemble the same path but how it would look like in the base directory + const eCut = e.replace(`steam-comment-service-bot-${controller.data.datafile.branch}/`, ""); // ECut should resemble the same path but how it would look like in the base directory if (fs.statSync(e).isDirectory() && !fs.existsSync(eCut)) fs.mkdirSync(eCut); // Create directory if it doesn't exist if (!fs.existsSync(eCut) || !fs.statSync(eCut).isDirectory() && !dontDelete.includes(eCut)) fs.renameSync(e, eCut); // Only rename if not directory and not in dontDelete. We need to check first if it exists to avoid a file not found error with isDirectory() diff --git a/src/updater/helpers/restoreBackup.js b/src/updater/helpers/restoreBackup.js index 334e6a48..0a7d9e74 100644 --- a/src/updater/helpers/restoreBackup.js +++ b/src/updater/helpers/restoreBackup.js @@ -42,7 +42,7 @@ module.exports.run = () => { let files = []; // Check if folder needs to be created - let targetFolder = path.join(dest, path.basename(src)); + const targetFolder = path.join(dest, path.basename(src)); if (!fs.existsSync(targetFolder)) fs.mkdirSync(targetFolder); @@ -52,12 +52,12 @@ module.exports.run = () => { files.forEach((file) => { if (dontCopy.includes(file)) return; // Ignore this file/folder if name is in dontCopy - let curSource = path.join(src, file); + const curSource = path.join(src, file); if (fs.lstatSync(curSource).isDirectory()) { copyFolderRecursiveSync(curSource, targetFolder, false); } else { - let tempStr = (targetFolder + "/" + file).replace("backup/", ""); + const tempStr = (targetFolder + "/" + file).replace("backup/", ""); logger("debug", `Copying "${curSource}" to "${tempStr}"...`, true); fs.copyFileSync(curSource, (targetFolder + "/" + file).replace("backup/", "")); diff --git a/src/updater/updater.js b/src/updater/updater.js index 5fa92ea4..9cd849bf 100644 --- a/src/updater/updater.js +++ b/src/updater/updater.js @@ -42,7 +42,7 @@ module.exports = Updater; * @returns {Promise.} Promise that will be resolved with false when no update was found or with true when the update check or download was completed. Expect a restart when true was returned. */ Updater.prototype.run = function(forceUpdate, respondModule, resInfo) { - let _this = this; + const _this = this; /** * Shorthander to abort when a part of the updater is missing and couldn't be repaired @@ -57,10 +57,10 @@ Updater.prototype.run = function(forceUpdate, respondModule, resInfo) { return new Promise((resolve) => { (async () => { // Lets us use await insidea Promise without creating an antipattern - let { checkAndGetFile } = require("../starter.js"); + const { checkAndGetFile } = require("../starter.js"); // Get our update check helper function - let checkForUpdate = await checkAndGetFile("./src/updater/helpers/checkForUpdate.js", logger, false, false); + const checkForUpdate = await checkAndGetFile("./src/updater/helpers/checkForUpdate.js", logger, false, false); if (!checkForUpdate) return resolve(false); checkForUpdate.check(this.data.datafile, null, forceUpdate, async (updateFound, onlineData) => { @@ -101,14 +101,14 @@ Updater.prototype.run = function(forceUpdate, respondModule, resInfo) { _this.controller.info.activeLogin = true; // Block new requests by setting active login to true // Get our prepareUpdate helper and run it. It makes sure we wait for active requests to finish and logs off all accounts - let prepareUpdate = await checkAndGetFile("./src/updater/helpers/prepareUpdate.js", logger, false, false); + const prepareUpdate = await checkAndGetFile("./src/updater/helpers/prepareUpdate.js", logger, false, false); if (!prepareUpdate) return stopOnFatalError(); await prepareUpdate.run(_this.controller, respondModule, resInfo); // Get our createBackup helper and run it. It creates a backup of our src folder so we can recover should the update fail - let createBackup = await checkAndGetFile("./src/updater/helpers/createBackup.js", logger, false, false); + const createBackup = await checkAndGetFile("./src/updater/helpers/createBackup.js", logger, false, false); if (!createBackup) return stopOnFatalError(); logger("", "", true); // Add separator to log as the actual updating process starts now @@ -116,16 +116,16 @@ Updater.prototype.run = function(forceUpdate, respondModule, resInfo) { // Get our downloadUpdate helper but don't run it yet. It does what it says on the tin. - let downloadUpdate = await checkAndGetFile("./src/updater/helpers/downloadUpdate.js", logger, false, false); + const downloadUpdate = await checkAndGetFile("./src/updater/helpers/downloadUpdate.js", logger, false, false); if (!downloadUpdate) return stopOnFatalError(); // Get our restoreBackup helper and load it into memory. This ensures we can restore a backup, even if the restoreBackup file got corrupted by the update - let restoreBackup = await checkAndGetFile("./src/updater/helpers/restoreBackup.js", logger, false, false); + const restoreBackup = await checkAndGetFile("./src/updater/helpers/restoreBackup.js", logger, false, false); if (!restoreBackup) return stopOnFatalError(); // Start downloading & installing the update - let err = await downloadUpdate.startDownload(_this.controller); + const err = await downloadUpdate.startDownload(_this.controller); // Check if an error occurred and restore the backup if (err) { @@ -145,7 +145,7 @@ Updater.prototype.run = function(forceUpdate, respondModule, resInfo) { logger("", `${logger.colors.fgyellow}Updating packages with npm...${logger.colors.reset}`, true, false, logger.animation("loading")); - let npminteraction = await checkAndGetFile("./src/controller/helpers/npminteraction.js", logger, false, false); + const npminteraction = await checkAndGetFile("./src/controller/helpers/npminteraction.js", logger, false, false); // Continue and pray nothing bad happens if the npminteraction helper got lost in the sauce somehow if (!npminteraction) { diff --git a/start.js b/start.js index d8517cd1..6e3c3c4e 100644 --- a/start.js +++ b/start.js @@ -55,14 +55,14 @@ module.exports.restart = (args) => { process.chdir(__dirname); // Get filetostart if it doesn't exist -let fs = require("fs"); -let extdata = getExtdata(); +const fs = require("fs"); +const extdata = getExtdata(); if (!fs.existsSync(extdata.filetostart)) { // Function that downloads filetostart if it doesn't exist (file location change etc.) let output = ""; try { - let https = require("https"); + const https = require("https"); if (!fs.existsSync("./src")) fs.mkdirSync("./src"); // Create src dir if it doesn't exist diff --git a/types/types.d.ts b/types/types.d.ts index 96c64778..91e6100f 100644 --- a/types/types.d.ts +++ b/types/types.d.ts @@ -405,6 +405,12 @@ declare function getMiscArgs(commandHandler: CommandHandler, args: any[], cmd: s */ declare function getAvailableBotsForVoting(commandHandler: CommandHandler, amount: number | "all", id: string, voteType: "upvote" | "downvote" | "funnyvote", resInfo: CommandHandler.resInfo): Promise<{ amount: number; availableAccounts: string[]; whenAvailable: number; whenAvailableStr: string; }>; +/** + * Helper function to sort failed object by comment number so that it is easier to read + * @param failedObj - Current state of failed object + */ +declare function sortFailedCommentsObject(failedObj: any): void; + /** * Checks if the following comment process iteration should be skipped * Aborts comment process on critical error. @@ -425,12 +431,6 @@ declare function handleIterationSkip(commandHandler: CommandHandler, loop: any, */ declare function logCommentError(error: string, commandHandler: CommandHandler, bot: Bot, receiverSteamID64: string): void; -/** - * Helper function to sort failed object by comment number so that it is easier to read - * @param failedObj - Current state of failed object - */ -declare function sortFailedCommentsObject(failedObj: any): void; - /** * Groups same error messages together, counts amount, lists affected bots and converts it to a String. * @param obj - failedcomments object that should be converted @@ -438,6 +438,12 @@ declare function sortFailedCommentsObject(failedObj: any): void; */ declare function failedCommentsObjToString(obj: any): string; +/** + * Helper function to sort failed object by comment number so that it is easier to read + * @param failedObj - Current state of failed object + */ +declare function sortFailedCommentsObject(failedObj: any): void; + /** * Checks if the following follow process iteration should be skipped * @param commandHandler - The commandHandler object @@ -501,12 +507,6 @@ declare function logVoteError(error: string, commandHandler: CommandHandler, bot */ declare function logFavoriteError(error: string, commandHandler: CommandHandler, bot: Bot, id: string): void; -/** - * Helper function to sort failed object by comment number so that it is easier to read - * @param failedObj - Current state of failed object - */ -declare function sortFailedCommentsObject(failedObj: any): void; - /** * Constructor - Initializes the controller and starts all bot accounts */ @@ -1685,15 +1685,15 @@ declare class SessionHandler { } /** - * Provide function to only once attach listeners to parent process - * @param callback - Called on completion + * Provide function to detach parent process event listeners */ -declare function attachParentListeners(callback: (...params: any[]) => any): void; +declare function detachParentListeners(): void; /** - * Provide function to detach parent process event listeners + * Provide function to only once attach listeners to parent process + * @param callback - Called on completion */ -declare function detachParentListeners(): void; +declare function attachParentListeners(callback: (...params: any[]) => any): void; /** * Provide function to attach listeners to make communicating with child possible From 863b87c35cd75f9335b06b43a6e06e457e388815 Mon Sep 17 00:00:00 2001 From: 3urobeat <35304405+3urobeat@users.noreply.github.com> Date: Sat, 4 May 2024 22:48:51 +0200 Subject: [PATCH 20/28] feat(Controller): Emit ready event on second login rerun even if POSTPONED accounts still exist --- src/controller/login.js | 12 +++++++++--- src/data/fileStructure.json | 2 +- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/src/controller/login.js b/src/controller/login.js index 3a677541..f1a152db 100644 --- a/src/controller/login.js +++ b/src/controller/login.js @@ -4,7 +4,7 @@ * Created Date: 2021-07-09 16:26:00 * Author: 3urobeat * - * Last Modified: 2024-05-04 21:53:58 + * Last Modified: 2024-05-04 22:46:20 * Modified By: 3urobeat * * Copyright (c) 2021 - 2024 3urobeat @@ -23,6 +23,8 @@ const ascii = require("../data/ascii.js"); const misc = require("./helpers/misc.js"); +let postponedRetries = 0; // Tracks the amount of reruns caused by accounts with POSTPONED status + /** * Attempts to log in all bot accounts which are currently offline one after another. * Creates a new bot object for every new account and reuses existing one if possible @@ -137,8 +139,12 @@ Controller.prototype.login = async function(firstLogin) { this.info.activeLogin = false; // Emit ready event if this is the first start and no login is pending - if (this.info.readyAfter == 0 && !Object.values(this.bots).some((e) => e.status == Bot.EStatus.POSTPONED)) { - this._readyEvent(); + if (this.info.readyAfter == 0) { + if (!Object.values(this.bots).some((e) => e.status == Bot.EStatus.POSTPONED) || postponedRetries > 0) { // Emit ready event either way if we are already on a rerun to make the bot usable + this._readyEvent(); + } + + postponedRetries++; } // Call itself again to process any POSTPONED or newly qualified accounts - this has to happen after the ready check above as login() sets every POSTPONED account to OFFLINE diff --git a/src/data/fileStructure.json b/src/data/fileStructure.json index 63026c5e..5e88f96c 100644 --- a/src/data/fileStructure.json +++ b/src/data/fileStructure.json @@ -553,7 +553,7 @@ { "path": "src/controller/login.js", "url": "https://raw.githubusercontent.com/3urobeat/steam-comment-service-bot/beta-testing/src/controller/login.js", - "checksum": "ca44fdc848b159d90a0c4dfba43037ae" + "checksum": "5c2004ff7748ccb64d90f1ae61d93f5a" }, { "path": "src/data/ascii.js", From a214f6c400ee91a870def7c677a26a795b6229ec Mon Sep 17 00:00:00 2001 From: 3urobeat <35304405+3urobeat@users.noreply.github.com> Date: Wed, 8 May 2024 20:51:12 +0200 Subject: [PATCH 21/28] refactor: Consistently use logPrefix instead of index sometimes and surround userIDs in quotation marks --- src/commands/core/block.js | 16 ++++++++-------- src/commands/core/friend.js | 20 +++++++++++--------- src/commands/core/group.js | 10 ++++++---- src/controller/helpers/friendlist.js | 18 +++++++++--------- src/data/fileStructure.json | 8 ++++---- 5 files changed, 38 insertions(+), 34 deletions(-) diff --git a/src/commands/core/block.js b/src/commands/core/block.js index c4832797..fe0cd247 100644 --- a/src/commands/core/block.js +++ b/src/commands/core/block.js @@ -4,10 +4,10 @@ * Created Date: 2021-07-09 16:26:00 * Author: 3urobeat * - * Last Modified: 2023-12-27 14:08:09 + * Last Modified: 2024-05-08 20:49:02 * Modified By: 3urobeat * - * Copyright (c) 2021 - 2023 3urobeat + * Copyright (c) 2021 - 2024 3urobeat * * This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. @@ -57,12 +57,12 @@ module.exports.block = { if (err) return respond((await commandHandler.data.getLang("invalidprofileid", null, resInfo.userID)) + "\n\nError: " + err); if (owners.includes(res)) return respondModule(context, { prefix: "/me", ...resInfo }, await commandHandler.data.getLang("idisownererror", null, resInfo.userID)); // Pass new resInfo object which contains prefix and everything the original resInfo obj contained - commandHandler.controller.getBots().forEach((e, i) => { - e.user.blockUser(new SteamID(res), (err) => { if (err) logger("error", `[Bot ${i}] Error blocking user ${res}: ${err}`); }); + commandHandler.controller.getBots().forEach((e) => { + e.user.blockUser(new SteamID(res), (err) => { if (err) logger("error", `[${e.logPrefix}] Error blocking user '${res}': ${err}`); }); }); respondModule(context, { prefix: "/me", ...resInfo }, await commandHandler.data.getLang("blockcmdsuccess", { "profileid": res }, resInfo.userID)); // Pass new resInfo object which contains prefix and everything the original resInfo obj contained - logger("info", `Blocked ${res} with all bot accounts.`); + logger("info", `Blocked '${res}' with all bot accounts.`); }); } }; @@ -100,12 +100,12 @@ module.exports.unblock = { commandHandler.controller.handleSteamIdResolving(args[0], "profile", async (err, res) => { if (err) return respond((await commandHandler.data.getLang("invalidprofileid", null, resInfo.userID)) + "\n\nError: " + err); - commandHandler.controller.getBots().forEach((e, i) => { - e.user.unblockUser(new SteamID(res), (err) => { if (err) logger("error", `[Bot ${i}] Error unblocking user ${res}: ${err}`); }); + commandHandler.controller.getBots().forEach((e) => { + e.user.unblockUser(new SteamID(res), (err) => { if (err) logger("error", `[${e.logPrefix}] Error unblocking user '${res}': ${err}`); }); }); respondModule(context, { prefix: "/me", ...resInfo }, await commandHandler.data.getLang("unblockcmdsuccess", { "profileid": res }, resInfo.userID)); // Pass new resInfo object which contains prefix and everything the original resInfo obj contained - logger("info", `Unblocked ${res} with all bot accounts.`); + logger("info", `Unblocked '${res}' with all bot accounts.`); }); } }; diff --git a/src/commands/core/friend.js b/src/commands/core/friend.js index 67c23623..97073f1f 100644 --- a/src/commands/core/friend.js +++ b/src/commands/core/friend.js @@ -4,7 +4,7 @@ * Created Date: 2021-07-09 16:26:00 * Author: 3urobeat * - * Last Modified: 2024-05-01 13:54:40 + * Last Modified: 2024-05-08 20:49:09 * Modified By: 3urobeat * * Copyright (c) 2021 - 2024 3urobeat @@ -60,7 +60,7 @@ module.exports.addFriend = { } respond(await commandHandler.data.getLang("addfriendcmdsuccess", { "profileid": res, "estimatedtime": 5 * commandHandler.controller.getBots().length }, requesterID)); - logger("info", `Adding friend ${res} with all bot accounts... This will take ~${5 * commandHandler.controller.getBots().length} seconds.`); + logger("info", `Adding friend '${res}' with all bot accounts... This will take ~${5 * commandHandler.controller.getBots().length} seconds.`); commandHandler.controller.getBots().forEach((e, i) => { // Check if this bot account is limited @@ -72,8 +72,8 @@ module.exports.addFriend = { if (e.user.myFriends[res] != 3 && e.user.myFriends[res] != 1) { // Check if provided user is not friend and not blocked setTimeout(() => { e.user.addFriend(new SteamID(res), (err) => { - if (err) logger("error", `Error adding ${res} with bot${e.index}: ${err}`); - else logger("info", `Added ${res} with bot${e.index} as friend.`); + if (err) logger("error", `Error adding '${res}' with bot${e.index}: ${err}`); + else logger("info", `Added '${res}' with bot${e.index} as friend.`); }); commandHandler.controller.friendListCapacityCheck(e, (remaining) => { // Check remaining friendlist space @@ -123,7 +123,7 @@ module.exports.unfriend = { // Unfriend message sender with all bot accounts if no id was provided and the command was called from the steam chat if (!args[0] && resInfo.userID && resInfo.fromSteamChat) { respond(commandHandler.data.getLang("unfriendcmdsuccess", null, requesterID)); - logger("info", `Removing friend ${resInfo.userID} from all bot accounts...`); + logger("info", `Removing friend '${resInfo.userID}' from all bot accounts...`); commandHandler.controller.getBots().forEach((e, i) => { setTimeout(() => { @@ -151,7 +151,7 @@ module.exports.unfriend = { }); respond(await commandHandler.data.getLang("unfriendidcmdsuccess", { "profileid": res }, requesterID)); - logger("info", `Removed friend ${res} from all bot accounts.`); + logger("info", `Removed friend '${res}' from all bot accounts.`); }); } } @@ -204,19 +204,21 @@ module.exports.unfriendall = { for (let i = 0; i < commandHandler.controller.getBots().length; i++) { for (const friend in commandHandler.controller.getBots()[i].user.myFriends) { + const thisBot = commandHandler.controller.getBots()[i]; + try { setTimeout(() => { const friendSteamID = new SteamID(String(friend)); if (!commandHandler.data.cachefile.ownerid.includes(friend)) { // Check for the "original" ownerid array here, we don't care about non Steam IDs - logger("info", `Removing friend ${friendSteamID.getSteamID64()} from all bot accounts...`, false, false, logger.animation("loading")); - commandHandler.controller.getBots()[i].user.removeFriend(friendSteamID); + logger("info", `Removing friend '${friendSteamID.getSteamID64()}' from all bot accounts...`, false, false, logger.animation("loading")); + thisBot.user.removeFriend(friendSteamID); } else { logger("debug", `unfriendAll(): Friend ${friendSteamID.getSteamID64()} seems to be an owner, skipping...`); } }, 1000 * i); // Delay every iteration so that we don't make a ton of requests at once } catch (err) { - logger("error", `[Bot ${i}] unfriendall error unfriending ${friend}: ${err}`); + logger("error", `[${thisBot.logPrefix}] unfriendall error unfriending ${friend}: ${err}`); } } } diff --git a/src/commands/core/group.js b/src/commands/core/group.js index 63bd6223..9939e6ff 100644 --- a/src/commands/core/group.js +++ b/src/commands/core/group.js @@ -4,10 +4,10 @@ * Created Date: 2021-07-09 16:26:00 * Author: 3urobeat * - * Last Modified: 2023-12-27 14:07:07 + * Last Modified: 2024-05-08 20:40:33 * Modified By: 3urobeat * - * Copyright (c) 2021 - 2023 3urobeat + * Copyright (c) 2021 - 2024 3urobeat * * This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. @@ -193,14 +193,16 @@ module.exports.leaveAllGroups = { for (let i = 0; i < commandHandler.controller.getBots().length; i++) { for (const group in commandHandler.controller.getBots()[i].user.myGroups) { + const thisBot = commandHandler.controller.getBots()[i]; + try { setTimeout(() => { - if (commandHandler.controller.getBots()[i].user.myGroups[group] == 3) { + if (thisBot.user.myGroups[group] == 3) { if (group != commandHandler.data.cachefile.botsgroupid && group != commandHandler.data.cachefile.configgroup64id) commandHandler.controller.getBots()[i].community.leaveGroup(String(group)); } }, 1000 * i); // Delay every iteration so that we don't make a ton of requests at once } catch (err) { - logger("error", `[Bot ${i}] leaveallgroups error leaving ${group}: ${err}`); + logger("error", `[${thisBot.logPrefix}] leaveallgroups error leaving ${group}: ${err}`); } } } diff --git a/src/controller/helpers/friendlist.js b/src/controller/helpers/friendlist.js index 15fc4429..74a18642 100644 --- a/src/controller/helpers/friendlist.js +++ b/src/controller/helpers/friendlist.js @@ -4,10 +4,10 @@ * Created Date: 2021-07-09 16:26:00 * Author: 3urobeat * - * Last Modified: 2023-12-27 14:09:33 + * Last Modified: 2024-05-08 20:36:46 * Modified By: 3urobeat * - * Copyright (c) 2021 - 2023 3urobeat + * Copyright (c) 2021 - 2024 3urobeat * * This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. @@ -91,12 +91,12 @@ Controller.prototype.friendListCapacityCheck = function(bot, callback) { bot.sendChatMessage(bot, { userID: steamID.getSteamID64() }, await this.data.getLang("userunfriend", { "forceFriendlistSpaceTime": this.data.advancedconfig.forceFriendlistSpaceTime }, steamID.getSteamID64())); bot.user.removeFriend(steamID); - logger("info", `[Bot ${bot.index}] Force-Unfriended ${e.id} after being inactive for ${this.data.advancedconfig.forceFriendlistSpaceTime} days to keep 1 empty slot on the friendlist`); + logger("info", `[${bot.logPrefix}] Force-Unfriended '${e.id}' after being inactive for ${this.data.advancedconfig.forceFriendlistSpaceTime} days to keep 1 empty slot on the friendlist`); return false; // Stop loop as one friend slot should now be free } // Log warning if we are on the last iteration as when this code is executed no candidate was found - if (i + 1 == docs.length) logger("warn", `[Bot ${bot.index}] No user was found to unfriend in order to keep at least one friendlist slot empty! Consider lowering 'forceFriendlistSpaceTime' in advancedconfig.json`); + if (i + 1 == docs.length) logger("warn", `[${bot.logPrefix}] No user was found to unfriend in order to keep at least one friendlist slot empty! Consider lowering 'forceFriendlistSpaceTime' in advancedconfig.json`); return true; // Keep loop running }); @@ -131,15 +131,15 @@ Controller.prototype._lastcommentUnfriendCheck = function() { docs.forEach((e, i) => { // Take action for all results setTimeout(() => { - this.getBots().forEach(async (f, j) => { - const thisbot = f.user; + this.getBots().forEach(async (thisBot, j) => { + const thisUser = thisBot.user; - if (thisbot.myFriends[e.id] && thisbot.myFriends[e.id] == 3 && !this.data.cachefile.ownerid.includes(e.id)) { // Check if the targeted user is still friend and not an owner + if (thisUser.myFriends[e.id] && thisUser.myFriends[e.id] == 3 && !this.data.cachefile.ownerid.includes(e.id)) { // Check if the targeted user is still friend and not an owner if (j == 0) this.main.sendChatMessage(this.main, { userID: e.id }, await this.data.getLang("userforceunfriend", { "unfriendtime": this.data.config.unfriendtime }, e.id)); setTimeout(() => { - thisbot.removeFriend(new SteamID(e.id)); // Unfriend user with each bot - logger("info", `[Bot ${j}] Unfriended ${e.id} after ${this.data.config.unfriendtime} days of inactivity.`); + thisUser.removeFriend(new SteamID(e.id)); // Unfriend user with each bot + logger("info", `[${thisBot.logPrefix}] Unfriended '${e.id}' after ${this.data.config.unfriendtime} days of inactivity.`); }, 1000 * j); // Delay every iteration so that we don't make a ton of requests at once (IP) } diff --git a/src/data/fileStructure.json b/src/data/fileStructure.json index 5e88f96c..1fe89057 100644 --- a/src/data/fileStructure.json +++ b/src/data/fileStructure.json @@ -388,7 +388,7 @@ { "path": "src/commands/core/block.js", "url": "https://raw.githubusercontent.com/3urobeat/steam-comment-service-bot/beta-testing/src/commands/core/block.js", - "checksum": "02d2da4f42f8f267660e9beb46885251" + "checksum": "cae3d0d707509089dba88c42e19844ca" }, { "path": "src/commands/core/comment.js", @@ -408,7 +408,7 @@ { "path": "src/commands/core/friend.js", "url": "https://raw.githubusercontent.com/3urobeat/steam-comment-service-bot/beta-testing/src/commands/core/friend.js", - "checksum": "011a6386096ab3260049b00cf045abab" + "checksum": "c57ca2eaabfb88383d37ea6d3506dd4f" }, { "path": "src/commands/core/general.js", @@ -418,7 +418,7 @@ { "path": "src/commands/core/group.js", "url": "https://raw.githubusercontent.com/3urobeat/steam-comment-service-bot/beta-testing/src/commands/core/group.js", - "checksum": "4867499cb856539c981bc241d3b070d6" + "checksum": "dc04c054f927211c18a61913c06d5c15" }, { "path": "src/commands/core/requests.js", @@ -518,7 +518,7 @@ { "path": "src/controller/helpers/friendlist.js", "url": "https://raw.githubusercontent.com/3urobeat/steam-comment-service-bot/beta-testing/src/controller/helpers/friendlist.js", - "checksum": "0e116bb6b2e761d1fc802ceb8a300082" + "checksum": "0753c10e9b2e55388014a005b8a21eed" }, { "path": "src/controller/helpers/getBots.js", From 860749a4469db6935ee903d05735c5a3dfe3d7ad Mon Sep 17 00:00:00 2001 From: 3urobeat <35304405+3urobeat@users.noreply.github.com> Date: Wed, 8 May 2024 21:19:27 +0200 Subject: [PATCH 22/28] refactor: Simplify unfriendall cmd and use logPrefix more consistently --- src/commands/core/friend.js | 18 ++++++++---------- src/data/fileStructure.json | 2 +- 2 files changed, 9 insertions(+), 11 deletions(-) diff --git a/src/commands/core/friend.js b/src/commands/core/friend.js index 97073f1f..0bb2be64 100644 --- a/src/commands/core/friend.js +++ b/src/commands/core/friend.js @@ -4,7 +4,7 @@ * Created Date: 2021-07-09 16:26:00 * Author: 3urobeat * - * Last Modified: 2024-05-08 20:49:09 + * Last Modified: 2024-05-08 21:10:22 * Modified By: 3urobeat * * Copyright (c) 2021 - 2024 3urobeat @@ -65,15 +65,15 @@ module.exports.addFriend = { commandHandler.controller.getBots().forEach((e, i) => { // Check if this bot account is limited if (e.user.limitations && e.user.limitations.limited == true) { - logger("error", `Can't add friend ${res} with bot${e.index} because the bot account is limited.`); + logger("error", `[${e.logPrefix}] Can't add user '${res}' as a friend because the bot account is limited.`); return; } if (e.user.myFriends[res] != 3 && e.user.myFriends[res] != 1) { // Check if provided user is not friend and not blocked setTimeout(() => { e.user.addFriend(new SteamID(res), (err) => { - if (err) logger("error", `Error adding '${res}' with bot${e.index}: ${err}`); - else logger("info", `Added '${res}' with bot${e.index} as friend.`); + if (err) logger("error", `[${e.logPrefix}] Failed to add '${res}' as a friend: ${err}`); + else logger("info", `[${e.logPrefix}] Added '${res}' as a friend.`); }); commandHandler.controller.friendListCapacityCheck(e, (remaining) => { // Check remaining friendlist space @@ -81,7 +81,7 @@ module.exports.addFriend = { }); }, 5000 * i); } else { - logger("warn", `bot${e.index} is already friend with ${res} or the account was blocked/blocked you.`); // Somehow logs steamIDs in separate row?! + logger("warn", `[${e.logPrefix}] This bot account is already friend with '${res}' or the account was blocked/blocked you.`); } }); }); @@ -202,10 +202,8 @@ module.exports.unfriendall = { respondModule(context, { prefix: "/me", ...resInfo }, await commandHandler.data.getLang("unfriendallcmdstart", null, requesterID)); // Pass new resInfo object which contains prefix and everything the original resInfo obj contained logger("info", "Starting to unfriend everyone..."); - for (let i = 0; i < commandHandler.controller.getBots().length; i++) { - for (const friend in commandHandler.controller.getBots()[i].user.myFriends) { - const thisBot = commandHandler.controller.getBots()[i]; - + commandHandler.controller.getBots().forEach((thisBot, i) => { + for (const friend in thisBot.user.myFriends) { try { setTimeout(() => { const friendSteamID = new SteamID(String(friend)); @@ -221,7 +219,7 @@ module.exports.unfriendall = { logger("error", `[${thisBot.logPrefix}] unfriendall error unfriending ${friend}: ${err}`); } } - } + }); }, 30000); } }; diff --git a/src/data/fileStructure.json b/src/data/fileStructure.json index 1fe89057..b21ba35f 100644 --- a/src/data/fileStructure.json +++ b/src/data/fileStructure.json @@ -408,7 +408,7 @@ { "path": "src/commands/core/friend.js", "url": "https://raw.githubusercontent.com/3urobeat/steam-comment-service-bot/beta-testing/src/commands/core/friend.js", - "checksum": "c57ca2eaabfb88383d37ea6d3506dd4f" + "checksum": "3e5b234b7b2e1b6fbcff64e06ba64fbe" }, { "path": "src/commands/core/general.js", From a67fe4347728016dee578913ff8fc8e73a1bf339 Mon Sep 17 00:00:00 2001 From: 3urobeat <35304405+3urobeat@users.noreply.github.com> Date: Wed, 8 May 2024 21:29:43 +0200 Subject: [PATCH 23/28] fix: Fix wrong syntax of lang str variable --- src/data/fileStructure.json | 6 +++--- src/data/lang/english.json | 2 +- src/data/lang/portuguese.json | 2 +- src/data/lang/russian.json | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/data/fileStructure.json b/src/data/fileStructure.json index b21ba35f..5e4a509b 100644 --- a/src/data/fileStructure.json +++ b/src/data/fileStructure.json @@ -568,17 +568,17 @@ { "path": "src/data/lang/english.json", "url": "https://raw.githubusercontent.com/3urobeat/steam-comment-service-bot/beta-testing/src/data/lang/english.json", - "checksum": "05de5a7d2da79c40834733f124427980" + "checksum": "a6f26ae844583175e729ced992b433ce" }, { "path": "src/data/lang/portuguese.json", "url": "https://raw.githubusercontent.com/3urobeat/steam-comment-service-bot/beta-testing/src/data/lang/portuguese.json", - "checksum": "1afec7300ee8f6fd729422e55994405f" + "checksum": "0a83249bb51bfb36b1c2e4ed4887fe37" }, { "path": "src/data/lang/russian.json", "url": "https://raw.githubusercontent.com/3urobeat/steam-comment-service-bot/beta-testing/src/data/lang/russian.json", - "checksum": "9f93de745e5596791a2bdef226ee1b6b" + "checksum": "acca87a864e611aaaa6733e0964ce4fc" }, { "path": "src/data/lang/traditional-chinese.json", diff --git a/src/data/lang/english.json b/src/data/lang/english.json index aeca56f2..0df12632 100644 --- a/src/data/lang/english.json +++ b/src/data/lang/english.json @@ -122,7 +122,7 @@ "mysessionscmdnosessions": "There are currently no active sessions that you have started.", "addfriendcmdacclimited": "Can't add friend ${profileid} with bot0 because the bot account is limited.", - "addfriendcmdsuccess": "Adding friend ${profileid} with all bot accounts... This will take ~estimatedtime seconds. Please check the log for potential errors.", + "addfriendcmdsuccess": "Adding friend ${profileid} with all bot accounts... This will take ~${estimatedtime} seconds. Please check the log for potential errors.", "unfriendcmdsuccess": "I am unfriending you with all bot accounts. This will take a moment...\nYou can send me a friend request again at any time.", "unfriendidcmdsuccess": "Removed friend ${profileid} from all bot accounts.", diff --git a/src/data/lang/portuguese.json b/src/data/lang/portuguese.json index df94a389..63d5ce12 100644 --- a/src/data/lang/portuguese.json +++ b/src/data/lang/portuguese.json @@ -122,7 +122,7 @@ "mysessionscmdnosessions": "Atualmente não há sessões ativas que você iniciou.", "addfriendcmdacclimited": "Não é possível adicionar o amigo ${profileid} com o bot0 porque a conta do bot está limitada.", - "addfriendcmdsuccess": "Adicionando amigo ${profileid} com todas as contas de bot... Isso levará aproximadamente ~estimatedtime segundos. Por favor, verifique o log para possíveis erros.", + "addfriendcmdsuccess": "Adicionando amigo ${profileid} com todas as contas de bot... Isso levará aproximadamente ~${estimatedtime} segundos. Por favor, verifique o log para possíveis erros.", "unfriendcmdsuccess": "Estou cancelando a amizade com você em todas as contas de bot. Isso levará um momento...\nVocê pode me enviar um pedido de amizade novamente a qualquer momento.", "unfriendidcmdsuccess": "Removido o amigo ${profileid} de todas as contas de bot.", diff --git a/src/data/lang/russian.json b/src/data/lang/russian.json index c9ddee79..8956620a 100644 --- a/src/data/lang/russian.json +++ b/src/data/lang/russian.json @@ -122,7 +122,7 @@ "mysessionscmdnosessions": "В настоящее время нет активных сессий, которые вы начали.", "addfriendcmdacclimited": "Невозможно добавить ${profileid} в друзья с помощью bot0, потому что аккаунт бота ограничен.", - "addfriendcmdsuccess": "Добавление ${profileid} в друзья ко всем аккаунтам ботов... Это займёт ~estimatedtime сек. Пожалуйста, проверьте журнал на наличие возможных ошибок.", + "addfriendcmdsuccess": "Добавление ${profileid} в друзья ко всем аккаунтам ботов... Это займёт ~${estimatedtime} сек. Пожалуйста, проверьте журнал на наличие возможных ошибок.", "unfriendcmdsuccess": "Я удаляю вас из друзей со всех аккаунтов ботов. Это займёт некоторое время...\nВы можете отправить мне запрос в друзья в любое время.", "unfriendidcmdsuccess": "Удалён ${profileid} из друзей из всех аккаунтов ботов.", From 2bb7a1979135cc0c432c84ea51d1e078e9fc59e7 Mon Sep 17 00:00:00 2001 From: 3urobeat <35304405+3urobeat@users.noreply.github.com> Date: Wed, 8 May 2024 21:34:41 +0200 Subject: [PATCH 24/28] fix: Fix userunfriend & userforceunfriend lang strings being flipped internally --- src/controller/helpers/friendlist.js | 6 +++--- src/data/fileStructure.json | 12 ++++++------ src/data/lang/chinese.json | 4 ++-- src/data/lang/english.json | 4 ++-- src/data/lang/portuguese.json | 4 ++-- src/data/lang/russian.json | 4 ++-- src/data/lang/traditional-chinese.json | 6 +++--- 7 files changed, 20 insertions(+), 20 deletions(-) diff --git a/src/controller/helpers/friendlist.js b/src/controller/helpers/friendlist.js index 74a18642..2388b4c6 100644 --- a/src/controller/helpers/friendlist.js +++ b/src/controller/helpers/friendlist.js @@ -4,7 +4,7 @@ * Created Date: 2021-07-09 16:26:00 * Author: 3urobeat * - * Last Modified: 2024-05-08 20:36:46 + * Last Modified: 2024-05-08 21:33:43 * Modified By: 3urobeat * * Copyright (c) 2021 - 2024 3urobeat @@ -88,7 +88,7 @@ Controller.prototype.friendListCapacityCheck = function(bot, callback) { const steamID = new SteamID(e.id); // Unfriend user and send them a message // TODO: Maybe only do this from the main bot? - bot.sendChatMessage(bot, { userID: steamID.getSteamID64() }, await this.data.getLang("userunfriend", { "forceFriendlistSpaceTime": this.data.advancedconfig.forceFriendlistSpaceTime }, steamID.getSteamID64())); + bot.sendChatMessage(bot, { userID: steamID.getSteamID64() }, await this.data.getLang("userforceunfriend", { "forceFriendlistSpaceTime": this.data.advancedconfig.forceFriendlistSpaceTime }, steamID.getSteamID64())); bot.user.removeFriend(steamID); logger("info", `[${bot.logPrefix}] Force-Unfriended '${e.id}' after being inactive for ${this.data.advancedconfig.forceFriendlistSpaceTime} days to keep 1 empty slot on the friendlist`); @@ -135,7 +135,7 @@ Controller.prototype._lastcommentUnfriendCheck = function() { const thisUser = thisBot.user; if (thisUser.myFriends[e.id] && thisUser.myFriends[e.id] == 3 && !this.data.cachefile.ownerid.includes(e.id)) { // Check if the targeted user is still friend and not an owner - if (j == 0) this.main.sendChatMessage(this.main, { userID: e.id }, await this.data.getLang("userforceunfriend", { "unfriendtime": this.data.config.unfriendtime }, e.id)); + if (j == 0) this.main.sendChatMessage(this.main, { userID: e.id }, await this.data.getLang("userunfriend", { "unfriendtime": this.data.config.unfriendtime }, e.id)); setTimeout(() => { thisUser.removeFriend(new SteamID(e.id)); // Unfriend user with each bot diff --git a/src/data/fileStructure.json b/src/data/fileStructure.json index 5e4a509b..fb56d0b7 100644 --- a/src/data/fileStructure.json +++ b/src/data/fileStructure.json @@ -518,7 +518,7 @@ { "path": "src/controller/helpers/friendlist.js", "url": "https://raw.githubusercontent.com/3urobeat/steam-comment-service-bot/beta-testing/src/controller/helpers/friendlist.js", - "checksum": "0753c10e9b2e55388014a005b8a21eed" + "checksum": "b2440b26ecd6ebba5cc54ac823e35c14" }, { "path": "src/controller/helpers/getBots.js", @@ -563,27 +563,27 @@ { "path": "src/data/lang/chinese.json", "url": "https://raw.githubusercontent.com/3urobeat/steam-comment-service-bot/beta-testing/src/data/lang/chinese.json", - "checksum": "b6b4d96c7eb14d097904163336dc3da2" + "checksum": "4cd2509c0e0125fa2166901c03ae960b" }, { "path": "src/data/lang/english.json", "url": "https://raw.githubusercontent.com/3urobeat/steam-comment-service-bot/beta-testing/src/data/lang/english.json", - "checksum": "a6f26ae844583175e729ced992b433ce" + "checksum": "6d888d188a93c91d6226fa75f576503a" }, { "path": "src/data/lang/portuguese.json", "url": "https://raw.githubusercontent.com/3urobeat/steam-comment-service-bot/beta-testing/src/data/lang/portuguese.json", - "checksum": "0a83249bb51bfb36b1c2e4ed4887fe37" + "checksum": "2049d7f916c4cdd8687b6d014aa940b5" }, { "path": "src/data/lang/russian.json", "url": "https://raw.githubusercontent.com/3urobeat/steam-comment-service-bot/beta-testing/src/data/lang/russian.json", - "checksum": "acca87a864e611aaaa6733e0964ce4fc" + "checksum": "63fa3da42a0e915a1f0e5c1ee60a0358" }, { "path": "src/data/lang/traditional-chinese.json", "url": "https://raw.githubusercontent.com/3urobeat/steam-comment-service-bot/beta-testing/src/data/lang/traditional-chinese.json", - "checksum": "77dac08416877be42feade0473810c13" + "checksum": "ff9dab1c2b225c5f6b360aae9a9f91ac" }, { "path": "src/dataManager/dataCheck.js", diff --git a/src/data/lang/chinese.json b/src/data/lang/chinese.json index 5c814071..33bd8339 100644 --- a/src/data/lang/chinese.json +++ b/src/data/lang/chinese.json @@ -42,8 +42,8 @@ "followsuccess": "所有未追随/已追随的操作已发送。失败: ${failedamount}/${totalamount}", "useradded": "你好!感谢添加我!\n使用 '${cmdprefix}comment' 请求一条免费评论\n输入 '${cmdprefix}help' 了解更多命令,或 '${cmdprefix}about' 了解更多信息!\n你可以使用'${cmdprefix}lang'命令在${langcount}语言之间切换。", - "userunfriend": "由于朋友列表空间不足,您已在 ${forceFriendlistSpaceTime} 天内因不活跃而被解除好友关系。\n如果您需要我,请随时再次添加我!", - "userforceunfriend": "由于 ${unfriendtime} 天不活跃,您已被解除好友关系。\n如果您需要我,请随时再次添加我!", + "userforceunfriend": "由于朋友列表空间不足,您已在 ${forceFriendlistSpaceTime} 天内因不活跃而被解除好友关系。\n如果您需要我,请随时再次添加我!", + "userunfriend": "由于 ${unfriendtime} 天不活跃,您已被解除好友关系。\n如果您需要我,请随时再次添加我!", "userspamblock": "由于垃圾信息,您已被封锁 90 秒。", "usernotfriend": "请在使用命令之前先添加我为好友!", diff --git a/src/data/lang/english.json b/src/data/lang/english.json index 0df12632..0c7df061 100644 --- a/src/data/lang/english.json +++ b/src/data/lang/english.json @@ -42,8 +42,8 @@ "followsuccess": "All un-/follows have been sent. Failed: ${failedamount}/${totalamount}", "useradded": "Hey! Thanks for adding me!\nRequest a free comment with '${cmdprefix}comment'\nType '${cmdprefix}help' for more commands or '${cmdprefix}about' for more information.\nYou can use the '${cmdprefix}lang' command to switch between ${langcount} languages.", - "userunfriend": "You have been unfriended for being inactive for ${forceFriendlistSpaceTime} days as the friendlist was running low on space.\nIf you need me again, feel free to add me again!", - "userforceunfriend": "You have been unfriended for being inactive for ${unfriendtime} days.\nIf you need me again, feel free to add me again!", + "userforceunfriend": "You have been unfriended for being inactive for ${forceFriendlistSpaceTime} days as the friendlist was running low on space.\nIf you need me again, feel free to add me again!", + "userunfriend": "You have been unfriended for being inactive for ${unfriendtime} days.\nIf you need me again, feel free to add me again!", "userspamblock": "You have been blocked for 90 seconds for spamming.", "usernotfriend": "Please add me before using a command!", diff --git a/src/data/lang/portuguese.json b/src/data/lang/portuguese.json index 63d5ce12..bcb35295 100644 --- a/src/data/lang/portuguese.json +++ b/src/data/lang/portuguese.json @@ -42,8 +42,8 @@ "followsuccess": "Todos os seguir/deixar de seguir foram enviados. Falhou: ${failedamount}/${totalamount}", "useradded": "Olá! Obrigado por me adicionar!\nSolicite um comentário gratuito com '${cmdprefix}comment'\nDigite '${cmdprefix}help' para mais comandos ou '${cmdprefix}about' para mais informações!\nYou can use the '${cmdprefix}lang' command to switch between ${langcount} languages.", - "userunfriend": "Você foi desfeito como amigo por estar inativo por ${forceFriendlistSpaceTime} dias, pois a lista de amigos estava ficando cheia.\nSe precisar de mim novamente, sinta-se à vontade para me adicionar novamente!", - "userforceunfriend": "Você foi desfeito como amigo por estar inativo por ${unfriendtime} dias.\nSe precisar de mim novamente, sinta-se à vontade para me adicionar novamente!", + "userforceunfriend": "Você foi desfeito como amigo por estar inativo por ${forceFriendlistSpaceTime} dias, pois a lista de amigos estava ficando cheia.\nSe precisar de mim novamente, sinta-se à vontade para me adicionar novamente!", + "userunfriend": "Você foi desfeito como amigo por estar inativo por ${unfriendtime} dias.\nSe precisar de mim novamente, sinta-se à vontade para me adicionar novamente!", "userspamblock": "Você foi bloqueado por 90 segundos por fazer spam.", "usernotfriend": "Por favor, me adicione antes de usar um comando!", diff --git a/src/data/lang/russian.json b/src/data/lang/russian.json index 8956620a..c487e03d 100644 --- a/src/data/lang/russian.json +++ b/src/data/lang/russian.json @@ -42,8 +42,8 @@ "followsuccess": "Все подписки/отписки были отправлены. Не удалось: ${failedamount}/${totalamount}", "useradded": "Здравствуйте! Спасибо, что добавили меня!\nЗапросите бесплатный комментарий с помощью '${cmdprefix}comment'\nВведите '${cmdprefix}help' для получения дополнительных команд или '${cmdprefix}about' для получения дополнительной информации!\nМожете использовать команду '${cmdprefix}lang' чтобы переключаться между ${langcount} языками.", - "userunfriend": "Вы были удалены из друзей за неактивность в течение ${forceFriendlistSpaceTime} дн., так как в списке друзей было мало места.\nЕсли я вам снова понадоблюсь, добавляйте меня снова!", - "userforceunfriend": "Вы были удалены из друзей за неактивность в течение ${unfriendtime} дн.\nЕсли я вам снова понадоблюсь, не стесняйтесь добавить меня снова!", + "userforceunfriend": "Вы были удалены из друзей за неактивность в течение ${forceFriendlistSpaceTime} дн., так как в списке друзей было мало места.\nЕсли я вам снова понадоблюсь, добавляйте меня снова!", + "userunfriend": "Вы были удалены из друзей за неактивность в течение ${unfriendtime} дн.\nЕсли я вам снова понадоблюсь, не стесняйтесь добавить меня снова!", "userspamblock": "Вы были заблокированы на 90 секунд за спам.", "usernotfriend": "Пожалуйста, добавьте меня, прежде чем использовать команду!", diff --git a/src/data/lang/traditional-chinese.json b/src/data/lang/traditional-chinese.json index 420ecb13..9fa1e9cf 100644 --- a/src/data/lang/traditional-chinese.json +++ b/src/data/lang/traditional-chinese.json @@ -25,7 +25,7 @@ "commentretrying": "${failedamount}/${numberOfComments}條評論失敗。開始重試 ${untilStr}. (Attempt ${thisattempt}/${maxattempt})", "commentsuccess": "全部評論已發送。 無法傳送數量: ${failedamount}/${numberOfComments}\n如果你覺得這個還不錯的話,在我的留言區底下留下好評,讓更多人知道!", "genericnoaccounts": "對不起,你輸入無效的ID了。", - + "genericnounlimitedaccs": "對不起,目前帳號沒貨。請聯繫開發者\n${cmdprefix}owner", "genericrequestless": "目前只有${availablenow}個可以使用。", "genericnotenoughavailableaccs": "對不起,目前沒有足夠的帳號可用於提供的ID資料。請等待 ${waittime} and try again or only request ${availablenow} now.", @@ -41,8 +41,8 @@ "followsuccess": "未追蹤已追蹤已發送成功。無法傳送數量: ${failedamount}/${totalamount}", "useradded": "你好哇^w^ 謝謝你添加我為你的好友\n我是一個免費服務有: '${cmdprefix}comment' - 評論\n'${cmdprefix}help' - 菜單\n'${cmdprefix}about' - 關於\n'${cmdprefix}lang' - 切換語言", - "userunfriend": "由於使用者太多,你${forceFriendlistSpaceTime}天沒使用我\n如果還有需要繼續使用請添加。", - "userforceunfriend": "你${unfriendtime}天沒使用我\n如果還有需要繼續使用請添加。", + "userforceunfriend": "由於使用者太多,你${forceFriendlistSpaceTime}天沒使用我\n如果還有需要繼續使用請添加。", + "userunfriend": "你${unfriendtime}天沒使用我\n如果還有需要繼續使用請添加。", "userspamblock": "已封鎖90秒\n原因 : 刷屏", "usernotfriend": "請在使用我之前添加好友。", From 5151c7a8145b093715f232e9bdd48b9878cd0d09 Mon Sep 17 00:00:00 2001 From: 3urobeat <35304405+3urobeat@users.noreply.github.com> Date: Thu, 9 May 2024 14:12:45 +0200 Subject: [PATCH 25/28] feat(Bot): Provide setting to en-/disable relog on LogOnSessionReplaced error --- advancedconfig.json | 1 + docs/wiki/advancedconfig_doc.md | 1 + src/bot/events/error.js | 22 +++++++--------------- src/data/fileStructure.json | 4 ++-- 4 files changed, 11 insertions(+), 17 deletions(-) diff --git a/advancedconfig.json b/advancedconfig.json index b011cc06..e5abee25 100644 --- a/advancedconfig.json +++ b/advancedconfig.json @@ -10,6 +10,7 @@ "relogTimeout": 900000, "maxLogOnRetries": 1, "useLocalIP": true, + "enableRelogOnLogOnSessionReplaced": true, "dummy1": "------------------- General Settings: -------------------", "acceptFriendRequests": true, "forceFriendlistSpaceTime": 4, diff --git a/docs/wiki/advancedconfig_doc.md b/docs/wiki/advancedconfig_doc.md index d4eab5af..d1696816 100644 --- a/docs/wiki/advancedconfig_doc.md +++ b/docs/wiki/advancedconfig_doc.md @@ -22,6 +22,7 @@ This is the full documentation to customize your `advancedconfig.json`. | relogTimeout | Number in ms | Time the bot will wait after failing all reconnect attempts before trying again. Default: 900000 (15 minutes) | | maxLogOnRetries | Number | Amount of times the bot will retry logging in to an account if the first try fails. Default: 1 | | useLocalIP | true or false | If the bot should use your real IP as well when using proxies. Default: true | +| enableRelogOnLogOnSessionReplaced | true or false | If the bot should relog accounts when they loose connection with the error message 'LogOnSessionReplaced'. This error is usually caused when someone logs into an account from somewhere else. Default: true | |   | | | | acceptFriendRequests | true or false | If the bot should accept friend requests. Default: true | | forceFriendlistSpaceTime | Number in days | Amount of days a user hasn't requested something to get unfriended if only one friend slot is left. Set to 0 to disable. Default: 4 | diff --git a/src/bot/events/error.js b/src/bot/events/error.js index e880e634..975a9934 100644 --- a/src/bot/events/error.js +++ b/src/bot/events/error.js @@ -4,7 +4,7 @@ * Created Date: 2021-07-09 16:26:00 * Author: 3urobeat * - * Last Modified: 2024-03-08 17:44:50 + * Last Modified: 2024-05-09 14:05:33 * Modified By: 3urobeat * * Copyright (c) 2021 - 2024 3urobeat @@ -28,22 +28,14 @@ Bot.prototype._attachSteamErrorEvent = function() { // Handle errors that were caused during logOn this.user.on("error", (err) => { - // Custom behavior for LogonSessionReplaced error - if (err.eresult == EResult.LogonSessionReplaced) { - logger("", "", true); - logger("warn", `${logger.colors.fgred}[${this.logPrefix}] Lost connection to Steam! Reason: 'Error: LogonSessionReplaced'. I won't try to relog this account because someone else is using it now.`, false, false, null, true); // Force print this message now + // Do not relog on LogOnSessionReplaced if feature is disabled in advancedconfig + if (err.eresult == EResult.LogonSessionReplaced && !this.data.advancedconfig.enableRelogOnLogOnSessionReplaced) { + logger("warn", `${logger.colors.fgred}[${this.logPrefix}] Lost connection to Steam! Reason: 'Error: LogonSessionReplaced'. I won't try to relog this account because 'enableRelogOnLogOnSessionReplaced' is disabled in 'advancedconfig.json'.`, false, false, null, true); // Force print this message now - // Abort or skip account. No need to attach handleRelog() here - if (this.index == 0) { - logger("error", `${logger.colors.fgred}Failed account is bot0! Aborting...`, true); - return this.controller.stop(); - } else { - this.controller.info.skippedaccounts.push(this.loginData.logOnOptions.accountName); - - // Set status to error so it won't be used for anything anymore - this.controller._statusUpdateEvent(this, Bot.EStatus.ERROR); - } + // Skip account and set status to ERROR so the account won't be used anymore + this.controller.info.skippedaccounts.push(this.loginData.logOnOptions.accountName); + this.controller._statusUpdateEvent(this, Bot.EStatus.ERROR); return; } diff --git a/src/data/fileStructure.json b/src/data/fileStructure.json index fb56d0b7..f2969a95 100644 --- a/src/data/fileStructure.json +++ b/src/data/fileStructure.json @@ -138,7 +138,7 @@ { "path": "docs/wiki/advancedconfig_doc.md", "url": "https://raw.githubusercontent.com/3urobeat/steam-comment-service-bot/beta-testing/docs/wiki/advancedconfig_doc.md", - "checksum": "bca398c7db36e3ad845cafcc31726f64" + "checksum": "6948c00ddb3c97dcb92e42ebf2174bdd" }, { "path": "docs/wiki/changelogs/CHANGELOG_v1.x.md", @@ -333,7 +333,7 @@ { "path": "src/bot/events/error.js", "url": "https://raw.githubusercontent.com/3urobeat/steam-comment-service-bot/beta-testing/src/bot/events/error.js", - "checksum": "d0ff306a25e58b9c910c77ffd994df08" + "checksum": "155830f0d23d9b15138b93c18ede2930" }, { "path": "src/bot/events/friendMessage.js", From 487385595bde3ad16de60dbe7f6267c05d407c15 Mon Sep 17 00:00:00 2001 From: 3urobeat <35304405+3urobeat@users.noreply.github.com> Date: Thu, 9 May 2024 15:13:30 +0200 Subject: [PATCH 26/28] chore: Misc --- src/bot/events/relationship.js | 4 ++-- src/controller/helpers/friendlist.js | 5 +++-- src/data/fileStructure.json | 4 ++-- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/src/bot/events/relationship.js b/src/bot/events/relationship.js index 4e34b94e..64ab3a05 100644 --- a/src/bot/events/relationship.js +++ b/src/bot/events/relationship.js @@ -4,7 +4,7 @@ * Created Date: 2021-07-09 16:26:00 * Author: 3urobeat * - * Last Modified: 2024-02-28 22:24:32 + * Last Modified: 2024-05-09 14:23:48 * Modified By: 3urobeat * * Copyright (c) 2021 - 2024 3urobeat @@ -47,7 +47,7 @@ Bot.prototype._attachSteamFriendRelationshipEvent = function() { // Add user to lastcomment database - const time = Date.now() - (this.controller.data.config.requestCooldown * 60000); // Subtract requestCooldown so that the user is able to use the command instantly; + const time = Date.now() - (this.controller.data.config.requestCooldown * 60000); // Subtract requestCooldown so that the user is able to use the comment command instantly; this.controller.data.lastCommentDB.update({ id: steamID64 }, { $set: { time: time } }, { upsert: true }, (err) => { if (err) logger("error", "Error inserting new user into lastcomment.db database! Error: " + err); diff --git a/src/controller/helpers/friendlist.js b/src/controller/helpers/friendlist.js index 2388b4c6..e2370e49 100644 --- a/src/controller/helpers/friendlist.js +++ b/src/controller/helpers/friendlist.js @@ -4,7 +4,7 @@ * Created Date: 2021-07-09 16:26:00 * Author: 3urobeat * - * Last Modified: 2024-05-08 21:33:43 + * Last Modified: 2024-05-09 15:04:39 * Modified By: 3urobeat * * Copyright (c) 2021 - 2024 3urobeat @@ -19,6 +19,7 @@ const SteamID = require("steamid"); const Controller = require("../../controller/controller.js"); const Bot = require("../../bot/bot.js"); // eslint-disable-line +const { EFriendRelationship } = require("steam-user"); /** @@ -134,7 +135,7 @@ Controller.prototype._lastcommentUnfriendCheck = function() { this.getBots().forEach(async (thisBot, j) => { const thisUser = thisBot.user; - if (thisUser.myFriends[e.id] && thisUser.myFriends[e.id] == 3 && !this.data.cachefile.ownerid.includes(e.id)) { // Check if the targeted user is still friend and not an owner + if (thisUser.myFriends[e.id] && thisUser.myFriends[e.id] == EFriendRelationship.Friend && !this.data.cachefile.ownerid.includes(e.id)) { // Check if the targeted user is still friend and not an owner if (j == 0) this.main.sendChatMessage(this.main, { userID: e.id }, await this.data.getLang("userunfriend", { "unfriendtime": this.data.config.unfriendtime }, e.id)); setTimeout(() => { diff --git a/src/data/fileStructure.json b/src/data/fileStructure.json index f2969a95..416c7de0 100644 --- a/src/data/fileStructure.json +++ b/src/data/fileStructure.json @@ -348,7 +348,7 @@ { "path": "src/bot/events/relationship.js", "url": "https://raw.githubusercontent.com/3urobeat/steam-comment-service-bot/beta-testing/src/bot/events/relationship.js", - "checksum": "9cf313aa7818ae27640a6ad0848da290" + "checksum": "a9eb97b258a58fc2d6ca274f16ea64bd" }, { "path": "src/bot/events/webSession.js", @@ -518,7 +518,7 @@ { "path": "src/controller/helpers/friendlist.js", "url": "https://raw.githubusercontent.com/3urobeat/steam-comment-service-bot/beta-testing/src/controller/helpers/friendlist.js", - "checksum": "b2440b26ecd6ebba5cc54ac823e35c14" + "checksum": "6ca8db673bf51a60a2be39e574451bfd" }, { "path": "src/controller/helpers/getBots.js", From 99cfc3add8911fe098511f1c00d531fd1480cd01 Mon Sep 17 00:00:00 2001 From: 3urobeat <35304405+3urobeat@users.noreply.github.com> Date: Thu, 9 May 2024 15:53:35 +0200 Subject: [PATCH 27/28] docs(wiki): Added changelog for v2.15.2 --- docs/wiki/changelogs/CHANGELOG_v2.15.md | 36 +++++++++++++++++++++++++ src/data/fileStructure.json | 2 +- 2 files changed, 37 insertions(+), 1 deletion(-) diff --git a/docs/wiki/changelogs/CHANGELOG_v2.15.md b/docs/wiki/changelogs/CHANGELOG_v2.15.md index 2044e6d7..e73ab4b5 100644 --- a/docs/wiki/changelogs/CHANGELOG_v2.15.md +++ b/docs/wiki/changelogs/CHANGELOG_v2.15.md @@ -6,6 +6,7 @@ **Current** - [2.15.0](#2.15.0) - [2.15.1](#2.15.1) +- [2.15.2](#2.15.2)   @@ -160,3 +161,38 @@ Commit: [be41d68](https://github.com/3urobeat/steam-comment-service-bot/commit/b - Minor other changes Commit: [a8a04eb](https://github.com/3urobeat/steam-comment-service-bot/commit/a8a04eb) + +  + + + +## **2024-05-09, Version 2.15.2** +**Additions:** +- Added traditional chinese translation [@Tira-tw](https://github.com/Tira-tw) in [#242](https://github.com/3urobeat/steam-comment-service-bot/pull/242) +- Added !add alias to !addfriend command +- Added steamGuardQrCode event to enable plugins to resolve Steam Guard QR-Code requests +- Added more login related log messages to default log level +- Added more login related debug log messages to improve ability to debug login process resolving issues +- Added (experimental) force-resolve feature to login process when inactivity is detected +- Added setting 'enableRelogOnLogOnSessionReplaced' to `advancedconfig.json` to control whether the bot should relog accounts that have lost their connection with the error 'LogOnSessionReplaced'. Default value is `true`. To retain the same behavior as previously, where the bot would skip those accounts, set the value to `false`. + +**Fixes:** +- Fixed login starting faster than plugin load, making it unable for them to handle steamGuardCode events +- Fixed proxy switcher not switching to proxy 0 +- Fixed default quotes file containing a political entry +- (Potentially) finally fixed 'Already logged on, cannot log on again' errors when relogging for good +- Fixed potential login softlock when account switches proxy while a login process is active, with that account queued in it +- Fixed wrong syntax of variable in language string 'addfriendcmdsuccess' +- Fixed 'userunfriend' & 'userforceunfriend' language strings being flipped internally + +**Changes:** +- The bot will now always emit the ready event on the second login rerun even if POSTPONED accounts still exist +- Refactored some code to use the proper log prefix more consistently instead of sometimes switching to bot index +- Refactored some code to surround userIDs more consistently with quotation marks +- Refactored some code to simplify the unfriendall command +- Improved contributing page +- Improved issue templates +- Migrated eslint config for eslint v9 and added & enforced two more rules +- Updated hostname check +- Updated dependencies +- Minor other changes diff --git a/src/data/fileStructure.json b/src/data/fileStructure.json index 416c7de0..0a269c23 100644 --- a/src/data/fileStructure.json +++ b/src/data/fileStructure.json @@ -183,7 +183,7 @@ { "path": "docs/wiki/changelogs/CHANGELOG_v2.15.md", "url": "https://raw.githubusercontent.com/3urobeat/steam-comment-service-bot/beta-testing/docs/wiki/changelogs/CHANGELOG_v2.15.md", - "checksum": "645bb579fb2ea90bdd3c91910f5e71de" + "checksum": "bec83acdff8fd756b2085609d44134bf" }, { "path": "docs/wiki/changelogs/CHANGELOG_v2.2.md", From 5e148f6ca2ed192c8e67b67df87b56bea609030f Mon Sep 17 00:00:00 2001 From: 3urobeat <35304405+3urobeat@users.noreply.github.com> Date: Thu, 9 May 2024 15:59:02 +0200 Subject: [PATCH 28/28] Version 2.15.2 --- package-lock.json | 4 ++-- package.json | 2 +- src/data/data.json | 10 +++++----- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/package-lock.json b/package-lock.json index b77f1913..a9cf7b94 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "steam-comment-service-bot", - "version": "2.15.1", + "version": "2.15.2", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "steam-comment-service-bot", - "version": "2.15.1", + "version": "2.15.2", "license": "GPL-3.0", "dependencies": { "@seald-io/nedb": "^4.0.4", diff --git a/package.json b/package.json index 03262a59..8431d453 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "steam-comment-service-bot", - "version": "2.15.1", + "version": "2.15.2", "description": "The most advanced Steam Multi Account Manager with built-in comment, like & favorite commands and extensive plugin support.", "main": "start.js", "dependencies": { diff --git a/src/data/data.json b/src/data/data.json index bdf58f1a..baa41146 100644 --- a/src/data/data.json +++ b/src/data/data.json @@ -1,14 +1,14 @@ { - "version": "21501", - "versionstr": "2.15.1", - "branch": "beta-testing", + "version": "21502", + "versionstr": "2.15.2", + "branch": "master", "filetostart": "./src/starter.js", - "filetostarturl": "https://raw.githubusercontent.com/3urobeat/steam-comment-service-bot/beta-testing/src/starter.js", + "filetostarturl": "https://raw.githubusercontent.com/3urobeat/steam-comment-service-bot/master/src/starter.js", "mestr": "3urobeat", "aboutstr": "This bot was created by 3urobeat.\nGitHub: https://github.com/3urobeat/steam-comment-service-bot \nSteam: https://steamcommunity.com/id/3urobeat \nIf you like my work, any donation would be appreciated! https://github.com/sponsors/3urobeat", "firststart": true, "compatibilityfeaturedone": false, - "whatsnew": "Fixed softlocked login process after proxy switch, fixed vote & fav error logging throwing an error and reduced amount of log messages logged during startup, login, disconnect & relog.", + "whatsnew": "Added traditional-chinese translation, added steamGuardQrCode event, fixed login starting faster than plugins could catch related events, fixed multiple login/relog bugs and made some more changes.", "timesloggedin": 0, "totallogintime": 0 }