Achivements abends um 19 uhr

This commit is contained in:
2025-09-07 16:54:09 +02:00
parent 8342d95a13
commit 5bed125cf6
10 changed files with 1136 additions and 347 deletions

View File

@@ -0,0 +1,198 @@
const { Pool } = require('pg');
require('dotenv').config();
const pool = new Pool({
host: process.env.DB_HOST || 'localhost',
port: process.env.DB_PORT || 5432,
database: process.env.DB_NAME || 'ninjacross',
user: process.env.DB_USER || '',
password: process.env.DB_PASSWORD || '',
ssl: process.env.NODE_ENV === 'production' ? { rejectUnauthorized: false } : false
});
async function runBestTimeAchievements() {
const client = await pool.connect();
try {
console.log('🏆 Starting best-time achievement check at 19:00...');
const currentHour = new Date().getHours();
const currentDay = new Date().getDay(); // 0 = Sunday
const currentDate = new Date();
const isLastDayOfMonth = new Date(currentDate.getFullYear(), currentDate.getMonth() + 1, 0).getDate() === currentDate.getDate();
console.log(`Current time: ${currentHour}:00`);
console.log(`Is Sunday: ${currentDay === 0}`);
console.log(`Is last day of month: ${isLastDayOfMonth}`);
// Get all players who have played
const playersResult = await client.query(`
SELECT DISTINCT p.id, p.firstname, p.lastname
FROM players p
INNER JOIN times t ON p.id = t.player_id
`);
console.log(`Found ${playersResult.rows.length} players with times`);
let dailyAwards = 0;
let weeklyAwards = 0;
let monthlyAwards = 0;
// Check best-time achievements for each player
for (const player of playersResult.rows) {
console.log(`Checking best-time achievements for ${player.firstname} ${player.lastname}...`);
// Run best-time achievement check function
await client.query('SELECT check_best_time_achievements_timed($1)', [player.id]);
// Check if new daily achievement was earned today
const dailyResult = await client.query(`
SELECT COUNT(*) as count
FROM player_achievements pa
INNER JOIN achievements a ON pa.achievement_id = a.id
WHERE pa.player_id = $1
AND a.category = 'best_time'
AND a.condition_type = 'daily_best'
AND pa.is_completed = true
AND DATE(pa.earned_at AT TIME ZONE 'Europe/Berlin') = CURRENT_DATE
`, [player.id]);
if (parseInt(dailyResult.rows[0].count) > 0) {
dailyAwards++;
console.log(` 🥇 Daily best achievement earned!`);
}
// Check if new weekly achievement was earned (only on Sunday)
if (currentDay === 0) {
const weeklyResult = await client.query(`
SELECT COUNT(*) as count
FROM player_achievements pa
INNER JOIN achievements a ON pa.achievement_id = a.id
WHERE pa.player_id = $1
AND a.category = 'best_time'
AND a.condition_type = 'weekly_best'
AND pa.is_completed = true
AND DATE(pa.earned_at AT TIME ZONE 'Europe/Berlin') = CURRENT_DATE
`, [player.id]);
if (parseInt(weeklyResult.rows[0].count) > 0) {
weeklyAwards++;
console.log(` 🏆 Weekly best achievement earned!`);
}
}
// Check if new monthly achievement was earned (only on last day of month)
if (isLastDayOfMonth) {
const monthlyResult = await client.query(`
SELECT COUNT(*) as count
FROM player_achievements pa
INNER JOIN achievements a ON pa.achievement_id = a.id
WHERE pa.player_id = $1
AND a.category = 'best_time'
AND a.condition_type = 'monthly_best'
AND pa.is_completed = true
AND DATE(pa.earned_at AT TIME ZONE 'Europe/Berlin') = CURRENT_DATE
`, [player.id]);
if (parseInt(monthlyResult.rows[0].count) > 0) {
monthlyAwards++;
console.log(` 👑 Monthly best achievement earned!`);
}
}
}
console.log(`\n🎉 Best-time achievement check completed!`);
console.log(`Daily awards: ${dailyAwards}`);
console.log(`Weekly awards: ${weeklyAwards}`);
console.log(`Monthly awards: ${monthlyAwards}`);
// Get current best times for today
const bestTimesResult = await client.query(`
SELECT
'daily' as period,
p.firstname || ' ' || p.lastname as player_name,
MIN(t.recorded_time) as best_time
FROM times t
INNER JOIN players p ON t.player_id = p.id
WHERE DATE(t.created_at AT TIME ZONE 'Europe/Berlin') = CURRENT_DATE
GROUP BY p.id, p.firstname, p.lastname
ORDER BY MIN(t.recorded_time) ASC
LIMIT 1
`);
if (bestTimesResult.rows.length > 0) {
const dailyBest = bestTimesResult.rows[0];
console.log(`\n🥇 Today's best time: ${dailyBest.player_name} - ${dailyBest.best_time}`);
}
// Get current best times for this week (if Sunday)
if (currentDay === 0) {
const weekStart = new Date();
weekStart.setDate(weekStart.getDate() - weekStart.getDay());
const weeklyBestResult = await client.query(`
SELECT
'weekly' as period,
p.firstname || ' ' || p.lastname as player_name,
MIN(t.recorded_time) as best_time
FROM times t
INNER JOIN players p ON t.player_id = p.id
WHERE DATE(t.created_at AT TIME ZONE 'Europe/Berlin') >= $1
AND DATE(t.created_at AT TIME ZONE 'Europe/Berlin') <= CURRENT_DATE
GROUP BY p.id, p.firstname, p.lastname
ORDER BY MIN(t.recorded_time) ASC
LIMIT 1
`, [weekStart.toISOString().split('T')[0]]);
if (weeklyBestResult.rows.length > 0) {
const weeklyBest = weeklyBestResult.rows[0];
console.log(`🏆 This week's best time: ${weeklyBest.player_name} - ${weeklyBest.best_time}`);
}
}
// Get current best times for this month (if last day of month)
if (isLastDayOfMonth) {
const monthStart = new Date(currentDate.getFullYear(), currentDate.getMonth(), 1);
const monthlyBestResult = await client.query(`
SELECT
'monthly' as period,
p.firstname || ' ' || p.lastname as player_name,
MIN(t.recorded_time) as best_time
FROM times t
INNER JOIN players p ON t.player_id = p.id
WHERE DATE(t.created_at AT TIME ZONE 'Europe/Berlin') >= $1
AND DATE(t.created_at AT TIME ZONE 'Europe/Berlin') <= CURRENT_DATE
GROUP BY p.id, p.firstname, p.lastname
ORDER BY MIN(t.recorded_time) ASC
LIMIT 1
`, [monthStart.toISOString().split('T')[0]]);
if (monthlyBestResult.rows.length > 0) {
const monthlyBest = monthlyBestResult.rows[0];
console.log(`👑 This month's best time: ${monthlyBest.player_name} - ${monthlyBest.best_time}`);
}
}
} catch (error) {
console.error('❌ Error running best-time achievements:', error);
throw error;
} finally {
client.release();
}
}
// Run if called directly
if (require.main === module) {
runBestTimeAchievements()
.then(() => {
console.log('✅ Best-time achievements script completed successfully');
process.exit(0);
})
.catch((error) => {
console.error('❌ Best-time achievements script failed:', error);
process.exit(1);
});
}
module.exports = { runBestTimeAchievements };

View File

@@ -1,24 +1,48 @@
const { exec } = require('child_process');
const path = require('path');
// Cron job setup for daily achievements
const cronJob = {
// Run daily at 23:59 (end of day)
schedule: '59 23 * * *',
command: `cd ${__dirname} && node daily_achievements.js >> /var/log/ninjaserver_achievements.log 2>&1`,
description: 'Daily achievement check for Ninja Cross Parkour'
};
// Cron job setup for achievements
const cronJobs = [
{
name: 'daily_achievements',
// Run daily at 19:00 for best-time achievements
schedule: '0 19 * * *',
command: `cd ${__dirname} && node best_time_achievements.js >> /var/log/ninjaserver_achievements.log 2>&1`,
description: 'Daily best-time achievement check at 19:00'
},
{
name: 'weekly_achievements',
// Run every Sunday at 19:00 for weekly best-time achievements
schedule: '0 19 * * 0',
command: `cd ${__dirname} && node best_time_achievements.js >> /var/log/ninjaserver_achievements.log 2>&1`,
description: 'Weekly best-time achievement check on Sunday at 19:00'
},
{
name: 'monthly_achievements',
// Run on last day of month at 19:00 for monthly best-time achievements
schedule: '0 19 28-31 * * [ $(date -d tomorrow +\\%d) -eq 1 ]',
command: `cd ${__dirname} && node best_time_achievements.js >> /var/log/ninjaserver_achievements.log 2>&1`,
description: 'Monthly best-time achievement check on last day of month at 19:00'
}
];
function setupCronJob() {
console.log('🕐 Setting up daily achievement cron job...');
function setupCronJobs() {
console.log('🕐 Setting up best-time achievement cron jobs...');
// Create cron job entry
const cronEntry = `${cronJob.schedule} ${cronJob.command}`;
let cronEntries = [];
// Add to crontab
exec(`(crontab -l 2>/dev/null; echo "${cronEntry}") | crontab -`, (error, stdout, stderr) => {
// Create cron job entries
cronJobs.forEach(job => {
const cronEntry = `${job.schedule} ${job.command}`;
cronEntries.push(cronEntry);
console.log(`📅 ${job.name}: ${job.schedule} - ${job.description}`);
});
// Add all cron jobs to crontab
const allCronEntries = cronEntries.join('\n');
exec(`(crontab -l 2>/dev/null; echo "${allCronEntries}") | crontab -`, (error, stdout, stderr) => {
if (error) {
console.error('❌ Error setting up cron job:', error);
console.error('❌ Error setting up cron jobs:', error);
return;
}
@@ -26,9 +50,7 @@ function setupCronJob() {
console.error('⚠️ Cron job warning:', stderr);
}
console.log('✅ Cron job setup successfully!');
console.log(`📅 Schedule: ${cronJob.schedule}`);
console.log(`🔧 Command: ${cronJob.command}`);
console.log('✅ All cron jobs setup successfully!');
console.log('📝 Logs will be written to: /var/log/ninjaserver_achievements.log');
// Show current crontab
@@ -41,16 +63,16 @@ function setupCronJob() {
});
}
function removeCronJob() {
console.log('🗑️ Removing daily achievement cron job...');
function removeCronJobs() {
console.log('🗑️ Removing best-time achievement cron jobs...');
exec('crontab -l | grep -v "daily_achievements.js" | crontab -', (error, stdout, stderr) => {
exec('crontab -l | grep -v "best_time_achievements.js" | crontab -', (error, stdout, stderr) => {
if (error) {
console.error('❌ Error removing cron job:', error);
console.error('❌ Error removing cron jobs:', error);
return;
}
console.log('✅ Cron job removed successfully!');
console.log('✅ All cron jobs removed successfully!');
});
}
@@ -60,27 +82,27 @@ if (require.main === module) {
switch (command) {
case 'setup':
setupCronJob();
setupCronJobs();
break;
case 'remove':
removeCronJob();
removeCronJobs();
break;
case 'status':
exec('crontab -l | grep daily_achievements', (error, stdout, stderr) => {
exec('crontab -l | grep best_time_achievements', (error, stdout, stderr) => {
if (stdout) {
console.log('✅ Cron job is active:');
console.log('✅ Best-time achievement cron jobs are active:');
console.log(stdout);
} else {
console.log('❌ No cron job found');
console.log('❌ No best-time achievement cron jobs found');
}
});
break;
default:
console.log('Usage: node setup_cron.js [setup|remove|status]');
console.log(' setup - Add daily achievement cron job');
console.log(' remove - Remove daily achievement cron job');
console.log(' status - Check if cron job is active');
console.log(' setup - Add best-time achievement cron jobs (daily 19:00, Sunday 19:00, last day of month 19:00)');
console.log(' remove - Remove all best-time achievement cron jobs');
console.log(' status - Check if best-time achievement cron jobs are active');
}
}
module.exports = { setupCronJob, removeCronJob };
module.exports = { setupCronJobs, removeCronJobs };