Skip to content
This repository has been archived by the owner on Aug 29, 2024. It is now read-only.

Fix player movement when on zoned servers #1235

Merged
merged 3 commits into from
Jul 29, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Fixed issue where an Actor's Spatial position was not updated if it had an owner that was not replicated.
- BeginPlay is only called once with authority per deployment for startup actors
- Fixed null pointer dereference crash when trying to initiate a Spatial connection without an existing one.
- Fixed an issue that could cause multiple Channels to be created for an Actor.

## [`0.5.0-preview`](https://github.com/spatialos/UnrealGDK/releases/tag/0.5.0-preview) - 2019-06-25
- Prevented `Spatial GDK Content` from appearing under Content Browser in the editor, as the GDK plugin does not contain any game content.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -769,6 +769,13 @@ int32 USpatialNetDriver::ServerReplicateActors_PrepConnections(const float Delta

int32 USpatialNetDriver::ServerReplicateActors_PrioritizeActors(UNetConnection* InConnection, const TArray<FNetViewer>& ConnectionViewers, const TArray<FNetworkObjectInfo*> ConsiderList, const bool bCPUSaturated, FActorPriority*& OutPriorityList, FActorPriority**& OutPriorityActors)
{
// Since this function signature is copied from NetworkDriver.cpp, I don't want to change the signature. But we expect
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

// that the input connection will be the SpatialOS server connection to the runtime (the first client connection),
// so let's make sure that assumption continues to hold.
check(InConnection != nullptr);
check(GetSpatialOSNetConnection() != nullptr);
check(InConnection == GetSpatialOSNetConnection());

// Get list of visible/relevant actors.

NetTag++;
Expand Down Expand Up @@ -865,6 +872,13 @@ int32 USpatialNetDriver::ServerReplicateActors_PrioritizeActors(UNetConnection*

void USpatialNetDriver::ServerReplicateActors_ProcessPrioritizedActors(UNetConnection* InConnection, const TArray<FNetViewer>& ConnectionViewers, FActorPriority** PriorityActors, const int32 FinalSortedCount, int32& OutUpdated)
{
// Since this function signature is copied from NetworkDriver.cpp, I don't want to change the signature. But we expect
// that the input connection will be the SpatialOS server connection to the runtime (the first client connection),
// so let's make sure that assumption continues to hold.
check(InConnection != nullptr);
check(GetSpatialOSNetConnection() != nullptr);
check(InConnection == GetSpatialOSNetConnection());

// SpatialGDK - Here Unreal would check if the InConnection was saturated (!IsNetReady) and early out. Removed this as we do not currently use channel saturation.

int32 ActorUpdatesThisConnection = 0;
Expand Down Expand Up @@ -977,7 +991,7 @@ void USpatialNetDriver::ServerReplicateActors_ProcessPrioritizedActors(UNetConne
continue;
}

Channel = CreateSpatialActorChannel(Actor, Cast<USpatialNetConnection>(InConnection));
Channel = GetOrCreateSpatialActorChannel(Actor);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the change that fixes the root cause.

if ((Channel == nullptr) && (Actor->NetUpdateFrequency < 1.0f))
{
UE_LOG(LogNetTraffic, Log, TEXT("Unable to replicate %s"), *Actor->GetName());
Expand Down Expand Up @@ -1096,11 +1110,14 @@ int32 USpatialNetDriver::ServerReplicateActors(float DeltaSeconds)
SCOPE_CYCLE_COUNTER(STAT_SpatialServerReplicateActors);

#if WITH_SERVER_CODE
if (ClientConnections.Num() == 0)
// Only process the stand-in client connection, which is the connection to the runtime itself.
// It will be responsible for replicating all actors, regardless of whether they're owned by a client.
USpatialNetConnection* SpatialConnection = GetSpatialOSNetConnection();
if (SpatialConnection == nullptr)
{
return 0;
}

check(SpatialConnection && SpatialConnection->bReliableSpatialConnection);
check(World);

int32 Updated = 0;
Expand Down Expand Up @@ -1143,10 +1160,6 @@ int32 USpatialNetDriver::ServerReplicateActors(float DeltaSeconds)

FMemMark Mark(FMemStack::Get());

// Only process the fake spatial connection. It will be responsible for replicating all actors, regardless of whether they're owned by a client.
USpatialNetConnection* SpatialConnection = Cast<USpatialNetConnection>(ClientConnections[0]);
check(SpatialConnection && SpatialConnection->bReliableSpatialConnection);

// Make a list of viewers this connection should consider
TArray<FNetViewer>& ConnectionViewers = WorldSettings->ReplicationViewers;

Expand Down Expand Up @@ -1327,7 +1340,7 @@ void USpatialNetDriver::TickFlush(float DeltaTime)
double ServerReplicateActorsTimeMs = 0.0f;
#endif // USE_SERVER_PERF_COUNTERS

if (IsServer() && ClientConnections.Num() > 0 && EntityPool->IsReady())
if (IsServer() && GetSpatialOSNetConnection() != nullptr && EntityPool->IsReady())
{
// Update all clients.
#if WITH_SERVER_CODE
Expand Down Expand Up @@ -1673,7 +1686,7 @@ USpatialActorChannel* USpatialNetDriver::GetOrCreateSpatialActorChannel(UObject*
TargetActor = Cast<AActor>(TargetObject->GetOuter());
}
check(TargetActor);
Channel = CreateSpatialActorChannel(TargetActor, GetSpatialOSNetConnection());
Channel = CreateSpatialActorChannel(TargetActor);
}
return Channel;
}
Expand All @@ -1683,27 +1696,34 @@ USpatialActorChannel* USpatialNetDriver::GetActorChannelByEntityId(Worker_Entity
return EntityToActorChannel.FindRef(EntityId);
}

USpatialActorChannel* USpatialNetDriver::CreateSpatialActorChannel(AActor* Actor, USpatialNetConnection* InConnection)
USpatialActorChannel* USpatialNetDriver::CreateSpatialActorChannel(AActor* Actor)
{
if (InConnection == nullptr)
{
return nullptr;
}
// This should only be called from GetOrCreateSpatialActorChannel, otherwise we could end up clobbering an existing channel.
m-samiec marked this conversation as resolved.
Show resolved Hide resolved

USpatialActorChannel* Channel = nullptr;
check(Actor != nullptr);
check(PackageMap != nullptr);
check(GetActorChannelByEntityId(PackageMap->GetEntityIdFromObject(Actor)) == nullptr);

USpatialNetConnection* NetConnection = GetSpatialOSNetConnection();
check(NetConnection != nullptr);

USpatialActorChannel* Channel = nullptr;
if (Actor->GetClass()->HasAnySpatialClassFlags(SPATIALCLASS_Singleton))
{
Channel = GlobalStateManager->AddSingleton(Actor);
}
else
{
#if ENGINE_MINOR_VERSION <= 20
Channel = static_cast<USpatialActorChannel*>(InConnection->CreateChannel(CHTYPE_Actor, 1));
Channel = static_cast<USpatialActorChannel*>(NetConnection->CreateChannel(CHTYPE_Actor, 1));
#else
Channel = static_cast<USpatialActorChannel*>(InConnection->CreateChannelByName(NAME_Actor, EChannelCreateFlags::OpenedLocally));
Channel = static_cast<USpatialActorChannel*>(NetConnection->CreateChannelByName(NAME_Actor, EChannelCreateFlags::OpenedLocally));
#endif
if (Channel != nullptr)
if (Channel == nullptr)
{
UE_LOG(LogSpatialOSNetDriver, Warning, TEXT("Failed to create a channel for actor %s."), *GetNameSafe(Actor));
}
else
{
Channel->SetChannelActor(Actor);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,6 @@ class SPATIALGDK_API USpatialNetDriver : public UIpNetDriver

USpatialActorChannel* GetOrCreateSpatialActorChannel(UObject* TargetObject);
USpatialActorChannel* GetActorChannelByEntityId(Worker_EntityId EntityId) const;
USpatialActorChannel* CreateSpatialActorChannel(AActor* Actor, USpatialNetConnection* InConnection);

DECLARE_DELEGATE(PostWorldWipeDelegate);

Expand Down Expand Up @@ -192,6 +191,7 @@ class SPATIALGDK_API USpatialNetDriver : public UIpNetDriver
void CreateAndInitializeCoreClasses();

void CreateServerSpatialOSNetConnection();
USpatialActorChannel* CreateSpatialActorChannel(AActor* Actor);

void QueryGSMToLoadMap();

Expand Down