diff --git a/.gitignore b/.gitignore
index d0bb205..469feb6 100644
--- a/.gitignore
+++ b/.gitignore
@@ -64,3 +64,5 @@ typings/
# next.js build output
.next
+misc/secretStuff.json
+misc/secretStuff.json
diff --git a/api/messages/countMessages.js b/api/messages/countMessages.js
new file mode 100644
index 0000000..e10419c
--- /dev/null
+++ b/api/messages/countMessages.js
@@ -0,0 +1,29 @@
+const request = require('request')
+const XOR = require('../../classes/XOR.js');
+const xor = new XOR();
+
+module.exports = async (app, req, res) => {
+
+ if (!req.body.accountID) return res.status(400).send("No account ID provided!")
+ if (!req.body.password) return res.status(400).send("No password provided!")
+
+ let params = {
+ accountID: req.body.accountID,
+ targetAccountID: req.body.accountID,
+ gjp: xor.encrypt(req.body.password, 37526),
+ secret: app.secret,
+ gameVersion: app.gameVersion,
+ binaryVersion: app.binaryVersion,
+ }
+
+ request.post(app.endpoint + 'getGJUserInfo20.php', {
+ form: params
+ }, async function (err, resp, body) {
+
+ if (err || body == '-1' || body == '-2' || !body) return res.status(400).send("Error fetching profile! Make sure your username and password are entered correctly.")
+ let count = app.parseResponse(body)[38]
+ if (!count) return res.status(400).send("Error fetching unread messages!")
+ else res.status(200).send(count)
+ })
+
+}
\ No newline at end of file
diff --git a/api/messages/deleteMessage.js b/api/messages/deleteMessage.js
index 33f60a6..fd4d560 100644
--- a/api/messages/deleteMessage.js
+++ b/api/messages/deleteMessage.js
@@ -6,6 +6,7 @@ module.exports = async (app, req, res, api) => {
if (!req.body.accountID) return res.status(400).send("No account ID provided!")
if (!req.body.password) return res.status(400).send("No password provided!")
+ if (!req.body.id) return res.status(400).send("No message ID(s) provided!")
let params = {
accountID: req.body.accountID,
diff --git a/api/messages/fetchMessage.js b/api/messages/fetchMessage.js
index 6b95a84..a69361e 100644
--- a/api/messages/fetchMessage.js
+++ b/api/messages/fetchMessage.js
@@ -23,13 +23,17 @@ module.exports = async (app, req, res, api) => {
let x = app.parseResponse(body)
let msg = {}
msg.id = x[1];
- msg.playerID = x[2]
- msg.accountID = x[3]
+ msg.playerID = x[3]
+ msg.accountID = x[2]
msg.author = x[6]
msg.subject = Buffer.from(x[4], "base64").toString()
msg.content = xor.decrypt(x[5], 14251)
msg.date = x[7] + app.config.timestampSuffix
-
+ if (msg.subject.endsWith("☆")) {
+ msg.subject = msg.subject.slice(0, -1)
+ msg.browserColor = true
+ }
+
return res.status(200).send(msg)
})
diff --git a/api/messages/getMessages.js b/api/messages/getMessages.js
index 797ab42..da67e1d 100644
--- a/api/messages/getMessages.js
+++ b/api/messages/getMessages.js
@@ -4,6 +4,7 @@ const xor = new XOR();
module.exports = async (app, req, res, api) => {
+ if (req.body.count) return app.run.countMessages(app, req, res)
if (!req.body.accountID) return res.status(400).send("No account ID provided!")
if (!req.body.password) return res.status(400).send("No password provided!")
@@ -14,7 +15,7 @@ module.exports = async (app, req, res, api) => {
secret: app.secret,
gameVersion: app.gameVersion,
binaryVersion: app.binaryVersion,
- getSent: req.query.hasOwnProperty("sent") ? 1 : 0
+ getSent: req.query.sent ? 1 : 0
}
request.post(app.endpoint + 'getGJMessages20.php', {
@@ -29,12 +30,16 @@ module.exports = async (app, req, res, api) => {
let msg = {}
msg.id = x[1];
- msg.playerID = x[2]
- msg.accountID = x[3]
+ msg.playerID = x[3]
+ msg.accountID = x[2]
msg.author = x[6]
msg.subject = Buffer.from(x[4], "base64").toString()
msg.date = x[7] + app.config.timestampSuffix
msg.unread = x[8] != "1"
+ if (msg.subject.endsWith("☆")) {
+ msg.subject = msg.subject.slice(0, -1)
+ msg.browserColor = true
+ }
messageArray.push(msg)
})
diff --git a/api/messages/sendMessage.js b/api/messages/sendMessage.js
index 2028412..6afcad2 100644
--- a/api/messages/sendMessage.js
+++ b/api/messages/sendMessage.js
@@ -9,7 +9,7 @@ module.exports = async (app, req, res, api) => {
if (!req.body.accountID) return res.status(400).send("No account ID provided!")
if (!req.body.password) return res.status(400).send("No password provided!")
- let subject = new Buffer(req.body.subject.slice(0, 50) || "No subject").toString('base64').replace(/\//g, '_').replace(/\+/g, "-")
+ let subject = new Buffer(req.body.subject ? (req.body.subject.slice(0, 50) + (req.body.color ? "☆" : "")) : "No subject").toString('base64').replace(/\//g, '_').replace(/\+/g, "-")
let body = xor.encrypt(req.body.message.slice(0, 300), 14251)
let params = {
diff --git a/api/post/postComment.js b/api/post/postComment.js
index a3dec78..7a0f4be 100644
--- a/api/post/postComment.js
+++ b/api/post/postComment.js
@@ -50,6 +50,10 @@ module.exports = async (app, req, res) => {
}, function (err, resp, body) {
if (err) return res.status(400).send("The Geometry Dash servers returned an error! Perhaps they're down for maintenance")
if (!body || body == "-1") return res.status(400).send("The Geometry Dash servers rejected your comment! Try again later, or make sure your username and password are entered correctly.")
+ if (body.startsWith("temp")) {
+ let banStuff = body.split("_")
+ return res.status(400).send(`You have been banned from commenting for ${(parseInt(banStuff[1]) / 86400).toFixed(0)} days. Reason: ${banStuff[2]}`)
+ }
res.status(200).send(`Comment posted to level ${params.levelID} with ID ${body}`)
rateLimit[req.body.username] = Date.now();
setTimeout(() => {delete rateLimit[req.body.username]; }, cooldown);
diff --git a/assets/btn-cancel-green.png b/assets/btn-cancel-green.png
new file mode 100644
index 0000000..4ea722e
Binary files /dev/null and b/assets/btn-cancel-green.png differ
diff --git a/assets/btn-cancel.png b/assets/btn-cancel.png
index afa8724..3f8075c 100644
Binary files a/assets/btn-cancel.png and b/assets/btn-cancel.png differ
diff --git a/assets/btn-delete.png b/assets/btn-delete.png
index 3f48011..2d362f7 100644
Binary files a/assets/btn-delete.png and b/assets/btn-delete.png differ
diff --git a/assets/check.png b/assets/check.png
new file mode 100644
index 0000000..1004b57
Binary files /dev/null and b/assets/check.png differ
diff --git a/assets/css/browser.css b/assets/css/browser.css
index 5086e2e..2fcf0ff 100644
--- a/assets/css/browser.css
+++ b/assets/css/browser.css
@@ -41,6 +41,10 @@ img, .noSelect {
max-width: 100%;
}
+.fit {
+ width: fit-content;
+}
+
.supercenter {
position: absolute;
top: 50%;
@@ -302,6 +306,13 @@ input::-webkit-inner-spin-button {
border-image: url('./../assets/brownbox.png') 10% round;
}
+.blueBox {
+ border: 2.5vh solid transparent;
+ border-radius: 3vh;
+ background-color: #334499;
+ border-image: url('./../assets/bluebox.png') 10% round;
+}
+
.fancybox {
width: 69vh;
padding: 1vh 3vh;
@@ -412,16 +423,20 @@ input::-webkit-inner-spin-button {
height: 11%
}
+.msgAuthor:hover {
+ transform: scale(1.03);
+}
+
.gdButton {
cursor: pointer;
z-index: 1;
user-select: none;
pointer-events: all;
+ transition-duration: 0.07s;
+ transition-timing-function: ease-in-out;
}
.gdButton:active {
- transition-duration: 0.07s;
- transition-timing-function: ease-in-out;
transform: scale(1.08);
}
@@ -686,6 +701,110 @@ input::-webkit-inner-spin-button {
height: 5.5%;
}
+#msgList {
+ margin: 2% auto;
+ width: 115vh;
+ height: 75%;
+ background-color: #BE6F3F;
+ overflow-y: scroll;
+ scrollbar-width: none;
+ -ms-overflow-style: none;
+}
+
+#msgList::-webkit-scrollbar {
+ width: 0;
+ height: 0;
+}
+
+#theMfMessage {
+ margin: 2% auto 1.2% auto;
+ width: 90%;
+ height: 65%;
+ display: table;
+ padding: 1% 3%;
+}
+
+#theMfMessage p {
+ white-space: normal;
+ vertical-align: middle;
+ display: table-cell;
+ font-size: 3.5vh;
+}
+
+#messageOptions img {
+ margin: 0% 5%;
+}
+
+.gdMessage {
+ text-align: left;
+ padding-left: 10%;
+ padding-top: 0.75%;
+ height: 12.5vh;
+ width: auto;
+ overflow: hidden;
+ cursor: pointer;
+ border: 0.6vh solid transparent;
+ transition-duration: 0.07s;
+}
+
+.gdMessage h3 {
+ font-size: 4vh;
+ min-height: 35%;
+}
+
+.gdMessage:hover {
+ border: 0.6vh solid rgba(0, 0, 0, 0.5);
+}
+
+/* .gdMessage:active {
+ box-shadow: inset 0px 0px 400px 400px rgba(0, 0, 0, .1);
+} */
+
+.messageInput {
+ font-size: 3.5vh;
+ text-align: left;
+ padding: 1.5%;
+ overflow: hidden;
+ background-color: rgba(0, 0, 0, 0.35);
+}
+
+.labelButton {
+ pointer-events: none;
+ position: relative;
+ bottom: 90%;
+ right: 9.25%;
+}
+
+.labelButton label {
+ padding: 3% 3.5%;
+}
+
+.xButton {
+ pointer-events: none;
+ position: relative;
+ bottom: 152%;
+ text-align: right;
+ margin-right: 2.5%;
+}
+
+#selectCount {
+ position: absolute;
+ bottom: 7.5%;
+ left: 4.8%;
+ background-color: red;
+ width: 4.5vh;
+ height: 4.5vh;
+ border-radius: 10vh;
+ border: 0.25vh solid white;
+}
+
+.msgDate {
+ text-align: left;
+ font-size: 1.9vh;
+ color: rgba(0, 0, 0, 0.5);
+ margin-top: 0.4%;
+}
+
.specialThanks {
display: inline-block;
width: 27%;
diff --git a/assets/exclamation.png b/assets/exclamation.png
new file mode 100644
index 0000000..7b48e79
Binary files /dev/null and b/assets/exclamation.png differ
diff --git a/assets/messagerope.png b/assets/messagerope.png
new file mode 100644
index 0000000..1ec2a0f
Binary files /dev/null and b/assets/messagerope.png differ
diff --git a/assets/reply.png b/assets/reply.png
new file mode 100644
index 0000000..7a2db68
Binary files /dev/null and b/assets/reply.png differ
diff --git a/assets/select-all.png b/assets/select-all.png
new file mode 100644
index 0000000..d61a988
Binary files /dev/null and b/assets/select-all.png differ
diff --git a/assets/select-none.png b/assets/select-none.png
new file mode 100644
index 0000000..8c0dc8f
Binary files /dev/null and b/assets/select-none.png differ
diff --git a/assets/trash-square.png b/assets/trash-square.png
new file mode 100644
index 0000000..bbed186
Binary files /dev/null and b/assets/trash-square.png differ
diff --git a/assets/trash.png b/assets/trash.png
new file mode 100644
index 0000000..74746ca
Binary files /dev/null and b/assets/trash.png differ
diff --git a/assets/xbutton.png b/assets/xbutton.png
new file mode 100644
index 0000000..98789f2
Binary files /dev/null and b/assets/xbutton.png differ
diff --git a/classes/Level.js b/classes/Level.js
index e0364b0..6094bf4 100644
--- a/classes/Level.js
+++ b/classes/Level.js
@@ -1,5 +1,5 @@
-const XOR = require(__dirname + "../../classes/XOR");
-const config = require(__dirname + "../../misc/gdpsConfig");
+const XOR = require(__dirname + "/../classes/XOR");
+const config = require(__dirname + "/../misc/gdpsConfig");
let orbs = [0, 0, 50, 75, 125, 175, 225, 275, 350, 425, 500]
let length = ['Tiny', 'Short', 'Medium', 'Long', 'XL']
diff --git a/html/api.html b/html/api.html
index 05bf99e..df0c8c4 100644
--- a/html/api.html
+++ b/html/api.html
@@ -645,6 +645,7 @@
/messages:
page: The page of the search
sent: Set to 1 or true to fetch your sent messages
+count: Set to 1 or true to fetch your number of unread messages
/deleteMessage:
id: The ID of the message to delete, or an array of multiple IDs
@@ -653,6 +654,7 @@targetID: The account ID of the message recipient
subject: The subject of the message, max 50 characters
message: The content of the message, max 300 characters
+color: If the message should have a special pink color on GDBrowser (optional)