ldc-babyweb/index.php
2021-02-16 23:28:41 +01:00

547 lines
21 KiB
PHP

<?php
require_once 'Db.php';
$db = new Database('localhost', 'babyweb', 'root', '');
$ranking = $db->requestAll("SELECT * FROM players ORDER BY score DESC");
$players = $db->requestAll("SELECT * FROM players ORDER BY name");
?>
<html>
<head>
<title>BabyWeb</title>
<link rel="preconnect" href="https://fonts.gstatic.com">
<link href="https://fonts.googleapis.com/css2?family=Montserrat:wght@500&display=swap" rel="stylesheet">
<script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
<!-- development version, includes helpful console warnings -->
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<!-- production version, optimized for size and speed -->
<!--<script src="https://cdn.jsdelivr.net/npm/vue@2"></script>-->
<style>
body {
padding: 0;
margin: 0;
font-family: 'Montserrat', sans-serif;
}
.ranking table {
font-size: 40px;
text-align: center;
}
.ranking th, .ranking td {
padding: 10px;
}
.ranking tr:nth-child(2) {
color: gold;
}
.ranking tr:nth-child(3) {
color: silver;
}
.ranking tr:nth-child(4) {
color: saddlebrown;
}
.main {
height: 100vh;
display: flex;
justify-content: center;
}
.ranking, .add-match {
padding-top: 5vh;
display: flex;
justify-content: center;
flex: 1;
}
.add-match {
flex-direction: column;
align-items: center;
justify-content: flex-start;
}
.match_type {
margin-bottom: 25px;
font-size: 2.5vw;
font-weight: bold;
}
.add-btn {
height: 50px;
width: 100px;
font-size: 15px;
border: 2px solid;
border-radius: 5px;
font-weight: bold;
}
.score-input {
height: 40px;
width: 80px;
font-size: 1.5vw;
text-align: center;
text-align-last: center;
-moz-text-align-last: center;
}
.blue {
color: blue;
font-weight: bold;
}
.red {
color: red;
font-weight: bold;
}
.add-match table td {
font-size: 2.3vw;
padding: 0 20px;
text-align: center;
}
.add-match table th {
font-size: 2.5vw;
padding: 0 20px;
}
.player-select {
height: 40px;
width: 20vw;
font-size: 1.5vw;
text-align: center;
text-align-last: center;
-moz-text-align-last: center;
}
</style>
</head>
<body>
<div id="app">
<section class="main">
<div class="ranking" style="background-color: lightcoral">
<table>
<tr>
<th>#</th>
<th>Player</th>
<th>Score</th>
</tr>
<tr v-for="(rank, i) in ranking">
<td>{{ i + 1 }}</td>
<td>{{ rank.name }}</td>
<td>{{ rank.score }}</td>
</tr>
</table>
</div>
<div class="add-match" style="background-color: lightblue">
<div v-if="error.length">
<b>{{ error }}</b>
</div>
<div class="match_type">
<label for="1v1" style="margin-right: 30px;">
<input id="1v1" type="radio" v-model="match_type" value="1v1">
1 vs 1
</label>
<label for="2v2">
<input id="2v2" type="radio" v-model="match_type" value="2v2">
2 vs 2
</label>
</div>
<table>
<tr>
<th class="red">Joueur 1</th>
<th class="blue">Joueur 1</th>
</tr>
<tr>
<td>
<select class="player-select" v-model="red_p1">
<option v-for="player in players" :value="player.id">{{ player.name }}</option>
</select>
</td>
<td>
<select class="player-select" v-model="blue_p1">
<option v-for="player in players" :value="player.id">{{ player.name }}</option>
</select>
</td>
</tr>
</table>
<table v-show="match_type === '2v2'" style="margin-top: 20px;">
<tr>
<th class="red">Joueur 2</th>
<th class="blue">Joueur 2</th>
</tr>
<tr>
<td>
<select class="player-select" v-model="red_p2">
<option value="NULL">Vide.</option>
<option v-for="player in players" :value="player.id">{{ player.name }}</option>
</select>
</td>
<td>
<select class="player-select" v-model="blue_p2">
<option value="NULL">Vide.</option>
<option v-for="player in players" :value="player.id">{{ player.name }}</option>
</select>
</td>
</tr>
</table>
<br><br>
<div>
<label style="margin-right: 20px;font-size: 2.3vw;">
<span class="red">Score</span>
<input class="score-input" type="number" v-model="red_score" min="-11" max="15">
</label>
<label style="font-size: 2.3vw">
<input class="score-input" type="number" v-model="blue_score" min="-11" max="15">
<span class="blue">Score</span>
</label>
</div>
<br>
<input class="add-btn" type="submit" value="AJOUTER" @click="addMatch">
</div>
</section>
</div>
<script>
let app = new Vue({
el: '#app',
data: {
players: <?= json_encode($players); ?>,
ranking: <?= json_encode($ranking); ?>,
match_type: '1v1',
red_p1: '',
red_p2: 'NULL',
blue_p1: '',
blue_p2: 'NULL',
red_score: 0,
blue_score: 0,
error: '',
utterance: null,
messages: {
'missing.red_p2': {
error: 'Selectionnez joueur rouge 2',
speech: 'Aqueu coucou bob !'
},
'missing.blue_p2': {
error: 'Selectionnez joueur bleu 2',
speech: 'Il manque la bleusaille !'
},
'missing.red_p1': {
error: 'Selectionnez joueur rouge 1',
speech: 'Rejoins le coté obscure de la force !'
},
'missing.blue_p1': {
error: 'Selectionnez joueur bleu 1',
speech: 'Aller les bleu !'
},
'need2differentplayers': {
error: 'Selectionnez des joueurs différents !',
speech: 'Un traitre se cache parmi vous !'
},
'needdifferentplayers': {
error: 'Selectionnez deux joueurs différents !',
speech: 'Même Chuck Norris ne sais pas jouer contre lui même !'
},
'noequals': {
error: 'Les égalités ne sont pas tolérés !',
speech: 'Il n\'en restera qu\'un ! Voici une balle, battez vous !'
},
'1v1': {
'forthewinner': [
'Le gagnant est :winner.',
':winner paye sa tournée !',
':winner peut gagner sans toucher les manettes !',
':winner as battu :looser !',
'Le baby aime :winner, ça cache quelque chose.',
'Avec les :winnercolor :winner est imbattable !',
(new Audio('sounds/champions.mp3')),
(new Audio('sounds/dading.mp3')),
(new Audio('sounds/dundunduuun.mp3')),
(new Audio('sounds/money.mp3')),
(new Audio('sounds/rasputin.mp3')),
(new Audio('sounds/sanandreas.mp3'))
],
'forthelooser': [
'Tu as perdu :looser !',
'Dommage :looser, essaye encore !',
':looser n\'est pas dans son assiette on dirais, réconforte le :winner',
'Laisse tomber les :loosercolor :looser, ça te porte pas chance !',
(new Audio('sounds/denied.mp3')),
(new Audio('sounds/punch.mp3')),
(new Audio('sounds/stillstanding.mp3')),
(new Audio('sounds/windauberror.mp3'))
],
},
'2v2': {
'forthewinner': [
'C\'est gagné pour :winners !',
'Les :winnercolor ont gagné !',
'Monster kill !',
'La prochaine partie :redP1 est avec :blueP2, :blueP1 avec :redP2, alea jacta este !',
':winnerP1 ne prends pas la grosse tête, c\'est :winnerp2 qui ai fait tout le travail !',
':winnerp2 ne prends pas la grosse tête, c\'est :winnerP1 qui ai fait tout le travail !',
':winnerP1 ta couleur fétiche est le :winnercolor, c\'est certain',
'C\est l\'histoire de :winners qui sont sur un bateau, :loosers tombent à l\'eau...',
':winners devraient surement signer au Paris Saint Germain',
(new Audio('sounds/denied.mp3')),
(new Audio('sounds/punch.mp3')),
(new Audio('sounds/stillstanding.mp3')),
(new Audio('sounds/windauberror.mp3'))
],
'forthelooser': [
'La team :loosers a perdu !',
'Les :loosercolor ont perdu !',
'La team :loosercolor craint !',
'La prochaine partie, :redP1 et avec :blueP2, :blueP1 avec :redP2, alea jacta este !',
':looserP1, devrais motiver :looserP2 !',
':looserP2, devrais motiver :looserP1 !',
':looserP1, les :loosercolor ne sont pas fait pour toi !',
'Activation du programme reconforter les loosers, :loosers à deux on est plus fort l\'important c\'est de jouer, ..., Fin du programme',
(new Audio('sounds/champions.mp3')),
(new Audio('sounds/dading.mp3')),
(new Audio('sounds/dundunduuun.mp3')),
(new Audio('sounds/money.mp3')),
(new Audio('sounds/rasputin.mp3')),
(new Audio('sounds/sanandreas.mp3'))
]
}
}
},
mounted() {
this.utterance = new SpeechSynthesisUtterance();
this.setBestVoice();
},
watch: {
match_type() {
if (this.match_type === '1v1') {
this.red_p2 = 'NULL';
this.blue_p2 = 'NULL';
}
}
},
computed: {
redP1: function() {
let player = this.getPlayer(this.red_p1);
if(player) {
return player.name.slice(0, -3);
}
return '';
},
redP2: function() {
let player = this.getPlayer(this.red_p2);
if(player) {
return player.name.slice(0, -3);
}
return '';
},
blueP1: function() {
let player = this.getPlayer(this.blue_p1);
if(player) {
return player.name.slice(0, -3);
}
return '';
},
blueP2: function() {
let player = this.getPlayer(this.blue_p2);
if(player) {
return player.name.slice(0, -3);
}
return '';
},
winner: function() {
return this.red_score > this.blue_score ?
this.redP1 : this.blueP1;
},
looser: function() {
return this.red_score < this.blue_score ?
this.redP1 : this.blueP1;
},
winners: function() {
return this.red_score > this.blue_score ?
this.redP1 + (this.redP2.length && this.redP1 !== this.redP2 ? ' et ' + this.redP2 : ''):
this.blueP1 + (this.blueP2.length && this.blueP1 !== this.blueP2 ? ' et ' + this.blueP2 : '');
},
loosers: function() {
return this.red_score < this.blue_score ?
this.redP1 + (this.redP2.length && this.redP1 !== this.redP2 ? ' et ' + this.redP2 : ''):
this.blueP1 + (this.blueP2.length && this.blueP1 !== this.blueP2 ? ' et ' + this.blueP2 : '');
},
looserP1: function() {
return this.red_score < this.blue_score ? this.redP1 : this.blueP1 ;
},
looserP2: function() {
return this.red_score < this.blue_score ? this.redP2 : this.blueP2;
},
winnerP1: function() {
return this.red_score > this.blue_score ? this.redP1 : this.blueP1 ;
},
winnerP2: function() {
return this.red_score > this.blue_score ? this.redP2 : this.blueP2;
},
winnercolor: function() {
return this.red_score > this.blue_score ? 'rouge' : 'bleu';
},
loosercolor: function() {
return this.red_score < this.blue_score ? 'rouge' : 'bleu';
},
},
methods: {
checkSubmission() {
this.error = '';
switch(this.match_type) {
case '2v2':
if(!this.red_p2 || this.red_p2 === '') {
this.sendMessage('missing.red_p2');
return false;
}
if(!this.blue_p2 || this.blue_p2 === '') {
this.sendMessage('missing.blue_p2');
return false;
}
if(!this.red_p1 || this.red_p1 === '') {
this.sendMessage('missing.red_p1');
return false;
}
if(!this.blue_p1 || this.blue_p1 === '') {
this.sendMessage('missing.blue_p1');
return false;
}
if(
(this.red_p1 === this.blue_p1 || this.red_p1 === this.blue_p2 ||
this.red_p2 === this.blue_p1 || this.red_p2 === this.blue_p2) &&
this.blue_p2 !== 'NULL' && this.red_p2 !== 'NULL'
) {
this.sendMessage('need2differentplayers');
return false;
}
default:
if(!this.red_p1 || this.red_p1 === '') {
this.sendMessage('missing.red_p1');
return false;
}
if(!this.blue_p1 || this.blue_p1 === '') {
this.sendMessage('missing.blue_p1');
return false;
}
if(this.red_p1 === this.blue_p1) {
this.sendMessage('needdifferentplayers');
return false;
}
if(this.red_score === this.blue_score) {
this.sendMessage('noequals');
return false;
}
break;
}
return true;
},
addMatch() {
if (this.checkSubmission()) {
let self = this;
axios.post('/add_score.php', {
red_score: self.red_score,
blue_score: self.blue_score,
red_p1: self.red_p1,
red_p2: self.red_p2,
blue_p1: self.blue_p1,
blue_p2: self.blue_p2,
}).then(function (response) {
console.log(response);
self.ranking = response.data;
self.commentMatch.call(self);
self.red_p1 = 0;
self.red_p2 = 'NULL';
self.blue_p1 = 0;
self.blue_p2 = 'NULL';
self.red_score = 0;
self.blue_score = 0;
}).catch(function (error) {
console.error(error);
this.say('Une erreur est survenue.');
alert('Une erreur est survenue.');
});
}
},
commentMatch() {
let self = this,
vars,
message,
messages = this.messages[this.match_type][Math.floor(Math.random()*2) ?
'forthewinner' : 'forthelooser'];
if(messages.length) {
message = messages[Math.floor(Math.random() * messages.length)];
console.log(message);
if( message.constructor.name === 'HTMLAudioElement') {
this.play(message);
} else {
vars = message.match(/:[0-9A-Za-z_]*/g);
if(vars) {
for(let match of vars) {
try {
message = message.replace(new RegExp(match, 'g'), self[match.substr(1)]);
} catch(e) {
console.error('String replace failed ', e);
}
}
}
this.say(message);
}
}
},
sendMessage(messageKey) {
this.error = this.messages[messageKey].error;
this.say(this.messages[messageKey].speech);
},
setBestVoice() {
(new Promise(
function (resolve, reject) {
let synth = window.speechSynthesis;
let id;
id = setInterval(() => {
if (synth.getVoices().length !== 0) {
resolve(synth.getVoices());
clearInterval(id);
}
}, 10);
}
)).then((function(voices) {
let frVoices = {};
for(let voice of window.speechSynthesis.getVoices()) {
if(voice.lang.indexOf('fr') !== -1) {
if(voice.name === 'Google français') {
frVoices.google = voice;
}
if(voice.name.indexOf('Microsoft') !== -1) {
frVoices.microsoft = voice;
}
frVoices.unknown = voice;
}
}
this.utterance.voice = frVoices.google ? frVoices.google : (frVoices.microsoft ? frVoices.microsoft : frVoices.unknown)
}).bind(this));
},
say(text) {
console.info('Saying : ' + text);
this.utterance.text = text;
window.speechSynthesis.speak(this.utterance);
},
play(audio) {
console.info('Playing : ' + audio.src);
audio.play();
},
getPlayer(id) {
for(let player of this.players) {
if(player.id === id) {
return player;
}
}
return null;
},
}
})
</script>
</body>
</html>