]> git.deb.at Git - rhonda/impostor.git/commitdiff
Record and restore player colors
authorminiduikboot <mini@duikbo.at>
Sun, 17 Nov 2024 15:18:49 +0000 (16:18 +0100)
committerminiduikboot <mini@duikbo.at>
Thu, 22 May 2025 21:48:50 +0000 (23:48 +0200)
This prevents situations where a player that requested red has a
different color when rejoining because red is the default color of a
PlayerInfo object. This is most noticeable if the host is late with
rejoining, and a lot of players are alreading in WaitingForHost limbo.

When the host finally rejoins, they will not assign Red immediately to
players that requested Red as it is "in use", and instead assign the
next color.

By recording and restoring this is avoided, and players tend to get
their own colors back in most cases.

This is not something that officials do at the moment, but I don't think
this has an impact on mods, as a normal checkcolor/setcolor cycle will
take place as usual.

src/Impostor.Server/Net/ClientBase.cs
src/Impostor.Server/Net/Inner/Objects/InnerPlayerControl.cs
src/Impostor.Server/Net/State/Game.Data.cs

index a8945fafc4e67f120ea3e45e697d9c417e7d2463..1aee622dbd61261a1211e2600e95819f696a28c7 100644 (file)
@@ -3,6 +3,7 @@ using System.Collections.Generic;
 using System.Threading.Tasks;
 using Impostor.Api;
 using Impostor.Api.Innersloth;
+using Impostor.Api.Innersloth.Customization;
 using Impostor.Api.Net;
 using Impostor.Server.Net.State;
 
@@ -39,6 +40,8 @@ namespace Impostor.Server.Net
 
         public ClientPlayer? Player { get; set; }
 
+        public ColorType? PreviousColor { get; set; } = null;
+
         IClientPlayer? IClient.Player => Player;
 
         public virtual ValueTask<bool> ReportCheatAsync(CheatContext context, CheatCategory category, string message)
index 6503ed493c6a496fceea0512613ed992978d661b..e9cec15ca5b7ff4377a27c7421637ac80b8c759a 100644 (file)
@@ -845,6 +845,16 @@ namespace Impostor.Server.Net.Inner.Objects
 
             PlayerInfo.CurrentOutfit.Color = color;
 
+            // Record the color so it can be restored on the next game
+            if (!Game.IsHostAuthoritive && Game.TryGetPlayer(OwnerId, out var clientPlayer))
+            {
+                clientPlayer.Client.PreviousColor = color;
+            }
+            else
+            {
+                _logger.LogWarning("Tried to record color, but couldn't get player with id {PlayerId}", OwnerId);
+            }
+
             return true;
         }
 
index 9d0fb550d88cb4224697ffc79391c93fb9f232ff..dcd57e0bd7d3a226494f7d26985424a30e43aee5 100644 (file)
@@ -499,6 +499,14 @@ namespace Impostor.Server.Net.State
             playerInfo.ClientId = sender.Client.Id;
             playerInfo.PlayerId = GameNet.GameData.GetNextAvailablePlayerId();
 
+            // If player played a previous game, restore their color
+            var prevColor = sender.Client.PreviousColor;
+            if (prevColor.HasValue)
+            {
+                _logger.LogTrace("Color restored to {Color}", prevColor.Value);
+                playerInfo.CurrentOutfit.Color = prevColor.Value;
+            }
+
             if (!AddNetObject(playerInfo))
             {
                 _logger.LogError("Couldn't spawn PlayerInfo for {Name} ({ClientId})", sender.Client.Name, sender.Client.Id);