244 lines
8.0 KiB
JavaScript
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();
|
|
}
|
|
|
|
})();
|