Топ контрибюторов в лобби (#1828)
This commit is contained in:
parent
a5a2bbd386
commit
091f0b22ee
18 changed files with 558 additions and 6 deletions
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
@ -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}"));
|
||||
}
|
||||
}
|
||||
29
Content.Client/_Sunrise/Contributors/ContributorsManager.cs
Normal file
29
Content.Client/_Sunrise/Contributors/ContributorsManager.cs
Normal 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);
|
||||
}
|
||||
}
|
||||
30
Content.Client/_Sunrise/Contributors/ContributorsTop.xaml
Normal file
30
Content.Client/_Sunrise/Contributors/ContributorsTop.xaml
Normal 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>
|
||||
54
Content.Client/_Sunrise/Contributors/ContributorsTop.xaml.cs
Normal file
54
Content.Client/_Sunrise/Contributors/ContributorsTop.xaml.cs
Normal 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
|
|
|||
204
Content.Server/_Sunrise/Contributors/ContributorsManager.cs
Normal file
204
Content.Server/_Sunrise/Contributors/ContributorsManager.cs
Normal 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; }
|
||||
}
|
||||
}
|
||||
12
Content.Shared/_Sunrise/Contributors/ContributorEntry.cs
Normal file
12
Content.Shared/_Sunrise/Contributors/ContributorEntry.cs
Normal 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);
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -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)
|
||||
|
|
|
|||
8
Resources/Locale/ru-RU/contributors/contributors.ftl
Normal file
8
Resources/Locale/ru-RU/contributors/contributors.ftl
Normal 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 = Вклад
|
||||
Loading…
Add table
Reference in a new issue