using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using Robust.Shared.Enums;
using Robust.Shared.GameObjects;
using Robust.Shared.GameStates;
using Robust.Shared.Network;
using Robust.Shared.Timing;
using Robust.Shared.ViewVariables;
namespace Robust.Shared.Player;
[NotContentImplementable]
public interface ISharedPlayerManager
{
///
/// List of all connected sessions.
///
///
/// You should not modify the contents of this list.
///
ICommonSession[] Sessions { get; }
///
/// Sessions with a remote endpoint. On the server, this is equivalent to . On the client,
/// this will only ever contain
///
///
/// You should not modify the contents of this list.
///
ICommonSession[] NetworkedSessions { get; }
///
/// Dictionary mapping connected users to their sessions.
///
IReadOnlyDictionary SessionsDict { get; }
///
/// Number of players currently connected to this server.
///
int PlayerCount { get; }
///
/// Maximum number of players that can connect to this server at one time.
///
int MaxPlayers { get; }
///
/// Initializes the manager.
///
/// Maximum number of players that can connect to this server at one time. Does nothing
/// on the client.
void Initialize(int maxPlayers);
void Startup();
void Shutdown();
///
/// Indicates that some session's networked data has changed. This will cause an updated player list to be sent
/// to all players.
///
void Dirty();
///
/// The session of the local player. This will be null on the server.
///
[ViewVariables] ICommonSession? LocalSession { get; }
///
/// The user id of the local player. This will be null on the server.
///
[ViewVariables] NetUserId? LocalUser { get; }
///
/// The entity currently controlled by the local player. This will be null on the server.
///
[ViewVariables] EntityUid? LocalEntity { get; }
///
/// This gets invoked when a session's changes.
///
event EventHandler? PlayerStatusChanged;
///
/// Attempts to resolve a username into a .
///
bool TryGetUserId(string userName, out NetUserId userId);
///
/// Attempts to get the session that is currently attached to a given entity.
///
bool TryGetSessionByEntity(EntityUid uid, [NotNullWhen(true)] out ICommonSession? session);
///
/// Attempts to get the session with the given .
///
bool TryGetSessionById([NotNullWhen(true)] NetUserId? user, [NotNullWhen(true)] out ICommonSession? session);
///
/// Attempts to get the session with the given .
///
bool TryGetSessionByUsername(string username, [NotNullWhen(true)] out ICommonSession? session);
///
/// Attempts to get the session that corresponds to the given channel.
///
bool TryGetSessionByChannel(INetChannel channel, [NotNullWhen(true)] out ICommonSession? session);
///
/// Gets the session that corresponds to the given channel, throwing if it doesn't exist.
///
/// Thrown if no such session exists.
ICommonSession GetSessionByChannel(INetChannel channel) => GetSessionById(channel.UserId);
///
/// Gets the session that corresponds to the given user id, throwing if it doesn't exist.
///
/// Thrown if no such session exists.
ICommonSession GetSessionById(NetUserId user);
///
/// Check if the given user id has an active session.
///
bool ValidSessionId(NetUserId user) => TryGetSessionById(user, out _);
///
/// Alternate method to get
///
SessionData GetPlayerData(NetUserId userId);
///
/// Grabs a session's if it can be found.
///
/// The user ID to get data for.
/// The session data if found.
/// Success or failure.
bool TryGetPlayerData(NetUserId userId, [NotNullWhen(true)] out SessionData? data);
///
/// Grabs a session's if it can be found.
///
/// The username to get data for.
/// The session data if found.
/// Success or failure.
bool TryGetPlayerDataByUsername(string userName, [NotNullWhen(true)] out SessionData? data);
///
/// Checks if a given user has any .
///
bool HasPlayerData(NetUserId userId);
///
/// Returns all session data.
///
///
IEnumerable GetAllPlayerData();
void GetPlayerStates(GameTick fromTick, List states);
void UpdateState(ICommonSession commonSession);
///
void RemoveSession(ICommonSession session, bool removeData = false);
///
/// Completely destroys a session, optionally also removing its data.
///
void RemoveSession(NetUserId user, bool removeData = false);
///
/// Creates a session from a network channel.
///
ICommonSession CreateAndAddSession(INetChannel channel);
///
/// Creates a new session, without a network channel attached.
///
///
/// This should be used carefully, games tend to expect a network channel to be present unless they're client
/// side. This is for example used to create a session for singleplayer clients.
///
ICommonSession CreateAndAddSession(NetUserId user, string name);
///
/// Sets a session's attached entity, optionally kicking any sessions already attached to it.
///
/// The player whose attached entity should get updated
/// The entity to attach the player to, if any.
/// Whether to kick any existing players that are already attached to the entity
/// The player that was forcefully kicked, if any.
/// Whether the attach succeeded, or not.
bool SetAttachedEntity(
[NotNullWhen(true)] ICommonSession? session,
EntityUid? entity,
out ICommonSession? kicked,
bool force = false);
///
/// Sets a session's attached entity, optionally kicking any sessions already attached to it.
///
/// The player whose attached entity should get updated
/// The entity to attach the player to, if any.
/// Whether to kick any existing players that are already attached to the entity
/// Whether the attach succeeded, or not.
bool SetAttachedEntity([NotNullWhen(true)] ICommonSession? session, EntityUid? entity, bool force = false)
=> SetAttachedEntity(session, entity, out _, force);
///
/// Updates a session's
///
void SetStatus(ICommonSession session, SessionStatus status);
///
/// Updates a session's
///
void SetPing(ICommonSession session, short ping);
///
/// Updates a session's
///
public void SetName(ICommonSession session, string name);
///
/// Set the session's status to .
///
void JoinGame(ICommonSession session);
}