This commit is contained in:
Oscar
2025-06-10 02:09:21 +03:00
parent 38754d2b59
commit 6e784491fd
34 changed files with 1429 additions and 574 deletions

View File

@@ -2,94 +2,105 @@
@using Sandbox.UI;
@inherits PanelComponent
<root class="@(Visible ? "" : "hidden")">
@* <div class="decoration top-left"></div> *@
@* <div class="decoration top-right"></div> *@
@* <div class="decoration bottom-left"></div> *@
@* <div class="decoration bottom-right"></div> *@
<label class="title">Players</label>
<div class="content">
<div class="header">
<label class="column nick">Player</label>
<label class="column status">Status</label>
<label class="column ping">Ping</label>
</div>
<div class="player-list">
@if (Dedugan.All is not null)
{
foreach (var ded in Dedugan.All)
{
<div class="player" onclick="@(() => OpenProfile(ded.Connection))">
<div class="avatar">
<img src="avatar:@ded.SteamID"/>
</div>
<label class="column nick">@ded.Connection.DisplayName</label>
<label class="column status">@GetPlayerStatus(ded.Connection)</label>
<label class="column ping">@ded.Connection.Ping</label>
</div>
}
}
</div>
</div>
<root class="@( Visible ? "" : "hidden" )">
@* <div class="decoration top-left"></div> *@
@* <div class="decoration top-right"></div> *@
@* <div class="decoration bottom-left"></div> *@
@* <div class="decoration bottom-right"></div> *@
<label class="title">Players</label>
<div class="content">
<div class="header">
<label class="column nick">Player</label>
<label class="column status">Status</label>
<label class="column ping">Ping</label>
</div>
<div class="player-list">
@if ( Dedugan.All is not null )
{
foreach ( var ded in Dedugan.All )
{
<div class="player" onclick="@( () => OpenProfile( ded.Connection ) )">
<div class="avatar">
<img src="avatar:@ded.SteamID"/>
</div>
<label class="column nick">@ded.Connection.DisplayName</label>
<label class="column status">@GetPlayerStatus( ded.Connection )</label>
<label class="column ping">@ded.Connection.Ping</label>
</div>
}
}
</div>
</div>
</root>
@code
{
public static bool Visible => Input.Down("Score");
private NetworkManager _networkManager;
private NetworkManager NetworkManager
{
get
{
if (_networkManager == null || !_networkManager.IsValid)
{
_networkManager = Scene.Directory.FindByName("Network Manager")
.FirstOrDefault()?
.GetComponent<NetworkManager>();
}
return _networkManager;
}
}
public static bool Visible = false;
private NetworkManager _networkManager;
protected override void OnEnabled()
{
// Кэшируем NetworkManager при включении компонента
_networkManager = Scene.Directory.FindByName("Network Manager")
.FirstOrDefault()?
.GetComponent<NetworkManager>();
}
private NetworkManager NetworkManager
{
get
{
if ( _networkManager == null || !_networkManager.IsValid )
{
_networkManager = Scene.Directory.FindByName( "Network Manager" )
.FirstOrDefault()?
.GetComponent<NetworkManager>();
}
private string GetPlayerStatus(Connection conn)
{
var playerObj = Dedugan.GetByID( conn.Id ).GameObject;
return playerObj?.IsValid == true ? "In Game" : "Connecting";
}
return _networkManager;
}
}
private void OpenProfile(Connection connection)
{
Log.Info($"Opening profile: {connection.SteamId}");
Game.Overlay.ShowPlayer(connection.SteamId);
}
protected override int BuildHash()
{
if (!Visible || Dedugan.All == null)
return -1;
var hash = new System.HashCode();
hash.Add(Visible);
foreach (var ded in Dedugan.All)
{
hash.Add(ded.Id);
hash.Add(ded.Connection.Ping);
hash.Add(ded.Name);
}
return hash.ToHashCode();
}
protected override void OnUpdate()
{
if ( Input.Pressed( "Score" ) )
{
Visible = !Visible;
}
}
protected override void OnEnabled()
{
// Кэшируем NetworkManager при включении компонента
_networkManager = Scene.Directory.FindByName( "Network Manager" )
.FirstOrDefault()?
.GetComponent<NetworkManager>();
}
private string GetPlayerStatus( Connection conn )
{
var playerObj = Dedugan.GetByID( conn.Id ).GameObject;
return playerObj?.IsValid == true ? "In Game" : "Connecting";
}
private void OpenProfile( Connection connection )
{
Log.Info( $"Opening profile: {connection.SteamId}" );
Game.Overlay.ShowPlayer( connection.SteamId );
}
protected override int BuildHash()
{
base.BuildHash();
if ( !Visible || Dedugan.All == null )
return -1;
var hash = new System.HashCode();
hash.Add( Visible );
foreach ( var ded in Dedugan.All )
{
hash.Add( ded.Id );
hash.Add( ded.Connection.Ping );
hash.Add( ded.Name );
}
return hash.ToHashCode();
}
}

View File

@@ -1,191 +1,191 @@
Scoreboard {
background: linear-gradient(135deg, #0a1a2b 0%, #08111f 100%);
border: 3px solid #2a3d54;
border-radius: 16px;
//box-shadow:
// 0 0 15px rgba(0, 150, 255, 0.2),
// inset 0 0 10px rgba(0, 100, 200, 0.1);
font-family: 'Orbitron', 'Poppins', sans-serif;
background: linear-gradient(135deg, #0a1a2b 0%, #08111f 100%);
border: 3px solid #2a3d54;
border-radius: 14px;
//box-shadow:
// 0 0 15px rgba(0, 150, 255, 0.2),
// inset 0 0 10px rgba(0, 100, 200, 0.1);
font-family: 'Orbitron', 'Poppins', sans-serif;
position: absolute;
width: 30%;
height: 96vh;
top: 20px;
left: 20px;
padding: 30px;
display: flex;
flex-direction: column;
gap: 20px;
transition: all 0.2s ease;
z-index: 100;
overflow: hidden;
&.hidden {
opacity: 0;
}
.decoration {
position: absolute;
width: 60%;
height: 70vh;
top: 15vh;
left: 20%;
padding: 30px;
width: 60px;
height: 60px;
border: 2px solid rgba(0, 180, 255, 0.25);
opacity: 0.8;
box-shadow: 0 0 8px rgba(100, 200, 255, 0.1);
&.top-left {
top: 10px;
left: 10px;
border-right: none;
border-bottom: none;
border-radius: 12px 0 0 0;
}
&.top-right {
top: 10px;
right: 10px;
border-left: none;
border-bottom: none;
border-radius: 0 12px 0 0;
}
&.bottom-left {
bottom: 10px;
left: 10px;
border-right: none;
border-top: none;
border-radius: 0 0 0 12px;
}
&.bottom-right {
bottom: 10px;
right: 10px;
border-left: none;
border-top: none;
border-radius: 0 0 12px 0;
}
}
.title {
font-size: 24px;
color: #a0e0ff;
text-align: center;
//text-shadow:
// 0 0 10px rgba(100, 200, 255, 0.7),
// 0 0 20px rgba(80, 180, 255, 0.4);
letter-spacing: 4px;
margin-bottom: 15px;
font-weight: 600;
text-transform: uppercase;
}
.content {
display: flex;
flex-direction: column;
gap: 20px;
transition: all 0.2s ease;
z-index: 100;
background-color: rgba(10, 25, 40, 0.6);
border-radius: 12px;
border: 1px solid #253a50;
overflow: hidden;
flex-grow: 1;
//box-shadow: inset 0 0 20px rgba(0, 30, 60, 0.5);
&.hidden {
opacity: 0;
}
.header {
display: flex;
padding: 15px 20px 15px 85px;
background: linear-gradient(90deg, #0f2a42 0%, #0a1d30 100%);
border-bottom: 2px solid #1e3a5c;
text-shadow: 0 0 5px rgba(100, 200, 255, 0.5);
.decoration {
position: absolute;
width: 60px;
height: 60px;
border: 2px solid rgba(0, 180, 255, 0.25);
opacity: 0.8;
box-shadow: 0 0 8px rgba(100, 200, 255, 0.1);
&.top-left {
top: 10px;
left: 10px;
border-right: none;
border-bottom: none;
border-radius: 12px 0 0 0;
}
&.top-right {
top: 10px;
right: 10px;
border-left: none;
border-bottom: none;
border-radius: 0 12px 0 0;
}
&.bottom-left {
bottom: 10px;
left: 10px;
border-right: none;
border-top: none;
border-radius: 0 0 0 12px;
}
&.bottom-right {
bottom: 10px;
right: 10px;
border-left: none;
border-top: none;
border-radius: 0 0 12px 0;
}
}
.title {
font-size: 42px;
color: #a0e0ff;
text-align: center;
//text-shadow:
// 0 0 10px rgba(100, 200, 255, 0.7),
// 0 0 20px rgba(80, 180, 255, 0.4);
letter-spacing: 4px;
margin-bottom: 15px;
.column {
font-size: 18px;
color: #6eb4ff;
font-weight: 600;
text-transform: uppercase;
letter-spacing: 1px;
&.nick {
flex: 1;
text-align: left;
}
&.status {
flex: 1;
text-align: left;
}
&.ping {
flex: 1;
text-align: right;
padding-right: 20px;
}
}
}
.content {
.player-list {
pointer-events: all;
flex-grow: 1;
height: 100%;
flex-direction: column;
overflow-x: hidden;
overflow-y: scroll;
.player {
flex-shrink: 0;
display: flex;
flex-direction: column;
background-color: rgba(10, 25, 40, 0.6);
border-radius: 12px;
border: 1px solid #253a50;
overflow: hidden;
flex-grow: 1;
//box-shadow: inset 0 0 20px rgba(0, 30, 60, 0.5);
align-items: center;
padding: 16px 0 16px 24px;
transition: all 0.2s ease;
width: 100%;
//background: rgba(15, 30, 50, 0.4);
border-bottom: 1px solid rgba(40, 80, 120, 0.2);
cursor: pointer;
.header {
display: flex;
padding: 15px 20px 15px 85px;
background: linear-gradient(90deg, #0f2a42 0%, #0a1d30 100%);
border-bottom: 2px solid #1e3a5c;
text-shadow: 0 0 5px rgba(100, 200, 255, 0.5);
.column {
font-size: 18px;
color: #6eb4ff;
font-weight: 600;
letter-spacing: 1px;
&.nick {
flex: 3;
text-align: left;
}
&.status {
flex: 1;
text-align: center;
}
&.ping {
flex: 1;
text-align: right;
padding-right: 20px;
}
}
&:hover {
//background: rgba(25, 60, 90, 0.4);
box-shadow: 0 0 15px rgba(0, 150, 255, 0.1);
}
.player-list {
pointer-events: all;
flex-grow: 1;
.avatar {
width: 45px;
height: 45px;
border-radius: 4px;
overflow: hidden;
margin-right: 20px;
border: 2px solid #2a4a6b;
box-shadow: 0 0 8px rgba(100, 180, 255, 0.2);
background: #0c1a2a;
img {
width: 100%;
height: 100%;
flex-direction: column;
overflow-x: hidden;
overflow-y: scroll;
.player {
flex-shrink: 0;
display: flex;
align-items: center;
padding: 15px 25px;
transition: all 0.2s ease;
width: 100%;
//background: rgba(15, 30, 50, 0.4);
border-bottom: 1px solid rgba(40, 80, 120, 0.2);
cursor: pointer;
&:hover {
//background: rgba(25, 60, 90, 0.4);
box-shadow: 0 0 15px rgba(0, 150, 255, 0.1);
}
.avatar {
width: 45px;
height: 45px;
border-radius: 4px;
overflow: hidden;
margin-right: 20px;
border: 2px solid #2a4a6b;
box-shadow: 0 0 8px rgba(100, 180, 255, 0.2);
background: #0c1a2a;
img {
width: 100%;
height: 100%;
object-fit: cover;
}
}
.column {
font-size: 17px;
color: #c0e8ff;
text-shadow: 0 0 5px rgba(100, 180, 255, 0.3);
&.nick {
flex: 3;
text-align: left;
font-weight: 500;
letter-spacing: 0.5px;
}
&.status {
flex: 1;
text-align: center;
color: #6ecbff;
}
&.ping {
flex: 1;
text-align: right;
padding-right: 20px;
font-family: 'Courier New', monospace;
color: #88d6ff;
}
}
}
object-fit: cover;
}
}
.column {
font-size: 17px;
color: #c0e8ff;
text-shadow: 0 0 5px rgba(100, 180, 255, 0.3);
&.nick {
flex: 3;
text-align: left;
font-weight: 500;
letter-spacing: 0.5px;
}
&.status {
flex: 1;
text-align: center;
color: #6ecbff;
}
&.ping {
flex: 1;
text-align: right;
padding-right: 20px;
font-family: 'Courier New', monospace;
color: #88d6ff;
}
}
}
}
}
}