185 lines
6.3 KiB
C#
Executable File
185 lines
6.3 KiB
C#
Executable File
using System.Collections.Generic;
|
|
using RebootKit.Engine.Main;
|
|
using RebootKit.Engine.Services.Console;
|
|
using RebootKit.Engine.Services.Simulation;
|
|
using RebootReality.jelycho.Player;
|
|
using Unity.Collections;
|
|
using Unity.Netcode;
|
|
using UnityEngine;
|
|
using UnityEngine.Assertions;
|
|
using Logger = RebootKit.Engine.Foundation.Logger;
|
|
|
|
namespace RebootReality.jelycho.Main {
|
|
class PlayerState : INetworkSerializable {
|
|
public ulong clientID;
|
|
|
|
public PlayerController Controller;
|
|
public PlayerActor Actor;
|
|
|
|
public void NetworkSerialize<T>(BufferSerializer<T> serializer) where T : IReaderWriter { }
|
|
}
|
|
|
|
public class JelychoGame : Game {
|
|
static readonly Logger s_Logger = new Logger(nameof(JelychoGame));
|
|
|
|
[Header("Gameplay")]
|
|
[SerializeField] GameWorldController m_GameWorldControllerPrefab;
|
|
|
|
public GameWorldController m_GameWorldController;
|
|
|
|
[Header("Player")]
|
|
[SerializeField] PlayerController m_PlayerControllerPrefab;
|
|
[SerializeField] PlayerActor m_PlayerActorPrefab;
|
|
|
|
readonly List<PlayerState> m_PlayerStates = new List<PlayerState>();
|
|
|
|
void Awake() { }
|
|
|
|
public override void OnDestroy() {
|
|
base.OnDestroy();
|
|
}
|
|
|
|
public override void OnNetworkSpawn() {
|
|
base.OnNetworkSpawn();
|
|
|
|
NetworkManager.Singleton.OnClientConnectedCallback += OnClientConnected;
|
|
NetworkManager.Singleton.OnClientDisconnectCallback += OnClientStopped;
|
|
}
|
|
|
|
public override void OnNetworkDespawn() {
|
|
base.OnNetworkDespawn();
|
|
|
|
NetworkManager.Singleton.OnClientConnectedCallback -= OnClientConnected;
|
|
NetworkManager.Singleton.OnClientDisconnectCallback -= OnClientStopped;
|
|
}
|
|
|
|
void OnClientConnected(ulong clientID) {
|
|
s_Logger.Info($"Client {clientID} connected");
|
|
|
|
if (IsServer) {
|
|
s_Logger.Info($"Creating player state for client {clientID}");
|
|
|
|
PlayerController controller = Instantiate(m_PlayerControllerPrefab);
|
|
controller.name = $"PlayerController_{clientID}";
|
|
controller.NetworkObject.SpawnAsPlayerObject(clientID);
|
|
|
|
m_PlayerStates.Add(new PlayerState {
|
|
clientID = clientID,
|
|
Controller = controller,
|
|
});
|
|
}
|
|
}
|
|
|
|
void OnClientStopped(ulong clientID) {
|
|
s_Logger.Info($"Client {clientID} disconnected");
|
|
|
|
if (IsServer) {
|
|
for (int i = m_PlayerStates.Count - 1; i >= 0; i--) {
|
|
if (m_PlayerStates[i].clientID == clientID) {
|
|
s_Logger.Info($"Removing player state for client {clientID}");
|
|
m_PlayerStates.RemoveAtSwapBack(i);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
public override void OnWorldLoaded() {
|
|
base.OnWorldLoaded();
|
|
|
|
if (IsServer) {
|
|
m_GameWorldController = Instantiate(m_GameWorldControllerPrefab);
|
|
m_GameWorldController.NetworkObject.Spawn();
|
|
}
|
|
|
|
OnPlayerReadyRpc(NetworkManager.Singleton.LocalClientId);
|
|
}
|
|
|
|
public override void OnWorldUnload() {
|
|
base.OnWorldUnload();
|
|
|
|
if (IsServer) {
|
|
m_GameWorldController.NetworkObject.Despawn();
|
|
Destroy(m_GameWorldController.gameObject);
|
|
}
|
|
}
|
|
|
|
[Rpc(SendTo.Server)]
|
|
void OnPlayerReadyRpc(ulong clientID) {
|
|
if (!IsServer) {
|
|
return;
|
|
}
|
|
|
|
PlayerActor actor = Instantiate(m_PlayerActorPrefab);
|
|
actor.name = $"PlayerActor_{clientID}";
|
|
actor.NetworkObject.SpawnAsPlayerObject(clientID);
|
|
|
|
PlayerState playerState = GetPlayerState(clientID);
|
|
Assert.IsNotNull(playerState);
|
|
playerState.Actor = actor;
|
|
playerState.Controller.SetActorClientRpc(actor.NetworkObjectId);
|
|
}
|
|
|
|
PlayerState GetPlayerState(ulong clientID) {
|
|
foreach (PlayerState state in m_PlayerStates) {
|
|
if (state.clientID == clientID) {
|
|
return state;
|
|
}
|
|
}
|
|
|
|
s_Logger.Error($"Player state for client {clientID} not found");
|
|
return null;
|
|
}
|
|
}
|
|
|
|
public static class JelychoConsoleCommands {
|
|
[RCCMD("worlds", "Lists all worlds")]
|
|
public static void Worlds(string[] args) {
|
|
if (args.Length != 1) {
|
|
RR.WriteToConsole($"Usage: {args[0]}");
|
|
return;
|
|
}
|
|
|
|
RR.WriteToConsole("Worlds:");
|
|
foreach (WorldConfigAsset worldConfigAsset in RR.WorldConfigsAssets) {
|
|
RR.WriteToConsole($" {worldConfigAsset.Config.name}");
|
|
}
|
|
}
|
|
|
|
[RCCMD("connect", "Connects to a server with given Steam ID. Usage: connect <steam_id>")]
|
|
public static void ConnectToServer(string[] args) {
|
|
if (args.Length < 1 || args.Length > 2) {
|
|
RR.WriteToConsole($"Usage: {args[0]} <steam_id>");
|
|
return;
|
|
}
|
|
|
|
RR.WriteToConsole("Connecting to server...");
|
|
|
|
if (args.Length != 2) {
|
|
RR.WriteToConsole($"Usage: {args[0]} <steam_id>");
|
|
return;
|
|
}
|
|
|
|
if (ulong.TryParse(args[1], out ulong steamID)) {
|
|
RR.ConnectWithSteamID(steamID);
|
|
} else {
|
|
RR.WriteToConsole($"Invalid Steam ID: {args[1]}");
|
|
}
|
|
}
|
|
|
|
[RCCMD("disconnect", "Disconnects from the current server")]
|
|
public static void DisconnectFromServer(string[] args) {
|
|
if (args.Length != 1) {
|
|
RR.WriteToConsole($"Usage: {args[0]}");
|
|
return;
|
|
}
|
|
|
|
RR.Disconnect();
|
|
}
|
|
|
|
[RCCMD("version", "Displays the current game version")]
|
|
public static void GameVersion(string[] args) {
|
|
RR.WriteToConsole($"Game version: {Application.version}");
|
|
}
|
|
}
|
|
} |