353 lines
14 KiB
HTML
353 lines
14 KiB
HTML
<!DOCTYPE html>
|
|
<html>
|
|
|
|
<head>
|
|
<meta charset="UTF-8" />
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1">
|
|
<link rel="apple-touch-icon" sizes="60x60" href="/apple-touch-icon-60x60.png">
|
|
<link rel="apple-touch-icon" sizes="76x76" href="/apple-touch-icon-76x76.png">
|
|
<link rel="apple-touch-icon" sizes="120x120" href="/apple-touch-icon-120x120.png">
|
|
<link rel="apple-touch-icon" sizes="152x152" href="/apple-touch-icon-152x152.png">
|
|
<link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon-180x180.png">
|
|
<link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png">
|
|
<link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png">
|
|
<link rel="manifest" href="/site.webmanifest">
|
|
<link rel="mask-icon" href="/safari-pinned-tab.svg" color="#181825">
|
|
<meta name="apple-mobile-web-app-title" content="Black Cat">
|
|
<meta name="application-name" content="Black Cat">
|
|
<meta name="msapplication-TileColor" content="#181825">
|
|
<meta name="theme-color" content="#181825">
|
|
|
|
<link rel="stylesheet" type="text/css" href="/css/style.css" />
|
|
|
|
<title>Black Cat</title>
|
|
<script src="/js/socket.io.min.js" integrity="sha384-/KNQL8Nu5gCHLqwqfQjA689Hhoqgi2S84SNUxC3roTe4EhJ9AfLkp8QiQcU8AMzI"
|
|
crossorigin="anonymous"></script>
|
|
</head>
|
|
|
|
<body>
|
|
<!-- Box shown when starting a new session -->
|
|
<div id="centerbox" class="center">
|
|
<span class="title" style="color: #626262;">black<span
|
|
style="color: #e5e5e5; font-weight: normal; font-family: 'Noto Sans Mono', monospace;"><span
|
|
style="color: #74c7ec">~</span><span style="color: #a6e3a1">$</span> <a
|
|
style="color:#e5e5e5;text-decoration:none;" href="https://man7.org/linux/man-pages/man1/cat.1.html"
|
|
target="_blank">cat</a><span class="blink">_</span></span></span>
|
|
<div class="inputs">
|
|
<label for="playerName">Your Name:</label>
|
|
<span><input id="playerName" placeholder="_"></input></span>
|
|
<label for="roomCode">Game Code:</label>
|
|
<span><input id="roomCode" placeholder="_"></input></span>
|
|
<script type="text/javascript">
|
|
document.getElementById("playerName").value = "";
|
|
document.getElementById("roomCode").value = "";
|
|
</script>
|
|
</div>
|
|
<span id="error"></span>
|
|
<div class="buttons">
|
|
<div class="buttongroup" id="gamestart">
|
|
<button class="hostbutton" onclick="host()">Host</button>
|
|
<button class="joinbutton" onclick="join()">Join</button>
|
|
</div>
|
|
<div style="display: none;" id="classselect">
|
|
<button id="scout" onclick="classChange('Scout')">Scanner</button>
|
|
<button id="antivirus" onclick="classChange('Antivirus')">Antivirus</button>
|
|
<button id="firewall" onclick="classChange('Firewall')">Firewall</button>
|
|
</div>
|
|
<div class="buttongroup" id="readyup" style="display:none;">
|
|
<button id="ready" onclick="ready()">Ready</button>
|
|
</div>
|
|
</div>
|
|
|
|
<div id="playerContainer" class="stats buttons" style="text-align: left; width: 90%;display:none;">
|
|
<h3 id="playerHeader" for="playerList" style="display: none;">Players:</h3>
|
|
<ul id="playerList" style="margin-left: 30px;display: none;">
|
|
</ul>
|
|
<br>
|
|
<hr>
|
|
<br>
|
|
<label style="display: none;" id="classLabel" for="playerClass">Your Class: </label>
|
|
<span style="display: none;" id="playerClass"></span>
|
|
<p id="readiness"></p>
|
|
<button id="start" style="display: none" onclick="start()">Start</button>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Box shown after the game has begun -->
|
|
<div id="game" class="game" style="display:none;">
|
|
<h1 id="winLose" style="display: none;"></h1>
|
|
<span id="cover" class="cover" style="display:none;"></span>
|
|
<h1 style="text-align: center;">Files</h1>
|
|
<ol id="files">
|
|
</ol>
|
|
</div>
|
|
|
|
<div id="controlMenu" class="center" style="display:none;">
|
|
<p id="hp"></p>
|
|
<p id="actionAmount"></p>
|
|
<br class="hidemobile"><br class="hidemobile">
|
|
<div id="controlButtons">
|
|
<button id="move" onclick="move()">Move</button>
|
|
<button style="display:none;" id="detect" onclick="action('detect')">Detect</button>
|
|
<button style="display:none;" id="disinfect" onclick="action('disinfect')">Disinfect</button>
|
|
<button style="display:none;" id="purge" onclick="action('purge')">Purge</button>
|
|
<button style="display:none;" id="smash" onclick="smash()">Clean</button>
|
|
</div>
|
|
<span id="direction" style="font-size: 16pt;width:100%;text-align:center;display:block;"></span>
|
|
<br class="hidemobile">
|
|
<hr class="hidemobile">
|
|
<br class="hidemobile">
|
|
<h2>Log:</h2>
|
|
<p id="status"></p>
|
|
</div>
|
|
|
|
<div id="debugMenu" class="center" style="display: none;">
|
|
<button id="godStart" onclick="godStart()">Force Start</button>
|
|
<button id="godScout" onclick="classChange('Scout')">Scout</button>
|
|
<button id="godAntivirus" onclick="classChange('Antivirus')">Antivirus</button>
|
|
<button id="godFirewall" onclick="classChange('Firewall')">Firewall</button>
|
|
<button id="godActions" onclick="actionUp()">Action+</button>
|
|
<button id="godExit" onclick="location.reload()">Lobby</button>
|
|
</div>
|
|
</body>
|
|
|
|
</html>
|
|
|
|
<!-- End of HTML, beginning of JS -->
|
|
|
|
<script>
|
|
const socket = io();
|
|
|
|
socket.on('hp', function (hp) {
|
|
document.getElementById('hp').innerText = `Computer is at ${hp}HP`
|
|
})
|
|
|
|
socket.on('actionAmount', function (actionAmount) {
|
|
document.getElementById('actionAmount').innerText = `You have ${actionAmount}/2 actions remaining`
|
|
})
|
|
|
|
//TODO: REMOVE AFTER DEBUG
|
|
function godStart() {
|
|
socket.emit('godStart', document.getElementById('playerName').value)
|
|
}
|
|
|
|
//TODO: REMOVE AFTER DEBUG
|
|
function actionUp() {
|
|
socket.emit('actionUp', document.getElementById('roomCode').value)
|
|
}
|
|
|
|
function start() {
|
|
socket.emit('start', document.getElementById('roomCode').value)
|
|
}
|
|
|
|
function action(action) {
|
|
// Get a reference to all elements with the class "files"
|
|
var files = document.getElementsByClassName('files');
|
|
|
|
// Loop through the elements and add an event listener to each one
|
|
for (var i = 0; i < files.length; i++) {
|
|
files[i].classList.add("highlight");
|
|
files[i].addEventListener('click', (e) => {
|
|
// When the event is triggered, retrieve the value of the element and send it as the file ID
|
|
socket.emit('action', document.getElementById('roomCode').value, action, e.target.id)
|
|
// Loop through the elements again and remove the event listener from each one
|
|
for (var j = 0; j < files.length; j++) {
|
|
files[j].removeEventListener('click', this);
|
|
}
|
|
});
|
|
}
|
|
}
|
|
|
|
function move() {
|
|
socket.emit('move', document.getElementById('roomCode').value)
|
|
}
|
|
|
|
function smash() {
|
|
//TODO: Implement checking the user input
|
|
socket.emit('smash', document.getElementById('roomCode').value, prompt("Player X Position", "A-J"), prompt("Player Y Position", "1-9"))
|
|
}
|
|
|
|
socket.on('file', function (files) {
|
|
// Wipe previous file info
|
|
document.getElementById('files').innerHTML = ''
|
|
// Fill with every file
|
|
for (var i = 0; i < files.length; i++) {
|
|
var file = files[i];
|
|
document.getElementById('files').innerHTML +=
|
|
`<ul class="files" id=${file.id}>
|
|
<span id="tab"><span class="curve"></span></span>
|
|
<span style="font-size:24pt;float: right;right:50px;top:50%;transform:translatey(-50%);position: relative;">${file.id} </span>
|
|
<li id=${file.id}> Location: ${file.x}${file.y} </li>
|
|
<li id=${file.id}> Good Data: ${file.goodData} </li>
|
|
<li id=${file.id}> Bad Data: ${file.badData} </li>
|
|
</ul>`
|
|
;
|
|
}
|
|
})
|
|
|
|
socket.on('start', function (start) {
|
|
document.getElementById('centerbox').style.display = 'none'
|
|
document.getElementById('game').style.display = 'block'
|
|
document.getElementById('controlMenu').style.display = 'block'
|
|
switch (document.getElementById('playerClass').innerText) {
|
|
case 'Scout':
|
|
document.getElementById('detect').style.display = 'inline'
|
|
break
|
|
case 'Antivirus':
|
|
document.getElementById('disinfect').style.display = 'inline'
|
|
break
|
|
case 'Firewall':
|
|
document.getElementById('purge').style.display = 'inline'
|
|
document.getElementById('smash').style.display = 'inline'
|
|
break
|
|
}
|
|
})
|
|
|
|
//TODO: REMOVE AFTER DEBUG
|
|
socket.on('godStart', function (start) {
|
|
switch (document.getElementById('playerClass').innerText) {
|
|
case 'Scout':
|
|
document.getElementById('detect').style.display = 'inline'
|
|
document.getElementById('disinfect').style.display = 'none'
|
|
document.getElementById('purge').style.display = 'none'
|
|
document.getElementById('smash').style.display = 'none'
|
|
break
|
|
case 'Antivirus':
|
|
document.getElementById('disinfect').style.display = 'inline'
|
|
document.getElementById('detect').style.display = 'none'
|
|
document.getElementById('purge').style.display = 'none'
|
|
document.getElementById('smash').style.display = 'none'
|
|
break
|
|
case 'Firewall':
|
|
document.getElementById('purge').style.display = 'inline'
|
|
document.getElementById('smash').style.display = 'inline'
|
|
document.getElementById('detect').style.display = 'none'
|
|
document.getElementById('disinfect').style.display = 'none'
|
|
break
|
|
}
|
|
})
|
|
|
|
function host() {
|
|
var playerName = document.getElementById('playerName').value
|
|
if (playerName === '') {
|
|
socket.emit('host', 'Player')
|
|
} else {
|
|
socket.emit('host', playerName)
|
|
}
|
|
}
|
|
|
|
function join() {
|
|
var playerName = document.getElementById('playerName').value
|
|
if (playerName === '') {
|
|
socket.emit('join', document.getElementById('roomCode').value, 'Player')
|
|
} else {
|
|
socket.emit('join', document.getElementById('roomCode').value, playerName)
|
|
}
|
|
}
|
|
|
|
function classChange(playerClass) {
|
|
// Check if class has already been picked, if it isn't then send class change
|
|
if (document.getElementById(playerClass.toLowerCase()).classList[0] != ('greyedout')) {
|
|
socket.emit('class', document.getElementById('roomCode').value, playerClass)
|
|
}
|
|
}
|
|
|
|
function ready() {
|
|
socket.emit('ready', document.getElementById('roomCode').value)
|
|
}
|
|
|
|
socket.on('code', function (roomCode) {
|
|
document.getElementById('roomCode').value = roomCode
|
|
|
|
//show all classes here, since we know roomCode is valid
|
|
document.getElementById('classselect').style = "display:flex;justify-content:space-between;";
|
|
document.getElementById('readyup').style = "";
|
|
})
|
|
|
|
socket.on('class', function (playerClass) {
|
|
document.getElementById('playerClass').innerText = playerClass
|
|
})
|
|
|
|
socket.on('error', function (error) {
|
|
document.getElementById('error').innerHTML = error
|
|
document.getElementById('status').innerHTML += error + '<br>'
|
|
})
|
|
|
|
socket.on('success', function (message) {
|
|
document.getElementById('status').innerHTML += message + '<br>'
|
|
})
|
|
|
|
socket.on('end', function (message) {
|
|
document.getElementById('winLose').innerText = message
|
|
document.getElementById('winLose').style.display = "block"
|
|
document.getElementById('cover').style.display = "block"
|
|
})
|
|
|
|
socket.on('ready', function (ready) {
|
|
// Updates readiness
|
|
if (ready) {
|
|
document.getElementById('ready').innerText = 'Cancel'
|
|
return
|
|
}
|
|
document.getElementById('ready').innerText = 'Ready'
|
|
})
|
|
|
|
socket.on('startAllowed', function (id) {
|
|
if (id === socket.id) {
|
|
document.getElementById('start').style.display = 'inline'
|
|
}
|
|
else {
|
|
document.getElementById('start').style.display = 'none'
|
|
}
|
|
})
|
|
|
|
socket.on('players', function (playerData) {
|
|
//Reset Error
|
|
document.getElementById('error').innerHTML = ''
|
|
|
|
// Update roles that user can pick
|
|
if (playerData.some((player) => player.class === 'Scout')) {
|
|
document.getElementById('scout').classList.add('greyedout')
|
|
} else {
|
|
document.getElementById('scout').classList.remove('greyedout')
|
|
}
|
|
if (playerData.some((player) => player.class === 'Antivirus')) {
|
|
document.getElementById('antivirus').classList.add('greyedout')
|
|
} else {
|
|
document.getElementById('antivirus').classList.remove('greyedout')
|
|
}
|
|
if (playerData.some((player) => player.class === 'Firewall')) {
|
|
document.getElementById('firewall').classList.add('greyedout')
|
|
} else {
|
|
document.getElementById('firewall').classList.remove('greyedout')
|
|
}
|
|
|
|
document.getElementById('scout').classList.remove('chosenClass')
|
|
document.getElementById('antivirus').classList.remove('chosenClass')
|
|
document.getElementById('firewall').classList.remove('chosenClass')
|
|
|
|
if (document.getElementById('playerClass').innerText != '') {
|
|
document.getElementById(document.getElementById('playerClass').innerText.toLowerCase()).classList.remove('greyedout')
|
|
document.getElementById(document.getElementById('playerClass').innerText.toLowerCase()).classList.add('chosenClass')
|
|
}
|
|
|
|
// Update player list
|
|
document.getElementById('playerList').innerHTML = ''; // Clear existing list\
|
|
document.getElementById('playerContainer').style.display = 'block';
|
|
document.getElementById('playerList').style.display = 'block';
|
|
document.getElementById('playerHeader').style.display = 'block';
|
|
for (var i = 0; i < playerData.length; i++) {
|
|
var player = playerData[i];
|
|
document.getElementById('playerList').innerHTML += '<li>' + player.name + '</li>';
|
|
}
|
|
|
|
// Update readiness of players
|
|
document.getElementById('readiness').innerText = playerData.filter((player) => player.ready === true).length + '/' + playerData.length + ' players ready'
|
|
if (playerData.length < 3) {
|
|
document.getElementById('readiness').innerText += `, still need ${3 - playerData.length} more player`
|
|
if (3 - playerData.length > 1) {
|
|
document.getElementById('readiness').innerText += 's'
|
|
}
|
|
}
|
|
})
|
|
</script>
|