DCTF/frontend/script.js

331 lines
11 KiB
JavaScript

"use strict";
document.addEventListener('DOMContentLoaded', function () {
const contractAddress = '0xc8bd0A15E35Ddc1692D907583696443e2970779b';
const nullAddress = '0x0000000000000000000000000000000000000000';
var userAccount = nullAddress;
var btnRegister = document.getElementById("register");
var btnAccountEnable = document.getElementById("account_enable");
btnRegister.addEventListener('click', register);
btnAccountEnable.addEventListener('click', accountEnable);
var funcType;
var mark;
var expirationTime;
var timerIsRunning = false;
var players = [];
// Modern dapp browsers...
if(window.ethereum) {
console.log("Modern dapp browser detected");
window.web3 = new Web3(window.ethereum);
checkNetworkType();
ethereum.on('accountsChanged', (accounts) => accountChange(accounts[0]));
ethereum.on('chainChanged', (_chainId) => window.location.reload());
}
// Legacy dapp browsers...
else if(window.web3) {
console.log("Legacy dapp browser detected");
window.web3 = new Web3(web3.currentProvider);
// Acccounts always exposed
checkNetworkType();
}
// Non-dapp browsers...
else {
console.log("Non-Ethereum browser detected. You should consider trying MetaMask!");
window.web3 = new Web3(new Web3.providers.WebsocketProvider('wss://goerli.infura.io/ws/v3/d82552d5ad5841e5acbbe7a8417a23ad'));
}
function switchToGoerli() {
const iconUrl = "";
const goerli = {
chainId: "0x5",
chainName: "Goerli test network",
rpcUrls: ["https://goerli.infura.io/v3/"],
nativeCurrency: {
name: "GoerliETH",
symbol: "ETH",
decimals: 18,
},
blockExplorerUrls: ["https://goerli.etherscan.io"],
iconUrls: [iconUrl],
};
const { request } = window.ethereum;
request({
method: "wallet_switchEthereumChain",
params: [{ chainId: goerli.chainId }],
}).catch(e => {
// This error code indicates that the chain has not been added to MetaMask.
if (e.code === 4902) {
return request({
method: "wallet_addEthereumChain",
params: [goerli],
});
} else {
throw e;
}
});
}
function checkNetworkType() {
web3.eth.net.getId()
.then(function(result) {
if(result != 5) { /* Goerli Mainnet */
alert("Please select Goerli test network on your Metamask!");
console.log('switchToGoerli');
switchToGoerli();
}
console.log('Network Id:', result);
});
}
function displayShortAddress(address) {
return(address.slice(0, 6) + "..." + address.slice(-4))
}
function setUserAccount() {
var x = userAccount.toString();
document.getElementById("user").textContent = displayShortAddress(x);
if(userAccount != nullAddress) {
document.getElementById("account_locked").style.display = "none";
document.getElementById("account_unlocked").style.display = "block";
}
else {
document.getElementById("account_locked").style.display = "block";
document.getElementById("account_unlocked").style.display = "none";
}
}
function getPlayerStatus() {
myContract.methods.getPlayerStatus(userAccount).call()
.then(function(result) {
console.log("Player status: " + result);
if(result == 0) {
document.getElementById("unverified").style.display = "block";
document.getElementById("verified").style.display = "none";
document.getElementById("banned").style.display = "none";
}
else if(result == 1) {
document.getElementById("unverified").style.display = "none";
document.getElementById("verified").style.display = "block";
document.getElementById("banned").style.display = "none";
}
else {
document.getElementById("unverified").style.display = "none";
document.getElementById("verified").style.display = "none";
document.getElementById("banned").style.display = "block";
}
});
}
function accountChange(newAccount) {
if(web3.utils.isAddress(newAccount)) {
userAccount = web3.utils.toChecksumAddress(newAccount);
}
else userAccount = nullAddress;
console.log('ACCOUNT: ' + userAccount);
console.log('CheckNetworkType');
checkNetworkType();
setUserAccount();
getPlayerStatus();
}
async function getAccount(type) {
if (window.ethereum) { // for modern DApps browser
try {
await window.ethereum.request({ method: 'eth_requestAccounts' });
} catch (error) {
console.error(error);
}
}
if (window.web3){
await window.web3.eth.getAccounts().then(it => {
accountChange(it[0]);
if (type == "REGISTER") registerPlayer();
});
}
else {
alert('No Metamask or Ethereum wallet found. Read "Getting Started" for more information');
console.log('No Metamask or Ethereum wallet found. Read "Getting Started" for more information');
}
}
function register() {
funcType = "REGISTER";
getAccount(funcType);
}
function accountEnable() {
funcType = "NONE";
getAccount(funcType);
}
function setPlayers(data) {
document.getElementById("players").textContent = data;
}
function setSubmissions(data) {
document.getElementById("submissions").textContent = data;
}
function setExpiration(newExpiration) {
if(! timerIsRunning) startTimer();
expirationTime = newExpiration;
updateClock();
}
function setRank(data) {
var text = "";
text += "<tr><th>PlayerStatus</th><th>Name</th><th>Flags found</th><th>Points</th></tr>";
data.forEach(item => {
console.log(item[2]);
text += "<tr><td>" + item[0] + "</td><td>" + item[2] + "</td><td>" + item[3] + "</td><td>" + item[1] + "</td></tr>";
});
document.getElementById("loading").style.display = "none";
document.getElementById("rank_list").innerHTML = text;
}
function registerPlayer() {
var rtfm = 'I_read_it'; // todo: Checkbox check removed for easier testing
var playerName = document.getElementById("playerName").value;
myContract.methods.register(rtfm, playerName).send({from: userAccount})
.then(function() {
console.log("register()");
rank();
getPlayerStatus();
getPlayers();
});
}
function isGameGoing() {
myContract.methods.started().call()
.then(function(result) {
console.log("is going: " + result);
return(result);
});
}
function startTimer() {
mark = setInterval(updateClock, 1000);
timerIsRunning = true;
}
function stopTimer() {
clearInterval(mark);
timerIsRunning = false;
}
function updateClock() {
const remainingTime = expirationTime - Math.floor((new Date()).getTime() / 1000);
if(remainingTime > 0) {
//var hour = Math.floor(remainingTime / (60 * 60)) % 24;
var hour = Math.floor(remainingTime / (60 * 60));
var min = Math.floor(remainingTime / 60) % 60;
var sec = remainingTime % 60;
if(hour < 10) hour = '0' + hour;
if(min < 10) min = '0' + min;
if(sec < 10) sec = '0' + sec;
document.getElementById("remaining_time").textContent = hour + ':' + min + ':' + sec;
}
else gameOver();
}
function gameOver() {
stopTimer();
document.getElementById("remaining_time").textContent = "--:--:--";
if(isGameGoing()) {
document.getElementById("remaining_time").textContent = "Game Over";
}
else {
document.getElementById("remaining_time").textContent = "Not Started";
}
}
function expiration() {
myContract.methods.endTime().call()
.then(function(result) {
console.log("expiration: " + result);
setExpiration(result);
});
}
function getPlayers() {
myContract.methods.playerCount().call()
.then(function(result) {
console.log("playerCount: " + result);
setPlayers(result);
});
}
function submissions() {
myContract.methods.getSuccessfulSubmissionCount().call()
.then(function(result) {
console.log("SuccessfulSubmissionCount: " + result);
setSubmissions(result);
});
}
function rank() {
myContract.methods.getPlayers().call()
.then(function(result) {
console.log("Players: " + result);
setRank(result);
});
}
//===============================================================================================
// Get the modal
var modal = document.getElementById('myModal');
// Get the button that opens the modal
var btn = document.getElementById("myBtn");
// Get the <span> element that closes the modal
var span = document.getElementsByClassName("close")[0];
// When the user clicks the button, open the modal
btn.onclick = function() {
modal.style.display = "block";
}
// When the user clicks on <span> (x), close the modal
span.onclick = function() {
modal.style.display = "none";
}
// When the user clicks anywhere outside of the modal, close it
window.onclick = function(event) {
if (event.target == modal) {
modal.style.display = "none";
}
}
//===============================================================================================
var myContract;
myContract = new web3.eth.Contract(myABI, contractAddress);
myContract.events.PlayerStatusChanged()
.on("data", function(event) {
var data = event.returnValues;
console.log("PlayerStatusChanged: " + data);
rank();
})
.on("error", function(error) {
var text = error;
console.log("PlayerStatusChanged: " + text);
})
.on("error", console.error);
expiration();
getPlayers();
submissions();
rank();
});