Files
GoakeFlax/Source/Game/GameMode/GameMode.cs
2023-03-02 22:07:43 +02:00

234 lines
6.6 KiB
C#

using FlaxEditor.Content.Settings;
using FlaxEngine;
using FlaxEngine.Networking;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
namespace Game
{
/// <summary>
/// The game mode logic that only exists on server.
/// </summary>
public class GameMode
{
private static GameMode currentGameMode = null;
private static bool ServerRunning => currentGameMode != null;
public const string DefaultServerAddress = "localhost";
public const ushort DefaultServerPort = 59183;
public string ServerAddress = DefaultServerAddress;
public ushort ServerPort = DefaultServerPort;
private Dictionary<uint, PlayerActor> players = new Dictionary<uint, PlayerActor>();
public static bool Connect(string ip = null, ushort port = 0)
{
Console.Clear();
if (ServerRunning)
NetworkManager_Cleanup();
var networkSettings = GameSettings.Load<NetworkSettings>();
networkSettings.Address = ip ?? DefaultServerAddress;
networkSettings.Port = port != 0 ? port : DefaultServerPort;
GameSettings.LoadAsset<NetworkSettings>().SetInstance(networkSettings);
if (NetworkManager.StartClient())
{
Console.PrintError("Server connection failed.");
return false;
}
Console.Print($"Connecting to {networkSettings.Address}:{networkSettings.Port}...");
return true;
}
public static bool StartServer(bool listenServer)
{
Console.Clear();
if (ServerRunning)
NetworkManager_Cleanup();
var networkSettings = GameSettings.Load<NetworkSettings>();
networkSettings.Address = "any";
networkSettings.Port = DefaultServerPort;
GameSettings.LoadAsset<NetworkSettings>().SetInstance(networkSettings);
currentGameMode = new GameMode()
{
ServerAddress = "localhost",
ServerPort = networkSettings.Port,
};
Console.Print("Starting server... port: " + networkSettings.Port);
#if FLAX_EDITOR
FlaxEditor.Editor.Instance.PlayModeEnd += NetworkManager_Cleanup;
#else
#endif
NetworkManager.ClientConnected += NetworkManager_ClientConnected;
NetworkManager.ClientConnecting += NetworkManager_ClientConnecting;
NetworkManager.StateChanged += NetworkManager_StateChanged;
bool failure;
if (listenServer)
failure = NetworkManager.StartHost();
else
failure = NetworkManager.StartServer();
if (failure)
{
Console.PrintError($"Failed to start the server, unable to bind to address {networkSettings.Address}:{networkSettings.Port}");
return false;
}
currentGameMode.Start();
return true;
}
public static void StopServer()
{
if (ServerRunning)
NetworkManager_Cleanup();
}
private static void NetworkManager_Cleanup()
{
if (ServerRunning)
{
NetworkManager.ClientConnected -= NetworkManager_ClientConnected;
NetworkManager.ClientConnecting -= NetworkManager_ClientConnecting;
NetworkManager.StateChanged -= NetworkManager_StateChanged;
#if FLAX_EDITOR
FlaxEditor.Editor.Instance.PlayModeEnd -= NetworkManager_Cleanup;
#else
#endif
currentGameMode = null;
}
}
private static void NetworkManager_StateChanged()
{
Console.Print("network manager state changed: " + NetworkManager.State.ToString());
}
private static void NetworkManager_ClientConnected(NetworkClient networkClient)
{
Console.Print("new client connected");
currentGameMode.OnPlayerSpawn(networkClient.ClientId);
}
private static void NetworkManager_ClientConnecting(ref NetworkClientConnectionData arg0)
{
Console.Print("new client is connecting");
bool allowConnection = true;
arg0.Result = allowConnection ? 0 : 1;
}
public void Start()
{
// When mode is started
}
public void Tick()
{
// Run on every frame
}
public void End()
{
// When win condition is met
}
public void OnClientConnect()
{
}
public void OnClientDisconnect()
{
}
public void OnClientKill()
{
}
public bool OnJoin()
{
return true;
}
public bool OnSpectate()
{
return true;
}
public bool OnPlayerRequestRespawn()
{
return true;
}
public void OnPlayerSpawn(uint clientId)
{
// Get random spawn
var spawns = Level.GetActors<Actor>().Where(x => x.Name.StartsWith("PlayerSpawn_")).ToArray();
Console.Print($"found {spawns.Length} spawns");
var randomSpawn = spawns.First();
Float3 spawnPosition = randomSpawn.Position + new Float3(0f, 4.1f, 0f);
Float3 spawnAngles = randomSpawn.Orientation.EulerAngles;
// Create player actor
string prefabPath = Path.Combine(AssetManager.ContentPath, "Common");
var playerPrefab = Content.Load<Prefab>(Path.Combine(prefabPath, "PlayerPrefab.prefab"));
if (playerPrefab == null)
Console.PrintError("GameModeManager: Failed to find PlayerPrefab");
PlayerActor playerActor = PrefabManager.SpawnPrefab(playerPrefab).As<PlayerActor>();
NetworkReplicator.AddObject(playerActor);
playerActor.hai = 123;
playerActor.Initialize(clientId);
playerActor.IsActive = true;
playerActor.Teleport(spawnPosition, spawnAngles);
//NetworkReplicator.SetObjectOwnership(playerActor, clientId);
NetworkReplicator.SpawnObject(playerActor);
}
public void OnPlayerInit()
{
}
public void OnPlayerDeath()
{
}
public void OnPlayerTakeDamage(/*entity player, float damage, entity source*/)
{
}
public Float3 OnPlayerApplyForce(/*entity player, vector force, entity source*/)
{
return Float3.Zero;
}
}
}