Skip to content

Commit 5fe8816

Browse files
committed
Enable shared-server VIP data [build]
Introduce a ShareServerId setting and EffectiveServerId to allow sharing VIP data across all servers. ConfigModels gains ShareServerId; ServerIdentifier exposes EffectiveServerId (null when sharing enabled) and logs when active. IUserRepository and UserRepository methods were changed to accept nullable serverId and now treat null as a global (no-server-filter) query/update; GetAllUsers falls back to GetAllAsync when serverId is null. VipService and ManageMenuService now use EffectiveServerId so VIP operations respect the shared-server mode. Also add a local NuGet package source and update the VIPCore.Contract.dll binary.
1 parent f61adf7 commit 5fe8816

7 files changed

Lines changed: 75 additions & 33 deletions

File tree

NuGet.config

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
<configuration>
33
<packageSources>
44
<clear />
5+
<add key="local" value="nupkgs" />
56
<add key="nuget.org" value="https://api.nuget.org/v3/index.json" protocolVersion="3" />
67
</packageSources>
78
</configuration>
0 Bytes
Binary file not shown.

VIPCore/src/Config/ConfigModels.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ public class VipConfig
88
public int TimeMode { get; set; } = 0;
99
public bool VipLogging { get; set; } = true;
1010
public int? ServerId { get; set; } = null;
11+
public bool ShareServerId { get; set; } = false;
1112
public bool FreezeMenu { get; set; } = false;
1213
public bool FreezeAdminMenu { get; set; } = false;
1314
}

VIPCore/src/Database/Repositories/UserRepository.cs

Lines changed: 59 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,13 @@ namespace VIPCore.Database.Repositories;
99

1010
public interface IUserRepository
1111
{
12-
Task<User?> GetUserAsync(long accountId, long serverId);
13-
Task<IEnumerable<User>> GetUserGroupsAsync(long accountId, long serverId);
14-
Task<IEnumerable<User>> GetExpiredUsersAsync(long serverId, long currentTime);
12+
Task<User?> GetUserAsync(long accountId, long? serverId);
13+
Task<IEnumerable<User>> GetUserGroupsAsync(long accountId, long? serverId);
14+
Task<IEnumerable<User>> GetExpiredUsersAsync(long? serverId, long currentTime);
1515
Task AddUserAsync(User user);
1616
Task UpdateUserAsync(User user);
17-
Task DeleteUserAsync(long accountId, long serverId);
18-
Task DeleteUserGroupAsync(long accountId, long serverId, string group);
17+
Task DeleteUserAsync(long accountId, long? serverId);
18+
Task DeleteUserGroupAsync(long accountId, long? serverId, string group);
1919
Task<bool> ServerExistsAsync(string ip, int port);
2020
Task AddServerAsync(VipServer server);
2121
Task<long> GetServerIdAsync(string ip, int port);
@@ -26,7 +26,7 @@ public interface IUserRepository
2626
Task<bool> TryMoveServerIdAsync(long fromServerId, long toServerId);
2727
Task<bool> TryInsertServerWithIdAsync(VipServer server);
2828
Task ClearGuidFromOtherServersAsync(string guid, long keepServerId);
29-
Task<IEnumerable<User>> GetAllUsersAsync(long serverId);
29+
Task<IEnumerable<User>> GetAllUsersAsync(long? serverId);
3030
}
3131

3232
public class UserRepository(DatabaseConnectionFactory connectionFactory) : IUserRepository
@@ -41,25 +41,37 @@ private static bool IsDuplicateKeyException(Exception ex)
4141
|| msg.Contains("UNIQUE constraint failed", StringComparison.OrdinalIgnoreCase);
4242
}
4343

44-
public async Task<User?> GetUserAsync(long accountId, long serverId)
44+
public async Task<User?> GetUserAsync(long accountId, long? serverId)
4545
{
4646
using var db = connectionFactory.CreateConnection();
47-
var users = await db.SelectAsync<User>(u => u.account_id == accountId && u.sid == serverId);
48-
return users.FirstOrDefault();
47+
if (serverId.HasValue)
48+
{
49+
var users = await db.SelectAsync<User>(u => u.account_id == accountId && u.sid == serverId.Value);
50+
return users.FirstOrDefault();
51+
}
52+
return (await db.SelectAsync<User>(u => u.account_id == accountId)).FirstOrDefault();
4953
}
5054

51-
public async Task<IEnumerable<User>> GetUserGroupsAsync(long accountId, long serverId)
55+
public async Task<IEnumerable<User>> GetUserGroupsAsync(long accountId, long? serverId)
5256
{
5357
using var db = connectionFactory.CreateConnection();
54-
var users = await db.SelectAsync<User>(u => u.account_id == accountId && u.sid == serverId);
55-
return users.ToList();
58+
if (serverId.HasValue)
59+
{
60+
var users = await db.SelectAsync<User>(u => u.account_id == accountId && u.sid == serverId.Value);
61+
return users.ToList();
62+
}
63+
return (await db.SelectAsync<User>(u => u.account_id == accountId)).ToList();
5664
}
5765

58-
public async Task<IEnumerable<User>> GetExpiredUsersAsync(long serverId, long currentTime)
66+
public async Task<IEnumerable<User>> GetExpiredUsersAsync(long? serverId, long currentTime)
5967
{
6068
using var db = connectionFactory.CreateConnection();
61-
var users = await db.SelectAsync<User>(u => u.sid == serverId && u.expires < currentTime && u.expires > 0);
62-
return users.ToList();
69+
if (serverId.HasValue)
70+
{
71+
var users = await db.SelectAsync<User>(u => u.sid == serverId.Value && u.expires < currentTime && u.expires > 0);
72+
return users.ToList();
73+
}
74+
return (await db.SelectAsync<User>(u => u.expires < currentTime && u.expires > 0)).ToList();
6375
}
6476

6577
public async Task AddUserAsync(User user)
@@ -81,19 +93,37 @@ public async Task UpdateUserAsync(User user)
8193
await db.UpdateAsync(user);
8294
}
8395

84-
public async Task DeleteUserAsync(long accountId, long serverId)
96+
public async Task DeleteUserAsync(long accountId, long? serverId)
8597
{
8698
using var db = connectionFactory.CreateConnection();
87-
var groups = await db.SelectAsync<User>(u => u.account_id == accountId && u.sid == serverId);
88-
foreach (var user in groups)
89-
await db.DeleteAsync(user);
99+
if (serverId.HasValue)
100+
{
101+
var groups = await db.SelectAsync<User>(u => u.account_id == accountId && u.sid == serverId.Value);
102+
foreach (var user in groups)
103+
await db.DeleteAsync(user);
104+
}
105+
else
106+
{
107+
var groups = await db.SelectAsync<User>(u => u.account_id == accountId);
108+
foreach (var user in groups)
109+
await db.DeleteAsync(user);
110+
}
90111
}
91112

92-
public async Task DeleteUserGroupAsync(long accountId, long serverId, string group)
113+
public async Task DeleteUserGroupAsync(long accountId, long? serverId, string group)
93114
{
94115
using var db = connectionFactory.CreateConnection();
95-
var user = new User { account_id = accountId, sid = serverId, group = group, name = string.Empty };
96-
await db.DeleteAsync(user);
116+
if (serverId.HasValue)
117+
{
118+
var user = new User { account_id = accountId, sid = serverId.Value, group = group, name = string.Empty };
119+
await db.DeleteAsync(user);
120+
}
121+
else
122+
{
123+
var users = await db.SelectAsync<User>(u => u.account_id == accountId && u.group == group);
124+
foreach (var user in users)
125+
await db.DeleteAsync(user);
126+
}
97127
}
98128

99129
public async Task<bool> ServerExistsAsync(string ip, int port)
@@ -187,10 +217,14 @@ await db.ExecuteAsync(
187217
new { Guid = guid, KeepId = keepServerId });
188218
}
189219

190-
public async Task<IEnumerable<User>> GetAllUsersAsync(long serverId)
220+
public async Task<IEnumerable<User>> GetAllUsersAsync(long? serverId)
191221
{
192222
using var db = connectionFactory.CreateConnection();
193-
var users = await db.SelectAsync<User>(u => u.sid == serverId);
194-
return users.ToList();
223+
if (serverId.HasValue)
224+
{
225+
var users = await db.SelectAsync<User>(u => u.sid == serverId.Value);
226+
return users.ToList();
227+
}
228+
return (await db.GetAllAsync<User>()).ToList();
195229
}
196230
}

VIPCore/src/Services/ManageMenuService.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ public void OpenManageMenu(IPlayer admin)
6262
{
6363
try
6464
{
65-
var users = await userRepository.GetAllUsersAsync(serverIdentifier.ServerId);
65+
var users = await userRepository.GetAllUsersAsync(serverIdentifier.EffectiveServerId);
6666
var userList = users.ToList();
6767
core.Scheduler.NextTick(() => OpenManageGroupsMenu(args.Player, userList));
6868
}

VIPCore/src/Services/ServerIdentifier.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ public class ServerIdentifier
2424
private string _serverGuid = string.Empty;
2525

2626
public long ServerId => _serverId;
27+
public long? EffectiveServerId => _coreConfigMonitor.CurrentValue.ShareServerId ? null : _serverId;
2728
public string? ServerIp => _serverIp;
2829
public int ServerPort => _serverPort;
2930
public bool IsInitialized => _initialized;
@@ -47,6 +48,11 @@ public async Task InitializeAsync()
4748
_core.Logger.LogInformation("[VIPCore] Server identified using configured ID {ServerId}.", configuredServerId.Value);
4849
}
4950

51+
if (_coreConfigMonitor.CurrentValue.ShareServerId)
52+
{
53+
_core.Logger.LogInformation("[VIPCore] ShareServerId is enabled — VIP data is shared across all servers (server ID filter skipped).");
54+
}
55+
5056
if (string.IsNullOrWhiteSpace(_core.PluginDataDirectory))
5157
{
5258
_core.Logger.LogError("[VIPCore] Cannot initialize server GUID: PluginDataDirectory is empty.");

VIPCore/src/Services/VipService.cs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -59,11 +59,11 @@ public async Task LoadPlayer(IPlayer player)
5959
var steamId64 = (long)player.SteamID;
6060
var accountId = NormalizeToAccountId(steamId64);
6161

62-
var allGroups = (await userRepository.GetUserGroupsAsync(steamId64, serverIdentifier.ServerId)).ToList();
62+
var allGroups = (await userRepository.GetUserGroupsAsync(steamId64, serverIdentifier.EffectiveServerId)).ToList();
6363

6464
// Also try the AccountID form in case VIP was added with the short Steam AccountID
6565
if (allGroups.Count == 0 && accountId != steamId64)
66-
allGroups = (await userRepository.GetUserGroupsAsync(accountId, serverIdentifier.ServerId)).ToList();
66+
allGroups = (await userRepository.GetUserGroupsAsync(accountId, serverIdentifier.EffectiveServerId)).ToList();
6767

6868
if (allGroups.Count == 0) return null;
6969

@@ -231,7 +231,7 @@ private void InitializeFeaturesForUser(VipUser user)
231231
public async Task AddVip(long accountId, string name, string group, int time)
232232
{
233233
accountId = NormalizeToAccountId(accountId);
234-
var existingUser = await userRepository.GetUserAsync(accountId, serverIdentifier.ServerId);
234+
var existingUser = await userRepository.GetUserAsync(accountId, serverIdentifier.EffectiveServerId);
235235
long expires;
236236

237237
if (time <= 0)
@@ -270,9 +270,9 @@ public async Task RemoveVip(long accountId)
270270
var normalized = NormalizeToAccountId(accountId);
271271
var steamId64 = ToSteamId64(accountId);
272272

273-
await userRepository.DeleteUserAsync(normalized, serverIdentifier.ServerId);
273+
await userRepository.DeleteUserAsync(normalized, serverIdentifier.EffectiveServerId);
274274
if (steamId64 != normalized)
275-
await userRepository.DeleteUserAsync(steamId64, serverIdentifier.ServerId);
275+
await userRepository.DeleteUserAsync(steamId64, serverIdentifier.EffectiveServerId);
276276

277277
_users.TryRemove((ulong)steamId64, out _);
278278
_users.TryRemove((ulong)normalized, out _);
@@ -283,9 +283,9 @@ public async Task RemoveVipGroup(long accountId, string group)
283283
var normalized = NormalizeToAccountId(accountId);
284284
var steamId64 = ToSteamId64(accountId);
285285

286-
await userRepository.DeleteUserGroupAsync(normalized, serverIdentifier.ServerId, group);
286+
await userRepository.DeleteUserGroupAsync(normalized, serverIdentifier.EffectiveServerId, group);
287287
if (steamId64 != normalized)
288-
await userRepository.DeleteUserGroupAsync(steamId64, serverIdentifier.ServerId, group);
288+
await userRepository.DeleteUserGroupAsync(steamId64, serverIdentifier.EffectiveServerId, group);
289289
}
290290

291291
public void InitializeFeatureForLoadedPlayers(string featureKey)

0 commit comments

Comments
 (0)