using System; using System.Linq; using System.Collections.Generic; using System.Text; using EliteBGS.LogGenerator; using System.Reflection; namespace EliteBGS; public class DiscordLogGenerator { protected List formatters = new List() { new MissionFormat(), new MurderFormat(), new VoucherFormat(), new ThargoidFormatter(), new CombatZoneFormat(), new KillBondsFormat(), new CartographicsFormat(), new MicroResourcesFormat(), new MarketBuyFormat(), new CargoSoldFormatter(), new VistaGenomicsFormat(), new SearchAndRescueFormat(), }; protected virtual string GetToolVersion() { Version v = Assembly.GetCallingAssembly().GetName().Version; string ver; if (v == null) { ver = "v?.?.?"; } else { ver = "v" + v.ToString(3); } return string.Format("EliteBGS {0}", ver); } protected virtual DateTime? GetDateOfEarliestEntry(Objective objective) { var it = objective .Transactions .OrderBy(x => x.CompletedAtDateTime) .FirstOrDefault() ; if (it != null) { return it.CompletedAtDateTime; } return null; } protected virtual DateTime? GetDateOfLatestEntry(Objective objective) { var it = objective .Transactions .OrderByDescending(x => x.CompletedAtDateTime) .FirstOrDefault() ; if (it != null) { return it.CompletedAtDateTime; } return null; } protected virtual string GenerateSummary(Objective objective) { StringBuilder sb = new StringBuilder(); foreach (var formatter in formatters) { string summary = ""; try { summary = formatter.GenerateSummary(objective); } catch (NotImplementedException) { } if (string.IsNullOrEmpty(summary)) { continue; } if (sb.Length > 0) { sb.Append("; "); } sb.Append(summary); } return sb.ToString(); } protected virtual string GenerateHeader() { return ""; } protected virtual string GenerateFooter() { return "\n"; } protected virtual string GenerateObjectiveHeader(Objective objective) { StringBuilder log = new StringBuilder(); string location; if (!string.IsNullOrEmpty(objective.System) && !string.IsNullOrEmpty(objective.Faction)) { location = string.Format("{0}, {1}", objective.System, objective.Faction); } else if (!string.IsNullOrEmpty(objective.System)) { location = objective.System; } else { location = "Unknown Location"; } int legacycount = objective.Transactions .Where(x => x.IsLegacy) .Count() ; string summary = GenerateSummary(objective); var earliest = GetDateOfEarliestEntry(objective); var latest = GetDateOfLatestEntry(objective); if (earliest != null && latest != null) { log.AppendFormat("**Date:** {0} - {1}\n", GetDateOfEarliestEntry(objective), GetDateOfLatestEntry(objective) ); } log.AppendFormat("**Target:** {0}\n", location); if (!string.IsNullOrEmpty(summary)) { log.AppendFormat("**Summary:** {0}\n", summary); } if (legacycount > 0) { log.AppendFormat("**Warning:** Some actions were performed on ED Legacy\n"); } log.AppendLine("```"); return log.ToString(); } protected virtual string GenerateObjectiveFooter(Objective objective) { return "```\n"; } /// /// Is called to do final adjustments to the log body of a given objective. /// /// Objective in question. /// Final log as generated. /// The transformed log. protected virtual string TransformFinalLogForObjective(Objective objective, string log) { return log; } public virtual string Name { get { return "GenericLog"; } } protected virtual string BotHeader() { var sb = new StringBuilder(); sb.AppendFormat("**Bot-Header:** {0}; {1}\n", GetToolVersion(), this.Name); return sb.ToString(); } public virtual string GenerateDiscordLog(Report report) { StringBuilder log = new StringBuilder(); if (report == null) { return ""; } var objectives = report.Objectives .Where(x => x.IsEnabled && x.Transactions.Count() > 0) ; if (objectives == null || objectives.Count() <= 0) { return ""; } log.AppendFormat("{0}", BotHeader()); log.AppendFormat("{0}", GenerateHeader()); foreach (Objective objective in objectives) { StringBuilder objlog = new StringBuilder(); log.AppendFormat("{0}", GenerateObjectiveHeader(objective)); foreach (LogFormatter formatter in formatters) { string text = formatter.GenerateLog(objective); text = text.Trim(); if (!string.IsNullOrEmpty(text)) { objlog.AppendFormat("{0}\n\n", text); } } string finallog = objlog.ToString().Trim(); finallog = TransformFinalLogForObjective(objective, finallog); log.AppendFormat("{0}\n", finallog); log.AppendFormat("{0}", GenerateObjectiveFooter(objective)); } log.AppendFormat("{0}", GenerateFooter()); return log.ToString().Trim(); } public virtual string[] SplitLog(string log, int maxcount = 2000) { throw new NotImplementedException(); } protected string[] SplitLogWithHeader(string log, string header, int maxcount = 2000) { string[] lines = log.Split("\n"); List chunks = new(); string chunk = string.Empty; // Optimisation if (log.Length <= maxcount) { return new string[] { log }; } // First split the log into its headers // skip first bot header line for (int i = 1; i < lines.Length; i++) { string line = lines[i]; if (line.StartsWith(header) && !string.IsNullOrEmpty(chunk)) { chunks.Add(chunk.Trim()); chunk = string.Empty; } chunk = chunk + "\n" + line; } int curchunk = 0; string botheader = BotHeader().Trim() + "\n"; // Leave room for botheader and some leeway int maxlength = (2000 - botheader.Length - 10); // Then try to collate chunks for (curchunk = 0; curchunk < chunks.Count; ++curchunk) { int count = chunks[curchunk].Length; while (count < maxlength && (curchunk+1) < chunks.Count) { count += chunks[curchunk + 1].Length + 2; if (count < maxlength) { chunks[curchunk] += "\n"; chunks[curchunk] += chunks[curchunk + 1]; chunks.RemoveAt(curchunk + 1); } } } // Readd bott headers for (int i = 0; i < chunks.Count; i++) { chunks[i] = chunks[i].Insert(0, botheader); } // Now finally check if any one chunk is bigger than max length for (int i = 0; i < chunks.Count; i++) { if (chunks[i].Length > maxcount) { throw new ApplicationException( string.Format("a chunk turned out bigger than {0}", maxcount)); } } return chunks.ToArray(); } }