gj-boomlings-api 1.5.7 → 2.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (55) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +31 -7
  3. package/functions/blockUser.js +29 -30
  4. package/functions/deleteAccountPost.js +22 -32
  5. package/functions/deleteComment.js +20 -20
  6. package/functions/deleteLevel.js +23 -29
  7. package/functions/dlLevel.js +157 -6
  8. package/functions/dlMessage.js +30 -36
  9. package/functions/getAccountPosts.js +23 -36
  10. package/functions/getBlockedList.js +47 -63
  11. package/functions/getCommentHistory.js +59 -39
  12. package/functions/getComments.js +46 -27
  13. package/functions/getCreatorScores.js +18 -30
  14. package/functions/getDailyLevel.js +5 -9
  15. package/functions/getFriendsList.js +48 -56
  16. package/functions/getGauntlets.js +18 -24
  17. package/functions/getLevelByID.js +9 -156
  18. package/functions/getLevelScores.js +63 -46
  19. package/functions/getMapPacks.js +40 -28
  20. package/functions/getMessages.js +36 -41
  21. package/functions/getOfficialSongInfo.js +9 -87
  22. package/functions/getProfile.js +159 -7
  23. package/functions/getSongInfo.js +22 -31
  24. package/functions/getSongsLibrary.js +80 -0
  25. package/functions/getTab.js +16 -7
  26. package/functions/getTop100.js +18 -27
  27. package/functions/getTopLists.js +14 -0
  28. package/functions/getUserLevels.js +24 -88
  29. package/functions/getWeeklyDemon.js +5 -9
  30. package/functions/reportLevel.js +9 -22
  31. package/functions/searchLevels.js +15 -84
  32. package/functions/searchLists.js +15 -0
  33. package/functions/unblockUser.js +29 -30
  34. package/functions/updateLevelDesc.js +27 -43
  35. package/functions/uploadAccountPost.js +23 -36
  36. package/functions/uploadComment.js +43 -57
  37. package/functions/uploadMessage.js +32 -41
  38. package/gjReq.js +18 -0
  39. package/index.js +36 -1
  40. package/misc/GJDecode.js +210 -1
  41. package/misc/colors.json +1 -1
  42. package/misc/gauntlets.json +1 -0
  43. package/misc/officialsongs.json +1 -1
  44. package/misc/rgbToHEX.js +1 -1
  45. package/package.json +2 -6
  46. package/.nvmrc +0 -1
  47. package/config.json +0 -1
  48. package/functions/searchUsers.js +0 -27
  49. package/misc/decB64.js +0 -4
  50. package/misc/demonlist.js +0 -1
  51. package/misc/encB64.js +0 -1
  52. package/misc/gjReq.js +0 -1
  53. package/misc/gjWReq.js +0 -1
  54. package/misc/gjp.js +0 -1
  55. /package/{misc/xor.js → xor.js} +0 -0
package/LICENSE CHANGED
@@ -1,4 +1,4 @@
1
- Copyright 2022 shikoshib
1
+ Copyright 2023 shikoshib
2
2
 
3
3
  Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above copyright notice and this permission notice appear in all copies.
4
4
 
package/README.md CHANGED
@@ -14,15 +14,39 @@
14
14
  # About
15
15
  **gj-boomlings-api** is a light-weight Node.js module that allows you to easily interact with Geometry Dash API.
16
16
  # Installation
17
+ ## Node.js
17
18
  ```
18
19
  npm i gj-boomlings-api
19
20
  yarn add gj-boomlings-api
20
21
  ```
21
- ## In browser...
22
- ```html
23
- <script src="https://shikoshib.github.io/gba-max.min.js"></script>
22
+ ## In browser
23
+ Not yet, coming soon
24
+ # Examples
25
+ ## Download a level
26
+ ```js
27
+ const gd = require("gj-boomlings-api");
28
+ gd.dlLevel("95540029").then(console.log);
24
29
  ```
25
-
26
- ---
27
-
28
- Inspired by [GDBrowser](https://github.com/GDColon/GDBrowser/). Thanks to [Wireshark](https://www.wireshark.org/) and [GD Docs](https://github.com/gd-programming/gd.docs/) for helping me in creating this package.
30
+ ## View a profile
31
+ ```js
32
+ const gd = require("gj-boomlings-api");
33
+ gd.getProfile("shikoshib").then(console.log);
34
+ ```
35
+ ## Get gauntlets
36
+ ```js
37
+ const gd = require("gj-boomlings-api");
38
+ gd.getGauntlets().then(console.log);
39
+ ```
40
+ ## Post a message on a profile
41
+ ```js
42
+ const gd = require("gj-boomlings-api");
43
+ gd.uploadAccountPost("I love gj-boomlings-api!","shikoshib","your password here");
44
+ ```
45
+ ## Send a message
46
+ ```js
47
+ // This code sends a message from shikoshib to Mipper6
48
+ const gd = require("gj-boomlings-api");
49
+ gd.uploadMessage("Mipper6", "message subject", "message content", "shikoshib", "your password here");
50
+ ```
51
+ # License
52
+ [ISC](https://github.com/shikoshib/gj-boomlings-api/blob/main/LICENSE)
@@ -1,38 +1,37 @@
1
1
  module.exports = {
2
- /**
3
- * Blocks the specified user.
4
- * @param {*} target - Target's player ID or username.
5
- * @param {*} username - Blocking person's player ID or username.
6
- * @param {*} password - Blocking person's password.
7
- */
8
- blockUser:
9
- async function(target, username, password) {
10
- if(!target) throw new Error("Please provide a target's player ID or username!");
11
- if(!username) throw new Error("Please provide your player ID or username!");
12
- if(!password) throw new Error("Please provide your password!");
2
+ blockUser: async function (target, username, password) {
3
+ if (!target) throw new Error("Please provide a target's player ID or username!");
4
+ if (!username) throw new Error("Please provide a player ID or username!");
5
+ if (!password) throw new Error("Please provide a password!");
13
6
 
14
- const {gjReq} = require("../misc/gjReq.js");
15
- const {gjWReq} = require("../misc/gjWReq.js");
16
- const { searchUsers } = require("./searchUsers.js");
7
+ const { gjReq } = require("../gjReq");
8
+ const XOR = require("../xor");
9
+ const xor = new XOR;
17
10
 
18
- let user = await searchUsers(username);
19
- let targetObj = await searchUsers(target);
11
+ let userSearch = await gjReq("getGJUsers20", {
12
+ str: username,
13
+ secret: "Wmfd2893gb7"
14
+ });
15
+ if (userSearch.data == -1) throw new Error(-1);
16
+ let userAccID = userSearch.data.split(":")[21];
20
17
 
21
- const {gjp} = require("../misc/gjp.js");
18
+ let recSearch = await gjReq("getGJUsers20", {
19
+ str: target,
20
+ secret: "Wmfd2893gb7"
21
+ });
22
+ if (recSearch.data == -1) throw new Error(-1);
23
+ let targetAccID = recSearch.data.split(":")[21];
22
24
 
23
- const data = {
24
- secret: "Wmfd2893gb7",
25
- targetAccountID: targetObj.accountID,
26
- accountID: user.accountID,
27
- gjp: gjp(password)
28
- }
29
-
30
- let res = await gjReq("blockGJUser20", data);
31
- if(res.data == -1) throw new Error(-1);
25
+ const data = {
26
+ secret: "Wmfd2893gb7",
27
+ targetAccountID: targetAccID,
28
+ accountID: userAccID,
29
+ gjp: xor.encrypt(password, 37526)
30
+ }
32
31
 
33
- if(res.data == "error code: 1005") res = await gjWReq("blockUser", `${target}?user=${username}&password=${password}`);
34
- if(res.status == 403) throw new Error(res.data.error);
32
+ let res = await gjReq("blockGJUser20", data);
33
+ if (res.data == -1) throw new Error(-1);
35
34
 
36
- return res.data;
37
- }
35
+ return res.data;
36
+ }
38
37
  }
@@ -1,38 +1,28 @@
1
1
  module.exports = {
2
- /**
3
- * Deletes the account post, specified by its ID (returned by `uploadAccountPost()` function).
4
- * @param {*} id - The account post ID.
5
- * @param {*} str - Deleting person's player ID or username.
6
- * @param {*} password - Deleting person's password.
7
- */
8
- deleteAccountPost:
9
- async function(id, str, password) {
10
- if(!id) throw new Error("Please provide an account post ID!");
11
- if(!str) throw new Error("Please provide a user ID or name!");
12
- if(!password) throw new Error("Please provide a password!");
2
+ deleteAccountPost: async function (id, str, password) {
3
+ if (!id) throw new Error("Please provide an account post ID!");
4
+ if (!str) throw new Error("Please provide a user ID or name!");
5
+ if (!password) throw new Error("Please provide a password!");
13
6
 
14
- const {gjReq} = require("../misc/gjReq.js");
15
- const {gjWReq} = require("../misc/gjWReq.js");
16
- const { searchUsers } = require("./searchUsers.js");
7
+ const { gjReq } = require("../gjReq");
8
+ const XOR = require("../xor");
9
+ const xor = new XOR;
17
10
 
18
- let user = await searchUsers(str);
11
+ let search = await gjReq("getGJUsers20", {
12
+ str: str,
13
+ secret: "Wmfd2893gb7"
14
+ });
15
+ if (search.data == -1) throw new Error(-1);
16
+ let accID = search.data.split(":")[21];
19
17
 
20
- const XOR = require("../misc/xor.js");
21
- const xor = new XOR();
18
+ let res = await gjReq("deleteGJAccComment20", {
19
+ accountID: accID,
20
+ secret: "Wmfd2893gb7",
21
+ gjp: xor.encrypt(password, 37526),
22
+ commentID: id
23
+ });
24
+ if (res.data == -1) throw new Error(-1);
22
25
 
23
- let data = {
24
- accountID: user.accountID,
25
- secret: "Wmfd2893gb7",
26
- gjp: xor.encrypt(password, 37526),
27
- commentID: id,
28
- };
29
-
30
- let res = await gjReq("deleteGJAccComment20", data);
31
- if(res.data == -1) throw new Error(-1);
32
-
33
- if(res.data == "error code: 1005") res = await gjWReq("deleteAccountPost", `?id=${id}&user=${str}&password=${password}`);
34
- if(res.status == 403) throw new Error(res.data.error);
35
-
36
- return res.data;
37
- }
26
+ return res.data;
27
+ }
38
28
  }
@@ -1,31 +1,31 @@
1
1
  module.exports = {
2
2
  deleteComment:
3
- async function(id, lvl, str, password) {
4
- if(!id) throw new Error("Please provide a comment ID!");
5
- if(!lvl) throw new Error("Please provide a level ID!");
6
- if(!str) throw new Error("Please provide a user ID or name!");
7
- if(!password) throw new Error("Please provide a password!");
3
+ async function (id, lvl, str, password) {
4
+ if (!id) throw new Error("Please provide a comment ID!");
5
+ if (!lvl) throw new Error("Please provide a level ID!");
6
+ if (!str) throw new Error("Please provide a user ID or name!");
7
+ if (!password) throw new Error("Please provide a password!");
8
8
 
9
- const {gjReq} = require("../misc/gjReq.js");
10
- const {gjWReq} = require("../misc/gjWReq.js");
11
- const { searchUsers } = require("./searchUsers.js");
9
+ const { gjReq } = require("../gjReq.js");
10
+ let search = await gjReq("getGJUsers20", {
11
+ str: str,
12
+ secret: "Wmfd2893gb7"
13
+ });
14
+ if (search.data == -1) throw new Error(-1);
15
+ let accID = search.data.split(":")[21];
12
16
 
13
- let user = await searchUsers(str);
17
+ const XOR = require("../xor.js");
18
+ const xor = new XOR;
14
19
 
15
- const XOR = require("../misc/xor.js");
16
- const xor = new XOR();
17
-
18
- let data = {
19
- accountID: user.accountID,
20
+ const res = await gjReq("deleteGJComment20", {
21
+ accountID: accID,
20
22
  secret: "Wmfd2893gb7",
21
23
  levelID: lvl,
22
24
  gjp: xor.encrypt(password, 37526),
23
- commentID: id,
24
- };
25
-
26
- let res = await gjReq("deleteGJComment20", data);
27
- if(res.data == -1) throw new Error(-1);
25
+ commentID: id
26
+ });
27
+ if (res.data == -1) throw new Error(-1);
28
28
 
29
- return 1;
29
+ return res.data;
30
30
  }
31
31
  }
@@ -1,36 +1,30 @@
1
1
  module.exports = {
2
- /**
3
- * Deletes the specified level.
4
- * @param {*} lvl - The ID of a level to delete.
5
- * @param {*} str - The username or player ID of a creator.
6
- * @param {*} password - The password of a creator.
7
- */
8
- deleteLevel:
9
- async function(lvl, str, password) {
10
- if(!lvl) throw new Error("Please provide a level ID!");
11
- if(!str) throw new Error("Please provide a user ID or name!");
12
- if(!password) throw new Error("Please provide a password!");
2
+ deleteLevel: async function (lvl, str, password) {
3
+ if (isNaN(lvl)) throw new Error("Please provide a valid level ID!");
4
+ if (!str) throw new Error("Please provide a user ID or name!");
5
+ if (!password) throw new Error("Please provide a password!");
13
6
 
14
- const {gjReq} = require("../misc/gjReq.js");
15
- const {gjWReq} = require("../misc/gjWReq.js");
16
- const { searchUsers } = require("./searchUsers.js");
17
- const {gjp} = require("../misc/gjp.js");
7
+ const { gjReq } = require("../gjReq");
8
+ const XOR = require("../xor");
9
+ const xor = new XOR;
18
10
 
19
- let user = await searchUsers(str);
11
+ let search = await gjReq("getGJUsers20", {
12
+ str: str,
13
+ secret: "Wmfd2893gb7"
14
+ });
15
+ if (search.data == -1) throw new Error(-1);
16
+ let accID = search.data.split(":")[21];
20
17
 
21
- let data = {
22
- accountID: user.accountID,
23
- secret: "Wmfv2898gc9",
24
- levelID: lvl,
25
- gjp: gjp(password),
26
- };
18
+ let data = {
19
+ accountID: accID,
20
+ secret: "Wmfv2898gc9",
21
+ levelID: lvl,
22
+ gjp: xor.encrypt(password, 37526),
23
+ };
27
24
 
28
- let res = await gjReq("deleteGJLevelUser20", data);
29
- if(res.data == -1) throw new Error(-1);
25
+ let res = await gjReq("deleteGJLevelUser20", data);
26
+ if (res.data == -1) throw new Error(-1);
30
27
 
31
- if(res.data == "error code: 1005") res = await gjWReq("deleteLevel", `${lvl}?user=${str}&password=${password}`);
32
- if(res.status == 403) throw new Error(res.data.error);
33
-
34
- return res.data;
35
- }
28
+ return res.data;
29
+ }
36
30
  }
@@ -1,8 +1,159 @@
1
1
  module.exports = {
2
- /**
3
- * Downloads the level.
4
- * @param {*} level - The level ID to download.
5
- */
6
- dlLevel:
7
- async function(level){const{decB64}=require("../misc/decB64.js");const zlib=require("zlib");if(!level)throw new Error("Please provide a level ID.");if(isNaN(level))throw new Error("The level parameter should be a number.");const{gjReq}=require("../misc/gjReq.js");const{gjWReq}=require("../misc/gjWReq.js");const{server}=require("../config.json");const XOR=require("../misc/xor.js");let xor=new XOR;const data={levelID:level.toString().trim(),secret:"Wmfd2893gb7"};let res=await gjReq("downloadGJLevel22",data);if(res.data==-1)throw new Error("-1 This level is not found.");if(res.data=="error code: 1005"){res=await gjWReq("dlLevel",level);if(res.status==403)throw new Error(res.data.error);return res.data}let spl=res.data.split(":");let levelInfo=[];for(let i=0;i<spl.length;i++){if(i%2!=0){levelInfo.push(spl[i-1]+`:`+spl[i])}}let id=levelInfo[0].split("1:")[1];let name=levelInfo[1].split("2:")[1];let description=decB64(levelInfo[2].split("3:")[1]);let levelStr=levelInfo[3].split("4:")[1];let version=levelInfo[4].split("5:")[1];let difficulty=levelInfo[7].split("9:")[1];let downloads=levelInfo[8].split("10:")[1];let gameVersion=levelInfo[10].split("13:")[1];let likes=levelInfo[11].split("14:")[1];let demonBool=levelInfo[12].split("17:")[1];let stars=levelInfo[15].split("18:")[1];let ftrd=levelInfo[16].split("19:")[1];let epic=levelInfo[17].split("42:")[1];let objs=levelInfo[18].split("45:")[1];let length=levelInfo[19].split("15:")[1];let copiedID=levelInfo[20].split("30:")[1];let twoPlayer=levelInfo[21].split("31:")[1];let uploaded=levelInfo[22].split("28:")[1];let updated=levelInfo[23].split("29:")[1];let coins=levelInfo[26].split("37:")[1];let verifiedCoins=levelInfo[27].split("38:")[1];let starsRequested=levelInfo[28].split("39:")[1];let ldm=levelInfo[31].split("40:")[1];let password=xor.decrypt(levelInfo[32].split("27:")[1].split("#")[0],26364);if(password.length==7)password=password.replace("1","");let disliked=likes.includes("-")?true:false;let featured=Boolean(Number(ftrd));let difficultyDecoding={"-10":"Auto",0:"Unrated",10:"Easy",20:"Normal",30:"Hard",40:"Harder",50:"Insane"};if(Boolean(Number(demonBool))){difficultyDecoding={10:"Easy Demon",20:"Medium Demon",30:"Hard Demon",40:"Insane Demon",50:"Extreme Demon"}}const lengthDecoding={0:"Tiny",1:"Short",2:"Medium",3:"Long",4:"XL"};const decodeGameVersion={1:"Pre-1.7",2:"Pre-1.7",3:"Pre-1.7",4:"Pre-1.7",5:"Pre-1.7",6:"Pre-1.7",7:"Pre-1.7",10:"1.7",18:"1.8",19:"1.9",20:"2.0",21:"2.1"};let objects;zlib.unzip(Buffer.from(levelStr,"base64"),(err,buffer)=>{const raw_data=buffer.toString();const objArray=raw_data.split(";");objArray.shift();objects=objArray.length-1});const{getLevelByID}=require("./getLevelByID.js");let getLvl=await getLevelByID(id);let result={id:Number(id),name:name,description:!description?"(No description provided)":description,creator:getLvl.creator,level_version:Number(version),difficulty:difficultyDecoding[difficulty],stars:Number(stars),downloads:Number(downloads),likes:Number(likes),disliked:disliked,length:lengthDecoding[length],password:password,demon:Boolean(Number(demonBool)),featured:featured,epic:Boolean(Number(epic)),objects:objects,uploaded:uploaded,updated:updated,stars_requested:Number(starsRequested),game_version:decodeGameVersion[gameVersion],ldm:Boolean(Number(ldm)),copied:Number(copiedID),large:Number(objs)>4e4?true:false,two_p:Boolean(Number(twoPlayer)),coins:Number(coins),verified_coins:Boolean(Number(verifiedCoins)),song:getLvl.song};if(getLvl.pointercrate!=undefined&&server.includes("boomlings.com/database")){result.pointercrate=getLvl.pointercrate}return result}
2
+ dlLevel: async function (level) {
3
+ const zlib = require("zlib");
4
+ if (!level) throw new Error("Please provide a level ID.");
5
+ if (isNaN(level)) throw new Error("The level parameter should be a number.");
6
+
7
+ const { gjReq } = require("../gjReq");
8
+
9
+ const data = {
10
+ levelID: level.toString().trim(),
11
+ secret: "Wmfd2893gb7"
12
+ }
13
+
14
+ let res = await gjReq("downloadGJLevel22", data);
15
+ if (res.data == -1) return {};
16
+ const XOR = require("../xor");
17
+ let xor = new XOR;
18
+
19
+ let s = res.data.split("#")[0].split(":");
20
+
21
+ let id = Number(s[1]);
22
+ let name = s[3];
23
+ let description = Buffer.from(s[5], "base64url").toString();
24
+ let levelString = s[7];
25
+ let version = Number(s[9]);
26
+ let playerID = Number(s[11]);
27
+ let difficulty = s[15];
28
+ let downloads = Number(s[17]);
29
+ let officialSongID = Number(s[19]);
30
+ let gameVersion = Number(s[21]);
31
+ let likes = Number(s[23]);
32
+ let isDemon = s[25];
33
+ let stars = Number(s[31]);
34
+ let isFeatured = s[33];
35
+ let isEpic = s[35];
36
+ let objStats = Number(s[37]);
37
+ let length = Number(s[39]);
38
+ let copiedID = Number(s[41]);
39
+ let is2P = s[43];
40
+ let uploaded = s[45];
41
+ let updated = s[47];
42
+ let NGSongID = Number(s[49]);
43
+ let coins = Number(s[53]);
44
+ let coinsVerified = s[55];
45
+ let starReq = Number(s[57]);
46
+ let isLDM = s[63];
47
+ let password = xor.decrypt(s[67].split("#")[0], 26364);
48
+ if (password.length == 7) password = password.replace("1", "");
49
+
50
+ let diffObj = {
51
+ "-10": "Auto",
52
+ 0: "N/A",
53
+ 10: "Easy",
54
+ 20: "Normal",
55
+ 30: "Hard",
56
+ 40: "Harder",
57
+ 50: "Insane"
58
+ }
59
+
60
+ if (Boolean(Number(isDemon))) {
61
+ diffObj = {
62
+ 10: "Easy Demon",
63
+ 20: "Medium Demon",
64
+ 30: "Hard Demon",
65
+ 40: "Insane Demon",
66
+ 50: "Extreme Demon"
67
+ }
68
+ }
69
+
70
+ const lengthObj = {
71
+ 0: "Tiny",
72
+ 1: "Short",
73
+ 2: "Medium",
74
+ 3: "Long",
75
+ 4: "XL",
76
+ 5: "Platformer"
77
+ }
78
+
79
+ const versionObj = {
80
+ 10: "1.7",
81
+ 18: "1.8",
82
+ 19: "1.9",
83
+ 20: "2.0",
84
+ 21: "2.1",
85
+ 22: "2.2"
86
+ }
87
+
88
+ const buffer = await new Promise((resolve, reject) => {
89
+ zlib.unzip(Buffer.from(levelString, "base64"), (err, buffer) => {
90
+ if (err) {
91
+ reject(err);
92
+ } else {
93
+ resolve(buffer);
94
+ }
95
+ });
96
+ })
97
+ const rawData = buffer.toString();
98
+ const objs = rawData.split(";");
99
+ objs.shift();
100
+
101
+ let song;
102
+ const { getOfficialSongInfo } = require("./getOfficialSongInfo");
103
+ const { getSongInfo } = require("./getSongInfo");
104
+ if (officialSongID && !NGSongID) {
105
+ song = getOfficialSongInfo(officialSongID + 1);
106
+ } else if (NGSongID && !officialSongID) {
107
+ let findSong = await getSongInfo(NGSongID);
108
+ song = findSong;
109
+ }else if(!officialSongID&&!NGSongID){
110
+ song = getOfficialSongInfo(1);
111
+ }
112
+
113
+ let result = {
114
+ id: id,
115
+ name: name,
116
+ description: !description ? "(No description provided)" : description,
117
+ levelVersion: version,
118
+ playerID: playerID,
119
+ difficulty: diffObj[difficulty],
120
+ stars: stars,
121
+ downloads: downloads,
122
+ likes: likes,
123
+ disliked: likes < 0 ? true : false,
124
+ length: lengthObj[length],
125
+ password: password,
126
+ demon: Boolean(Number(isDemon)),
127
+ featured: Boolean(Number(isFeatured)),
128
+ epic: Boolean(Number(isEpic)),
129
+ objects: objs.length - 1,
130
+ uploaded: uploaded,
131
+ updated: updated,
132
+ starsRequested: starReq,
133
+ gameVersion: versionObj[gameVersion] ? versionObj[gameVersion] : "Pre-1.7",
134
+ ldm: Boolean(Number(isLDM)),
135
+ copiedFrom: copiedID,
136
+ large: objStats > 4e4 ? true : false,
137
+ twoPlayer: Boolean(Number(is2P)),
138
+ coins: coins,
139
+ verifiedCoins: Boolean(Number(coinsVerified)),
140
+ song: song
141
+ }
142
+
143
+ if (s[69] && s[68] != "41") {
144
+ let songsIDArray = [];
145
+ let sfxIDArray = [];
146
+ for (let songID of s[69].split(",")) {
147
+ if (songID == NGSongID) continue;
148
+ songsIDArray.push(Number(songID));
149
+ }
150
+ for (let sfx of s[71].split("#")[0].split(",")) {
151
+ sfxIDArray.push(Number(sfx));
152
+ }
153
+ result.additionalSongs = songsIDArray;
154
+ result.sfx = sfxIDArray;
155
+ }
156
+
157
+ return result;
158
+ }
8
159
  }
@@ -1,43 +1,37 @@
1
1
  module.exports = {
2
- /**
3
- * Downloads the message specified by its ID.
4
- * @param {*} id - The message ID.
5
- * @param {*} user - The downloading person's player ID or username.
6
- * @param {*} pass - The downloading person's password.
7
- */
8
- dlMessage:
9
- async function(id, user, pass) {
10
- if(!id) throw new Error("Please provide a message ID!");
11
- if(Number(id) == NaN) throw new Error("The message ID should be a number!");
12
- if(!user) throw new Error("Please provide your player ID or username!");
13
- if(!pass) throw new Error("Please provide your password!");
14
-
15
- const {gjReq} = require("../misc/gjReq.js");
16
- const {gjWReq} = require("../misc/gjWReq.js");
17
- const {secret} = require("../config.json");
18
- const { searchUsers } = require("./searchUsers.js");
19
- const {gjp} = require("../misc/gjp.js");
20
- let GJDecode = require("../misc/GJDecode.js");
21
- let {decMessage} = GJDecode();
2
+ dlMessage: async function (id, user, pass) {
3
+ if (!id) throw new Error("Please provide a valid message ID!");
4
+ if (!user) throw new Error("Please provide a player ID or username!");
5
+ if (!pass) throw new Error("Please provide a password!");
22
6
 
23
- let userObj = await searchUsers(user);
7
+ const { gjReq } = require("../gjReq");
8
+ const XOR = require("../xor");
9
+ const xor = new XOR;
24
10
 
25
- const data = {
26
- accountID: userObj.accountID,
27
- gjp: gjp(pass),
28
- secret: secret,
29
- messageID: id
30
- }
11
+ let search = await gjReq("getGJUsers20", {
12
+ str: user,
13
+ secret: "Wmfd2893gb7"
14
+ });
15
+ if (search.data == -1) return {};
16
+ let accID = search.data.split(":")[21];
31
17
 
32
- let res = await gjReq("downloadGJMessage20", data);
33
- if(res.data == -1) throw new Error(-1);
18
+ let res = await gjReq("downloadGJMessage20", {
19
+ accountID: accID,
20
+ gjp: xor.encrypt(pass, 37526),
21
+ secret: "Wmfd2893gb7",
22
+ messageID: id
23
+ });
24
+ if (res.data == -1) return {};
34
25
 
35
- if(res.data == "error code: 1005") {
36
- res = await gjWReq("dlMessage", `${id}?user=${user}&password=${pass}`);
37
- if(res.status == 403) throw new Error(res.data.error);
38
- return res.data;
39
- }
40
-
41
- return decMessage(res.data);
26
+ let s = res.data.split(":");
27
+ return {
28
+ username: s[1],
29
+ title: Buffer.from(s[9], "base64").toString(),
30
+ content: xor.decrypt(s[15], 14251),
31
+ playerID: Number(s[3]),
32
+ accountID: Number(s[5]),
33
+ messageID: Number(s[7]),
34
+ age: s[17]
42
35
  }
36
+ }
43
37
  }
@@ -1,42 +1,29 @@
1
1
  module.exports = {
2
- /**
3
- * Gets the list of account posts of a specified user.
4
- * @param {*} str - The user's name.
5
- * @param {*} page - The page.
6
- */
7
- getAccountPosts:
8
- async function(str, page = 1) {
9
- if(!str) throw new Error("Please provide a user ID or name!");
10
- let GJDecode = require("../misc/GJDecode.js");
11
- const { decodeAccountPost } = new GJDecode();
12
- const {gjReq} = require("../misc/gjReq.js");
13
- const {gjWReq} = require("../misc/gjWReq.js");
14
- const { searchUsers } = require("./searchUsers.js");
2
+ getAccountPosts: async function (str, page = 1) {
3
+ if (!str) throw new Error("Please provide a player ID or name!");
4
+ const { gjReq } = require("../gjReq");
15
5
 
16
- let user = await searchUsers(str);
6
+ let search = await gjReq("getGJUsers20", {
7
+ str: str,
8
+ secret: "Wmfd2893gb7"
9
+ });
10
+ if (search.data == -1) return [];
11
+ let targetAccID = search.data.split(":")[21];
17
12
 
18
- let ACdata = {
19
- accountID: user.accountID,
20
- secret: "Wmfd2893gb7",
21
- page: page - 1
22
- };
13
+ let res = await gjReq("getGJAccountComments20", {
14
+ accountID: targetAccID,
15
+ secret: "Wmfd2893gb7",
16
+ page: page - 1
17
+ })
18
+ if (res.data == -1) throw new Error("-1 Not found.");
19
+ if (res.data.startsWith("#")) return [];
23
20
 
24
- let res = await gjReq("getGJAccountComments20", ACdata);
25
- if(res.data == -1) throw new Error("-1 Not found.");
26
- if(res.data.startsWith("#")) throw new Error("Whoops! Couldn't find anything!");
21
+ let accPosts = res.data.split("#")[0].split("|");
22
+ let result = [];
23
+ accPosts.forEach(p => {
24
+ result.push({ content: Buffer.from(p.split("~")[1], "base64").toString(), likes: Number(p.split("~")[3]), age: p.split("~")[5], id: Number(p.split("~")[7]) });
25
+ })
27
26
 
28
- if(res.data == "error code: 1005") {
29
- res = await gjWReq("getAccountPosts", `${str}?page=${page}`);
30
- if(res.status == 403) throw new Error(res.data.error);
31
- return res.data;
32
- }
33
-
34
- let accPosts = res.data.split("|");
35
- let result = [];
36
- accPosts.forEach(p => {
37
- result.push(decodeAccountPost(p));
38
- })
39
-
40
- return result;
41
- }
27
+ return result;
28
+ }
42
29
  }