Merge pull request #2985 from HeatXD/drop_spectator_no_reset

Netplay/Spectating: Drop spectator without having to reset
This commit is contained in:
Connor McLaughlin 2023-07-09 23:07:33 +10:00 committed by GitHub
commit 4d262c2da7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 3424 additions and 2749 deletions

View File

@ -60,12 +60,9 @@ GGPOErrorCode Peer2PeerBackend::AddSpectator(ENetPeer* peer)
if (_num_spectators == GGPO_MAX_SPECTATORS) {
return GGPO_ERRORCODE_TOO_MANY_SPECTATORS;
}
/*
* Currently, we can only add spectators before the game starts.
*/
if (!_synchronizing) {
return GGPO_ERRORCODE_INVALID_REQUEST;
}
_synchronizing = true;
int queue = _num_spectators++;
_spectators[queue].Init(peer, queue + 1000, _local_connect_status);
@ -164,7 +161,7 @@ Peer2PeerBackend::DoPoll()
input.size = _input_size * _num_players;
_sync.GetConfirmedInputs(input.bits, _input_size * _num_players, _next_spectator_frame);
for (int i = 0; i < _num_spectators; i++) {
_spectators[i].SendInput(input);
_spectators[i].SendInput(input);
}
_next_spectator_frame++;
}
@ -721,6 +718,7 @@ Peer2PeerBackend::CheckInitialSync()
return;
}
}
for (i = 0; i < _num_spectators; i++) {
if (_spectators[i].IsInitialized() && !_spectators[i].IsSynchronized()) {
return;

View File

@ -17,13 +17,6 @@ SpectatorBackend::SpectatorBackend(GGPOSessionCallbacks* cb, int num_players, in
_inputs[i].frame = -1;
}
/*
* Initialize the UDP port
*/
// FIXME
//abort();
//_udp.Init(localport, &_poll, this);
/*
* Init the host endpoint
*/

View File

@ -63,7 +63,7 @@ int UdpProtocol::RemoteFrameDelay()const
void UdpProtocol::Init(ENetPeer* peer, int queue, UdpMsg::connect_status *status)
{
_peer = peer;
_peer = peer;
_queue = queue;
_local_connect_status = status;
@ -75,6 +75,12 @@ void UdpProtocol::Init(ENetPeer* peer, int queue, UdpMsg::connect_status *status
void
UdpProtocol::SendInput(GameInput &input)
{
// when spectating and you hit the end of the buffer its time to acknowledge that the peer is dead.
if (_queue >= 1000 && _pending_output.size() >= 63) {
Disconnect();
return;
}
if (_peer) {
if (_current_state == Running) {
/*

View File

@ -169,6 +169,7 @@ static Common::Timer s_last_host_connection_attempt;
static std::array<Peer, MAX_SPECTATORS> s_spectators;
static std::bitset<MAX_SPECTATORS> s_reset_spectators;
static s32 s_num_spectators = 0;
static s32 s_spectating_failed_count = 0;
static bool s_local_spectating;
/// GGPO
@ -848,6 +849,7 @@ void Netplay::DestroyGGPOSession()
s_ggpo = nullptr;
s_save_buffer_pool.clear();
s_local_handle = GGPO_INVALID_HANDLE;
s_spectating_failed_count = 0;
for (Peer& p : s_peers)
p.ggpo_handle = GGPO_INVALID_HANDLE;
@ -1072,10 +1074,6 @@ void Netplay::DropSpectator(s32 slot_id, DropPlayerReason reason)
enet_peer_disconnect_now(s_spectators[slot_id].peer, 0);
s_spectators[slot_id] = {};
s_num_spectators--;
// sadly we have to reset here. this really sucks for the active players since you dont really want to halt for a spectator.
// not resetting seems to be creating index out of bounds errors in the ringbuffer.
// TODO ?
Reset();
}
void Netplay::UpdateConnectingState()
@ -1973,6 +1971,15 @@ void Netplay::RunFrame()
if (GGPO_SUCCEEDED(result))
{
result = SyncInput(inputs, &disconnect_flags);
// check if you get stuck while spectating. if this is the case try to disconnect.
if (s_local_spectating && result != GGPO_OK)
{
s_spectating_failed_count++;
// after 5 seconds and still not spectating close since you are stuck.
if (s_spectating_failed_count >= 300)
CloseSessionWithError("Failed to sync spectator with host. Please try again.");
}
if (GGPO_SUCCEEDED(result))
{
// enable again when rolling back done

File diff suppressed because it is too large Load Diff