diff --git a/OAuth/index.php b/OAuth/index.php index 9ad4397..19f282c 100644 --- a/OAuth/index.php +++ b/OAuth/index.php @@ -18,7 +18,7 @@ else if (empty($_GET["code"])) $code = $_GET["code"]; include "../api_key.php"; -$final_uri = "http://zovguran.net/Unalike/"; +$final_uri = $unalike_root_public; $postdata = array( "client_id" => $client_id, diff --git a/displayed.php b/displayed.php new file mode 100644 index 0000000..c01e671 --- /dev/null +++ b/displayed.php @@ -0,0 +1,55 @@ + + + + <?php + if ($authenticated) + { + echo "" . $username . " |"; + } + ?> + Unalike + + + + + + + + + + +
+ + +
+
+
+

Lobbies

+
+
+ +
+
+ +
+
+
+

Match History

+
+
+ +
+
+ +
+ + + + + \ No newline at end of file diff --git a/handlers.js b/handlers.js new file mode 100644 index 0000000..233a44e --- /dev/null +++ b/handlers.js @@ -0,0 +1,101 @@ +function isEmpty(obj) { + for (var prop in obj) { + if (obj.hasOwnProperty(prop)) return false; + } + return true; +} + +function clearLocalStorage() { + Object.keys(localStorage).forEach(function(key) { + if (key.indexOf(localStoragePrefix) === 0) { + localStorage.removeItem(key); + } + console.log("Removed from local storage: " + key); + }); +} +function hiddenFunctionClick(element, url, destroyMode = 0) // 0 = nothing, 1 = disable, 2 = delete, 3 = disable siblings too +{ + if (!this.disabled) { + var clickRequest = new XMLHttpRequest(); + clickRequest.onreadystatechange = function() { }; + clickRequest.open("GET", url, true); + clickRequest.send(); + + if (destroyMode == 3) { + for (var sibling of element.parentElement.children) { + sibling.disabled = true; + } + } + else if (destroyMode == 2) { + element.outerHTML = ""; + } + else if (destroyMode == 1) { + element.disabled = true; + } + } +} + +function keyDownTextField(e) { + var keyCode = e.code; + var forceRefresh = false; + + if (keyCode == "KeyU") { + if (opMode) { + opMode = false; + } + else { + opMode = true; + } + forceRefresh = true; + } + else if (keyCode == "Digit1") { + randomCover = 1; + localStorage.setItem(localStoragePrefix + "lobbyCover", randomCover); + forceRefresh = true; + } + else if (keyCode == "Digit2") { + randomCover = 2; + localStorage.setItem(localStoragePrefix + "lobbyCover", randomCover); + forceRefresh = true; + } + else if (keyCode == "Digit3") { + randomCover = 3; + localStorage.setItem(localStoragePrefix + "lobbyCover", randomCover); + forceRefresh = true; + } + else if (keyCode == "Digit4") { + randomCover = 4; + localStorage.setItem(localStoragePrefix + "lobbyCover", randomCover); + forceRefresh = true; + } + else if (keyCode == "Digit5") { + randomCover = 5; + localStorage.setItem(localStoragePrefix + "lobbyCover", randomCover); + forceRefresh = true; + } + else if (keyCode == "Digit6") { + randomCover = 6; + localStorage.setItem(localStoragePrefix + "lobbyCover", randomCover); + forceRefresh = true; + } + else if (keyCode == "Digit7") { + randomCover = 7; + localStorage.setItem(localStoragePrefix + "lobbyCover", randomCover); + forceRefresh = true; + } + else if (keyCode == "Digit8") { + randomCover = 8; + localStorage.setItem(localStoragePrefix + "lobbyCover", randomCover); + forceRefresh = true; + } + else if (keyCode == "Digit9") { + randomCover = 9; + localStorage.setItem(localStoragePrefix + "lobbyCover", randomCover); + forceRefresh = true; + } + + if (forceRefresh) { + currentLobbiesContent = ""; + } +} +document.addEventListener("keydown", keyDownTextField, false); \ No newline at end of file diff --git a/index.php b/index.php index 501ab75..65b087d 100644 --- a/index.php +++ b/index.php @@ -103,1173 +103,5 @@ if ($authenticated) } } -$json_display = false; -?> - - - - <?php - if ($authenticated) - { - echo "" . $username . " |"; - } - ?> - Unalike - <?php - // echo " ・ Home"; - ?> - - - - - - - - - - -
-
-
-
-

- - -
- - - - Unalike - -
- - - Unalike Access: - Granted'; - } - else - { - echo 'Denied!!'; - } - ?> - - Log in to continue. - - -

-
- -

- - - - - Authorize this app again to get an access key. -

- Either your refresh token has expired, you have revoked access manually, or the application has been unregistered from the osu! api clients. -

- You might need to re-authorize this application from your account settings page. -

 

- - - - Please don't change the password because it breaks the invitation system. You are free to invite players, add any mods, change the team mode or win condition, and quit the match at any time, but the scores will only be evaluated after everyone has finished. - - -

- - - - Unalike is a lobby synchronization system that allows you and your friends to play the same song but on different difficulties. - The results are calculated based on your accuracy.

- Log in using your osu! account to get started. - -

-
- -
-

Loading...

-
-
- -
-
-
-

Lobbies

-
-
- -
-
- -
-
-
-

Match History

-
-
- -
-
- - - -
-
-

Unalike JSON

-
-

Player JSON

- "; - print_r($userJson); - echo ""; - } - $cover_url = ""; // some default pls - ?> -
-
- - -
- - - - - - - - - - - - \ No newline at end of file +require "displayed.php"; +?> \ No newline at end of file diff --git a/info-panel.php b/info-panel.php new file mode 100644 index 0000000..f80ce6c --- /dev/null +++ b/info-panel.php @@ -0,0 +1,63 @@ +
+
+
+

+ + +
+ + + + Unalike + +
+ + + Unalike Access: + Granted'; + } + else + { + echo 'Denied!!'; + } + ?> + + Log in to continue. + + +

+
+

+ + + Authorize this app again to get an access key. +

+ Either your refresh token has expired, you have revoked access manually, or the application has been unregistered from the osu! api clients. +

+ You might need to re-authorize this application from your account settings page. +

 

+ + BUG: Once all players are ready in a lobby, they remain ready until the map selector is opened or someone joins/leaves. +

+ + Please don't change the password because it breaks the invitation system. You are free to invite players, add any mods, change the team mode or win condition, and quit the match at any time, but the scores will only be evaluated after everyone has finished. Also, feel free to open slots and invite other friends to your difficulty, but the game will only start if everyone is ready. + + +

+ + + + Unalike is a lobby synchronization system that allows you and your friends to play the same song but on different difficulties. + The results are calculated based on your accuracy.

+ Log in using your osu! account to get started. + +

+
+ +
+

Loading...

+
+
\ No newline at end of file diff --git a/navbar.php b/navbar.php new file mode 100644 index 0000000..8e36adc --- /dev/null +++ b/navbar.php @@ -0,0 +1,16 @@ + \ No newline at end of file diff --git a/style.css b/style.css new file mode 100644 index 0000000..c6a4401 --- /dev/null +++ b/style.css @@ -0,0 +1,319 @@ +* { + box-sizing: border-box; +} +:root { + --void: #1c1719; + --background-darker: #2a2225; + --background: #382e32; + + --void-alt: #171a1c; + --background-alt: #2e3438; + + --text: #ffffff; + + --text-disabled: #dddddd; + --disabled: #5c5c5c; + + --positive: #3c9cc8; + --positive-dim: #4fb7e7; + + --negative: #c82838; + --negative-dim: #e73e4b; + + --link: #d7a5bc; + + --shadow: #000000; + --glow: #ffffff; +} +html { + font-family: "Lucida Grande", sans-serif; + color: var(--text); + font-size: 1.2em; + text-align: center; +} +body { + text-align: left; +} +html, body { + margin: 0; + padding: 0; + overflow-x: hidden; +} +.void-color { + background-color: var(--void); +} +.background-color { + background-color: var(--background); +} +.positive-color { + color: var(--positive); +} +.negative-color { + color: var(--negative); +} +a:link, a:visited, a:active, a:hover { + text-decoration: none; + color: var(--link); +} +.button-positive { + background-color: var(--positive); +} +.button-positive:hover { + background-color: var(--positive-dim); +} +.button-negative { + background-color: var(--negative); +} +.button-negative:hover { + background-color: var(--negative-dim); +} +h3 { + margin: 0; + padding: 30px 0; + font-weight: normal; + font-size: 1.5em; +} +p { + margin-top: 0; + text-align: justify; +} +.cover-image { + background-image: linear-gradient(rgba(0, 0, 0, 0.6), rgba(0, 0, 0, 0.6)), url(''); + background-size: cover; + font-weight: normal; + margin: 0 -50px; + border-top-left-radius: 10px; + border-top-right-radius: 10px; +} +a:hover, a:active { + text-decoration: underline; +} +.link-osu { + transition-duration: 0.3s; + text-shadow: 0px 0px 0px var(--shadow); +} +.link-osu:hover { + text-shadow:3px 3px 4px var(--shadow); +} +.card-container { + padding: 10px 20px; + display: flex; + flex-flow: row wrap; + align-content: center; + align-items: flex-start; + /* align-items: stretch; */ /* enable for disgusting-but-even containers */ + justify-content: flex-start; +} +.card-sub-container { + flex: 1 1 0; + display: flex; + flex-flow: column nowrap; + align-content: center; + align-items: stretch; + justify-content: flex-start; +} +.hr-osu { + flex: 2 0 100%; + padding: 0; + // margin: 0 -50px; + border: none; + background-color: var(--text); + height: 2px; + border-radius: 10px; +} +.card-osu { + flex: 1 0 auto; + min-width: 600px; + padding: 20px 50px; + margin: 0; + border-radius: 10px; + margin-bottom: 10px; + margin-right: 10px; +} +.card-osu-fullrow { + flex: 1 0 100%; +} +.card-osu-topless { + padding-top: 0px; +} +.button-osu { + font-family: inherit; + border: none; + color: var(--text); + min-width: 170px; + height: 44px; + line-height: 22px; + padding: 13px 20px; + border-radius:50px; + font-size: 0.8em; + font-weight: bold; +} +.button-osu-round { + height: 44px; + min-width: 44px; + padding: 12px; + width: 44px; + line-height: 22px; + border-radius:50%; +} +.button-osu:active { + box-shadow: 0 0 3px var(--glow); + transition-duration: 0.2s; +} +.button-osu:disabled { + transition-duration: 0.2s; + color: var(--text-disabled); + background-color: var(--disabled); +} +.button-osu-management { + display: flex; + flex-flow: row wrap; + flex: 1 0 0; + margin: 10px; + padding-right: 30px; + min-width: 200px; + text-align: center; +} +.button-osu-management-container { + display: flex; + flex-flow: row wrap; + align-items: stretch; + align-content: flex-start; + justify-content: space-evenly; +} +.button-symbol { + flex: 0 0 0; +} +.button-label { + flex: 2 0 auto; + text-align: center; + width: auto; + margin: 0; +} +.card-title { + text-align: center; +} +.card-avatar { + width: 120px; + height: 120px; + border-radius: 50%; + margin-bottom: 30px; +} +.card-right { + text-align: right; +} +.navbar { + margin-bottom: 5px; + margin: 10px 30px 0 20px; + padding: 20px 50px; + border-radius: 10px; + min-width: 600px; + height: 80px; + white-space: nowrap; + overflow: hidden; +} +.navbar-title { + float: left; + margin: -10px 0 0 -10px; + padding-top: 6px; + white-space: nowrap; + text-overflow: ellipsis; + overflow: hidden; +} +.navbar-logo { + display: inline-block; + height: 50px; + width: 50px; + background: url('img/favicon/128.png'); + background-size: contain; +} +.navbar h2 { + display: inline-block; + margin: 10px 10px; + vertical-align: top; +} +.navbar-button { + line-height: 15px; + height: 40px; +} +.navbar-button-container { + position: absolute; + top: 0; + right: 0; + margin: 30px 80px 0 40px; +} +.link-spacer { + width: 20px; + display: inline-block; +} +.song-info { + text-align: left; + font-size: 1em; +} +.song-info, .song-info * { + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; +} +.song-title { + font-weight: normal; + font-size: 1.2em; +} +.song-artist { + font-weight: normal; + font-size: 1em; +} +.song-version { + font-weight: bold; + font-size: 1em; +} +.song-star-difficulty { + font-weight: normal; + font-size: 1em; +} +.scores { + font-size: 0.6em; + width: 100%; + border-radius: 10px; + overflow: hidden; +} +.scores, .scores tr, .scores td { + border: none; + border-collapse: collapse; +} +.scores .rowspan { + font-size: 1.5em; + padding: 30px 15px; +} +.scores .row-upper { + vertical-align: bottom; +} +.scores .row-lower { + vertical-align: top; +} +.scores .row-upper, .scores .row-lower { + max-width: 100px; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; +} +.scores .score-accuracy { + text-align: right; +} +.scores .score-place { + padding-right: 0; + width: 40px; +} +.scores .score-name { + padding-left: 0; +} +.scores .score-status { + font-weight: bold; + margin-right: 10px; +} +.scores tr:nth-child(4n), .scores tr:nth-child(4n-1) { + background-color: var(--background-darker); +} +#multiplayer-stats { + align-items: flex-start; +} \ No newline at end of file diff --git a/templates.js b/templates.js new file mode 100644 index 0000000..0b8a5a3 --- /dev/null +++ b/templates.js @@ -0,0 +1,72 @@ +var multiplayerMatchTemplate = ` + + `; + +var buttonsTitle = ` + +
+ `; + +var buttonsEnd = ` +
+ `; + +var buttonsIfOffline = ` + + `; + +var buttonsIfOnline = ` + +
+ + + + `; + +var opButtons = ` +
+ + + +
+ + + `; + +var opButtonsEnd = ` +

(Power mode is enabled!)

+ `; + +buttonsIfOffline = buttonsTitle + buttonsIfOffline + buttonsEnd; +opButtonsIfOnline = buttonsTitle + buttonsIfOnline + opButtons + buttonsEnd + opButtonsEnd; +buttonsIfOnline = buttonsTitle + buttonsIfOnline + buttonsEnd; diff --git a/updater.js b/updater.js new file mode 100644 index 0000000..cafc61d --- /dev/null +++ b/updater.js @@ -0,0 +1,492 @@ +var localStorage = window.localStorage; +var localStoragePrefix = "unalike-"; + +var refreshFrequency = 5000; +var maxUpdateDelayTolerance = 30; +var defaultLobbyContent = '

No lobbies are open.

'; +var defaultMultiplayerContent = '

History is empty.

'; +var lobbyTemplate = '

Template loading...

'; +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; + + +var randomCover = (Math.floor(Math.random() * 8)+1); + +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 = '

Unalike: Offline

Unalike is not running.

'; + 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 = '

Unalike: Online

Unalike is up.

'; + + 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 += "

" + unalikeJson.roundsPlayed + " game" + plural + " been played since boot."; + } + + if (unalikeJson.delay) { + newStatus += "

Current delay: " + unalikeJson.delay + " seconds between commands. (~" + unalikeJson.delay*4 + " seconds to create a lobby.)"; + } + // 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 += "

  • " + player + "
  • "; + if (session_username == player) + { + playerList.push('' + player + ''); + } + else + { + playerList.push('' + player + ''); + } + } + // playerList = '

    Players:

    ' + + // ''; + playerList = '

    Players: ' + playerList.join(", ") + '

    '; + } + else + { + // playerList += "

    No one is in the lobby.

    "; + } + + var title = 'Loading...
    ' + + '
    ' + + '
    ' + + ''; + if (lobby.beatmap && lobby.beatmap > 0) { + var requestId = "songTitle" + counter++; + var title = '
    ' + title + '
    '; + songsInContent.push({ + "requestId":requestId, + "beatmapId":lobby.beatmap + }); + } + else if (lobby.beatmap && lobby.beatmap == -2) { + var title = 'Changing beatmap...
    ' + + '
    ' + + '
    ' + + ''; + } + else { + var title = 'No beatmap set.
    ' + + '
    ' + + '
    ' + + ''; + } + + 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) { + + lobbyTemplate = templateReply; + refreshData(); +} + +function updateSongInfo(elementId, beatmapId, beatmapJson) { + if (document.getElementById(elementId)) { + var content = ''; + if (beatmapJson.url) { + content += '
    '; + } + if (beatmapJson.beatmapset.title) { + content += '' + beatmapJson.beatmapset.title + '
    '; + } + else { + content += '
    '; + } + if (beatmapJson.beatmapset.artist) { + content += '' + beatmapJson.beatmapset.artist + " // " + beatmapJson.beatmapset.creator + '
    '; + } + else { + content += '
    '; + } + if (beatmapJson.version) { + content += '' + beatmapJson.version + '
    '; + } + else { + content += '
    '; + } + if (beatmapJson.difficulty_rating) { + content += '' + beatmapJson.difficulty_rating.toFixed(2) + '★'; + } + else { + content += ''; + } + + if (beatmapJson.url) { + content += '
    '; + } + + 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 += '
    '; + } + } + + 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 = "

    Game ID: " + game.game_id + "

    "; + for (var score of game.scores) { + newContent += "

    [#" + score.place + "] " + score.username + ": " + score.accuracy.toFixed(2) + "%

    "; + } + 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); + } +}