using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Net.Sockets; using System.Reflection.Emit; using System.Runtime.InteropServices; using System.Text; using System.Threading.Tasks; using TELTest.Matchmaking; namespace TELTest { internal class GUIUtilities { public static async Task Promptfull(ConnectionHandler handler, NetworkStream stream, string prompt, string @default = null, int nMax = 32, bool noClear = false) { if (!noClear) await handler.TryClear(stream); await handler.WriteASCII(stream, "\r\n" + prompt + ": "); var res = await handler.Read(stream, new ReadConfiguration() { Echo = true, MaxLength = nMax, FlushAfterReading = true, Terminator = '\r', Whitelist = Utilities.ALPHANUMERIC + " ?,.{}[]()/\\:;'\"'\b" }); return string.IsNullOrWhiteSpace(res) ? @default : res; } public static async Task AskUsernameIfNeeded(ConnectionHandler handler, NetworkStream stream, bool force = false) { bool usrset = string.IsNullOrWhiteSpace(handler.PlayerName); if (!usrset && !force) return; while (true) { await handler.TryClear(stream); //await handler.WriteASCII(stream, "Musisz wybrac nick zanim rozpoczniesz gre multiplayer.\r\n\r\n"); await handler.WriteASCII(stream, "Nick: "); string nam = await handler.Read(stream, new ReadConfiguration() { Terminator = '\r', Echo = true, MaxLength = 32, Whitelist = Utilities.ALPHANUMERIC, FlushAfterReading = true, }); handler.PlayerName = nam.Trim(); if (!string.IsNullOrWhiteSpace(nam)) break; } } public static async Task LobbyAwait(ConnectionHandler handler, NetworkStream stream, Lobby lobby) { while (true) { string[][] menu = new string[1][]; List players = new List(); players.Add("Odswiez"); players.Add("Gotowe..."); players.Add("Wyjdz..."); foreach (var item in lobby.Players) { players.Add(item.PlayerName + (item.PlayerReady? "*" : "")); } menu[0] = players.ToArray(); var res = await Create2DMenu(handler, stream, menu, new[] { "Identyfikator: [" + lobby.Identifier + "]" }); if (res.Item2 == 1) return true; if (res.Item2 == 2) return false; } } public static async Task LobbySettings(ConnectionHandler handler, NetworkStream stream, Lobby lobby) { int lastsel = 7; while (true) { string[][] menu = new string[1][]; menu[0] = new string[] { /* 0 */ "Tryb gry: " + lobby.Gamemode.Name, /* 1 */ "Quiz: " + lobby.Subject.Title, /* 2 */ "----------------", /* 3 */ "Nazwa: " + lobby.Name, /* 4 */ "Publiczne? " + (lobby.AnnouncePublic? "Tak" : "Nie"), /* 5 */ "Haslo: " + (lobby.Password != null? new string('*', lobby.Password.Length) : "[Brak]"), /* 6 */ "Max graczy: " + (lobby.PlayerLimit == -1? "Bez limitu" : lobby.PlayerLimit + ""), /* 7 */ "Gotowe." }; var res = await Create2DMenu(handler, stream, menu, new[] { "Identyfikator: [" + lobby.Identifier + "]" }, defaulty: lastsel); var sel = res.Item2; if (sel == 3) { await handler.TryClear(stream); await handler.WriteASCII(stream, "Nazwa: "); string nam = await handler.Read(stream, new ReadConfiguration() { Terminator = '\r', Echo = true, MaxLength = 32, Whitelist = Utilities.ALPHANUMERIC + " ", FlushAfterReading = true, }); lobby.Name = nam; } if (sel == 4) lobby.AnnouncePublic = !lobby.AnnouncePublic; if (sel == 5) { await handler.TryClear(stream); await handler.WriteASCII(stream, "Haslo: "); string nam = await handler.Read(stream, new ReadConfiguration() { Terminator = '\r', MaxLength = 32, Echo = true, EchoPasswordChars = true, PasswordChar= '*', FlushAfterReading = true, }); nam = nam.Trim(); lobby.Password = string.IsNullOrEmpty(nam) ? null : nam; } if (sel == 6) { await handler.TryClear(stream); await handler.WriteASCII(stream, "Max: "); string nam = await handler.Read(stream, new ReadConfiguration() { Terminator = '\r', Echo = true, MaxLength = 32, Whitelist = "0123456789", FlushAfterReading = true, }); if (string.IsNullOrWhiteSpace(nam)) { lobby.PlayerLimit = -1; } else { lobby.PlayerLimit = int.Parse(nam); } } if (sel == 7) break; lastsel = sel; } } public static async Task> Create2DMenu(ConnectionHandler handler, NetworkStream stream, string[][] menu, string[] labels, string caption = null, int defaultx = 0, int defaulty = 0) { int xsel = defaultx; int ysel = defaulty; while (true) { await handler.TryClear(stream); StringBuilder sb = new StringBuilder(); if (caption != null) sb.AppendLineRN(caption); //sb.AppendLineRN("Wybierz menu/widok/katalog klawiszami A/D.\r\n"); if (labels.Length > xsel) { if (xsel != 0) sb.Append(labels[xsel - 1] + " <-- "); sb.Append("[" + (labels[xsel] != null ? labels[xsel] : "Bez nazwy") + "]"); if (xsel != menu.Length - 1) sb.AppendLineRN(" --> " + labels[xsel + 1]); else sb.AppendLineRN(); sb.AppendLineRN(); } //for (int i = 0; i < menu.Length; i++) { int off = 0; if (ysel > 20) { off = ysel / 20 * 20; } if (off != 0) sb.AppendLineRN(" [... + " + off + "]"); for (int j = off; j < menu[xsel].Length; j++) { bool t = ysel == j; string name = menu[xsel][j]; if (name != null && name.StartsWith("FILE:")) name = Path.GetFileName(name.Substring(5)); sb.AppendLineRN((t ? " -> " : " ") + name + " "); if (j - off > 20) { sb.AppendLineRN("[... +" + (menu[xsel].Length - (off + 20)) + "]"); break; } } //sb.AppendLineRN(); //} sb.Append("\r\n[W/A/S/D/ENTER] "); await handler.WriteASCII(stream, sb.ToString()); char c = char.ToUpper(await handler.ReadChar(stream, false)); if (c == '\n' || c == '\r') { handler.Flush(stream); break; } if (c == 'W') { if (ysel == 0) { ysel = menu[xsel].Length - 1; } else { ysel--; } } if (c == 'S') { if (ysel == menu[xsel].Length - 1) { ysel = 0; } else { ysel++; } } if (c == 'A') { if (xsel == 0) { xsel = menu.Length - 1; } else { xsel--; } } if (c == 'D') { if (xsel == menu.Length - 1) { xsel = 0; } else { xsel++; } } if (menu[xsel].Length - 1 < ysel) ysel = menu[xsel].Length - 1; } return new Tuple(xsel, ysel); } } }