Early in the implementation of UNetConnection::CleanUp, Driver->ServerConnection is set to nullptr. Then, ConditionalCleanUp is called on each open channel in turn.
Here’s the problem:
bool UActorChannel::CleanUp(const bool bForDestroy, EChannelCloseReason CloseReason) { //... const bool bIsServer = Connection->Driver->IsServer();
Now that the driver’s ServerConnection has been nulled, IsServer() is going to return true even if this is a client driver, causing important code to be skipped in ActorChannel::CleanUp. The fix I’ve made in our codebase is to move the clearing of ServerConnection past the channel cleanup in UNetConnection::CleanUp.
Steps to Reproduce
Call UNetConnection::CleanUp() on an open ServerConnection in the NetDriver.
Hi,
I haven’t been able to reproduce this issue in my own test project, and I haven’t seen any reports of similar problems.
Are you manually calling UNetConnection::CleanUp? Or are you able to reproduce this behavior when using something like the “Disconnect” command or when calling UNetConnection::Close?
Thanks,
Alex
We’re manually calling Connection::CleanUp on the client in the case that leads to bad behavior. The why behind that is complex, but it should be pretty straightforward to verify that this leads to channel cleanup operating as if it’s the server.
Hi,
I don’t believe it is generally a recommended operation for a project to call UNetConnection::CleanUp directly. Disconnecting a client is often handled by shutting down the NetDriver (usually done when traveling to a different map), which calls UNetConnection::Close.
Given that it’s not a common practice to call CleanUp directly, I don’t think this is something we’d open a new issue for. However, I can see that calling this directly would result in the problem you’ve described, and I do think your workaround is reasonable. If you run into any further problems or are able to reproduce the issue through another disconnect flow, please don’t hesitate to reach out.
Thanks,
Alex