123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268 |
- const express = require('express')
- const app = express()
- const port = 9700
- const web3operatorAddress = "http://vps.playpoolstudios.com:2015/"
- const apiAddress = "https://vps.playpoolstudios.com/metahunt/api/"
- app.get('/', (req, res) => {
- res.send('Validator is validating')
- })
- app.listen(port, () => {
- console.log(`Mhunt Validator is listening on port ${port}`)
- })
- app.get('/validateSession', async (req, res) => {
- const { tournamentId, address } = req.query;
- if (!tournamentId || !address) { res.send("invalid params"); return; }
- let tournament = GetTournamentById(tournamentId);
- if (tournament == null) {
- await CheckForStartedTourneys();
- tournament = GetTournamentById(tournamentId);
- }
- if (tournament == null) {
- console.log(`tourney id:${tournamentId} is not available`);
- //res.send("This tournament is not either started or valid");
- // return;
- }
- tournament.displayDetails();
- const found = tournament.participents.some(participant => participant == address);
- if (found) {
- return res.send("0");
- } else {
- return res.send("-1");
- }
- })
- app.post('/updateBlock', async (req, res) => {
- const jsonData = req.body;
-
- const tournamentBlock = new TournamentBlockData(jsonData);
- tournamentBlocks.push(tournamentBlock);
- console.log(tournamentBlocks);
- res.sendStatus(200);
- });
- /* ------------------------------------------------------------------------------- */
- let tournamentsList ;
- let startedTournaments;
- let tournamentBlocks = [];
- /* ------------------------------------------------------------------------------- */
- CheckForStartedTourneys();
- setInterval(async () => {
- CheckForStartedTourneys();
- }, 60000)
- async function CheckForStartedTourneys() {
- const tournamentsResponse = await fetch(apiAddress + "get_tournaments_raw.php");
- const tournaments = await tournamentsResponse.json();
- tournamentsList = [];
- startedTournaments = [];
- const now = new Date();
- const tenMinutesAgo = new Date(now.getTime() - 10 * 60000); // 10 minutes ago from now
- tournaments.forEach(async tournament => {
- const tournamentDate = new Date(tournament.start_date); // Converts the string date to a Date object
- // Create a new TournamentData instance using the tournament JSON data
- const newTournament = new TournamentData(
- tournament.id,
- tournament.name,
- tournament.start_date,
- tournament.game_mode,
- tournament.reward,
- tournament.php_reward,
- tournament.is_test,
- tournament.ticket_count,
- tournament.owner_id
- );
- if (tournamentDate >= tenMinutesAgo && tournamentDate <= now || true) {
- console.log(`Tournament "${tournament.name}" started within the last 10 minutes.`);
- const participentsUrl = web3operatorAddress + "getTournamentParticipants?id=" + newTournament.id;
- const participentsResponse = await fetch(participentsUrl);
- const participentsJson = await participentsResponse.json();
- const participents = participentsJson["wallets"].split(',');
- try {
- participents.forEach(participent => {
- newTournament.participents.push(participent);
- })
- //newTournament.displayDetails();
- } catch {
- console.log(`tourneyId:${newTournament.id} has no participents. ${JSON.stringify(participents)}`)
- }
- startedTournaments.push(newTournament);
- } else if (tournamentDate > now) {
- console.log(`Tournament "${tournament.name}" is yet to come`)
- } else {
- // console.log(`Tournament "${tournament.name}" is expired`)
- }
- // newTournament.displayDetails();
- // Push the new tournament instance into tournamentsList
- tournamentsList.push(newTournament);
- });
- }
- /* ------------------------------------------------------------------------------- */
- setInterval(async () => {
- ScanBlocks();
- }, 60000)
- function ScanBlocks(){
- for(let i=0; i < tournamentBlocks.length; i++){
- let isValid = true;
- for(let j=0; j < startedTournaments.length; j++){
- if(startedTournaments[j].id == tournamentBlocks[i].tournamentId){
- //Found the matching tourney for this block
- if(!startedTournaments[j].participents.include(tournamentBlocks[i].owner)){
- // isValid=false;
- console.log("***Block was sent by non-participent. Allowing this for now.");
- }
- break;
- }
- }
- }
- }
- /* ----------------------------------METHODS----------------------------------- */
- function GetTournamentById(tournamentId) {
- const tournament = startedTournaments.find(tournament => tournament.id == tournamentId);
- return tournament;
- }
- /* ------------------------------------------------------------------------------- */
- /* ------------------------------CUSTOM CLASSES------------------------------------ */
- class TournamentData {
- constructor(id, name, start_date, game_mode, reward, php_reward, is_test, ticket_count, owner_id) {
- this.id = id;
- this.name = name;
- this.start_date = start_date;
- this.game_mode = game_mode;
- this.reward = reward;
- this.php_reward = php_reward;
- this.is_test = is_test;
- this.ticket_count = ticket_count;
- this.owner_id = owner_id;
- this.participents = [];
- }
- // Method to display tournament details
- displayDetails() {
- console.log(`Tournament ID: ${this.id}`);
- console.log(`Name: ${this.name}`);
- console.log(`Date: ${this.start_date}`);
- console.log(`Game Mode: ${this.game_mode}`);
- console.log(`Reward: ${this.reward}`);
- console.log(`PHP Reward: ${this.php_reward}`);
- console.log(`Test Tournament: ${this.is_test ? "Yes" : "No"}`);
- console.log(`Ticket Count: ${this.ticket_count}`);
- console.log(`Owner ID: ${this.owner_id}`);
- console.log(`Participents: ${this.participents}`);
- }
- }
- // Define a dictionary to store tournament leaderboards after validation
- const confirmedLeaderboards = {};
- // Function to scan and analyze blocks
- function ScanBlocks() {
- const blockValidationCounts = {};
- // First, validate each block and count valid ones for each tournament
- for (let i = 0; i < tournamentBlocks.length; i++) {
- let isValid = true;
- // Loop through the started tournaments to validate the block
- for (let j = 0; j < startedTournaments.length; j++) {
- if (startedTournaments[j].id === tournamentBlocks[i].tournamentId) {
- // Found the matching tournament for this block
- if (!startedTournaments[j].participants.includes(tournamentBlocks[i].owner)) {
- console.log("***Block was sent by non-participant. Allowing this for now.");
- isValid = false;
- break;
- }
- // Compare blocks with the same tournamentId and minute number
- for (let k = 0; k < tournamentBlocks.length; k++) {
- if (
- k !== i &&
- tournamentBlocks[k].tournamentId === tournamentBlocks[i].tournamentId &&
- tournamentBlocks[k].minute === tournamentBlocks[i].minute
- ) {
- // Found another block with the same tournamentId and minute
- if (JSON.stringify(tournamentBlocks[k].leaderboard) !== JSON.stringify(tournamentBlocks[i].leaderboard)) {
- console.log(`***Mismatch detected in leaderboard for tournament ${tournamentBlocks[i].tournamentId} at minute ${tournamentBlocks[i].minute}`);
- isValid = false;
- break;
- }
- }
- }
- }
- }
- if (isValid) {
- console.log(`Block ${i + 1} is valid.`);
-
- // Track the valid blocks per tournament
- const tournamentId = tournamentBlocks[i].tournamentId;
- if (!blockValidationCounts[tournamentId]) {
- blockValidationCounts[tournamentId] = { count: 0, total: 0 };
- }
- blockValidationCounts[tournamentId].count++;
- } else {
- console.log(`Block ${i + 1} is invalid.`);
- }
- // Track total blocks per tournament for comparison later
- const tournamentId = tournamentBlocks[i].tournamentId;
- if (!blockValidationCounts[tournamentId]) {
- blockValidationCounts[tournamentId] = { count: 0, total: 0 };
- }
- blockValidationCounts[tournamentId].total++;
- }
- // After validation, confirm tournaments with more than 50% valid blocks
- for (const tournamentId in blockValidationCounts) {
- const { count, total } = blockValidationCounts[tournamentId];
- if (count > total / 2) {
- // More than 50% of blocks are valid, store the leaderboard
- const validBlock = tournamentBlocks.find(block => block.tournamentId === parseInt(tournamentId));
- if (validBlock) {
- confirmedLeaderboards[tournamentId] = validBlock.leaderboard;
- console.log(`*** Tournament ${tournamentId} confirmed with a valid leaderboard.`);
- }
- } else {
- console.log(`*** Tournament ${tournamentId} did not meet the 50% valid block requirement.`);
- }
- }
- }
|