Show sourcecode
The following files exists in this folder. Click to view.
webbsrvprg/exercises/slutprojekt/
actions.php
administer_users.php
create_code.php
database_include.php
dbconnection.php
index.php
login copy.php
login.php
main.php
password_renewals.php
play copy.php
play.php
setup.php
sign_up.php
statistics.php
verification.php
verify_mail.php
main.php
345 lines UTF-8 Windows (CRLF)
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345
<?php
ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
error_reporting(E_ALL);
session_start(["gc_maxlifetime" => 86400]);
?>
<!DOCTYPE html>
<html lang="sv">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Main</title>
<style>
fieldset {
margin: 5px;
padding: 5px;
border: 2px solid black;
}
#show_password {
width: 10em;
border: 1px solid gray;
background-color: lightgray;
}
#que_status {
background-color: lightgreen;
border: 2px solid black;
box-shadow: 0px 0px 4px;
border-radius: 10px;
text-align: center;
font-size: 2em;
}
#friend_cont {
padding: 0 5px 5px 5px;
border: 2px solid black;
}
#friend_request_cont {
padding: 0 5px 5px 5px;
border: 2px solid black;
}
.green {
background-color: lightgreen;
}
.red {
background-color: lightcoral;
}
h3 {
margin: 3px;
}
b {
font-weight: bold;
}
button {
cursor: pointer;
}
* {
box-sizing: border-box;
font-family: Arial, Helvetica, sans-serif;
}
</style>
</head>
<body>
<?php
echo ("<h1>" . $_SESSION["username"] . "</h1>");
try {
/** @var PDO $dbconn */
include("dbconnection.php");
$adminrequired = FALSE;
include("verification.php");
if (isset($_POST["request_username"])) {
// Man har skickat en vänförfrågan
$username = $_POST["request_username"];
$sql = "SELECT id FROM bs_users WHERE username = ?";
$stmt = $dbconn->prepare($sql);
$data = [$username];
$stmt->execute($data);
$row = $stmt->fetch(PDO::FETCH_ASSOC);
// if ($row) { // Om användaren finns
$target_id = $row["id"]; // id't av användaren man vill fråga.
$user_id = $_SESSION["user_id"]; // Ens egna id.
// Inget hinder mot att skicka till de som redan är ens vänner men det blockeras där vänrelationerna skapas
$sql = "INSERT INTO bs_friend_requests (user_1_id, user_2_id)
SELECT ?, ?
WHERE NOT EXISTS (
SELECT 1 FROM bs_friend_requests WHERE user_1_id = ? AND user_2_id = ?)";
$stmt = $dbconn->prepare($sql);
$data = [$user_id, $target_id, $user_id, $target_id];
$stmt->execute($data);
// }
}
} catch (PDOException $e) {
echo ($e->getMessage());
}
if ($_SESSION["is_admin"]) {
// Eftersom det är ofarligt att rensa matchloggar så kan även vanliga användare göra det om de lyckas ta reda på hur koden ser ut.
echo ('<a href="administer_users.php">Överse användare</a><br><br><!-- <button>Rensa matchloggar</button> -->');
}
?>
<a href="login.php?log_out=true">Logga ut</a><br>
<a href="password_renewals.php" target="_blank">Byt lösenord</a><br><br>
<a href="statistics.php">Se statistik</a><br>
<fieldset>
<legend>SPELA</legend>
<p id="que_status">Inte i kö</p>
<button type="button" id="que_all" class="que_btn">Spela med vem som helst</button><br>
<button type="button" id="que_friends" class="que_btn">Spela med vänner</button><br>
<!-- <button type="button" id="que_individual" class="que_btn" disabled>Spela med markerad vän</button><br> -->
<br>
<button type="button" id="exit_que">Gå ur kön</button><br>
</fieldset>
<div id="friend_cont">
<h3>Vänner</h3>
<div id="friend_list"></div>
</div>
<div id="friend_request_cont">
<h3>Inkommande vänförfrågningar</h3>
<div id="friend_request_list"></div>
<h3>Skicka vänföfrågning</h3>
<form method="POST">
<input type="text" required name="request_username" id="username"><label for="username">Användarnamn</label><br>
<button type="submit">Skicka förfrågan (om användaren finns kommer den skickas)</button>
</form>
<script>
let que_interval = null; // Används för att spara interval-id som checkar ens que-status.
function get(id) {
return (document.getElementById(id));
}
function checkIn() {
fetch("actions.php?action=CHECKIN", {
cache: "no-store"
});
}
function toggleQueInterval(toggle_to) { // Toggle_to är true ska vara true eller false för på eller av.
if (toggle_to && !que_interval) {
// Den ska vara på och är inte det
que_interval = setInterval(updateQueStatus, 3000);
} else if (!toggle_to && que_interval) {
// Den ska vara av och är på
clearInterval(que_interval);
que_interval = null;
}
}
async function updateFriendList() {
// Uppdaterar även vänförfrågningar till en.
try {
const response = await fetch("actions.php?action=GET_FRIENDS", {
cache: "no-store"
});
if (!response.ok) {
throw new Error(`Response status: ${response.status}`);
}
const result = await response.json(); // Det är json-encodat.
let friend_list_element = get("friend_list");
let html = "";
html += '<b>AKTIVA:</b><br><span class="green">';
result.online.forEach((username) => {
html += username + "<br>";
});
html += '</span>';
html += '<br><b>INAKTIVA:</b><br><span class="red">'
result.offline.forEach((username) => {
html += username + "<br>";
});
html += '</span>';
friend_list_element.innerHTML = html;
const container = get("friend_request_list");
container.innerHTML = ""; // Tömmer den
result.pending.forEach((request) => {
// Skapar en liten ruta i för varje request där man får tacka ja eller nej
// request[0] är id't och [1] är username
const box = document.createElement("div");
box.style.border = "1px solid black";
box.style.padding = "10px";
box.style.margin = "10px";
box.style.width = "200px";
box.id = "request_box_" + request[0];
// Texten i rutan
const label = document.createElement("div");
label.innerText = request[1];
// Ja-knappen
const yes_btn = document.createElement("button");
yes_btn.innerText = "Acceptera";
yes_btn.style.backgroundColor = "lightgreen";
yes_btn.onclick = () => answerFriendRequest(1, request[0]); // Tackar ja
// Nej-knappen
const no_btn = document.createElement("button");
no_btn.innerText = "Neka";
no_btn.style.backgroundColor = "lightcoral";
no_btn.onclick = () => answerFriendRequest(0, request[0]); // Tackar nej
// Lägg ihop allt i lådan
box.appendChild(label);
box.appendChild(yes_btn);
box.appendChild(no_btn);
// Skapa lådan i listan
container.appendChild(box);
});
} catch (error) {
console.error(error.message);
}
}
function answerFriendRequest(answer, id) {
// answer är 1 eller 0 för säga ja eller nej. id är id't på personen som skickat förfrågan
box = get("request_box_" + id);
box.remove(); // Tar bort förfrågningen
const link = "actions.php?action=ANSWER_FRIEND_REQUEST" +
"&id=" + encodeURIComponent(id) +
"&answer=" + encodeURIComponent(answer);
fetch(link, {
cache: "no-store"
}); // Fipplar i databasen.
}
function setQueStatus(status) {
// status är 1, 2 eller 3 för inte sökande, söker alla eller söker vänner
let element = get("que_status")
if (status == 1) {
element.style.background = "lightgreen";
element.innerHTML = "Inte i kö";
} else if (status == 2) {
element.style.background = "lightcoral";
element.innerHTML = "Söker efter match";
} else {
element.style.background = "lightcoral";
element.innerHTML = "Söker efter match med vänner";
}
}
async function updateQueStatus() {
// Kollar om man är i kön när man laddar in sidan och kollar om man hamnat i en match när man står i kön
// Uppdaterar även ens bs_que.lastcheckin om man är i kö
try {
const response = await fetch("actions.php?action=UPDATE_QUE_STATUS", {
cache: "no-store"
});
if (!response.ok) {
throw new Error(`Response status: ${response.status}`);
}
let result = await response.text();
result = result.trim();
// response är ALL eller FRIENDS eller ett tal (id på matchen man är i) eller tom
if (result == "ALL") {
setQueStatus(2);
toggleQueInterval(true);
} else if (result == "FRIENDS") {
setQueStatus(3);
toggleQueInterval(true);
} else if (result == "") {
// Om man inte är i kö
setQueStatus(1);
toggleQueInterval(false);
} else if (!isNaN(result)) {
// Konstig dubbelnegation men kommer hit om det är ett nummer, alltså id't på matchen man är i.
// Man är inne i en match
setQueStatus(1);
toggleQueInterval(false);
// Den som joinar är den som "skapar" matchen i databasen så det görs inte här.
window.location.href = 'play.php?game_id=' + result;
} else {
// Något har gått fel
console.error(result);
}
} catch (error) {
console.error(error.message);
}
}
updateQueStatus() // Hämtar direkt ens que-information.
checkIn(); // Checkar in en gång direkt
updateFriendList(); // Kollar vilka vänner som finns och är online
setInterval(() => {
// Checkar in och kollar efter vänner 2ggr per minut
checkIn();
updateFriendList();
console.log("30s update ran");
}, 30000);
get("que_all").addEventListener("click", () => {
fetch("actions.php?action=ENTER_QUE&scope=ALL", {
cache: "no-store"
});
setQueStatus(2); // Skriver ut för användaren hur det är med kön
toggleQueInterval(true);
})
get("que_friends").addEventListener("click", () => {
fetch("actions.php?action=ENTER_QUE&scope=FRIENDS", {
cache: "no-store"
});
setQueStatus(3)
toggleQueInterval(true);
})
get("exit_que").addEventListener("click", () => {
fetch("actions.php?action=EXIT_QUE", {
cache: "no-store"
});
setQueStatus(1)
toggleQueInterval(false);
})
</script>
</body>
</html>