zio fork 1.8.2b-zio15: in-game gags/mutes/silences expire with TimeMode 0
Some checks are pending
Build and Publish / build (push) Waiting to run
Build and Publish / publish (push) Blocked by required conditions

The in-memory penalty was only cleared when its end time exactly matched the
database row's, which never happens for one given in game (sub-second vs
to-the-second), so it lasted until reconnect. Match by type within 5 seconds,
and stop applying a penalty as soon as it's marked passed.
This commit is contained in:
Astra 2026-10-03 00:15:03 +01:00
parent 7b3d0ed452
commit dc5ad30952
4 changed files with 39 additions and 5 deletions

View file

@ -22,7 +22,7 @@ public partial class CS2_SimpleAdmin : BasePlugin, IPluginConfig<CS2_SimpleAdmin
public override string ModuleName => "CS2-SimpleAdmin" + (Helper.IsDebugBuild ? " (DEBUG)" : " (RELEASE)");
public override string ModuleDescription => "Simple admin plugin for Counter-Strike 2 :)";
public override string ModuleAuthor => "daffyy";
public override string ModuleVersion => "1.8.2b-zio14";
public override string ModuleVersion => "1.8.2b-zio15";
public override void Load(bool hotReload)
{

View file

@ -212,7 +212,15 @@ internal class MuteManager(IDatabaseProvider? databaseProvider)
foreach (var muteRecord in muteRecords)
{
DateTime endDateTime = muteRecord.ends;
PlayerPenaltyManager.RemovePenaltiesByDateTime(slot, endDateTime);
// zio: match by type and approximate end time; see RemovePenaltiesByDateTime.
string muteType = muteRecord.type;
var penaltyType = muteType switch
{
"MUTE" => PenaltyType.Mute,
"SILENCE" => PenaltyType.Silence,
_ => PenaltyType.Gag
};
PlayerPenaltyManager.RemovePenaltiesByDateTime(slot, penaltyType, endDateTime);
}
}

View file

@ -95,9 +95,11 @@ public static class PlayerPenaltyManager
if (CS2_SimpleAdmin.Instance.Config.OtherSettings.TimeMode == 0)
{
if (penaltiesList.Count == 0) return false;
endDateTime = penaltiesList.First().EndDateTime;
// zio: a penalty marked passed is over, even before RemoveExpiredPenalties drops it.
var active = penaltiesList.FirstOrDefault(p => !p.Passed || p.Duration == 0);
if (active == default) return false;
endDateTime = active.EndDateTime;
return true;
}
@ -255,6 +257,26 @@ public static class PlayerPenaltyManager
}
}
/// <summary>
/// zio: marks a penalty of one type as passed when its end is within a few seconds of the
/// database's. A penalty added in game keeps the end time from the command, which has
/// sub-second precision and is taken a moment before the one the database stores (to the
/// second), so an exact match never finds it and the penalty outlives its database row.
/// </summary>
public static void RemovePenaltiesByDateTime(int slot, PenaltyType penaltyType, DateTime dateTime)
{
if (!Penalties.TryGetValue(slot, out var penaltyDict) ||
!penaltyDict.TryGetValue(penaltyType, out var penaltiesList)) return;
for (var i = 0; i < penaltiesList.Count; i++)
{
if ((penaltiesList[i].EndDateTime - dateTime).Duration() > TimeSpan.FromSeconds(5)) continue;
var penalty = penaltiesList[i];
penalty.Passed = true;
penaltiesList[i] = penalty;
}
}
/// <summary>
/// Removes or expires penalties automatically across all players based on their duration or "passed" flag.
/// </summary>

View file

@ -33,6 +33,10 @@ from the `build-1.8.2b` tag). Changes, all marked `zio:` in the code:
highest-immunity group, and who changed it) to `sa_rank_log`, the table simpleadmin-web creates
and lists as the public promotions/demotions log. If the table is missing, it warns once in the
log and the admin change goes ahead.
- With `TimeMode` 0 (online time only), a gag, mute or silence given in game now ends when its
database row expires. Upstream matched the two by exact end time, which never matched for one
given in game (the database stores the time to the second), so it lasted until the player
reconnected. A penalty marked passed also stops applying at once, not on the next 61-second tick.
Publish with `FORGEJO_TOKEN=... ./release.sh v<ModuleVersion>` (ModuleVersion is `1.8.2b-zioN`).
It rebuilds from the committed source and uploads `SimpleAdmin-<tag>.tar.gz` to git.zio.sh