Implemented browser-based web client alongside existing pygame desktop client with dual-protocol server architecture supporting both TCP and WebSocket. Backend Changes: - Refactored GameServer for dual-protocol support (TCP + WebSocket) - Added WebSocketHandler for handling WebSocket connections - Added HTTPServer using aiohttp for serving web client files - Updated protocol handling to work with both connection types - Server tracks clients with protocol metadata (TCP/WebSocket) - Protocol-agnostic message sending and broadcasting - Added WebSocket port (8889) and HTTP port (8000) configuration Web Client: - Complete HTML5/CSS/JavaScript implementation - Responsive dark-themed UI - HTML5 Canvas rendering matching pygame visual style - WebSocket connection with auto-detected server URL - Real-time multiplayer gameplay in browser - Player list with scores and status - Mobile-friendly responsive design Deployment Options: - Development: Built-in HTTP server for local testing - Production: Disable HTTP server, use nginx/Apache for static files - Flexible server configuration (--no-http, --no-websocket flags) - Comprehensive nginx/Apache deployment documentation New Files: - src/server/websocket_handler.py - WebSocket connection handler - src/server/http_server.py - Static file server - web/index.html - Web client interface - web/style.css - Responsive styling - web/protocol.js - Protocol implementation - web/game.js - Game client with Canvas rendering - web/README.md - Deployment documentation Updated Files: - requirements.txt - Added websockets and aiohttp dependencies - src/server/game_server.py - Dual-protocol support - src/shared/constants.py - WebSocket and HTTP port constants - run_server.py - Server options for web support - README.md - Web client documentation - CLAUDE.md - Architecture documentation Features: - Web and desktop clients can play together simultaneously - Same JSON protocol for both client types - Independent server components (disable what you don't need) - Production-ready with reverse proxy support 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
66 lines
1.4 KiB
JavaScript
66 lines
1.4 KiB
JavaScript
/**
|
|
* Network protocol for client-server communication
|
|
* Matches the Python protocol implementation
|
|
*/
|
|
|
|
const MessageType = {
|
|
// Client -> Server
|
|
JOIN: 'JOIN',
|
|
MOVE: 'MOVE',
|
|
START_GAME: 'START_GAME',
|
|
LEAVE: 'LEAVE',
|
|
|
|
// Server -> Client
|
|
WELCOME: 'WELCOME',
|
|
STATE_UPDATE: 'STATE_UPDATE',
|
|
PLAYER_JOINED: 'PLAYER_JOINED',
|
|
PLAYER_LEFT: 'PLAYER_LEFT',
|
|
GAME_STARTED: 'GAME_STARTED',
|
|
GAME_OVER: 'GAME_OVER',
|
|
ERROR: 'ERROR'
|
|
};
|
|
|
|
class Message {
|
|
constructor(type, data = {}) {
|
|
this.type = type;
|
|
this.data = data;
|
|
}
|
|
|
|
toJSON() {
|
|
return JSON.stringify({
|
|
type: this.type,
|
|
data: this.data
|
|
});
|
|
}
|
|
|
|
static fromJSON(jsonStr) {
|
|
const obj = JSON.parse(jsonStr);
|
|
return new Message(obj.type, obj.data || {});
|
|
}
|
|
}
|
|
|
|
// Helper functions for creating messages
|
|
function createJoinMessage(playerName) {
|
|
return new Message(MessageType.JOIN, { player_name: playerName });
|
|
}
|
|
|
|
function createMoveMessage(direction) {
|
|
return new Message(MessageType.MOVE, { direction: direction });
|
|
}
|
|
|
|
function createStartGameMessage() {
|
|
return new Message(MessageType.START_GAME);
|
|
}
|
|
|
|
function createLeaveMessage() {
|
|
return new Message(MessageType.LEAVE);
|
|
}
|
|
|
|
// Direction constants (matching Python)
|
|
const Direction = {
|
|
UP: [0, -1],
|
|
DOWN: [0, 1],
|
|
LEFT: [-1, 0],
|
|
RIGHT: [1, 0]
|
|
};
|