Files
monkeygg2.github.io/js/index.js
T

546 lines
16 KiB
JavaScript

let currentMenu = $(".homepage");
$(".column button .card").on("click", function () {
let nextMenu = this.getAttribute("data");
if (nextMenu === "proxy") {
if (!config["proxy"]) {
$("#disabled").showModal();
return;
}
$("#everything-else").fadeOut(300, () => {
$("#page-loader").fadeIn(200);
$("#page-loader iframe").attr("src", config["proxyPath"] || "/proxy");
$("#page-loader iframe")[0].focus();
});
currentMenu = $("#page-loader");
inGame = true;
return;
}
currentMenu.fadeOut(300, () => {
$("." + nextMenu).fadeIn(200);
});
currentMenu = $("." + nextMenu);
});
$("logo img").on("click", returnHome);
$("#gameButton").on("click", returnHome);
$("#refresh").on("click", refreshPage);
$("dialog").on("click", function (e) {
if (!e.originalEvent.target.closest("div")) {
e.originalEvent.target.close();
}
});
// Function to calculate the
// Jaro Similarity of two strings
// from https://www.geeksforgeeks.org/jaro-and-jaro-winkler-similarity/
function jaro_distance(s1, s2) {
// If the strings are equal
if (s1 == s2)
return 1.0;
// Length of two strings
let len1 = s1.length, len2 = s2.length;
if (len1 == 0 || len2 == 0)
return 0.0;
// Maximum distance upto which matching
// is allowed
let max_dist = Math.floor(Math.max(len1, len2) / 2) - 1;
// Count of matches
let match = 0;
// Hash for matches
let hash_s1 = new Array(s1.length);
hash_s1.fill(0);
let hash_s2 = new Array(s2.length);
hash_s2.fill(0);
// Traverse through the first string
for (let i = 0; i < len1; i++) {
// Check if there is any matches
for (let j = Math.max(0, i - max_dist);
j < Math.min(len2, i + max_dist + 1); j++)
// If there is a match
if (s1[i] == s2[j] &&
hash_s2[j] == 0) {
hash_s1[i] = 1;
hash_s2[j] = 1;
match++;
break;
}
}
// If there is no match
if (match == 0)
return 0.0;
// Number of transpositions
let t = 0;
let point = 0;
// Count number of occurrences
// where two characters match but
// there is a third matched character
// in between the indices
for (let i = 0; i < len1; i++)
if (hash_s1[i] == 1) {
// Find the next matched character
// in second string
while (hash_s2[point] == 0)
point++;
if (s1[i] != s2[point++])
t++;
}
t /= 2;
// Return the Jaro Similarity
return ((match) / (len1)
+ (match) / (len2)
+ (match - t) / (match))
/ 3.0;
}
// Jaro Winkler Similarity
function jaroWinklerSimilarity(s1, s2) {
let jaro_dist = jaro_distance(s1, s2);
// If the jaro Similarity is above a threshold
if (jaro_dist > 0.7) {
// Find the length of common prefix
let prefix = 0;
for (let i = 0; i < Math.min(s1.length, s2.length); i++) {
// If the characters match
if (s1[i] == s2[i])
prefix++;
// Else break
else
break;
}
// Maximum of 4 characters are allowed in prefix
prefix = Math.min(4, prefix);
// Calculate jaro winkler Similarity
jaro_dist += 0.1 * prefix * (1 - jaro_dist);
}
return jaro_dist.toFixed(6);
}
/**
* Updates the list of games based on the current search filter and sort type.
*
* @return {void}
*/
function updateList() {
const filter = $("#search").val().toLowerCase();
const elems = Array.from(document.querySelectorAll("#gamesList li"));
const sortType = $("#sort").val();
// sort by selected sort type
elems.sort(function (a, b) {
if (sortType === 'alphabetical') {
return a.textContent.localeCompare(b.textContent);
} else if (sortType === 'reverse') {
return b.textContent.localeCompare(a.textContent);
}
});
// then filter items with the search input
elems.forEach(function (item) {
let similarity = jaroWinklerSimilarity(filter, item.innerHTML.toLowerCase().slice(0, filter.length - 1));
if (item.getAttribute("aliases")) {
for (alias in item.getAttribute("aliases").split(',')) {
if (alias.length > 1) {
console.log("alias");
console.log(alias);
console.log(typeof alias);
console.log(alias.length);
similarity += jaroWinklerSimilarity(filter, alias.toLowerCase().slice(0, filter.length - 1));
}
}
}
if (similarity >= 0.7 && item.innerHTML.length > 2 || item.innerHTML.toLowerCase().indexOf(filter) > -1) {
item.style.display = "";
} else {
item.style.display = "none";
}
});
// now sort by jaro winkler distance
elems.sort(function (a, b) {
let distanceA = jaroWinklerSimilarity(filter, a.textContent.toLowerCase());
if (a.getAttribute("aliases")) {
for (alias in a.getAttribute("aliases").split(',')) {
distanceA += jaroWinklerSimilarity(filter, alias.toLowerCase());
}
}
let distanceB = jaroWinklerSimilarity(filter, b.textContent.toLowerCase());
if (b.getAttribute("aliases")) {
for (alias in b.getAttribute("aliases").split(',')) {
distanceB += jaroWinklerSimilarity(filter, alias.toLowerCase());
}
}
return distanceA - distanceB;
});
// then fill it with the sorted and filtered list
for (const item of elems) {
document.getElementById("gamesList").appendChild(item);
}
}
$("#search").on("input", updateList);
$("#sort").on("change", updateList);
dragElement(document.getElementById("gameButton"));
dragElement(document.getElementById("refresh"));
function toggleStar(event, star) {
event.preventDefault();
event.stopPropagation();
star.classList.toggle('filled');
}
/**
* Adds drag functionality to an HTML element.
*
* @param {HTMLElement} elmnt - The element to be dragged.
* @return {void}
*/
function dragElement(elmnt) {
var pos1 = 0, pos2 = 0, pos3 = 0, pos4 = 0;
if (document.getElementById(elmnt.id)) {
document.getElementById(elmnt.id).onmousedown = dragMouseDown;
} else {
elmnt.onmousedown = dragMouseDown;
}
function dragMouseDown(e) {
e = e || window.event;
e.preventDefault();
pos3 = e.clientX;
pos4 = e.clientY;
document.onmouseup = closeDragElement;
document.onmousemove = elementDrag;
}
function elementDrag(e) {
e = e || window.event;
e.preventDefault();
pos1 = pos3 - e.clientX;
pos2 = pos4 - e.clientY;
pos3 = e.clientX;
pos4 = e.clientY;
window.click = 1;
elmnt.style.top = (elmnt.offsetTop - pos2) + "px";
}
function closeDragElement() {
document.onmouseup = null;
document.onmousemove = null;
if (window.click == 1) {
window.hold = true;
window.click = 0;
}
setTimeout(function () { window.hold = false; }, 100);
}
}
/**
* Returns the user to the home page.
*
* @return {void}
*/
function returnHome() {
currentMenu.fadeOut(300, () => {
$("#everything-else").fadeIn(200);
$(".games").hide();
$(".homepage").fadeIn(200);
});
currentMenu = $(".homepage");
inGame = false;
console.log("e");
}
/**
* Refreshes the current page by reloading it.
*
* @return {void}
*/
function refreshPage() {
const oldUrl = $("#page-loader iframe").attr("src");
console.log(oldUrl);
$("#page-loader iframe").attr("src", "");
// delay is needed for some reason
setTimeout(() => {
$("#page-loader iframe").attr("src", oldUrl);
}, 10);
}
/**
* Generates a clone of the current window in an about:blank.
*
* @return {void}
*/
function makecloak(replaceUrl = preferences.cloakUrl) {
if ((window.top.location.href !== "about:blank")) {
var url = window.location.href;
const win = window.open();
if (!win || win.closed || typeof win.closed == 'undefined') {
return;
}
win.document.body.style.margin = "0";
win.document.body.style.height = "100vh";
var iframe = win.document.createElement("iframe");
iframe.style.border = "none";
iframe.style.width = "100%";
iframe.style.height = "100%";
iframe.style.margin = "0";
iframe.referrerpolicy = "no-referrer";
iframe.allow = "fullscreen";
iframe.src = url.toString();
win.document.body.appendChild(iframe);
window.location.replace(replaceUrl);
}
}
/**
* Changes the browser tab's title and favicon
*
* @return {void}
*/
function mask(title = preferences.maskTitle, iconUrl = preferences.maskIconUrl) {
const e = window.top.document;
e.title = title;
var link = e.querySelector("link[rel*='icon']") || document.createElement('link');
link.type = 'image/x-icon';
link.rel = 'shortcut icon';
link.href = iconUrl;
e.getElementsByTagName('head')[0].appendChild(link);
}
function popupsAllowed() {
var windowName = 'userConsole';
var popUp = window.open('/popup-page.php', windowName, 'width=1000, height=700, left=24, top=24, scrollbars, resizable');
if (popUp == null || typeof (popUp) == 'undefined') {
return false;
}
else {
popUp.close();
return true;
}
}
function getMainSave() {
var mainSave = {};
localStorageSave = Object.entries(localStorage);
localStorageSave = btoa(JSON.stringify(localStorageSave));
mainSave.localStorage = localStorageSave;
cookiesSave = document.cookie;
cookiesSave = btoa(cookiesSave);
mainSave.cookies = cookiesSave;
mainSave = btoa(JSON.stringify(mainSave));
mainSave = CryptoJS.AES.encrypt(mainSave, "save").toString();
return mainSave;
}
function downloadMainSave() {
var data = new Blob([getMainSave()]);
var dataURL = URL.createObjectURL(data);
var fakeElement = document.createElement("a");
fakeElement.href = dataURL;
fakeElement.download = "monkey.data";
fakeElement.click();
URL.revokeObjectURL(dataURL);
}
function getMainSaveFromUpload(data) {
data = CryptoJS.AES.decrypt(data, "save").toString(CryptoJS.enc.Utf8);
var mainSave = JSON.parse(atob(data));
var mainLocalStorageSave = JSON.parse(atob(mainSave.localStorage));
var cookiesSave = atob(mainSave.cookies);
for (let item in mainLocalStorageSave) {
localStorage.setItem(mainLocalStorageSave[item][0], mainLocalStorageSave[item][1]);
}
document.cookie = cookiesSave;
}
function uploadMainSave() {
var hiddenUpload = document.createElement("input");
hiddenUpload.type = "file";
hiddenUpload.accept = ".data";
document.body.appendChild(hiddenUpload);
hiddenUpload.click();
hiddenUpload.addEventListener("change", function (e) {
var files = e.target.files;
var file = files[0];
if (!file) {
return;
}
var reader = new FileReader();
reader.onload = function (e) {
getMainSaveFromUpload(e.target.result);
var uploadResult = document.querySelector(".upload-result");
uploadResult.innerText = "Uploaded save!";
setTimeout(function () {
uploadResult.innerText = "";
}, 3000);
};
reader.readAsText(file);
document.body.removeChild(hiddenUpload);
});
}
const keySlots = document.querySelectorAll('.keySlot');
keySlots.forEach((slot) => {
slot.addEventListener('click', () => {
slot.textContent = 'Press any key';
// Add a one-time event listener to capture the key press
const keyPressHandler = (event) => {
slot.textContent = event.key;
document.removeEventListener('keydown', keyPressHandler);
};
document.addEventListener('keydown', keyPressHandler);
});
});
const preferencesDefaults = {
cloak: true,
cloakUrl: "https://classroom.google.com",
mask: true,
maskTitle: "Home",
maskIconUrl: "https://ssl.gstatic.com/classroom/ic_product_classroom_32.png"
};
if (localStorage.getItem("preferences") == null) {
localStorage.setItem("preferences", JSON.stringify(preferencesDefaults));
}
const preferences = JSON.parse(localStorage.getItem("preferences"));
const cloakCheckbox = document.getElementById('cloakCheckboxInput');
const cloakUrl = document.getElementById('cloakUrlInput');
const maskCheckbox = document.getElementById('maskCheckboxInput');
const maskTitle = document.getElementById('maskTitleInput');
const maskIcon = document.getElementById('maskIconInput');
cloakCheckbox.checked = preferences.cloak;
cloakUrl.value = preferences.cloakUrl;
maskCheckbox.checked = preferences.mask;
maskTitle.value = preferences.maskTitle;
maskIcon.value = preferences.maskIconUrl;
if (preferences.cloak && (window.location.href == window.top.location.href)) {
if (popupsAllowed()) {
makecloak();
}
else {
currentMenu.fadeOut(300, () => {
$(".cloaklaunch").fadeIn(200);
});
currentMenu = $(".cloaklaunch");
document.addEventListener("click", (event) => { event.preventDefault(); makecloak(); });
}
}
maskCheckbox.addEventListener('change', function () {
preferences.mask = maskCheckbox.checked;
localStorage.setItem('preferences', JSON.stringify(preferences));
});
cloakCheckbox.addEventListener('change', function () {
preferences.cloak = cloakCheckbox.checked;
localStorage.setItem('preferences', JSON.stringify(preferences));
});
/* if it is wanted to save on input change wather than submission
document.querySelector('.text-field').addEventListener('change', function () {
preferences.maskTitle = maskTitle.value;
localStorage.setItem('preferences', JSON.stringify(preferences));
});
*/
document.getElementById('cloakUrlSubmit').addEventListener('click', function () {
preferences.cloakUrl = cloakUrl.value;
localStorage.setItem('preferences', JSON.stringify(preferences));
alert("Submitted! Change will take place upon refresh");
});
document.getElementById('maskTitleSubmit').addEventListener('click', function () {
preferences.maskTitle = maskTitle.value;
localStorage.setItem('preferences', JSON.stringify(preferences));
alert("Submitted! Change will take place upon refresh");
});
document.getElementById('maskIconSubmit').addEventListener('click', function () {
preferences.maskIconUrl = maskIcon.value;
localStorage.setItem('preferences', JSON.stringify(preferences));
alert("Submitted! Change will take place upon refresh");
});
document.getElementById('download').addEventListener('click', function () {
downloadMainSave();
});
document.getElementById('upload').addEventListener('click', function () {
uploadMainSave();
})
/* if (preferences.cloak && !localStorage.getItem("cloakTabOpened")){
if (window.top.location.href !== "about:blank"){
localStorage.setItem("cloakTabOpened", "true");
document.addEventListener("click", (event) => {event.preventDefault(); makecloak()});
}
makecloak();
window.addEventListener("beforeunload", () => {
localStorage.removeItem("cloakTabOpened");
});
} */
if (preferences.mask) {
mask();
}