一键导入
dev-multiplayer-anti-cheat-validation
Input validation and anti-cheat patterns for multiplayer servers. Use when implementing server-side validation.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
Input validation and anti-cheat patterns for multiplayer servers. Use when implementing server-side validation.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
基于 SOC 职业分类
Complete Developer workflow orchestration - task research sequence, implementation flow, validation gates, PRD synchronization, exit conditions.
Complete Game Designer workflow - skill invocation protocol, GDD creation, playtest flow with GDD review, design sessions. MUST load before starting assignments.
Complete PM Coordinator workflow - task assignment, project orchestration, PRD management, worker coordination. Use proactively when starting PM agent work.
Complete PM Coordinator workflow - task assignment, project orchestration, PRD management, worker coordination. Use proactively when starting PM agent work.
Complete QA Validator workflow orchestration. References specialized skills for each validation step. Load at session startup for full protocol.
Base instructions and guidelines for all agents in the system. This skill provides foundational behaviors and communication protocols that all agents should follow.
| name | dev-multiplayer-anti-cheat-validation |
| description | Input validation and anti-cheat patterns for multiplayer servers. Use when implementing server-side validation. |
| category | multiplayer |
Server-side validation to prevent cheating in multiplayer games.
Use when:
function validateInput(input: PlayerInput, player: PlayerState): boolean {
// Sanity checks - reject impossible inputs
if (input.movementSpeed > 20) return false; // Speed hack
if (input.jumpHeight > 10) return false; // Super jump hack
// Movement constraints
const dx = input.targetX - player.x;
const dz = input.targetZ - player.z;
const distance = Math.sqrt(dx * dx + dz * dz);
// Can't move more than X meters per tick
if (distance > 2) return false;
return true;
}
onMessage(client: Client, data: any) {
const player = this.state.players.get(client.sessionId);
if (!player) return;
if (data.type === 'player_input') {
// VALIDATE before processing
if (validateInput(data.input, player)) {
player.pendingInput = data.input;
} else {
// Log potential cheater
console.warn(`Suspicious input from ${client.sessionId}`);
}
}
}
onMessage(client: Client, data: any) {
if (data.type !== 'shoot') return;
const shooter = this.state.players.get(client.sessionId);
if (!shooter) return;
// Validate shooter can shoot
if (shooter.ink <= 0) return;
if (Date.now() - shooter.lastShotTime < 100) return; // 100ms cooldown
// Validate aim direction is reasonable
const aim = data.aimDirection;
const aimLength = Math.sqrt(aim.x ** 2 + aim.y ** 2 + aim.z ** 2);
if (aimLength > 1.1 || aimLength < 0.9) return; // Must be normalized
// Server creates paint projectile
const projectile = {
x: shooter.x,
y: shooter.y + 1.5,
z: shooter.z,
dx: aim.x * 25,
dy: aim.y * 25,
dz: aim.z * 25,
owner: client.sessionId,
team: shooter.team,
};
this.projectiles.push(projectile);
shooter.ink -= 1;
shooter.lastShotTime = Date.now();
}
// Server validates hits by rewinding time
function checkHit(shooter: PlayerState, targetId: string, aim: Vector3): boolean {
const target = this.state.players.get(targetId);
if (!target) return false;
// Get target position at the time of shooting (lag compensation)
const shotTime = Date.now();
const latency = this.getClientLatency(shooter.sessionId);
const rewindTime = shotTime - latency;
// Find where target was at rewindTime
const historicalPosition = this.getPositionHistory(targetId, rewindTime);
if (!historicalPosition) return false;
// Raycast from shooter to historical position
return this.raycastHits(shooter, historicalPosition, aim);
}
// Store position history for lag compensation
private positionHistory: Map<string, Array<{time: number, x: number, y: number, z: number}>> = new Map();
update(dt: number) {
const now = Date.now();
for (const [sessionId, player] of this.state.players) {
if (!this.positionHistory.has(sessionId)) {
this.positionHistory.set(sessionId, []);
}
const history = this.positionHistory.get(sessionId)!;
// Store position for lag compensation (keep last 500ms)
history.push({ time: now, x: player.x, y: player.y, z: player.z });
// Remove old entries
while (history.length > 0 && history[0].time < now - 500) {
history.shift();
}
}
}
| ❌ Wrong | ✅ Right |
|---|---|
| Trust client position | Validate all inputs |
| No rate limiting | Add cooldowns |
| No logging | Log suspicious activity |
| Client determines hit | Server validates hit |