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, 4 days ago) by figdor32
File size: 20766 byte(s)
Log Message:
Initial check-in

File Contents

# User Rev Content
1 figdor32 2 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