Added song verification checking
This commit is contained in:
parent
ea5c732c75
commit
8f71e596bf
6 changed files with 137 additions and 42 deletions
30
api/song.js
Normal file
30
api/song.js
Normal 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
BIN
assets/btn-check.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 53 KiB |
BIN
assets/x.png
Normal file
BIN
assets/x.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 4.8 KiB |
119
html/api.html
119
html/api.html
|
@ -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">
|
||||
|
|
|
@ -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)
|
||||
|
|
1
index.js
1
index.js
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue