using System; using System.Collections.Generic; using System.ComponentModel; using System.IO; using System.Linq; using System.Text; using System.Threading.Tasks; namespace TELTest.Gamemodes { internal class Comments : QuizGamemode { static Comments() { bk.MaximumMemoryPressure = 512 * 1024 * 1024; // 512MB UpdateCDB(); } static void UpdateCDB() { tmr.Interval = 15000; tmr.Elapsed += Tmr_Elapsed; tmr.AutoReset = false; } private static void Retime() { tmr.Stop(); tmr.Start(); } public Comments() { } public Comments(QuizContainer container, BaseQuizContext context) : base(container, context) { } private static System.Timers.Timer tmr = new System.Timers.Timer(); private static void Tmr_Elapsed(Object sender, System.Timers.ElapsedEventArgs e) { Program.WriteWithTime("Begin write comments..."); bk.SavePendingChanges(); Program.WriteWithTime("Done. {0} tuples out, ~{1}B memory in use.", bk.LastTuplesOut, bk.CurrentMemoryPressure); } static BasicKeyValue bk = new BasicKeyValue("Comments"); public override String Name => "Komentarze"; public override String SystemName => "Comments"; public override String Description => "Zostaw komentarz pod quizem."; public override QuizGamemode CreateInstance(QuizContainer quiz, BaseQuizContext context) => new Comments(quiz, context); public override async Task Begin() { int score = 0; await WriteLine("Tytul quizu: " + Quiz.Title); await WriteLine("Autor quizu: " + Quiz.Author); await WriteLine(); var g = Quiz.Guid.ToString(); List cms = new List(); recreate = true; int lastx = 0; int lasty = 2; while (true) { if (recreate) { cms.Clear(); DeserializeComs(); cms.Add("Tytul quizu: " + Quiz.Title); cms.Add("Autor quizu: " + Quiz.Author); cms.Add("Powrot..."); cms.Add("Dodaj..."); for (int i = 0; i < comments.Count; i++) { var item = comments[i]; cms.Add("[" + item.Date + "] " + item.Author + ": " + item.Content); } recreate = false; } var outp = await GUIUtilities.Create2DMenu(Context.Handler, Context.Stream, new string[][] { cms.ToArray() }, new[] { "Komentarze" }, null, lastx, lasty); if (outp.Item2 == 2) break; if (outp.Item2 == 3) { await GUIUtilities.AskUsernameIfNeeded(Context.Handler, Context.Stream); await WriteComment(); } lastx = outp.Item1; lasty = outp.Item2; } } private bool recreate = false; protected void DeserializeComs() { comments.Clear(); Byte[] com = null; lock (bk) com = bk[Quiz.Guid.ToString()]; DeserializeCommentsInner(com); comments.Reverse(); } protected void DeserializeCommentsInner(byte[] data) { if (data == null || data.Length < 4) return; using (MemoryStream ms = new MemoryStream(data)) { using (BinaryReader br = new BinaryReader(ms)) { while (true) { var al = br.ReadInt32(); if (al == 0x7FFFFFFF) break; Comment com = new Comment(); var bt = br.ReadBytes(al); com.Author = DecStr(bt); al = br.ReadInt32(); bt = br.ReadBytes(al); com.Content = DecStr(bt); int y = br.ReadInt32(); int m = br.ReadInt32(); int d = br.ReadInt32(); int h = br.ReadInt32(); int mn = br.ReadInt32(); int s = br.ReadInt32(); com.Date = new DateTime(y, m, d, h, mn, s); comments.Add(com); } } } } List comments = new List(); protected byte[] SerializeComments() { MemoryStream ms = new MemoryStream(); BinaryWriter bw = new BinaryWriter(ms); for (int i = 0; i < comments.Count; i++) { var item = comments[i]; var aut = EncStr(item.Author); bw.Write(aut.Length); bw.Write(aut); var cont = EncStr(item.Content); bw.Write(cont.Length); bw.Write(cont); bw.Write(item.Date.Year); bw.Write(item.Date.Month); bw.Write(item.Date.Day); bw.Write(item.Date.Hour); bw.Write(item.Date.Minute); bw.Write(item.Date.Second); } bw.Write(0x7FFFFFFF); return ms.ToArray(); } protected static byte[] EncStr(string str) { return System.Text.Encoding.UTF8.GetBytes(str); } protected static string DecStr(byte[] str) { return System.Text.Encoding.UTF8.GetString(str); } async Task WriteComment() { var res = await GUIUtilities.Promptfull(Context.Handler, Context.Stream, "Komentarz", null, 96); if (string.IsNullOrWhiteSpace(res)) return; comments.Add(new Comment() { Author = Context.Handler.PlayerName, Content = res, Date = DateTime.Now, }); var b = SerializeComments(); lock (bk) bk[Quiz.Guid.ToString()] = b; Retime(); recreate = true; } struct Comment { public DateTime Date; public string Author; public string Content; } } }