Skip to content

Commit eefa922

Browse files
HandyS11claude
andcommitted
refactor: extract helpers to reduce cognitive complexity below 15 (S3776)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
1 parent 79f7d13 commit eefa922

3 files changed

Lines changed: 86 additions & 58 deletions

File tree

src/RustPlusBot.Features.Connections/Supervisor/ConnectionSupervisor.cs

Lines changed: 27 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -491,24 +491,7 @@ void OnSmartDevice(object? sender, SmartDeviceTrigger trigger)
491491
CancellationToken.None);
492492
try
493493
{
494-
while (!ct.IsCancellationRequested)
495-
{
496-
await Task.Delay(_options.HeartbeatInterval, ct).ConfigureAwait(false);
497-
var beat = await connection.GetInfoAsync(_options.HeartbeatTimeout, ct).ConfigureAwait(false);
498-
switch (beat.Kind)
499-
{
500-
case HeartbeatKind.Ok:
501-
await PublishStatusAsync(key, ConnectionStatus.Connected, beat.PlayerCount, credentialId, ct)
502-
.ConfigureAwait(false);
503-
break;
504-
case HeartbeatKind.AuthRejected:
505-
return ReconnectReason.AuthRejected;
506-
default:
507-
return ReconnectReason.Unreachable;
508-
}
509-
}
510-
511-
return ReconnectReason.Stopped;
494+
return await RunHeartbeatLoopAsync(key, connection, credentialId, ct).ConfigureAwait(false);
512495
}
513496
finally
514497
{
@@ -530,6 +513,32 @@ await PublishStatusAsync(key, ConnectionStatus.Connected, beat.PlayerCount, cred
530513
}
531514
}
532515

516+
private async Task<ReconnectReason> RunHeartbeatLoopAsync(
517+
(ulong Guild, Guid Server) key,
518+
IRustServerConnection connection,
519+
Guid credentialId,
520+
CancellationToken ct)
521+
{
522+
while (!ct.IsCancellationRequested)
523+
{
524+
await Task.Delay(_options.HeartbeatInterval, ct).ConfigureAwait(false);
525+
var beat = await connection.GetInfoAsync(_options.HeartbeatTimeout, ct).ConfigureAwait(false);
526+
switch (beat.Kind)
527+
{
528+
case HeartbeatKind.Ok:
529+
await PublishStatusAsync(key, ConnectionStatus.Connected, beat.PlayerCount, credentialId, ct)
530+
.ConfigureAwait(false);
531+
break;
532+
case HeartbeatKind.AuthRejected:
533+
return ReconnectReason.AuthRejected;
534+
default:
535+
return ReconnectReason.Unreachable;
536+
}
537+
}
538+
539+
return ReconnectReason.Stopped;
540+
}
541+
533542
private async Task PollMarkersAsync(
534543
(ulong Guild, Guid Server) key,
535544
IRustServerConnection connection,

src/RustPlusBot.Features.Map/Rendering/MapRenderer.cs

Lines changed: 32 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -189,34 +189,42 @@ private static void DrawPlayers(Image<Rgba32> image, IReadOnlyList<PlayerPlaceme
189189
{
190190
foreach (var player in players)
191191
{
192-
var isActive = player is { IsAlive: true, IsOnline: true };
193-
194-
if (icon is not null)
195-
{
196-
ctx.DrawImage(icon, CenterAt(player.PixelX, player.PixelY, icon), 1f);
197-
}
198-
else
199-
{
200-
var dotColor = isActive ? Color.LimeGreen : Color.Gray;
201-
var dot = new EllipsePolygon(player.PixelX, player.PixelY, PlayerRadius);
202-
ctx.Fill(dotColor, dot);
203-
ctx.Draw(Color.Black, OutlinePenWidth, dot);
204-
}
205-
206-
var suffix = player.IsAlive ? " (offline)" : " (dead)";
207-
var label = isActive ? player.Name : player.Name + suffix;
208-
var labelColor = isActive ? Color.White : Color.Gray;
209-
var textOptions = new RichTextOptions(Font)
210-
{
211-
Origin = new PointF(player.PixelX, player.PixelY + PlayerLabelOffset),
212-
HorizontalAlignment = HorizontalAlignment.Center,
213-
VerticalAlignment = VerticalAlignment.Top,
214-
};
215-
ctx.DrawText(textOptions, label, labelColor);
192+
DrawPlayerIcon(ctx, player, icon);
193+
DrawPlayerLabel(ctx, player);
216194
}
217195
});
218196
}
219197

198+
private static void DrawPlayerIcon(IImageProcessingContext ctx, PlayerPlacement player, Image<Rgba32>? icon)
199+
{
200+
if (icon is not null)
201+
{
202+
ctx.DrawImage(icon, CenterAt(player.PixelX, player.PixelY, icon), 1f);
203+
return;
204+
}
205+
206+
var isActive = player is { IsAlive: true, IsOnline: true };
207+
var dotColor = isActive ? Color.LimeGreen : Color.Gray;
208+
var dot = new EllipsePolygon(player.PixelX, player.PixelY, PlayerRadius);
209+
ctx.Fill(dotColor, dot);
210+
ctx.Draw(Color.Black, OutlinePenWidth, dot);
211+
}
212+
213+
private static void DrawPlayerLabel(IImageProcessingContext ctx, PlayerPlacement player)
214+
{
215+
var isActive = player is { IsAlive: true, IsOnline: true };
216+
var suffix = player.IsAlive ? " (offline)" : " (dead)";
217+
var label = isActive ? player.Name : player.Name + suffix;
218+
var labelColor = isActive ? Color.White : Color.Gray;
219+
var textOptions = new RichTextOptions(Font)
220+
{
221+
Origin = new PointF(player.PixelX, player.PixelY + PlayerLabelOffset),
222+
HorizontalAlignment = HorizontalAlignment.Center,
223+
VerticalAlignment = VerticalAlignment.Top,
224+
};
225+
ctx.DrawText(textOptions, label, labelColor);
226+
}
227+
220228
private static Point CenterAt(float x, float y, Image<Rgba32> icon) =>
221229
new((int)(x - (icon.Width / 2f)), (int)(y - (icon.Height / 2f)));
222230
}

src/RustPlusBot.Features.Workspace/Messages/ServerInfoMessageRenderer.cs

Lines changed: 27 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -66,22 +66,7 @@ public async ValueTask<MessagePayload> RenderAsync(MessageRenderContext context,
6666

6767
if (status == ConnectionStatus.Connected)
6868
{
69-
var team = await query.GetTeamInfoAsync(context.GuildId, serverId, cancellationToken).ConfigureAwait(false);
70-
if (team is not null)
71-
{
72-
var online = team.Members.Count(m => m.IsOnline);
73-
var leaderEntry = team.Members.FirstOrDefault(m => m.SteamId == team.LeaderSteamId);
74-
// The API can report a member with no display name, so treat an empty name as missing.
75-
var leaderName = string.IsNullOrWhiteSpace(leaderEntry?.Name)
76-
? team.LeaderSteamId.ToString(CultureInfo.InvariantCulture)
77-
: leaderEntry.Name;
78-
embed.AddField(
79-
localizer.Get("server.info.team.label", context.Culture),
80-
localizer.Get("server.info.team.value", context.Culture,
81-
online.ToString(CultureInfo.InvariantCulture),
82-
team.Members.Count.ToString(CultureInfo.InvariantCulture),
83-
leaderName));
84-
}
69+
await AddTeamFieldAsync(embed, context, serverId, cancellationToken).ConfigureAwait(false);
8570
}
8671

8772
var eligible = pool
@@ -113,6 +98,32 @@ public async ValueTask<MessagePayload> RenderAsync(MessageRenderContext context,
11398
return new MessagePayload(null, embed.Build(), builder.Build());
11499
}
115100

101+
private async ValueTask AddTeamFieldAsync(
102+
EmbedBuilder embed,
103+
MessageRenderContext context,
104+
Guid serverId,
105+
CancellationToken cancellationToken)
106+
{
107+
var team = await query.GetTeamInfoAsync(context.GuildId, serverId, cancellationToken).ConfigureAwait(false);
108+
if (team is null)
109+
{
110+
return;
111+
}
112+
113+
var online = team.Members.Count(m => m.IsOnline);
114+
var leaderEntry = team.Members.FirstOrDefault(m => m.SteamId == team.LeaderSteamId);
115+
// The API can report a member with no display name, so treat an empty name as missing.
116+
var leaderName = string.IsNullOrWhiteSpace(leaderEntry?.Name)
117+
? team.LeaderSteamId.ToString(CultureInfo.InvariantCulture)
118+
: leaderEntry.Name;
119+
embed.AddField(
120+
localizer.Get("server.info.team.label", context.Culture),
121+
localizer.Get("server.info.team.value", context.Culture,
122+
online.ToString(CultureInfo.InvariantCulture),
123+
team.Members.Count.ToString(CultureInfo.InvariantCulture),
124+
leaderName));
125+
}
126+
116127
private static string Glyph(ConnectionStatus status) => status switch
117128
{
118129
ConnectionStatus.Connected => "🟢",

0 commit comments

Comments
 (0)