Game server security including encryption, anti-cheat, and secure communication
Implements server-side validation, encryption, and anti-cheat detection for game servers. Use when building authoritative game servers that need to prevent speed hacks, wall hacks, and replay attacks.
/plugin marketplace add pluginagentmarketplace/custom-plugin-server-side-game-dev/plugin install server-side-game-dev-plugin@pluginagentmarketplace-game-serverThis skill inherits all available tools. When active, it can use any tool Claude has access to.
assets/config.yamlassets/security-checklist.yamlreferences/GUIDE.mdreferences/SECURITY_GUIDE.mdscripts/helper.pyscripts/token_generator.pyImplement secure game server architecture with encryption and anti-cheat measures.
[Client] ← TLS 1.3 → [Load Balancer] ← mTLS → [Game Server]
↓
[Encrypted State]
#include <openssl/ssl.h>
SSL_CTX* createSecureContext() {
SSL_CTX* ctx = SSL_CTX_new(TLS_server_method());
// TLS 1.3 only
SSL_CTX_set_min_proto_version(ctx, TLS1_3_VERSION);
SSL_CTX_set_max_proto_version(ctx, TLS1_3_VERSION);
// Load certificates
SSL_CTX_use_certificate_file(ctx, "server.crt", SSL_FILETYPE_PEM);
SSL_CTX_use_PrivateKey_file(ctx, "server.key", SSL_FILETYPE_PEM);
// Secure cipher suites only
SSL_CTX_set_ciphersuites(ctx,
"TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256");
// Enable session tickets
SSL_CTX_set_session_cache_mode(ctx, SSL_SESS_CACHE_SERVER);
return ctx;
}
SSL_CTX* createDTLSContext() {
SSL_CTX* ctx = SSL_CTX_new(DTLS_server_method());
SSL_CTX_set_min_proto_version(ctx, DTLS1_2_VERSION);
// Cookie verification to prevent DoS
SSL_CTX_set_cookie_generate_cb(ctx, generateCookie);
SSL_CTX_set_cookie_verify_cb(ctx, verifyCookie);
return ctx;
}
// NEVER trust client data - validate everything server-side
class AuthoritativeServer {
public:
bool onMoveCommand(uint32_t playerId, Vector3 targetPos) {
auto& player = players[playerId];
Vector3 currentPos = player.position;
// Validate movement speed
float distance = (targetPos - currentPos).length();
float maxDistance = player.speed * deltaTime * 1.1f; // 10% tolerance
if (distance > maxDistance) {
logSuspicious(playerId, "SPEED_HACK", {
{"distance", distance},
{"max_allowed", maxDistance}
});
return false;
}
// Validate path (no teleporting through walls)
if (!isPathClear(currentPos, targetPos)) {
logSuspicious(playerId, "WALL_HACK", {});
return false;
}
// Apply validated movement
player.position = targetPos;
return true;
}
bool onFireCommand(uint32_t playerId, Vector3 aimDir) {
auto& player = players[playerId];
// Validate fire rate
auto now = Clock::now();
auto timeSinceLastShot = now - player.lastFireTime;
if (timeSinceLastShot < player.weapon.fireRate) {
logSuspicious(playerId, "FIRE_RATE_HACK", {});
return false;
}
// Server performs hit detection
auto hit = raycast(player.position, aimDir);
if (hit.entity) {
applyDamage(hit.entity, player.weapon.damage);
}
player.lastFireTime = now;
return true;
}
};
class AntiCheatSystem {
struct PlayerStats {
float avgAccuracy;
float avgReactionTime;
int suspicionScore;
std::vector<SuspiciousEvent> events;
};
std::unordered_map<uint32_t, PlayerStats> stats;
public:
void onHit(uint32_t shooter, uint32_t target, const HitInfo& info) {
auto& s = stats[shooter];
// Statistical aimbot detection
updateAccuracy(s, info);
if (s.avgAccuracy > 0.95f && s.shots > 100) {
s.suspicionScore += 10;
flagForReview(shooter, "STATISTICAL_AIMBOT");
}
// Inhuman reaction time detection
if (info.reactionTime < 0.1f) { // 100ms
s.suspicionScore += 5;
s.events.push_back({
"INHUMAN_REACTION",
info.reactionTime,
Clock::now()
});
}
// Trigger ban review if threshold exceeded
if (s.suspicionScore > 100) {
triggerBanReview(shooter, s);
}
}
void validatePacket(uint32_t playerId, const Packet& pkt) {
// Check sequence numbers for replay attacks
if (pkt.sequence <= lastSequence[playerId]) {
logSuspicious(playerId, "REPLAY_ATTACK", {});
return;
}
// Verify packet checksum
if (!verifyChecksum(pkt)) {
logSuspicious(playerId, "PACKET_TAMPERING", {});
disconnectPlayer(playerId);
}
}
};
#include <jwt-cpp/jwt.h>
class AuthService {
std::string secret;
public:
std::string generateToken(const Player& player) {
return jwt::create()
.set_issuer("game-auth-server")
.set_type("JWS")
.set_payload_claim("player_id", jwt::claim(player.id))
.set_payload_claim("username", jwt::claim(player.username))
.set_issued_at(std::chrono::system_clock::now())
.set_expires_at(std::chrono::system_clock::now() +
std::chrono::hours(24))
.sign(jwt::algorithm::hs256{secret});
}
std::optional<PlayerClaims> validateToken(const std::string& token) {
try {
auto verifier = jwt::verify()
.allow_algorithm(jwt::algorithm::hs256{secret})
.with_issuer("game-auth-server");
auto decoded = jwt::decode(token);
verifier.verify(decoded);
return PlayerClaims{
decoded.get_payload_claim("player_id").as_string(),
decoded.get_payload_claim("username").as_string()
};
} catch (const std::exception& e) {
return std::nullopt;
}
}
};
class RateLimiter {
struct Bucket {
int tokens;
std::chrono::steady_clock::time_point lastRefill;
};
std::unordered_map<std::string, Bucket> buckets;
std::shared_mutex mutex;
public:
bool allow(const std::string& key, int cost = 1) {
std::unique_lock lock(mutex);
auto& bucket = buckets[key];
refill(bucket);
if (bucket.tokens >= cost) {
bucket.tokens -= cost;
return true;
}
return false;
}
private:
void refill(Bucket& bucket) {
auto now = std::chrono::steady_clock::now();
auto elapsed = now - bucket.lastRefill;
auto refillAmount = elapsed.count() * refillRate;
bucket.tokens = std::min(maxTokens, bucket.tokens + refillAmount);
bucket.lastRefill = now;
}
};
// Usage
RateLimiter limiter;
void onClientMessage(Connection* conn, Message& msg) {
if (!limiter.allow(conn->ip, 1)) {
// Rate limited
conn->send(RateLimitedResponse{});
return;
}
processMessage(conn, msg);
}
| Action | Limit | Window |
|---|---|---|
| Login attempts | 5 | 1 min |
| Commands/sec | 60 | 1 sec |
| Chat messages | 10 | 10 sec |
| API requests | 100 | 1 min |
| Error | Root Cause | Solution |
|---|---|---|
| TLS handshake fail | Cert expired | Auto-renew certs |
| Token rejected | Clock drift | NTP sync |
| False positives | Strict thresholds | Tune detection |
| DoS vulnerability | No rate limit | Add rate limiting |
# Verify TLS configuration
openssl s_client -connect game.example.com:443 -tls1_3
# Check certificate validity
openssl x509 -in server.crt -noout -dates
# Monitor security events
journalctl -u game-server | grep -E "(SUSPICIOUS|BLOCKED|VIOLATION)"
# Test rate limiter
for i in {1..100}; do curl -s game.example.com/api; done
#include <gtest/gtest.h>
TEST(Security, RejectsInvalidToken) {
AuthService auth;
auto result = auth.validateToken("invalid.token.here");
EXPECT_FALSE(result.has_value());
}
TEST(Security, DetectsSpeedHack) {
AuthoritativeServer server;
Player player{.position = {0, 0, 0}, .speed = 10.0f};
// Normal movement
EXPECT_TRUE(server.onMoveCommand(1, {5, 0, 0}));
// Teleport attempt
EXPECT_FALSE(server.onMoveCommand(1, {1000, 0, 0}));
}
TEST(Security, RateLimiterWorks) {
RateLimiter limiter;
// First 10 requests pass
for (int i = 0; i < 10; ++i) {
EXPECT_TRUE(limiter.allow("test_ip"));
}
// 11th request blocked
EXPECT_FALSE(limiter.allow("test_ip"));
}
TEST(Security, AESEncryptDecrypt) {
std::string plaintext = "game state data";
auto [ciphertext, iv] = encrypt_aes_gcm(plaintext, key);
auto decrypted = decrypt_aes_gcm(ciphertext, key, iv);
EXPECT_EQ(plaintext, decrypted);
}
assets/ - Security checklistsreferences/ - Encryption guidesThis skill should be used when the user asks to "create an agent", "add an agent", "write a subagent", "agent frontmatter", "when to use description", "agent examples", "agent tools", "agent colors", "autonomous agent", or needs guidance on agent structure, system prompts, triggering conditions, or agent development best practices for Claude Code plugins.
This skill should be used when the user asks to "create a slash command", "add a command", "write a custom command", "define command arguments", "use command frontmatter", "organize commands", "create command with file references", "interactive command", "use AskUserQuestion in command", or needs guidance on slash command structure, YAML frontmatter fields, dynamic arguments, bash execution in commands, user interaction patterns, or command development best practices for Claude Code.
This skill should be used when the user asks to "create a hook", "add a PreToolUse/PostToolUse/Stop hook", "validate tool use", "implement prompt-based hooks", "use ${CLAUDE_PLUGIN_ROOT}", "set up event-driven automation", "block dangerous commands", or mentions hook events (PreToolUse, PostToolUse, Stop, SubagentStop, SessionStart, SessionEnd, UserPromptSubmit, PreCompact, Notification). Provides comprehensive guidance for creating and implementing Claude Code plugin hooks with focus on advanced prompt-based hooks API.