ViewVC Help
View File | Revision Log | Show Annotations | Download File | View Changeset | Root Listing
root/public/Qzhteln/trunk/TELTest/QuizGamemode.cs
Revision: 2
Committed: Wed Feb 11 13:07:01 2026 UTC (8 weeks, 3 days ago) by figdor32
File size: 8969 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.Linq;
4     using System.Text;
5     using System.Threading.Tasks;
6     using TELTest.Matchmaking;
7    
8     namespace TELTest {
9     public abstract class QuizGamemode {
10     public static List<QuizGamemode> Registry { get; } = new List<QuizGamemode>() {
11     new Gamemodes.Classic(),
12     new Gamemodes.ClassicMP(),
13     new Gamemodes.Kbmio(),
14     new Gamemodes.Pisania(),
15     new Gamemodes.Comments(),
16     //new Gamemodes.Turns()
17     };
18     protected QuizGamemode() { }
19     protected QuizGamemode(QuizContainer container, BaseQuizContext context) {
20     this.Quiz = container;
21     this.Context = context;
22     }
23     public QuizContainer Quiz { get; protected set; }
24     public BaseQuizContext Context { get; protected set; }
25     public abstract QuizGamemode CreateInstance(QuizContainer quiz, BaseQuizContext context);
26     public QuizGamemode CreateCheckInstance(QuizContainer quiz, BaseQuizContext context) {
27     var inst = CreateInstance(quiz, context);
28     if (inst.GetType() != this.GetType()) throw new InvalidOperationException("Sanity check: QuizGamemode.CreateInstance should return the current type, it returned " + inst.GetType() + " instead of " + this.GetType() + ".");
29     return inst;
30     }
31     public abstract string Name { get; }
32     public abstract string SystemName { get; }
33     public abstract string Description { get; }
34     protected const string SYSTEMNAME_WHITELIST = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_";
35     public abstract Task Begin();
36     public void JoinExistingLobby(Lobby lobby) {
37     m_JoinMe = lobby;
38     }
39     private Lobby m_JoinMe = null;
40     protected bool ValidateSystemName() {
41     if (string.IsNullOrWhiteSpace(Name)) return false;
42     for (int i = 0; i < SystemName.Length; i++) {
43     if (!SYSTEMNAME_WHITELIST.Contains(SystemName[i])) return false;
44     }
45     return true;
46     }
47     public virtual async Task<Lobby> CreateJoinLobbyStandard() {
48     await GUIUtilities.AskUsernameIfNeeded(Context.Handler, Context.Stream);
49     Lobby lobby = null;
50     if (m_JoinMe == null) {
51     lobby = MatchmakingStuff.RequestNew(Quiz, this);
52     lobby.Players.Add(this.Context.Handler);
53     await GUIUtilities.LobbySettings(this.Context.Handler, this.Context.Stream, lobby);
54     } else {
55     lobby = m_JoinMe;
56     lobby.Players.Add(this.Context.Handler);
57     m_JoinMe = null;
58     }
59     bool aw = await GUIUtilities.LobbyAwait(this.Context.Handler, this.Context.Stream, lobby);
60     if (!aw) {
61     lobby.Players.Remove(Context.Handler);
62     return null;
63     }
64     //MakePlayersUnready(lobby);
65     return lobby;
66     }
67     const string SPINNER = "|/-\\";
68     public virtual async Task WaitForPlayersReady(Lobby lobby, bool clearScreen = false) {
69     //lobby.Players.Where(x => x == Context.Handler).First().PlayerReady = true;
70     Context.Handler.PlayerReady = true;
71     int spinstage = 0;
72     if (clearScreen) {
73     await Clear();
74     await WriteLine();
75     }
76     while (true) {
77     bool allready = true;
78     for (int i = 0; i < lobby.Players.Count; i++) {
79     allready &= lobby.Players[i].PlayerReady;
80     }
81    
82     await Write("\r " + SPINNER[spinstage] + " Czekanie na reszte graczy... " + SPINNER[spinstage] + " ");
83     await Task.Delay(150);
84     spinstage++;
85     if (spinstage >= SPINNER.Length) spinstage = 0;
86     if (allready) break;
87     }
88     await WriteLine();
89     await Task.Delay(300);
90     }
91     public void MakePlayersUnready(Lobby lobby) {
92     for (int i = 0; i < lobby.Players.Count; i++) {
93     lobby.Players[i].PlayerReady = false;
94     }
95     }
96     public virtual async Task DoScoreSubmission(int score, bool _reserved = false) {
97     if (!ValidateSystemName()) throw new InvalidOperationException("The system name of the gamemode is null, empty, exclusively whitespace, or contains invalid characters. Valid characters are \"" + SYSTEMNAME_WHITELIST + "\" (without quotes).");
98     Context.Handler.Flush(Context.Stream);
99     var scoreboard = Scoreboard.Of(Quiz.Guid + "_" + SystemName);
100     await Clear();
101     string nic = "";
102     if (!string.IsNullOrWhiteSpace(Context.Handler.PlayerName)) {
103     if (await Context.Handler.Choice(Context.Stream, new[] { 'Y', 'N' }, "Zapisac wynik?", def: 'Y') == 'Y') {
104     nic = Context.Handler.PlayerName;
105     scoreboard.Add(new Scoreboard.ScoreboardEntry(nic, score));
106     }
107    
108     } else {
109     await Write(Localization.UI["SAVESCORE"] + " ");
110     nic = await Context.Handler.Read(Context.Stream, new ReadConfiguration() {
111     Echo = true,
112     Terminator = '\n',
113     FlushAfterReading = true,
114     MaxLength = 30,
115     Whitelist = SYSTEMNAME_WHITELIST
116     });
117     nic = nic.TrimEnd('\r', '\n').Trim();
118     if (!string.IsNullOrWhiteSpace(nic)) {
119     scoreboard.Add(new Scoreboard.ScoreboardEntry(nic, score));
120     Context.Handler.PlayerName = nic;
121     }
122     }
123     await Clear();
124     StringBuilder sb = new StringBuilder();
125     var high = scoreboard.Highscore();
126     bool hadScore = false;
127     for (Int32 i = 0; i < high.Length; i++) {
128     Scoreboard.ScoreboardEntry item = high[i];
129     bool current = item.Name == nic;
130     hadScore |= current;
131     sb.AppendLineRN(((i + 1).ToString().PadLeft(2) + ". " + (current? "-> " : " ") + item.Name).PadRight(38) + " " + item.Value);
132     }
133    
134     if (!string.IsNullOrWhiteSpace(nic) && !hadScore) {
135     for (Int32 i = 0; i < scoreboard.Entries.Count; i++) {
136     var item = scoreboard.Entries[i];
137     if (item.Name == nic) {
138     sb.AppendLineRN();
139     bool current = true;
140     sb.AppendLineRN((i.ToString().PadLeft(2) + ". " + (current ? "->" : "") + item.Name).PadRight(38) + " " + item.Value);
141     }
142     }
143     }
144     sb.AppendLineRN();
145     await WriteLine(sb.ToString());
146     await Pause();
147     }
148     public Task EndMP(Lobby lobby) {
149     lobby.Players.Remove(Context.Handler);
150     if (lobby.Players.Count == 0 && !lobby.AnnouncePublic) {
151     lock (MatchmakingStuff.AllLobbies)
152     MatchmakingStuff.AllLobbies.Remove(lobby);
153     }
154     Context.Handler.PlayerReady = false;
155     return Task.FromResult(true);
156     }
157     public Task Flush() {
158     Context.Handler.Flush(Context.Stream);
159     return Task<bool>.FromResult(true);
160     }
161     public async Task Clear() {
162     await Context.Handler.TryClear(Context.Stream);
163     }
164     public async Task Pause() {
165     await Write(Localization.UI["ANYKEYCONTINUE"]);
166     await ReadKey(false);
167     await Flush();
168     await WriteLine();
169     }
170     public async Task WriteLine() => await WriteLine("");
171     public async Task WriteLine(object format, params object[] args) {
172     await Write(format + "\r\n", args);
173     }
174     public async Task Write(object format, params object[] args) {
175     await Context.Handler.WriteASCII(Context.Stream, string.Format(format.ToString(), args));
176     }
177     public async Task<string> ReadLine() => await ReadLine(true);
178     public async Task<string> ReadLine(bool echo) {
179     string rl = await Context.Handler.Read(Context.Stream, '\n', echo);
180     return rl.TrimEnd('\r', '\n');
181     }
182     public async Task<char> ReadUppercaseKey() {
183     char c = char.ToUpper(await ReadKey(false));
184     await Write(c);
185     return c;
186     }
187     public async Task<char> ReadKey() => await ReadKey(true);
188     public async Task<char> ReadKey(bool echo) {
189     return await Context.Handler.ReadChar(Context.Stream, echo);
190     }
191    
192     }
193     }