x

Search in
Sort by:

Question Status:

Search help

  • Simple searches use one or more words. Separate the words with spaces (cat dog) to search cat,dog or both. Separate the words with plus signs (cat +dog) to search for items that may contain cat but must contain dog.
  • You can further refine your search on the search results page, where you can search by keywords, author, topic. These can be combined with each other. Examples
    • cat dog --matches anything with cat,dog or both
    • cat +dog --searches for cat +dog where dog is a mandatory term
    • cat -dog -- searches for cat excluding any result containing dog
    • [cats] —will restrict your search to results with topic named "cats"
    • [cats] [dogs] —will restrict your search to results with both topics, "cats", and "dogs"

No Owning Connection for "Player 2"'s ClientController

So, this is probably something stupid that I'm just not wrapping my head around, but I've got really baffling behavior in my example application that I haven't been able to figure out. This isn't just a C++ problem, since it includes Blueprint as well, but I suspect that if I were trying to do what I'm doing with Blueprint in C++, I'd get the same outcome.

I'm working with an example game that is very simple - there's a widget object generated in the level script that creates a button and two score counters (one for "my score" and one for "their score"). When a player clicks the button in their client, they increment their score by one and both clients should update to reflect the change in scores. However, the behavior I'm seeing when I test is that one of the clients can increment score while the other can't, instead generating a warning:

 LogNet: Warning: UIpNetDriver::ProcessRemoteFunction: No owning connection for actor NEPlayerController_0. Function Server_ScoreButtonPressed will not be processed.

So here's what I'm doing. On my player controller, I've got the following function:

.h:

 UFUNCTION(Server, Reliable, WithValidation, BlueprintCallable) void Server_ScoreButtonPressed(int32 PlayerID);

.cpp:

 void ANEPlayerController::Server_ScoreButtonPressed_Implementation(int32 PlayerId)
 {
     UE_LOG(LogTemp, Verbose, TEXT("Incrementing Player Score For Player: %i"), PlayerId);
 
     ANetworkExampleGameState* gameState = Cast<ANetworkExampleGameState>(UGameplayStatics::GetGameState(GetWorld()));
     if (gameState != nullptr)
     {
         int32 score = gameState->IncrementScore(PlayerId, 1);
         Client_TriggerScoreChangedEvent(PlayerId, score);
     }
 }

The UI itself is scripted in Blueprint because the whole point of this example game was to explore how easy it was to let designers handle UI in Blueprint while actual game logic happens on the C++ side. I've got a single widget that contains the whole UI (all three elements of it), with the following logic for constructing itself and actually responding to a button press:alt text

So I'm starting two clients and a separate server on my machine for test purposes. I've arbitrarily chosen to label the one that starts directly in editor Player 1 and the one that opens in a new editor window Player 2. When Player 1 clicks the button, everything works. When Player 2 clicks the button I get the "No owning connection for actor NEPlayerController_0" warning and nothing happens (which, since the server isn't executing the function, makes sense). Can anyone tell me what I've done wrong?

Thanks.

Product Version: UE 4.19
Tags:
more ▼

asked Jul 06 '18 at 02:13 AM in C++ Programming

avatar image

Anodoin
16 3 5

avatar image Anodoin Jul 09 '18 at 09:03 PM

For clarification: I'm launching a dedicated server and two clients from within the editor proper.

(comments are locked)
10|2000 characters needed characters left

1 answer: sort voted first

So, it turns out that I had a bunch of problems in here. Because documentation leaves a lot to be desired in this space, I'm gonna go ahead and explain a few of them in hopes that the next poor bastard who runs into this problem has a better go of it.

1) I was creating my widgets in the level script, which appears to have caused this issue. I'm not entirely certain why, but it appears that the widget was created in both viewports, but when I tried to get player controller 0 or my owning player, the function was returning client 1's client controller. I fixed this by initializing the widget in the client controller in an if(!HasAuthority()) block and setting the player owner manually.

2) I was calling a net multicast function on the client controller. This is, apparently, a really, really bad idea, since each client contains each client controller, so I was calling the function multiple times on each machine, resulting in very strange behavior. This one took me forever to figure out. I was able to move the function into a new default pawn class to fix the matter.

3) I was sending a player ID from the client to the server, when I could have simply extracted the same information on the server side, because the client controller I was called from was replicated anyway and knew which client it was on. I ended up sending a player object back to the client from the server on score change and having the widget test whether the player in question was its owner. No generation of a UUID necessary. Of course, I could have also just used the pre-existing net ID. That said, using the controller itself to determine who sent the RPC is ultimately more secure (not that a game about pressing a button really needs to be secure), since the ownership of the connection makes it impossible for non-owning controllers to simply fake which ID was their's.

I hope that if anyone else stumbled into this particularly thorny maze that you found this helpful, since I was entirely lost for a week working on what was ultimately a silly set of mistakes on my part. But, hey, what's explicit documentation good for anyway?

more ▼

answered Jul 16 '18 at 01:08 PM

avatar image

Anodoin
16 3 5

(comments are locked)
10|2000 characters needed characters left
Your answer
toggle preview:

Up to 5 attachments (including images) can be used with a maximum of 5.2 MB each and 5.2 MB total.

Follow this question

Once you sign in you will be able to subscribe for any updates here

Answers to this question