Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
3kh0
GitHub Repository: 3kh0/3kh0.github.io-replit
Path: blob/main/js/games.js
617 views
1
/*
2
Hello epic hacker (maybe skid) you are looking at one of the many scripts that powers the site,
3
this script has extra comments and info to help you understand what is going on.
4
5
This is a JavaScript code that creates a game catalog page with a search feature,
6
a game detail page, and the ability to save and load user data.
7
8
It uses fetch to load game data from a JSON file, creates game elements for each game,
9
and adds click event listeners to show the game in a game container.
10
11
The code also includes functions to handle saving and loading user data as well as a function to handle a specific key sequence.
12
*/
13
// Select the elements
14
const gamesContainer = document.querySelector('.games');
15
const searchBar = document.querySelector('.searchbar');
16
const gameContainer = document.querySelector('.gamecontainer');
17
const gameFrame = gameContainer.querySelector('.frame');
18
const gameNav = gameContainer.querySelector('.nav');
19
20
// Listen for input event on the search bar
21
searchBar.addEventListener('input', (e) => {
22
const query = searchBar.value.trim().toLowerCase();
23
24
// Loop through all the games in the container and show/hide them depending on whether they match the search query
25
for (let game of gamesContainer.children) {
26
if (game instanceof Element) {
27
if (query) {
28
const gameName = game.querySelector('span').innerText.trim().toLowerCase();
29
if (gameName.includes(query)) {
30
game.removeAttribute('hidden');
31
} else {
32
game.setAttribute('hidden', '');
33
}
34
} else {
35
game.removeAttribute('hidden');
36
}
37
}
38
}
39
40
// If there are no games shown, display the "No games" message, otherwise hide it
41
if (document.querySelectorAll('.game:not([hidden])').length == 0) {
42
document.querySelector('.nogames').style.display = 'initial';
43
} else {
44
document.querySelector('.nogames').style.display = 'none';
45
}
46
});
47
48
// Fetch the games data from a JSON file
49
fetch('./assets/json/games.json')
50
.then((res) => res.json())
51
.then((games) => {
52
// Loop through each game and create a new game element for it
53
games.forEach((game) => {
54
const gameEl = document.createElement('div');
55
gameEl.className = 'game';
56
gameEl.innerHTML = `<img src="${cdn + "/" + game.root + "/" + game.img}" onerror="this.src='./assets/globe.svg'"/><span>${game.name}</span>`;
57
gamesContainer.appendChild(gameEl);
58
59
// Add click event listener to the game element to show the game in the game container
60
gameEl.onclick = (e) => {
61
gamesContainer.classList.add('hidden');
62
searchBar.classList.add('hidden');
63
gameContainer.classList.remove('hidden');
64
document.querySelector('.saveItems').classList.add('hidden');
65
document.querySelector('.navbar').classList.add('noshadow');
66
gameFrame.querySelector('iframe').src = `./assets/game?game=${game.root}`;
67
gameNav.querySelector('span').textContent = game.name;
68
};
69
70
// Add click event listener to the back button in the game container to go back to the games list
71
gameNav.querySelector('#back').addEventListener('click', (e) => {
72
gamesContainer.classList.remove('hidden');
73
searchBar.classList.remove('hidden');
74
gameContainer.classList.add('hidden');
75
document.querySelector('.saveItems').classList.remove('hidden');
76
document.querySelector('.navbar').classList.remove('noshadow');
77
gameFrame.src = '';
78
});
79
80
// Add click event listener to the fullscreen button in the game container to enter fullscreen mode
81
gameNav.querySelector('#fullscreen').addEventListener('click', (e) => {
82
if (!document.fullscreenElement) {
83
gameFrame.requestFullscreen();
84
}
85
});
86
});
87
})
88
.catch((e) => {
89
alert('Could not load games');
90
alert(e);
91
});
92
93
// Hide the spinner element after the page is loaded
94
document.querySelector('.spinner').style.display = 'none';
95
96
// Function to get the main save data
97
function getMainSave() {
98
var mainSave = {};
99
100
// List of items in localStorage that should not be saved
101
var localStorageDontSave = ['theme', 'tab', 'nebelung'];
102
103
// Convert localStorage to an array of key-value pairs and remove the items that should not be saved
104
localStorageSave = Object.entries(localStorage);
105
106
for (let entry in localStorageSave) {
107
if (localStorageDontSave.includes(localStorageSave[entry][0])) {
108
localStorageSave.splice(entry, 1);
109
}
110
}
111
112
// Convert the localStorage array to a base64-encoded JSON string
113
localStorageSave = btoa(JSON.stringify(localStorageSave));
114
115
// Add the localStorage data to the mainSave object
116
mainSave.localStorage = localStorageSave;
117
118
// Get the cookies data and add it to the mainSave object
119
cookiesSave = document.cookie;
120
cookiesSave = btoa(cookiesSave);
121
mainSave.cookies = cookiesSave;
122
123
// Convert the mainSave object to a base64-encoded JSON string
124
mainSave = btoa(JSON.stringify(mainSave));
125
126
// Encrypt the mainSave data using AES encryption with the key 'save'
127
mainSave = CryptoJS.AES.encrypt(mainSave, 'save').toString();
128
129
// Return the encrypted mainSave data
130
return mainSave;
131
}
132
133
// Function to download the main save data as a file
134
function downloadMainSave() {
135
var data = new Blob([getMainSave()]);
136
var dataURL = URL.createObjectURL(data);
137
138
var fakeElement = document.createElement('a');
139
fakeElement.href = dataURL;
140
fakeElement.download = 'games.save';
141
fakeElement.click();
142
URL.revokeObjectURL(dataURL);
143
}
144
145
// Function to get the main save data from an uploaded file
146
function getMainSaveFromUpload(data) {
147
// Decrypt the uploaded data using AES decryption with the key 'save'
148
data = CryptoJS.AES.decrypt(data, 'save').toString(CryptoJS.enc.Utf8);
149
150
// Parse the decrypted data as JSON
151
var mainSave = JSON.parse(atob(data));
152
var mainLocalStorageSave = JSON.parse(atob(mainSave.localStorage));
153
var cookiesSave = atob(mainSave.cookies);
154
155
// Set the items in localStorage using the uploaded data
156
for (let item of mainLocalStorageSave) {
157
localStorage.setItem(item[0], item[1]);
158
}
159
160
// Set the cookies using the uploaded data
161
document.cookie = cookiesSave;
162
}
163
164
// Function to handle the file upload
165
function uploadMainSave() {
166
var hiddenUpload = document.querySelector('.hiddenUpload');
167
hiddenUpload.click();
168
169
// Listen for the change event on the file input element
170
hiddenUpload.addEventListener('change', function (e) {
171
var files = e.target.files;
172
var file = files[0];
173
if (!file) {
174
return;
175
}
176
177
// Read the contents of the uploaded file as text and call getMainSaveFromUpload with the result
178
var reader = new FileReader();
179
180
reader.onload = function (e) {
181
getMainSaveFromUpload(e.target.result);
182
183
// Show a success message to the user
184
var uploadResult = document.querySelector('.uploadResult');
185
uploadResult.innerText = 'Uploaded save!';
186
uploadResult.style.display = 'initial';
187
setTimeout(function () {
188
uploadResult.style.display = 'none';
189
}, 3000);
190
};
191
192
reader.readAsText(file);
193
});
194
}
195
196
// Handle the hii pattern when keys are pressed
197
var hiiPattern = ['h', 'i', 'i'];
198
var hiiCurrent = 0;
199
200
document.addEventListener('keydown', function (e) {
201
if (e.key !== hiiPattern[hiiCurrent]) {
202
return (hiiCurrent = 0);
203
}
204
205
hiiCurrent++;
206
207
if (hiiPattern.length == hiiCurrent) {
208
hiiCurrent = 0;
209
document.querySelector('.hii').removeAttribute('hidden');
210
}
211
});
212
213