Skip to content
This repository was archived by the owner on Mar 11, 2025. It is now read-only.

Commit 3dc88a2

Browse files
committed
Patch v1.4.0
1 parent 8c4ada0 commit 3dc88a2

File tree

4 files changed

+82
-54
lines changed

4 files changed

+82
-54
lines changed

CHANGELOG

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
-- 2024. 07. 02 - v1.4.0
2+
3+
- feat: Added option to allow private profiles join for given seconds to warn them about the issue
4+
- remove: Removed fully SteamWorks dependency and solved with own solutions instead
5+
- remove: Removed prime based checks for now due to SteamWorks not detect primes if bought after CS2 release
6+
17
-- 2024. 05. 21 - v1.3.2
28

39
- feat: Added option to disable join logs

src/KitsuneSteamRestrict.cs

Lines changed: 51 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,7 @@
66

77
using System.Text.Json.Serialization;
88
using Microsoft.Extensions.Logging;
9-
using Steamworks;
10-
using CounterStrikeSharp.API.Modules.Cvars;
9+
using CounterStrikeSharp.API.Modules.Utils;
1110

1211
namespace KitsuneSteamRestrict;
1312

@@ -19,23 +18,17 @@ public class PluginConfig : BasePluginConfig
1918
[JsonPropertyName("SteamWebAPI")]
2019
public string SteamWebAPI { get; set; } = "";
2120

22-
[JsonPropertyName("MinimumCS2LevelPrime")]
23-
public int MinimumCS2LevelPrime { get; set; } = -1;
21+
[JsonPropertyName("MinimumCS2Level")]
22+
public int MinimumCS2Level { get; set; } = -1;
2423

25-
[JsonPropertyName("MinimumCS2LevelNonPrime")]
26-
public int MinimumCS2LevelNonPrime { get; set; } = -1;
2724

28-
[JsonPropertyName("MinimumHourPrime")]
29-
public int MinimumHourPrime { get; set; } = -1;
25+
[JsonPropertyName("MinimumHour")]
26+
public int MinimumHour { get; set; } = -1;
3027

31-
[JsonPropertyName("MinimumHourNonPrime")]
32-
public int MinimumHourNonPrime { get; set; } = -1;
3328

34-
[JsonPropertyName("MinimumLevelPrime")]
35-
public int MinimumLevelPrime { get; set; } = -1;
29+
[JsonPropertyName("MinimumLevel")]
30+
public int MinimumLevel { get; set; } = -1;
3631

37-
[JsonPropertyName("MinimumLevelNonPrime")]
38-
public int MinimumLevelNonPrime { get; set; } = -1;
3932

4033
[JsonPropertyName("MinimumSteamAccountAgeInDays")]
4134
public int MinimumSteamAccountAgeInDays { get; set; } = -1;
@@ -55,11 +48,14 @@ public class PluginConfig : BasePluginConfig
5548
[JsonPropertyName("BlockGameBanned")]
5649
public bool BlockGameBanned { get; set; } = false;
5750

51+
[JsonPropertyName("PrivateProfileWarningTime")]
52+
public int PrivateProfileWarningTime { get; set; } = 5;
53+
5854
[JsonPropertyName("DatabaseSettings")]
5955
public DatabaseSettings DatabaseSettings { get; set; } = new DatabaseSettings();
6056

6157
[JsonPropertyName("ConfigVersion")]
62-
public override int Version { get; set; } = 3;
58+
public override int Version { get; set; } = 4;
6359
}
6460

6561
public sealed class DatabaseSettings
@@ -93,14 +89,15 @@ public sealed class DatabaseSettings
9389
public class SteamRestrictPlugin : BasePlugin, IPluginConfig<PluginConfig>
9490
{
9591
public override string ModuleName => "Steam Restrict";
96-
public override string ModuleVersion => "1.3.2";
92+
public override string ModuleVersion => "1.4.0";
9793
public override string ModuleAuthor => "K4ryuu, Cruze @ KitsuneLab";
9894
public override string ModuleDescription => "Restrict certain players from connecting to your server.";
9995

10096
public readonly HttpClient Client = new HttpClient();
10197
private bool g_bSteamAPIActivated = false;
10298

103-
private CounterStrikeSharp.API.Modules.Timers.Timer?[] g_hAuthorize = new CounterStrikeSharp.API.Modules.Timers.Timer?[65];
99+
private CounterStrikeSharp.API.Modules.Timers.Timer?[] g_hTimer = new CounterStrikeSharp.API.Modules.Timers.Timer?[65];
100+
private int[] g_iWarnTime = new int[65];
104101

105102
private BypassConfig? _bypassConfig;
106103
public PluginConfig Config { get; set; } = new();
@@ -129,8 +126,8 @@ public override void Load(bool hotReload)
129126
}
130127

131128
RegisterListener<Listeners.OnGameServerSteamAPIActivated>(() => { g_bSteamAPIActivated = true; });
132-
RegisterListener<Listeners.OnClientConnect>((int slot, string name, string ipAddress) => { g_hAuthorize[slot]?.Kill(); });
133-
RegisterListener<Listeners.OnClientDisconnect>((int slot) => { g_hAuthorize[slot]?.Kill(); });
129+
RegisterListener<Listeners.OnClientConnect>((int slot, string name, string ipAddress) => { g_hTimer[slot]?.Kill(); });
130+
RegisterListener<Listeners.OnClientDisconnect>((int slot) => { g_hTimer[slot]?.Kill(); });
134131
RegisterEventHandler<EventPlayerConnectFull>(OnPlayerConnectFull, HookMode.Post);
135132

136133
if (hotReload)
@@ -164,11 +161,11 @@ private void OnPlayerConnectFull(CCSPlayerController player)
164161

165162
if (player.AuthorizedSteamID == null)
166163
{
167-
g_hAuthorize[player.Slot] = AddTimer(1.0f, () =>
164+
g_hTimer[player.Slot] = AddTimer(1.0f, () =>
168165
{
169166
if (player.AuthorizedSteamID != null)
170167
{
171-
g_hAuthorize[player.Slot]?.Kill();
168+
g_hTimer[player.Slot]?.Kill();
172169
OnPlayerConnectFull(player);
173170
return;
174171
}
@@ -203,12 +200,8 @@ private void OnPlayerConnectFull(CCSPlayerController player)
203200

204201
private void CheckUserViolations(nint handle, ulong authorizedSteamID)
205202
{
206-
CSteamID cSteamID = new CSteamID(authorizedSteamID);
207-
208203
SteamUserInfo UserInfo = new SteamUserInfo
209204
{
210-
HasPrime = SteamGameServer.UserHasLicenseForApp(cSteamID, (AppId_t)624820) == EUserHasLicenseForAppResult.k_EUserHasLicenseResultHasLicense
211-
|| SteamGameServer.UserHasLicenseForApp(cSteamID, (AppId_t)54029) == EUserHasLicenseForAppResult.k_EUserHasLicenseResultHasLicense,
212205
CS2Level = new CCSPlayerController_InventoryServices(handle).PersonaDataPublicLevel
213206
};
214207

@@ -236,7 +229,7 @@ private void CheckUserViolations(nint handle, ulong authorizedSteamID)
236229
Logger.LogInformation($"Steam Account Creation Date: {userInfo.SteamAccountAge:dd-MM-yyyy} ({(int)(DateTime.Now - userInfo.SteamAccountAge).TotalDays} days ago)");
237230
else
238231
Logger.LogInformation($"Steam Account Creation Date: N/A");
239-
Logger.LogInformation($"HasPrime: {userInfo.HasPrime}");
232+
//Logger.LogInformation($"HasPrime: {userInfo.HasPrime}"); Removed due to people bought prime after CS2 cannot be detected sadly (or atleast not yet)
240233
Logger.LogInformation($"HasPrivateProfile: {userInfo.IsPrivate}");
241234
Logger.LogInformation($"IsTradeBanned: {userInfo.IsTradeBanned}");
242235
Logger.LogInformation($"IsGameBanned: {userInfo.IsGameBanned}");
@@ -245,7 +238,32 @@ private void CheckUserViolations(nint handle, ulong authorizedSteamID)
245238

246239
if (IsRestrictionViolated(player, userInfo))
247240
{
248-
Server.ExecuteCommand($"kickid {player.UserId} \"You have been kicked for not meeting the minimum requirements.\"");
241+
if (Config.PrivateProfileWarningTime > 0 && userInfo.IsPrivate)
242+
{
243+
g_iWarnTime[player.Slot] = Config.PrivateProfileWarningTime;
244+
int playerSlot = player.Slot;
245+
246+
g_hTimer[playerSlot] = AddTimer(1, () =>
247+
{
248+
if (player?.IsValid == true)
249+
{
250+
player.PrintToChat($" {ChatColors.Silver}[ {ChatColors.Lime}SteamRestrict {ChatColors.Silver}] {ChatColors.LightRed}Your Steam profile or Game details are private. You will be kicked in {g_iWarnTime[playerSlot]} seconds.");
251+
}
252+
253+
g_iWarnTime[playerSlot]--;
254+
255+
if (g_iWarnTime[playerSlot] <= 0)
256+
{
257+
if (player?.IsValid == true)
258+
Server.ExecuteCommand($"kickid {player.UserId} \"You have been kicked for not meeting the minimum requirements.\"");
259+
260+
g_hTimer[playerSlot]?.Kill();
261+
g_hTimer[playerSlot] = null;
262+
}
263+
}, TimerFlags.REPEAT);
264+
}
265+
else
266+
Server.ExecuteCommand($"kickid {player.UserId} \"You have been kicked for not meeting the minimum requirements.\"");
249267
}
250268
else if (!IsDatabaseConfigDefault())
251269
{
@@ -269,30 +287,15 @@ private bool IsRestrictionViolated(CCSPlayerController player, SteamUserInfo use
269287

270288
BypassConfig bypassConfig = _bypassConfig ?? new BypassConfig();
271289
PlayerBypassConfig? playerBypassConfig = bypassConfig.GetPlayerConfig(player.AuthorizedSteamID?.SteamId64 ?? 0);
272-
bool isPrime = userInfo.HasPrime;
273-
274-
if (isPrime)
275-
{
276-
if (!(playerBypassConfig?.BypassMinimumCS2Level ?? false) && Config.MinimumCS2LevelPrime != -1 && userInfo.CS2Level < Config.MinimumCS2LevelPrime)
277-
return true;
278290

279-
if (!(playerBypassConfig?.BypassMinimumHours ?? false) && Config.MinimumHourPrime != -1 && userInfo.CS2Playtime < Config.MinimumHourPrime)
280-
return true;
281-
282-
if (!(playerBypassConfig?.BypassMinimumLevel ?? false) && Config.MinimumLevelPrime != -1 && userInfo.SteamLevel < Config.MinimumLevelPrime)
283-
return true;
284-
}
285-
else
286-
{
287-
if (!(playerBypassConfig?.BypassMinimumCS2Level ?? false) && Config.MinimumCS2LevelNonPrime != -1 && userInfo.CS2Level < Config.MinimumCS2LevelNonPrime)
288-
return true;
291+
if (!(playerBypassConfig?.BypassMinimumCS2Level ?? false) && Config.MinimumCS2Level != -1 && userInfo.CS2Level < Config.MinimumCS2Level)
292+
return true;
289293

290-
if (!(playerBypassConfig?.BypassMinimumHours ?? false) && Config.MinimumHourNonPrime != -1 && userInfo.CS2Playtime < Config.MinimumHourNonPrime)
291-
return true;
294+
if (!(playerBypassConfig?.BypassMinimumHours ?? false) && Config.MinimumHour != -1 && userInfo.CS2Playtime < Config.MinimumHour)
295+
return true;
292296

293-
if (!(playerBypassConfig?.BypassMinimumLevel ?? false) && Config.MinimumLevelNonPrime != -1 && userInfo.SteamLevel < Config.MinimumLevelNonPrime)
294-
return true;
295-
}
297+
if (!(playerBypassConfig?.BypassMinimumLevel ?? false) && Config.MinimumLevel != -1 && userInfo.SteamLevel < Config.MinimumLevel)
298+
return true;
296299

297300
if (!(playerBypassConfig?.BypassMinimumSteamAccountAge ?? false) && Config.MinimumSteamAccountAgeInDays != -1 && (DateTime.Now - userInfo.SteamAccountAge).TotalDays < Config.MinimumSteamAccountAgeInDays)
298301
return true;

src/KitsuneSteamRestrict.csproj

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,8 @@
1515
<ExcludeAssets>runtime</ExcludeAssets>
1616
<IncludeAssets>compile; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
1717
</PackageReference>
18-
<PackageReference Include="Dapper" Version="2.1.35" />
19-
<PackageReference Include="MySqlConnector" Version="2.3.7" />
18+
<PackageReference Include="Dapper" Version="*" />
19+
<PackageReference Include="MySqlConnector" Version="*" />
2020
<PackageReference Include="Newtonsoft.Json" Version="*" />
21-
<PackageReference Include="Steamworks.NET" Version="*" />
2221
</ItemGroup>
2322
</Project>

src/Models/SteamService.cs

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,7 @@
11

2-
using CounterStrikeSharp.API;
3-
using CounterStrikeSharp.API.Core;
42
using KitsuneSteamRestrict;
53
using Microsoft.Extensions.Logging;
64
using Newtonsoft.Json.Linq;
7-
using Steamworks;
85

96
public class SteamUserInfo
107
{
@@ -39,6 +36,7 @@ public SteamService(SteamRestrictPlugin plugin, SteamUserInfo userInfo)
3936

4037
public async Task FetchSteamUserInfo(string steamId)
4138
{
39+
//UserInfo.HasPrime = await FetchHasPrimeAsync(steamId);
4240
UserInfo!.CS2Playtime = await FetchCS2PlaytimeAsync(steamId) / 60;
4341
UserInfo.SteamLevel = await FetchSteamLevelAsync(steamId);
4442
await FetchProfilePrivacyAsync(steamId, UserInfo);
@@ -174,4 +172,26 @@ private void ParseVACBanStatus(string json, SteamUserInfo userInfo)
174172
JToken? userGameBan = data["players"]?.FirstOrDefault();
175173
userInfo.IsVACBanned = userGameBan != null && (bool)(userGameBan["VACBanned"] ?? false);
176174
}
175+
176+
/*
177+
! This method is not used in the current implementation due to the people who bought Prime after
178+
! the CS2 release are not visible as Prime users. This method is kept here for reference if its gonna
179+
! be used in the future, whenever Volvo decides to fix their API.
180+
181+
private async Task<bool> FetchHasPrimeAsync(string steamId)
182+
{
183+
var url = $"https://api.steampowered.com/IPlayerService/GetOwnedGames/v1/?key={_steamWebAPIKey}&steamid={steamId}&include_appinfo=false&include_played_free_games=true&format=json";
184+
var json = await GetApiResponseAsync(url);
185+
if (json != null)
186+
{
187+
JObject data = JObject.Parse(json);
188+
var games = data["response"]?["games"];
189+
if (games != null)
190+
{
191+
_logger.LogInformation($"Prime: {games.Any(game => game["appid"]?.Value<int>() == 624820 || game["appid"]?.Value<int>() == 54029)}");
192+
return games.Any(game => game["appid"]?.Value<int>() == 624820 || game["appid"]?.Value<int>() == 54029);
193+
}
194+
}
195+
return false;
196+
}*/
177197
}

0 commit comments

Comments
 (0)