mirror of
https://github.com/space-wizards/RobustToolbox.git
synced 2026-02-15 03:30:53 +01:00
* Some stuff for auth * Holy crap auth works * Enable encryption even if no auth token is provided. It's still possible that the public key was retrieved over HTTPS via the status API, in which case it will be secure. * Fix integration test compile. * Secure CVar API. * Literally rewrite the auth protocol to be minecraft's. * Better exception tolerance in server handshake. * Auth works from launcher. * Fix some usages of UserID instead of UserName * Fix auth.server CVar * Kick existing connection if same account connects twice. * Username assignment, guest session distinguishing. * Necessary work to make bans work. * Expose LoginType to OnConnecting. * Fixing tests and warnings.
186 lines
5.3 KiB
C#
186 lines
5.3 KiB
C#
using Robust.Server.Interfaces.Player;
|
|
using Robust.Shared.GameStates;
|
|
using Robust.Shared.Interfaces.GameObjects;
|
|
using Robust.Server.GameObjects;
|
|
using System;
|
|
using Robust.Shared.Enums;
|
|
using Robust.Shared.GameObjects;
|
|
using Robust.Shared.Interfaces.Network;
|
|
using Robust.Shared.Network;
|
|
using Robust.Shared.ViewVariables;
|
|
|
|
namespace Robust.Server.Player
|
|
{
|
|
/// <summary>
|
|
/// This is the session of a connected client.
|
|
/// </summary>
|
|
internal class PlayerSession : IPlayerSession
|
|
{
|
|
private readonly PlayerManager _playerManager;
|
|
public readonly PlayerState PlayerState;
|
|
|
|
public PlayerSession(PlayerManager playerManager, INetChannel client, PlayerData data)
|
|
{
|
|
_playerManager = playerManager;
|
|
UserId = client.UserId;
|
|
Name = client.UserName;
|
|
_data = data;
|
|
|
|
PlayerState = new PlayerState
|
|
{
|
|
UserId = client.UserId,
|
|
};
|
|
|
|
ConnectedClient = client;
|
|
|
|
UpdatePlayerState();
|
|
}
|
|
|
|
[ViewVariables] public INetChannel ConnectedClient { get; }
|
|
|
|
[ViewVariables] public IEntity? AttachedEntity { get; private set; }
|
|
|
|
[ViewVariables] public EntityUid? AttachedEntityUid => AttachedEntity?.Uid;
|
|
|
|
private SessionStatus _status = SessionStatus.Connecting;
|
|
|
|
/// <inheritdoc />
|
|
public string Name { get; }
|
|
|
|
/// <inheritdoc />
|
|
[ViewVariables]
|
|
public SessionStatus Status
|
|
{
|
|
get => _status;
|
|
set
|
|
{
|
|
if (_status == value)
|
|
return;
|
|
|
|
var old = _status;
|
|
_status = value;
|
|
UpdatePlayerState();
|
|
|
|
PlayerStatusChanged?.Invoke(this, new SessionStatusEventArgs(this, old, value));
|
|
}
|
|
}
|
|
|
|
/// <inheritdoc />
|
|
public DateTime ConnectedTime { get; private set; }
|
|
|
|
/// <inheritdoc />
|
|
[ViewVariables(VVAccess.ReadWrite)]
|
|
public int VisibilityMask { get; set; } = 1;
|
|
|
|
/// <inheritdoc />
|
|
[ViewVariables]
|
|
public NetUserId UserId { get; }
|
|
|
|
private readonly PlayerData _data;
|
|
[ViewVariables] public IPlayerData Data => _data;
|
|
|
|
/// <inheritdoc />
|
|
public event EventHandler<SessionStatusEventArgs>? PlayerStatusChanged;
|
|
|
|
/// <inheritdoc />
|
|
public void AttachToEntity(IEntity a)
|
|
{
|
|
DetachFromEntity();
|
|
|
|
if (a == null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
var actorComponent = a.AddComponent<BasicActorComponent>();
|
|
actorComponent.playerSession = this;
|
|
AttachedEntity = a;
|
|
a.SendMessage(actorComponent, new PlayerAttachedMsg(this));
|
|
a.EntityManager.EventBus.RaiseEvent(EventSource.Local, new PlayerAttachSystemMessage(a, this));
|
|
UpdatePlayerState();
|
|
}
|
|
|
|
/// <inheritdoc />
|
|
public void DetachFromEntity()
|
|
{
|
|
if (AttachedEntity == null)
|
|
return;
|
|
|
|
if (AttachedEntity.Deleted)
|
|
{
|
|
throw new InvalidOperationException("Tried to detach player, but my entity does not exist!");
|
|
}
|
|
|
|
if (AttachedEntity.TryGetComponent<BasicActorComponent>(out var actor))
|
|
{
|
|
AttachedEntity.SendMessage(actor, new PlayerDetachedMsg(this));
|
|
AttachedEntity.EntityManager.EventBus.RaiseEvent(EventSource.Local, new PlayerDetachedSystemMessage(AttachedEntity));
|
|
AttachedEntity.RemoveComponent<BasicActorComponent>();
|
|
AttachedEntity = null;
|
|
UpdatePlayerState();
|
|
}
|
|
else
|
|
{
|
|
throw new InvalidOperationException("Tried to detach player, but entity does not have ActorComponent!");
|
|
}
|
|
}
|
|
|
|
/// <inheritdoc />
|
|
public void OnConnect()
|
|
{
|
|
ConnectedTime = DateTime.Now;
|
|
Status = SessionStatus.Connected;
|
|
UpdatePlayerState();
|
|
}
|
|
|
|
/// <inheritdoc />
|
|
public void OnDisconnect()
|
|
{
|
|
Status = SessionStatus.Disconnected;
|
|
|
|
DetachFromEntity();
|
|
UpdatePlayerState();
|
|
}
|
|
|
|
private void SetAttachedEntityName()
|
|
{
|
|
if (Name != null && AttachedEntity != null)
|
|
{
|
|
AttachedEntity.Name = Name;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Causes the session to switch from the lobby to the game.
|
|
/// </summary>
|
|
public void JoinGame()
|
|
{
|
|
if (ConnectedClient == null || Status == SessionStatus.InGame)
|
|
return;
|
|
|
|
Status = SessionStatus.InGame;
|
|
UpdatePlayerState();
|
|
}
|
|
|
|
public LoginType AuthType => ConnectedClient.AuthType;
|
|
|
|
private void UpdatePlayerState()
|
|
{
|
|
PlayerState.Status = Status;
|
|
PlayerState.Name = Name;
|
|
if (AttachedEntity == null)
|
|
PlayerState.ControlledEntity = null;
|
|
else
|
|
PlayerState.ControlledEntity = AttachedEntity.Uid;
|
|
|
|
_playerManager.Dirty();
|
|
}
|
|
|
|
/// <inheritdoc />
|
|
public override string ToString()
|
|
{
|
|
return Name;
|
|
}
|
|
}
|
|
}
|