Топ контрибюторов в лобби (#1828)

This commit is contained in:
Vigers Ray 2025-04-17 06:27:30 +03:00 committed by GitHub
parent a5a2bbd386
commit 091f0b22ee
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
18 changed files with 558 additions and 6 deletions

View file

@ -1,5 +1,6 @@
using Content.Client._RMC14.Explosion;
using Content.Client._RMC14.Xenonids.Screech;
using Content.Client._Sunrise.Contributors;
using Content.Client._Sunrise.Entry;
using Content.Client._Sunrise.ServersHub;
using Content.Client.Administration.Managers;
@ -79,6 +80,7 @@ namespace Content.Client.Entry
[Dependency] private readonly DebugMonitorManager _debugMonitorManager = default!;
[Dependency] private readonly TitleWindowManager _titleWindowManager = default!;
[Dependency] private readonly ServersHubManager _serversHubManager = default!; // Sunrise-Hub
[Dependency] private readonly ContributorsManager _contributorsManager = default!; // Sunrise-Edit
public override void Init()
{
@ -145,6 +147,7 @@ namespace Content.Client.Entry
_playbackMan.Initialize();
_serversHubManager.Initialize(); // Sunrise-Hub
_contributorsManager.Initialize(); // Sunrise-Hub
// Sunrise-Sponsors-Start
SunriseClientEntry.Init();

View file

@ -1,4 +1,5 @@
using Content.Client._Sunrise.IoC;
using Content.Client._Sunrise.Contributors;
using Content.Client._Sunrise.IoC;
using Content.Client._Sunrise.ServersHub;
using Content.Client.Administration.Managers;
using Content.Client.Changelog;
@ -64,6 +65,7 @@ namespace Content.Client.IoC
// Sunrise-Start
collection.Register<ServersHubManager>();
collection.Register<ContributorsManager>();
SunriseClientContentIoC.Register();
// Sunrise-End
}

View file

@ -1,4 +1,5 @@
using System.Linq;
using Content.Client._Sunrise.Contributors;
using Content.Client._Sunrise.Latejoin;
using Content.Client._Sunrise.ServersHub;
using Content.Client.Audio;
@ -8,6 +9,7 @@ using Content.Client.Message;
using Content.Client.UserInterface.Systems.Chat;
using Content.Client.Voting;
using Content.Shared.CCVar;
using Content.Shared._Sunrise.Contributors;
using Robust.Client;
using Robust.Client.Console;
using Robust.Client.ResourceManagement;
@ -46,6 +48,7 @@ namespace Content.Client.Lobby
[Dependency] private readonly ISerializationManager _serialization = default!;
[Dependency] private readonly IResourceManager _resource = default!;
[Dependency] private readonly ServersHubManager _serversHubManager = default!;
[Dependency] private readonly ContributorsManager _contributorsManager = default!;
[Dependency] private readonly ChangelogManager _changelogManager = default!;
[Dependency] private readonly IConfigurationManager _cfg = default!;
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
@ -123,6 +126,9 @@ namespace Content.Client.Lobby
_gameTicker.LobbyLateJoinStatusUpdated += LobbyLateJoinStatusUpdated;
_serversHubManager.ServersDataListChanged += RefreshServersHubHeader;
_contributorsManager.ContributorsDataListChanged += RefreshContributorsHeader;
RefreshContributorsHeader(_contributorsManager.ContributorsDataList);
}
protected override void Shutdown()
@ -143,6 +149,7 @@ namespace Content.Client.Lobby
Lobby = null;
_serversHubManager.ServersDataListChanged -= RefreshServersHubHeader;
_contributorsManager.ContributorsDataListChanged -= RefreshContributorsHeader;
}
private void RefreshServersHubHeader(List<ServerHubEntry> servers)
@ -152,6 +159,11 @@ namespace Content.Client.Lobby
Lobby!.ServersHubHeaderLabel.Text = Loc.GetString("serverhub-playingnow", ("total", totalPlayers), ("max", maxPlayers)); // Sunrise-Edit
}
private void RefreshContributorsHeader(List<ContributorEntry> contributors)
{
Lobby!.ContributorsHeaderLabel.Text = Loc.GetString("contributors-header-count", ("count", contributors.Count));
}
public void SwitchState(LobbyGui.LobbyGuiState state)
{
// Yeah I hate this but LobbyState contains all the badness for now.

View file

@ -12,7 +12,8 @@
xmlns:serversHub="clr-namespace:Content.Client._Sunrise.ServersHub"
xmlns:changelog="clr-namespace:Content.Client.Changelog"
xmlns:userProfile="clr-namespace:Content.Client._Sunrise.UserProfile"
xmlns:texture="clr-namespace:Content.Client._Sunrise.Texture">
xmlns:texture="clr-namespace:Content.Client._Sunrise.Texture"
xmlns:contributors="clr-namespace:Content.Client._Sunrise.Contributors">
<!-- Background -->
<TextureRect Name="LobbyArt" Access="Public" VerticalExpand="True" HorizontalExpand="True"
Stretch="KeepAspectCovered" />
@ -113,6 +114,26 @@
VerticalExpand="True" />
</BoxContainer>
</BoxContainer>
<BoxContainer Orientation="Vertical" Name="ContributorsBox" VerticalExpand="True"
VerticalAlignment="Bottom" Access="Public" SizeFlagsStretchRatio="2">
<controls:StripeBack>
<BoxContainer Orientation="Horizontal" Name="ContributorsHeader" >
<Label HorizontalExpand="True" Name="ContributorsHeaderLabel" Access="Public"
Text="{Loc 'contributors-header'}" VAlign="Center" StyleClasses="LabelHeading"
Align="Center"/>
<TextureRect Name="ContributorsHider" VerticalAlignment="Center" SetSize="25 25"
Stretch="KeepAspectCentered" Margin="5 1" MouseFilter="Stop"
HorizontalAlignment="Right" Access="Public">
</TextureRect>
</BoxContainer>
</controls:StripeBack>
<BoxContainer Orientation="Vertical" Name="ContributorsContent" HorizontalExpand="True"
VerticalExpand="True"
HorizontalAlignment="Stretch" VerticalAlignment="Top">
<contributors:ContributorsTop Name="ContributorsBody" Access="Public" HorizontalExpand="True"
VerticalExpand="True" />
</BoxContainer>
</BoxContainer>
<BoxContainer Orientation="Vertical" Name="ChangelogBox" VerticalExpand="True"
MaxWidth="580"
HorizontalAlignment="Stretch" VerticalAlignment="Bottom"

View file

@ -100,6 +100,15 @@ namespace Content.Client.Lobby.UI
ServersHubHider.Texture = ServersHubContent.Visible ? IconExpanded : IconCollapsed;
};
ContributorsHider.OnKeyBindUp += args =>
{
if (args.Function != EngineKeyFunctions.Use)
return;
ContributorsContent.Visible = !ContributorsContent.Visible;
ContributorsHider.Texture = ContributorsContent.Visible ? IconExpanded : IconCollapsed;
};
ChangelogHider.OnKeyBindUp += args =>
{
if (args.Function != EngineKeyFunctions.Use)
@ -164,17 +173,23 @@ namespace Content.Client.Lobby.UI
}
ServersHubHider.Texture = ServersHubContent.Visible ? IconExpanded : IconCollapsed;
ContributorsHider.Texture = ContributorsContent.Visible ? IconExpanded : IconCollapsed;
ChangelogHider.Texture = ChangelogContent.Visible ? IconExpanded : IconCollapsed;
ServerInfoHider.Texture = ServerInfoContent.Visible ? IconExpanded : IconCollapsed;
CharacterInfoHider.Texture = CharacterInfoContent.Visible ? IconExpanded : IconCollapsed;
ChatHider.Texture = ChatContent.Visible ? IconExpanded : IconCollapsed;
UserProfileHider.Texture = CharacterInfoContent.Visible ? IconExpanded : IconCollapsed;
ServersHubHider.Modulate = StyleNano.NanoGold;
ContributorsHider.Modulate = StyleNano.NanoGold;
ChangelogHider.Modulate = StyleNano.NanoGold;
ServerInfoHider.Modulate = StyleNano.NanoGold;
CharacterInfoHider.Modulate = StyleNano.NanoGold;
ChatHider.Modulate = StyleNano.NanoGold;
UserProfileHider.Modulate = StyleNano.NanoGold;
// Скрываем чейнджлог по умолчанию
ChangelogContent.Visible = false;
ChangelogHider.Texture = IconCollapsed;
}
private void OnServersHubEnableChanged(bool enable)

View file

@ -0,0 +1,33 @@
<PanelContainer xmlns="https://spacestation14.io"
xmlns:customControls="clr-namespace:Content.Client.Administration.UI.CustomControls"
Name="BackgroundColorPanel"
MouseFilter="Stop">
<BoxContainer Orientation="Vertical">
<customControls:HSeparator/>
<BoxContainer Orientation="Horizontal"
HorizontalExpand="True"
Margin="5 2">
<customControls:VSeparator/>
<Label Name="SS14UsernameLabel"
SizeFlagsStretchRatio="2"
HorizontalExpand="True"
StyleClasses="LabelSubText"
ClipText="True"/>
<customControls:VSeparator/>
<Label Name="GithubLoginLabel"
SizeFlagsStretchRatio="2"
HorizontalExpand="True"
StyleClasses="LabelSubText"
ClipText="True"/>
<customControls:VSeparator/>
<Label Name="ContributionsLabel"
SizeFlagsStretchRatio="1"
HorizontalExpand="True"
StyleClasses="LabelSubText"
Align="Center"
ClipText="True"/>
<customControls:VSeparator/>
</BoxContainer>
<customControls:HSeparator/>
</BoxContainer>
</PanelContainer>

View file

@ -0,0 +1,62 @@
using Content.Shared._Sunrise.Contributors;
using Robust.Client.AutoGenerated;
using Robust.Client.Graphics;
using Robust.Client.UserInterface;
using Robust.Client.UserInterface.Controls;
using Robust.Client.UserInterface.XAML;
using Robust.Shared.Input;
namespace Content.Client._Sunrise.Contributors;
[GenerateTypedNameReferences]
public sealed partial class ContributorEntryControl : PanelContainer
{
private static readonly Color NormalColor = Color.FromHex("#202023");
private static readonly Color HoverColor = Color.FromHex("#2F2F33");
public ContributorEntryControl()
{
RobustXamlLoader.Load(this);
TooltipDelay = 0.5f;
BackgroundColorPanel.PanelOverride = new StyleBoxFlat
{
BackgroundColor = NormalColor
};
BackgroundColorPanel.OnMouseEntered += args =>
{
var panel = (StyleBoxFlat)BackgroundColorPanel.PanelOverride!;
panel.BackgroundColor = HoverColor;
};
BackgroundColorPanel.OnMouseExited += args =>
{
var panel = (StyleBoxFlat)BackgroundColorPanel.PanelOverride!;
panel.BackgroundColor = NormalColor;
};
}
public void UpdateData(ContributorEntry entry)
{
SS14UsernameLabel.Text = entry.SS14Username;
GithubLoginLabel.Text = entry.GithubLogin;
ContributionsLabel.Text = entry.Contributions.ToString();
BackgroundColorPanel.OnKeyBindDown += args =>
{
if (args.Function != EngineKeyFunctions.Use)
return;
OpenGitHubProfile(entry.GithubLogin);
};
}
private void OpenGitHubProfile(string githubLogin)
{
if (string.IsNullOrEmpty(githubLogin))
return;
IoCManager.Resolve<IUriOpener>().OpenUri(new Uri($"https://github.com/{githubLogin}"));
}
}

View file

@ -0,0 +1,29 @@
using Content.Shared._Sunrise.Contributors;
using Robust.Shared.Network;
namespace Content.Client._Sunrise.Contributors;
public sealed partial class ContributorsManager
{
[Dependency] private readonly IClientNetManager _netManager = default!;
public event Action<List<ContributorEntry>>? ContributorsDataListChanged;
public List<ContributorEntry> ContributorsDataList = [];
public ContributorsManager()
{
IoCManager.InjectDependencies(this);
}
public void Initialize()
{
_netManager.RegisterNetMessage<MsgFullContributorsList>(OnContributorsDataChanged);
}
private void OnContributorsDataChanged(MsgFullContributorsList msg)
{
ContributorsDataList = msg.ContributorsEntries;
ContributorsDataListChanged?.Invoke(ContributorsDataList);
}
}

View file

@ -0,0 +1,30 @@
<Control xmlns="https://spacestation14.io"
xmlns:customControls="clr-namespace:Content.Client.Administration.UI.CustomControls"
MinSize="300 100">
<BoxContainer Orientation="Vertical" VerticalExpand="True" HorizontalExpand="True">
<BoxContainer Orientation="Horizontal"
HorizontalExpand="True"
Margin="0 0 15 0">
<customControls:VSeparator/>
<Label Text="{Loc 'contributors-column-ss14'}"
SizeFlagsStretchRatio="2"
HorizontalExpand="True"
Align="Center"/>
<customControls:VSeparator/>
<Label Text="{Loc 'contributors-column-github'}"
SizeFlagsStretchRatio="2"
HorizontalExpand="True"
Align="Center"/>
<customControls:VSeparator/>
<Label Text="{Loc 'contributors-column-contributions'}"
SizeFlagsStretchRatio="1"
HorizontalExpand="True"
Align="Center"/>
<customControls:VSeparator/>
</BoxContainer>
<customControls:HSeparator/>
<ScrollContainer HScrollEnabled="False" HorizontalExpand="True" VerticalExpand="True" MinHeight="150">
<BoxContainer Name="ContributorsList" Access="Public" Orientation="Vertical" VerticalExpand="True" HorizontalExpand="True"/>
</ScrollContainer>
</BoxContainer>
</Control>

View file

@ -0,0 +1,54 @@
using System.Linq;
using Content.Shared._Sunrise.Contributors;
using Robust.Client.AutoGenerated;
using Robust.Client.UserInterface;
using Robust.Client.UserInterface.XAML;
namespace Content.Client._Sunrise.Contributors;
[GenerateTypedNameReferences]
public sealed partial class ContributorsTop : Control
{
[Dependency] private readonly ContributorsManager _contributorsManager = default!;
private readonly Dictionary<int, ContributorEntryControl> _contributorControls = new();
public ContributorsTop()
{
RobustXamlLoader.Load(this);
IoCManager.InjectDependencies(this);
_contributorsManager.ContributorsDataListChanged += RefreshContributors;
}
private void RefreshContributors(List<ContributorEntry> contributors)
{
var sortedContributors = contributors.OrderByDescending(x => x.Contributions).ToList();
var toRemove = _contributorControls.Keys.Where(id => !sortedContributors.Any(c => c.GithubId == id)).ToList();
foreach (var id in toRemove)
{
if (_contributorControls.TryGetValue(id, out var control))
{
ContributorsList.RemoveChild(control);
_contributorControls.Remove(id);
}
}
foreach (var contributor in sortedContributors)
{
if (_contributorControls.TryGetValue(contributor.GithubId, out var existingControl))
{
existingControl.UpdateData(contributor);
}
else
{
var control = new ContributorEntryControl();
control.UpdateData(contributor);
_contributorControls[contributor.GithubId] = control;
ContributorsList.AddChild(control);
}
}
}
}

View file

@ -1,3 +1,4 @@
using Content.Server._Sunrise.Contributors;
using Content.Server._Sunrise.Entry;
using Content.Server._Sunrise.GuideGenerator;
using Content.Server._Sunrise.ServersHub;
@ -51,6 +52,7 @@ namespace Content.Server.Entry
private IVoteManager _voteManager = default!;
private ServerUpdateManager _updateManager = default!;
private ServersHubManager _serversHubManager = default!; // Sunrise-Edit
private ContributorsManager _contributorsManager = default!; // Sunrise-Edit
private PlayTimeTrackingManager? _playTimeTracking;
private IEntitySystemManager? _sysMan;
private IServerDbManager? _dbManager;
@ -101,6 +103,7 @@ namespace Content.Server.Entry
_voteManager = IoCManager.Resolve<IVoteManager>();
_updateManager = IoCManager.Resolve<ServerUpdateManager>();
_serversHubManager = IoCManager.Resolve<ServersHubManager>(); // Sunrise-Edit
_contributorsManager = IoCManager.Resolve<ContributorsManager>(); // Sunrise-Edit
_playTimeTracking = IoCManager.Resolve<PlayTimeTrackingManager>();
_connectionManager = IoCManager.Resolve<IConnectionManager>();
_sysMan = IoCManager.Resolve<IEntitySystemManager>();
@ -117,11 +120,12 @@ namespace Content.Server.Entry
IoCManager.Resolve<INodeGroupFactory>().Initialize();
IoCManager.Resolve<ContentNetworkResourceManager>().Initialize();
IoCManager.Resolve<GhostKickManager>().Initialize();
IoCManager.Resolve<TTSManager>().Initialize(); // Sunrise-TTS
IoCManager.Resolve<ServerInfoManager>().Initialize();
IoCManager.Resolve<ServerApi>().Initialize();
IoCManager.Resolve<TTSManager>().Initialize(); // Sunrise-TTS
IoCManager.Resolve<ServersHubManager>().Initialize(); // Sunrise-Hub
IoCManager.Resolve<ContributorsManager>().Initialize(); // Sunrise-Hub
// Sunrise-Sponsors-Start
SunriseServerEntry.Init();
@ -207,6 +211,7 @@ namespace Content.Server.Entry
_watchlistWebhookManager.Update();
_connectionManager?.Update();
_serversHubManager.Update(); // Sunrise-Edit
_contributorsManager.Update(); // Sunrise-Edit
_sponsorsManager?.Update(); // Sunrise-Edit
break;
}

View file

@ -1,3 +1,4 @@
using Content.Server._Sunrise.Contributors;
using Content.Server._Sunrise.IoC;
using Content.Server._Sunrise.ServersHub;
using Content.Server._Sunrise.TTS;
@ -84,6 +85,7 @@ namespace Content.Server.IoC
// Sunrise-Start
IoCManager.Register<ServersHubManager>();
IoCManager.Register<ContributorsManager>();
SunriseServerContentIoC.Register();
// Sunrise-End
}

View file

@ -0,0 +1,204 @@
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Net.Http.Json;
using System.Threading.Tasks;
using Content.Shared._Sunrise.Contributors;
using Content.Shared._Sunrise.SunriseCCVars;
using Robust.Server.Player;
using Robust.Shared;
using Robust.Shared.Configuration;
using Robust.Shared.Enums;
using Robust.Shared.Network;
using Robust.Shared.Player;
using Robust.Shared.Timing;
namespace Content.Server._Sunrise.Contributors;
public sealed class ContributorsManager
{
[Dependency] private readonly IPlayerManager _playerManager = default!;
[Dependency] private readonly ILogManager _logManager = default!;
[Dependency] private readonly IConfigurationManager _cfg = default!;
[Dependency] private readonly IServerNetManager _netMgr = default!;
[Dependency] private readonly IGameTiming _timing = default!;
private readonly List<ContributorEntry> _contributorsList = new();
private bool _enable = true;
private string _apiUrl = string.Empty;
private string _projectName = string.Empty;
private readonly HttpClient _httpClient = new();
private ISawmill _sawmill = default!;
private readonly TimeSpan _updateRate = TimeSpan.FromHours(1);
private TimeSpan _nextUpdate = TimeSpan.Zero;
public void Initialize()
{
_sawmill = _logManager.GetSawmill("contributors");
_cfg.OnValueChanged(SunriseCCVars.ContributorsEnable, OnContributorsEnableChanged);
_cfg.OnValueChanged(SunriseCCVars.ContributorsApiUrl, OnApiUrlChanged, true);
_cfg.OnValueChanged(SunriseCCVars.ContributorsProjectName, OnProjectNameChanged, true);
_cfg.OnValueChanged(SunriseCCVars.ContributorsApiToken, OnApiTokenChanged, true);
_netMgr.RegisterNetMessage<MsgFullContributorsList>();
_playerManager.PlayerStatusChanged += OnPlayerStatusChanged;
}
private void OnPlayerStatusChanged(object? sender, SessionStatusEventArgs e)
{
if (e.NewStatus != SessionStatus.Connected || !_enable || _contributorsList.Count == 0)
return;
var netMsg = new MsgFullContributorsList
{
ContributorsEntries = _contributorsList,
};
_netMgr.ServerSendMessage(netMsg, e.Session.Channel);
}
private void OnContributorsEnableChanged(bool enable)
{
_enable = enable;
if (enable && _contributorsList.Count == 0)
{
UpdateContributorsData();
}
}
private void OnApiUrlChanged(string apiUrl)
{
_apiUrl = apiUrl;
}
private void OnProjectNameChanged(string projectName)
{
_projectName = projectName;
}
private void OnApiTokenChanged(string apiToken)
{
_httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", apiToken);
}
public void Update()
{
if (_nextUpdate > _timing.CurTime)
return;
_nextUpdate += _updateRate;
UpdateContributorsData();
}
private async void UpdateContributorsData()
{
if (!_enable)
return;
if (string.IsNullOrEmpty(_apiUrl) || string.IsNullOrEmpty(_projectName))
{
_sawmill.Warning("API URL or Project Name not set, skipping update");
return;
}
if (string.IsNullOrEmpty(_cfg.GetCVar(SunriseCCVars.ContributorsApiToken)))
{
_sawmill.Error("API token is not set!");
return;
}
var data = await RefreshContributorsData();
if (data == null)
{
_sawmill.Warning("Failed to get contributors data");
return;
}
_contributorsList.Clear();
_contributorsList.AddRange(data);
SendFullContributorsList(_playerManager.Sessions);
}
private async Task<List<ContributorEntry>?> RefreshContributorsData()
{
try
{
var requestUrl = $"{_apiUrl}/contributors/{_projectName}";
_sawmill.Debug($"Sending request to: {requestUrl}");
using var request = new HttpRequestMessage(HttpMethod.Get, requestUrl);
using var resp = await _httpClient.SendAsync(request);
if (resp.StatusCode == HttpStatusCode.NotFound)
{
_sawmill.Error("API endpoint not found");
return null;
}
if (resp.StatusCode == HttpStatusCode.Unauthorized)
{
_sawmill.Error("Invalid API token!");
return null;
}
if (!resp.IsSuccessStatusCode)
{
_sawmill.Error($"API returned bad response {resp.StatusCode}!");
return null;
}
var responseData = await resp.Content.ReadFromJsonAsync<ContributorsResponse>();
if (responseData?.Contributors == null)
{
_sawmill.Error("Invalid response format from API");
return null;
}
return responseData.Contributors.Select(c => new ContributorEntry(
c.GithubId,
c.GithubLogin,
c.SS14UserId,
c.SS14Username,
c.Contributions)).ToList();
}
catch (HttpRequestException e)
{
_sawmill.Error($"Failed to get contributors data:\n{e}");
}
return null;
}
private void SendFullContributorsList(IEnumerable<ICommonSession> sessions)
{
var netMsg = new MsgFullContributorsList
{
ContributorsEntries = _contributorsList,
};
foreach (var session in sessions)
{
_sawmill.Debug($"Sending contributors data to player: {session.Name}");
_netMgr.ServerSendMessage(netMsg, session.Channel);
}
}
private sealed class ContributorsResponse
{
public List<ContributorInfo> Contributors { get; set; } = new();
}
private sealed class ContributorInfo
{
public int GithubId { get; set; }
public string GithubLogin { get; set; } = string.Empty;
public string SS14UserId { get; set; } = string.Empty;
public string SS14Username { get; set; } = string.Empty;
public int Contributions { get; set; }
}
}

View file

@ -0,0 +1,12 @@
using Robust.Shared.Serialization;
namespace Content.Shared._Sunrise.Contributors
{
[Serializable, NetSerializable]
public sealed record ContributorEntry(
int GithubId,
string GithubLogin,
string SS14UserId,
string SS14Username,
int Contributions);
}

View file

@ -0,0 +1,41 @@
using Lidgren.Network;
using Robust.Shared.Network;
using Robust.Shared.Serialization;
namespace Content.Shared._Sunrise.Contributors;
public sealed class MsgFullContributorsList : NetMessage
{
public override MsgGroups MsgGroup => MsgGroups.EntityEvent;
public List<ContributorEntry> ContributorsEntries { get; set; } = [];
public override void ReadFromBuffer(NetIncomingMessage buffer, IRobustSerializer serializer)
{
var count = buffer.ReadInt32();
ContributorsEntries.EnsureCapacity(count);
for (var i = 0; i < count; i++)
{
ContributorsEntries.Add(new ContributorEntry(
buffer.ReadInt32(),
buffer.ReadString(),
buffer.ReadString(),
buffer.ReadString(),
buffer.ReadInt32()
));
}
}
public override void WriteToBuffer(NetOutgoingMessage buffer, IRobustSerializer serializer)
{
buffer.Write(ContributorsEntries.Count);
foreach (var contributor in ContributorsEntries)
{
buffer.Write(contributor.GithubId);
buffer.Write(contributor.GithubLogin);
buffer.Write(contributor.SS14UserId);
buffer.Write(contributor.SS14Username);
buffer.Write(contributor.Contributions);
}
}
}

View file

@ -0,0 +1,19 @@
using Robust.Shared.Configuration;
namespace Content.Shared._Sunrise.SunriseCCVars;
[CVarDefs]
public sealed partial class SunriseCCVars
{
public static readonly CVarDef<bool> ContributorsEnable =
CVarDef.Create("contributors.enable", false, CVar.SERVERONLY);
public static readonly CVarDef<string> ContributorsApiUrl =
CVarDef.Create("contributors.api_url", string.Empty, CVar.SERVERONLY);
public static readonly CVarDef<string> ContributorsProjectName =
CVarDef.Create("contributors.project_name", string.Empty, CVar.SERVERONLY);
public static readonly CVarDef<string> ContributorsApiToken =
CVarDef.Create("contributors.api_token", string.Empty, CVar.SERVERONLY | CVar.CONFIDENTIAL);
}

View file

@ -1,9 +1,9 @@
using Robust.Shared.Configuration;
using Robust.Shared;
using Robust.Shared.Configuration;
namespace Content.Shared._Sunrise.SunriseCCVars;
[CVarDefs]
public sealed class SunriseCCVars
public sealed partial class SunriseCCVars : CVars
{
/**
* TTS (Text-To-Speech)

View file

@ -0,0 +1,8 @@
contributors-header = Контрибьюторы
contributors-header-count = Контрибьюторы ({$count})
contributors-ss14-name = SS14: {$name}
contributors-github-name = GitHub: {$name}
contributors-count = {$count}
contributors-column-ss14 = SS14
contributors-column-github = GitHub
contributors-column-contributions = Вклад