Skip to content

Commit

Permalink
Patch v1.4.0
Browse files Browse the repository at this point in the history
  • Loading branch information
K4ryuu committed Jul 2, 2024
1 parent 8c4ada0 commit 3dc88a2
Show file tree
Hide file tree
Showing 4 changed files with 82 additions and 54 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
-- 2024. 07. 02 - v1.4.0

- feat: Added option to allow private profiles join for given seconds to warn them about the issue
- remove: Removed fully SteamWorks dependency and solved with own solutions instead
- remove: Removed prime based checks for now due to SteamWorks not detect primes if bought after CS2 release

-- 2024. 05. 21 - v1.3.2

- feat: Added option to disable join logs
Expand Down
99 changes: 51 additions & 48 deletions src/KitsuneSteamRestrict.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,7 @@

using System.Text.Json.Serialization;
using Microsoft.Extensions.Logging;
using Steamworks;
using CounterStrikeSharp.API.Modules.Cvars;
using CounterStrikeSharp.API.Modules.Utils;

namespace KitsuneSteamRestrict;

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

[JsonPropertyName("MinimumCS2LevelPrime")]
public int MinimumCS2LevelPrime { get; set; } = -1;
[JsonPropertyName("MinimumCS2Level")]
public int MinimumCS2Level { get; set; } = -1;

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

[JsonPropertyName("MinimumHourPrime")]
public int MinimumHourPrime { get; set; } = -1;
[JsonPropertyName("MinimumHour")]
public int MinimumHour { get; set; } = -1;

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

[JsonPropertyName("MinimumLevelPrime")]
public int MinimumLevelPrime { get; set; } = -1;
[JsonPropertyName("MinimumLevel")]
public int MinimumLevel { get; set; } = -1;

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

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

[JsonPropertyName("PrivateProfileWarningTime")]
public int PrivateProfileWarningTime { get; set; } = 5;

[JsonPropertyName("DatabaseSettings")]
public DatabaseSettings DatabaseSettings { get; set; } = new DatabaseSettings();

[JsonPropertyName("ConfigVersion")]
public override int Version { get; set; } = 3;
public override int Version { get; set; } = 4;
}

public sealed class DatabaseSettings
Expand Down Expand Up @@ -93,14 +89,15 @@ public sealed class DatabaseSettings
public class SteamRestrictPlugin : BasePlugin, IPluginConfig<PluginConfig>
{
public override string ModuleName => "Steam Restrict";
public override string ModuleVersion => "1.3.2";
public override string ModuleVersion => "1.4.0";
public override string ModuleAuthor => "K4ryuu, Cruze @ KitsuneLab";
public override string ModuleDescription => "Restrict certain players from connecting to your server.";

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

private CounterStrikeSharp.API.Modules.Timers.Timer?[] g_hAuthorize = new CounterStrikeSharp.API.Modules.Timers.Timer?[65];
private CounterStrikeSharp.API.Modules.Timers.Timer?[] g_hTimer = new CounterStrikeSharp.API.Modules.Timers.Timer?[65];
private int[] g_iWarnTime = new int[65];

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

RegisterListener<Listeners.OnGameServerSteamAPIActivated>(() => { g_bSteamAPIActivated = true; });
RegisterListener<Listeners.OnClientConnect>((int slot, string name, string ipAddress) => { g_hAuthorize[slot]?.Kill(); });
RegisterListener<Listeners.OnClientDisconnect>((int slot) => { g_hAuthorize[slot]?.Kill(); });
RegisterListener<Listeners.OnClientConnect>((int slot, string name, string ipAddress) => { g_hTimer[slot]?.Kill(); });
RegisterListener<Listeners.OnClientDisconnect>((int slot) => { g_hTimer[slot]?.Kill(); });
RegisterEventHandler<EventPlayerConnectFull>(OnPlayerConnectFull, HookMode.Post);

if (hotReload)
Expand Down Expand Up @@ -164,11 +161,11 @@ private void OnPlayerConnectFull(CCSPlayerController player)

if (player.AuthorizedSteamID == null)
{
g_hAuthorize[player.Slot] = AddTimer(1.0f, () =>
g_hTimer[player.Slot] = AddTimer(1.0f, () =>
{
if (player.AuthorizedSteamID != null)
{
g_hAuthorize[player.Slot]?.Kill();
g_hTimer[player.Slot]?.Kill();
OnPlayerConnectFull(player);
return;
}
Expand Down Expand Up @@ -203,12 +200,8 @@ private void OnPlayerConnectFull(CCSPlayerController player)

private void CheckUserViolations(nint handle, ulong authorizedSteamID)
{
CSteamID cSteamID = new CSteamID(authorizedSteamID);

SteamUserInfo UserInfo = new SteamUserInfo
{
HasPrime = SteamGameServer.UserHasLicenseForApp(cSteamID, (AppId_t)624820) == EUserHasLicenseForAppResult.k_EUserHasLicenseResultHasLicense
|| SteamGameServer.UserHasLicenseForApp(cSteamID, (AppId_t)54029) == EUserHasLicenseForAppResult.k_EUserHasLicenseResultHasLicense,
CS2Level = new CCSPlayerController_InventoryServices(handle).PersonaDataPublicLevel
};

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

if (IsRestrictionViolated(player, userInfo))
{
Server.ExecuteCommand($"kickid {player.UserId} \"You have been kicked for not meeting the minimum requirements.\"");
if (Config.PrivateProfileWarningTime > 0 && userInfo.IsPrivate)
{
g_iWarnTime[player.Slot] = Config.PrivateProfileWarningTime;
int playerSlot = player.Slot;

g_hTimer[playerSlot] = AddTimer(1, () =>
{
if (player?.IsValid == true)
{
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.");
}

g_iWarnTime[playerSlot]--;

if (g_iWarnTime[playerSlot] <= 0)
{
if (player?.IsValid == true)
Server.ExecuteCommand($"kickid {player.UserId} \"You have been kicked for not meeting the minimum requirements.\"");

g_hTimer[playerSlot]?.Kill();
g_hTimer[playerSlot] = null;
}
}, TimerFlags.REPEAT);
}
else
Server.ExecuteCommand($"kickid {player.UserId} \"You have been kicked for not meeting the minimum requirements.\"");
}
else if (!IsDatabaseConfigDefault())
{
Expand All @@ -269,30 +287,15 @@ private bool IsRestrictionViolated(CCSPlayerController player, SteamUserInfo use

BypassConfig bypassConfig = _bypassConfig ?? new BypassConfig();
PlayerBypassConfig? playerBypassConfig = bypassConfig.GetPlayerConfig(player.AuthorizedSteamID?.SteamId64 ?? 0);
bool isPrime = userInfo.HasPrime;

if (isPrime)
{
if (!(playerBypassConfig?.BypassMinimumCS2Level ?? false) && Config.MinimumCS2LevelPrime != -1 && userInfo.CS2Level < Config.MinimumCS2LevelPrime)
return true;

if (!(playerBypassConfig?.BypassMinimumHours ?? false) && Config.MinimumHourPrime != -1 && userInfo.CS2Playtime < Config.MinimumHourPrime)
return true;

if (!(playerBypassConfig?.BypassMinimumLevel ?? false) && Config.MinimumLevelPrime != -1 && userInfo.SteamLevel < Config.MinimumLevelPrime)
return true;
}
else
{
if (!(playerBypassConfig?.BypassMinimumCS2Level ?? false) && Config.MinimumCS2LevelNonPrime != -1 && userInfo.CS2Level < Config.MinimumCS2LevelNonPrime)
return true;
if (!(playerBypassConfig?.BypassMinimumCS2Level ?? false) && Config.MinimumCS2Level != -1 && userInfo.CS2Level < Config.MinimumCS2Level)
return true;

if (!(playerBypassConfig?.BypassMinimumHours ?? false) && Config.MinimumHourNonPrime != -1 && userInfo.CS2Playtime < Config.MinimumHourNonPrime)
return true;
if (!(playerBypassConfig?.BypassMinimumHours ?? false) && Config.MinimumHour != -1 && userInfo.CS2Playtime < Config.MinimumHour)
return true;

if (!(playerBypassConfig?.BypassMinimumLevel ?? false) && Config.MinimumLevelNonPrime != -1 && userInfo.SteamLevel < Config.MinimumLevelNonPrime)
return true;
}
if (!(playerBypassConfig?.BypassMinimumLevel ?? false) && Config.MinimumLevel != -1 && userInfo.SteamLevel < Config.MinimumLevel)
return true;

if (!(playerBypassConfig?.BypassMinimumSteamAccountAge ?? false) && Config.MinimumSteamAccountAgeInDays != -1 && (DateTime.Now - userInfo.SteamAccountAge).TotalDays < Config.MinimumSteamAccountAgeInDays)
return true;
Expand Down
5 changes: 2 additions & 3 deletions src/KitsuneSteamRestrict.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,8 @@
<ExcludeAssets>runtime</ExcludeAssets>
<IncludeAssets>compile; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Dapper" Version="2.1.35" />
<PackageReference Include="MySqlConnector" Version="2.3.7" />
<PackageReference Include="Dapper" Version="*" />
<PackageReference Include="MySqlConnector" Version="*" />
<PackageReference Include="Newtonsoft.Json" Version="*" />
<PackageReference Include="Steamworks.NET" Version="*" />
</ItemGroup>
</Project>
26 changes: 23 additions & 3 deletions src/Models/SteamService.cs
Original file line number Diff line number Diff line change
@@ -1,10 +1,7 @@

using CounterStrikeSharp.API;
using CounterStrikeSharp.API.Core;
using KitsuneSteamRestrict;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json.Linq;
using Steamworks;

public class SteamUserInfo
{
Expand Down Expand Up @@ -39,6 +36,7 @@ public SteamService(SteamRestrictPlugin plugin, SteamUserInfo userInfo)

public async Task FetchSteamUserInfo(string steamId)
{
//UserInfo.HasPrime = await FetchHasPrimeAsync(steamId);
UserInfo!.CS2Playtime = await FetchCS2PlaytimeAsync(steamId) / 60;
UserInfo.SteamLevel = await FetchSteamLevelAsync(steamId);
await FetchProfilePrivacyAsync(steamId, UserInfo);
Expand Down Expand Up @@ -174,4 +172,26 @@ private void ParseVACBanStatus(string json, SteamUserInfo userInfo)
JToken? userGameBan = data["players"]?.FirstOrDefault();
userInfo.IsVACBanned = userGameBan != null && (bool)(userGameBan["VACBanned"] ?? false);
}

/*
! This method is not used in the current implementation due to the people who bought Prime after
! the CS2 release are not visible as Prime users. This method is kept here for reference if its gonna
! be used in the future, whenever Volvo decides to fix their API.
private async Task<bool> FetchHasPrimeAsync(string steamId)
{
var url = $"https://api.steampowered.com/IPlayerService/GetOwnedGames/v1/?key={_steamWebAPIKey}&steamid={steamId}&include_appinfo=false&include_played_free_games=true&format=json";
var json = await GetApiResponseAsync(url);
if (json != null)
{
JObject data = JObject.Parse(json);
var games = data["response"]?["games"];
if (games != null)
{
_logger.LogInformation($"Prime: {games.Any(game => game["appid"]?.Value<int>() == 624820 || game["appid"]?.Value<int>() == 54029)}");
return games.Any(game => game["appid"]?.Value<int>() == 624820 || game["appid"]?.Value<int>() == 54029);
}
}
return false;
}*/
}

0 comments on commit 3dc88a2

Please sign in to comment.