Added song verification checking

This commit is contained in:
GDColon 2021-01-05 11:03:04 -05:00
parent ea5c732c75
commit 8f71e596bf
6 changed files with 137 additions and 42 deletions

30
api/song.js Normal file
View file

@ -0,0 +1,30 @@
const request = require('request')
let newSong = 732000 // rough estimate of the point when the whitelisted song system was implemented. (around march 1st, 2017)
module.exports = async (app, req, res) => {
let info = {error: true, exists: false, artist: { name: "", scouted: false, whitelisted: false }, song: { name: "", externalUse: false, allowed: false } }
if (app.offline) return res.send(info)
let songID = req.params.song
request.post(app.endpoint + 'testSong.php?songID=' + songID, req.gdParams(), async function(err, resp, body) {
if (err || !body || body == '-1' || body.startsWith("<!")) return res.send(info)
let artistInfo = body.split(/<\/?br>/)
info.artist.name = artistInfo[0].split(": ")[1]
info.exists = info.artist.name.length > 0
info.artist.scouted = artistInfo[2].split("is NOT").length == 1
info.artist.whitelisted = artistInfo[1].split("is NOT").length == 1
info.song.name = artistInfo[4].split(": ")[1]
info.song.externalUse = artistInfo[5].split("API NOT").length == 1
info.song.allowed = info.artist.scouted && info.song.externalUse && (+songID > newSong ? info.artist.whitelisted : true)
delete info.error
res.send(info)
})
}

BIN
assets/btn-check.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 53 KiB

BIN
assets/x.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.8 KiB

View file

@ -52,6 +52,7 @@
<div class="category-name">Misc</div>
<div class="category-content">
<a class="header-link" href="#analyze">Level Analysis</a>
<a class="header-link" href="#artist">Song Verification</a>
<a class="header-link" href="#icons">Icons</a>
</div>
</div>
@ -529,47 +530,6 @@
</div>
<div class="seperator"></div>
</main>
<main>
<div id="analyze" class="anchor"></div>
<div class="main-block">
<h1>Level Analysis</h1>
<p>/api/analyze/levelID</p>
<p>Analyzes a level's data</p>
<p><sb>Level analysis is updated a lot so there may be changes in the future</sb></p>
<br>
<p class="reveal" onclick="$('#params-analyze').slideToggle(100)"><b>Parameters (0)</b></p>
<div class="subdiv" id="params-analyze">
<p>No parameters for this one!</p>
</div>
<br>
<p class="reveal" onclick="$('#response-analyze').slideToggle(100)"><b>Response (12)</b></p>
<div class="subdiv" id="response-analyze">
<p><b>Response is subject to change in the future</b></p>
<p>The API will return an array of each player with the following information:</p>
<p>level: Basic level info (name, ID, author, etc)</p>
<p>settings: The level's settings (song offset, starting form/speed, two player mode, font, etc)</p>
<p>portals: A string listing the order of all the portals in the level + their percent. Does not include starting form/speed</p>
<p>orbs: How many of each jump ring is in the level</p>
<p>triggers: How many of each trigger is in the level</p>
<p>blocks: How many of each block type is in the level</p>
<p>triggerGroups: How many of each group ID is in the level</p>
<p>misc: Amount of objects that aren't categorized above (glow, arrows, clouds, pickups, etc)</p>
<p>colors: The level's initial color channels. Contains channel, R, G, B, opacity, player color, blending, and copied channel</p>
<p>text: An array of all the text objects in a level. ([text, percent])</p>
<p>dataLength: How long the level data is (spoilers - very)</p>
<p>data: The decrypted data of the level. And it's freakin' huge</p>
</div>
<br>
</div>
<div class="seperator"></div>
</main>
<main>
<div id="commenting" class="anchor"></div>
@ -765,6 +725,83 @@
<div class="seperator"></div>
</main>
<main>
<div id="artist" class="anchor"></div>
<div class="main-block">
<h1>Song Verification</h1>
<p>/api/song/songID</p>
<p>Checks if a song is allowed for use</p>
<p>For a song to be useable, the artist must be scouted on Newgrounds and the song must be enabled for external use.
<br>If the song was published after March 2017, the artist must also be whitelisted by a GD moderator.</p>
<br>
<p class="reveal" onclick="$('#params-analyze').slideToggle(100)"><b>Parameters (0)</b></p>
<div class="subdiv" id="params-analyze">
<p>No parameters for this one!</p>
</div>
<br>
<p class="reveal" onclick="$('#response-analyze').slideToggle(100)"><b>Response (8)</b></p>
<div class="subdiv" id="response-analyze">
<p>error: Appears if the GD servers rejected the request or not</p>
<p>exists: If the provided song exists on Newgrounds</p>
<p>artist.name: The name of the artist</p>
<p>artist.scouted: If the artist was scouted by a Newgrounds member</p>
<p>artist.whitelisted: If the artist was whitelisted by a Geometry Dash moderator</p>
<p>song.name: The name of the song</p>
<p>song.externalUse: If the song is allowed for external use</p>
<p>song.allowed: If the song is allowed for use in GD</p>
</div>
<br>
</div>
<div class="seperator"></div>
</main>
<main>
<div id="analyze" class="anchor"></div>
<div class="main-block">
<h1>Level Analysis</h1>
<p>/api/analyze/levelID</p>
<p>Analyzes a level's data</p>
<p><sb>Level analysis is updated a lot so there may be changes in the future</sb></p>
<br>
<p class="reveal" onclick="$('#params-analyze').slideToggle(100)"><b>Parameters (0)</b></p>
<div class="subdiv" id="params-analyze">
<p>No parameters for this one!</p>
</div>
<br>
<p class="reveal" onclick="$('#response-analyze').slideToggle(100)"><b>Response (12)</b></p>
<div class="subdiv" id="response-analyze">
<p><b>Response is subject to change in the future</b></p>
<p>The API will return an array of each player with the following information:</p>
<p>level: Basic level info (name, ID, author, etc)</p>
<p>settings: The level's settings (song offset, starting form/speed, two player mode, font, etc)</p>
<p>portals: A string listing the order of all the portals in the level + their percent. Does not include starting form/speed</p>
<p>orbs: How many of each jump ring is in the level</p>
<p>triggers: How many of each trigger is in the level</p>
<p>blocks: How many of each block type is in the level</p>
<p>triggerGroups: How many of each group ID is in the level</p>
<p>misc: Amount of objects that aren't categorized above (glow, arrows, clouds, pickups, etc)</p>
<p>colors: The level's initial color channels. Contains channel, R, G, B, opacity, player color, blending, and copied channel</p>
<p>text: An array of all the text objects in a level. ([text, percent])</p>
<p>dataLength: How long the level data is (spoilers - very)</p>
<p>data: The decrypted data of the level. And it's freakin' huge</p>
</div>
<br>
</div>
<div class="seperator"></div>
</main>
<main>
<div id="icons" class="anchor"></div>
<div class="main-block">

View file

@ -115,7 +115,14 @@
<div class="brownBox" id="songBox" style="position:absolute; bottom: 4%; left: 0; right: 0; width: 85vh; height: 20%; margin-left: auto; margin-right: auto;">
<div style="margin-left: 0.5%">
<h1 class="pre slightlySmaller" id="songname">[[SONGNAME]]</h1>
<h2 class="pre smaller">By: [[SONGAUTHOR]] <a class="songLink" href="https://[[SONGAUTHOR]].newgrounds.com" target="_blank"><img class="gdButton valign" src="../assets/more.png" width="12%"></a></h2>
<h2 class="pre smaller">By: [[SONGAUTHOR]]<!--
--><img id="scout" title="Artist is scouted" style="display: none; cursor: help; margin-left: 1.5%; filter: hue-rotate(-55deg);" class="valign" src="../assets/check.png" width="5%"><!--
--><img id="whitelist" title="Artist is whitelisted" style="display: none; cursor: help" class="valign" src="../assets/check.png" width="5%"><!--
--> <a class="songLink" href="https://[[SONGAUTHOR]].newgrounds.com" target="_blank"><img class="gdButton valign" src="../assets/more.png" width="12%"></a></h2>
<img id="checkSong" style="display: none; margin-top: 1%" class="gdButton valign" src="../assets/btn-check.png" width="16%">
<h3 id="songLoading" style="display: none; margin-top: 0.5%;">Loading...</h3>
<h3 id="songAllowed" style="display: none; margin-top: 0.5%; color: lime">Song is allowed for use</h3>
<h3 id="songNotAllowed" style="display: none; margin-top: 0.5%; color: red">Song is not allowed for use</h3>
</div>
<a class="songLink" href="https://www.newgrounds.com/audio/listen/[[SONGID]]" target="_blank"><img class="gdButton sideButton" src="../assets/playsong.png" style="position:absolute; right: 1%; top: 50%; width: 11%; height: auto;"></a>
</div>
@ -252,6 +259,7 @@ else $('.dailyLevel').remove()
if ("[[SONGID]]".startsWith("Level")) {
$('#songInfo').text('[[SONGID]]')
$('.songLink').hide()}
else $('#checkSong').show()
if ("[[INVALIDSONG]]" == "true") $('.songLink').hide()
if ("[[DISLIKED]]" == "true") $('#likeImg').attr('src', '../assets/dislike.png').css('transform', 'translateY(20%)')
@ -297,6 +305,25 @@ function deleteLevel() {
freeze = true;
}
$('#checkSong').click(function() {
$('#checkSong').hide()
$('#songLoading').show()
fetch(`../api/song/[[SONGID]]`).then(res => res.json()).then(info => {
$('#songLoading').hide()
$(info.song.allowed ? '#songAllowed' : '#songNotAllowed').show()
if (!info.artist.scouted) {
$('#scout').attr('src', '../assets/x.png')
$('#scout').attr('title', $('#scout').attr('title').replace('is ', 'is NOT '))
$('#scout').css('filter', 'saturate(0.4)')
}
if (!info.artist.whitelisted) {
$('#whitelist').attr('src', '../assets/x.png')
$('#whitelist').attr('title', $('#whitelist').attr('title').replace('is ', 'is NOT '))
}
$('#scout').show(); $('#whitelist').show()
})
})
// let like;
// let likedLevels = localStorage.likedLevels ? JSON.parse(localStorage.likedLevels) : []
// if (likedLevels.includes('[[ID]]')) $('#likeButton').attr('src', '../assets/voted.png').removeClass('gdButton').prop("onclick", null)

View file

@ -167,6 +167,7 @@ app.get("/api/level/:id", RL, async function(req, res) { app.run.level(app, req,
app.get("/api/mappacks", async function(req, res) { app.run.mappack(app, req, res) })
app.get("/api/profile/:id", RL2, function(req, res) { app.run.profile(app, req, res, api) })
app.get("/api/search/:text", RL2, function(req, res) { app.run.search(app, req, res) })
app.get("/api/song/:song", function(req, res){ app.run.song(app, req, res) })
// REDIRECTS