Simple sponsorship system (#1189)
* simple sponsorship system * priority Join * OOC Sponsor Color * Update CP14SponsorRolePrototype.cs * loadout sponsorship * bruh * refactor to interfaces * Update CP14ClientSponsorManager.cs * finish loadout option * role pass
This commit is contained in:
@@ -24,6 +24,7 @@ using Content.Client.Singularity;
|
||||
using Content.Client.Stylesheets;
|
||||
using Content.Client.Viewport;
|
||||
using Content.Client.Voting;
|
||||
using Content.Shared._CP14.Sponsor;
|
||||
using Content.Shared.Ame.Components;
|
||||
using Content.Shared.CCVar;
|
||||
using Content.Shared.Gravity;
|
||||
@@ -48,6 +49,7 @@ namespace Content.Client.Entry
|
||||
//CP14
|
||||
[Dependency] private readonly DiscordAuthManager _discordAuth = default!;
|
||||
[Dependency] private readonly JoinQueueManager _joinQueueManager = default!;
|
||||
[Dependency] private readonly ICP14SponsorManager _sponsorManager = default!;
|
||||
//CP14 end
|
||||
[Dependency] private readonly IBaseClient _baseClient = default!;
|
||||
[Dependency] private readonly IGameController _gameController = default!;
|
||||
@@ -170,6 +172,7 @@ namespace Content.Client.Entry
|
||||
_overlayManager.AddOverlay(new CP14BasePostProcessOverlay());
|
||||
_discordAuth.Initialize();
|
||||
_joinQueueManager.Initialize();
|
||||
_sponsorManager.Initialize();
|
||||
//CP14 end
|
||||
_overlayManager.AddOverlay(new SingularityOverlay());
|
||||
_overlayManager.AddOverlay(new RadiationPulseOverlay());
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using Content.Client._CP14.Discord;
|
||||
using Content.Client._CP14.JoinQueue;
|
||||
using Content.Client._CP14.Sponsor;
|
||||
using Content.Client.Administration.Managers;
|
||||
using Content.Client.Changelog;
|
||||
using Content.Client.Chat.Managers;
|
||||
@@ -22,6 +23,7 @@ using Content.Client.Voting;
|
||||
using Content.Shared.Administration.Logs;
|
||||
using Content.Client.Lobby;
|
||||
using Content.Client.Players.RateLimiting;
|
||||
using Content.Shared._CP14.Sponsor;
|
||||
using Content.Shared.Administration.Managers;
|
||||
using Content.Shared.Chat;
|
||||
using Content.Shared.Players.PlayTimeTracking;
|
||||
@@ -38,6 +40,7 @@ namespace Content.Client.IoC
|
||||
//CP14
|
||||
collection.Register<DiscordAuthManager>();
|
||||
collection.Register<JoinQueueManager>();
|
||||
collection.Register<ICP14SponsorManager, ClientSponsorSystem>();
|
||||
//CP14 end
|
||||
collection.Register<IParallaxManager, ParallaxManager>();
|
||||
collection.Register<IChatManager, ChatManager>();
|
||||
|
||||
@@ -126,7 +126,8 @@ public sealed class JobRequirementsManager : ISharedPlaytimeManager
|
||||
var reasons = new List<string>();
|
||||
foreach (var requirement in requirements)
|
||||
{
|
||||
if (requirement.Check(_entManager, _prototypes, profile, _roles, out var jobReason))
|
||||
//CP14 Add NetUserId for sponsorship checks
|
||||
if (requirement.Check(_playerManager.LocalSession?.UserId, _entManager, _prototypes, profile, _roles, out var jobReason))
|
||||
continue;
|
||||
|
||||
reasons.Add(jobReason.ToMarkup());
|
||||
|
||||
49
Content.Client/_CP14/Sponsor/CP14ClientSponsorManager.cs
Normal file
49
Content.Client/_CP14/Sponsor/CP14ClientSponsorManager.cs
Normal file
@@ -0,0 +1,49 @@
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using Content.Shared._CP14.Sponsor;
|
||||
using Robust.Shared.Network;
|
||||
using Robust.Shared.Prototypes;
|
||||
|
||||
namespace Content.Client._CP14.Sponsor;
|
||||
|
||||
public sealed class ClientSponsorSystem : ICP14SponsorManager
|
||||
{
|
||||
[Dependency] private readonly IPrototypeManager _proto = default!;
|
||||
[Dependency] private readonly IClientNetManager _net = default!;
|
||||
|
||||
private CP14SponsorRolePrototype? _sponsorRole;
|
||||
|
||||
public void Initialize()
|
||||
{
|
||||
_net.RegisterNetMessage<CP14SponsorRoleUpdate>(OnSponsorRoleUpdate);
|
||||
_net.Disconnect += NetOnDisconnected;
|
||||
}
|
||||
|
||||
private void NetOnDisconnected(object? sender, NetDisconnectedArgs e)
|
||||
{
|
||||
_sponsorRole = null;
|
||||
}
|
||||
|
||||
private void OnSponsorRoleUpdate(CP14SponsorRoleUpdate msg)
|
||||
{
|
||||
if (!_proto.TryIndex(msg.Role, out var indexedRole))
|
||||
return;
|
||||
|
||||
_sponsorRole = indexedRole;
|
||||
}
|
||||
|
||||
public bool TryGetSponsorOOCColor(NetUserId userId, [NotNullWhen(true)] out Color? color)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public bool UserHasFeature(NetUserId userId, ProtoId<CP14SponsorFeaturePrototype> feature, bool ifDisabledSponsorhip = true)
|
||||
{
|
||||
if (_sponsorRole is null)
|
||||
return false;
|
||||
|
||||
if (!_proto.TryIndex(feature, out var indexedFeature))
|
||||
return false;
|
||||
|
||||
return _sponsorRole.Priority >= indexedFeature.MinPriority;
|
||||
}
|
||||
}
|
||||
@@ -7,6 +7,7 @@ using Content.Server.Administration.Systems;
|
||||
using Content.Server.MoMMI;
|
||||
using Content.Server.Players.RateLimiting;
|
||||
using Content.Server.Preferences.Managers;
|
||||
using Content.Shared._CP14.Sponsor;
|
||||
using Content.Shared.Administration;
|
||||
using Content.Shared.CCVar;
|
||||
using Content.Shared.Chat;
|
||||
@@ -44,6 +45,7 @@ internal sealed partial class ChatManager : IChatManager
|
||||
[Dependency] private readonly INetConfigurationManager _netConfigManager = default!;
|
||||
[Dependency] private readonly IEntityManager _entityManager = default!;
|
||||
[Dependency] private readonly PlayerRateLimitManager _rateLimitManager = default!;
|
||||
[Dependency] private readonly ICP14SponsorManager _sponsor = default!; //CP14 OCC color
|
||||
|
||||
/// <summary>
|
||||
/// The maximum length a player-sent message can be sent
|
||||
@@ -256,6 +258,12 @@ internal sealed partial class ChatManager : IChatManager
|
||||
{
|
||||
wrappedMessage = Loc.GetString("chat-manager-send-ooc-patron-wrap-message", ("patronColor", patronColor),("playerName", player.Name), ("message", FormattedMessage.EscapeText(message)));
|
||||
}
|
||||
//CP14 Sponsor OOC Color
|
||||
if (_sponsor.TryGetSponsorOOCColor(player.UserId, out var oocColor))
|
||||
{
|
||||
wrappedMessage = Loc.GetString("chat-manager-send-ooc-patron-wrap-message", ("patronColor", oocColor),("playerName", player.Name), ("message", FormattedMessage.EscapeText(message)));
|
||||
}
|
||||
//CP14 Sponsor OOC Color end
|
||||
|
||||
//TODO: player.Name color, this will need to change the structure of the MsgChatMessage
|
||||
ChatMessageToAll(ChatChannel.OOC, message, wrappedMessage, EntityUid.Invalid, hideChat: false, recordReplay: true, colorOverride: colorOverride, author: player.UserId);
|
||||
|
||||
@@ -2,12 +2,14 @@ using System.Collections.Immutable;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using System.Runtime.InteropServices;
|
||||
using Content.Server._CP14.Sponsor;
|
||||
using Content.Server.Administration.Managers;
|
||||
using Content.Server.Chat.Managers;
|
||||
using Content.Server.Connection.IPIntel;
|
||||
using Content.Server.Database;
|
||||
using Content.Server.GameTicking;
|
||||
using Content.Server.Preferences.Managers;
|
||||
using Content.Shared._CP14.Sponsor;
|
||||
using Content.Shared.CCVar;
|
||||
using Content.Shared.GameTicking;
|
||||
using Content.Shared.Players.PlayTimeTracking;
|
||||
@@ -64,6 +66,7 @@ namespace Content.Server.Connection
|
||||
[Dependency] private readonly IChatManager _chatManager = default!;
|
||||
[Dependency] private readonly IHttpClientHolder _http = default!;
|
||||
[Dependency] private readonly IAdminManager _adminManager = default!;
|
||||
[Dependency] private readonly ICP14SponsorManager _sponsor = default!; //CP14 Priority Join
|
||||
|
||||
private ISawmill _sawmill = default!;
|
||||
private readonly Dictionary<NetUserId, TimeSpan> _temporaryBypasses = [];
|
||||
@@ -375,11 +378,11 @@ namespace Content.Server.Connection
|
||||
public async Task<bool> HavePrivilegedJoin(NetUserId userId)
|
||||
{
|
||||
var adminBypass = _cfg.GetCVar(CCVars.AdminBypassMaxPlayers) && await _db.GetAdminDataForAsync(userId) != null;
|
||||
//var havePriorityJoin = _sponsors
|
||||
var havePriorityJoin = _sponsor.UserHasFeature(userId, "PriorityJoin", false);
|
||||
var wasInGame = EntitySystem.TryGet<GameTicker>(out var ticker) &&
|
||||
ticker.PlayerGameStatuses.TryGetValue(userId, out var status) &&
|
||||
status == PlayerGameStatus.JoinedGame;
|
||||
return adminBypass || wasInGame;
|
||||
return adminBypass || wasInGame || havePriorityJoin;
|
||||
}
|
||||
//CP14 Join Queue end
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using Content.Server._CP14.Discord;
|
||||
using Content.Server._CP14.JoinQueue;
|
||||
using Content.Server._CP14.Sponsor;
|
||||
using Content.Server.Acz;
|
||||
using Content.Server.Administration;
|
||||
using Content.Server.Administration.Logs;
|
||||
@@ -25,6 +26,7 @@ using Content.Server.Preferences.Managers;
|
||||
using Content.Server.ServerInfo;
|
||||
using Content.Server.ServerUpdates;
|
||||
using Content.Server.Voting.Managers;
|
||||
using Content.Shared._CP14.Sponsor;
|
||||
using Content.Shared.CCVar;
|
||||
using Content.Shared.Kitchen;
|
||||
using Content.Shared.Localizations;
|
||||
@@ -106,6 +108,7 @@ namespace Content.Server.Entry
|
||||
//CP14
|
||||
IoCManager.Resolve<DiscordAuthManager>().Initialize();
|
||||
IoCManager.Resolve<JoinQueueManager>().Initialize();
|
||||
IoCManager.Resolve<ICP14SponsorManager>().Initialize();
|
||||
//CP14 end
|
||||
|
||||
IoCManager.Resolve<IAdminLogManager>().Initialize();
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using Content.Server._CP14.Discord;
|
||||
using Content.Server._CP14.JoinQueue;
|
||||
using Content.Server._CP14.Sponsor;
|
||||
using Content.Server.Administration;
|
||||
using Content.Server.Administration.Logs;
|
||||
using Content.Server.Administration.Managers;
|
||||
@@ -25,6 +26,7 @@ using Content.Server.ServerInfo;
|
||||
using Content.Server.ServerUpdates;
|
||||
using Content.Server.Voting.Managers;
|
||||
using Content.Server.Worldgen.Tools;
|
||||
using Content.Shared._CP14.Sponsor;
|
||||
using Content.Shared.Administration.Logs;
|
||||
using Content.Shared.Administration.Managers;
|
||||
using Content.Shared.Chat;
|
||||
@@ -41,6 +43,7 @@ namespace Content.Server.IoC
|
||||
//CP14
|
||||
IoCManager.Register<DiscordAuthManager>();
|
||||
IoCManager.Register<JoinQueueManager>();
|
||||
IoCManager.Register<ICP14SponsorManager, SponsorSystem>();
|
||||
//CP14 end
|
||||
IoCManager.Register<IChatManager, ChatManager>();
|
||||
IoCManager.Register<ISharedChatManager, ChatManager>();
|
||||
|
||||
@@ -201,7 +201,7 @@ public sealed class PlayTimeTrackingSystem : EntitySystem
|
||||
playTimes = new Dictionary<string, TimeSpan>();
|
||||
}
|
||||
|
||||
return JobRequirements.TryRequirementsMet(job, playTimes, out _, EntityManager, _prototypes, (HumanoidCharacterProfile?) _preferencesManager.GetPreferences(player.UserId).SelectedCharacter);
|
||||
return JobRequirements.TryRequirementsMet(player.UserId, job, playTimes, out _, EntityManager, _prototypes, (HumanoidCharacterProfile?) _preferencesManager.GetPreferences(player.UserId).SelectedCharacter); //CP14 add NetUserId for sponsorship checks
|
||||
}
|
||||
|
||||
public HashSet<ProtoId<JobPrototype>> GetDisallowedJobs(ICommonSession player)
|
||||
@@ -218,7 +218,7 @@ public sealed class PlayTimeTrackingSystem : EntitySystem
|
||||
|
||||
foreach (var job in _prototypes.EnumeratePrototypes<JobPrototype>())
|
||||
{
|
||||
if (JobRequirements.TryRequirementsMet(job, playTimes, out _, EntityManager, _prototypes, (HumanoidCharacterProfile?) _preferencesManager.GetPreferences(player.UserId).SelectedCharacter))
|
||||
if (JobRequirements.TryRequirementsMet(player.UserId, job, playTimes, out _, EntityManager, _prototypes, (HumanoidCharacterProfile?) _preferencesManager.GetPreferences(player.UserId).SelectedCharacter)) //CP14 add NetUserId for sponsorship checks
|
||||
roles.Add(job.ID);
|
||||
}
|
||||
|
||||
@@ -241,7 +241,7 @@ public sealed class PlayTimeTrackingSystem : EntitySystem
|
||||
for (var i = 0; i < jobs.Count; i++)
|
||||
{
|
||||
if (_prototypes.TryIndex(jobs[i], out var job)
|
||||
&& JobRequirements.TryRequirementsMet(job, playTimes, out _, EntityManager, _prototypes, (HumanoidCharacterProfile?) _preferencesManager.GetPreferences(userId).SelectedCharacter))
|
||||
&& JobRequirements.TryRequirementsMet(userId, job, playTimes, out _, EntityManager, _prototypes, (HumanoidCharacterProfile?) _preferencesManager.GetPreferences(userId).SelectedCharacter)) //CP14 add NetUserId for sponsorship checks
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -30,11 +30,10 @@ public sealed class DiscordAuthManager
|
||||
private string _apiUrl = string.Empty;
|
||||
private string _apiKey = string.Empty;
|
||||
|
||||
private string _discordGuild = "1221923073759121468"; //CrystallEdge server required
|
||||
public const string DISCORD_GUILD = "1221923073759121468"; //CrystallEdge server required
|
||||
|
||||
private HashSet<string> _blockedGuilds = new()
|
||||
{
|
||||
"1361786483073093673", //Testing one
|
||||
"1346922008000204891",
|
||||
"1186566619858731038",
|
||||
"1355279097906855968",
|
||||
@@ -137,7 +136,6 @@ public sealed class DiscordAuthManager
|
||||
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", _apiKey);
|
||||
|
||||
var response = await _httpClient.SendAsync(request, cancel);
|
||||
_sawmill.Debug($"Guilds response: {await response.Content.ReadAsStringAsync(cancel)}");
|
||||
_sawmill.Debug($"(int) response.StatusCode: {(int)response.StatusCode}");
|
||||
if (!response.IsSuccessStatusCode)
|
||||
{
|
||||
@@ -161,9 +159,9 @@ public sealed class DiscordAuthManager
|
||||
}
|
||||
}
|
||||
|
||||
if (guilds.Guilds.All(guild => guild.Id != _discordGuild))
|
||||
if (guilds.Guilds.All(guild => guild.Id != DISCORD_GUILD))
|
||||
{
|
||||
_sawmill.Debug($"Player {userId} is not in required guild {_discordGuild}");
|
||||
_sawmill.Debug($"Player {userId} is not in required guild {DISCORD_GUILD}");
|
||||
return new AuthData { Verified = false, ErrorMessage = "You are not a member of the CrystallEdge server." };
|
||||
}
|
||||
|
||||
|
||||
@@ -40,7 +40,6 @@ public sealed class JoinQueueManager
|
||||
[Dependency] private readonly IConfigurationManager _cfg = default!;
|
||||
[Dependency] private readonly IServerNetManager _netManager = default!;
|
||||
[Dependency] private readonly DiscordAuthManager _discordAuthManager = default!;
|
||||
//[Dependency] private readonly SponsorsManager _sponsors = default!;
|
||||
private ISawmill _sawmill = default!;
|
||||
|
||||
/// <summary>
|
||||
|
||||
156
Content.Server/_CP14/Sponsor/CP14SponsorManager.cs
Normal file
156
Content.Server/_CP14/Sponsor/CP14SponsorManager.cs
Normal file
@@ -0,0 +1,156 @@
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Linq;
|
||||
using System.Net.Http;
|
||||
using System.Net.Http.Headers;
|
||||
using System.Net.Http.Json;
|
||||
using System.Text.Json.Serialization;
|
||||
using System.Threading.Tasks;
|
||||
using Content.Server._CP14.Discord;
|
||||
using Content.Shared._CP14.Sponsor;
|
||||
using Content.Shared.CCVar;
|
||||
using Robust.Shared.Configuration;
|
||||
using Robust.Shared.Network;
|
||||
using Robust.Shared.Player;
|
||||
using Robust.Shared.Prototypes;
|
||||
|
||||
namespace Content.Server._CP14.Sponsor;
|
||||
|
||||
public sealed class SponsorSystem : ICP14SponsorManager
|
||||
{
|
||||
[Dependency] private readonly IPrototypeManager _proto = default!;
|
||||
[Dependency] private readonly IConfigurationManager _cfg = default!;
|
||||
[Dependency] private readonly DiscordAuthManager _discordAuthManager = default!;
|
||||
[Dependency] private readonly INetManager _netMgr = default!;
|
||||
[Dependency] private readonly IServerNetManager _netManager = default!;
|
||||
|
||||
private readonly HttpClient _httpClient = new();
|
||||
private string _apiUrl = string.Empty;
|
||||
private string _apiKey = string.Empty;
|
||||
private bool _enabled;
|
||||
|
||||
private ISawmill _sawmill = null!;
|
||||
|
||||
private Dictionary<NetUserId, CP14SponsorRolePrototype> _cachedSponsors = new();
|
||||
|
||||
public void Initialize()
|
||||
{
|
||||
_sawmill = Logger.GetSawmill("sponsors");
|
||||
|
||||
_netManager.RegisterNetMessage<CP14SponsorRoleUpdate>();
|
||||
|
||||
_cfg.OnValueChanged(CCVars.SponsorsEnabled, val => { _enabled = val; }, true);
|
||||
_cfg.OnValueChanged(CCVars.SponsorsApiUrl, val => { _apiUrl = val; }, true);
|
||||
_cfg.OnValueChanged(CCVars.SponsorsApiKey, val => { _apiKey = val; }, true);
|
||||
|
||||
_discordAuthManager.PlayerVerified += async (_, e) =>
|
||||
{
|
||||
await OnPlayerVerified(e);
|
||||
};
|
||||
|
||||
_netMgr.Disconnect += OnDisconnect;
|
||||
|
||||
_httpClient.DefaultRequestHeaders.Authorization =
|
||||
new AuthenticationHeaderValue("Bearer", _apiKey);
|
||||
}
|
||||
|
||||
private async Task<List<string>?> GetRoles(NetUserId userId)
|
||||
{
|
||||
var requestUrl = $"{_apiUrl}/api/roles?method=uid&id={userId}&guildId={DiscordAuthManager.DISCORD_GUILD}";
|
||||
var response = await _httpClient.GetAsync(requestUrl);
|
||||
|
||||
if (!response.IsSuccessStatusCode)
|
||||
{
|
||||
_sawmill.Error($"Failed to retrieve roles for user {userId}: {response.StatusCode}");
|
||||
return null;
|
||||
}
|
||||
|
||||
var responseContent = await response.Content.ReadFromJsonAsync<RolesResponse>();
|
||||
|
||||
if (responseContent is not null)
|
||||
{
|
||||
return responseContent.Roles.ToList();
|
||||
}
|
||||
|
||||
_sawmill.Error($"Roles not found in response for user {userId}");
|
||||
return null;
|
||||
}
|
||||
|
||||
private async Task OnPlayerVerified(ICommonSession e)
|
||||
{
|
||||
if (!_enabled)
|
||||
return;
|
||||
|
||||
var roles = await GetRoles(e.UserId);
|
||||
if (roles is null)
|
||||
return;
|
||||
|
||||
CP14SponsorRolePrototype? targetRole = null;
|
||||
foreach (var role in _proto.EnumeratePrototypes<CP14SponsorRolePrototype>())
|
||||
{
|
||||
if (!roles.Contains(role.DiscordRoleId))
|
||||
continue;
|
||||
|
||||
if (targetRole is null || role.Priority > targetRole.Priority)
|
||||
{
|
||||
targetRole = role;
|
||||
}
|
||||
}
|
||||
|
||||
if (targetRole is not null)
|
||||
_cachedSponsors[e.UserId] = targetRole;
|
||||
|
||||
if (_cachedSponsors.TryGetValue(e.UserId, out var cachedRole))
|
||||
{
|
||||
e.Channel.SendMessage(new CP14SponsorRoleUpdate
|
||||
{
|
||||
Role = cachedRole,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private void OnDisconnect(object? sender, NetDisconnectedArgs e)
|
||||
{
|
||||
//Remove cached roles
|
||||
if (_cachedSponsors.ContainsKey(e.Channel.UserId))
|
||||
{
|
||||
_cachedSponsors.Remove(e.Channel.UserId);
|
||||
}
|
||||
}
|
||||
|
||||
public bool UserHasFeature(NetUserId userId,
|
||||
ProtoId<CP14SponsorFeaturePrototype> feature,
|
||||
bool ifDisabledSponsorhip = true)
|
||||
{
|
||||
if (!_enabled)
|
||||
return ifDisabledSponsorhip;
|
||||
|
||||
if (!_proto.TryIndex(feature, out var indexedFeature))
|
||||
return false;
|
||||
|
||||
if (!_cachedSponsors.TryGetValue(userId, out var userRoles))
|
||||
return false;
|
||||
|
||||
return _cachedSponsors[userId].Priority >= indexedFeature.MinPriority;
|
||||
}
|
||||
|
||||
public bool TryGetSponsorOOCColor(NetUserId userId, [NotNullWhen(true)] out Color? color)
|
||||
{
|
||||
color = null;
|
||||
|
||||
if (!_enabled)
|
||||
return false;
|
||||
|
||||
if (!_cachedSponsors.TryGetValue(userId, out var sponsorRole))
|
||||
return false;
|
||||
|
||||
color = sponsorRole.Color;
|
||||
|
||||
return color is not null;
|
||||
}
|
||||
|
||||
private sealed class RolesResponse
|
||||
{
|
||||
[JsonPropertyName("roles")]
|
||||
public string[] Roles { get; set; } = [];
|
||||
}
|
||||
}
|
||||
@@ -25,7 +25,9 @@ public sealed partial class JobRequirementLoadoutEffect : LoadoutEffect
|
||||
|
||||
var manager = collection.Resolve<ISharedPlaytimeManager>();
|
||||
var playtimes = manager.GetPlayTimes(session);
|
||||
return Requirement.Check(collection.Resolve<IEntityManager>(),
|
||||
return Requirement.Check(
|
||||
session.UserId, //CP14 add NetUserId for sponsorship checks
|
||||
collection.Resolve<IEntityManager>(),
|
||||
collection.Resolve<IPrototypeManager>(),
|
||||
profile,
|
||||
playtimes,
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using Content.Shared.Preferences;
|
||||
using JetBrains.Annotations;
|
||||
using Robust.Shared.Network;
|
||||
using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.Serialization;
|
||||
using Robust.Shared.Utility;
|
||||
@@ -17,7 +18,8 @@ public sealed partial class AgeRequirement : JobRequirement
|
||||
[DataField(required: true)]
|
||||
public int RequiredAge;
|
||||
|
||||
public override bool Check(IEntityManager entManager,
|
||||
public override bool Check(NetUserId? userId, //CP14 Sponsorship Checks
|
||||
IEntityManager entManager,
|
||||
IPrototypeManager protoManager,
|
||||
HumanoidCharacterProfile? profile,
|
||||
IReadOnlyDictionary<string, TimeSpan> playTimes,
|
||||
|
||||
@@ -2,6 +2,7 @@ using System.Diagnostics.CodeAnalysis;
|
||||
using Content.Shared.Localizations;
|
||||
using Content.Shared.Preferences;
|
||||
using JetBrains.Annotations;
|
||||
using Robust.Shared.Network;
|
||||
using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.Serialization;
|
||||
using Robust.Shared.Utility;
|
||||
@@ -24,7 +25,8 @@ public sealed partial class DepartmentTimeRequirement : JobRequirement
|
||||
[DataField(required: true)]
|
||||
public TimeSpan Time;
|
||||
|
||||
public override bool Check(IEntityManager entManager,
|
||||
public override bool Check(NetUserId? userId, //CP14 Sponsorship Checks
|
||||
IEntityManager entManager,
|
||||
IPrototypeManager protoManager,
|
||||
HumanoidCharacterProfile? profile,
|
||||
IReadOnlyDictionary<string, TimeSpan> playTimes,
|
||||
|
||||
@@ -3,6 +3,7 @@ using Content.Shared.Localizations;
|
||||
using Content.Shared.Players.PlayTimeTracking;
|
||||
using Content.Shared.Preferences;
|
||||
using JetBrains.Annotations;
|
||||
using Robust.Shared.Network;
|
||||
using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.Serialization;
|
||||
using Robust.Shared.Utility;
|
||||
@@ -17,7 +18,8 @@ public sealed partial class OverallPlaytimeRequirement : JobRequirement
|
||||
[DataField(required: true)]
|
||||
public TimeSpan Time;
|
||||
|
||||
public override bool Check(IEntityManager entManager,
|
||||
public override bool Check(NetUserId? userId, //CP14 Sponsorship Checks
|
||||
IEntityManager entManager,
|
||||
IPrototypeManager protoManager,
|
||||
HumanoidCharacterProfile? profile,
|
||||
IReadOnlyDictionary<string, TimeSpan> playTimes,
|
||||
|
||||
@@ -4,6 +4,7 @@ using Content.Shared.Players.PlayTimeTracking;
|
||||
using Content.Shared.Preferences;
|
||||
using Content.Shared.Roles.Jobs;
|
||||
using JetBrains.Annotations;
|
||||
using Robust.Shared.Network;
|
||||
using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.Serialization;
|
||||
using Robust.Shared.Utility;
|
||||
@@ -24,7 +25,8 @@ public sealed partial class RoleTimeRequirement : JobRequirement
|
||||
[DataField(required: true)]
|
||||
public TimeSpan Time;
|
||||
|
||||
public override bool Check(IEntityManager entManager,
|
||||
public override bool Check(NetUserId? userId, //CP14 Sponsorship Checks
|
||||
IEntityManager entManager,
|
||||
IPrototypeManager protoManager,
|
||||
HumanoidCharacterProfile? profile,
|
||||
IReadOnlyDictionary<string, TimeSpan> playTimes,
|
||||
|
||||
@@ -3,6 +3,7 @@ using System.Text;
|
||||
using Content.Shared.Humanoid.Prototypes;
|
||||
using Content.Shared.Preferences;
|
||||
using JetBrains.Annotations;
|
||||
using Robust.Shared.Network;
|
||||
using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.Serialization;
|
||||
using Robust.Shared.Utility;
|
||||
@@ -19,7 +20,8 @@ public sealed partial class SpeciesRequirement : JobRequirement
|
||||
[DataField(required: true)]
|
||||
public HashSet<ProtoId<SpeciesPrototype>> Species = new();
|
||||
|
||||
public override bool Check(IEntityManager entManager,
|
||||
public override bool Check(NetUserId? userId, //CP14 Sponsorship Checks
|
||||
IEntityManager entManager,
|
||||
IPrototypeManager protoManager,
|
||||
HumanoidCharacterProfile? profile,
|
||||
IReadOnlyDictionary<string, TimeSpan> playTimes,
|
||||
|
||||
@@ -4,6 +4,7 @@ using Content.Shared.Humanoid.Prototypes;
|
||||
using Content.Shared.Preferences;
|
||||
using Content.Shared.Traits;
|
||||
using JetBrains.Annotations;
|
||||
using Robust.Shared.Network;
|
||||
using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.Serialization;
|
||||
using Robust.Shared.Utility;
|
||||
@@ -20,7 +21,8 @@ public sealed partial class TraitsRequirement : JobRequirement
|
||||
[DataField(required: true)]
|
||||
public HashSet<ProtoId<TraitPrototype>> Traits = new();
|
||||
|
||||
public override bool Check(IEntityManager entManager,
|
||||
public override bool Check(NetUserId? userId, //CP14 Sponsorship Checks
|
||||
IEntityManager entManager,
|
||||
IPrototypeManager protoManager,
|
||||
HumanoidCharacterProfile? profile,
|
||||
IReadOnlyDictionary<string, TimeSpan> playTimes,
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using Content.Shared.Preferences;
|
||||
using Robust.Shared.Network;
|
||||
using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.Serialization;
|
||||
using Robust.Shared.Utility;
|
||||
@@ -9,6 +10,7 @@ namespace Content.Shared.Roles;
|
||||
public static class JobRequirements
|
||||
{
|
||||
public static bool TryRequirementsMet(
|
||||
NetUserId userId, //CP14 add NetUserId for sponsorship checks
|
||||
JobPrototype job,
|
||||
IReadOnlyDictionary<string, TimeSpan> playTimes,
|
||||
[NotNullWhen(false)] out FormattedMessage? reason,
|
||||
@@ -24,7 +26,7 @@ public static class JobRequirements
|
||||
|
||||
foreach (var requirement in requirements)
|
||||
{
|
||||
if (!requirement.Check(entManager, protoManager, profile, playTimes, out reason))
|
||||
if (!requirement.Check(userId, entManager, protoManager, profile, playTimes, out reason)) //CP14 add NetUserId for sponsorship checks
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -43,6 +45,7 @@ public abstract partial class JobRequirement
|
||||
public bool Inverted;
|
||||
|
||||
public abstract bool Check(
|
||||
NetUserId? userId, //CP14 Sponsorship Checks
|
||||
IEntityManager entManager,
|
||||
IPrototypeManager protoManager,
|
||||
HumanoidCharacterProfile? profile,
|
||||
|
||||
@@ -4,6 +4,9 @@ namespace Content.Shared.CCVar;
|
||||
|
||||
public sealed partial class CCVars
|
||||
{
|
||||
public static readonly CVarDef<bool> SponsorsEnabled =
|
||||
CVarDef.Create("cp14.sponsor_enabled", false, CVar.SERVERONLY);
|
||||
|
||||
public static readonly CVarDef<string> SponsorsApiUrl =
|
||||
CVarDef.Create("cp14.sponsor_api_url", "http://localhost:8000/sponsors", CVar.SERVERONLY | CVar.CONFIDENTIAL);
|
||||
|
||||
|
||||
74
Content.Shared/_CP14/Roles/CP14SponsorFeatureRequired.cs
Normal file
74
Content.Shared/_CP14/Roles/CP14SponsorFeatureRequired.cs
Normal file
@@ -0,0 +1,74 @@
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using Content.Shared._CP14.Sponsor;
|
||||
using Content.Shared.Preferences;
|
||||
using Content.Shared.Roles;
|
||||
using JetBrains.Annotations;
|
||||
using Robust.Shared.Network;
|
||||
using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.Serialization;
|
||||
using Robust.Shared.Utility;
|
||||
|
||||
namespace Content.Shared._CP14.Roles;
|
||||
|
||||
/// <summary>
|
||||
/// Requires a character to have, or not have, certain traits
|
||||
/// </summary>
|
||||
[UsedImplicitly]
|
||||
[Serializable, NetSerializable]
|
||||
public sealed partial class CP14SponsorFeatureRequired : JobRequirement
|
||||
{
|
||||
[DataField(required: true)]
|
||||
public ProtoId<CP14SponsorFeaturePrototype> Feature = string.Empty;
|
||||
|
||||
public override bool Check(NetUserId? userId,
|
||||
IEntityManager entManager,
|
||||
IPrototypeManager protoManager,
|
||||
HumanoidCharacterProfile? profile,
|
||||
IReadOnlyDictionary<string, TimeSpan> playTimes,
|
||||
[NotNullWhen(false)] out FormattedMessage? reason)
|
||||
{
|
||||
reason = new FormattedMessage();
|
||||
|
||||
if (userId is null)
|
||||
return false;
|
||||
|
||||
var sponsorship = IoCManager.Resolve<ICP14SponsorManager>();
|
||||
|
||||
var haveFeature = sponsorship.UserHasFeature(userId.Value, Feature);
|
||||
|
||||
if (haveFeature)
|
||||
return true;
|
||||
|
||||
var prototypeMan = IoCManager.Resolve<IPrototypeManager>();
|
||||
|
||||
var indexedFeature = prototypeMan.Index(Feature);
|
||||
var lowestRole = GetLowestPriorityRole(indexedFeature.MinPriority, prototypeMan);
|
||||
prototypeMan.TryIndex(lowestRole, out var indexedRole);
|
||||
|
||||
if (indexedRole == null)
|
||||
return false;
|
||||
reason = FormattedMessage.FromMarkupPermissive(Loc.GetString("cp14-role-req-sponsor-feature-req", ("role", indexedRole.Name)));
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public ProtoId<CP14SponsorRolePrototype>? GetLowestPriorityRole(float priority, IPrototypeManager protoMan)
|
||||
{
|
||||
ProtoId<CP14SponsorRolePrototype>? lowestRole = null;
|
||||
float lowestPriority = float.MaxValue;
|
||||
|
||||
foreach (var role in protoMan.EnumeratePrototypes<CP14SponsorRolePrototype>())
|
||||
{
|
||||
if (!role.Examinable)
|
||||
continue;
|
||||
|
||||
if (role.Priority >= priority && role.Priority < lowestPriority)
|
||||
{
|
||||
lowestPriority = role.Priority;
|
||||
lowestRole = role.ID;
|
||||
}
|
||||
}
|
||||
|
||||
return lowestRole;
|
||||
}
|
||||
}
|
||||
35
Content.Shared/_CP14/Sponsor/CP14SharedSponsorManager.cs
Normal file
35
Content.Shared/_CP14/Sponsor/CP14SharedSponsorManager.cs
Normal file
@@ -0,0 +1,35 @@
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using Lidgren.Network;
|
||||
using Robust.Shared.Network;
|
||||
using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.Serialization;
|
||||
|
||||
namespace Content.Shared._CP14.Sponsor;
|
||||
|
||||
public interface ICP14SponsorManager
|
||||
{
|
||||
public void Initialize();
|
||||
|
||||
public bool UserHasFeature(NetUserId userId,
|
||||
ProtoId<CP14SponsorFeaturePrototype> feature,
|
||||
bool ifDisabledSponsorhip = true);
|
||||
|
||||
public bool TryGetSponsorOOCColor(NetUserId userId, [NotNullWhen(true)] out Color? color);
|
||||
}
|
||||
|
||||
public sealed class CP14SponsorRoleUpdate : NetMessage
|
||||
{
|
||||
public override MsgGroups MsgGroup => MsgGroups.Command;
|
||||
|
||||
public ProtoId<CP14SponsorRolePrototype> Role { get; set; }
|
||||
|
||||
public override void ReadFromBuffer(NetIncomingMessage buffer, IRobustSerializer serializer)
|
||||
{
|
||||
Role = buffer.ReadString();
|
||||
}
|
||||
|
||||
public override void WriteToBuffer(NetOutgoingMessage buffer, IRobustSerializer serializer)
|
||||
{
|
||||
buffer.Write(Role);
|
||||
}
|
||||
}
|
||||
33
Content.Shared/_CP14/Sponsor/CP14SponsorRolePrototype.cs
Normal file
33
Content.Shared/_CP14/Sponsor/CP14SponsorRolePrototype.cs
Normal file
@@ -0,0 +1,33 @@
|
||||
using Robust.Shared.Prototypes;
|
||||
|
||||
namespace Content.Shared._CP14.Sponsor;
|
||||
|
||||
[Prototype("sponsorRole")]
|
||||
public sealed partial class CP14SponsorRolePrototype : IPrototype
|
||||
{
|
||||
[IdDataField] public string ID { get; } = string.Empty;
|
||||
|
||||
[DataField(required: true)]
|
||||
public string Name = string.Empty;
|
||||
|
||||
[DataField(required: true)]
|
||||
public string DiscordRoleId = string.Empty;
|
||||
|
||||
[DataField]
|
||||
public Color? Color = null;
|
||||
|
||||
[DataField]
|
||||
public float Priority = 0;
|
||||
|
||||
[DataField]
|
||||
public bool Examinable = false;
|
||||
}
|
||||
|
||||
[Prototype("sponsorFeature")]
|
||||
public sealed partial class CP14SponsorFeaturePrototype : IPrototype
|
||||
{
|
||||
[IdDataField] public string ID { get; } = string.Empty;
|
||||
|
||||
[DataField]
|
||||
public float MinPriority = 1;
|
||||
}
|
||||
@@ -67,4 +67,5 @@ mob_pushing = true
|
||||
|
||||
[cp14]
|
||||
discord_auth_enabled = true
|
||||
closet_beta_test = true
|
||||
closet_beta_test = true
|
||||
sponsor_enabled = true
|
||||
1
Resources/Locale/en-US/_CP14/job/requirements.ftl
Normal file
1
Resources/Locale/en-US/_CP14/job/requirements.ftl
Normal file
@@ -0,0 +1 @@
|
||||
cp14-role-req-sponsor-feature-req = You must have at least the “{$role}” role in the discord server to access this.
|
||||
1
Resources/Locale/ru-RU/_CP14/job/requirements.ftl
Normal file
1
Resources/Locale/ru-RU/_CP14/job/requirements.ftl
Normal file
@@ -0,0 +1 @@
|
||||
cp14-role-req-sponsor-feature-req = Вы должны иметь как минимум роль "{$role}" в дискорд сервере, чтобы получить доступ к этому.
|
||||
3
Resources/Prototypes/_CP14/Sponsor/features.yml
Normal file
3
Resources/Prototypes/_CP14/Sponsor/features.yml
Normal file
@@ -0,0 +1,3 @@
|
||||
- type: sponsorFeature
|
||||
id: PriorityJoin # Allows you to connect to the server by bypassing the queue
|
||||
minPriority: 1
|
||||
76
Resources/Prototypes/_CP14/Sponsor/roles.yml
Normal file
76
Resources/Prototypes/_CP14/Sponsor/roles.yml
Normal file
@@ -0,0 +1,76 @@
|
||||
# Development assistance
|
||||
|
||||
- type: sponsorRole
|
||||
id: Contributor
|
||||
name: Contributor
|
||||
discordRoleId: "1224637355193929818"
|
||||
priority: 1
|
||||
color: "#1fbf51"
|
||||
|
||||
- type: sponsorRole
|
||||
id: Moderator
|
||||
name: "Discord Moderator"
|
||||
discordRoleId: "1225071736286875718"
|
||||
priority: 1
|
||||
color: "#1fbf51"
|
||||
|
||||
- type: sponsorRole
|
||||
id: Maintainer
|
||||
name: Maintainer
|
||||
discordRoleId: "1263856724868333688"
|
||||
priority: 2
|
||||
color: "#287fc7"
|
||||
|
||||
- type: sponsorRole
|
||||
id: Headmin
|
||||
name: Headmin
|
||||
discordRoleId: "1359572736095289544"
|
||||
priority: 3
|
||||
color: "#2c65f5"
|
||||
|
||||
- type: sponsorRole
|
||||
id: LoreKeeper
|
||||
name: Lore Keeper
|
||||
discordRoleId: "1264150382821773354"
|
||||
priority: 3
|
||||
color: "#2c65f5"
|
||||
|
||||
- type: sponsorRole
|
||||
id: HeadMapper
|
||||
name: Head Mapper
|
||||
discordRoleId: "1316306180297064488"
|
||||
priority: 3
|
||||
color: "#2c65f5"
|
||||
|
||||
- type: sponsorRole
|
||||
id: ArtDirector
|
||||
name: Art Director
|
||||
discordRoleId: "1242043180745097236"
|
||||
priority: 3
|
||||
color: "#2c65f5"
|
||||
|
||||
# Sponsorship assistance
|
||||
|
||||
- type: sponsorRole
|
||||
id: Sponsor1
|
||||
name: Sponsorship I
|
||||
discordRoleId: "1254132975897935986"
|
||||
priority: 1.1
|
||||
color: "#bf397c"
|
||||
examinable: true
|
||||
|
||||
- type: sponsorRole
|
||||
id: Sponsor2
|
||||
name: Sponsorship II
|
||||
discordRoleId: "1316306142833414195"
|
||||
priority: 2
|
||||
color: "#d92567"
|
||||
examinable: true
|
||||
|
||||
- type: sponsorRole
|
||||
id: Sponsor3
|
||||
name: Sponsorship III
|
||||
discordRoleId: "1327377639882752052"
|
||||
priority: 3
|
||||
color: "#fa1639"
|
||||
examinable: true
|
||||
Reference in New Issue
Block a user