ViewVC Help
View File | Revision Log | Show Annotations | Download File | View Changeset | Root Listing
root/public/Qzhteln/trunk/TELTest/NormalConnectionHandler.cs
Revision: 2
Committed: Wed Feb 11 13:07:01 2026 UTC (8 weeks, 3 days ago) by figdor32
File size: 20766 byte(s)
Log Message:
Initial check-in

File Contents

# Content
1 using System;
2 using System.Collections.Generic;
3 using System.IO;
4 using System.Linq;
5 using System.Net.Sockets;
6 using System.Runtime.InteropServices;
7 using System.Text;
8 using System.Threading;
9 using System.Threading.Tasks;
10 using TELTest.Matchmaking;
11
12 namespace TELTest {
13 class NormalConnectionHandler : ConnectionHandler {
14 public override async Task HandleMe(NetworkStream stream) {
15 //await HandleTerminalSetup(stream);
16 //await DoQuizNew(stream);
17 await QuizExplorer(stream);
18 //await DoQuizNewest(stream);
19 }
20 protected async Task QuizExplorer(NetworkStream stream) {
21 int selx = 1;
22 int sely = 0;
23 TooLazyToAddWhile:
24 string[] publicq = new string[QuizListing.CachePublic.Count];
25 QuizEntry[] qe = new QuizEntry[QuizListing.CachePublic.Count];
26 lock (QuizListing.Entries) {
27 for (Int32 i = 0; i < QuizListing.CachePublic.Count; i++) {
28 QuizEntry item = QuizListing.CachePublic[i];
29 publicq[i] = item.Name;
30 qe[i] = item;
31 }
32 }
33 PlayerReady = false;
34 var cd = Path.Combine(".", "Quizzes", "Quizhouse_poor");
35 var cdn = Path.Combine(".", "Quizzes", "New");
36 string[] dirqhp = Directory.GetFileSystemEntries(cd, "*.jp2");
37 for (int i = 0; i < dirqhp.Length; i++) {
38 dirqhp[i] = "FILE:" + dirqhp[i];
39 }
40
41 string[] dirneu = Directory.GetFileSystemEntries(cdn, "*.xml");
42 for (int i = 0; i < dirneu.Length; i++) {
43 dirneu[i] = "FILE:" + dirneu[i];
44 }
45
46 string[] labels = new[] { "Klasycznym", "Menu", "Nowymi" };
47 string[][] menu = new string[3][];
48 //List<string> ls = new List<string>();
49
50 //for (int i = 0; i < 30; i++) {
51 // ls.Add(Utilities.RandomString());
52 //}
53 menu[0] = dirqhp;
54 menu[1] = new[] {
55 /* 0 */ "Dolacz do lobby",
56 /* 1 */ "Publiczne lobby",
57 //* 2 */ "Matchmaking",
58 /* 2 */ "Stworz quiz",
59 /* 3 */ "Zmien nick (" + (PlayerName == null? "Brak" : PlayerName)+ ")",
60 /* 4 */ "Otworz prywatny quiz...",
61 /* 5 */ "Wyjdz",
62 };
63 menu[2] = publicq;
64
65 var res = await GUIUtilities.Create2DMenu(this, stream, menu, labels, null, defaultx: selx, defaulty: sely);
66 int xsel = res.Item1;
67 int ysel = res.Item2;
68 selx = xsel;
69 sely = ysel;
70 string sp = menu[xsel][ysel];
71 if (xsel == 1) {
72 switch (ysel) {
73 case 0:
74 await JoinLobby(this, stream);
75 break;
76 case 1:
77 await LobbyBrowser(stream);
78 break;
79 case 2:
80 QuizCreator creator = new QuizCreator();
81 await creator.Handle(this, stream);
82 break;
83 case 3:
84 await GUIUtilities.AskUsernameIfNeeded(this, stream, true);
85 break;
86 case 4:
87 await OpenPrivate(stream);
88 break;
89 case 5:
90 return;
91 default:
92 break;
93 }
94 }
95 if (xsel == 2) {
96 var itm = qe[ysel];
97 QuizContainer qc = QuizDraftManager.GetDraft(itm.ID);
98 await ProcOpenQuiz(stream, qc);
99 }
100 if (sp.StartsWith("FILE:")) {
101 sp = sp.Substring(5).Trim();
102 QuizContainer qc = null;
103 switch (Path.GetExtension(sp).ToUpper()) {
104 case ".JP2":
105 string content = System.IO.File.ReadAllText(sp);
106 qc = QuizContainer.FromQuizhouse_poor(content);
107 string meta = sp + ".meta";
108
109 if (!System.IO.File.Exists(meta)) {
110 System.IO.File.AppendAllText(meta, Guid.NewGuid() + "\r\n");
111 }
112 Guid g = Guid.Parse(System.IO.File.ReadAllLines(meta)[0].Trim());
113 qc.Guid = g;
114 break;
115 case ".XML":
116 qc = QuizContainer.FromXml(System.IO.File.ReadAllText(sp));
117 break;
118 default:
119 throw new InvalidOperationException("Not a filename - " + sp);
120 }
121 await ProcOpenQuiz(stream, qc);
122 }
123 goto TooLazyToAddWhile;
124 }
125 public async Task OpenPrivate(NetworkStream stream) {
126 await WriteASCII(stream, "Wpisz ID quizu aby go otworzyc.");
127 bool invalid = false;
128 while (true) {
129 await TryClear(stream);
130 await WriteASCII(stream, "Wpisz identyfikator quizu aby go otworzyc.\r\n\r\n");
131 if (invalid) await WriteASCII(stream, "Wpisano nieprawidlowy identyfikator.\r\n");
132 await WriteASCII(stream, "Identyfikator: ");
133 string nam = await Read(stream, new ReadConfiguration() {
134 Terminator = '\r',
135 Echo = true,
136 MaxLength = 20,
137 Whitelist = Utilities.ALPHANUMERIC,
138 FlushAfterReading = true,
139 });
140 string li = nam.Trim();
141 bool lockObtained = false;
142 try {
143 Monitor.Enter(QuizListing.Entries);
144 lockObtained = true;
145 for (int i = 0; i < QuizListing.Entries.Count; i++) {
146 var itm = QuizListing.Entries[i];
147 if (itm.ID == li) {
148 await TryClear(stream);
149 await WriteASCII(stream, "Czekaj....");
150 if (!QuizDraftManager.Contains(itm.ID)) {
151 Monitor.Exit(QuizListing.Entries);
152 lockObtained = false;
153 await TryClear(stream);
154 await WriteASCII(stream, "Wystapil nieoczekiwany blad - znaleziono wpis quizu ale nie znaleziono danych.");
155 await ReadChar(stream);
156 Flush(stream);
157 return;
158 }
159 Monitor.Exit(QuizListing.Entries);
160 lockObtained = false;
161 await ProcOpenQuiz(stream, QuizDraftManager.GetDraft(itm.ID));
162 return;
163 }
164 }
165 } finally {
166 if (lockObtained) Monitor.Exit(QuizListing.Entries);
167 }
168
169 invalid = true;
170 if (string.IsNullOrWhiteSpace(nam)) break;
171 }
172 }
173 public async Task ProcOpenQuiz(NetworkStream stream, QuizContainer container) {
174 BaseQuizContext bq = new BaseQuizContext(this, stream, container);
175 await bq.Handle();
176 }
177 public async Task LobbyBrowser(NetworkStream stream) {
178 Lobby[] lobbies = MatchmakingStuff.GetPublic().ToArray();
179 int lastsel = 1;
180 while (true) {
181 string[] names = lobbies.Select(x =>
182 x.Name + ", " + x.Subject.Author + " - " + x.Subject.Title
183 + " [" + x.Identifier + (x.PlayerLimit == -1 ? "" : (", " + x.Players.Count + "/" + x.PlayerLimit)) + "]").ToArray();
184 string[][] menu = new string[1][];
185 menu[0] = new string[names.Length + 2];
186 menu[0][0] = "Powrot...";
187 menu[0][1] = "Odswiez";
188 Array.Copy(names, 0, menu[0], 2, names.Length);
189 var res = (await GUIUtilities.Create2DMenu(this, stream, menu, new[] { "Publiczne lobby" }, defaulty: lastsel)).Item2;
190 if (res == 0) {
191 return;
192 } else if (res == 1) {
193 lobbies = MatchmakingStuff.GetPublic().ToArray();
194 names = lobbies.Select(x => x.Name + "[" + x.Identifier + "]").ToArray();
195 } else {
196 var sel = res - 2;
197 await JoinLobbyProcess(stream, lobbies[sel]);
198 }
199 lastsel = res;
200 }
201 }
202 public async Task JoinLobby(ConnectionHandler handler, NetworkStream stream) {
203 //if (!string.IsNullOrWhiteSpace(handler.PlayerName)) return;
204 bool invalid = false;
205 while (true) {
206 await handler.TryClear(stream);
207 await handler.WriteASCII(stream, "Wpisz identyfikator lobby (5-7 znakow).\r\n\r\n");
208 if (invalid) await handler.WriteASCII(stream, "Wpisano nieprawidlowy identyfikator.\r\n");
209 await handler.WriteASCII(stream, "Identyfikator: ");
210 string nam = await handler.Read(stream, new ReadConfiguration() {
211 Terminator = '\r',
212 Echo = true,
213 MaxLength = 10,
214 Whitelist = Utilities.ALPHANUMERIC,
215 FlushAfterReading = true,
216 });
217 string li = nam.Trim();
218 for (int i = 0; i < MatchmakingStuff.AllLobbies.Count; i++) {
219 var itm = MatchmakingStuff.AllLobbies[i];
220 if (itm.Identifier == li) {
221 await TryClear(stream);
222 await WriteASCII(stream, "Czekaj....");
223 await JoinLobbyProcess(stream, itm);
224 return;
225 }
226 }
227 invalid = true;
228 if (string.IsNullOrWhiteSpace(nam)) break;
229 }
230 }
231
232 public async Task JoinLobbyProcess(NetworkStream stream, Lobby lobby) {
233 QuizGamemode qg = lobby.Gamemode;
234 if (lobby.PlayerLimit != -1 && lobby.Players.Count >= lobby.PlayerLimit) {
235 await TryClear(stream);
236 await WriteASCII(stream, "Lobby jest pelne.\r\n\r\nNacisnij dowolny klawisz aby kontynuowac...");
237 await ReadChar(stream);
238 Flush(stream);
239 return;
240 }
241 if (!string.IsNullOrWhiteSpace(lobby.Password)) {
242 await TryClear(stream);
243 await WriteASCII(stream, "Haslo: ");
244 var rc = ReadConfiguration.Default;
245 rc.EchoPasswordChars = true;
246 string pwd = await Read(stream, rc);
247 if (!string.IsNullOrWhiteSpace(pwd)) {
248 if (lobby.Password != pwd) return;
249 } else {
250 return;
251 }
252 }
253 var ctx = new BaseQuizContext(this, stream, lobby.Subject);
254 var game = qg.CreateCheckInstance(lobby.Subject, ctx);
255 game.JoinExistingLobby(lobby);
256 await game.Begin();
257 }
258 protected async Task DoQuizNewest(NetworkStream stream) {
259 string qc = File.ReadAllText("Quizzes\\Quizhouse_poor\\quiz.jp2");
260 QuizContainer quiz = QuizContainer.FromQuizhouse_poor(qc);
261 BaseQuizContext bq = new BaseQuizContext(this, stream, quiz);
262 await bq.Handle();
263 }
264 protected async Task HandleTerminalSetup(NetworkStream stream) {
265 await TryClear(stream);
266 char c = await Choice(stream, new[] { '4', '8', '1' }, "Czy to terminal z [4]0, [8]0, czy [1]20 kolumn?", def: '1');
267 switch (c) {
268 default:
269 case '4':
270 Columns = 40;
271 break;
272 case '8':
273 Columns = 80;
274 break;
275 case '1':
276 Columns = 120;
277 break;
278 }
279 Flush(stream);
280 await TryClear(stream);
281 await WriteASCII(stream, "The bar below should fill the width of the console. If not, resize your console, or reconnect and try again.\r\n");
282 await WriteBar(stream);
283 }
284
285 protected async Task DoQuizNew(NetworkStream stream) {
286 var ct = File.ReadAllText("quiz.jp2");
287 var quiz = QuizContainer.FromQuizhouse_poor(ct);
288 async Task CW(object ln = null) => await WriteASCII(stream, ln + "\r\n");
289 async Task<char> RK() { char c = await ReadChar(stream); Flush(stream); return c; }
290 int wynik = 0;
291 await TryClear(stream);
292 await CW("Tytul quizu: " + quiz.Title);
293 await CW("Autor quizu: " + quiz.Author);
294 await CW("Dowolny klawisz aby rozpoczac....");
295 await RK();
296
297
298 for (int i = 0; i < quiz.Questions.Length; i++) {
299 await TryClear(stream);
300 var itm = quiz.Questions[i];
301 await CW((i + 1) + ". " + itm.Content + "\r\n");
302 char correctAnswer = 'A';
303 for (int j = 0; j < itm.Answers.Length; j++) {
304 await CW(Utilities.NumberToLetter(j) + ") " + itm.Answers[j].Content);
305 if (itm.Answers[j].Correct) correctAnswer = Utilities.NumberToLetter(j)[0];
306 }
307 await WriteASCII(stream, "Twoja odpowiedz: ");
308 char c = await ReadChar(stream, false);
309 await CW(char.ToUpper(c));
310
311 await CW();
312 if (char.ToUpper(c) == correctAnswer) {
313 wynik++;
314 await CW("Dobrze! Zdobywasz punkt!");
315 } else {
316 await CW("Zle! Prawidlowa odpowiedz to: " + correctAnswer);
317 }
318 await CW("Dowolny klawisz aby kontynuowac....");
319 await RK();
320 }
321 await TryClear(stream);
322 await CW("Twoj wynik: " + wynik + "/" + quiz.Questions.Length);
323 await CW("Dowolny klawisz aby kontynuowac....");
324 await RK();
325 }
326
327 protected async Task DoQuiz(NetworkStream stream) {
328 bool twrd = false;
329 await TryClear(stream);
330 // await WriteBar(stream);
331 //await WriteASCII(stream, "Tryb T W A R D O R D Z E N wcisnij \"T\", klasyczny wcisnij inny dowolny klawisz.\r\n");
332 await WriteASCII(stream, "Tryb trudny wcisnij \"T\", klasyczny wcisnij inny dowolny klawisz.\r\n");
333 //await WriteBar(stream);
334 twrd = char.ToUpper(await ReadChar(stream)) == 'T';
335 Flush(stream);
336 Stream s = File.OpenRead("quiz.jp2");
337 TextReader tr = new StreamReader(s);
338 int wynik = 0;
339 bool twrdis = false;
340 int twr = 1;
341 string qti = tr.ReadLine();
342 string qau = tr.ReadLine();
343 #region process
344 for (int i = 0; i < 5; ++i) {
345 await TryClear(stream);
346 await WriteASCII(stream, (i == 0 ? "Tytul quizu: " : "") + qti + "\r\n");
347 if (i == 0)
348 await WriteASCII(stream, "Autor quizu: " + qau + "\r\n");
349 //await WriteBar(stream);
350 await WriteASCII(stream, "\r\n\r\n");
351 await WriteASCII(stream, (i + 1) + ". " + tr.ReadLine() + "\r\n\r\n");
352 await WriteASCII(stream, "a) " + tr.ReadLine() + "\r\n");
353 await WriteASCII(stream, "b) " + tr.ReadLine() + "\r\n");
354 await WriteASCII(stream, "c) " + tr.ReadLine() + "\r\n");
355 await WriteASCII(stream, "d) " + tr.ReadLine() + "\r\n");
356 char op = tr.ReadLine()[0];
357 await WriteASCII(stream, "\r\n? ");
358 char rc = await ReadChar(stream, true);
359 await WriteASCII(stream, "\r\n");
360 if (char.ToUpper(op) == Char.ToUpper(rc)) {
361 await WriteASCII(stream, "Dobrze! Zdobywasz punkt!\r\n");
362
363 wynik++;
364 } else {
365 if (twrd) {
366 if (!twrdis) {
367 //await WriteASCII(stream, "Tryb T W A R D O R D Z E N oznacza, ze niepoprawne odpowiedzi dodatkowo usuwaja twoje punkty. Kazda kolejna niepoprawna odpowiedz usuwa dwa razy wiecej punktow od poprzedniej, na przyklad pierwsza usuwa 1, druga 2 a trzecia 4.\r\n");
368 await WriteASCII(stream, "Tryb trudny: kazda kolejna niepoprawna odpowiedz usuwa dwa razy wiecej punktow od poprzedniej.\r\n");
369 twrdis = true;
370 }
371 await WriteASCII(stream, "Zle! Tracisz " + (twr == 1 ? "" : twr + "") + "punkt" + (
372 twr == 1 ? "" :
373 twr <= 5 ? "y"
374 : "ow" // max 31, 32 znowu sie odmienia na "-y" ale akurat -31 to max
375 ) + ".\r\n");
376 wynik -= twr;
377 twr <<= 1;
378 } else {
379 await WriteASCII(stream, "Zle! Poprawna odpowiedz to: " + op + "\r\n");
380 }
381 }
382 Flush(stream);
383 if (wynik < 0) await WriteASCII(stream, "Uwaga: Twoj wynik jest ujemny! Masz [" + wynik + "] punktow.\r\n\r\n");
384 await WriteASCII(stream, "Nacisnij dowolny klawisz aby kontynuowac....");
385 await ReadChar(stream, true);
386 Flush(stream);
387 }
388 #endregion
389 await TryClear(stream);
390 await WriteASCII(stream, "Twoj wynik: " + wynik + "/5\r\n\r\nUdostepnic?\r\n- Jezeli tak, wpisz nick (max 30 znakow) i wcisnij enter.\r\n- Jezeli nie, nic nie wpisuj i wcisnij enter.\r\n\r\n");
391 string nic = await Prompt(stream, "? ", new ReadConfiguration() { MaxLength = 30, Whitelist = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890-_", Echo = true, Terminator = '\n' });
392 if (!string.IsNullOrWhiteSpace(nic)) {
393 File.AppendAllText("Hiscore.txt", nic + ":" + wynik + "\n");
394 }
395 Tuple<string, int>[] hs = Array.ConvertAll(File.ReadAllLines("Hiscore.txt"), (x) => {
396 string nm = x.Split(':')[0];
397 string trz = x.Split(':')[1];
398 int ioi;
399 if (!int.TryParse(trz, out ioi)) {
400 ioi = -123456789;
401 }
402 return new Tuple<string, int>(nm, ioi);
403 });
404 StringBuilder sb = new StringBuilder();
405 hs = hs.OrderBy(x => -x.Item2).ToArray();
406 bool ht = false;
407 const int MAX_HISCORE = 15;
408 for (int i = 0; i < (hs.Length < MAX_HISCORE? hs.Length : MAX_HISCORE); i++) {
409 var item = hs[i];
410 bool tho = item.Item1 == nic;
411 ht |= tho;
412 sb.Append(((i + 1) + ". " + (tho? "-> " : "") + item.Item1).PadRight(38) + " " + item.Item2 + "\r\n");
413 }
414 if (!ht && !string.IsNullOrWhiteSpace(nic)) {
415 int ord = 0;
416 for (int i = 0; i < hs.Length; i++) {
417 if (hs[i].Item1 == nic) { ord = i; break; }
418 }
419 sb.Append((ord + ". -> " + nic).PadRight(38) + " " + wynik + "\r\n");
420 }
421 await TryClear(stream);
422 //await WriteBar(stream);
423 await WriteASCII(stream, "============= WYSOKI WYNIK: =============\r\n" + sb.ToString() + "\r\n");
424 //await WriteBar(stream);
425 await WriteASCII(stream, "\r\n");
426 await WriteASCII(stream, "Nacisnij klawisz aby sie rozlaczyc.");
427 await ReadChar(stream, true);
428 Flush(stream);
429 }
430
431 }
432 }
433