custom string.Join & performance boost

This commit is contained in:
Gurge44 committed 2026-08-12 20:14:12 +02:00
1 parent d68798092f
commit 29c392ff78
49 files changed
+257 -137

No files matched your search

+1 -1
View File
@@ -290,7 +290,7 @@ public static class BedWars
{
WinnerData = (team.GetColor(), team.GetName() + Translator.GetString("Win"));
CustomWinnerHolder.WinnerIds = Data.Where(x => x.Value.Team == team).Select(x => x.Key).ToHashSet();
Logger.Info($"Winners: {team.GetName()} - {string.Join(", ", CustomWinnerHolder.WinnerIds.Select(id => Main.AllPlayerNames.GetValueOrDefault(id, string.Empty)))}", "BedWars");
Logger.Info($"Winners: {team.GetName()} - {CustomWinnerHolder.WinnerIds.Join(", ", id => Main.AllPlayerNames.GetValueOrDefault(id, string.Empty))}", "BedWars");
SendRPC();
return true;
}
+56 -18
View File
@@ -346,34 +346,72 @@ internal static class CustomHnS
return targetRole.Interface.Team == Team.Impostor && (targetRole.Role != CustomRoles.Agent || seerRole.Interface.Team == Team.Impostor);
}
private static readonly StringBuilder TaskBarText = new();
public static string GetTaskBarText()
{
string text = Main.PlayerStates.IntersectBy(PlayerRoles.Keys, x => x.Key).Aggregate("<size=80%>", (current, state) => $"{current}{GetStateText(state)}\n");
return $"{text}</size>\r\n\r\n<#00ffa5>{Translator.GetString("HNS.TaskCount")}</color> {GameData.Instance.CompletedTasks}/{GameData.Instance.TotalTasks}";
bool seeRoles = PlayersSeeRoles.GetBool();
bool agentEnabled = CustomRoles.Agent.IsEnable();
string deadText = Translator.GetString("Dead");
static string GetStateText(KeyValuePair<byte, PlayerState> state)
TaskBarText.Clear();
TaskBarText.Append("<size=80%>");
foreach ((byte id, PlayerState state) in Main.PlayerStates)
{
string name = Main.AllPlayerNames.GetValueOrDefault(state.Key, $"ID {state.Key}");
name = Utils.ColorString(Main.PlayerColors.GetValueOrDefault(state.Key, Color.white), name);
bool isSeeker = PlayerRoles[state.Key].Interface.Team == Team.Impostor;
bool alive = !state.Value.IsDead;
if (!PlayerRoles.TryGetValue(id, out var playerRole)) continue;
TaskState taskState = state.Value.TaskState;
var stateText = string.Empty;
string name = Main.AllPlayerNames.TryGetValue(id, out string playerName) ? playerName : $"ID {id}";
name = Utils.ColorString(Main.PlayerColors.GetValueOrDefault(id, Color.white), name);
TaskBarText.Append(name);
if (PlayersSeeRoles.GetBool())
stateText = $" ({GetRole().ToColoredString()}){GetTaskCount()}";
else if (isSeeker) stateText = $" ({CustomRoles.Seeker.ToColoredString()})";
if (seeRoles)
{
CustomRoles role = state.MainRole == CustomRoles.Agent ? CustomRoles.Hider : state.MainRole;
if (!alive) stateText += $" <color=#ff0000>{Translator.GetString("Dead")}</color>";
TaskBarText.Append(' ');
TaskBarText.Append('(');
TaskBarText.Append(role.ToColoredString());
TaskBarText.Append(')');
stateText = $"{name}{stateText}";
return stateText;
TaskState taskState = state.TaskState;
CustomRoles GetRole() => state.Value.MainRole == CustomRoles.Agent ? CustomRoles.Hider : state.Value.MainRole;
if (state.MainRole != CustomRoles.GM && !agentEnabled && taskState.HasTasks)
{
TaskBarText.Append(' ');
TaskBarText.Append('(');
TaskBarText.Append(taskState.CompletedTasksCount);
TaskBarText.Append('/');
TaskBarText.Append(taskState.AllTasksCount);
TaskBarText.Append(')');
}
}
else if (playerRole.Interface.Team == Team.Impostor)
{
TaskBarText.Append(' ');
TaskBarText.Append('(');
TaskBarText.Append(CustomRoles.Seeker.ToColoredString());
TaskBarText.Append(')');
}
string GetTaskCount() => state.Value.MainRole == CustomRoles.GM || CustomRoles.Agent.IsEnable() || !taskState.HasTasks ? string.Empty : $" ({taskState.CompletedTasksCount}/{taskState.AllTasksCount})";
if (state.IsDead)
{
TaskBarText.Append(" <color=#ff0000>");
TaskBarText.Append(deadText);
TaskBarText.Append("</color>");
}
TaskBarText.Append('\n');
}
TaskBarText.Append("</size>\r\n\r\n<#00ffa5>");
TaskBarText.Append(Translator.GetString("HNS.TaskCount"));
TaskBarText.Append("</color> ");
TaskBarText.Append(GameData.Instance.CompletedTasks);
TaskBarText.Append('/');
TaskBarText.Append(GameData.Instance.TotalTasks);
return TaskBarText.ToString();
}
private static readonly StringBuilder Suffix = new();
@@ -401,7 +439,7 @@ internal static class CustomHnS
if (PlayersSeeRoles.GetBool() && !CustomRoles.Agent.IsEnable() && IntroCutsceneDestroyPatch.IntroDestroyTS + 15 > Utils.TimeStamp)
{
Suffix.AppendLine();
Suffix.AppendFormat(Translator.GetString("HNSSeekers"), string.Join(", ", PlayerRoles.Where(x => x.Value.Interface.Team == Team.Impostor).Select(x => x.Key.ColoredPlayerName())));
Suffix.AppendFormat(Translator.GetString("HNSSeekers"), PlayerRoles.Where(x => x.Value.Interface.Team == Team.Impostor).Join(", ", x => x.Key.ColoredPlayerName()));
}
}
}
+2 -2
View File
@@ -250,7 +250,7 @@ public static class Deathrace
var track = Track.ToList();
if (!Clockwise) track.Reverse();
players.NotifyPlayers("<#ffffff>" + string.Format(Translator.GetString("Deathrace.Tutorial.Track"), string.Join(" » ", track.ConvertAll(x => Translator.GetString(x.ToString())))), 100f);
players.NotifyPlayers("<#ffffff>" + string.Format(Translator.GetString("Deathrace.Tutorial.Track"), track.Join(" » ", x => Translator.GetString(x.ToString()))), 100f);
yield return new WaitForSecondsRealtime(Track.Count);
NameNotifyManager.Reset();
@@ -394,7 +394,7 @@ public static class Deathrace
public static string GetTaskBarText()
{
return string.Join('\n', Data.Select(x => $"{x.Key.ColoredPlayerName()}: {string.Format(Translator.GetString("Deathrace.Lap"), x.Value.Lap + 1, LapsToWin)}"));
return Data.Join('\n', x => $"{x.Key.ColoredPlayerName()}: {string.Format(Translator.GetString("Deathrace.Lap"), x.Value.Lap + 1, LapsToWin)}");
}
public static void OnCheckMurder(PlayerControl killer, PlayerControl target)
+4 -4
View File
@@ -579,10 +579,10 @@ public static class KingOfTheZones
SystemTypes zone = !room ? SystemTypes.Hallway : room.RoomId;
if (justStarted) Suffix.Append(GetString(Zones.Count == 1 ? "KOTZ.SuffixHelp.Zones.Single" : "KOTZ.SuffixHelp.Zones.Plural"));
Suffix.AppendLine(string.Join(" | ", Zones.Select(x => Utils.ColorString(ZoneDomination[x].GetColor(), (zone == x ? "<u>" : string.Empty) + GetString($"{x}") + (zone == x ? "</u>" : string.Empty) + (ZoneMoveSchedules.TryGetValue(x, out long moveTS) ? $"<size=80%> {(ZoneDowntimeExpire.TryGetValue(x, out long downtimeEndTS) ? Utils.ColorString(Color.gray, $"{downtimeEndTS - now}") : $"<#ffff44>{moveTS - now}</color>")}</size>" : string.Empty)))));
Suffix.AppendLine(Zones.Join(" | ", x => Utils.ColorString(ZoneDomination[x].GetColor(), (zone == x ? "<u>" : string.Empty) + GetString($"{x}") + (zone == x ? "</u>" : string.Empty) + (ZoneMoveSchedules.TryGetValue(x, out long moveTS) ? $"<size=80%> {(ZoneDowntimeExpire.TryGetValue(x, out long downtimeEndTS) ? Utils.ColorString(Color.gray, $"{downtimeEndTS - now}") : $"<#ffff44>{moveTS - now}</color>")}</size>" : string.Empty))));
if (justStarted) Suffix.Append(GetString("KOTZ.SuffixHelp.Points"));
Suffix.AppendLine(string.Join(" | ", Points.IntersectBy(PlayerTeams.Values, x => x.Key).Select(x => Utils.ColorString(x.Key.GetColor(), $"{x.Value}"))));
Suffix.AppendLine(Points.IntersectBy(PlayerTeams.Values, x => x.Key).Join(" | ", x => Utils.ColorString(x.Key.GetColor(), $"{x.Value}")));
int highestPoints = Points.Values.Max();
bool tie = Points.Values.Count(x => x == highestPoints) > 1;
@@ -590,7 +590,7 @@ public static class KingOfTheZones
if (tie && end)
{
string tieTeams = string.Join(' ', Points.Where(x => x.Value == highestPoints).Select(x => Utils.ColorString(x.Key.GetColor(), "\u25a0")));
string tieTeams = Points.Where(x => x.Value == highestPoints).Join(' ', x => Utils.ColorString(x.Key.GetColor(), "\u25a0"));
Suffix.Append("<size=80%>").AppendFormat(GetString("KOTZ.Suffix.Tie"), tieTeams).AppendLine("</size>");
}
else
@@ -966,7 +966,7 @@ public static class KingOfTheZones
}
}
Logger.Info($"Zone domination: {string.Join(", ", ZoneDomination.Select(x => $"{x.Key} = {x.Value}"))}", "KOTZ");
Logger.Info($"Zone domination: {ZoneDomination.Join(", ", x => $"{x.Key} = {x.Value}")}", "KOTZ");
}
catch (Exception e) { Utils.ThrowException(e); }
+1 -1
View File
@@ -130,7 +130,7 @@ public static class Mingle
return true;
case var p when p <= MaxWinningPlayers:
CustomWinnerHolder.WinnerIds = aapc.Select(x => x.PlayerId).ToHashSet();
Logger.Info($"Winners: {string.Join(", ", aapc.Select(x => x.GetRealName().RemoveHtmlTags()))}", "Mingle");
Logger.Info($"Winners: {aapc.Join(", ", x => x.GetRealName().RemoveHtmlTags())}", "Mingle");
Main.DoBlockNameChange = true;
return true;
default:
+1 -1
View File
@@ -393,7 +393,7 @@ public static class NaturalDisasters
if (DeathMessageQueue.Count > 0 && DeathMessageQueue.FindFirst(x => x.recordTimeStamp + 3 <= now, out var expired))
{
var names = string.Join(", ", DeathMessageQueue.Where(x => x.deathReason == expired.deathReason).Select(x => x.id.ColoredPlayerName()));
var names = DeathMessageQueue.Where(x => x.deathReason == expired.deathReason).Join(", ", x => x.id.ColoredPlayerName());
string msgOthers = string.Format(Translator.GetString($"ND_DRLaughMessageOthers-{IRandom.Instance.Next(4)}.{expired.deathReason}"), names);
Main.EnumerateAlivePlayerControls().NotifyPlayers($"<#ff0000>[╳]</color> {Utils.ColorString(DeathReasonColor(expired.deathReason), msgOthers)}");
DeathMessageQueue.RemoveAll(x => x.deathReason == expired.deathReason);
+7 -7
View File
@@ -149,7 +149,7 @@ public static class Quiz
public static string GetStatistics(byte id)
{
if (!NumCorrectAnswers.TryGetValue(id, out var data)) return string.Empty;
string str = string.Join(" | ", data.Select(x => $"{x.Key.ToString()[0]}-{x.Value.Sum()}"));
string str = data.Join(" | ", x => $"{x.Key.ToString()[0]}-{x.Value.Sum()}");
return GetString("Quiz.EndResults.CorrectAnswerNum") + str;
}
@@ -235,7 +235,7 @@ public static class Quiz
if (!AllowKills) return string.Empty;
requiredCorrect = Settings[CurrentDifficulty].CorrectRequirement.GetInt();
gotCorrect = NumCorrectAnswers[seer.PlayerId][CurrentDifficulty][Round];
gotCorrect = NumCorrectAnswers[seer.PlayerId][CurrentDifficulty][Round - 1];
failed = gotCorrect < requiredCorrect;
var ffaTimeLeft = FFAEndTS - Utils.TimeStamp;
@@ -276,7 +276,7 @@ public static class Quiz
var aapc = Main.AllAlivePlayerControlsToList;
bool showTutorial = !SubmergedCompatibility.IsSubmerged() && aapc.ExceptBy(HasPlayedFriendCodes, x => x.FriendCode).Count() > aapc.Count / 2;
var usedRooms = string.Join('\n', UsedRooms[Main.CurrentMap].Select(x => $"{x.Key}: {GetString(x.Value.ToString())}"));
var usedRooms = UsedRooms[Main.CurrentMap].Join('\n', x => $"{x.Key}: {GetString(x.Value.ToString())}");
aapc.NotifyPlayers(string.Format(GetString("Quiz.Tutorial.Basics"), usedRooms), 11f);
yield return new WaitForSecondsRealtime(showTutorial ? 9f : 5f);
if (GameStates.IsMeeting || ExileController.Instance || !GameStates.InGame || GameStates.IsLobby) yield break;
@@ -454,8 +454,8 @@ public static class Quiz
if (DyingPlayers.Count == 0) NumAllCorrectAnswers++;
bool everyoneWasWrong = DyingPlayers.Count == aapcCount;
if (!everyoneWasWrong) NumCorrectAnswers.IntersectBy(aapc.Select(x => x.PlayerId), x => x.Key).DoIf(x => !DyingPlayers.Contains(x.Key), x => x.Value[CurrentDifficulty][Round]++);
Logger.Info($"{(everyoneWasWrong ? "Everyone" : "Players who")} got the question wrong: {string.Join(", ", DyingPlayers.Select(x => Main.AllPlayerNames.GetValueOrDefault(x, $"Someone (ID {x})")))}", "Quiz");
Logger.Info($"Number of correct answers for everyone currently: {string.Join(", ", NumCorrectAnswers.Select(x => $"{Main.AllPlayerNames.GetValueOrDefault(x.Key, string.Empty)}: {x.Value[CurrentDifficulty][Round]}"))}", "Quiz");
Logger.Info($"{(everyoneWasWrong ? "Everyone" : "Players who")} got the question wrong: {DyingPlayers.Join(", ", x => Main.AllPlayerNames.GetValueOrDefault(x, $"Someone (ID {x})"))}", "Quiz");
Logger.Info($"Number of correct answers for everyone currently: {NumCorrectAnswers.Join(", ", x => $"{Main.AllPlayerNames.GetValueOrDefault(x.Key, string.Empty)}: {x.Value[CurrentDifficulty][Round]}")}", "Quiz");
if (everyoneWasWrong) QuestionsAsked--;
Utils.NotifyRoles();
@@ -475,7 +475,7 @@ public static class Quiz
var correctRequirement = settings.CorrectRequirement.GetInt();
List<byte> dyingPlayers = NumCorrectAnswers.Where(x => x.Value[CurrentDifficulty][Round] < correctRequirement).Select(x => x.Key).Where(x => Main.PlayerStates.TryGetValue(x, out var s) && !s.IsDead).ToList();
Logger.Info($"Round {Round + 1} of {CurrentDifficulty} difficulty ended. Dying players: {dyingPlayers.Count} | {string.Join(", ", dyingPlayers.Select(x => Main.AllPlayerNames[x]))}", "Quiz");
Logger.Info($"Round {Round + 1} of {CurrentDifficulty} difficulty ended. Dying players: {dyingPlayers.Count} | {dyingPlayers.Join(", ", x => Main.AllPlayerNames[x])}", "Quiz");
Round++;
QuestionsAsked = 0;
@@ -559,7 +559,7 @@ public static class Quiz
{
try
{
var correctAnswers = string.Join('\n', NumCorrectAnswers.Select(x => $"{x.Key.ColoredPlayerName()}: {string.Join(' ', x.Value.Select(k => $"{k.Key.ToString()[0]}-{k.Value.Sum()}"))}"));
var correctAnswers = NumCorrectAnswers.Join('\n', x => $"{x.Key.ColoredPlayerName()}: {x.Value.Join(' ', k => $"{k.Key.ToString()[0]}-{k.Value.Sum()}")}");
return string.Format(GetString("Quiz.TaskBarText"), CurrentDifficulty, Round + 1, QuestionsAsked + 1, correctAnswers);
}
catch { return string.Empty; }
+1 -1
View File
@@ -899,7 +899,7 @@ public static class RoomRush
if (WinByPointsInsteadOfDeaths.GetBool())
{
Logger.Info($"Points: {string.Join(", ", Points.Select(x => $"{Main.AllPlayerNames[x.Key]}: {x.Value}"))}", "RoomRush");
Logger.Info($"Points: {Points.Join(", ", x => $"{Main.AllPlayerNames[x.Key]}: {x.Value}")}", "RoomRush");
if (Utils.DoRPC)
{
+1 -1
View File
@@ -198,7 +198,7 @@ public static class Snowdown
{
int max = Data.Values.Max(x => x.Points);
CustomWinnerHolder.WinnerIds = Data.Where(x => x.Value.Points == max && x.Key.GetPlayer()).Select(x => x.Key).ToHashSet();
Logger.Info($"Winners: {string.Join(", ", CustomWinnerHolder.WinnerIds.Select(x => Main.AllPlayerNames.GetValueOrDefault(x, "[Unknown player]")))}", "Snowdown");
Logger.Info($"Winners: {CustomWinnerHolder.WinnerIds.Join(", ", x => Main.AllPlayerNames.GetValueOrDefault(x, "[Unknown player]"))}", "Snowdown");
Main.DoBlockNameChange = true;
return true;
}
+8 -7
View File
@@ -87,14 +87,15 @@ public static class Speedrun
public static string GetTaskBarText()
{
return string.Join('\n', Main.PlayerStates
.Join(Main.EnumerateAlivePlayerControls(), x => x.Key, x => x.PlayerId, (kvp, _) => (
Name: kvp.Key.ColoredPlayerName(),
CompletedTasks: kvp.Value.TaskState.CompletedTasksCount,
AllTasks: kvp.Value.TaskState.AllTasksCount,
Time: AmongUsClient.Instance.AmHost ? $" ({Timers.GetValueOrDefault(kvp.Key)}s)" : string.Empty))
return Main.PlayerStates
.Where(x => !x.Value.IsDead)
.Select(x => (
Name: x.Key.ColoredPlayerName(),
CompletedTasks: x.Value.TaskState.CompletedTasksCount,
AllTasks: x.Value.TaskState.AllTasksCount,
Time: AmongUsClient.Instance.AmHost ? $" ({Timers.GetValueOrDefault(x.Key)}s)" : string.Empty))
.OrderByDescending(x => x.CompletedTasks)
.Select(x => x.CompletedTasks < x.AllTasks ? $"{x.Name}: {x.CompletedTasks}/{x.AllTasks}{x.Time}" : $"{x.Name}: {Translator.GetString("Speedrun_KillingPlayer")}{x.Time}"));
.Join('\n', x => x.CompletedTasks < x.AllTasks ? $"{x.Name}: {x.CompletedTasks}/{x.AllTasks}{x.Time}" : $"{x.Name}: {Translator.GetString("Speedrun_KillingPlayer")}{x.Time}");
}
public static string GetSuffixText(PlayerControl pc)
+1 -1
View File
@@ -183,7 +183,7 @@ internal static class StopAndGo
private static IntegerValueRule CounterValueRule => new(1, 100, 1);
private static IntegerValueRule ExtraTimeValue => new(0, 50, 1);
private static int DefaultMinValue => 5;
private static int DefaultMaxValue => 30;
private static int DefaultMaxValue => 20;
public static string GetHudText()
{
+4 -4
View File
@@ -219,7 +219,7 @@ public static class TheMindGame
sb.Append('\n');
sb.Append('\n');
sb.Append("<size=80%>");
sb.Append(string.Join('\n', AllItem.Select(x => $"{Translator.GetString($"TMG.Item.{x}")} (ID {ItemIds[seer.PlayerId][x]}) ({string.Format(Translator.GetString("TMG.Suffix.ItemCost"), ItemCosts[x])}) - {Translator.GetString($"TMG.ItemDescription.{x}")}")));
sb.Append(AllItem.Join('\n', x => $"{Translator.GetString($"TMG.Item.{x}")} (ID {ItemIds[seer.PlayerId][x]}) ({string.Format(Translator.GetString("TMG.Suffix.ItemCost"), ItemCosts[x])}) - {Translator.GetString($"TMG.ItemDescription.{x}")}"));
sb.Append('\n');
sb.Append('\n');
sb.Append(Translator.GetString("TMG.Suffix.BuyItemHint"));
@@ -236,7 +236,7 @@ public static class TheMindGame
sb.Append('\n');
sb.Append(Translator.GetString("TMG.Suffix.YourItems"));
sb.Append('\n');
sb.Append(string.Join(", ", items.GroupBy(x => x).Select(x => $"{x.Count()}x {Translator.GetString($"TMG.Item.{x.Key}")} (ID {ItemIds[seer.PlayerId][x.Key]})")));
sb.Append(items.GroupBy(x => x).Join(", ", x => $"{x.Count()}x {Translator.GetString($"TMG.Item.{x.Key}")} (ID {ItemIds[seer.PlayerId][x.Key]})"));
sb.Append('\n');
sb.Append('\n');
sb.Append(Translator.GetString("TMG.Suffix.UseItemHint"));
@@ -439,7 +439,7 @@ public static class TheMindGame
List<byte> auctionWinners = Pick.Where(x => x.Value == highestBid).Select(x => x.Key).ToList();
auctionWinners.ForEach(x => SuperPoints[x] += AuctionValue);
yield return NotifyEveryone("TMG.Notify.AuctionEnd", 4, highestBid, string.Join(" & ", auctionWinners.ConvertAll(x => x.ColoredPlayerName())), AuctionValue);
yield return NotifyEveryone("TMG.Notify.AuctionEnd", 4, highestBid, auctionWinners.Join(" & ", x => x.ColoredPlayerName()), AuctionValue);
if (Stop) yield break;
}
@@ -633,7 +633,7 @@ public static class TheMindGame
Dictionary<byte, int> round4Points = ranking.ToDictionary(x => x, x => (ranking.Count - ranking.IndexOf(x)) * 10);
round4Points.Do(x => Points[x.Key] += x.Value);
join = string.Join('\n', round4Points.Select(x => $"{x.Key.ColoredPlayerName()}: +{x.Value}"));
join = round4Points.Join('\n', x => $"{x.Key.ColoredPlayerName()}: +{x.Value}");
yield return NotifyEveryone("TMG.Notify.Round4PointGain", 5, join);
if (Stop) yield break;