gj-boomlings-api 2.0.1 → 2.0.2

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 (44) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +2 -9
  3. package/functions/blockUser.js +8 -2
  4. package/functions/deleteAccountPost.js +11 -5
  5. package/functions/deleteComment.js +14 -7
  6. package/functions/deleteLevel.js +13 -7
  7. package/functions/dlLevel.js +64 -4
  8. package/functions/dlMessage.js +23 -5
  9. package/functions/getAccountPosts.js +23 -4
  10. package/functions/getBlockedList.js +20 -6
  11. package/functions/getCommentHistory.js +35 -6
  12. package/functions/getComments.js +31 -3
  13. package/functions/getCreatorScores.js +18 -0
  14. package/functions/getDailyLevel.js +5 -1
  15. package/functions/getFriendsList.js +21 -6
  16. package/functions/getGauntlets.js +11 -0
  17. package/functions/getLevelByID.js +43 -0
  18. package/functions/getLevelScores.js +32 -9
  19. package/functions/getMapPacks.js +16 -0
  20. package/functions/getMessages.js +22 -5
  21. package/functions/getOfficialSongInfo.js +15 -4
  22. package/functions/getProfile.js +46 -7
  23. package/functions/getSongInfo.js +21 -6
  24. package/functions/getSongsLibrary.js +31 -4
  25. package/functions/getTab.js +8 -0
  26. package/functions/getTop100.js +4 -0
  27. package/functions/getTopLists.js +5 -0
  28. package/functions/getUserLevels.js +11 -5
  29. package/functions/getWeeklyDemon.js +4 -0
  30. package/functions/reportLevel.js +5 -0
  31. package/functions/searchLevels.js +6 -0
  32. package/functions/searchLists.js +24 -0
  33. package/functions/unblockUser.js +7 -1
  34. package/functions/updateLevelDesc.js +11 -4
  35. package/functions/uploadAccountPost.js +10 -3
  36. package/functions/uploadComment.js +15 -6
  37. package/functions/uploadMessage.js +18 -9
  38. package/misc/GJDecode.js +14 -3
  39. package/misc/colors.json +109 -1
  40. package/misc/gauntlets.json +36 -1
  41. package/misc/officialsongs.json +248 -1
  42. package/misc/rgbToHEX.js +17 -1
  43. package/package.json +1 -1
  44. package/xor.js +9 -3
package/LICENSE CHANGED
@@ -1,4 +1,4 @@
1
- Copyright 2023 shikoshib
1
+ Copyright 2025 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
@@ -1,14 +1,9 @@
1
1
  <div align="center">
2
- <h1>
3
- <a href="https://www.npmjs.com/package/gj-boomlings-api"><img src="https://shikoshib.github.io/font1.png" width="500"></a>
4
- </h1>
2
+ <h1>gj-boomlings-api</h1>
5
3
  A light-weight Geometry Dash API wrapper<br><br><a href="https://github.com/shikoshib/gj-boomlings-api/wiki"><b>Documentation</b></a><br><br>
6
4
  <a href="https://www.npmjs.com/package/gj-boomlings-api"><img src="https://img.shields.io/npm/v/gj-boomlings-api.svg?maxAge=3600" alt="npm version" /></a>
7
- <img alt="npm bundle size" src="https://img.shields.io/bundlephobia/min/gj-boomlings-api">
8
- <a href="https://github.com/shikoshib/gj-boomlings-api/actions/workflows/node.js.yml"><img src="https://github.com/shikoshib/gj-boomlings-api/actions/workflows/node.js.yml/badge.svg" /></a>
9
5
  <a href="https://www.npmjs.com/package/gj-boomlings-api"><img src="https://img.shields.io/npm/dt/gj-boomlings-api" /></a>
10
6
  <a href="https://snyk.io/test/github/shikoshib/gj-boomlings-api"><img src="https://snyk.io/test/github/shikoshib/gj-boomlings-api/badge.svg" alt="Known Vulnerabilities" /></a>
11
- <a href="https://packagequality.com/#?package=gj-boomlings-api"><img src="https://packagequality.com/shield/gj-boomlings-api.svg"/></a>
12
7
  </div>
13
8
 
14
9
  # About
@@ -19,8 +14,6 @@
19
14
  npm i gj-boomlings-api
20
15
  yarn add gj-boomlings-api
21
16
  ```
22
- ## In browser
23
- Not yet, coming soon
24
17
  # Examples
25
18
  ## Download a level
26
19
  ```js
@@ -40,7 +33,7 @@ gd.getGauntlets().then(console.log);
40
33
  ## Post a message on a profile
41
34
  ```js
42
35
  const gd = require("gj-boomlings-api");
43
- gd.uploadAccountPost("I love gj-boomlings-api!","shikoshib","your password here");
36
+ gd.uploadAccountPost("I love gj-boomlings-api!", "shikoshib", "your password here");
44
37
  ```
45
38
  ## Send a message
46
39
  ```js
@@ -1,4 +1,11 @@
1
1
  module.exports = {
2
+ /**
3
+ * Blocks a specified user.
4
+ * @param {string} target - The player that needs to be blocked.
5
+ * @param {string} username - The blocking person's username or player ID.
6
+ * @param {string} password - The blocking person's password.
7
+ * @returns {number} Returns 1 if everything's OK, and -1 if something went wrong.
8
+ */
2
9
  blockUser: async function (target, username, password) {
3
10
  if (!target) throw new Error("Please provide a target's player ID or username!");
4
11
  if (!username) throw new Error("Please provide a player ID or username!");
@@ -30,8 +37,7 @@ module.exports = {
30
37
  }
31
38
 
32
39
  let res = await gjReq("blockGJUser20", data);
33
- if (res.data == -1) throw new Error(-1);
34
40
 
35
- return res.data;
41
+ return Number(res.data);
36
42
  }
37
43
  }
@@ -1,7 +1,14 @@
1
1
  module.exports = {
2
- deleteAccountPost: async function (id, str, password) {
2
+ /**
3
+ * Deletes a post from the user's account.
4
+ * @param {number} id - The post's ID.
5
+ * @param {string} username - The poster's username or player ID.
6
+ * @param {string} password - The poster's password.
7
+ * @returns {number} Returns 1 if everything's OK, and -1 if something went wrong.
8
+ */
9
+ deleteAccountPost: async function (id, username, password) {
3
10
  if (!id) throw new Error("Please provide an account post ID!");
4
- if (!str) throw new Error("Please provide a user ID or name!");
11
+ if (!username) throw new Error("Please provide a player ID or username!");
5
12
  if (!password) throw new Error("Please provide a password!");
6
13
 
7
14
  const { gjReq } = require("../gjReq");
@@ -9,7 +16,7 @@ module.exports = {
9
16
  const xor = new XOR;
10
17
 
11
18
  let search = await gjReq("getGJUsers20", {
12
- str: str,
19
+ str: username,
13
20
  secret: "Wmfd2893gb7"
14
21
  });
15
22
  if (search.data == -1) throw new Error(-1);
@@ -21,8 +28,7 @@ module.exports = {
21
28
  gjp: xor.encrypt(password, 37526),
22
29
  commentID: id
23
30
  });
24
- if (res.data == -1) throw new Error(-1);
25
31
 
26
- return res.data;
32
+ return Number(res.data);
27
33
  }
28
34
  }
@@ -1,14 +1,22 @@
1
1
  module.exports = {
2
+ /**
3
+ * Deletes a comment from a level.
4
+ * @param {number} id - The comment's ID.
5
+ * @param {number} level - The ID of the level which has the comment.
6
+ * @param {string} username - The commenter's username.
7
+ * @param {string} password - The commenter's password.
8
+ * @returns {number} Returns 1 if everything's OK, and -1 if something went wrong.
9
+ */
2
10
  deleteComment:
3
- async function (id, lvl, str, password) {
11
+ async function (id, level, username, password) {
4
12
  if (!id) throw new Error("Please provide a comment ID!");
5
- if (!lvl) throw new Error("Please provide a level ID!");
6
- if (!str) throw new Error("Please provide a user ID or name!");
13
+ if (!level) throw new Error("Please provide a level ID!");
14
+ if (!username) throw new Error("Please provide a user ID or name!");
7
15
  if (!password) throw new Error("Please provide a password!");
8
16
 
9
17
  const { gjReq } = require("../gjReq.js");
10
18
  let search = await gjReq("getGJUsers20", {
11
- str: str,
19
+ str: username,
12
20
  secret: "Wmfd2893gb7"
13
21
  });
14
22
  if (search.data == -1) throw new Error(-1);
@@ -20,12 +28,11 @@ module.exports = {
20
28
  const res = await gjReq("deleteGJComment20", {
21
29
  accountID: accID,
22
30
  secret: "Wmfd2893gb7",
23
- levelID: lvl,
31
+ levelID: level,
24
32
  gjp: xor.encrypt(password, 37526),
25
33
  commentID: id
26
34
  });
27
- if (res.data == -1) throw new Error(-1);
28
35
 
29
- return res.data;
36
+ return Number(res.data);
30
37
  }
31
38
  }
@@ -1,7 +1,14 @@
1
1
  module.exports = {
2
- deleteLevel: async function (lvl, str, password) {
3
- if (isNaN(lvl)) throw new Error("Please provide a valid level ID!");
4
- if (!str) throw new Error("Please provide a user ID or name!");
2
+ /**
3
+ * Deletes a level.
4
+ * @param {number} level - The ID of the level that needs to be deleted.
5
+ * @param {string} username - The uploader's username or player ID.
6
+ * @param {string} password - The uploader's password.
7
+ * @returns {number} Returns 1 if everything's OK, and -1 if something went wrong.
8
+ */
9
+ deleteLevel: async function (level, username, password) {
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!");
5
12
  if (!password) throw new Error("Please provide a password!");
6
13
 
7
14
  const { gjReq } = require("../gjReq");
@@ -9,7 +16,7 @@ module.exports = {
9
16
  const xor = new XOR;
10
17
 
11
18
  let search = await gjReq("getGJUsers20", {
12
- str: str,
19
+ str: username,
13
20
  secret: "Wmfd2893gb7"
14
21
  });
15
22
  if (search.data == -1) throw new Error(-1);
@@ -18,13 +25,12 @@ module.exports = {
18
25
  let data = {
19
26
  accountID: accID,
20
27
  secret: "Wmfv2898gc9",
21
- levelID: lvl,
28
+ levelID: level,
22
29
  gjp: xor.encrypt(password, 37526),
23
30
  };
24
31
 
25
32
  let res = await gjReq("deleteGJLevelUser20", data);
26
- if (res.data == -1) throw new Error(-1);
27
33
 
28
- return res.data;
34
+ return Number(res.data);
29
35
  }
30
36
  }
@@ -1,4 +1,54 @@
1
+ /**
2
+ * @typedef {Object} Song
3
+ * @property {string} name - The song's name.
4
+ * @property {number} id - The song's ID.
5
+ * @property {string} artist - The song artist.
6
+ * @property {number} artistId - The song artist's ID on Newgrounds.
7
+ * @property {number} fileSize - The song's file size in megabytes.
8
+ * @property {string} link - The direct link to download the song file.
9
+ */
10
+
11
+ /**
12
+ * A playable Geometry Dash online level.
13
+ * @typedef {Object} Level
14
+ * @property {number} id - The level's ID.
15
+ * @property {string} name - The level's name.
16
+ * @property {string} description - The level's description.
17
+ * @property {string} levelVersion - The level's current version number.
18
+ * @property {number} playerID - The level uploader's player ID.
19
+ * @property {string} difficulty - The level's difficulty.
20
+ * @property {number} stars - The amount of stars given when completing the level.
21
+ * @property {number} downloads - The amount of times the level has been downloaded.
22
+ * @property {number} likes - The amount of likes the level has.
23
+ * @property {boolean} disliked - Whether the level is disliked (i.e. if the likes count is less than 0).
24
+ * @property {string} length - The level's length.
25
+ * @property {string} password - The level's password. Otherwise, returns "" (an empty string) if the level isn't copyable, and "1" if the level is copyable without a password.
26
+ * @property {boolean} demon - Whether the level is a demon.
27
+ * @property {boolean} featured - Whether the level is featured.
28
+ * @property {boolean} epic - Whether the level is epic-rated.
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
+ * @property {number} objects - The amount of objects the level has, based on the level data.
31
+ * @property {string} uploaded - How long ago the level was uploaded.
32
+ * @property {string} updated - How long ago the level was last updated.
33
+ * @property {number} starsRequested - The amount of stars the uploader requested for this level.
34
+ * @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
+ * @property {boolean} ldm - Whether the level has a "Low Detail Mode" option.
36
+ * @property {number} copiedID - The original level's ID if this level was copied. Returns 0 if the level is original on itself.
37
+ * @property {boolean} large - Whether the level is considered "large" (i.e. has more than 40k objects).
38
+ * @property {boolean} twoPlayer - Whether the level can be played by two people.
39
+ * @property {number} coins - The amount of coins the level has.
40
+ * @property {boolean} verifiedCoins - Whether the coins are verified.
41
+ * @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
+ */
45
+
1
46
  module.exports = {
47
+ /**
48
+ * Downloads a level.
49
+ * @param {number} level - The level ID.
50
+ * @returns {Level}
51
+ */
2
52
  dlLevel: async function (level) {
3
53
  const zlib = require("zlib");
4
54
  if (!level) throw new Error("Please provide a level ID.");
@@ -98,6 +148,13 @@ module.exports = {
98
148
  const objs = rawData.split(";");
99
149
  objs.shift();
100
150
 
151
+ const epicObj = {
152
+ 0: null,
153
+ 1: "epic",
154
+ 2: "legendary",
155
+ 3: "mythic"
156
+ }
157
+
101
158
  let song;
102
159
  const { getOfficialSongInfo } = require("./getOfficialSongInfo");
103
160
  const { getSongInfo } = require("./getSongInfo");
@@ -106,7 +163,7 @@ module.exports = {
106
163
  } else if (NGSongID && !officialSongID) {
107
164
  let findSong = await getSongInfo(NGSongID);
108
165
  song = findSong;
109
- }else if(!officialSongID&&!NGSongID){
166
+ } else if (!officialSongID && !NGSongID) {
110
167
  song = getOfficialSongInfo(1);
111
168
  }
112
169
 
@@ -125,7 +182,8 @@ module.exports = {
125
182
  password: password,
126
183
  demon: Boolean(Number(isDemon)),
127
184
  featured: Boolean(Number(isFeatured)),
128
- epic: Boolean(Number(isEpic)),
185
+ epic: Number(isEpic) >= 1,
186
+ rating: epicObj[Number(isEpic)],
129
187
  objects: objs.length - 1,
130
188
  uploaded: uploaded,
131
189
  updated: updated,
@@ -137,7 +195,9 @@ module.exports = {
137
195
  twoPlayer: Boolean(Number(is2P)),
138
196
  coins: coins,
139
197
  verifiedCoins: Boolean(Number(coinsVerified)),
140
- song: song
198
+ song: song,
199
+ additionalSongs: [],
200
+ sfx: []
141
201
  }
142
202
 
143
203
  if (s[69] && s[68] != "41") {
@@ -156,4 +216,4 @@ module.exports = {
156
216
 
157
217
  return result;
158
218
  }
159
- }
219
+ }
@@ -1,15 +1,33 @@
1
+ /**
2
+ * @typedef {Object} Message
3
+ * @property {string} username - The message sender's username.
4
+ * @property {string} title - The message's title.
5
+ * @property {string} content - The message's content.
6
+ * @property {number} playerID - The message sender's player ID.
7
+ * @property {number} accountID - The message sender's account ID.
8
+ * @property {number} messageID - The message ID.
9
+ * @property {string} age - How long ago the message was sent.
10
+ */
11
+
1
12
  module.exports = {
2
- dlMessage: async function (id, user, pass) {
13
+ /**
14
+ * Downloads a message.
15
+ * @param {number} id - The message ID.
16
+ * @param {string} username - The message recipient's username or player ID.
17
+ * @param {string} password - The message recipient's password.
18
+ * @returns {Message}
19
+ */
20
+ dlMessage: async function (id, username, password) {
3
21
  if (!id) throw new Error("Please provide a valid message ID!");
4
- if (!user) throw new Error("Please provide a player ID or username!");
5
- if (!pass) throw new Error("Please provide a password!");
22
+ if (!username) throw new Error("Please provide a player ID or username!");
23
+ if (!password) throw new Error("Please provide a password!");
6
24
 
7
25
  const { gjReq } = require("../gjReq");
8
26
  const XOR = require("../xor");
9
27
  const xor = new XOR;
10
28
 
11
29
  let search = await gjReq("getGJUsers20", {
12
- str: user,
30
+ str: username,
13
31
  secret: "Wmfd2893gb7"
14
32
  });
15
33
  if (search.data == -1) return {};
@@ -17,7 +35,7 @@ module.exports = {
17
35
 
18
36
  let res = await gjReq("downloadGJMessage20", {
19
37
  accountID: accID,
20
- gjp: xor.encrypt(pass, 37526),
38
+ gjp: xor.encrypt(password, 37526),
21
39
  secret: "Wmfd2893gb7",
22
40
  messageID: id
23
41
  });
@@ -1,10 +1,24 @@
1
+ /**
2
+ * @typedef {Object} AccountPost
3
+ * @property {string} content - The account post's content.
4
+ * @property {number} likes - The amount of likes the account post has.
5
+ * @property {string} age - How long ago the account post was published.
6
+ * @property {number} id - The account post's ID.
7
+ */
8
+
1
9
  module.exports = {
2
- getAccountPosts: async function (str, page = 1) {
3
- if (!str) throw new Error("Please provide a player ID or name!");
10
+ /**
11
+ * Get the list of a user's account posts.
12
+ * @param {string} target - The targeted user's username or player ID.
13
+ * @param {number} page - The page to look through. Defaults to 1.
14
+ * @returns {AccountPost[]}
15
+ */
16
+ getAccountPosts: async function (target, page = 1) {
17
+ if (!target) throw new Error("Please provide a player ID or username!");
4
18
  const { gjReq } = require("../gjReq");
5
19
 
6
20
  let search = await gjReq("getGJUsers20", {
7
- str: str,
21
+ str: target,
8
22
  secret: "Wmfd2893gb7"
9
23
  });
10
24
  if (search.data == -1) return [];
@@ -21,7 +35,12 @@ module.exports = {
21
35
  let accPosts = res.data.split("#")[0].split("|");
22
36
  let result = [];
23
37
  accPosts.forEach(p => {
24
- result.push({ content: Buffer.from(p.split("~")[1], "base64").toString(), likes: Number(p.split("~")[3]), age: p.split("~")[5], id: Number(p.split("~")[7]) });
38
+ result.push({
39
+ content: Buffer.from(p.split("~")[1], "base64").toString(),
40
+ likes: Number(p.split("~")[3]),
41
+ age: p.split("~")[5],
42
+ id: Number(p.split("~")[7])
43
+ });
25
44
  })
26
45
 
27
46
  return result;
@@ -1,14 +1,29 @@
1
+ /**
2
+ * @typedef {Object} BlockedUser
3
+ * @property {string} username - The blocked person's username.
4
+ * @property {number} playerID - The blocked person's player ID.
5
+ * @property {number} accountID - The blocked person's account ID.
6
+ * @property {string} color1 - The HEX code of the blocked person's primary color.
7
+ * @property {string} color2 - The HEX code of the blocked person's secondary color.
8
+ */
9
+
1
10
  module.exports = {
2
- getBlockedList: async function (user, pass) {
3
- if (!user) throw new Error("Please provide a player ID or username!");
4
- if (!pass) throw new Error("Please provide a password!");
11
+ /**
12
+ * Gets the list of people in a user's blacklist.
13
+ * @param {string} username - The user's username or player ID.
14
+ * @param {string} password - The user's password.
15
+ * @returns {BlockedUser[]}
16
+ */
17
+ 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!");
5
20
 
6
21
  const { gjReq } = require("../gjReq");
7
22
  const XOR = require("../xor");
8
23
  const xor = new XOR;
9
24
 
10
25
  let search = await gjReq("getGJUsers20", {
11
- str: user,
26
+ str: username,
12
27
  secret: "Wmfd2893gb7"
13
28
  });
14
29
  if (search.data == -1) return [];
@@ -16,7 +31,7 @@ module.exports = {
16
31
 
17
32
  const data = {
18
33
  accountID: accID,
19
- gjp: xor.encrypt(pass, 37526),
34
+ gjp: xor.encrypt(password, 37526),
20
35
  secret: "Wmfd2893gb7",
21
36
  type: 1
22
37
  }
@@ -24,7 +39,6 @@ module.exports = {
24
39
  let res = await gjReq("getGJUserList20", data);
25
40
  if (res.data == -1 || res.data == -2) return [];
26
41
 
27
- let players = res.data.split("|");
28
42
  let result = [];
29
43
 
30
44
  let colors = require("../misc/colors.json");
@@ -1,6 +1,33 @@
1
+ /**
2
+ * @typedef {Object} Comment
3
+ * @property {number} levelID - The ID of a level the comment was left on.
4
+ * @property {string} content - The comment's content.
5
+ * @property {number} likes - The amount of likes the comment has.
6
+ * @property {boolean} disliked - Whether the comment is disliked (i.e. if the likes count is less than 0).
7
+ * @property {number} percent - The achieved level percentage at the time of publishing the comment.
8
+ * @property {number} id - The comment's ID.
9
+ * @property {string} age - How long ago the comment was published.
10
+ * @property {string} username - The commenter's username.
11
+ * @property {string} iconID - The commenter's icon ID.
12
+ * @property {string} color1 - The commenter's primary color.
13
+ * @property {string} color2 - The commenter's secondary color.
14
+ * @property {string} iconType - The commenter's selected game mode to be displayed as an icon.
15
+ * @property {number} glow - Whether the commenter's icon has the "glow" feature enabled.
16
+ * @property {number} playerID - The commenter's player ID.
17
+ * @property {number} accountID - The commenter's account ID.
18
+ * @property {string|null} mod - Whether the commenter is a moderator. Returns `null` if not, "mod" if the user is a regular moderator and "elder" if the user is an elder moderator.
19
+ * @property {string|null} color - The comment's text color (usually tied to moderators). Returns `null` if the color is white, otherwise returns the HEX code of the color.
20
+ */
1
21
  module.exports = {
2
- getCommentHistory: async function (str, page = 1, mode = 1) {
3
- if (!str) throw new Error("Please provide a player ID or name!");
22
+ /**
23
+ * Gets the comment history of a user.
24
+ * @param {string} username - The target's username or player ID.
25
+ * @param {number} page - The page to search through. Defaults to 1.
26
+ * @param {number} mode - The viewing mode. Can be either 0 (most recent) or 1 (most liked). Defaults to 1.
27
+ * @returns {Comment[]}
28
+ */
29
+ getCommentHistory: async function (username, page = 1, mode = 1) {
30
+ if (!username) throw new Error("Please provide a player ID or name!");
4
31
  if (page && isNaN(page)) throw new Error("Please provide a page!");
5
32
  if (mode && isNaN(mode)) throw new Error("Please provide a valid mode ID! 0 for recent, 1 for most liked.");
6
33
 
@@ -9,7 +36,7 @@ module.exports = {
9
36
  const { rgbToHEX } = require("../misc/rgbToHEX");
10
37
  const colors = require("../misc/colors.json");
11
38
 
12
- const user = await getProfile(str);
39
+ const user = await getProfile(username);
13
40
  if (user.commentHistory != "all") throw new Error("Whoops! This user has disabled viewing his comment history!");
14
41
 
15
42
  let res = await gjReq("getGJCommentHistory", {
@@ -48,12 +75,14 @@ module.exports = {
48
75
  age: comment[11],
49
76
  username: user[1],
50
77
  iconID: Number(user[3]),
51
- c1: rgbToHEX(colors[user[5]]),
52
- c2: rgbToHEX(colors[user[7]]),
78
+ color1: rgbToHEX(colors[user[5]]),
79
+ color2: rgbToHEX(colors[user[7]]),
53
80
  iconType: iconObj[user[9]],
54
81
  glow: Boolean(Number(user[11])),
55
82
  playerID: Number(comment[5]),
56
- accountID: Number(user[13])
83
+ accountID: Number(user[13]),
84
+ mod: null,
85
+ color: null
57
86
  };
58
87
  if (comment.length > 14) {
59
88
  obj.mod = comment[15] == "1" ? "mod" : "elder";
@@ -1,4 +1,30 @@
1
+ /**
2
+ * @typedef {Object} Comment
3
+ * @property {string} content - The comment's content.
4
+ * @property {number} likes - The amount of likes the comment has.
5
+ * @property {boolean} disliked - Whether the comment is disliked (i.e. if the likes count is less than 0).
6
+ * @property {number} percent - The achieved level percentage at the time of publishing the comment.
7
+ * @property {number} id - The comment's ID.
8
+ * @property {string} age - How long ago the comment was published.
9
+ * @property {string} username - The commenter's username.
10
+ * @property {string} iconID - The commenter's icon ID.
11
+ * @property {string} color1 - The commenter's primary color.
12
+ * @property {string} color2 - The commenter's secondary color.
13
+ * @property {string} iconType - The commenter's selected game mode to be displayed as an icon.
14
+ * @property {number} glow - Whether the commenter's icon has the "glow" feature enabled.
15
+ * @property {number} playerID - The commenter's player ID.
16
+ * @property {number} accountID - The commenter's account ID.
17
+ * @property {string|null} mod - Whether the user is a moderator. Returns `null` if not, "mod" if the user is a regular moderator and "elder" if the user is an elder moderator.
18
+ * @property {string|null} color - The comment's text color (usually tied to moderators). Returns `null` if the color is white, otherwise returns the HEX code of the color.
19
+ */
1
20
  module.exports = {
21
+ /**
22
+ * Gets a list of comments on a level.
23
+ * @param {number} level - The level ID.
24
+ * @param {number} page - The page to search through. Defaults to 1.
25
+ * @param {number} mode - The viewing mode. Can be either 0 (most recent) or 1 (most liked). Defaults to 1.
26
+ * @returns {Comment[]}
27
+ */
2
28
  getComments:
3
29
  async function (level, page = 1, mode = 1) {
4
30
  if (isNaN(level)) throw new Error("Please provide a valid level ID!");
@@ -44,11 +70,13 @@ module.exports = {
44
70
  age: comment[11],
45
71
  username: user[1],
46
72
  iconID: Number(user[3]),
47
- c1: rgbToHEX(colors[user[5]]),
48
- c2: rgbToHEX(colors[user[7]]),
73
+ color1: rgbToHEX(colors[user[5]]),
74
+ color2: rgbToHEX(colors[user[7]]),
49
75
  iconType: iconObj[user[9]],
50
76
  glow: Boolean(Number(user[11])),
51
- accountID: Number(user[13])
77
+ accountID: Number(user[13]),
78
+ mod: null,
79
+ color: null
52
80
  };
53
81
  if (comment.length > 14) {
54
82
  obj.mod = comment[15] == "1" ? "mod" : "elder";
@@ -1,4 +1,22 @@
1
+ /**
2
+ * @typedef {Object} ScoresUser
3
+ * @property {string} name - The player's username.
4
+ * @property {number} playerID - The player's player ID.
5
+ * @property {number} accountID - The player's account ID.
6
+ * @property {number} rank - The player's ranking on the leaderboard.
7
+ * @property {number} stars - The amount of stars the player has.
8
+ * @property {number} diamonds - The amount of diamonds the player has.
9
+ * @property {number} secretCoins - The amount of secret coins the player has.
10
+ * @property {number} userCoins - The amount of user coins the player has.
11
+ * @property {number} demons - The amount of demons the player has completed.
12
+ * @property {number} moons - The amount of moons the player has.
13
+ * @property {number} creatorPoints - The amount of creator points the player has.
14
+ */
1
15
  module.exports = {
16
+ /**
17
+ * Fetches the player leaderboard based on the amount of creator points.
18
+ * @returns {ScoresUser[]}
19
+ */
2
20
  getCreatorScores: async function () {
3
21
  let GJDecode = require("../misc/GJDecode");
4
22
  const { decodeScoresUser } = new GJDecode;
@@ -1,6 +1,10 @@
1
1
  module.exports = {
2
+ /**
3
+ * Gets the current daily level.
4
+ * @returns {import("./dlLevel").Level}
5
+ */
2
6
  getDailyLevel: async function () {
3
- const { dlLevel } = require("./dlLevel")
7
+ const { dlLevel } = require("./dlLevel");
4
8
  let res = await dlLevel(-1);
5
9
  return res;
6
10
  }
@@ -1,14 +1,29 @@
1
+ /**
2
+ * @typedef {Object} Friend
3
+ * @property {string} username - The friend's username.
4
+ * @property {number} playerID - The friend's player ID.
5
+ * @property {number} accountID - The friend's account ID.
6
+ * @property {string} color1 - The HEX code of the friend's primary color.
7
+ * @property {string} color2 - The HEX code of the friend's secondary color.
8
+ * @property {string} messages - The current state of messaging the friend. Returns "all" if anyone can message the person, "friends" if it's limited to friends, and "none" if no one can.
9
+ */
1
10
  module.exports = {
2
- getFriendsList: async function (user, pass) {
3
- if (!user) throw new Error("Please provide a player ID or username!");
4
- if (!pass) throw new Error("Please provide a password!");
11
+ /**
12
+ * Gets the list of a user's friends.
13
+ * @param {string} username - The user's username or player ID.
14
+ * @param {string} password - The user's password.
15
+ * @returns {Friend[]}
16
+ */
17
+ getFriendsList: 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!");
5
20
 
6
21
  const { gjReq } = require("../gjReq");
7
22
  const XOR = require("../xor");
8
23
  const xor = new XOR;
9
24
 
10
25
  let search = await gjReq("getGJUsers20", {
11
- str: user,
26
+ str: username,
12
27
  secret: "Wmfd2893gb7"
13
28
  });
14
29
  if (search.data == -1) return [];
@@ -16,7 +31,7 @@ module.exports = {
16
31
 
17
32
  const data = {
18
33
  accountID: accID,
19
- gjp: xor.encrypt(pass, 37526),
34
+ gjp: xor.encrypt(password, 37526),
20
35
  secret: "Wmfd2893gb7"
21
36
  }
22
37
 
@@ -30,7 +45,7 @@ module.exports = {
30
45
  const { rgbToHEX } = require("../misc/rgbToHEX");
31
46
 
32
47
  players.forEach(p => {
33
- let s=p.split(":");
48
+ let s = p.split(":");
34
49
  let username = s[1];
35
50
  let playerID = s[3];
36
51
  let p1 = s[7];
@@ -1,4 +1,14 @@
1
+ /**
2
+ * @typedef {Object} Gauntlet
3
+ * @property {string} name - The gauntlet's name.
4
+ * @property {number} id - The gauntlet's ID.
5
+ * @property {Array<Number>} levels - The list of level IDs in the gauntlet.
6
+ */
1
7
  module.exports = {
8
+ /**
9
+ * Gets the list of gauntlets.
10
+ * @returns {Gauntlet[]}
11
+ */
2
12
  getGauntlets: async function () {
3
13
  const glIDs = require("../misc/gauntlets.json");
4
14
  const { gjReq } = require("../gjReq");
@@ -15,6 +25,7 @@ module.exports = {
15
25
  }
16
26
  result.push({
17
27
  name: `${glIDs[g.split(":")[1]]} Gauntlet`,
28
+ id: Number(g.split(":")[1]),
18
29
  levels: list
19
30
  });
20
31
  })