gj-boomlings-api 1.0.0 → 1.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.
- package/README.md +1 -0
- package/docs/dlLevel.md +4 -4
- package/docs/objects/level.md +9 -9
- package/functions/blockUser.js +16 -14
- package/functions/deleteAccountPost.js +1 -2
- package/functions/dlLevel.js +100 -180
- package/functions/getAccountPosts.js +7 -9
- package/functions/getCommentHistory.js +6 -9
- package/functions/getComments.js +3 -4
- package/functions/getGauntlets.js +2 -3
- package/functions/getLevelByID.js +3 -4
- package/functions/getMapPacks.js +3 -3
- package/functions/getSongInfo.js +13 -13
- package/functions/reportLevel.js +2 -5
- package/functions/updateLevelDesc.js +6 -9
- package/functions/uploadAccountPost.js +4 -4
- package/functions/uploadComment.js +3 -1
- package/index.js +4 -1
- package/misc/decodeLevel.js +0 -2
- package/misc/decodeMapPack.js +32 -20
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
<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>
|
|
4
4
|
<a href="https://www.npmjs.com/package/gj-boomlings-api"><img src="https://img.shields.io/npm/dt/gj-boomlings-api.svg?maxAge=3600" alt="npm downloads" /></a>
|
|
5
5
|
<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>
|
|
6
|
+
<a href="https://packagequality.com/#?package=gj-boomlings-api"><img src="https://packagequality.com/shield/gj-boomlings-api.svg"/></a>
|
|
6
7
|
</div>
|
|
7
8
|
|
|
8
9
|
This package gets info from RobTop's servers (boomlings.com) and converts it into pure and beautiful JSON.
|
package/docs/dlLevel.md
CHANGED
|
@@ -21,8 +21,8 @@ gd.dlLevel(58825144).then(console.log);
|
|
|
21
21
|
level_version: 2,
|
|
22
22
|
difficulty: 'Extreme Demon',
|
|
23
23
|
stars: 10,
|
|
24
|
-
downloads:
|
|
25
|
-
likes:
|
|
24
|
+
downloads: 2640560,
|
|
25
|
+
likes: 107918,
|
|
26
26
|
disliked: false,
|
|
27
27
|
length: 'XL',
|
|
28
28
|
password: '000007',
|
|
@@ -30,8 +30,8 @@ gd.dlLevel(58825144).then(console.log);
|
|
|
30
30
|
featured: false,
|
|
31
31
|
epic: false,
|
|
32
32
|
objects: 37838,
|
|
33
|
-
uploaded: '
|
|
34
|
-
updated: '
|
|
33
|
+
uploaded: '3 years',
|
|
34
|
+
updated: '3 years',
|
|
35
35
|
stars_requested: 10,
|
|
36
36
|
game_version: '2.1',
|
|
37
37
|
ldm: false,
|
package/docs/objects/level.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Level object
|
|
2
2
|
|
|
3
|
-
Used by
|
|
3
|
+
Used by `dlLevel()`, `getLevelByID()` and `getUserLevels()`.
|
|
4
4
|
|
|
5
5
|
## Example
|
|
6
6
|
```
|
|
@@ -12,8 +12,8 @@ Used by ```dlLevel()```.
|
|
|
12
12
|
level_version: 2,
|
|
13
13
|
difficulty: 'Extreme Demon',
|
|
14
14
|
stars: 10,
|
|
15
|
-
downloads:
|
|
16
|
-
likes:
|
|
15
|
+
downloads: 2640560,
|
|
16
|
+
likes: 107918,
|
|
17
17
|
disliked: false,
|
|
18
18
|
length: 'XL',
|
|
19
19
|
password: '000007',
|
|
@@ -21,8 +21,8 @@ Used by ```dlLevel()```.
|
|
|
21
21
|
featured: false,
|
|
22
22
|
epic: false,
|
|
23
23
|
objects: 37838,
|
|
24
|
-
uploaded: '
|
|
25
|
-
updated: '
|
|
24
|
+
uploaded: '3 years',
|
|
25
|
+
updated: '3 years',
|
|
26
26
|
stars_requested: 10,
|
|
27
27
|
game_version: '2.1',
|
|
28
28
|
ldm: false,
|
|
@@ -60,11 +60,11 @@ Used by ```dlLevel()```.
|
|
|
60
60
|
|
|
61
61
|
```likes``` - the amount of level likes.
|
|
62
62
|
|
|
63
|
-
```disliked``` - a boolean that shows if the level is disliked. Returns
|
|
63
|
+
```disliked``` - a boolean that shows if the level is disliked. Returns `true` if the like amount is negative, otherwise it's `false`.
|
|
64
64
|
|
|
65
65
|
```length``` - the level length.
|
|
66
66
|
|
|
67
|
-
```password``` - the level password. It may return
|
|
67
|
+
```password``` - the level password. It may return `''` (an empty string) if the level is not copyable, or `'1'` if the level is free to copy.
|
|
68
68
|
|
|
69
69
|
```demon``` - a boolean that shows if the level is demon.
|
|
70
70
|
|
|
@@ -78,13 +78,13 @@ Used by ```dlLevel()```.
|
|
|
78
78
|
|
|
79
79
|
```updated``` - when the level has been last updated.
|
|
80
80
|
|
|
81
|
-
```stars_requested``` - basically how many stars the creator has requested. Returns
|
|
81
|
+
```stars_requested``` - basically how many stars the creator has requested. Returns`0` if no stars have been requested.
|
|
82
82
|
|
|
83
83
|
```game_version``` - the version required to play the level. Returns `Pre-1.7` if the level has been uploaded or last updated earlier, than 1.7 came out.
|
|
84
84
|
|
|
85
85
|
```ldm``` - a boolean that shows if the level has a "Low Detail Mode" checkbox.
|
|
86
86
|
|
|
87
|
-
```copied``` - the original level ID, that got copied. Returns
|
|
87
|
+
```copied``` - the original level ID, that got copied. Returns `0` if the level is already original.
|
|
88
88
|
|
|
89
89
|
```two_p``` - a boolean that shows if the level is in the 2-player mode.
|
|
90
90
|
|
package/functions/blockUser.js
CHANGED
|
@@ -6,14 +6,6 @@ module.exports = {
|
|
|
6
6
|
if(!password || password == "") throw new Error("Please provide your password!");
|
|
7
7
|
const axios = require("axios");
|
|
8
8
|
const {headers, server} = require("../config.json");
|
|
9
|
-
|
|
10
|
-
const userData = {
|
|
11
|
-
gameVersion: 21,
|
|
12
|
-
binaryVersion: 35,
|
|
13
|
-
gdw: 0,
|
|
14
|
-
str: target,
|
|
15
|
-
secret: "Wmfd2893gb7"
|
|
16
|
-
}
|
|
17
9
|
|
|
18
10
|
let resp = await axios.post(server + "getGJUsers20.php", {
|
|
19
11
|
gameVersion: 21,
|
|
@@ -23,17 +15,27 @@ module.exports = {
|
|
|
23
15
|
secret: "Wmfd2893gb7"
|
|
24
16
|
}, {
|
|
25
17
|
headers: headers
|
|
18
|
+
}).catch(e => {
|
|
19
|
+
if(e.response.data == -1) throw new Error(`Couldn't find a "${username}" user.`)
|
|
20
|
+
throw new Error(e.response.data)
|
|
26
21
|
})
|
|
27
|
-
|
|
28
|
-
if(resp.data.toLowerCase() == "error code: 1020") throw new Error("1020 error: Request denied.");
|
|
22
|
+
|
|
29
23
|
let accID = resp.data.split(":16:")[1].split(":3:")[0];
|
|
30
24
|
|
|
25
|
+
const userData = {
|
|
26
|
+
gameVersion: 21,
|
|
27
|
+
binaryVersion: 35,
|
|
28
|
+
gdw: 0,
|
|
29
|
+
str: target,
|
|
30
|
+
secret: "Wmfd2893gb7"
|
|
31
|
+
}
|
|
31
32
|
|
|
32
33
|
let r = await axios.post(server + "getGJUsers20.php", userData, {
|
|
33
34
|
headers: headers
|
|
35
|
+
}).catch(e => {
|
|
36
|
+
if(e.response.data == -1) throw new Error(`Couldn't find a "${username}" user.`)
|
|
37
|
+
throw new Error(e.response.data)
|
|
34
38
|
})
|
|
35
|
-
if(r.data == -1) throw new Error(`Couldn't find a "${username}" user.`)
|
|
36
|
-
if(r.data.toLowerCase() == "error code: 1020") throw new Error("1020 error: Request denied.");
|
|
37
39
|
let targetId = r.data.split(":16:")[1].split(":3:")[0];
|
|
38
40
|
|
|
39
41
|
const {gjp} = require("../misc/gjp.js");
|
|
@@ -51,8 +53,8 @@ module.exports = {
|
|
|
51
53
|
let res = await axios.post(server + "blockGJUser20.php", blockData, {
|
|
52
54
|
headers: headers
|
|
53
55
|
}).catch(e => {
|
|
54
|
-
if(res.data.toLowerCase() == "error code: 1020") throw new Error("1020 error: Request denied.");
|
|
55
|
-
throw new Error(
|
|
56
|
+
if(res.data.toString().toLowerCase() == "error code: 1020") throw new Error("1020 error: Request denied.");
|
|
57
|
+
throw new Error(e)
|
|
56
58
|
})
|
|
57
59
|
|
|
58
60
|
return 1;
|
|
@@ -20,11 +20,10 @@ module.exports = {
|
|
|
20
20
|
let r = await axios.post(server + "getGJUsers20.php", data, {
|
|
21
21
|
headers: headers
|
|
22
22
|
}).catch(e => {
|
|
23
|
+
if(e.response.data == -1) throw new Error("-1 This user is not found.");
|
|
23
24
|
throw new Error(e.response.data);
|
|
24
25
|
})
|
|
25
26
|
|
|
26
|
-
if(r.data == -1) throw new Error("-1 This user is not found.")
|
|
27
|
-
|
|
28
27
|
let accId = r.data.split(":16:")[1].split(":3:")[0];
|
|
29
28
|
if(Number(accId) < 71 || accId.includes(":")) accId = r.data.split(":16:")[2].split(":3:")[0];
|
|
30
29
|
|
package/functions/dlLevel.js
CHANGED
|
@@ -4,6 +4,7 @@ module.exports = {
|
|
|
4
4
|
const bs = require("js-base64")
|
|
5
5
|
if(!level || level == "") throw new Error("Please provide a level ID.");
|
|
6
6
|
if(isNaN(level)) throw new Error("The level parameter should be a number.");
|
|
7
|
+
|
|
7
8
|
const axios = require("axios");
|
|
8
9
|
const { headers, server } = require("../config.json");
|
|
9
10
|
|
|
@@ -22,40 +23,63 @@ module.exports = {
|
|
|
22
23
|
headers: headers
|
|
23
24
|
})
|
|
24
25
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
let
|
|
34
|
-
let
|
|
35
|
-
let
|
|
36
|
-
let
|
|
37
|
-
let
|
|
38
|
-
let
|
|
39
|
-
let
|
|
40
|
-
let
|
|
41
|
-
let
|
|
42
|
-
let
|
|
43
|
-
let
|
|
44
|
-
let
|
|
45
|
-
let
|
|
46
|
-
let
|
|
47
|
-
let
|
|
48
|
-
let
|
|
49
|
-
let
|
|
50
|
-
let
|
|
51
|
-
let
|
|
52
|
-
let
|
|
53
|
-
let
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
26
|
+
let spl = res.data.split(":");
|
|
27
|
+
let levelInfo = [];
|
|
28
|
+
for(let i =0;i<spl.length;i++) {
|
|
29
|
+
if(i%2!=0) {
|
|
30
|
+
levelInfo.push(spl[i-1]+`:`+spl[i]);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
let id = levelInfo[0].split("1:")[1];
|
|
35
|
+
let name = levelInfo[1].split("2:")[1];
|
|
36
|
+
let description = bs.decode(levelInfo[2].split("3:")[1])
|
|
37
|
+
let version = levelInfo[4].split("5:")[1];
|
|
38
|
+
let difficulty = levelInfo[7].split("9:")[1];
|
|
39
|
+
let downloads = levelInfo[8].split("10:")[1];
|
|
40
|
+
let officialSong = levelInfo[9].split("12:")[1];
|
|
41
|
+
let gameVersion = levelInfo[10].split("13:")[1];
|
|
42
|
+
let likes = levelInfo[11].split("14:")[1];
|
|
43
|
+
let demonBool = levelInfo[12].split("17:")[1];
|
|
44
|
+
let stars = levelInfo[15].split("18:")[1];
|
|
45
|
+
let ftrd = levelInfo[16].split("19:")[1];
|
|
46
|
+
let epic = levelInfo[17].split("42:")[1];
|
|
47
|
+
let objects = levelInfo[18].split("45:")[1];
|
|
48
|
+
let length = levelInfo[19].split("15:")[1];
|
|
49
|
+
let copiedID = levelInfo[20].split("30:")[1];
|
|
50
|
+
let twoPlayer = levelInfo[21].split("31:")[1];
|
|
51
|
+
let uploaded = levelInfo[22].split("28:")[1];
|
|
52
|
+
let updated = levelInfo[23].split("29:")[1];
|
|
53
|
+
let customSong = levelInfo[24].split("35:")[1];
|
|
54
|
+
let coins = levelInfo[26].split("37:")[1];
|
|
55
|
+
let verifiedCoins = levelInfo[27].split("38:")[1];
|
|
56
|
+
let starsRequested = levelInfo[28].split("39:")[1];
|
|
57
|
+
let ldm = levelInfo[31].split("40:")[1];
|
|
58
|
+
let password = xor.decrypt(levelInfo[32].split("27:")[1].split("#")[0], 26364);
|
|
59
|
+
|
|
60
|
+
let disliked = false;
|
|
61
|
+
if(likes.includes("-")) disliked = true;
|
|
62
|
+
|
|
63
|
+
if(verifiedCoins == "0") verifiedCoins = false;
|
|
64
|
+
if(verifiedCoins == "1") verifiedCoins = true;
|
|
65
|
+
|
|
66
|
+
let demonBoolDecoding = {
|
|
67
|
+
'1': true,
|
|
68
|
+
'': false,
|
|
69
|
+
'0': false
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
let featuredDecoding = {
|
|
73
|
+
"0": false,
|
|
74
|
+
"1": true,
|
|
75
|
+
undefined: true
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
let featured = featuredDecoding[ftrd];
|
|
79
|
+
if(featured == undefined) featured = true;
|
|
57
80
|
|
|
58
81
|
let difficultyDecoding = {
|
|
82
|
+
"-10": "Auto",
|
|
59
83
|
"0": "Unrated",
|
|
60
84
|
"10": "Easy",
|
|
61
85
|
"20": "Normal",
|
|
@@ -64,7 +88,7 @@ module.exports = {
|
|
|
64
88
|
"50": "Insane"
|
|
65
89
|
}
|
|
66
90
|
|
|
67
|
-
if(
|
|
91
|
+
if(demonBoolDecoding[demonBool] == true) {
|
|
68
92
|
difficultyDecoding = {
|
|
69
93
|
"10": "Easy Demon",
|
|
70
94
|
"20": "Medium Demon",
|
|
@@ -73,28 +97,7 @@ module.exports = {
|
|
|
73
97
|
"50": "Extreme Demon"
|
|
74
98
|
}
|
|
75
99
|
}
|
|
76
|
-
|
|
77
|
-
const binaryBool = {
|
|
78
|
-
undefined: false,
|
|
79
|
-
"0": false,
|
|
80
|
-
"1": true
|
|
81
|
-
};
|
|
82
|
-
|
|
83
|
-
const featuredDecoding = {
|
|
84
|
-
undefined: true,
|
|
85
|
-
"0": false,
|
|
86
|
-
"1": true
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
let featured = featuredDecoding[split12.split(":42:")[0]];
|
|
90
|
-
if(featured == undefined) featured = true;
|
|
91
|
-
|
|
92
|
-
let demonBool = binaryBool[split11.split(":43:")[0]];
|
|
93
|
-
if(split11.split(":43:")[0] == "") demonBool = false;
|
|
94
|
-
|
|
95
|
-
let ldm = binaryBool[split18.split(":27")[0]]
|
|
96
|
-
if(ldm == undefined) ldm = false;
|
|
97
|
-
|
|
100
|
+
|
|
98
101
|
const lengthDecoding = {
|
|
99
102
|
"0": "Tiny",
|
|
100
103
|
"1": "Short",
|
|
@@ -102,59 +105,15 @@ module.exports = {
|
|
|
102
105
|
"3": "Long",
|
|
103
106
|
"4": "XL"
|
|
104
107
|
}
|
|
105
|
-
if(lengthDecoding[split9.split(":30:")[0]] == undefined) split9 = res.data.split(":15:")[2];
|
|
106
|
-
|
|
107
|
-
let desc = bs.decode(split3.split(":4:")[0].replace(/_/g, '/').replace(/-/g, '+'));
|
|
108
|
-
if(desc == "") desc = "(No description provided)"
|
|
109
|
-
|
|
110
|
-
let likes = split8.split(":17:")[0];
|
|
111
|
-
let dislikedBool;
|
|
112
|
-
if(likes.includes("-")) {
|
|
113
|
-
dislikedBool = true;
|
|
114
|
-
} else {
|
|
115
|
-
dislikedBool = false;
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
const decryptedPass = xor.decrypt(split10, 26364);
|
|
119
|
-
if (decryptedPass.length > 1) split10 = decryptedPass.slice(1);
|
|
120
|
-
else split10 = decryptedPass;
|
|
121
|
-
if (decryptedPass.length > 7) split10 = "Non-copyable";
|
|
122
|
-
|
|
123
|
-
const authData = {
|
|
124
|
-
gameVersion: 21,
|
|
125
|
-
binaryVersion: 35,
|
|
126
|
-
gdw: 0,
|
|
127
|
-
str: split23.split(":8:")[0],
|
|
128
|
-
secret: "Wmfd2893gb7"
|
|
129
|
-
}
|
|
130
|
-
let auth = await axios.post(server + "getGJUsers20.php", authData, {
|
|
131
|
-
headers: headers
|
|
132
|
-
})
|
|
133
|
-
let authname;
|
|
134
|
-
if(auth.data == "-1") {
|
|
135
|
-
authname = "-"
|
|
136
|
-
} else if(!auth.data.startsWith("-")) {
|
|
137
|
-
authname = auth.data.split("1:")[1].split(":2:")[0];
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
const { getSongInfo } = require("./getSongInfo.js");
|
|
141
|
-
const { getOfficialSongInfo } = require("./getOfficialSongInfo.js");
|
|
142
|
-
let song;
|
|
143
|
-
|
|
144
|
-
let copiedId = split19.split(":31:")[0];
|
|
145
|
-
if(copiedId.includes(":")) split19 = res.data.split(":30:")[2];
|
|
146
|
-
|
|
147
|
-
let starsCount = split6.split(":19:")[0];
|
|
148
|
-
if(starsCount.includes(":")) split6 = res.data.split(":18:")[2];
|
|
149
108
|
|
|
150
109
|
const decodeGameVersion = {
|
|
151
|
-
"1": "1.
|
|
152
|
-
"2": "1.
|
|
153
|
-
"3": "1.
|
|
154
|
-
"4": "1.
|
|
155
|
-
"5": "1.
|
|
156
|
-
"6": "1.
|
|
157
|
-
"7": "1.
|
|
110
|
+
"1": "Pre-1.7",
|
|
111
|
+
"2": "Pre-1.7",
|
|
112
|
+
"3": "Pre-1.7",
|
|
113
|
+
"4": "Pre-1.7",
|
|
114
|
+
"5": "Pre-1.7",
|
|
115
|
+
"6": "Pre-1.7",
|
|
116
|
+
"7": "Pre-1.7",
|
|
158
117
|
"10": "1.7",
|
|
159
118
|
"18": "1.8",
|
|
160
119
|
"19": "1.9",
|
|
@@ -162,79 +121,40 @@ module.exports = {
|
|
|
162
121
|
"21": "2.1"
|
|
163
122
|
}
|
|
164
123
|
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
let
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
}
|
|
201
|
-
}
|
|
202
|
-
}
|
|
203
|
-
} else if(split25.split(":13:")[0] != "0" && split26.split(":36:")[0] == "0") {
|
|
204
|
-
song = getOfficialSongInfo(offSongID);
|
|
205
|
-
} else if(split25.split(":13:")[0] == "0" && split26.split(":36:")[0] == "0") {
|
|
206
|
-
song = getOfficialSongInfo(1);
|
|
207
|
-
}
|
|
208
|
-
|
|
209
|
-
const result = {
|
|
210
|
-
"id": Number(split1.split(":2:")[0]),
|
|
211
|
-
"name": split2.split(":3:")[0].toString(),
|
|
212
|
-
"description": desc.trim(),
|
|
213
|
-
"creator": authname,
|
|
214
|
-
"level_version": Number(split4.split(":6:")[0]),
|
|
215
|
-
"difficulty": difficultyDecoding[split5.split(":10:")[0]].toString(),
|
|
216
|
-
"stars": Number(split6.split(":19:")[0]),
|
|
217
|
-
"downloads": Number(split7.split(":12:")[0]),
|
|
218
|
-
"likes": Number(likes),
|
|
219
|
-
"disliked": dislikedBool,
|
|
220
|
-
"length": lengthDecoding[split9.split(":30:")[0]],
|
|
221
|
-
"password": split10,
|
|
222
|
-
"demon": demonBool,
|
|
223
|
-
"featured": featured,
|
|
224
|
-
"epic": featuredDecoding[split13.split(":45:")[0]],
|
|
225
|
-
"objects": Number(objs),
|
|
226
|
-
"uploaded": split15.split(":29:")[0],
|
|
227
|
-
"updated": split16.split(":35:")[0],
|
|
228
|
-
"stars_requested": Number(split17.split(":46:")[0]),
|
|
229
|
-
"game_version": decodeGameVersion[split24.split(":14:")[0]],
|
|
230
|
-
"ldm": ldm,
|
|
231
|
-
"copied": Number(split19.split(":31:")[0]),
|
|
232
|
-
"two_p": binaryBool[split20.split(":28:")[0]],
|
|
233
|
-
"coins": Number(split21.split(":38:")[0]),
|
|
234
|
-
"verified_coins": binaryBool[split22.split(":39:")[0]],
|
|
235
|
-
"song": song
|
|
236
|
-
}
|
|
237
|
-
|
|
238
|
-
return result;
|
|
124
|
+
if(description == '') description = "(No description provided)";
|
|
125
|
+
|
|
126
|
+
const { getLevelByID } = require("./getLevelByID.js");
|
|
127
|
+
let basicInfoAboutLevel = await getLevelByID(id);
|
|
128
|
+
|
|
129
|
+
const result = {
|
|
130
|
+
id: Number(id),
|
|
131
|
+
name: name,
|
|
132
|
+
description: description,
|
|
133
|
+
creator: basicInfoAboutLevel.creator,
|
|
134
|
+
level_version: Number(version),
|
|
135
|
+
difficulty: difficultyDecoding[difficulty],
|
|
136
|
+
stars: Number(stars),
|
|
137
|
+
downloads: Number(downloads),
|
|
138
|
+
likes: Number(likes),
|
|
139
|
+
disliked: disliked,
|
|
140
|
+
length: lengthDecoding[length],
|
|
141
|
+
password: password.replace("1", ""),
|
|
142
|
+
demon: demonBoolDecoding[demonBool],
|
|
143
|
+
featured: featured,
|
|
144
|
+
epic: demonBoolDecoding[epic],
|
|
145
|
+
objects: Number(objects),
|
|
146
|
+
uploaded: uploaded,
|
|
147
|
+
updated: updated,
|
|
148
|
+
stars_requested: Number(starsRequested),
|
|
149
|
+
game_version: decodeGameVersion[gameVersion],
|
|
150
|
+
ldm: demonBoolDecoding[ldm],
|
|
151
|
+
copied: Number(copiedID),
|
|
152
|
+
two_p: demonBoolDecoding[twoPlayer],
|
|
153
|
+
coins: Number(coins),
|
|
154
|
+
verified_coins: verifiedCoins,
|
|
155
|
+
song: basicInfoAboutLevel.song,
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
return result;
|
|
239
159
|
}
|
|
240
160
|
}
|
|
@@ -16,12 +16,11 @@ module.exports = {
|
|
|
16
16
|
|
|
17
17
|
let r = await axios.post(server + "getGJUsers20.php", data, {
|
|
18
18
|
headers: headers
|
|
19
|
+
}).catch(e => {
|
|
20
|
+
if(e.response.data == -1) throw new Error("-1 This user is not found.");
|
|
21
|
+
throw new Error(e.response.data);
|
|
19
22
|
})
|
|
20
23
|
|
|
21
|
-
if(r.data == -1) throw new Error("-1 This user is not found.")
|
|
22
|
-
if(r.data.toLowerCase() == "error code: 1020") throw new Error("1020 error: Request denied.");
|
|
23
|
-
if(r.data.toLowerCase() == "error code: 1005") throw new Error("1005 error: Your IP address has been blocked from sending requests to a server. It's recommended to use locally (directly from a PC).")
|
|
24
|
-
|
|
25
24
|
let id = r.data.split(":16:")[1].split(":3:")[0];
|
|
26
25
|
if(Number(id) < 71 || id.includes(":")) id = r.data.split(":16:")[2].split(":3:")[0];
|
|
27
26
|
|
|
@@ -36,12 +35,11 @@ module.exports = {
|
|
|
36
35
|
|
|
37
36
|
let res = await axios.post(server + "getGJAccountComments20.php", ACdata, {
|
|
38
37
|
headers: headers
|
|
38
|
+
}).catch(e => {
|
|
39
|
+
if(e.response.data == -1) throw new Error("-1 Not found.");
|
|
40
|
+
if(e.response.data.startsWith("#")) throw new Error("Whoops! Couldn't find anything!");
|
|
41
|
+
throw new Error(e.response.data);
|
|
39
42
|
})
|
|
40
|
-
|
|
41
|
-
if(res.data == -1) throw new Error("-1 Not found.")
|
|
42
|
-
if(res.data.toLowerCase() == "error code: 1020") throw new Error("1020 error: Request denied.");
|
|
43
|
-
if(res.data.toLowerCase() == "error code: 1005") throw new Error("1005 error: Your IP address has been blocked from sending requests to a server. It's recommended to use locally (directly from a PC).")
|
|
44
|
-
if(res.data.startsWith("#")) throw new Error("Whoops! Couldn't find anything!");
|
|
45
43
|
|
|
46
44
|
let firstPost = res.data;
|
|
47
45
|
let secondPost;
|
|
@@ -17,12 +17,11 @@ module.exports = {
|
|
|
17
17
|
|
|
18
18
|
let r = await axios.post(server + "getGJUsers20.php", userData, {
|
|
19
19
|
headers: headers
|
|
20
|
+
}).catch(e => {
|
|
21
|
+
if(e.response.data == -1) throw new Error("-1 This user is not found.");
|
|
22
|
+
throw new Error(e.response.data);
|
|
20
23
|
})
|
|
21
24
|
|
|
22
|
-
if(r.data == -1) throw new Error("-1 Not found.");
|
|
23
|
-
if(r.data.toLowerCase() == "error code: 1020") throw new Error("1020 error: Request denied.");
|
|
24
|
-
if(r.data.toLowerCase() == "error code: 1005") throw new Error("1005 error: Your IP address has been blocked from sending requests to a server. It's recommended to use locally (directly from a PC).")
|
|
25
|
-
|
|
26
25
|
let id = r.data.split(":2:")[1].split(":13:")[0];
|
|
27
26
|
|
|
28
27
|
const user = await getProfile(id);
|
|
@@ -40,12 +39,10 @@ module.exports = {
|
|
|
40
39
|
|
|
41
40
|
let res = await axios.post(server + "getGJCommentHistory.php", CHData, {
|
|
42
41
|
headers: headers
|
|
42
|
+
}).catch(e => {
|
|
43
|
+
if(e.response.data == -1) throw new Error("-1 Not found.");
|
|
44
|
+
throw new Error(e.response.data);
|
|
43
45
|
})
|
|
44
|
-
|
|
45
|
-
if(res.data == -1) throw new Error("-1 Not found.");
|
|
46
|
-
if(res.data.toLowerCase() == "error code: 1020") throw new Error("1020 error: Request denied.");
|
|
47
|
-
if(res.data.toLowerCase() == "error code: 1005") throw new Error("1005 error: Your IP address has been blocked from sending requests to a server. It's recommended to use locally (directly from a PC).")
|
|
48
|
-
|
|
49
46
|
|
|
50
47
|
let firstComment = res.data;
|
|
51
48
|
let secondComment;
|
package/functions/getComments.js
CHANGED
|
@@ -19,12 +19,11 @@ module.exports = {
|
|
|
19
19
|
|
|
20
20
|
let res = await axios.post(server + "getGJComments21.php", data, {
|
|
21
21
|
headers: headers
|
|
22
|
+
}).catch(e => {
|
|
23
|
+
if(e.response.data == -1) throw new Error("-1 This user is not found.");
|
|
24
|
+
throw new Error(e.response.data);
|
|
22
25
|
})
|
|
23
26
|
|
|
24
|
-
if(res.data == -1) throw new Error("-1 Not found.");
|
|
25
|
-
if(res.data.toLowerCase() == "error code: 1020") throw new Error("1020 error: Request denied.");
|
|
26
|
-
if(res.data.toLowerCase() == "error code: 1005") throw new Error("1005 error: Your IP address has been blocked from sending requests to a server. It's recommended to use locally (directly from a PC).")
|
|
27
|
-
|
|
28
27
|
let firstComment = res.data;
|
|
29
28
|
let secondComment;
|
|
30
29
|
let thirdComment;
|
|
@@ -14,10 +14,9 @@ module.exports = {
|
|
|
14
14
|
|
|
15
15
|
let res = await axios.post(server + "getGJGauntlets21.php", data, {
|
|
16
16
|
headers: headers
|
|
17
|
+
}).catch(e => {
|
|
18
|
+
throw new Error(e.response.data);
|
|
17
19
|
})
|
|
18
|
-
|
|
19
|
-
if(res.data.toLowerCase() == "error code: 1020") throw new Error("1020 error: Request denied.");
|
|
20
|
-
if(res.data.toLowerCase() == "error code: 1005") throw new Error("1005 error: Your IP address has been blocked from sending requests to a server. It's recommended to use locally (directly from a PC).")
|
|
21
20
|
|
|
22
21
|
let first = res.data.split("|")[0];
|
|
23
22
|
let second = res.data.split("|")[1].split("|")[0];
|
|
@@ -19,11 +19,10 @@ module.exports = {
|
|
|
19
19
|
|
|
20
20
|
let res = await axios.post(server + "getGJLevels21.php", data, {
|
|
21
21
|
headers: headers
|
|
22
|
+
}).catch(e => {
|
|
23
|
+
if(e.response.data == -1) throw new Error("-1 Not found.");
|
|
24
|
+
throw new Error(e.response.data);
|
|
22
25
|
})
|
|
23
|
-
|
|
24
|
-
if(res.data == -1) throw new Error("-1 Not found.");
|
|
25
|
-
if(res.data.toLowerCase() == "error code: 1020") throw new Error("1020 error: Request denied.");
|
|
26
|
-
if(res.data.toLowerCase() == "error code: 1005") throw new Error("1005 error: Your IP address has been blocked from sending requests to a server. It's recommended to use locally (directly from a PC).")
|
|
27
26
|
|
|
28
27
|
return decodeLevel(res.data);
|
|
29
28
|
}
|
package/functions/getMapPacks.js
CHANGED
|
@@ -11,10 +11,10 @@ module.exports = {
|
|
|
11
11
|
|
|
12
12
|
let res = await axios.post(server + "getGJMapPacks21.php", data, {
|
|
13
13
|
headers: headers
|
|
14
|
+
}).catch(e => {
|
|
15
|
+
if(e.response.data == -1) throw new Error("-1 Not found.");
|
|
16
|
+
throw new Error(e.response.data);
|
|
14
17
|
})
|
|
15
|
-
|
|
16
|
-
if(res.data.toLowerCase() == "error code: 1020") throw new Error("1020 error: Request denied.");
|
|
17
|
-
if(res.data.toLowerCase() == "error code: 1005") throw new Error("1005 error: Your IP address has been blocked from sending requests to a server. It's recommended to use locally (directly from a PC).")
|
|
18
18
|
|
|
19
19
|
let firstMapPack = res.data.split("|")[0];
|
|
20
20
|
let secondMapPack = res.data.split("|")[1].split("|")[0];
|
package/functions/getSongInfo.js
CHANGED
|
@@ -13,20 +13,20 @@ module.exports = {
|
|
|
13
13
|
|
|
14
14
|
let res = await axios.post(server + 'getGJSongInfo.php', data, {
|
|
15
15
|
headers: headers
|
|
16
|
+
}).catch(e => {
|
|
17
|
+
if(e.response.data == -2) throw new Error(`-2. Couldn't find a song with ID ${song}.`)
|
|
18
|
+
throw new Error(e.response.data);
|
|
16
19
|
})
|
|
17
20
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
"link": decodeURIComponent(res.data.split("~|~10~|~")[1].split("~|~7~|~")[0])
|
|
29
|
-
}
|
|
30
|
-
return result;
|
|
21
|
+
const result = {
|
|
22
|
+
"name": res.data.split("|~2~|~")[1].split("~|~3~|~")[0],
|
|
23
|
+
"id": Number(res.data.split("1~|~")[1].split("~|~2~|")[0]),
|
|
24
|
+
"artist": res.data.split("~|~4~|~")[1].split("~|~5~|~")[0],
|
|
25
|
+
"artistId": Number(res.data.split("~|~3~|~")[1].split("~|~4~|~")[0]),
|
|
26
|
+
"fileSize": `${res.data.split("~|~5~|~")[1].split("~|~6~|~")[0]} MB`,
|
|
27
|
+
"link": decodeURIComponent(res.data.split("~|~10~|~")[1].split("~|~7~|~")[0])
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
return result;
|
|
31
31
|
}
|
|
32
32
|
}
|
package/functions/reportLevel.js
CHANGED
|
@@ -14,12 +14,9 @@ module.exports = {
|
|
|
14
14
|
|
|
15
15
|
let res = await axios.post(server + "reportGJLevel.php", data, {
|
|
16
16
|
headers: headers
|
|
17
|
+
}).catch(e => {
|
|
18
|
+
throw new Error(e.response.data)
|
|
17
19
|
})
|
|
18
|
-
|
|
19
|
-
if(res.data == -1) throw new Error("-1 Request denied.");
|
|
20
|
-
if(res.data.toLowerCase() == "error code: 1020") throw new Error("1020 error: Request denied.");
|
|
21
|
-
if(res.data.toString().toLowerCase() == "error code: 1005") throw new Error("1005 error: Your IP address has been blocked from sending requests to a server. It's recommended to use locally (directly from a PC).")
|
|
22
|
-
|
|
23
20
|
return res.data;
|
|
24
21
|
}
|
|
25
22
|
}
|
|
@@ -22,12 +22,10 @@ module.exports = {
|
|
|
22
22
|
|
|
23
23
|
let r = await axios.post(server + "getGJUsers20.php", data, {
|
|
24
24
|
headers: headers
|
|
25
|
+
}).catch(e => {
|
|
26
|
+
throw new Error(e.response.data);
|
|
25
27
|
})
|
|
26
28
|
|
|
27
|
-
if(r.data == -1) throw new Error("-1 This user is not found.")
|
|
28
|
-
if(r.data.toString().toLowerCase() == "error code: 1020") throw new Error("1020 error: Request denied.");
|
|
29
|
-
if(r.data.toString().toLowerCase() == "error code: 1005") throw new Error("1005 error: Your IP address has been blocked from sending requests to a server. It's recommended to use locally (directly from a PC).")
|
|
30
|
-
|
|
31
29
|
let id = r.data.split(":16:")[1].split(":3:")[0];
|
|
32
30
|
if(Number(id) < 71 || id.includes(":")) id = r.data.split(":16:")[2].split(":3:")[0];
|
|
33
31
|
|
|
@@ -44,12 +42,11 @@ module.exports = {
|
|
|
44
42
|
|
|
45
43
|
let res = await axios.post(server + "updateGJDesc20.php", uLDdata, {
|
|
46
44
|
headers: headers
|
|
45
|
+
}).catch(e => {
|
|
46
|
+
if(e.response.data == -1) throw new Error("-1 Failed to update the description.")
|
|
47
|
+
throw new Error(e.response.data);
|
|
47
48
|
})
|
|
48
|
-
|
|
49
|
-
if(res.data == -1) throw new Error("-1 Failed to update the description.")
|
|
50
|
-
if(res.data.toString().toLowerCase() == "error code: 1020") throw new Error("1020 error: Request denied.");
|
|
51
|
-
if(res.data.toString().toLowerCase() == "error code: 1005") throw new Error("1005 error: Your IP address has been blocked from sending requests to a server. It's recommended to use locally (directly from a PC).")
|
|
52
|
-
|
|
49
|
+
|
|
53
50
|
return 1;
|
|
54
51
|
}
|
|
55
52
|
}
|
|
@@ -18,9 +18,11 @@ module.exports = {
|
|
|
18
18
|
|
|
19
19
|
let r = await axios.post(server + "getGJUsers20.php", data, {
|
|
20
20
|
headers: headers
|
|
21
|
+
}).catch(e => {
|
|
22
|
+
if(e.response.data == -1) throw new Error("-1 This user is not found.");
|
|
23
|
+
throw new Error(e.response.data);
|
|
21
24
|
})
|
|
22
25
|
|
|
23
|
-
if(r.data == -1) throw new Error("-1 This user is not found.")
|
|
24
26
|
let id = r.data.split(":16:")[1].split(":3:")[0];
|
|
25
27
|
if(Number(id) < 71 || id.includes(":")) id = r.data.split(":16:")[2].split(":3:")[0];
|
|
26
28
|
|
|
@@ -44,10 +46,8 @@ module.exports = {
|
|
|
44
46
|
headers: headers
|
|
45
47
|
}).catch(e => {
|
|
46
48
|
if(e.response.status == 500) throw new Error("500 Error: couldn't post!");
|
|
49
|
+
throw new Error(e.response.data);
|
|
47
50
|
})
|
|
48
|
-
|
|
49
|
-
if(res.data.toLowerCase() == "error code: 1020") throw new Error("1020 error: Request denied.");
|
|
50
|
-
if(res.data.toString().toLowerCase() == "error code: 1005") throw new Error("1005 error: Your IP address has been blocked from sending requests to a server. It's recommended to use locally (directly from a PC).")
|
|
51
51
|
|
|
52
52
|
return 1;
|
|
53
53
|
}
|
|
@@ -27,9 +27,11 @@ module.exports = {
|
|
|
27
27
|
|
|
28
28
|
let r = await axios.post(server + "getGJUsers20.php", data, {
|
|
29
29
|
headers: headers
|
|
30
|
+
}).catch(e => {
|
|
31
|
+
if(r.data == -1) throw new Error("-1 This user is not found.")
|
|
32
|
+
throw new Error(e.response.data)
|
|
30
33
|
})
|
|
31
34
|
|
|
32
|
-
if(r.data == -1) throw new Error("-1 This user is not found.")
|
|
33
35
|
let username = r.data.split("1:")[1].split(":2:")[0];
|
|
34
36
|
let accID = r.data.split(":16:")[1].split(":3:")[0];
|
|
35
37
|
if(Number(accID) < 71 || accID.includes(":")) accID = r.data.split(":16:")[2].split(":3:")[0];
|
package/index.js
CHANGED
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
console.log('\x1b[32m%s\x1b[40m', 'Thanks for using gj-boomlings-api!\nhttps://github.com/shikoshib/gj-boomlings-api');
|
|
2
|
+
console.log('\x1b[37m%s\x1b[0m', '');
|
|
3
|
+
|
|
1
4
|
const { dlLevel } = require("./functions/dlLevel.js");
|
|
2
5
|
const { getSongInfo } = require("./functions/getSongInfo.js");
|
|
3
6
|
const { getOfficialSongInfo } = require("./functions/getOfficialSongInfo.js");
|
|
@@ -30,7 +33,7 @@ module.exports.decURLSafeBase64 = decURLSafeBase64;
|
|
|
30
33
|
module.exports.encURLSafeBase64 = encURLSafeBase64;
|
|
31
34
|
module.exports.getDailyLevel = getDailyLevel;
|
|
32
35
|
module.exports.getWeeklyDemon = getWeeklyDemon;
|
|
33
|
-
module.exports.getProfile = getProfile;
|
|
36
|
+
module.exports.getProfile = getProfile; // to fix
|
|
34
37
|
module.exports.reportLevel = reportLevel;
|
|
35
38
|
module.exports.getComments = getComments;
|
|
36
39
|
module.exports.getCommentHistory = getCommentHistory;
|
package/misc/decodeLevel.js
CHANGED
package/misc/decodeMapPack.js
CHANGED
|
@@ -1,20 +1,28 @@
|
|
|
1
1
|
module.exports = {
|
|
2
2
|
decodeMapPack:
|
|
3
3
|
function(mp) {
|
|
4
|
-
let name = mp.split(":2:")[1].split(":3:")[0];
|
|
5
|
-
let unarrayedList = mp.split(":3:")[1].split(":4:")[0].split(":4")[0];
|
|
6
|
-
let stars = mp.split(":4:")[1].split(":5:")[0];
|
|
7
|
-
let coins = mp.split(":5:")[1].split(":6:")[0];
|
|
8
|
-
let difficulty = mp.split(":6:")[1].split(":7:")[0];
|
|
9
4
|
|
|
10
|
-
|
|
5
|
+
let spl = mp.split(':');
|
|
6
|
+
let mpInfo = [];
|
|
7
|
+
for(let i =0;i<spl.length;i++) {
|
|
8
|
+
if(i%2!=0) {
|
|
9
|
+
mpInfo.push(spl[i-1]+`:`+spl[i]);
|
|
10
|
+
}
|
|
11
|
+
}
|
|
11
12
|
|
|
13
|
+
let mappackID = mpInfo[0].split("1:")[1];
|
|
14
|
+
let name = mpInfo[1].split("2:")[1];
|
|
15
|
+
let unarrayedList = mpInfo[2].split("3:")[1];
|
|
16
|
+
let stars = mpInfo[3].split("4:")[1];
|
|
17
|
+
let coins = mpInfo[4].split("5:")[1];
|
|
18
|
+
let difficulty = mpInfo[5].split("6:")[1];
|
|
19
|
+
let txtCol = mpInfo[6].split("7:")[1];
|
|
20
|
+
let barCol = mpInfo[7].split("8:")[1];
|
|
21
|
+
|
|
12
22
|
let firstLvl = unarrayedList.split(",")[0];
|
|
13
23
|
let secondLvl = unarrayedList.split(",")[1].split(",")[0];
|
|
14
24
|
let thirdLvl = unarrayedList.split(",")[2].split(",")[0];
|
|
15
25
|
|
|
16
|
-
if(name.includes(":")) name = name.split("2:")[1]
|
|
17
|
-
|
|
18
26
|
let difficultyDecoder = {
|
|
19
27
|
"0": "Auto",
|
|
20
28
|
"1": "Easy",
|
|
@@ -29,25 +37,29 @@ module.exports = {
|
|
|
29
37
|
"10": "Extreme Demon",
|
|
30
38
|
}
|
|
31
39
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
40
|
+
function rgbToHEX(color) {
|
|
41
|
+
let r = color.split(",")[0];
|
|
42
|
+
let g = color.split(",")[1].split(",")[0];
|
|
43
|
+
let b = color.split(",")[2];
|
|
35
44
|
|
|
36
|
-
|
|
37
|
-
if(coins.includes(":")) {
|
|
38
|
-
coins = mp.split(":5:")[2].split(":6:")[0];
|
|
39
|
-
}
|
|
40
|
-
}
|
|
45
|
+
if(b.includes("#")) b = b.split("#")[0]
|
|
41
46
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
47
|
+
let rHex = Number(r).toString(16);
|
|
48
|
+
let gHex = Number(g).toString(16);
|
|
49
|
+
let bHex = Number(b).toString(16);
|
|
50
|
+
|
|
51
|
+
return `#${rHex.length == 1 ? "0" + rHex : rHex}${gHex.length == 1 ? "0" + gHex : gHex}${bHex.length == 1 ? "0" + bHex : bHex}`.toUpperCase();
|
|
52
|
+
}
|
|
45
53
|
|
|
46
54
|
const result = {
|
|
47
55
|
name: name,
|
|
56
|
+
id: Number(mappackID),
|
|
48
57
|
levels: [Number(firstLvl),Number(secondLvl),Number(thirdLvl)],
|
|
49
58
|
stars: Number(stars),
|
|
50
|
-
coins: Number(coins)
|
|
59
|
+
coins: Number(coins),
|
|
60
|
+
difficulty: difficultyDecoder[difficulty],
|
|
61
|
+
textColor: rgbToHEX(txtCol),
|
|
62
|
+
barColor: rgbToHEX(barCol)
|
|
51
63
|
}
|
|
52
64
|
|
|
53
65
|
return result;
|