gj-boomlings-api 2.0.1 → 2.0.3
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.
- package/LICENSE +1 -1
- package/README.md +2 -9
- package/functions/blockUser.js +8 -2
- package/functions/deleteAccountPost.js +11 -5
- package/functions/deleteComment.js +14 -7
- package/functions/deleteLevel.js +13 -7
- package/functions/dlLevel.js +64 -4
- package/functions/dlMessage.js +23 -5
- package/functions/getAccountPosts.js +23 -4
- package/functions/getBlockedList.js +20 -6
- package/functions/getCommentHistory.js +35 -6
- package/functions/getComments.js +31 -3
- package/functions/getCreatorScores.js +18 -0
- package/functions/getDailyLevel.js +5 -1
- package/functions/getFriendsList.js +21 -6
- package/functions/getGauntlets.js +11 -0
- package/functions/getLevelByID.js +43 -0
- package/functions/getLevelScores.js +32 -9
- package/functions/getMapPacks.js +16 -0
- package/functions/getMessages.js +22 -5
- package/functions/getOfficialSongInfo.js +15 -4
- package/functions/getProfile.js +46 -7
- package/functions/getSongInfo.js +21 -6
- package/functions/getSongsLibrary.js +31 -4
- package/functions/getTab.js +8 -0
- package/functions/getTop100.js +4 -0
- package/functions/getTopLists.js +5 -0
- package/functions/getUserLevels.js +11 -5
- package/functions/getWeeklyDemon.js +4 -0
- package/functions/reportLevel.js +5 -0
- package/functions/searchLevels.js +6 -0
- package/functions/searchLists.js +24 -0
- package/functions/unblockUser.js +7 -1
- package/functions/updateLevelDesc.js +11 -4
- package/functions/uploadAccountPost.js +10 -3
- package/functions/uploadComment.js +17 -8
- package/functions/uploadMessage.js +18 -9
- package/misc/GJDecode.js +14 -3
- package/misc/colors.json +109 -1
- package/misc/gauntlets.json +36 -1
- package/misc/officialsongs.json +248 -1
- package/misc/rgbToHEX.js +17 -1
- package/package.json +1 -1
- package/xor.js +9 -3
|
@@ -1,4 +1,47 @@
|
|
|
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
|
+
* @typedef {Object} Level
|
|
13
|
+
* @property {number} id - The level's ID.
|
|
14
|
+
* @property {string} name - The level's name.
|
|
15
|
+
* @property {string} description - The level's description.
|
|
16
|
+
* @property {string} levelVersion - The level's current version number.
|
|
17
|
+
* @property {number} playerID - The level uploader's player ID.
|
|
18
|
+
* @property {string} difficulty - The level's difficulty.
|
|
19
|
+
* @property {number} stars - The amount of given stars when completing the level.
|
|
20
|
+
* @property {number} downloads - The amount of times the level has been downloaded.
|
|
21
|
+
* @property {number} likes - The amount of likes the level has.
|
|
22
|
+
* @property {boolean} disliked - Whether the level is disliked (i.e. if the likes count is less than 0).
|
|
23
|
+
* @property {string} length - The level's length.
|
|
24
|
+
* @property {boolean} demon - Whether the level is a demon.
|
|
25
|
+
* @property {boolean} featured - Whether the level is featured.
|
|
26
|
+
* @property {boolean} epic - Whether the level is epic-rated.
|
|
27
|
+
* @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.
|
|
28
|
+
* @property {number} objects - The amount of objects the level has (inaccurate because it could be circumvented, and caps at 65,535).
|
|
29
|
+
* @property {number} starsRequested - The amount of stars the uploader requested for this level.
|
|
30
|
+
* @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.
|
|
31
|
+
* @property {number} copiedID - The original level's ID if this level was copied. Returns 0 if the level is original on itself.
|
|
32
|
+
* @property {boolean} large - Whether the level is considered "large" (i.e. has more than 40k objects).
|
|
33
|
+
* @property {boolean} twoPlayer - Whether the level can be played by two people.
|
|
34
|
+
* @property {number} coins - The amount of coins the level has.
|
|
35
|
+
* @property {boolean} verifiedCoins - Whether the coins are verified.
|
|
36
|
+
* @property {string} creator - The level uploader's username.
|
|
37
|
+
* @property {Song} song - The main song used in the level.
|
|
38
|
+
*/
|
|
1
39
|
module.exports = {
|
|
40
|
+
/**
|
|
41
|
+
* Gets a level by its ID. Works considerably faster than dlLevel(), yet lacks the last update/upload date, password, LDM, accurate object count, SFX and additional songs (if any).
|
|
42
|
+
* @param {number} id - The level's ID.
|
|
43
|
+
* @returns {Level}
|
|
44
|
+
*/
|
|
2
45
|
getLevelByID: async function (id) {
|
|
3
46
|
if (isNaN(id)) throw new Error("Please provide a valid level ID!");
|
|
4
47
|
const { gjReq } = require("../gjReq");
|
|
@@ -1,16 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @typedef {Object} LevelScore
|
|
3
|
+
* @property {string} username - 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 {string} color1 - The player's primary color.
|
|
8
|
+
* @property {string} color2 - The player's secondary color.
|
|
9
|
+
* @property {string} iconID - The player's icon ID.
|
|
10
|
+
* @property {string} iconType - The player's selected game mode to be displayed as an icon.
|
|
11
|
+
* @property {string} glow - Whether the player's icon has the "glow" feature enabled.
|
|
12
|
+
* @property {string} percent - The record's percentage.
|
|
13
|
+
* @property {string} coins - The amount of coins collected.
|
|
14
|
+
* @property {string} age - How long ago the record was published.
|
|
15
|
+
*/
|
|
1
16
|
module.exports = {
|
|
2
|
-
|
|
17
|
+
/**
|
|
18
|
+
* Fetches leaderboards from a specified level.
|
|
19
|
+
* @param {number} level - The level to fetch leaderboards from.
|
|
20
|
+
* @param {("week"|"top"|"player")} type - The leaderboard type. Possible types: \"week\", \"top\", \"friends\".
|
|
21
|
+
* @param {string} username - The user's username or player ID. For whatever reason, RobTop made this required, even for simple fetching.
|
|
22
|
+
* @param {string} password - The user's password. For whatever reason, RobTop made this required, even for simple fetching.
|
|
23
|
+
* @returns {LevelScore[]}
|
|
24
|
+
*/
|
|
25
|
+
getLevelScores: async function (level, type, username, password) {
|
|
3
26
|
let types = { week: "2", top: "1", friends: "0" }
|
|
4
|
-
if (!
|
|
27
|
+
if (!level) throw new Error("Please provide a level ID!");
|
|
5
28
|
if (!types[type.toLowerCase()]) throw new Error("Please provide a valid leaderboard type! Possible types: \"week\", \"top\", \"friends\".")
|
|
6
|
-
if (!
|
|
7
|
-
if (!
|
|
29
|
+
if (!username) throw new Error("Please provide a username or a Player ID!");
|
|
30
|
+
if (!password) throw new Error("Please provide a password!");
|
|
8
31
|
|
|
9
32
|
const { gjReq } = require("../gjReq.js");
|
|
10
33
|
const { rgbToHEX } = require("../misc/rgbToHEX");
|
|
11
34
|
const colors = require("../misc/colors.json");
|
|
12
35
|
let search = await gjReq("getGJUsers20", {
|
|
13
|
-
str:
|
|
36
|
+
str: username,
|
|
14
37
|
secret: "Wmfd2893gb7"
|
|
15
38
|
});
|
|
16
39
|
if (search.data == -1) return [];
|
|
@@ -21,8 +44,8 @@ module.exports = {
|
|
|
21
44
|
|
|
22
45
|
const data = {
|
|
23
46
|
accountID: accID,
|
|
24
|
-
gjp: xor.encrypt(
|
|
25
|
-
levelID:
|
|
47
|
+
gjp: xor.encrypt(password, 37526),
|
|
48
|
+
levelID: level,
|
|
26
49
|
secret: "Wmfd2893gb7",
|
|
27
50
|
type: types[type.toLowerCase()]
|
|
28
51
|
}
|
|
@@ -51,8 +74,8 @@ module.exports = {
|
|
|
51
74
|
playerID: Number(s[3]),
|
|
52
75
|
accountID: Number(s[15]),
|
|
53
76
|
rank: Number(s[19]),
|
|
54
|
-
|
|
55
|
-
|
|
77
|
+
color1: rgbToHEX(colors[username[7]]),
|
|
78
|
+
color2: rgbToHEX(colors[username[9]]),
|
|
56
79
|
iconID: Number(s[5]),
|
|
57
80
|
iconType: iconObj[s[11]],
|
|
58
81
|
glow: s[13] == "2" ? true : false,
|
package/functions/getMapPacks.js
CHANGED
|
@@ -1,4 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @typedef {Object} MapPack
|
|
3
|
+
* @property {string} name - The map pack's name.
|
|
4
|
+
* @property {number} id - The map pack's ID.
|
|
5
|
+
* @property {Array<Number>} levels - The list of level IDs in the map pack.
|
|
6
|
+
* @property {Number} stars - The amount of stars received from completing the map pack.
|
|
7
|
+
* @property {number} coins - The amount of secret coins received from completing the map pack.
|
|
8
|
+
* @property {string} difficulty - The map pack's difficulty.
|
|
9
|
+
* @property {string} textColor - The map pack's title color.
|
|
10
|
+
* @property {string} barColor - The map pack's progress bar color.
|
|
11
|
+
*/
|
|
1
12
|
module.exports = {
|
|
13
|
+
/**
|
|
14
|
+
* Gets the map packs from a specified page.
|
|
15
|
+
* @param {number} page - The page to search through. Defaults to 1.
|
|
16
|
+
* @returns {MapPack[]}
|
|
17
|
+
*/
|
|
2
18
|
getMapPacks: async function (page = 1) {
|
|
3
19
|
const { gjReq } = require("../gjReq");
|
|
4
20
|
const data = {
|
package/functions/getMessages.js
CHANGED
|
@@ -1,7 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @typedef {Object} Message
|
|
3
|
+
* @property {string} username - The message sender's username.
|
|
4
|
+
* @property {string} title - The message's title.
|
|
5
|
+
* @property {number} playerID - The message sender's player ID.
|
|
6
|
+
* @property {number} accountID - The message sender's account ID.
|
|
7
|
+
* @property {number} messageID - The message ID.
|
|
8
|
+
* @property {string} age - How long ago the message was sent.
|
|
9
|
+
* @property {boolean} read - Whether the message was already read.
|
|
10
|
+
*/
|
|
1
11
|
module.exports = {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
12
|
+
/**
|
|
13
|
+
* Gets the list of messages received by a user.
|
|
14
|
+
* @param {string} username - The user's username or player ID.
|
|
15
|
+
* @param {string} password - The user's password.
|
|
16
|
+
* @param {number} page - The page to search through. Defaults to 1.
|
|
17
|
+
* @returns {Message[]}
|
|
18
|
+
*/
|
|
19
|
+
getMessages: async function (username, password, page = 1) {
|
|
20
|
+
if (!username) throw new Error("Please provide a player ID or username!");
|
|
21
|
+
if (!password) throw new Error("Please provide a password!");
|
|
5
22
|
if (isNaN(page)) throw new Error("The page should be a number!");
|
|
6
23
|
|
|
7
24
|
const { gjReq } = require("../gjReq");
|
|
@@ -9,7 +26,7 @@ module.exports = {
|
|
|
9
26
|
const xor = new XOR;
|
|
10
27
|
|
|
11
28
|
let search = await gjReq("getGJUsers20", {
|
|
12
|
-
str:
|
|
29
|
+
str: username,
|
|
13
30
|
secret: "Wmfd2893gb7"
|
|
14
31
|
});
|
|
15
32
|
if (search.data == -1) return [];
|
|
@@ -17,7 +34,7 @@ module.exports = {
|
|
|
17
34
|
|
|
18
35
|
let res = await gjReq("getGJMessages20", {
|
|
19
36
|
accountID: accID,
|
|
20
|
-
gjp: xor.encrypt(
|
|
37
|
+
gjp: xor.encrypt(password, 37526),
|
|
21
38
|
secret: "Wmfd2893gb7",
|
|
22
39
|
page: page - 1
|
|
23
40
|
});
|
|
@@ -1,11 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @typedef {Object} Song
|
|
3
|
+
* @property {string} name - The song's name.
|
|
4
|
+
* @property {string} id - The ID of the level the song is used in (e.g. "Level 1").
|
|
5
|
+
* @property {string} artist - The song artist.
|
|
6
|
+
* @property {string} link - The link to listen to the song.
|
|
7
|
+
*/
|
|
1
8
|
module.exports = {
|
|
9
|
+
/**
|
|
10
|
+
* Gets song info about an official song.
|
|
11
|
+
* @param {number} song - The song ID.
|
|
12
|
+
* @returns {Song}
|
|
13
|
+
*/
|
|
2
14
|
getOfficialSongInfo: function (song) {
|
|
3
15
|
if (isNaN(song)) throw new Error("Please provide a valid official song ID.");
|
|
4
|
-
const
|
|
5
|
-
const jsons = { 1: sm, 2: bot, 3: pg, 4: dout, 5: bab, 6: clg, 7: j, 8: tm, 9: c, 10: xs, 11: cf, 12: toe, 13: ea, 14: cs, 15: ed, 16: hf, 17: bp, 18: toeii, 19: gd, 20: d, 21: fd, 22: dash, 23: exp, 24: tss, 25: va, 26: ar, 27: tc, 28: p, 29: bm, 30: m, 31: y, 32: f, 33: sp, 34: s, 35: e, 36: round, 37: mdo, 38: ps, 39: ne, 40: pt };
|
|
16
|
+
const officialSongs = require("../misc/officialsongs.json");
|
|
6
17
|
|
|
7
|
-
let result =
|
|
8
|
-
if (!result) result =
|
|
18
|
+
let result = officialSongs[Number(song)];
|
|
19
|
+
if (!result) result = officialSongs["-1"];
|
|
9
20
|
return result;
|
|
10
21
|
}
|
|
11
22
|
}
|
package/functions/getProfile.js
CHANGED
|
@@ -1,4 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @typedef {Object} Player
|
|
3
|
+
* @property {string} username - 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 position on the global 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
|
+
* @property {string} color1 - The HEX code of the player's primary color.
|
|
15
|
+
* @property {string} color2 - The HEX code of the player's secondary color.
|
|
16
|
+
* @property {number} cubeID - The ID of the currently selected cube icon.
|
|
17
|
+
* @property {number} shipID - The ID of the currently selected ship icon.
|
|
18
|
+
* @property {number} ballID - The ID of the currently selected ball icon.
|
|
19
|
+
* @property {number} ufoID - The ID of the currently selected UFO icon.
|
|
20
|
+
* @property {number} waveID - The ID of the currently selected wave icon.
|
|
21
|
+
* @property {number} robotID - The ID of the currently selected robot icon.
|
|
22
|
+
* @property {number} spiderID - The ID of the currently selected spider icon.
|
|
23
|
+
* @property {number} swingID - The ID of the currently selected swing icon.
|
|
24
|
+
* @property {number} jetpackID - The ID of the currently selected jetpack icon.
|
|
25
|
+
* @property {number} explosionID - The ID of the currently selected explosion animation.
|
|
26
|
+
* @property {boolean} glow - Whether the player's icon has the "glow" feature enabled.
|
|
27
|
+
* @property {string} messages - The current state of messaging the player. Returns "all" if anyone can message the person, "friends" if it's limited to friends, and "none" if no one can.
|
|
28
|
+
* @property {boolean} friendRequests - Whether the player has allowed to receive friend requests.
|
|
29
|
+
* @property {string} commentHistory - The current state of viewing the player's comment history. Returns "all" if anyone can do it, "friends" if it's limited to friends, and "none" if only the player can.
|
|
30
|
+
* @property {string|null} mod - Whether the player is a moderator. Returns `null` if not, "mod" if the user is a regular moderator and "elder" if the user is an elder moderator.
|
|
31
|
+
* @property {string} youtube - The player's YouTube channel ID, used in this template: `https://youtube.com/channel/((youtube))`.
|
|
32
|
+
* @property {string} twitter - The player's X (formerly Twitter) username, used in this template: `https://x.com/((twitter))`.
|
|
33
|
+
* @property {string} twitch - The player's Twitch username, used in this template: `https://twitch.tv/((twitch))`.
|
|
34
|
+
*/
|
|
35
|
+
|
|
1
36
|
module.exports = {
|
|
37
|
+
/**
|
|
38
|
+
* Fetches the profile of a specified user.
|
|
39
|
+
* @param {string} name - The search query (user, account ID or player ID).
|
|
40
|
+
* @param {("name"|"accountid"|"playerid")} mode - The search mode, defaults to "auto". If "auto" is selected, the search is first attempted by matching the matching the username, then account ID and then player ID.
|
|
41
|
+
* @returns {Player}
|
|
42
|
+
*/
|
|
2
43
|
getProfile: async function (name, mode = "auto") {
|
|
3
44
|
const { gjReq } = require("../gjReq");
|
|
4
45
|
const { rgbToHEX } = require("../misc/rgbToHEX");
|
|
@@ -46,12 +87,12 @@ module.exports = {
|
|
|
46
87
|
}
|
|
47
88
|
|
|
48
89
|
let friendReqsObj = {
|
|
49
|
-
0:
|
|
50
|
-
1:
|
|
90
|
+
0: true,
|
|
91
|
+
1: false
|
|
51
92
|
}
|
|
52
93
|
|
|
53
94
|
let modObj = {
|
|
54
|
-
0:
|
|
95
|
+
0: null,
|
|
55
96
|
1: "mod",
|
|
56
97
|
2: "elder"
|
|
57
98
|
}
|
|
@@ -68,8 +109,8 @@ module.exports = {
|
|
|
68
109
|
demons: demons,
|
|
69
110
|
moons: moons,
|
|
70
111
|
creatorPoints: cp,
|
|
71
|
-
|
|
72
|
-
|
|
112
|
+
color1: rgbToHEX(colors[c1]),
|
|
113
|
+
color2: rgbToHEX(colors[c2]),
|
|
73
114
|
cubeID: cube,
|
|
74
115
|
shipID: ship,
|
|
75
116
|
ballID: ball,
|
|
@@ -119,8 +160,6 @@ module.exports = {
|
|
|
119
160
|
return decodeUser(accArray);
|
|
120
161
|
}
|
|
121
162
|
|
|
122
|
-
let result;
|
|
123
|
-
|
|
124
163
|
if (mode == "accountid") {
|
|
125
164
|
const user = await new Promise((resolve) => {
|
|
126
165
|
accIDSearch().then(u => resolve(u));
|
package/functions/getSongInfo.js
CHANGED
|
@@ -1,4 +1,19 @@
|
|
|
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
|
+
|
|
1
11
|
module.exports = {
|
|
12
|
+
/**
|
|
13
|
+
* Searches for a song on Newgrounds or in the internal Geometry Dash song library.
|
|
14
|
+
* @param {number} song - The song ID.
|
|
15
|
+
* @returns {Song}
|
|
16
|
+
*/
|
|
2
17
|
getSongInfo: async function (song) {
|
|
3
18
|
if (isNaN(song)) throw new Error("Please provide a valid song ID.");
|
|
4
19
|
const { gjReq } = require("../gjReq");
|
|
@@ -16,12 +31,12 @@ module.exports = {
|
|
|
16
31
|
if (link == "CUSTOMURL") link = `https://geometrydashfiles.b-cdn.net/music/${song.toString().trim()}.ogg`;
|
|
17
32
|
|
|
18
33
|
const result = {
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
34
|
+
name: rawSong[3],
|
|
35
|
+
id: Number(rawSong[1]),
|
|
36
|
+
artist: rawSong[7],
|
|
37
|
+
artistId: Number(rawSong[5]),
|
|
38
|
+
fileSize: Number(rawSong[9]),
|
|
39
|
+
link: link
|
|
25
40
|
}
|
|
26
41
|
|
|
27
42
|
return result;
|
|
@@ -1,4 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @typedef {Object} Artist
|
|
3
|
+
* @property {number} id - The artist's ID.
|
|
4
|
+
* @property {string} name - The artist's name.
|
|
5
|
+
* @property {string} website - The artist's website.
|
|
6
|
+
* @property {string} youtube - The artist's YouTube channel ID.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* @typedef {Object} Song
|
|
11
|
+
* @property {number} id - The song ID.
|
|
12
|
+
* @property {string} name - The song name.
|
|
13
|
+
* @property {Artist} artist - The song artist.
|
|
14
|
+
* @property {number} size - The song file size in megabytes.
|
|
15
|
+
* @property {number} duration - The song duration in seconds.
|
|
16
|
+
* @property {Array<String>} genres - The song genres.
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* @typedef {Object} Library
|
|
21
|
+
* @property {number} version - The songs library's version.
|
|
22
|
+
* @property {Array<Song>} songs - The songs included in the internal Geometry Dash song library.
|
|
23
|
+
*/
|
|
24
|
+
|
|
1
25
|
module.exports = {
|
|
26
|
+
/**
|
|
27
|
+
* Gets the list of songs from the internal Geometry Dash song library.
|
|
28
|
+
* @returns {Library}
|
|
29
|
+
*/
|
|
2
30
|
getSongsLibrary: async function () {
|
|
3
31
|
const zlib = require("zlib");
|
|
4
32
|
const fetch = require("node-fetch");
|
|
@@ -34,7 +62,7 @@ module.exports = {
|
|
|
34
62
|
rawArtists.pop();
|
|
35
63
|
rawArtists.forEach(artist => {
|
|
36
64
|
let obj = {};
|
|
37
|
-
obj.id = artist.split(",")[0];
|
|
65
|
+
obj.id = Number(artist.split(",")[0]);
|
|
38
66
|
obj.name = artist.split(",")[1];
|
|
39
67
|
if (artist.split(",")[2].trim() != "") obj.website = decodeURIComponent(artist.split(",")[2]);
|
|
40
68
|
if (artist.split(",")[3].trim() != "") obj.youtube = artist.split(",")[3];
|
|
@@ -55,10 +83,9 @@ module.exports = {
|
|
|
55
83
|
|
|
56
84
|
let size = song.split(",")[3];
|
|
57
85
|
size = size / 1048576;
|
|
58
|
-
size = size.toFixed(1);
|
|
59
|
-
obj.size = `${size} MB`;
|
|
86
|
+
obj.size = size.toFixed(1);
|
|
60
87
|
|
|
61
|
-
obj.duration =
|
|
88
|
+
obj.duration = Number(song.split(",")[4]);
|
|
62
89
|
|
|
63
90
|
let songGenres = [];
|
|
64
91
|
let rawSongGenres = song.split(",")[5].split(".");
|
package/functions/getTab.js
CHANGED
|
@@ -1,7 +1,14 @@
|
|
|
1
1
|
module.exports = {
|
|
2
|
+
/**
|
|
3
|
+
* Fetches levels from a specified tab.
|
|
4
|
+
* @param {("trending"|"recent"|"featured"|"magic"|"awarded"|"sent")} tab - The tab to fetch.
|
|
5
|
+
* @param {number} page - The page to search through. Defaults to 1.
|
|
6
|
+
* @returns {import("./getLevelByID").Level[]}
|
|
7
|
+
*/
|
|
2
8
|
getTab: async function (tab, page = 1) {
|
|
3
9
|
let tabs = { trending: 3, recent: 4, featured: 6, magic: 7, awarded: 11, sent: 27 }
|
|
4
10
|
if (!tabs[tab.toLowerCase()]) throw new Error('Please provide a valid tab! Possible tabs: "trending", "recent", "featured", "magic", "awarded", "sent".');
|
|
11
|
+
|
|
5
12
|
const { gjReq } = require("../gjReq");
|
|
6
13
|
let GJDecode = require("../misc/GJDecode");
|
|
7
14
|
const { decodeSearchResults } = new GJDecode;
|
|
@@ -11,6 +18,7 @@ module.exports = {
|
|
|
11
18
|
secret: "Wmfd2893gb7"
|
|
12
19
|
});
|
|
13
20
|
if (res.data == -1) return [];
|
|
21
|
+
|
|
14
22
|
return decodeSearchResults(res.data);
|
|
15
23
|
}
|
|
16
24
|
}
|
package/functions/getTop100.js
CHANGED
|
@@ -1,4 +1,8 @@
|
|
|
1
1
|
module.exports = {
|
|
2
|
+
/**
|
|
3
|
+
* Fetches the player leaderboard based on the amount of stars.
|
|
4
|
+
* @returns {import("./getCreatorScores").ScoresUser[]}
|
|
5
|
+
*/
|
|
2
6
|
getTop100: async function () {
|
|
3
7
|
let GJDecode = require("../misc/GJDecode");
|
|
4
8
|
const { decodeScoresUser } = new GJDecode;
|
package/functions/getTopLists.js
CHANGED
|
@@ -1,4 +1,9 @@
|
|
|
1
1
|
module.exports = {
|
|
2
|
+
/**
|
|
3
|
+
* Fetches the list of top lists.
|
|
4
|
+
* @param {number} page - The page to search through. Defaults to 1.
|
|
5
|
+
* @returns {import("./searchLists").List[]}
|
|
6
|
+
*/
|
|
2
7
|
getTopLists: async function (page = 1) {
|
|
3
8
|
const { gjReq } = require("../gjReq");
|
|
4
9
|
const GJDecode = require("../misc/GJDecode");
|
|
@@ -1,14 +1,20 @@
|
|
|
1
1
|
module.exports = {
|
|
2
|
-
|
|
3
|
-
|
|
2
|
+
/**
|
|
3
|
+
* Fetches levels by a user.
|
|
4
|
+
* @param {string} username - The search query (username or player ID).
|
|
5
|
+
* @param {number} page - The page to search through. Defaults to 1.
|
|
6
|
+
* @returns {import("./getLevelByID").Level[]}
|
|
7
|
+
*/
|
|
8
|
+
getUserLevels: async function (username, page = 1) {
|
|
9
|
+
if (!username) throw new Error("Please provide a username or player ID!");
|
|
4
10
|
|
|
5
11
|
const { gjReq } = require("../gjReq.js");
|
|
6
12
|
let GJDecode = require("../misc/GJDecode.js");
|
|
7
13
|
const { decodeSearchResults } = new GJDecode;
|
|
8
|
-
let playerID=
|
|
9
|
-
if (isNaN(
|
|
14
|
+
let playerID=username;
|
|
15
|
+
if (isNaN(username)) {
|
|
10
16
|
let search = await gjReq("getGJUsers20", {
|
|
11
|
-
str:
|
|
17
|
+
str: username,
|
|
12
18
|
secret: "Wmfd2893gb7"
|
|
13
19
|
});
|
|
14
20
|
if (search.data == -1) return [];
|
package/functions/reportLevel.js
CHANGED
|
@@ -1,4 +1,9 @@
|
|
|
1
1
|
module.exports = {
|
|
2
|
+
/**
|
|
3
|
+
* Reports a level.
|
|
4
|
+
* @param {number} level - The level ID.
|
|
5
|
+
* @returns {1} - Always returns 1, regardless of whether the level was reported or not.
|
|
6
|
+
*/
|
|
2
7
|
reportLevel: async function (level) {
|
|
3
8
|
if (isNaN(level)) throw new Error("Please provide a valid level ID.");
|
|
4
9
|
const { gjReq } = require("../gjReq");
|
|
@@ -1,4 +1,10 @@
|
|
|
1
1
|
module.exports = {
|
|
2
|
+
/**
|
|
3
|
+
* Searches for levels.
|
|
4
|
+
* @param {string} query - The search query.
|
|
5
|
+
* @param {number} page - The page to search through. Defaults to 1.
|
|
6
|
+
* @returns {import("./getLevelByID").Level[]}
|
|
7
|
+
*/
|
|
2
8
|
searchLevels: async function (query, page = 1) {
|
|
3
9
|
const { gjReq } = require("../gjReq");
|
|
4
10
|
let GJDecode = require("../misc/GJDecode");
|
package/functions/searchLists.js
CHANGED
|
@@ -1,4 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @typedef {Object} List
|
|
3
|
+
* @property {number} id - The list ID.
|
|
4
|
+
* @property {string} name - The list name.
|
|
5
|
+
* @property {string} description - The list's description.
|
|
6
|
+
* @property {string} difficulty - The list's difficulty.
|
|
7
|
+
* @property {string} username - The list uploader's username.
|
|
8
|
+
* @property {number} playerID - The list uploader's player ID.
|
|
9
|
+
* @property {number} accountID - The list uploader's account ID.
|
|
10
|
+
* @property {string} downloads - The amount of times the list has been downloaded.
|
|
11
|
+
* @property {number} likes - The amount of likes the list has.
|
|
12
|
+
* @property {number} diamonds - The amount of diamonds given when completing the list.
|
|
13
|
+
* @property {boolean} disliked - Whether the list is disliked (i.e. if the likes count is less than 0).
|
|
14
|
+
* @property {Array<Number>} levels - The array of level IDs in the list.
|
|
15
|
+
* @property {number} required - The amount of completed levels required to get the reward.
|
|
16
|
+
* @property {number} uploadedUnix - The UNIX timestamp of the list's upload date.
|
|
17
|
+
*/
|
|
18
|
+
|
|
1
19
|
module.exports = {
|
|
20
|
+
/**
|
|
21
|
+
* Searches for lists.
|
|
22
|
+
* @param {string} query - The search query.
|
|
23
|
+
* @param {number} page - The page to search through. Defaults to 1.
|
|
24
|
+
* @returns {List[]}
|
|
25
|
+
*/
|
|
2
26
|
searchLists: async function (query, page = 1) {
|
|
3
27
|
const { gjReq } = require("../gjReq");
|
|
4
28
|
const GJDecode = require("../misc/GJDecode");
|
package/functions/unblockUser.js
CHANGED
|
@@ -1,4 +1,11 @@
|
|
|
1
1
|
module.exports = {
|
|
2
|
+
/**
|
|
3
|
+
* Unblocks a specified user.
|
|
4
|
+
* @param {string} target - The player that needs to be unblocked.
|
|
5
|
+
* @param {string} username - The unblocking person's username or player ID.
|
|
6
|
+
* @param {string} password - The unblocking person's password.
|
|
7
|
+
* @returns {number} Returns 1 if everything's OK, and -1 if something went wrong.
|
|
8
|
+
*/
|
|
2
9
|
unblockUser: 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,7 +37,6 @@ module.exports = {
|
|
|
30
37
|
}
|
|
31
38
|
|
|
32
39
|
let res = await gjReq("unblockGJUser20", data);
|
|
33
|
-
if (res.data == -1) throw new Error(-1);
|
|
34
40
|
|
|
35
41
|
return res.data;
|
|
36
42
|
}
|
|
@@ -1,7 +1,15 @@
|
|
|
1
1
|
module.exports = {
|
|
2
|
-
|
|
2
|
+
/**
|
|
3
|
+
* Updates the description on a level.
|
|
4
|
+
* @param {number} level - The level ID.
|
|
5
|
+
* @param {string} desc - The new description.
|
|
6
|
+
* @param {string} username - The level uploader's username or player ID.
|
|
7
|
+
* @param {string} password - The level uploader's password.
|
|
8
|
+
* @returns {number} Returns 1 if everything's OK, and -1 if something went wrong.
|
|
9
|
+
*/
|
|
10
|
+
updateLevelDesc: async function (level, desc, username, password) {
|
|
3
11
|
if (isNaN(level)) throw new Error("Please provide a valid level ID!");
|
|
4
|
-
if (!
|
|
12
|
+
if (!username) throw new Error("Please provide a player ID or username!");
|
|
5
13
|
if (!password) throw new Error("Please provide a password!");
|
|
6
14
|
|
|
7
15
|
const { gjReq } = require("../gjReq");
|
|
@@ -9,7 +17,7 @@ module.exports = {
|
|
|
9
17
|
const xor = new XOR;
|
|
10
18
|
|
|
11
19
|
let search = await gjReq("getGJUsers20", {
|
|
12
|
-
str:
|
|
20
|
+
str: username,
|
|
13
21
|
secret: "Wmfd2893gb7"
|
|
14
22
|
});
|
|
15
23
|
if (search.data == -1) throw new Error(-1);
|
|
@@ -22,7 +30,6 @@ module.exports = {
|
|
|
22
30
|
levelDesc: Buffer.from(desc).toString("base64"),
|
|
23
31
|
secret: "Wmfd2893gb7"
|
|
24
32
|
});
|
|
25
|
-
if (res.data == -1) throw new Error("-1: Failed to update the description.");
|
|
26
33
|
|
|
27
34
|
return res.data;
|
|
28
35
|
}
|
|
@@ -1,7 +1,14 @@
|
|
|
1
1
|
module.exports = {
|
|
2
|
-
|
|
2
|
+
/**
|
|
3
|
+
* Uploads a post to an account.
|
|
4
|
+
* @param {string} content - The account post content.
|
|
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
|
+
uploadAccountPost: async function (content, username, password) {
|
|
3
10
|
if (!content) throw new Error("Please provide an account post content!");
|
|
4
|
-
if (!
|
|
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:
|
|
19
|
+
str: username,
|
|
13
20
|
secret: "Wmfd2893gb7"
|
|
14
21
|
});
|
|
15
22
|
if (search.data == -1) throw new Error(-1);
|
|
@@ -1,8 +1,17 @@
|
|
|
1
1
|
module.exports = {
|
|
2
|
-
|
|
2
|
+
/**
|
|
3
|
+
* Posts a comment on a level.
|
|
4
|
+
* @param {string} comment - The comment content.
|
|
5
|
+
* @param {number} level - The level ID.
|
|
6
|
+
* @param {string} username - The commenter's username or player ID.
|
|
7
|
+
* @param {string} password - The commenter's password.
|
|
8
|
+
* @param {number} percent - The achieved level percentage to be displayed on the comment.
|
|
9
|
+
* @returns {number} Returns 1 if everything's OK, and -1 if something went wrong.
|
|
10
|
+
*/
|
|
11
|
+
uploadComment: async function (comment, level, username, password, percent = 0) {
|
|
3
12
|
if (!comment) throw new Error("Please provide a comment!");
|
|
4
|
-
if (!
|
|
5
|
-
if (!
|
|
13
|
+
if (!level) throw new Error("Please provide a level ID!");
|
|
14
|
+
if (!username) throw new Error("Please provide a username or a player ID!");
|
|
6
15
|
if (!password) throw new Error("Please provide a password!");
|
|
7
16
|
if (Number(percent) > 100) throw new Error("The percentage cannot be more than 100!");
|
|
8
17
|
|
|
@@ -12,25 +21,25 @@ module.exports = {
|
|
|
12
21
|
function sha1(data) { return crypto.createHash("sha1").update(data, "binary").digest("hex"); }
|
|
13
22
|
|
|
14
23
|
let search = await gjReq("getGJUsers20", {
|
|
15
|
-
str:
|
|
24
|
+
str: username,
|
|
16
25
|
secret: "Wmfd2893gb7"
|
|
17
26
|
});
|
|
18
27
|
if (search.data == -1) throw new Error(-1);
|
|
19
|
-
let
|
|
28
|
+
let name = search.data.split(":")[1];
|
|
20
29
|
let accID = search.data.split(":")[21];
|
|
21
30
|
|
|
22
31
|
const XOR = require("../xor.js");
|
|
23
32
|
const xor = new XOR;
|
|
24
33
|
|
|
25
|
-
let chkStr =
|
|
34
|
+
let chkStr = name.toLowerCase() + Buffer.from(comment).toString("base64") + level + percent + "0xPT6iUrtws0J";
|
|
26
35
|
let chk = xor.encrypt(sha1(chkStr), 29481);
|
|
27
36
|
|
|
28
37
|
let res = await gjReq("uploadGJComment21", {
|
|
29
38
|
accountID: accID,
|
|
30
39
|
gjp: xor.encrypt(password, 37526),
|
|
31
|
-
userName:
|
|
40
|
+
userName: name.toLowerCase(),
|
|
32
41
|
comment: Buffer.from(comment).toString("base64"),
|
|
33
|
-
levelID:
|
|
42
|
+
levelID: level,
|
|
34
43
|
percent: percent,
|
|
35
44
|
chk: chk,
|
|
36
45
|
secret: "Wmfd2893gb7"
|