Started on spawning a player actor

This commit is contained in:
AeonLucid
2022-01-13 02:00:36 +01:00
parent a7399a1960
commit 6cd03d9ff7
9 changed files with 173 additions and 20 deletions
+3 -1
View File
@@ -1,4 +1,6 @@
namespace Prospect.Unreal.Net.Player;
using Prospect.Unreal.Net.Actors;
namespace Prospect.Unreal.Runtime;
public class UPlayer
{
@@ -0,0 +1,53 @@
using System.Text;
using Prospect.Unreal.Core;
using Prospect.Unreal.Net;
using Prospect.Unreal.Net.Actors;
namespace Prospect.Unreal.Runtime;
public partial class UWorld
{
private APlayerController? SpawnPlayActor(UPlayer newPlayer, ENetRole remoteRole, FUrl inURL, FUniqueNetIdRepl uniqueId, out string error, byte inNetPlayerIndex = 0)
{
error = string.Empty;
// Make the option string.
var optionsBuilder = new StringBuilder();
foreach (var op in inURL.Options)
{
optionsBuilder.Append('?');
optionsBuilder.Append(op);
}
var options = optionsBuilder.ToString();
var gameMode = GetAuthGameMode();
if (gameMode != null)
{
var newPlayerController = gameMode.Login(newPlayer, remoteRole, inURL.Portal, options, uniqueId, out error);
if (newPlayerController == null)
{
Logger.Warning("Login failed: {Error}", error);
return null;
}
// Logger.Debug("{A} got player {B} [{C}]", newPlayerController);
// Possess the newly-spawned player.
newPlayerController.NetPlayerIndex = inNetPlayerIndex;
newPlayerController.SetRole(ENetRole.ROLE_Authority);
newPlayerController.SetReplicates(remoteRole != ENetRole.ROLE_None);
if (remoteRole == ENetRole.ROLE_AutonomousProxy)
{
newPlayerController.SetAutonomousProxy(true);
}
newPlayerController.SetPlayer(newPlayer);
gameMode.PostLogin(newPlayerController);
return newPlayerController;
}
Logger.Warning("Login failed: No game mode set");
return null;
}
}
+29 -12
View File
@@ -1,3 +1,4 @@
using System.Text;
using Prospect.Unreal.Core;
using Prospect.Unreal.Core.Names;
using Prospect.Unreal.Exceptions;
@@ -10,7 +11,7 @@ using Serilog;
namespace Prospect.Unreal.Runtime;
public abstract class UWorld : FNetworkNotify, IAsyncDisposable
public abstract partial class UWorld : FNetworkNotify, IAsyncDisposable
{
private static readonly ILogger Logger = Log.ForContext<UWorld>();
@@ -203,27 +204,28 @@ public abstract class UWorld : FNetworkNotify, IAsyncDisposable
case NMT.Login:
{
// Admit or deny the player here.
if (NMT_Login.Receive(bunch, out var clientResponse, out var requestUrl, out var uniqueIdRepl, out var onlinePlatformName))
if (NMT_Login.Receive(bunch, out var clientResponse, out var tmpRequestUrl, out var uniqueIdRepl, out var onlinePlatformName))
{
connection.ClientResponse = clientResponse;
connection.RequestURL = tmpRequestUrl;
// Only the options/portal for the URL should be used during join
var newRequestUrl = requestUrl;
var newRequestUrl = connection.RequestURL;
var oneIndex = requestUrl.IndexOf('?');
var twoIndex = requestUrl.IndexOf('#');
var oneIndex = newRequestUrl.IndexOf('?');
var twoIndex = newRequestUrl.IndexOf('#');
if (oneIndex != -1 && twoIndex != -1)
{
newRequestUrl = requestUrl.Substring(Math.Min(oneIndex, twoIndex));
newRequestUrl = newRequestUrl.Substring(Math.Min(oneIndex, twoIndex));
}
else if (oneIndex != -1)
{
newRequestUrl = requestUrl.Substring(oneIndex);
newRequestUrl = newRequestUrl.Substring(oneIndex);
}
else if (twoIndex != -1)
{
newRequestUrl = requestUrl.Substring(twoIndex);
newRequestUrl = newRequestUrl.Substring(twoIndex);
}
else
{
@@ -244,8 +246,8 @@ public abstract class UWorld : FNetworkNotify, IAsyncDisposable
if (!inUrl.Valid)
{
requestUrl = newRequestUrl;
Logger.Error("NMT_Login: Invalid URL {Url}", requestUrl);
connection.RequestURL = newRequestUrl;
Logger.Error("NMT_Login: Invalid URL {Url}", connection.RequestURL);
bunch.SetError();
break;
}
@@ -256,10 +258,10 @@ public abstract class UWorld : FNetworkNotify, IAsyncDisposable
inUrl.Options.Remove("SplitscreenCount");
inUrl.Options.Add($"SplitscreenCount={splitscreenCount}");
requestUrl = inUrl.ToString();
connection.RequestURL = inUrl.ToString();
// skip to the first option in the URL
var tmp = requestUrl.Substring(requestUrl.IndexOf('?'));
var tmp = connection.RequestURL.Substring(connection.RequestURL.IndexOf('?'));
// keep track of net id for player associated with remote connection
connection.PlayerId = uniqueIdRepl;
@@ -295,6 +297,21 @@ public abstract class UWorld : FNetworkNotify, IAsyncDisposable
break;
}
case NMT.Join:
{
if (connection.PlayerController == null)
{
// Spawn the player-actor for this network player.
Logger.Debug("Join request: {Request}", connection.RequestURL);
// TODO: Proper constructor
var inURL = new FUrl();
connection.PlayerController = SpawnPlayActor(connection, ENetRole.ROLE_AutonomousProxy, inURL, connection.PlayerId, out var errorMsg);
}
break;
}
default:
{
throw new NotImplementedException($"Unhandled control message {messageType}");