sam-coder-cli 1.0.26 → 1.0.27
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/multiplayer-server.js +62 -16
- package/package.json +1 -1
|
@@ -36,16 +36,35 @@ class MultiplayerServer {
|
|
|
36
36
|
this.sessions = new Map();
|
|
37
37
|
this.clients = new Map();
|
|
38
38
|
this.tasks = new Map();
|
|
39
|
-
this.
|
|
39
|
+
this.httpServer = null;
|
|
40
|
+
this.wss = null;
|
|
40
41
|
}
|
|
41
42
|
|
|
42
43
|
async start() {
|
|
43
44
|
try {
|
|
44
45
|
this.port = await findAvailablePort(this.port);
|
|
45
|
-
|
|
46
|
+
|
|
47
|
+
// Create HTTP server
|
|
48
|
+
this.httpServer = http.createServer();
|
|
49
|
+
|
|
50
|
+
// Create WebSocket server
|
|
51
|
+
this.wss = new WebSocket.Server({ server: this.httpServer });
|
|
52
|
+
|
|
53
|
+
// Setup event handlers
|
|
46
54
|
this.setupEventHandlers();
|
|
47
|
-
|
|
48
|
-
|
|
55
|
+
|
|
56
|
+
// Start listening
|
|
57
|
+
return new Promise((resolve, reject) => {
|
|
58
|
+
this.httpServer.on('error', (error) => {
|
|
59
|
+
console.error(chalk.red('HTTP server error:'), error);
|
|
60
|
+
reject(error);
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
this.httpServer.listen(this.port, () => {
|
|
64
|
+
console.log(chalk.green(`Multiplayer server started on port ${this.port}`));
|
|
65
|
+
resolve(this.port);
|
|
66
|
+
});
|
|
67
|
+
});
|
|
49
68
|
} catch (error) {
|
|
50
69
|
console.error(chalk.red('Failed to start multiplayer server:'), error.message);
|
|
51
70
|
throw error;
|
|
@@ -70,29 +89,56 @@ class MultiplayerServer {
|
|
|
70
89
|
}
|
|
71
90
|
|
|
72
91
|
setupEventHandlers() {
|
|
73
|
-
this.
|
|
92
|
+
if (!this.wss) {
|
|
93
|
+
throw new Error('WebSocket server not initialized');
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
this.wss.on('connection', (ws) => {
|
|
74
97
|
let clientId = uuid.v4();
|
|
75
98
|
let sessionId = null;
|
|
76
99
|
let clientInfo = {};
|
|
77
100
|
|
|
78
|
-
|
|
79
|
-
|
|
101
|
+
// Store client
|
|
102
|
+
this.clients.set(clientId, { ws, clientInfo });
|
|
103
|
+
|
|
104
|
+
ws.on('message', (data) => {
|
|
105
|
+
try {
|
|
106
|
+
const message = typeof data === 'string' ? JSON.parse(data) : data;
|
|
107
|
+
this.handleMessage(ws, clientId, message);
|
|
108
|
+
} catch (error) {
|
|
109
|
+
console.error('Error processing message:', error);
|
|
110
|
+
}
|
|
80
111
|
});
|
|
81
112
|
|
|
82
113
|
ws.on('close', () => {
|
|
114
|
+
// Remove client from any session
|
|
83
115
|
if (sessionId && this.sessions.has(sessionId)) {
|
|
84
116
|
const session = this.sessions.get(sessionId);
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
117
|
+
if (session && session.clients) {
|
|
118
|
+
delete session.clients[clientId];
|
|
119
|
+
|
|
120
|
+
// Notify other clients
|
|
121
|
+
this.broadcastToSession(sessionId, {
|
|
122
|
+
type: 'agent_left',
|
|
123
|
+
clientId,
|
|
124
|
+
clientInfo,
|
|
125
|
+
timestamp: new Date().toISOString()
|
|
126
|
+
}, clientId);
|
|
127
|
+
|
|
128
|
+
// Clean up empty sessions
|
|
129
|
+
if (Object.keys(session.clients).length === 0) {
|
|
130
|
+
this.sessions.delete(sessionId);
|
|
131
|
+
console.log(`Session ${sessionId} ended (no clients)`);
|
|
132
|
+
}
|
|
94
133
|
}
|
|
95
134
|
}
|
|
135
|
+
|
|
136
|
+
// Remove client from clients map
|
|
137
|
+
this.clients.delete(clientId);
|
|
138
|
+
});
|
|
139
|
+
|
|
140
|
+
ws.on('error', (error) => {
|
|
141
|
+
console.error('WebSocket error:', error);
|
|
96
142
|
});
|
|
97
143
|
});
|
|
98
144
|
}
|