gj-boomlings-api 2.0.3 → 2.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (51) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +5 -5
  3. package/functions/acceptFriendRequest.js +32 -0
  4. package/functions/blockUser.js +14 -22
  5. package/functions/deleteAccountPost.js +13 -16
  6. package/functions/deleteComment.js +11 -16
  7. package/functions/deleteFriendRequest.js +36 -0
  8. package/functions/deleteLevel.js +11 -17
  9. package/functions/deleteMessage.js +33 -0
  10. package/functions/{dlLevel.js → downloadLevel.js} +47 -43
  11. package/functions/{dlMessage.js → downloadMessage.js} +10 -13
  12. package/functions/getAccountPosts.js +4 -9
  13. package/functions/getBlockedList.js +32 -17
  14. package/functions/getCommentHistory.js +8 -7
  15. package/functions/getComments.js +12 -9
  16. package/functions/getCreatorScores.js +13 -5
  17. package/functions/getDailyLevel.js +3 -3
  18. package/functions/getFriendRequests.js +83 -0
  19. package/functions/getFriendsList.js +26 -16
  20. package/functions/getGauntlets.js +5 -3
  21. package/functions/getLevelByID.js +2 -3
  22. package/functions/getLevelScores.js +23 -26
  23. package/functions/getMapPacks.js +2 -6
  24. package/functions/getMessages.js +11 -15
  25. package/functions/getProfile.js +146 -57
  26. package/functions/getSongInfo.js +4 -9
  27. package/functions/getSongsLibrary.js +14 -3
  28. package/functions/getTab.js +3 -4
  29. package/functions/getTop100.js +3 -6
  30. package/functions/getTopLists.js +1 -2
  31. package/functions/getUserLevels.js +4 -8
  32. package/functions/getWeeklyDemon.js +3 -3
  33. package/functions/removeFriend.js +33 -0
  34. package/functions/reportLevel.js +3 -6
  35. package/functions/searchLevels.js +2 -3
  36. package/functions/searchLists.js +2 -3
  37. package/functions/unblockUser.js +17 -27
  38. package/functions/updateAccountSettings.js +75 -0
  39. package/functions/updateLevelDesc.js +11 -16
  40. package/functions/uploadAccountPost.js +11 -16
  41. package/functions/uploadComment.js +15 -19
  42. package/functions/uploadFriendRequest.js +35 -0
  43. package/functions/uploadMessage.js +18 -25
  44. package/index.js +30 -3
  45. package/misc/GJDecode.js +12 -9
  46. package/misc/gauntlets.json +14 -1
  47. package/misc/gjReq.js +33 -0
  48. package/misc/gjp2.js +5 -0
  49. package/package.json +2 -5
  50. package/gjReq.js +0 -18
  51. /package/{xor.js → misc/xor.js} +0 -0
package/LICENSE CHANGED
@@ -1,4 +1,4 @@
1
- Copyright 2025 shikoshib
1
+ Copyright 2026 shikoshib
2
2
 
3
3
  Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above copyright notice and this permission notice appear in all copies.
4
4
 
package/README.md CHANGED
@@ -7,7 +7,7 @@
7
7
  </div>
8
8
 
9
9
  # About
10
- **gj-boomlings-api** is a light-weight Node.js module that allows you to easily interact with Geometry Dash API.
10
+ **gj-boomlings-api** is a light-weight Node.js module that makes it easier to interact with Geometry Dash API.
11
11
  # Installation
12
12
  ## Node.js
13
13
  ```
@@ -18,7 +18,7 @@ yarn add gj-boomlings-api
18
18
  ## Download a level
19
19
  ```js
20
20
  const gd = require("gj-boomlings-api");
21
- gd.dlLevel("95540029").then(console.log);
21
+ gd.downloadLevel("117041578").then(console.log);
22
22
  ```
23
23
  ## View a profile
24
24
  ```js
@@ -37,9 +37,9 @@ gd.uploadAccountPost("I love gj-boomlings-api!", "shikoshib", "your password her
37
37
  ```
38
38
  ## Send a message
39
39
  ```js
40
- // This code sends a message from shikoshib to Mipper6
40
+ // This code makes shikoshib send a message to RobTop
41
41
  const gd = require("gj-boomlings-api");
42
- gd.uploadMessage("Mipper6", "message subject", "message content", "shikoshib", "your password here");
42
+ gd.uploadMessage("RobTop", "message subject", "message content", "shikoshib", "your password here");
43
43
  ```
44
44
  # License
45
- [ISC](https://github.com/shikoshib/gj-boomlings-api/blob/main/LICENSE)
45
+ [ISC](https://github.com/shikoshib/gj-boomlings-api/blob/main/LICENSE)
@@ -0,0 +1,32 @@
1
+ module.exports = {
2
+ /**
3
+ * Accepts a friend request.
4
+ * @param {string} from - The player the friend request was sent from.
5
+ * @param {string} username - The target's username or player ID.
6
+ * @param {string} password - The target's password.
7
+ * @returns {number} Returns 1 if everything's OK, or -1 if something went wrong.
8
+ */
9
+ acceptFriendRequest: async function (from, username, password) {
10
+ if (!from) throw new Error("Please specify the player the friend request was sent from!");
11
+ if (!username) throw new Error("Please provide the username or the player ID!");
12
+ if (!password) throw new Error("Please provide the password!");
13
+
14
+ const { gjReq } = require("../misc/gjReq");
15
+ const { gjp2 } = require("../misc/gjp2");
16
+
17
+ let userSearch = await gjReq("getGJUsers20", { str: username });
18
+ if (userSearch.data == -1) throw new Error(`-1: Player with the ID or player username "${username}" not found`);
19
+ let userAccID = userSearch.data.split(":")[23];
20
+
21
+ let recSearch = await gjReq("getGJUsers20", { str: from });
22
+ if (recSearch.data == -1) throw new Error(`-1: Player with the ID or player username "${from}" not found`);
23
+ let recAccID = recSearch.data.split(":")[23];
24
+
25
+ let res = await gjReq("acceptGJFriendRequest20", {
26
+ accountID: userAccID,
27
+ targetAccountID: recAccID,
28
+ gjp2: gjp2(password)
29
+ });
30
+ return Number(res.data);
31
+ }
32
+ }
@@ -1,39 +1,31 @@
1
1
  module.exports = {
2
2
  /**
3
3
  * Blocks a specified user.
4
- * @param {string} target - The player that needs to be blocked.
4
+ * @param {string} target - The player to be blocked.
5
5
  * @param {string} username - The blocking person's username or player ID.
6
6
  * @param {string} password - The blocking person's password.
7
- * @returns {number} Returns 1 if everything's OK, and -1 if something went wrong.
7
+ * @returns {number} Returns 1 if everything's OK, or -1 if something went wrong.
8
8
  */
9
9
  blockUser: async function (target, username, password) {
10
- if (!target) throw new Error("Please provide a target's player ID or username!");
11
- if (!username) throw new Error("Please provide a player ID or username!");
12
- if (!password) throw new Error("Please provide a password!");
10
+ if (!target) throw new Error("Please provide the target's player ID or username!");
11
+ if (!username) throw new Error("Please provide the player ID or username!");
12
+ if (!password) throw new Error("Please provide the password!");
13
13
 
14
- const { gjReq } = require("../gjReq");
15
- const XOR = require("../xor");
16
- const xor = new XOR;
14
+ const { gjReq } = require("../misc/gjReq");
15
+ const { gjp2 } = require("../misc/gjp2");
17
16
 
18
- let userSearch = await gjReq("getGJUsers20", {
19
- str: username,
20
- secret: "Wmfd2893gb7"
21
- });
22
- if (userSearch.data == -1) throw new Error(-1);
23
- let userAccID = userSearch.data.split(":")[21];
17
+ let userSearch = await gjReq("getGJUsers20", { str: username });
18
+ if (userSearch.data == -1) throw new Error(`-1: Player with the ID or player username "${username}" not found`);
19
+ let userAccID = userSearch.data.split(":")[23];
24
20
 
25
- let recSearch = await gjReq("getGJUsers20", {
26
- str: target,
27
- secret: "Wmfd2893gb7"
28
- });
29
- if (recSearch.data == -1) throw new Error(-1);
30
- let targetAccID = recSearch.data.split(":")[21];
21
+ let recSearch = await gjReq("getGJUsers20", { str: target });
22
+ if (recSearch.data == -1) throw new Error(`-1: Player with the ID or player username "${target}" not found`);
23
+ let targetAccID = recSearch.data.split(":")[23];
31
24
 
32
25
  const data = {
33
- secret: "Wmfd2893gb7",
34
26
  targetAccountID: targetAccID,
35
27
  accountID: userAccID,
36
- gjp: xor.encrypt(password, 37526)
28
+ gjp2: gjp2(password)
37
29
  }
38
30
 
39
31
  let res = await gjReq("blockGJUser20", data);
@@ -4,29 +4,26 @@ module.exports = {
4
4
  * @param {number} id - The post's ID.
5
5
  * @param {string} username - The poster's username or player ID.
6
6
  * @param {string} password - The poster's password.
7
- * @returns {number} Returns 1 if everything's OK, and -1 if something went wrong.
7
+ * @returns {number} Returns 1 if everything's OK, or -1 if something went wrong.
8
8
  */
9
9
  deleteAccountPost: async function (id, username, password) {
10
- if (!id) throw new Error("Please provide an account post ID!");
11
- if (!username) throw new Error("Please provide a player ID or username!");
12
- if (!password) throw new Error("Please provide a password!");
10
+ if (!id) throw new Error("Please provide the account post ID!");
11
+ if (!username) throw new Error("Please provide the player ID or username!");
12
+ if (!password) throw new Error("Please provide the password!");
13
13
 
14
- const { gjReq } = require("../gjReq");
15
- const XOR = require("../xor");
16
- const xor = new XOR;
14
+ const { gjReq } = require("../misc/gjReq");
15
+ const { gjp2 } = require("../misc/gjp2");
17
16
 
18
- let search = await gjReq("getGJUsers20", {
19
- str: username,
20
- secret: "Wmfd2893gb7"
21
- });
22
- if (search.data == -1) throw new Error(-1);
23
- let accID = search.data.split(":")[21];
17
+ let search = await gjReq("getGJUsers20", { str: username });
18
+ if (search.data == -1) throw new Error(`-1: Player with the ID or player username "${username}" not found`);
19
+ let accID = search.data.split(":")[23];
24
20
 
25
21
  let res = await gjReq("deleteGJAccComment20", {
26
22
  accountID: accID,
27
- secret: "Wmfd2893gb7",
28
- gjp: xor.encrypt(password, 37526),
29
- commentID: id
23
+ gjp2: gjp2(password),
24
+ commentID: id,
25
+ cType: 1,
26
+ targetAccountID: accID
30
27
  });
31
28
 
32
29
  return Number(res.data);
@@ -5,31 +5,26 @@ module.exports = {
5
5
  * @param {number} level - The ID of the level which has the comment.
6
6
  * @param {string} username - The commenter's username.
7
7
  * @param {string} password - The commenter's password.
8
- * @returns {number} Returns 1 if everything's OK, and -1 if something went wrong.
8
+ * @returns {number} Returns 1 if everything's OK, or -1 if something went wrong.
9
9
  */
10
10
  deleteComment:
11
11
  async function (id, level, username, password) {
12
- if (!id) throw new Error("Please provide a comment ID!");
13
- if (!level) throw new Error("Please provide a level ID!");
14
- if (!username) throw new Error("Please provide a user ID or name!");
15
- if (!password) throw new Error("Please provide a password!");
12
+ if (!id) throw new Error("Please provide the comment ID!");
13
+ if (!level) throw new Error("Please provide the level ID!");
14
+ if (!username) throw new Error("Please provide the username or the player ID!");
15
+ if (!password) throw new Error("Please provide the password!");
16
16
 
17
- const { gjReq } = require("../gjReq.js");
18
- let search = await gjReq("getGJUsers20", {
19
- str: username,
20
- secret: "Wmfd2893gb7"
21
- });
22
- if (search.data == -1) throw new Error(-1);
23
- let accID = search.data.split(":")[21];
17
+ const { gjReq } = require("../misc/gjReq");
18
+ const { gjp2 } = require("../misc/gjp2");
24
19
 
25
- const XOR = require("../xor.js");
26
- const xor = new XOR;
20
+ let search = await gjReq("getGJUsers20", { str: username });
21
+ if (search.data == -1) throw new Error(`-1: Player with the ID or player username "${username}" not found`);
22
+ let accID = search.data.split(":")[23];
27
23
 
28
24
  const res = await gjReq("deleteGJComment20", {
29
25
  accountID: accID,
30
- secret: "Wmfd2893gb7",
31
26
  levelID: level,
32
- gjp: xor.encrypt(password, 37526),
27
+ gjp2: gjp2(password),
33
28
  commentID: id
34
29
  });
35
30
 
@@ -0,0 +1,36 @@
1
+ module.exports = {
2
+ /**
3
+ * Deletes a friend request.
4
+ * @param {string} target - The player the friend request was sent to.
5
+ * @param {string} username - The sender's username or player ID.
6
+ * @param {string} password - The sender's password.
7
+ * @param {boolean} isSender - Whether the person specified in `username` was the one sending the friend request. Defaults to false (the person is the one receiving friend requests).
8
+ * @returns {number} Returns 1 if everything's OK, or -1 if something went wrong.
9
+ */
10
+ deleteFriendRequest: async function (target, username, password, isSender = false) {
11
+ if (!target) throw new Error("Please specify the target!");
12
+ if (!username) throw new Error("Please provide the username or the player ID!");
13
+ if (!password) throw new Error("Please provide the password!");
14
+ if (isSender && isNaN(isSender)) throw new Error("Please provide either false or true for isSender!");
15
+
16
+ const { gjReq } = require("../misc/gjReq");
17
+ const { gjp2 } = require("../misc/gjp2");
18
+
19
+ let userSearch = await gjReq("getGJUsers20", { str: username });
20
+ if (userSearch.data == -1) throw new Error(`-1: Player with the ID or player username "${username}" not found`);
21
+ let userAccID = userSearch.data.split(":")[23];
22
+
23
+ let recSearch = await gjReq("getGJUsers20", { str: target });
24
+ if (recSearch.data == -1) throw new Error(`-1: Player with the ID or player username "${target}" not found`);
25
+ let recAccID = recSearch.data.split(":")[23];
26
+
27
+ let res = await gjReq("deleteGJFriendRequests20", {
28
+ accountID: userAccID,
29
+ targetAccountID: recAccID,
30
+ gjp2: gjp2(password),
31
+ isSender: Number(isSender)
32
+ });
33
+
34
+ return Number(res.data);
35
+ }
36
+ }
@@ -4,32 +4,26 @@ module.exports = {
4
4
  * @param {number} level - The ID of the level that needs to be deleted.
5
5
  * @param {string} username - The uploader's username or player ID.
6
6
  * @param {string} password - The uploader's password.
7
- * @returns {number} Returns 1 if everything's OK, and -1 if something went wrong.
7
+ * @returns {number} Returns 1 if everything's OK, or -1 if something went wrong.
8
8
  */
9
9
  deleteLevel: async function (level, username, password) {
10
10
  if (isNaN(level)) throw new Error("Please provide a valid level ID!");
11
- if (!username) throw new Error("Please provide a user ID or name!");
12
- if (!password) throw new Error("Please provide a password!");
11
+ if (!username) throw new Error("Please provide the username or the player ID!");
12
+ if (!password) throw new Error("Please provide the password!");
13
13
 
14
- const { gjReq } = require("../gjReq");
15
- const XOR = require("../xor");
16
- const xor = new XOR;
14
+ const { gjReq } = require("../misc/gjReq");
15
+ const { gjp2 } = require("../misc/gjp2");
17
16
 
18
- let search = await gjReq("getGJUsers20", {
19
- str: username,
20
- secret: "Wmfd2893gb7"
21
- });
22
- if (search.data == -1) throw new Error(-1);
23
- let accID = search.data.split(":")[21];
17
+ let search = await gjReq("getGJUsers20", { str: username });
18
+ if (search.data == -1) throw new Error(`-1: Player with the ID or player username "${username}" not found`);
19
+ let accID = search.data.split(":")[23];
24
20
 
25
- let data = {
21
+ let res = await gjReq("deleteGJLevelUser20", {
26
22
  accountID: accID,
27
23
  secret: "Wmfv2898gc9",
28
24
  levelID: level,
29
- gjp: xor.encrypt(password, 37526),
30
- };
31
-
32
- let res = await gjReq("deleteGJLevelUser20", data);
25
+ gjp2: gjp2(password),
26
+ });
33
27
 
34
28
  return Number(res.data);
35
29
  }
@@ -0,0 +1,33 @@
1
+ module.exports = {
2
+ /**
3
+ * Deletes a message.
4
+ * @param {number} id - The message ID.
5
+ * @param {string} username - The deleting person's username or player ID.
6
+ * @param {string} password - The deleting person's password.
7
+ * @param {boolean} isSender - Whether the person specified in `username` was the one sending the message. Defaults to false (the person is the one receiving the message).
8
+ * @returns {Number} Returns 1 regardless of whether the message was deleted or not, or -1 if the credentials are incorrect.
9
+ */
10
+ deleteMessage: async function (id, username, password, isSender = false) {
11
+ if (!id) throw new Error("Please provide a valid message ID!");
12
+ if (!username) throw new Error("Please provide the player ID or username!");
13
+ if (!password) throw new Error("Please provide the password!");
14
+ if (isSender && isNaN(isSender)) throw new Error("Please provide either false or true for isSender!");
15
+
16
+ const { gjReq } = require("../misc/gjReq");
17
+ const { gjp2 } = require("../misc/gjp2");
18
+
19
+ let search = await gjReq("getGJUsers20", { str: username });
20
+ if (search.data == -1) throw new Error(`-1: Player with the ID or player username "${username}" not found`);
21
+ let accID = search.data.split(":")[23];
22
+
23
+ let data = {
24
+ accountID: accID,
25
+ gjp2: gjp2(password),
26
+ messageID: id
27
+ };
28
+ if (isSender) data.isSender = 1;
29
+
30
+ let res = await gjReq("deleteGJMessages20", data);
31
+ return Number(res.data);
32
+ }
33
+ }
@@ -29,7 +29,9 @@
29
29
  * @property {string|boolean} rating - Primarily used for new 2.2 ratings. Returns either "epic", "legendary", "mythic", or `false` if the level's rating is lower than epic.
30
30
  * @property {number} objects - The amount of objects the level has, based on the level data.
31
31
  * @property {string} uploaded - How long ago the level was uploaded.
32
+ * @property {number} uploadedTimestamp - The Unix timestamp of the level's upload date (GMT timezone).
32
33
  * @property {string} updated - How long ago the level was last updated.
34
+ * @property {number} updatedTimestamp - The Unix timestamp of the level's last update date (GMT timezone).
33
35
  * @property {number} starsRequested - The amount of stars the uploader requested for this level.
34
36
  * @property {string} gameVersion - The version of the game used to upload the current version of the level. Returns "Pre-1.7" if the level was last updated in 1.6 or earlier.
35
37
  * @property {boolean} ldm - Whether the level has a "Low Detail Mode" option.
@@ -39,8 +41,8 @@
39
41
  * @property {number} coins - The amount of coins the level has.
40
42
  * @property {boolean} verifiedCoins - Whether the coins are verified.
41
43
  * @property {Song} song - The main song used in the level.
42
- * @property {Array} additionalSongs - The array containing additional songs' IDs.
43
- * @property {Array} sfx - The array containing sound effects' IDs.
44
+ * @property {Array<number>} additionalSongs - The array containing additional songs' IDs.
45
+ * @property {Array<number>} sfx - The array containing sound effects' IDs.
44
46
  */
45
47
 
46
48
  module.exports = {
@@ -49,53 +51,51 @@ module.exports = {
49
51
  * @param {number} level - The level ID.
50
52
  * @returns {Level}
51
53
  */
52
- dlLevel: async function (level) {
54
+ downloadLevel: async function (level) {
53
55
  const zlib = require("zlib");
54
56
  if (!level) throw new Error("Please provide a level ID.");
55
57
  if (isNaN(level)) throw new Error("The level parameter should be a number.");
56
58
 
57
- const { gjReq } = require("../gjReq");
59
+ const { gjReq } = require("../misc/gjReq");
58
60
 
59
- const data = {
60
- levelID: level.toString().trim(),
61
- secret: "Wmfd2893gb7"
62
- }
63
61
 
64
- let res = await gjReq("downloadGJLevel22", data);
62
+ let res = await gjReq("downloadGJLevel22", { levelID: level.toString().trim() });
65
63
  if (res.data == -1) return {};
66
- const XOR = require("../xor");
64
+ const XOR = require("../misc/xor");
67
65
  let xor = new XOR;
68
66
 
69
67
  let s = res.data.split("#")[0].split(":");
70
68
 
71
- let id = Number(s[1]);
72
- let name = s[3];
73
- let description = Buffer.from(s[5], "base64url").toString();
74
- let levelString = s[7];
75
- let version = Number(s[9]);
76
- let playerID = Number(s[11]);
77
- let difficulty = s[15];
78
- let downloads = Number(s[17]);
79
- let officialSongID = Number(s[19]);
80
- let gameVersion = Number(s[21]);
81
- let likes = Number(s[23]);
82
- let isDemon = s[25];
83
- let stars = Number(s[31]);
84
- let isFeatured = s[33];
85
- let isEpic = s[35];
86
- let objStats = Number(s[37]);
87
- let length = Number(s[39]);
88
- let copiedID = Number(s[41]);
89
- let is2P = s[43];
90
- let uploaded = s[45];
91
- let updated = s[47];
92
- let NGSongID = Number(s[49]);
93
- let coins = Number(s[53]);
94
- let coinsVerified = s[55];
95
- let starReq = Number(s[57]);
96
- let isLDM = s[63];
97
- let password = xor.decrypt(s[67].split("#")[0], 26364);
98
- if (password.length == 7) password = password.replace("1", "");
69
+ let id = Number(s[1]); // 1:
70
+ let name = s[3]; // 2:
71
+ let description = Buffer.from(s[5], "base64url").toString(); // 3: in base64
72
+ let levelString = s[7]; // 4:
73
+ let version = Number(s[9]); // 5:
74
+ let playerID = Number(s[11]); // 6:
75
+ let difficulty = s[15]; // 9:
76
+ let downloads = Number(s[17]); // 10:
77
+ let officialSongID = Number(s[19]); // 12:
78
+ let gameVersion = Number(s[21]); // 13:
79
+ let likes = Number(s[23]); // 14:
80
+ let isDemon = s[25]; // 17:
81
+ let stars = Number(s[31]); // 18:
82
+ let isFeatured = s[33]; // 19:
83
+ let isEpic = s[35]; // 42:
84
+ let objStats = Number(s[37]); // 45:
85
+ let length = Number(s[39]); // 15:
86
+ let copiedID = Number(s[41]); // 30:
87
+ let is2P = s[43]; // 31:
88
+ let uploaded = s[45]; // 28:
89
+ let updated = s[47]; // 29:
90
+ let uploadedUnix = Number(s[49]); // 62:
91
+ let updatedUnix = Number(s[51]); // 63:
92
+ let NGSongID = Number(s[53]); // 35:
93
+ let coins = Number(s[57]); // 37:
94
+ let coinsVerified = s[59]; // 38:
95
+ let starReq = Number(s[61]); // 39:
96
+ let isLDM = s[67]; // 40:
97
+ let password = xor.decrypt(s[71].split("#")[0], 26364);
98
+ if (password.length == 5 || password.length == 7) password = password.replace("1", "");
99
99
 
100
100
  let diffObj = {
101
101
  "-10": "Auto",
@@ -186,12 +186,14 @@ module.exports = {
186
186
  rating: epicObj[Number(isEpic)],
187
187
  objects: objs.length - 1,
188
188
  uploaded: uploaded,
189
+ uploadedTimestamp: uploadedUnix,
189
190
  updated: updated,
191
+ updatedTimestamp: updatedUnix,
190
192
  starsRequested: starReq,
191
193
  gameVersion: versionObj[gameVersion] ? versionObj[gameVersion] : "Pre-1.7",
192
194
  ldm: Boolean(Number(isLDM)),
193
195
  copiedFrom: copiedID,
194
- large: objStats > 4e4 ? true : false,
196
+ large: objStats > 40000 ? true : false,
195
197
  twoPlayer: Boolean(Number(is2P)),
196
198
  coins: coins,
197
199
  verifiedCoins: Boolean(Number(coinsVerified)),
@@ -200,15 +202,17 @@ module.exports = {
200
202
  sfx: []
201
203
  }
202
204
 
203
- if (s[69] && s[68] != "41") {
205
+ if (s[73] && s[72] != "41") {
204
206
  let songsIDArray = [];
205
207
  let sfxIDArray = [];
206
- for (let songID of s[69].split(",")) {
208
+ for (let songID of s[73].split(",")) { // 52:
207
209
  if (songID == NGSongID) continue;
208
210
  songsIDArray.push(Number(songID));
209
211
  }
210
- for (let sfx of s[71].split("#")[0].split(",")) {
211
- sfxIDArray.push(Number(sfx));
212
+ if (s[74] == "53") {
213
+ for (let sfx of s[75].split("#")[0].split(",")) { // 53:
214
+ sfxIDArray.push(Number(sfx));
215
+ }
212
216
  }
213
217
  result.additionalSongs = songsIDArray;
214
218
  result.sfx = sfxIDArray;
@@ -17,26 +17,23 @@ module.exports = {
17
17
  * @param {string} password - The message recipient's password.
18
18
  * @returns {Message}
19
19
  */
20
- dlMessage: async function (id, username, password) {
20
+ downloadMessage: async function (id, username, password) {
21
21
  if (!id) throw new Error("Please provide a valid message ID!");
22
- if (!username) throw new Error("Please provide a player ID or username!");
23
- if (!password) throw new Error("Please provide a password!");
22
+ if (!username) throw new Error("Please provide the player ID or username!");
23
+ if (!password) throw new Error("Please provide the password!");
24
24
 
25
- const { gjReq } = require("../gjReq");
26
- const XOR = require("../xor");
25
+ const { gjReq } = require("../misc/gjReq");
26
+ const { gjp2 } = require("../misc/gjp2");
27
+ const XOR = require("../misc/xor");
27
28
  const xor = new XOR;
28
29
 
29
- let search = await gjReq("getGJUsers20", {
30
- str: username,
31
- secret: "Wmfd2893gb7"
32
- });
33
- if (search.data == -1) return {};
34
- let accID = search.data.split(":")[21];
30
+ let search = await gjReq("getGJUsers20", { str: username });
31
+ if (search.data == -1) throw new Error(`-1: Player with the ID or player username "${username}" not found`);
32
+ let accID = search.data.split(":")[23];
35
33
 
36
34
  let res = await gjReq("downloadGJMessage20", {
37
35
  accountID: accID,
38
- gjp: xor.encrypt(password, 37526),
39
- secret: "Wmfd2893gb7",
36
+ gjp2: gjp2(password),
40
37
  messageID: id
41
38
  });
42
39
  if (res.data == -1) return {};
@@ -15,21 +15,16 @@ module.exports = {
15
15
  */
16
16
  getAccountPosts: async function (target, page = 1) {
17
17
  if (!target) throw new Error("Please provide a player ID or username!");
18
- const { gjReq } = require("../gjReq");
18
+ const { gjReq } = require("../misc/gjReq");
19
19
 
20
- let search = await gjReq("getGJUsers20", {
21
- str: target,
22
- secret: "Wmfd2893gb7"
23
- });
24
- if (search.data == -1) return [];
25
- let targetAccID = search.data.split(":")[21];
20
+ let search = await gjReq("getGJUsers20", { str: target });
21
+ if (search.data == -1) throw new Error(`-1: Player with the ID or player username "${target}" not found`);
22
+ let targetAccID = search.data.split(":")[23];
26
23
 
27
24
  let res = await gjReq("getGJAccountComments20", {
28
25
  accountID: targetAccID,
29
- secret: "Wmfd2893gb7",
30
26
  page: page - 1
31
27
  })
32
- if (res.data == -1) throw new Error("-1 Not found.");
33
28
  if (res.data.startsWith("#")) return [];
34
29
 
35
30
  let accPosts = res.data.split("#")[0].split("|");
@@ -3,8 +3,10 @@
3
3
  * @property {string} username - The blocked person's username.
4
4
  * @property {number} playerID - The blocked person's player ID.
5
5
  * @property {number} accountID - The blocked person's account ID.
6
+ * @property {string} iconID - The blocked person's icon ID.
6
7
  * @property {string} color1 - The HEX code of the blocked person's primary color.
7
8
  * @property {string} color2 - The HEX code of the blocked person's secondary color.
9
+ * @property {("cube"|"ship"|"ball"|"ufo"|"wave"|"robot"|"spider"|"swing"|"jetpack")} iconType - The blocked person's selected game mode to be displayed as an icon.
8
10
  */
9
11
 
10
12
  module.exports = {
@@ -15,24 +17,19 @@ module.exports = {
15
17
  * @returns {BlockedUser[]}
16
18
  */
17
19
  getBlockedList: async function (username, password) {
18
- if (!username) throw new Error("Please provide a player ID or username!");
19
- if (!password) throw new Error("Please provide a password!");
20
+ if (!username) throw new Error("Please provide the player ID or username!");
21
+ if (!password) throw new Error("Please provide the password!");
20
22
 
21
- const { gjReq } = require("../gjReq");
22
- const XOR = require("../xor");
23
- const xor = new XOR;
23
+ const { gjReq } = require("../misc/gjReq");
24
+ const { gjp2 } = require("../misc/gjp2");
24
25
 
25
- let search = await gjReq("getGJUsers20", {
26
- str: username,
27
- secret: "Wmfd2893gb7"
28
- });
29
- if (search.data == -1) return [];
30
- let accID = search.data.split(":")[21];
26
+ let search = await gjReq("getGJUsers20", { str: username });
27
+ if (search.data == -1) throw new Error(`-1: Player with the ID or player username "${username}" not found`);
28
+ let accID = search.data.split(":")[23];
31
29
 
32
30
  const data = {
33
31
  accountID: accID,
34
- gjp: xor.encrypt(password, 37526),
35
- secret: "Wmfd2893gb7",
32
+ gjp2: gjp2(password),
36
33
  type: 1
37
34
  }
38
35
 
@@ -44,20 +41,38 @@ module.exports = {
44
41
  let colors = require("../misc/colors.json");
45
42
  const { rgbToHEX } = require("../misc/rgbToHEX");
46
43
 
47
- players.forEach(p => {
48
- let s=p.split(":");
44
+ let iconObj = {
45
+ 0: "cube",
46
+ 1: "ship",
47
+ 2: "ball",
48
+ 3: "ufo",
49
+ 4: "wave",
50
+ 5: "robot",
51
+ 6: "spider",
52
+ 7: "swing",
53
+ 8: "jetpack"
54
+ };
55
+
56
+ res.data.split("|").forEach(p => {
57
+ let s = p.split(":");
49
58
  let username = s[1];
50
59
  let playerID = s[3];
60
+ let iconID = s[5];
51
61
  let p1 = s[7];
52
62
  let p2 = s[9];
53
- let accID = s[15];
63
+ let glowColor = s[11];
64
+ let iconType = s[13];
65
+ let accID = s[17];
54
66
 
55
67
  result.push({
56
68
  username: username,
57
69
  playerID: Number(playerID),
58
70
  accountID: Number(accID),
71
+ iconID: Number(iconID),
59
72
  color1: rgbToHEX(colors[p1]),
60
- color2: rgbToHEX(colors[p2])
73
+ color2: rgbToHEX(colors[p2]),
74
+ glowColor: glowColor != "0" ? rgbToHEX(colors[glowColor]) : null,
75
+ iconType: iconObj[Number(iconType)]
61
76
  })
62
77
  })
63
78