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.
- package/LICENSE +1 -1
- package/README.md +5 -5
- package/functions/acceptFriendRequest.js +32 -0
- package/functions/blockUser.js +14 -22
- package/functions/deleteAccountPost.js +13 -16
- package/functions/deleteComment.js +11 -16
- package/functions/deleteFriendRequest.js +36 -0
- package/functions/deleteLevel.js +11 -17
- package/functions/deleteMessage.js +33 -0
- package/functions/{dlLevel.js → downloadLevel.js} +47 -43
- package/functions/{dlMessage.js → downloadMessage.js} +10 -13
- package/functions/getAccountPosts.js +4 -9
- package/functions/getBlockedList.js +32 -17
- package/functions/getCommentHistory.js +8 -7
- package/functions/getComments.js +12 -9
- package/functions/getCreatorScores.js +13 -5
- package/functions/getDailyLevel.js +3 -3
- package/functions/getFriendRequests.js +83 -0
- package/functions/getFriendsList.js +26 -16
- package/functions/getGauntlets.js +5 -3
- package/functions/getLevelByID.js +2 -3
- package/functions/getLevelScores.js +23 -26
- package/functions/getMapPacks.js +2 -6
- package/functions/getMessages.js +11 -15
- package/functions/getProfile.js +146 -57
- package/functions/getSongInfo.js +4 -9
- package/functions/getSongsLibrary.js +14 -3
- package/functions/getTab.js +3 -4
- package/functions/getTop100.js +3 -6
- package/functions/getTopLists.js +1 -2
- package/functions/getUserLevels.js +4 -8
- package/functions/getWeeklyDemon.js +3 -3
- package/functions/removeFriend.js +33 -0
- package/functions/reportLevel.js +3 -6
- package/functions/searchLevels.js +2 -3
- package/functions/searchLists.js +2 -3
- package/functions/unblockUser.js +17 -27
- package/functions/updateAccountSettings.js +75 -0
- package/functions/updateLevelDesc.js +11 -16
- package/functions/uploadAccountPost.js +11 -16
- package/functions/uploadComment.js +15 -19
- package/functions/uploadFriendRequest.js +35 -0
- package/functions/uploadMessage.js +18 -25
- package/index.js +30 -3
- package/misc/GJDecode.js +12 -9
- package/misc/gauntlets.json +14 -1
- package/misc/gjReq.js +33 -0
- package/misc/gjp2.js +5 -0
- package/package.json +2 -5
- package/gjReq.js +0 -18
- /package/{xor.js → misc/xor.js} +0 -0
package/LICENSE
CHANGED
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
|
|
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.
|
|
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
|
|
40
|
+
// This code makes shikoshib send a message to RobTop
|
|
41
41
|
const gd = require("gj-boomlings-api");
|
|
42
|
-
gd.uploadMessage("
|
|
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
|
+
}
|
package/functions/blockUser.js
CHANGED
|
@@ -1,39 +1,31 @@
|
|
|
1
1
|
module.exports = {
|
|
2
2
|
/**
|
|
3
3
|
* Blocks a specified user.
|
|
4
|
-
* @param {string} target - The player
|
|
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,
|
|
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
|
|
11
|
-
if (!username) throw new Error("Please provide
|
|
12
|
-
if (!password) throw new Error("Please provide
|
|
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
|
|
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
|
-
|
|
20
|
-
|
|
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
|
-
|
|
27
|
-
|
|
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
|
-
|
|
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,
|
|
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
|
|
11
|
-
if (!username) throw new Error("Please provide
|
|
12
|
-
if (!password) throw new Error("Please provide
|
|
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
|
|
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
|
-
|
|
20
|
-
|
|
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
|
-
|
|
28
|
-
|
|
29
|
-
|
|
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,
|
|
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
|
|
13
|
-
if (!level) throw new Error("Please provide
|
|
14
|
-
if (!username) throw new Error("Please provide
|
|
15
|
-
if (!password) throw new Error("Please provide
|
|
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
|
|
18
|
-
|
|
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
|
-
|
|
26
|
-
|
|
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
|
-
|
|
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
|
+
}
|
package/functions/deleteLevel.js
CHANGED
|
@@ -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,
|
|
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
|
|
12
|
-
if (!password) throw new Error("Please provide
|
|
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
|
|
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
|
-
|
|
20
|
-
|
|
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
|
|
21
|
+
let res = await gjReq("deleteGJLevelUser20", {
|
|
26
22
|
accountID: accID,
|
|
27
23
|
secret: "Wmfv2898gc9",
|
|
28
24
|
levelID: level,
|
|
29
|
-
|
|
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
|
-
|
|
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",
|
|
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
|
|
93
|
-
let
|
|
94
|
-
let
|
|
95
|
-
let
|
|
96
|
-
let
|
|
97
|
-
let
|
|
98
|
-
|
|
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 >
|
|
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[
|
|
205
|
+
if (s[73] && s[72] != "41") {
|
|
204
206
|
let songsIDArray = [];
|
|
205
207
|
let sfxIDArray = [];
|
|
206
|
-
for (let songID of s[
|
|
208
|
+
for (let songID of s[73].split(",")) { // 52:
|
|
207
209
|
if (songID == NGSongID) continue;
|
|
208
210
|
songsIDArray.push(Number(songID));
|
|
209
211
|
}
|
|
210
|
-
|
|
211
|
-
|
|
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
|
-
|
|
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
|
|
23
|
-
if (!password) throw new Error("Please provide
|
|
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
|
|
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
|
-
|
|
31
|
-
|
|
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
|
-
|
|
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
|
-
|
|
22
|
-
|
|
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
|
|
19
|
-
if (!password) throw new Error("Please provide
|
|
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
|
|
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
|
-
|
|
27
|
-
|
|
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
|
-
|
|
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
|
-
|
|
48
|
-
|
|
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
|
|
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
|
|