//Flee button vars
//---------------------------------------------------------------------------------------------------------------------
const fleeButton = document.getElementById("fleeButton");
const originalWidth = fleeButton.offsetWidth;
//Init Customizations
const fleeRadius = 130;
const fleeVelocity = 0.9;
//Compute Values
const fleeRadiusSquared = fleeRadius * fleeRadius;
const fleeReciprocal = 1.0 / fleeRadius;
//Global variables to store the mouse position
let mouseX = 0;
let mouseY = 0;
//Event listener for updating the mouse position
document.addEventListener("mousemove", function (event) {
mouseX = event.clientX;
mouseY = event.clientY;
});
//Event to make the button run
function flee() {
//Get the button's dimensions
const rect = fleeButton.getBoundingClientRect();
const curX = rect.left + fleeButton.offsetWidth * 0.5;
const curY = rect.top + fleeButton.offsetHeight * 0.5;
//Calculate distance from the center of the button
const distX = mouseX - curX;
const distY = mouseY - curY;
//Use Rootless Pythagorean Theorem to check if in radius
const d = distX * distX + distY * distY;
if (d < fleeRadiusSquared) {
//Run the button
const m = 1 / Math.sqrt(d);
let speed = m * 7500;
const matrix = new DOMMatrix(window.getComputedStyle(fleeButton).transform);
fleeButton.style.transform = `translate(${
matrix.m41 - distX * m * speed
}px,
${matrix.m42 - distY * m * speed}px)`;
}
}
// Add animation class to button
fleeButton.classList.add("fleeButton-resize");
// Set interval to run the flee function
let intervalID = 0;
//---------------------------------------------------------------------------------------------------------------------
//Swear word checking
//---------------------------------------------------------------------------------------------------------------------
//Swear words matrix X_X sorry to make you read this
const wordsDeemedAsBad = [
"anal",
"ass",
"bananao",
"bitch",
"cock",
"crack",
"cum",
"dick",
"escort",
"fag",
"fuck",
"hoe",
"hooker",
"meth",
"nigga",
"nigger",
"nigroe",
"penis",
"porn",
"prostitute",
"pussy",
"sex",
"shit",
"slut",
"tits",
"wank",
"whore",
];
//Return a percentage of how similar two strings are
function checkForSwears(given) {
// Max allowed similarity with the swears
const allowedPocentage = 0.5;
// Chop extra chars to avoid 4 rep bypass
//---------------------------------------------------
let newString = "";
{
let lastSeen = "",
doubleSeen = false;
for (let i = 0; i < given.length; i++) {
if (doubleSeen && lastSeen === given[i]) continue;
if (lastSeen === given[i]) doubleSeen = true;
else doubleSeen = false;
newString += given[i];
lastSeen = given[i];
}
}
//---------------------------------------------------
// For char apply check
for (let k = 0, repeat = newString.length; k < repeat; k++) {
// Binary search
//---------------------------------------------------
let cur = parseInt(wordsDeemedAsBad.length * 0.5);
let small = 0,
big = wordsDeemedAsBad.length;
for (; small <= big; cur = parseInt(small + (big - small) * 0.5)) {
switch (newString.localeCompare(wordsDeemedAsBad[cur])) {
case -1:
big = cur - 1;
break;
case 1:
small = cur + 1;
break;
default:
return true;
}
}
//---------------------------------------------------
if (cur >= wordsDeemedAsBad.length) cur = wordsDeemedAsBad.length - 1; //Taylor
//Check found index
//---------------------------------------------------
//Create a matrix to store the edit distance
const length2 = Math.min(wordsDeemedAsBad[cur].length, newString.length);
let dp = Array.from({ length: wordsDeemedAsBad[cur].length + 1 }, () =>
Array(length2 + 1).fill(0)
);
//Initialize the matrix
for (let i = 0; i <= wordsDeemedAsBad[cur].length; i++) dp[i][0] = i;
for (let j = 0; j <= length2; j++) dp[0][j] = j;
//Calculate the edit distance
for (let j, i = 1; i <= wordsDeemedAsBad[cur].length; i++) {
for (j = 1; j <= length2; j++) {
dp[i][j] = Math.min(
dp[i - 1][j] + 1,
dp[i][j - 1] + 1,
dp[i - 1][j - 1] +
(wordsDeemedAsBad[cur][i - 1] === newString[j - 1] ? 0 : 1)
);
}
}
//Calculate and return similarity
if (
1 -
dp[wordsDeemedAsBad[cur].length][wordsDeemedAsBad[cur].length] /
wordsDeemedAsBad[cur].length >
allowedPocentage
)
return true;
//---------------------------------------------------
//Continue chopping the string and repeat the loop
newString = newString.slice(1);
}
return false;
}
//---------------------------------------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------------------------------------
// Get the textbox element
const myTextbox = document.getElementById("username");
// This function will be called whenever the user types new characters
myTextbox.addEventListener("input", function () {
// Get the current value of the textbox
let usernameValue = myTextbox.value;
// Replace any spaces or invalid characters (anything that's not a letter, number, or underscore)
usernameValue = usernameValue.replace(/[^a-zA-Z0-9_]/g, "");
// Update the textbox value with the cleaned username
myTextbox.value = usernameValue;
// Check for swear words
//---------------------------------------------------------
let CheckString = "";
let readString = myTextbox.value.toLowerCase() + " ";
for (let i = 0; i < readString.length; i++) {
// Separate into individual words
if ("a" <= readString[i] && readString[i] <= "z")
CheckString += readString[i];
}
// Do some check on the parsed words
if (checkForSwears(CheckString)) {
fleeButton.classList.add("fleeButton-resize");
fleeButton.style.width = "120px";
// Wait 0.3s
setTimeout(function () {
fleeButton.classList.remove("fleeButton-resize");
}, 300);
if (intervalID) clearInterval(intervalID);
intervalID = setInterval(flee, 10);
return;
} // RUN
clearInterval(intervalID);
intervalID = 0;
fleeButton.classList.add("fleeButton-resize");
fleeButton.style.width = originalWidth + "px";
fleeButton.style.transform = "none";
//---------------------------------------------------------
});
//---------------------------------------------------------------------------------------------------------------------
//Alert that could not connect to servers
let serverDown = false;
function serverDownWarning() {
if (serverDown) return;
serverDown = true;
const warningDiv = document.createElement("div");
warningDiv.className =
"server-down-warning fixed bottom-5 left-1/2 transform -translate-x-1/2 flex items-center justify-between p-4 bg-gray-800 border border-gray-700 rounded-2xl w-[620px] h-14";
warningDiv.innerHTML = `
⚠️ Server is down. We are working on it.
`;
document.body.prepend(warningDiv);
document.getElementById("closeWarning").addEventListener("click", () => {
warningDiv.remove();
serverDown = false;
});
}
//Actually make the log in / sign in work
//---------------------------------------------------------------------------------------------------------------------
const ServerIP = "devserving.me";
const ServerPort = 8443;
fleeButton.addEventListener("click", function () {
//Get information typed in the front end
const user = document.getElementById("username").value;
const pass = document.getElementById("password").value;
let email;
if (fleeButton.getAttribute("data-signin") === "0") {email = document.getElementById("email").value;}
if (user && pass){
//User in the --sign up-- page
if (fleeButton.getAttribute("data-signin") === "0"){
//Send to server
fetch(`https://${ServerIP}:${ServerPort}/0`, {
method: "POST",
headers: {
"sub-method": "UP",
"content-type": "application/json",
},
body: JSON.stringify({ username: user, email: email, password: pass }),
//Catch err if servers are down
})
.catch((err) => serverDownWarning())
//Retrieve data from the server
.then((response) => response.json())
.then((data) => {
console.log(data);
if (data.ID == 0) {
document.getElementById("error-message").textContent = "Username already in use.";
return;
}
else if (data.ID == "f") {
document.getElementById("error-message").textContent = "Unknown error in the server. We are working on it.";
return;
}
localStorage.setItem(`__token${data.ID}`, BigInt(data.token));
localStorage.setItem(`__username${data.ID}`, user);
localStorage.setItem(`__${user}`, data.ID);
localStorage.setItem(`__curID`, data.ID);
window.location.href = `/index.html`;
});
}
//User in the --sign in-- page
else {
//See if user is in cache
const reqID = localStorage.getItem(`__${user}`);
const token = localStorage.getItem(`__token${reqID}`);
let gotIn = false;
if (reqID && token){ fetch(`https://${ServerIP}:${ServerPort}/0`, {
method: "POST",
headers: {
"sub-method": "UP",
"token": token,
"content-type": "application/json",
},
body: JSON.stringify({ username: user, email: email, password: pass }),
//Catch err if servers are down
}).catch((err) => serverDownWarning())
.then(response => response.text())
.then(data => { if (data !== "0") {
localStorage.setItem(`__username${reqID}`, user);
localStorage.setItem(`__curID`, reqID);
window.location.href = `/index.html`;
gotIn = true;
}
});
} if (gotIn) return;
//Actually send info to server
fetch(`https://${ServerIP}:${ServerPort}/0`, {
method: "POST",
headers: {
"sub-method": "IN",
"content-type": "application/json",
},
body: JSON.stringify({ username: user, password: pass }),
//Catch err if servers are down
})
.catch((err) => serverDownWarning())
//Retrieve data from the server
.then((response) => response.json())
.then((data) => {
if (data.ID == 0) {
document.getElementById("error-message").textContent = "The username or password given is wrong.";
return;
}
else if (data.ID == "false") {
document.getElementById("error-message").textContent = "Unknown error in the server. We are working on it.";
return;
}
localStorage.setItem(`__token${data.ID}`, BigInt(data.token));
localStorage.setItem(`__username${data.ID}`, user);
localStorage.setItem(`__${user}`, data.ID);
localStorage.setItem(`__curID`, data.ID);
window.location.href = `/index.html`;
});
}
}
return;
});