-
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
7 changed files
with
1,199 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
/* | ||
Hello epic hacker (maybe skid) you are looking at one of the many scripts that powers the site, | ||
this script has extra comments and info to help you understand what is going on. | ||
This script fetches version information from two JSON files and displays the current version and a warning message | ||
if the user is not on the latest released version. | ||
*/ | ||
|
||
// An asynchronous function is defined and immediately invoked. | ||
(async () => { | ||
// The 'version' and 'version-warning' elements are assigned to variables. | ||
var version = document.getElementById("version"); | ||
var versionWarning = document.getElementById("version-warning"); | ||
|
||
// Two variables are defined to hold version information. | ||
var currentVersion; | ||
var latestVersion; | ||
|
||
// A fetch request is made to a local 'info.json' file to get the current version information. | ||
try { | ||
var infoFetch = await fetch(location.origin + "./assets/json/info.json"); | ||
try { | ||
var infoResult = await infoFetch.json(); | ||
// If the current version information is available in the JSON file, it is assigned to the 'currentVersion' variable. | ||
if (infoResult.version) { | ||
currentVersion = infoResult.version; | ||
} | ||
} catch {} | ||
} catch {} | ||
|
||
// A fetch request is made to a remote 'info.json' file to get the latest version information. | ||
try { | ||
var infoFetch = await fetch("https://raw.githack.com/3kh0/3kh0.github.io/main/assets/json/info.json"); | ||
try { | ||
var infoResult = await infoFetch.json(); | ||
// If the latest version information is available in the JSON file, it is assigned to the 'latestVersion' variable. | ||
if (infoResult.version) { | ||
latestVersion = infoResult.version; | ||
} | ||
} catch {} | ||
} catch {} | ||
|
||
// The 'version' element is updated with the current version information, if available. | ||
if (currentVersion) { | ||
version.innerText = "You are on version " + currentVersion; | ||
} else { | ||
version.innerText = "Cannot get current version."; | ||
} | ||
|
||
// Messages are defined for different scenarios where the user is not on the latest released version. | ||
var oldMessage = "Warning: You are on a older version. The current version is %VERSION%"; | ||
var betaMessage = "You are on a pre-release version! The current release is %VERSION%"; | ||
var otherMessage = "You not on the currently released version. The current release is %VERSION%"; | ||
|
||
// If the latest version information is available and the current version is not the latest, a warning message is displayed to the user. | ||
if (latestVersion && currentVersion !== latestVersion) { | ||
// The version numbers are extracted from the version information and converted to a comparable format. | ||
var latestVersionNumber = latestVersion.replace("v", "").replaceAll("-", "."); | ||
var firstStr = latestVersionNumber.search(/\./) + 1; | ||
latestVersionNumber = Number(latestVersionNumber.substr(0, firstStr) + latestVersionNumber.slice(firstStr).replace(/\./g, "")); | ||
|
||
var currentVersionNumber = currentVersion.replace("v", "").replaceAll("-", "."); | ||
var firstStr2 = currentVersionNumber.search(/\./) + 1; | ||
currentVersionNumber = Number(currentVersionNumber.substr(0, firstStr2) + currentVersionNumber.slice(firstStr2).replace(/\./g, "")); | ||
|
||
var message; | ||
|
||
// Depending on the version comparison, a message is selected from the previously defined messages. | ||
if (isNaN(latestVersionNumber) || isNaN(currentVersionNumber)) { | ||
message = otherMessage; | ||
} else { | ||
if (currentVersionNumber > latestVersionNumber) { | ||
message = betaMessage; | ||
} else { | ||
message = oldMessage; | ||
} | ||
} | ||
|
||
// The 'version-warning' element is updated with the warning message and displayed. | ||
versionWarning.innerText = betaMessage.replace("%VERSION%", latestVersion); | ||
versionWarning.style.display = "block"; | ||
} | ||
})(); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,211 @@ | ||
/* | ||
Hello epic hacker (maybe skid) you are looking at one of the many scripts that powers the site, | ||
this script has extra comments and info to help you understand what is going on. | ||
This is a JavaScript code that creates a game catalog page with a search feature, | ||
a game detail page, and the ability to save and load user data. | ||
It uses fetch to load game data from a JSON file, creates game elements for each game, | ||
and adds click event listeners to show the game in a game container. | ||
The code also includes functions to handle saving and loading user data as well as a function to handle a specific key sequence. | ||
*/ | ||
// Select the elements | ||
const gamesContainer = document.querySelector('.games'); | ||
const searchBar = document.querySelector('.searchbar'); | ||
const gameContainer = document.querySelector('.gamecontainer'); | ||
const gameFrame = gameContainer.querySelector('.frame'); | ||
const gameNav = gameContainer.querySelector('.nav'); | ||
|
||
// Listen for input event on the search bar | ||
searchBar.addEventListener('input', (e) => { | ||
const query = searchBar.value.trim().toLowerCase(); | ||
|
||
// Loop through all the games in the container and show/hide them depending on whether they match the search query | ||
for (let game of gamesContainer.children) { | ||
if (game instanceof Element) { | ||
if (query) { | ||
const gameName = game.querySelector('span').innerText.trim().toLowerCase(); | ||
if (gameName.includes(query)) { | ||
game.removeAttribute('hidden'); | ||
} else { | ||
game.setAttribute('hidden', ''); | ||
} | ||
} else { | ||
game.removeAttribute('hidden'); | ||
} | ||
} | ||
} | ||
|
||
// If there are no games shown, display the "No games" message, otherwise hide it | ||
if (document.querySelectorAll('.game:not([hidden])').length == 0) { | ||
document.querySelector('.nogames').style.display = 'initial'; | ||
} else { | ||
document.querySelector('.nogames').style.display = 'none'; | ||
} | ||
}); | ||
|
||
// Fetch the games data from a JSON file | ||
fetch('./assets/json/games.json') | ||
.then((res) => res.json()) | ||
.then((games) => { | ||
// Loop through each game and create a new game element for it | ||
games.forEach((game) => { | ||
const gameEl = document.createElement('div'); | ||
gameEl.className = 'game'; | ||
gameEl.innerHTML = `<img src="${cdn + "/" + game.root + "/" + game.img}" onerror="this.src='./assets/globe.svg'"/><span>${game.name}</span>`; | ||
gamesContainer.appendChild(gameEl); | ||
|
||
// Add click event listener to the game element to show the game in the game container | ||
gameEl.onclick = (e) => { | ||
gamesContainer.classList.add('hidden'); | ||
searchBar.classList.add('hidden'); | ||
gameContainer.classList.remove('hidden'); | ||
document.querySelector('.saveItems').classList.add('hidden'); | ||
document.querySelector('.navbar').classList.add('noshadow'); | ||
gameFrame.querySelector('iframe').src = `./assets/game?game=${game.root}`; | ||
gameNav.querySelector('span').textContent = game.name; | ||
}; | ||
|
||
// Add click event listener to the back button in the game container to go back to the games list | ||
gameNav.querySelector('#back').addEventListener('click', (e) => { | ||
gamesContainer.classList.remove('hidden'); | ||
searchBar.classList.remove('hidden'); | ||
gameContainer.classList.add('hidden'); | ||
document.querySelector('.saveItems').classList.remove('hidden'); | ||
document.querySelector('.navbar').classList.remove('noshadow'); | ||
gameFrame.src = ''; | ||
}); | ||
|
||
// Add click event listener to the fullscreen button in the game container to enter fullscreen mode | ||
gameNav.querySelector('#fullscreen').addEventListener('click', (e) => { | ||
if (!document.fullscreenElement) { | ||
gameFrame.requestFullscreen(); | ||
} | ||
}); | ||
}); | ||
}) | ||
.catch((e) => { | ||
alert('Could not load games'); | ||
alert(e); | ||
}); | ||
|
||
// Hide the spinner element after the page is loaded | ||
document.querySelector('.spinner').style.display = 'none'; | ||
|
||
// Function to get the main save data | ||
function getMainSave() { | ||
var mainSave = {}; | ||
|
||
// List of items in localStorage that should not be saved | ||
var localStorageDontSave = ['theme', 'tab', 'nebelung']; | ||
|
||
// Convert localStorage to an array of key-value pairs and remove the items that should not be saved | ||
localStorageSave = Object.entries(localStorage); | ||
|
||
for (let entry in localStorageSave) { | ||
if (localStorageDontSave.includes(localStorageSave[entry][0])) { | ||
localStorageSave.splice(entry, 1); | ||
} | ||
} | ||
|
||
// Convert the localStorage array to a base64-encoded JSON string | ||
localStorageSave = btoa(JSON.stringify(localStorageSave)); | ||
|
||
// Add the localStorage data to the mainSave object | ||
mainSave.localStorage = localStorageSave; | ||
|
||
// Get the cookies data and add it to the mainSave object | ||
cookiesSave = document.cookie; | ||
cookiesSave = btoa(cookiesSave); | ||
mainSave.cookies = cookiesSave; | ||
|
||
// Convert the mainSave object to a base64-encoded JSON string | ||
mainSave = btoa(JSON.stringify(mainSave)); | ||
|
||
// Encrypt the mainSave data using AES encryption with the key 'save' | ||
mainSave = CryptoJS.AES.encrypt(mainSave, 'save').toString(); | ||
|
||
// Return the encrypted mainSave data | ||
return mainSave; | ||
} | ||
|
||
// Function to download the main save data as a file | ||
function downloadMainSave() { | ||
var data = new Blob([getMainSave()]); | ||
var dataURL = URL.createObjectURL(data); | ||
|
||
var fakeElement = document.createElement('a'); | ||
fakeElement.href = dataURL; | ||
fakeElement.download = 'games.save'; | ||
fakeElement.click(); | ||
URL.revokeObjectURL(dataURL); | ||
} | ||
|
||
// Function to get the main save data from an uploaded file | ||
function getMainSaveFromUpload(data) { | ||
// Decrypt the uploaded data using AES decryption with the key 'save' | ||
data = CryptoJS.AES.decrypt(data, 'save').toString(CryptoJS.enc.Utf8); | ||
|
||
// Parse the decrypted data as JSON | ||
var mainSave = JSON.parse(atob(data)); | ||
var mainLocalStorageSave = JSON.parse(atob(mainSave.localStorage)); | ||
var cookiesSave = atob(mainSave.cookies); | ||
|
||
// Set the items in localStorage using the uploaded data | ||
for (let item of mainLocalStorageSave) { | ||
localStorage.setItem(item[0], item[1]); | ||
} | ||
|
||
// Set the cookies using the uploaded data | ||
document.cookie = cookiesSave; | ||
} | ||
|
||
// Function to handle the file upload | ||
function uploadMainSave() { | ||
var hiddenUpload = document.querySelector('.hiddenUpload'); | ||
hiddenUpload.click(); | ||
|
||
// Listen for the change event on the file input element | ||
hiddenUpload.addEventListener('change', function (e) { | ||
var files = e.target.files; | ||
var file = files[0]; | ||
if (!file) { | ||
return; | ||
} | ||
|
||
// Read the contents of the uploaded file as text and call getMainSaveFromUpload with the result | ||
var reader = new FileReader(); | ||
|
||
reader.onload = function (e) { | ||
getMainSaveFromUpload(e.target.result); | ||
|
||
// Show a success message to the user | ||
var uploadResult = document.querySelector('.uploadResult'); | ||
uploadResult.innerText = 'Uploaded save!'; | ||
uploadResult.style.display = 'initial'; | ||
setTimeout(function () { | ||
uploadResult.style.display = 'none'; | ||
}, 3000); | ||
}; | ||
|
||
reader.readAsText(file); | ||
}); | ||
} | ||
|
||
// Handle the hii pattern when keys are pressed | ||
var hiiPattern = ['h', 'i', 'i']; | ||
var hiiCurrent = 0; | ||
|
||
document.addEventListener('keydown', function (e) { | ||
if (e.key !== hiiPattern[hiiCurrent]) { | ||
return (hiiCurrent = 0); | ||
} | ||
|
||
hiiCurrent++; | ||
|
||
if (hiiPattern.length == hiiCurrent) { | ||
hiiCurrent = 0; | ||
document.querySelector('.hii').removeAttribute('hidden'); | ||
} | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
/* | ||
Hello epic hacker (maybe skid) you are looking at one of the many scripts that powers the site, | ||
this script has extra comments and info to help you understand what is going on. | ||
This is a JavaScript code that generates random splash messages and sets them in the DOM. | ||
The code declares two variables for caching splash messages, "splashCacheAll" and "splashCache". | ||
The "randomSay" function fetches a set of splash messages and selects a random one from the set, | ||
caching the remaining messages in the "splashCache" variable. | ||
If the selected message contains special placeholders like "%REAL_IP%", "%GAMES_NUMBER%", or "%SPLASH_NUMBER%", | ||
the placeholders are replaced with corresponding values, such as the user's IP address, the number of available games, | ||
or the total number of splash messages. The "setRandomSay" function sets the selected splash message in the DOM. | ||
If there is an element with class "message", the "setRandomSay" function is called to set a random splash message in the DOM. | ||
*/ | ||
|
||
// Declare variables for caching splash messages | ||
var splashCacheAll; | ||
var splashCache; | ||
|
||
// Async function that returns a random splash message | ||
async function randomSay() { | ||
// If splashCache is defined and not empty | ||
if (splashCache) { | ||
// If splashCache is empty, set it equal to the full set of splash messages | ||
if (!splashCache.length) { | ||
splashCache = splashCacheAll; | ||
} | ||
// Set says variable to the current splashCache | ||
var says = splashCache; | ||
} else { | ||
// If splashCache is undefined or empty, fetch the full set of splash messages | ||
var say = await fetch("./assets/json/say.json"); | ||
var says = await say.json(); | ||
// Store the full set of splash messages in both splashCacheAll and splashCache | ||
splashCacheAll = says; | ||
splashCache = says; | ||
} | ||
|
||
// Get a random splash message from the current says set | ||
var getRandomSay = says[Math.floor(Math.random() * says.length)]; | ||
|
||
// Remove the randomly selected splash message from the cache | ||
splashCache = splashCache.filter((splash) => splash !== getRandomSay); | ||
|
||
// Return the randomly selected splash message | ||
return getRandomSay; | ||
} | ||
|
||
// Async function that sets a random splash message in the DOM | ||
async function setRandomSay() { | ||
// Get a random splash message using the randomSay() function | ||
var randomSplash = await randomSay(); | ||
|
||
// If the random message is "%REAL_IP%", replace it with the user's IP address | ||
if (randomSplash == "%REAL_IP%") { | ||
var ips = await getIPs(); | ||
if (ips[0]) { | ||
randomSplash = "Your real IP is " + ips[0]; | ||
} else { | ||
randomSplash = "Cannot get your real IP :("; | ||
} | ||
} | ||
// If the random message is "%GAMES_NUMBER%", replace it with the number of games available | ||
else if (randomSplash == "%GAMES_NUMBER%") { | ||
var gamesFetch = await fetch(location.origin + "/assets/json/games.json"); | ||
var games = await gamesFetch.json(); | ||
randomSplash = "There are " + games.length + " games currently"; | ||
} | ||
// If the random message is "%SPLASH_NUMBER%", replace it with the total number of splash messages | ||
else if (randomSplash == "%SPLASH_NUMBER%") { | ||
randomSplash = "There are " + splashCacheAll.length + " of these messages!"; | ||
} | ||
|
||
// Set the random splash message in the DOM | ||
document.querySelector(".message").innerText = randomSplash; | ||
} | ||
|
||
// If there is an element with class "message", set a random splash message in the DOM | ||
if (document.querySelector(".message")) { | ||
setRandomSay(); | ||
} |
Oops, something went wrong.