togethere.cloud/public_html/disciplines/ping-pong/js/anti-tamper.js

244 lines
8.0 KiB
JavaScript

/**
* Anti-Tamper Protection Module
* Copyright (c) 2026 Wspólnie - wspolpraca@togethere.cloud
* Wykrywa próby modyfikacji kodu i oszustw
*/
(function() {
'use strict';
class AntiTamper {
constructor() {
this.checksEnabled = true;
this.violations = 0;
this.maxViolations = 3;
this.originalCode = {};
if (this.checksEnabled) {
this.init();
}
}
init() {
// 1. Sprawdź integrity kodu
this.checkCodeIntegrity();
// 2. Wykrywaj Developer Tools
this.detectDevTools();
// 3. Monitoruj modyfikacje DOM
this.monitorDOMChanges();
// 4. Sprawdzaj timing (speed hacks)
this.checkTiming();
// 5. Blokuj console
this.disableConsole();
}
/**
* Sprawdza czy kod został zmodyfikowany
*/
checkCodeIntegrity() {
// Zapisz hash funkcji krytycznych
const criticalFunctions = [
window.PingPongGame,
window.botAI,
window.audioManager
];
setInterval(() => {
criticalFunctions.forEach(func => {
if (func && typeof func === 'function') {
const currentCode = func.toString();
const funcName = func.name;
if (this.originalCode[funcName]) {
if (this.originalCode[funcName] !== currentCode) {
this.reportViolation('Code modification detected');
}
} else {
this.originalCode[funcName] = currentCode;
}
}
});
}, 5000);
}
/**
* Wykrywa otwarcie DevTools
*/
detectDevTools() {
const devtools = {
isOpen: false,
orientation: null
};
const threshold = 160;
const emitEvent = (isOpen, orientation) => {
if (devtools.isOpen !== isOpen || devtools.orientation !== orientation) {
devtools.isOpen = isOpen;
devtools.orientation = orientation;
if (isOpen) {
this.reportViolation('DevTools detected');
}
}
};
setInterval(() => {
const widthThreshold = window.outerWidth - window.innerWidth > threshold;
const heightThreshold = window.outerHeight - window.innerHeight > threshold;
const orientation = widthThreshold ? 'vertical' : 'horizontal';
if (widthThreshold || heightThreshold) {
emitEvent(true, orientation);
} else {
emitEvent(false, null);
}
}, 500);
}
/**
* Monitoruje nielegalne zmiany DOM
*/
monitorDOMChanges() {
const canvas = document.getElementById('gameCanvas');
if (!canvas) return;
const observer = new MutationObserver((mutations) => {
mutations.forEach((mutation) => {
// Sprawdź czy ktoś próbuje modyfikować canvas
if (mutation.type === 'attributes' && mutation.target === canvas) {
this.reportViolation('Canvas modification detected');
}
});
});
observer.observe(canvas, {
attributes: true,
attributeOldValue: true
});
}
/**
* Wykrywa speed hacks poprzez sprawdzanie czasu
*/
checkTiming() {
let lastTime = Date.now();
let frameCount = 0;
setInterval(() => {
const currentTime = Date.now();
const delta = currentTime - lastTime;
// Normalny interval to ~1000ms
// Jeśli jest znacznie szybszy, ktoś modyfikuje czas
if (delta < 800 || delta > 1200) {
frameCount++;
if (frameCount > 3) {
this.reportViolation('Timing manipulation detected');
frameCount = 0;
}
} else {
frameCount = 0;
}
lastTime = currentTime;
}, 1000);
}
/**
* Blokuje console.log i inne metody debugowania
*/
disableConsole() {
if (window.location.hostname !== 'localhost' &&
window.location.hostname !== '127.0.0.1') {
// W produkcji wyłącz console
const noop = () => {};
['log', 'debug', 'info', 'warn', 'error'].forEach(method => {
console[method] = noop;
});
}
}
/**
* Raportuje wykryte naruszenie
*/
reportViolation(reason) {
this.violations++;
console.warn(`Anti-Tamper: ${reason} (${this.violations}/${this.maxViolations})`);
// Wyślij do serwera (opcjonalnie)
this.sendToServer({
type: 'violation',
reason: reason,
timestamp: Date.now(),
userAgent: navigator.userAgent
});
if (this.violations >= this.maxViolations) {
this.blockUser();
}
}
/**
* Blokuje użytkownika po wykryciu oszustwa
*/
blockUser() {
// Zatrzymaj grę
if (window.game) {
window.game.stop();
}
// Wyczyść canvas
const canvas = document.getElementById('gameCanvas');
if (canvas) {
const ctx = canvas.getContext('2d');
ctx.fillStyle = '#ff0000';
ctx.fillRect(0, 0, canvas.width, canvas.height);
ctx.fillStyle = '#ffffff';
ctx.font = '30px Arial';
ctx.textAlign = 'center';
ctx.fillText('CHEATING DETECTED', canvas.width / 2, canvas.height / 2);
ctx.font = '16px Arial';
ctx.fillText('Your session has been terminated', canvas.width / 2, canvas.height / 2 + 40);
}
// Zablokuj interakcję
document.body.style.pointerEvents = 'none';
// Przekieruj po 5 sekundach
setTimeout(() => {
window.location.href = '/';
}, 5000);
}
/**
* Wysyła dane do serwera
*/
sendToServer(data) {
// TODO: Zaimplementuj endpoint na serwerze
/*
fetch('/api/anti-tamper/report', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(data)
}).catch(err => {
// Silent fail
});
*/
}
}
// Inicjalizuj anti-tamper protection
if (typeof window !== 'undefined') {
window.antiTamper = new AntiTamper();
}
})();