デディケイテッドサーバーへの再接続について、クライアントが抜ける際にPlayerControllerとPlayerStateをデディケーテッドサーバー上に残して再接続を許可している時間分Logout類の処理を遅延させ、
再度該当のクライアントがLoginしてきたときには該当のPlayerControllerとPlayerStateを取得して使用出来るようにしました。
このPlayerControllerとPlayerStateはGameInstanceに保管しており、ユーザーIDをKeyとして取得出来るようにしています。
遅延させている処理は下記3つになります。
・PlayerController::PawnLeavingGame
・PlayerController::OnNetCleanup
・GameMode::Logout
クライアントの再接続時にはGameModeのLoginで該当の抜ける前に使用していたPlayerControllerを返却し、
ControlChannelのReceivedBunchにて再接続のプレイヤーに対して下記のような処理を行っています。(oldController=保管していたPlayerController)
- const FString& errorMessage = gameMode->GameSession->ApproveLogin(options);
- if (errorMessage.IsEmpty())
- {
- Connection->PlayerController = oldController;
- oldController->NetConnection = Connection;
- Connection->SetClientLoginState(EClientLoginState::ReceivedJoin);
- oldController->SetReplicates(true);
- if (oldController->GetPawn()) { oldController->Possess(oldController->GetPawn()); }
- Connection->SetClientLoginState(EClientLoginState::ReceivedJoin);
- // if we’re in the middle of a transition or the client is in the wrong world, tell it to travel
- FString LevelName;
- FSeamlessTravelHandler& SeamlessTravelHandler = GEngine->SeamlessTravelHandlerForWorld(Connection->Driver->World);
- if (SeamlessTravelHandler.IsInTransition())
- {
- // tell the client to go to the destination map
- LevelName = SeamlessTravelHandler.GetDestinationMapName();
- }
- else if (!Connection->PlayerController->HasClientLoadedCurrentWorld())
- {
- // tell the client to go to our current map
- FString NewLevelName = GetOutermost()->GetName();
- UE_LOG(LogNet, Log, TEXT(“Client joined but was sent to another level. Asking client to travel to: ‘%s’”), *NewLevelName);
- LevelName = NewLevelName;
- }
- if (LevelName != TEXT(“”))
- {
- Connection->PlayerController->ClientTravel(LevelName, TRAVEL_Relative, true);
- }
- // @TODO FIXME - TEMP HACK? - clear queue on join
- Connection->QueuedBits = 0;
- }
その後、添付ファイルにあるコールスタックでデディケーテッドサーバーがクラッシュします。
PlayerControllerやPlayerStateに関しましては、現状PlayerControllerやPlayerState、その他そこに紐づくComponentやCharacter等非常にパラメーターが多く、使いまわさない場合の対応コストが高いためなるべく使いまわせるようにしたいと考えております。
そのため、DEV COMMUNITYのDeveloper Assistant AIに相談して進めていましたが、
解決しなかったため何か知見や解決方法がございましたらご教授いただけますと幸いです。
[Attachment Removed]