Added commenting!

This commit is contained in:
GDColon 2019-11-17 17:00:19 -05:00
parent bebf1eb1fd
commit 469ffaf4b7
10 changed files with 177 additions and 22 deletions

View file

@ -38,6 +38,7 @@ module.exports = async (app, req, res) => {
let comment = {}
comment.content = app.clean(Buffer.from(x[2], 'base64').toString());
comment.ID = x[6]
comment.likes = x[4]
comment.date = (x[9] || "?") + " ago"
if (req.query.type == "commentHistory") comment.levelID = x[1]

58
api/postComment.js Normal file
View file

@ -0,0 +1,58 @@
const request = require('request')
const XOR = require('../misc/XOR.js');
const xor = new XOR();
const crypto = require('crypto')
function sha1(data) { return crypto.createHash("sha1").update(data, "binary").digest("hex"); }
let rateLimit = {};
let cooldown = 10000
function getTime(time) {
let seconds = Math.ceil(time / 1000);
seconds = seconds % 60;
return seconds}
module.exports = async (app, req, res) => {
if (!req.body.comment) return res.status(400).send("No comment provided!")
if (!req.body.username) return res.status(400).send("No username provided!")
if (!req.body.levelID) return res.status(400).send("No level ID provided!")
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 (rateLimit[req.body.username]) return res.status(400).send(`Please wait ${getTime(rateLimit[req.body.username] + cooldown - Date.now())} seconds before posting another comment!`)
let params = {
gameVersion: '21',
binaryVersion: '35',
secret: app.secret,
percent: 0
}
params.comment = new Buffer(req.body.comment).toString('base64').replace(/\//g, '_').replace(/\+/g, "-")
params.gjp = xor.encrypt(req.body.password, 37526)
params.levelID = req.body.levelID
params.accountID = req.body.accountID
params.userName = req.body.username
let percent = parseInt(req.body.percent)
if (percent && percent > 0 && percent <= 100) params.percent = percent
let chk = params.userName + params.comment + params.levelID + params.percent + "0xPT6iUrtws0J"
chk = sha1(chk)
chk = xor.encrypt(chk, 29481)
params.chk = chk
console.log(params)
request.post('http://boomlings.com/database/uploadGJComment21.php', {
form: params
}, 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! Make sure your username and password are entered correctly.")
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);
})
}

BIN
assets/btn-submit.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 100 KiB

View file

@ -125,7 +125,7 @@ img, .noSelect {
}
p {
font-family: aller, helvetica;
font-family: aller, helvetica, arial;
color: white;
font-size: 2.9vh;
word-break: break-word;
@ -155,7 +155,7 @@ h2 {
text-shadow: -0.275vh -0.275vh 0vh #000, 0.275vh -0.275vh 0vh #000, -0.275vh 0.275vh 0vh #000, 0.275vh 0.275vh 0vh #000, 0.5vh 0.5vh 0vh rgba(0,0,0,0.4);
}
h3, input[type=text], input[type=number] {
h3, input[type=text], input[type=password], input[type=number] {
font-weight: normal;
margin: 0 0;
font-size: 3.5vh;
@ -177,7 +177,7 @@ hr {
background: -webkit-gradient(radial, 50% 50%, 0, 50% 50%, 500, from(rgba(255, 255, 255, 0.5)), to(rgba(0, 0, 0, 0)));
}
input[type=text], input[type=number] {
input[type=text], input[type=password], input[type=number] {
padding-left: 1.2%;
border-radius: 1vh;
height: 80%;
@ -190,6 +190,37 @@ input[type=checkbox] {
display: none;
}
textarea {
resize: none;
font-family: aller, helvetica, arial;
padding: 2% 1%;
border-radius: 1vh;
height: 18.5vh;
margin-top: 1%;
width: 90%;
font-size: 3vh;
color: white;
text-align: center;
word-break: break-word;
white-space: initial !important;
}
textarea::-webkit-scrollbar {
height: 8%;
width: 2.2%;
background: #6d3c24;
}
textarea::-webkit-scrollbar-thumb {
background: rgb(83, 47, 28);
overflow: hidden;
}
input:-webkit-autofill, input:-webkit-autofill:hover, input:-webkit-autofill:focus, input:-webkit-autofill:active {
-webkit-box-shadow: 0 0 0px 1000px #764F1A inset !important;
-webkit-text-fill-color: white !important;
}
.gdcheckbox {
vertical-align: middle;
display: inline-block;
@ -209,7 +240,12 @@ input[type=checkbox]:checked + label.gdcheckbox {
font-size: 4vh;
}
input:focus {
textarea::placeholder {
color: lightgray;
font-size: 3vh;
}
input:focus, textarea:focus {
outline: none;
}
@ -225,7 +261,7 @@ input:focus {
margin: 1% 1%
}
.transparentBox, input[type=text], input[type=number] {
.transparentBox, input[type=text], input[type=password], input[type=number], textarea {
border: 0 solid transparent;
border-radius: 2vh;
background-color: rgba(0, 0, 0, 0.3);
@ -437,7 +473,7 @@ input::-webkit-inner-spin-button {
width: 100%;
height: 100%;
top: 0; left: 0; right: 0; bottom: 0;
background-color: rgba(0,0,0,0.5);
background-color: rgba(0,0,0,0.6);
z-index: 2;
}
@ -646,7 +682,7 @@ input::-webkit-inner-spin-button {
display: inline-block;
width: 27%;
height: 21%;
margin: 2% 0%;
margin: 0% 0% 7.5% 0%;
}
.specialThanks h2 {

View file

@ -403,6 +403,7 @@
<div class="subdiv" id="response-comment">
<p>The API will return an array of each comment with the following information.<br>Values that don't work for profile posts are in <span style="color:red">red</span></p>
<p>content: The comment text</p>
<p>ID: The ID of the comment (used for liking and deleting)</p>
<p>likes: The number of likes the comment has</p>
<p>date: Time since the comment was posted (sent as "x days/weeks/months" ago, since it's all the API sends)</p>
<p class="red">levelID: The ID of the level [COMMENT HISTORY ONLY]</p>

View file

@ -12,6 +12,24 @@
<body class="levelBG" onbeforeunload="saveUrl()">
<div id="everything">
<div class="popup" id="postComment">
<div class="brownbox bounce center supercenter" style="height: 80%; width: 110vh">
<h1 class="smaller center" style="font-size: 5.5vh">Add Comment (Beta)</h1>
<textarea placeholder="Insert comment" id="content" maxlength="150" style="margin: 2% 0%"></textarea><br>
<form id="form" action="nothing lol">
<h3 class="center">GD Username</h3>
<input type="text" name="gdbrowser" id="username" maxlength="50" style="height: 8vh; width: 90%; text-align: center; margin-top: 0.5%"></textarea>
<h3 class="center" style="margin-top: 2%">GD Password</h3>
<input type="password" id="password" maxlength="50" style="height: 8vh; width: 90%; text-align: center; margin-top: 0.5%"></textarea>
</form>
<div style="min-height: 16%; max-height: 16%">
<p id="message" style="padding: 0% 10%; margin-top: 1.5%"></p>
</div>
<img src="../assets/btn-cancel.png" height=10%; class="postButton gdButton center" style="margin-right: 1%" onclick="$('#postComment').hide(); $('textarea').val('')">
<img src="../assets/btn-submit.png" type="submit" height=10%; class="postButton gdButton center" style="margin-left: 1%" id="submitComment">
</div>
</div>
<div style="position:absolute; bottom: 0%; left: 0%; width: 100%">
<img class="cornerPiece" src="../assets/corner.png" width=7%;>
@ -58,13 +76,13 @@
<h2 class="smallGold inline" id="levelVersion"></h2>
<a id="levelLink"><h2 class="smallGold inline gdButton" id="levelID" style="margin-left: 6vh"></h2></a>
</div>
<div style="position:absolute;bottom: 0%;right: 0%;width: 14%;text-align: right;transform: translate(30%, 40%);">
<img class="gdButton" src="../assets/comment.png" width="60%" onclick="$('#postComment').show()">
</div>
</div>
<div style="position:absolute; top: 2%; left: 1.5%; width: 10%; height: 25%; pointer-events: none">
<img class="gdButton yesClick" id="backButton" src="../assets/back.png" height="30%" onclick="backButton()">
</div>
</div>
</body>
@ -74,6 +92,8 @@
<script>
let {mode, compact} = JSON.parse(localStorage.getItem('commentPreset') || '{"mode": "top", "compact": true}')
let messageText = 'Your <span style="color: yellow">Geometry Dash password</span> will <span style="color: lime">not be stored</span> anywhere on the site, both <span style="color:rgb(113, 234, 255)">locally and server-side.</span> You can view the code used for posting a comment <a class="menuLink" target="_blank" href="https://github.com/GDColon/GDBrowser/blob/master/api/postComment.js">here</a>.'
$('#message').html(messageText)
let lvlID = window.location.pathname.split('/')[2]
let history = false;
@ -107,7 +127,6 @@ fetch(target).then(res => res.json()).then(lvl => {
}
else {
console.log(lvl)
if (lvl.accountID == undefined) $('#levelAuthor').remove()
else if (lvl.accountID == 0) {
$('#levelAuthor').addClass("green").addClass("unregistered")
@ -259,6 +278,40 @@ $('#refresh').click(function() {
appendComments()
})
$('#submitComment').click(function() {
let comment = $('#content').val()
let username = $('#username').val()
let password = $('#password').val()
let levelID = window.location.pathname.split('/')[2]
let accountID = 0
if (!content || !username || !password || loadingComments) return $('#postComment').hide()
$('#message').text("Posting comment...")
$('.postbutton').hide()
allowEsc = false
fetch(`../api/profile/${username}`).then(res => res.json()).then(res => {
if (!res || res == "-1") {$('.postbutton').show(); return $('#message').text("The username you provided doesn't exist!")}
else accountID = res.accountID
$.post("../postComment", {comment, username, password, levelID, accountID, })
.done(x => {
$('#content').val("")
$('#postComment').hide()
$('.postbutton').show()
$('#message').html(messageText)
$('#timeSort').attr('src', "../assets/sort-time-on.png")
$('#topSort').attr('src', "../assets/sort-likes.png")
allowEsc = true
mode = "time"
page = 0
appendComments()
})
.fail(e => {$('.postbutton').show();$('#message').text(e.responseText.includes("DOCTYPE") ? "Something went wrong..." : e.responseText)})
})
})
$(window).on('beforeunload ',function() {
//0 - recent, 1 - top, 2 - recent/compact, 3 - top/compact
localStorage.setItem('commentPreset', JSON.stringify({

View file

@ -94,14 +94,13 @@ infoText(accurateText)
function leaderboard() {
if (loading == true) return;
$('#searchBox').html(`<div style="height: 4.5%"></div>`)
loading = true;
$('#loading').show()
fetch(`../api/leaderboard?count=250&${type}`).then(res => res.json()).then(res => {
$('.ranking').remove()
res.forEach((x, y) => {
$('#searchBox').append(`<div class="searchresult leaderboardSlot">
@ -117,7 +116,7 @@ function leaderboard() {
${x.cp != 0 ? `${x.cp} <img class="valign" src="../assets/cp.png" style="cursor: help" title="Creator Points">` : ""}
</h3>
<div class="center"
<div class="center ranking"
style="position:absolute; top: ${6.5 + (y * 26.572)}%; left: 3.5%; transform:scale(0.82); height: 10%; width: 12.5%;">
<img class="spaced lazyLoad" data-src="./icon/${x.username}" height="150%"
style="margin-bottom: 0%; transform:scale(1.1)">
@ -127,7 +126,6 @@ function leaderboard() {
})
$('#searchBox').append('<div style="height: 4.5%"></div>')
loading = false;
$('#loading').hide();
$('.lazyLoad').Lazy({
appendScroll: '#searchBox'
@ -140,7 +138,7 @@ function leaderboard() {
leaderboard()
$('#topTabOff').click(function() {
if (type == "top" || loading) return;
if (type == "top") return;
type = "top"
leaderboard()
$('.leaderboardTab').hide();
@ -151,7 +149,7 @@ function leaderboard() {
})
$('#accurateTabOff').click(function() {
if (type == "accurate" || loading) return;
if (type == "accurate") return;
type = "accurate"
leaderboard()
$('.leaderboardTab').hide();
@ -162,7 +160,7 @@ function leaderboard() {
})
$('#creatorTabOff').click(function() {
if (type == "creator" || loading) return;
if (type == "creator") return;
type = "creator"
leaderboard()
$('.leaderboardTab').hide();

View file

@ -52,6 +52,10 @@ app.use('/difficulty', express.static(__dirname + '/assets/gdfaces', {maxAge: "7
app.use('/iconkitbuttons', express.static(__dirname + '/assets/iconkitbuttons', {maxAge: "7d"}));
app.use('/gdicon', express.static(__dirname + '/icons/iconkit', {maxAge: "7d"}));
app.post("/postComment", function(req, res) {
app.modules.postComment(app, req, res)
})
app.get("/api", function(req, res) {
res.sendFile(__dirname + "/html/api.html")
})

View file

@ -68,8 +68,10 @@
],
"specialThanks": [
["Qufyy", "qufy"],
["Qufy", "Qufy"],
["AlFas", "AlFas"],
["ViPriN", "ViPriN"]
["ViPriN", "ViPriN"],
["NeKitDS", "NeKitDS"],
["cos8o", "cos8o"]
]
}

View file

@ -34,8 +34,10 @@ function backButton() {
else window.location.href = "../../../../../"
}
let allowEsc = true;
$(document).keydown(function(k) {
if (k.keyCode == 27) { //esc
if (!allowEsc) return
k.preventDefault()
if ($('.popup').is(":visible")) $('.popup').hide();
else $('#backButton').trigger('click')