Ymc3013 commited on
Commit
8b373a2
·
verified ·
1 Parent(s): 97abfa4

Update serveur.js

Browse files
Files changed (1) hide show
  1. serveur.js +62 -275
serveur.js CHANGED
@@ -1,280 +1,67 @@
1
- // Name: WebSocket avec Authentification
2
- // ID: gsaWebsocket
3
- // Description: Connect to WebSocket servers and handle user file verification with boolean status.
4
- // By: RedMan13 & Custom Auth
5
- // License: MIT
6
-
7
- (function (Scratch) {
8
- "use strict";
9
-
10
- if (!Scratch.extensions.unsandboxed) {
11
- throw new Error("can not load outside unsandboxed mode");
12
- }
13
-
14
- const blobToDataURL = (blob) =>
15
- new Promise((resolve, reject) => {
16
- const fr = new FileReader();
17
- fr.onload = () => resolve(fr.result);
18
- fr.onerror = () =>
19
- reject(new Error(`Failed to read as data URL: ${fr.error}`));
20
- fr.readAsDataURL(blob);
21
- });
22
-
23
- /* ------- BLOCKS -------- */
24
- const { BlockType, Cast, ArgumentType } = Scratch;
25
- const vm = Scratch.vm;
26
- const runtime = vm.runtime;
27
-
28
- class WebSocketExtension {
29
- constructor() {
30
- /** @type {Record<string, WebSocketInfo>} */
31
- this.instances = {};
32
-
33
- runtime.on("targetWasRemoved", (target) => {
34
- const instance = this.instances[target.id];
35
- if (instance) {
36
- instance.destroyed = true;
37
- if (instance.websocket) {
38
- instance.websocket.close();
39
- }
40
- delete this.instances[target.id];
41
- }
42
- });
43
- }
44
-
45
- getInfo() {
46
- return {
47
- id: "gsaWebsocket",
48
- name: "WebSocket Auth",
49
- color1: "#307eff",
50
- color2: "#2c5eb0",
51
- blocks: [
52
- {
53
- opcode: "newInstance",
54
- blockType: BlockType.COMMAND,
55
- arguments: {
56
- URL: {
57
- type: ArgumentType.STRING,
58
- defaultValue: "wss://ymc3013-user-save.hf.space",
59
- },
60
- },
61
- text: "connect to [URL]",
62
- },
63
- "---",
64
- {
65
- opcode: "enregistrerUtilisateur",
66
- blockType: BlockType.COMMAND,
67
- arguments: {
68
- PSEUDO: { type: ArgumentType.STRING, defaultValue: "Scratcher" },
69
- EMAIL: { type: ArgumentType.STRING, defaultValue: "exemple@gmail.com" },
70
- },
71
- text: "enregistrer l'utilisateur avec le pseudo [PSEUDO] et l'email [EMAIL]",
72
- },
73
- {
74
- opcode: "verifierUtilisateur",
75
- blockType: BlockType.COMMAND,
76
- arguments: {
77
- PSEUDO: { type: ArgumentType.STRING, defaultValue: "Scratcher" },
78
- EMAIL: { type: ArgumentType.STRING, defaultValue: "exemple@gmail.com" },
79
- },
80
- text: "vérifier l'utilisateur avec le pseudo [PSEUDO] et l'email [EMAIL]",
81
- },
82
- "---",
83
- // --- LES DEUX NOUVEAUX BLOCS DE STATUT ---
84
- {
85
- opcode: "estVerificationValide",
86
- blockType: BlockType.BOOLEAN,
87
- text: "dernière vérification valide ?",
88
- disableMonitor: false,
89
- },
90
- {
91
- opcode: "messageVerification",
92
- blockType: BlockType.REPORTER,
93
- text: "statut de la dernière vérification",
94
- disableMonitor: false,
95
- },
96
- "---",
97
- {
98
- opcode: "onOpen",
99
- blockType: BlockType.EVENT,
100
- isEdgeActivated: false,
101
- shouldRestartExistingThreads: true,
102
- text: "when connected",
103
- },
104
- {
105
- opcode: "isConnected",
106
- blockType: BlockType.BOOLEAN,
107
- text: "is connected?",
108
- disableMonitor: true,
109
- },
110
- "---",
111
- {
112
- opcode: "onMessage",
113
- blockType: BlockType.EVENT,
114
- isEdgeActivated: false,
115
- shouldRestartExistingThreads: true,
116
- text: "when message received",
117
- },
118
- {
119
- opcode: "messageData",
120
- blockType: BlockType.REPORTER,
121
- text: "received message data",
122
- disableMonitor: true,
123
- },
124
- "---",
125
- {
126
- opcode: "closeWithoutReason",
127
- blockType: BlockType.COMMAND,
128
- text: "close connection",
129
- }
130
- ],
131
- };
132
- }
133
-
134
- // --- ENREGISTREMENT ET VÉRIFICATION ---
135
-
136
- enregistrerUtilisateur(args, utils) {
137
- const payload = JSON.stringify({
138
- type: "enregistrement",
139
- pseudo: Cast.toString(args.PSEUDO),
140
- email: Cast.toString(args.EMAIL)
141
- });
142
- this.sendMessage({ PAYLOAD: payload }, utils);
143
- }
144
-
145
- verifierUtilisateur(args, utils) {
146
- const payload = JSON.stringify({
147
- type: "comparer",
148
- pseudo: Cast.toString(args.PSEUDO),
149
- email: Cast.toString(args.EMAIL)
150
- });
151
- this.sendMessage({ PAYLOAD: payload }, utils);
152
- }
153
-
154
- // --- FONCTIONS DES NOUVEAUX BLOCS BOULÉENS ---
155
-
156
- estVerificationValide(_, utils) {
157
- const instance = this.instances[utils.target.id];
158
- if (!instance || instance.verificationValide === undefined) return false;
159
- return instance.verificationValide; // Renvoie true ou false
160
- }
161
-
162
- messageVerification(_, utils) {
163
- const instance = this.instances[utils.target.id];
164
- if (!instance || !instance.verificationMessage) return "";
165
- return instance.verificationMessage; // Renvoie le texte ("Infos correctes", etc.)
166
- }
167
-
168
- // --- MOTEUR DE L'EXTENSION ---
169
-
170
- newInstance(args, util) {
171
- const target = util.target;
172
- let url = Cast.toString(args.URL);
173
-
174
- const oldInstance = this.instances[util.target.id];
175
- if (oldInstance) {
176
- oldInstance.destroyed = true;
177
- if (oldInstance.websocket) oldInstance.websocket.close();
178
- }
179
-
180
- const instance = {
181
- destroyed: false,
182
- errored: false,
183
- data: "",
184
- websocket: null,
185
- messageThreadsRunning: false,
186
- connectThreads: [],
187
- messageThreads: [],
188
- messageQueue: [],
189
- sendOnceConnected: [],
190
- // Variables pour mémoriser l'état de la connexion utilisateur
191
- verificationValide: false,
192
- verificationMessage: "Aucune vérification effectuée"
193
- };
194
- this.instances[util.target.id] = instance;
195
-
196
- return Scratch.canFetch(url)
197
- .then((allowed) => new Promise((resolve) => {
198
- if (!allowed) throw new Error("Not allowed");
199
- const websocket = new WebSocket(url);
200
- instance.websocket = websocket;
201
-
202
- const beforeExecute = () => {
203
- if (instance.messageThreadsRunning) {
204
- const stillRunning = instance.messageThreads.some((i) => runtime.isActiveThread(i));
205
- if (!stillRunning) {
206
- if (instance.messageQueue.length === 0) {
207
- instance.messageThreadsRunning = false;
208
- instance.messageThreads = [];
209
- } else {
210
- instance.data = instance.messageQueue.shift();
211
- instance.messageThreads = runtime.startHats("gsaWebsocket_onMessage", null, target);
212
- }
213
- }
214
  }
215
- };
216
-
217
- vm.runtime.on("BEFORE_EXECUTE", beforeExecute);
218
- websocket.onopen = () => {
219
- for (const item of instance.sendOnceConnected) websocket.send(item);
220
- instance.sendOnceConnected.length = 0;
221
- instance.connectThreads = runtime.startHats("gsaWebsocket_onOpen", null, target);
222
- resolve();
223
- };
224
-
225
- websocket.onmessage = async (e) => {
226
- if (instance.destroyed) return;
227
- let data = e.data;
228
- if (data instanceof Blob) data = await blobToDataURL(data);
229
 
230
- // --- INTERCEPTION DE LA RÉPONSE DE VÉRIFICATION ---
231
- try {
232
- const json = JSON.parse(data);
233
- if (json.type === "reponse_comparer") {
234
- instance.verificationValide = json.valide; // true ou false
235
- instance.verificationMessage = json.message; // Le message texte
236
- }
237
- } catch (err) {}
238
 
239
- if (instance.messageThreadsRunning) {
240
- instance.messageQueue.push(data);
241
- } else {
242
- instance.data = data;
243
- instance.messageThreads = runtime.startHats("gsaWebsocket_onMessage", null, target);
244
- instance.messageThreadsRunning = true;
245
  }
246
- };
247
- }));
248
- }
249
-
250
- isConnected(_, utils) {
251
- const instance = this.instances[utils.target.id];
252
- return !!instance && !!instance.websocket && instance.websocket.readyState === WebSocket.OPEN;
253
- }
254
-
255
- messageData(_, utils) {
256
- const instance = this.instances[utils.target.id];
257
- return instance ? instance.data : "";
258
- }
259
-
260
- sendMessage(args, utils) {
261
- const PAYLOAD = Cast.toString(args.PAYLOAD);
262
- const instance = this.instances[utils.target.id];
263
- if (!instance) return;
264
- if (!instance.websocket || instance.websocket.readyState === WebSocket.CONNECTING) {
265
- instance.sendOnceConnected.push(PAYLOAD);
266
- } else {
267
- instance.websocket.send(PAYLOAD);
268
- }
269
- }
270
-
271
- closeWithoutReason(_, utils) {
272
- const instance = this.instances[utils.target.id];
273
- if (!instance) return;
274
- instance.destroyed = true;
275
- if (instance.websocket) instance.websocket.close();
276
- }
277
- }
278
 
279
- Scratch.extensions.register(new WebSocketExtension());
280
- })(Scratch);
 
 
 
1
+ const { WebSocketServer } = require('ws');
2
+ const fs = require('fs');
3
+ const path = require('path');
4
+
5
+ // Utilise le port fourni par Hugging Face (7860) ou 3000 par défaut
6
+ const PORT = process.env.PORT || 7860;
7
+ const wss = new WebSocketServer({ port: PORT, host: '0.0.0.0' });
8
+
9
+ // Dossier où stocker les utilisateurs
10
+ const DOSSIER_USER = path.join(__dirname, 'user');
11
+
12
+ // Crée le dossier 'user' s'il n'existe pas encore
13
+ if (!fs.existsSync(DOSSIER_USER)) {
14
+ fs.mkdirSync(DOSSIER_USER);
15
+ }
16
+
17
+ console.log("=== SERVEUR DE CHAT PRIVÉ EN COURS D'EXÉCUTION ===");
18
+ console.log(`En attente de connexions sur le port ${PORT} ...\n`);
19
+
20
+ wss.on('connection', (ws) => {
21
+ console.log("[CONNEXION] Un utilisateur a rejoint le serveur.");
22
+
23
+ ws.on('message', (message) => {
24
+ const texteRecu = message.toString();
25
+
26
+ // 1. Tenter de lire le message comme une action d'inscription/connexion (JSON)
27
+ try {
28
+ const donnees = JSON.parse(texteRecu);
29
+
30
+ // Si le message contient un type "enregistrement", un email et un pseudo
31
+ if (donnees.type === "enregistrement" && donnees.email && donnees.pseudo) {
32
+
33
+ // Préparation du contenu du fichier demandé : pseudo et email
34
+ const contenuFichier = `pseudo: ${donnees.pseudo}\nemail: ${donnees.email}`;
35
+
36
+ // Sécurisation du nom de fichier pour éviter les caractères interdits
37
+ const nomFichier = `${donnees.email.replace(/[^a-zA-Z0-9@.]/g, "_")}.txt`;
38
+ const cheminFichier = path.join(DOSSIER_USER, nomFichier);
39
+
40
+ // Écriture (ou écrasement) du fichier utilisateur
41
+ fs.writeFileSync(cheminFichier, contenuFichier, 'utf8');
42
+ console.log(`[USER] Utilisateur enregistré dans : ${nomFichier}`);
43
+
44
+ // Envoi d'une confirmation à TurboWarp
45
+ ws.send(JSON.stringify({ statut: "succes", message: "Utilisateur enregistré !" }));
46
+ return; // On s'arrête ici pour ce message, pas besoin de l'envoyer sur le chat
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
47
  }
48
+ } catch (e) {
49
+ // Si ce n'est pas du JSON (ou qu'il manque des données), le serveur ignore l'erreur
50
+ // et passe directement à la suite (le code du chat normal)
51
+ }
 
 
 
 
 
 
 
 
 
 
52
 
53
+ // --- TON CODE DE CHAT CLASSIQUE ---
54
+ console.log(`[MESSAGE CHAT] : ${texteRecu}`);
 
 
 
 
 
 
55
 
56
+ // Renvoie le message reçu à tout le monde
57
+ wss.clients.forEach((client) => {
58
+ if (client.readyState === 1) {
59
+ client.send(texteRecu);
 
 
60
  }
61
+ });
62
+ });
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
63
 
64
+ ws.on('close', () => {
65
+ console.log("[DÉCONNEXION] Un utilisateur a quitté le chat.");
66
+ });
67
+ });