501 lines
15 KiB
JavaScript
501 lines
15 KiB
JavaScript
var localStorage = window.localStorage;
|
|
var localStoragePrefix = "unalike-";
|
|
|
|
var refreshFrequency = 5000;
|
|
var maxUpdateDelayTolerance = 30;
|
|
var defaultLobbyContent = '<div class="card-osu" style="text-align:center;"><h3>No lobbies are open.</h3></div>';
|
|
var defaultMultiplayerContent = '<div class="card-osu" style="text-align:center;"><h3>History is empty.</h3></div>';
|
|
var lobbyTemplate = '<div class="background-color card-osu"><h3>Template loading...</h3></div>';
|
|
var lobbyTemplate = '';
|
|
var refreshRequest = new XMLHttpRequest();
|
|
var templateRequest = new XMLHttpRequest();
|
|
var multiplayerRequest = new XMLHttpRequest();
|
|
var currentLobbiesContent = "initial";
|
|
var currentMultiplayerContent = "initial";
|
|
var onlineButtonSet = "initial";
|
|
var opMode = false;
|
|
|
|
var session_username = "Guest";
|
|
var session_username_irc = "Guest";
|
|
var session_user_id = -3;
|
|
<?php
|
|
if ($authenticated)
|
|
{
|
|
echo 'session_username = "' . $username . '"; ';
|
|
echo 'session_username_irc = "' . $username_irc . '"; ';
|
|
echo 'session_user_id = ' . $userid . '; ';
|
|
}
|
|
?>
|
|
|
|
var randomCover = (Math.floor(Math.random() * 8)+1);
|
|
<?php
|
|
if (!$authenticated)
|
|
{
|
|
echo 'randomCover = 3;';
|
|
}
|
|
?>
|
|
if (localStorage.getItem(localStoragePrefix + "lobbyCover")) {
|
|
randomCover = localStorage.getItem(localStoragePrefix + "lobbyCover");
|
|
}
|
|
refreshTemplate();
|
|
|
|
refreshRequest.onreadystatechange = function() {
|
|
if (this.readyState == 4 && this.status == 200) {
|
|
var result = JSON.parse(this.responseText);
|
|
updateUnalikeDisplay(result);
|
|
}
|
|
};
|
|
|
|
multiplayerRequest.onreadystatechange = function() {
|
|
if (this.readyState == 4 && this.status == 200) {
|
|
var result = JSON.parse(this.responseText);
|
|
updateMultiplayer(result);
|
|
}
|
|
};
|
|
|
|
function updateButtonSet(onlineState, force=false, full=false, empty=false) {
|
|
if (document.getElementById("management-buttons")) {
|
|
element = document.getElementById("management-buttons");
|
|
if (onlineButtonSet !== onlineState || force) {
|
|
onlineButtonSet = onlineState;
|
|
if (onlineButtonSet) {
|
|
var temp = buttonsIfOnline;
|
|
if (opMode) {
|
|
temp = opButtonsIfOnline;
|
|
}
|
|
|
|
if (full) {
|
|
temp = temp.replaceAll("putDisabledHere", "disabled");
|
|
}
|
|
|
|
if (empty) {
|
|
temp = temp.replaceAll("putDisabled2Here", "disabled");
|
|
}
|
|
|
|
element.innerHTML = temp;
|
|
}
|
|
else {
|
|
element.innerHTML = buttonsIfOffline;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
function updateUnalikeDisplay(unalikeJson) {
|
|
var thisUpdateInterval = 10; // in seconds
|
|
var thisUpdateIntervalIfLobby = 1;
|
|
var thisUpdateIntervalIfPlaying = 6;
|
|
|
|
var currentTimestamp = Math.floor(Date.now() / 1000);
|
|
if (unalikeJson.timestamp + maxUpdateDelayTolerance < currentTimestamp) {
|
|
unalikeJson = {}
|
|
}
|
|
|
|
statusDisplay = document.getElementById("unalike-status");
|
|
lobbiesContainer = document.getElementById("unalike-lobbies-container");
|
|
|
|
var oldLobbiesContent = currentLobbiesContent;
|
|
|
|
var newStatus = "";
|
|
if (isEmpty(unalikeJson)) {
|
|
newStatus = '<h3>Unalike: <span class="negative-colora">Offline</span></h3><p>Unalike is not running.</p>';
|
|
updateButtonSet(false);
|
|
|
|
if (lobbiesContainer.innerHTML.trim().replace(/\s/g, "") != defaultLobbyContent.trim().replace(/\s/g, "")) {
|
|
lobbiesContainer.innerHTML = defaultLobbyContent;
|
|
}
|
|
|
|
if (currentLobbiesContent != JSON.stringify(unalikeJson)) {
|
|
currentLobbiesContent = JSON.stringify(unalikeJson);
|
|
}
|
|
}
|
|
else {
|
|
newStatus = '<h3>Unalike: <span class="positive-colora">Online</span></h3><p>Unalike is up.</p>';
|
|
|
|
var full = false
|
|
var empty = false
|
|
if (unalikeJson.maxLobbies && !isEmpty(unalikeJson)) {
|
|
full = !(Object.keys(unalikeJson.lobbies).length < unalikeJson.maxLobbies)
|
|
}
|
|
if (!isEmpty(unalikeJson) && isEmpty(unalikeJson.lobbies)) {
|
|
updateButtonSet(true, false, full, true);
|
|
}
|
|
|
|
if (unalikeJson.roundsPlayed) {
|
|
var plural = "s have";
|
|
if (unalikeJson.roundsPlayed == 1) {
|
|
plural = " gas";
|
|
}
|
|
newStatus += "</p><p>" + unalikeJson.roundsPlayed + " game" + plural + " been played since boot.";
|
|
}
|
|
|
|
if (unalikeJson.delay) {
|
|
newStatus += "</p><p>Current delay: " + unalikeJson.delay + " seconds between commands. (~" + unalikeJson.delay*4 + " seconds to create a lobby.)";
|
|
}
|
|
|
|
if (unalikeJson.shutdownTimer) {
|
|
newStatus += "</p><p>If nothing happens, Unalike will shut down in " + unalikeJson.shutdownTimer + " seconds.";
|
|
}
|
|
|
|
if (unalikeJson.sessionAdmin) {
|
|
newStatus += "</p><p>" + unalikeJson.sessionAdmin + " was the first to interact with Unalike. Only he/she can shut it down on command.";
|
|
}
|
|
// dynamicJsonElement = document.getElementById("dynamic-json");
|
|
// dynamicJsonElement.innerHTML = JSON.stringify(unalikeJson);
|
|
|
|
if (!isEmpty(unalikeJson.lobbies)) {
|
|
if (unalikeJson.playing) {
|
|
thisUpdateInterval = thisUpdateIntervalIfPlaying;
|
|
}
|
|
else {
|
|
thisUpdateInterval = thisUpdateIntervalIfLobby;
|
|
}
|
|
|
|
var newLobbiesContent = "";
|
|
var songsInContent = [];
|
|
|
|
var counter = 2;
|
|
for (var lobby_id in unalikeJson.lobbies) {
|
|
var lobby = unalikeJson.lobbies[lobby_id];
|
|
var playerList = [];
|
|
|
|
if (!isEmpty(lobby.players)) {
|
|
for (var player of lobby.players) {
|
|
// playerList += "<li>" + player + "</li>";
|
|
if (session_username == player)
|
|
{
|
|
playerList.push('<span class="player positive-color">' + player + '</span>');
|
|
}
|
|
else
|
|
{
|
|
playerList.push('<span class="player">' + player + '</span>');
|
|
}
|
|
}
|
|
// playerList = '<p style="margin-bottom:0;">Players:</p>' +
|
|
// '<ul style="margin:10px 0;">' + playerList + '</ul>';
|
|
playerList = '<p style="margin-bottom:0;">Players: ' + playerList.join(", ") + '</p>';
|
|
}
|
|
else
|
|
{
|
|
// playerList += "<p>No one is in the lobby.</p>";
|
|
}
|
|
|
|
var title = '<span class="song-title">Loading...</span><br>' +
|
|
'<span class="song-artist"> </span><br>' +
|
|
'<span class="song-version"> </span><br>' +
|
|
'<span class="song-star-rating" style="opacity:0;">★</span>';
|
|
if (lobby.beatmap && lobby.beatmap > 0) {
|
|
var requestId = "songTitle" + counter++;
|
|
var title = '<div id="' + requestId + '">' + title + '</div>';
|
|
songsInContent.push({
|
|
"requestId":requestId,
|
|
"beatmapId":lobby.beatmap
|
|
});
|
|
}
|
|
else if (lobby.beatmap && lobby.beatmap == -2) {
|
|
var title = '<span class="song-title">Changing beatmap...</span><br>' +
|
|
'<span class="song-artist"> </span><br>' +
|
|
'<span class="song-version"> </span><br>' +
|
|
'<span class="song-star-rating" style="opacity:0;">★</span>';
|
|
}
|
|
else {
|
|
var title = '<span class="song-title">No beatmap set.</span><br>' +
|
|
'<span class="song-artist"> </span><br>' +
|
|
'<span class="song-version"> </span><br>' +
|
|
'<span class="song-star-rating" style="opacity:0;">★</span>';
|
|
}
|
|
|
|
var stateText = "Loading...";
|
|
var stateSymbol = "🔁";
|
|
var lobbyReady = true;
|
|
|
|
if (lobby.playing) {
|
|
stateSymbol = "▶️";
|
|
stateText = "Match in progress.";
|
|
}
|
|
else if (lobby.finished) {
|
|
stateSymbol = "⏸";
|
|
stateText = "Finished. Waiting others...";
|
|
}
|
|
else if (lobby.ready) {
|
|
if (unalikeJson.playing) {
|
|
stateSymbol = "🔁";
|
|
stateText = "Starting...";
|
|
}
|
|
else {
|
|
stateSymbol = "✅";
|
|
stateText = "Ready!";
|
|
}
|
|
}
|
|
else if (!isEmpty(lobby.players)) {
|
|
stateSymbol = "❎";
|
|
stateText = "Not ready.";
|
|
}
|
|
else if (lobby.password) {
|
|
stateSymbol = "🆙";
|
|
stateText = "Waiting for participants.";
|
|
}
|
|
else {
|
|
stateSymbol = "🆕";
|
|
stateText = "Setting up lobby...";
|
|
lobbyReady = false;
|
|
}
|
|
|
|
if (lobbyReady)
|
|
{
|
|
if (lobby.desynced) {
|
|
stateSymbol = "🔀 (Desynced)";
|
|
}
|
|
else if (lobby.beatmapset > 0 && lobby.beatmapset != unalikeJson.current_mapset)
|
|
{
|
|
stateSymbol = "🆘 (Desynced)";
|
|
}
|
|
}
|
|
var state = stateSymbol + " " + stateText;
|
|
|
|
var cover = "/Unalike/img/covers/c" + randomCover + ".jpg";
|
|
if (lobbyTemplate != '') {
|
|
var tempLobbyText = lobbyTemplate
|
|
.replaceAll("[[ SONG_INFO ]]", title)
|
|
.replaceAll("[[ PLAYERS ]]", playerList)
|
|
.replaceAll("[[ COVER_IMAGE ]]", cover)
|
|
.replaceAll("[[ CHANNEL ]]", lobby.match)
|
|
.replaceAll("[[ STATE ]]", state);
|
|
|
|
if (!lobbyReady) {
|
|
tempLobbyText = tempLobbyText.replaceAll("putDisabledHere", "disabled");
|
|
}
|
|
|
|
newLobbiesContent += tempLobbyText;
|
|
}
|
|
}
|
|
|
|
unalikeJson.timestamp = 0;
|
|
if (currentLobbiesContent != JSON.stringify(unalikeJson) ||
|
|
lobbiesContainer.innerHTML.trim().replace(/\s/g, "") == "" ||
|
|
lobbiesContainer.innerHTML.trim().replace(/\s/g, "") == defaultLobbyContent.trim().replace(/\s/g, "") ) {
|
|
|
|
lobbiesContainer.innerHTML = newLobbiesContent;
|
|
currentLobbiesContent = JSON.stringify(unalikeJson);
|
|
if (unalikeJson.maxLobbies) {
|
|
full = !(Object.keys(unalikeJson.lobbies).length < unalikeJson.maxLobbies)
|
|
}
|
|
updateButtonSet(true, true, full);
|
|
|
|
if (newLobbiesContent != "") {
|
|
for (var songInContent of songsInContent) {
|
|
refreshSongInfo(songInContent.requestId, songInContent.beatmapId);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
unalikeJson.timestamp = 0;
|
|
if (currentLobbiesContent != JSON.stringify(unalikeJson)) {
|
|
currentLobbiesContent = JSON.stringify(unalikeJson);
|
|
updateButtonSet(true, true, false, true);
|
|
}
|
|
|
|
if (lobbiesContainer.innerHTML != defaultLobbyContent) {
|
|
lobbiesContainer.innerHTML = defaultLobbyContent;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (statusDisplay.innerHTML != newStatus) {
|
|
statusDisplay.innerHTML = newStatus
|
|
}
|
|
|
|
if (currentLobbiesContent != oldLobbiesContent || currentLobbiesContent != oldLobbiesContent) {
|
|
refreshMultiplayer();
|
|
}
|
|
|
|
window.setTimeout(refreshData, thisUpdateInterval*1000)
|
|
}
|
|
|
|
function updateTemplate(templateReply) {
|
|
<?php
|
|
if (!$key_working)
|
|
{
|
|
echo 'templateReply = templateReply.replaceAll("putDisabledHere", "disabled");';
|
|
}
|
|
?>
|
|
lobbyTemplate = templateReply;
|
|
refreshData();
|
|
}
|
|
|
|
function updateSongInfo(elementId, beatmapId, beatmapJson) {
|
|
if (document.getElementById(elementId)) {
|
|
var content = '';
|
|
if (beatmapJson.url) {
|
|
content += '<a href="' + beatmapJson.url + '" class="link-osu" style="text-decoration:inherit;color:inherit;"><div>';
|
|
}
|
|
if (beatmapJson.beatmapset.title) {
|
|
content += '<span class="song-title">' + beatmapJson.beatmapset.title + '</span><br>';
|
|
}
|
|
else {
|
|
content += '<span class="song-title"> </span><br>';
|
|
}
|
|
if (beatmapJson.beatmapset.artist) {
|
|
content += '<span class="song-artist">' + beatmapJson.beatmapset.artist + " // " + beatmapJson.beatmapset.creator + '</span><br>';
|
|
}
|
|
else {
|
|
content += '<span class="song-artist"> </span><br>';
|
|
}
|
|
if (beatmapJson.version) {
|
|
content += '<span class="song-version">' + beatmapJson.version + '</span><br>';
|
|
}
|
|
else {
|
|
content += '<span class="song-version"> </span><br>';
|
|
}
|
|
if (beatmapJson.difficulty_rating) {
|
|
content += '<span class="song-star-rating">' + beatmapJson.difficulty_rating.toFixed(2) + '★</span>';
|
|
}
|
|
else {
|
|
content += '<span class="song-star-rating" style="opacity:0;">★</span>';
|
|
}
|
|
|
|
if (beatmapJson.url) {
|
|
content += '</div></a>';
|
|
}
|
|
|
|
var cover = beatmapJson.beatmapset.covers.cover;
|
|
if (beatmapJson.beatmapset.covers["cover@2x"]) {
|
|
cover = beatmapJson.beatmapset.covers["cover@2x"];
|
|
}
|
|
|
|
element = document.getElementById(elementId);
|
|
element.innerHTML = content
|
|
if (beatmapJson.beatmapset.covers.cover) {
|
|
element.parentElement.style.backgroundImage = "linear-gradient(rgba(0, 0, 0, 0.6), rgba(0, 0, 0, 0.6)), url('" + cover + "')";
|
|
element.parentElement.style.backgroundSize = "cover";
|
|
}
|
|
}
|
|
}
|
|
|
|
function updateMultiplayer(matchesJson) {
|
|
if (currentMultiplayerContent != JSON.stringify(matchesJson))
|
|
{
|
|
currentMultiplayerContent = JSON.stringify(matchesJson)
|
|
var newContent = "";
|
|
if (isEmpty(matchesJson)) {
|
|
newContent = defaultMultiplayerContent
|
|
}
|
|
else {
|
|
var elementPrefix = "multiplayerMatch";
|
|
var counter = 1;
|
|
for (var match of matchesJson) {
|
|
var eId = elementPrefix + counter++;
|
|
newContent += '<div id="' + eId + '" class="background-color card-osu card-osu-topless" style="flex: 1 0 0;"></div>';
|
|
}
|
|
}
|
|
|
|
if (document.getElementById("multiplayer-stats")) {
|
|
document.getElementById("multiplayer-stats").innerHTML = newContent;
|
|
|
|
var counter = 1;
|
|
for (var match of matchesJson) {
|
|
var eId = elementPrefix + counter++;
|
|
refreshMatchInfo(eId, match);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
function updateMatchInfoContent(elementId, matchContent) {
|
|
document.getElementById(elementId).innerHTML = matchContent;
|
|
}
|
|
|
|
function updateMatchInfo(elementId, matchJson) {
|
|
for (var game of matchJson.games) {
|
|
var newContent = "<h3>Game ID: " + game.game_id + "</h3>";
|
|
for (var score of game.scores) {
|
|
newContent += "<p>[#" + score.place + "] " + score.username + ": " + score.accuracy.toFixed(2) + "%</p>";
|
|
}
|
|
document.getElementById(elementId).innerHTML = newContent;
|
|
break;
|
|
}
|
|
}
|
|
|
|
function refreshData() {
|
|
refreshRequest.open("GET", "./async/?", true);
|
|
refreshRequest.send();
|
|
// console.log("Async request: ./async/?");
|
|
}
|
|
|
|
function refreshMultiplayer() {
|
|
multiplayerRequest.open("GET", "./async/match/?", true);
|
|
multiplayerRequest.send();
|
|
}
|
|
|
|
function refreshTemplate() {
|
|
var localItemName = localStoragePrefix + "lobby-template";
|
|
|
|
templateRequest.onreadystatechange = function() {
|
|
if (this.readyState == 4 && this.status == 200) {
|
|
localStorage.setItem(localItemName, this.responseText);
|
|
updateTemplate(this.responseText);
|
|
}
|
|
};
|
|
|
|
if (localStorage.getItem(localItemName)) {
|
|
updateTemplate(localStorage.getItem(localItemName));
|
|
}
|
|
else {
|
|
templateRequest.open("GET", "./async/lobby-template.html", true);
|
|
templateRequest.send();
|
|
console.log("Async request: ./async/lobby-template.html");
|
|
}
|
|
}
|
|
|
|
function refreshSongInfo(elementId, beatmapId) {
|
|
var songInfoRequest = new XMLHttpRequest();
|
|
var localItemName = localStoragePrefix + "beatmap-" + session_username + "-" + beatmapId;
|
|
|
|
songInfoRequest.onreadystatechange = function() {
|
|
if (this.readyState == 4 && this.status == 200) {
|
|
var eId = elementId;
|
|
var bId = beatmapId;
|
|
var result = JSON.parse(this.responseText);
|
|
localStorage.setItem(localItemName, this.responseText);
|
|
updateSongInfo(eId, bId, result);
|
|
}
|
|
};
|
|
|
|
if (localStorage.getItem(localItemName)) {
|
|
var localJson = JSON.parse(localStorage.getItem(localItemName));
|
|
updateSongInfo(elementId, beatmapId, localJson);
|
|
}
|
|
else {
|
|
var playerName = session_username;
|
|
songInfoRequest.open("GET", "./API/" + playerName + "/b/" + beatmapId, true);
|
|
songInfoRequest.send();
|
|
console.log("Async request: ./API/" + playerName + "/b/" + beatmapId);
|
|
}
|
|
}
|
|
|
|
function refreshMatchInfo(elementId, ualMatchId) {
|
|
var matchInfoRequest = new XMLHttpRequest();
|
|
var localItemName = localStoragePrefix + "multiplayer-" + session_username + "-" + ualMatchId;
|
|
|
|
matchInfoRequest.onreadystatechange = function() {
|
|
if (this.readyState == 4 && this.status == 200) {
|
|
var eId = elementId;
|
|
// var result = JSON.parse(this.responseText);
|
|
localStorage.setItem(localItemName, this.responseText);
|
|
updateMatchInfoContent(eId, this.responseText);
|
|
}
|
|
};
|
|
|
|
if (localStorage.getItem(localItemName)) {
|
|
updateMatchInfoContent(elementId, localStorage.getItem(localItemName));
|
|
|
|
}
|
|
else {
|
|
matchInfoRequest.open("GET", "./async/match/?render&select=" + ualMatchId, true);
|
|
matchInfoRequest.send();
|
|
console.log("Async request: ./async/match/?render&select=" + ualMatchId);
|
|
}
|
|
}
|