Refactor async server joining with eJoinState enum and dedicated progress UI
Replace the boolean-flag-based async join system with a clean state machine (eJoinState enum) and move connection progress handling from UIScene_JoinMenu into UIScene_ConnectingProgress as a dedicated UI class. Combines the best of two approaches: non-blocking sockets with select() timeout and SO_RCVTIMEO clearing (prevents random disconnects) with the upstream's state enum, FinalizeJoin separation, and ConnectingProgress UI. JoinGame() now returns JOINGAME_PENDING on Win64, and PlatformNetworkManagerStub::DoWork() polls the join state to finalize the connection when the background thread succeeds.
This commit is contained in:
@@ -2,6 +2,15 @@
|
||||
#include "UI.h"
|
||||
#include "UIScene_ConnectingProgress.h"
|
||||
#include "..\..\Minecraft.h"
|
||||
#ifdef _WINDOWS64
|
||||
#include "..\..\Windows64\Network\WinsockNetLayer.h"
|
||||
|
||||
static int ConnectingProgress_OnRejectedDialogOK(LPVOID, int iPad, const C4JStorage::EMessageResult)
|
||||
{
|
||||
ui.NavigateBack(iPad);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
UIScene_ConnectingProgress::UIScene_ConnectingProgress(int iPad, void *_initData, UILayer *parentLayer) : UIScene(iPad, parentLayer)
|
||||
{
|
||||
@@ -43,6 +52,12 @@ UIScene_ConnectingProgress::UIScene_ConnectingProgress(int iPad, void *_initData
|
||||
m_cancelFuncParam = param->cancelFuncParam;
|
||||
m_removeLocalPlayer = false;
|
||||
m_showingButton = false;
|
||||
#ifdef _WINDOWS64
|
||||
WinsockNetLayer::eJoinState initState = WinsockNetLayer::GetJoinState();
|
||||
m_asyncJoinActive = (initState == WinsockNetLayer::eJoinState_Connecting ||
|
||||
initState == WinsockNetLayer::eJoinState_Success);
|
||||
m_asyncJoinFailed = false;
|
||||
#endif
|
||||
}
|
||||
|
||||
UIScene_ConnectingProgress::~UIScene_ConnectingProgress()
|
||||
@@ -53,6 +68,18 @@ UIScene_ConnectingProgress::~UIScene_ConnectingProgress()
|
||||
|
||||
void UIScene_ConnectingProgress::updateTooltips()
|
||||
{
|
||||
#ifdef _WINDOWS64
|
||||
if (m_asyncJoinActive)
|
||||
{
|
||||
ui.SetTooltips(m_iPad, -1, IDS_TOOLTIPS_BACK);
|
||||
return;
|
||||
}
|
||||
if (m_asyncJoinFailed)
|
||||
{
|
||||
ui.SetTooltips(m_iPad, IDS_TOOLTIPS_SELECT, -1);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
// 4J-PB - removing the option of cancel join, since it didn't work anyway
|
||||
//ui.SetTooltips( m_iPad, -1, m_showTooltips?IDS_TOOLTIPS_CANCEL_JOIN:-1);
|
||||
ui.SetTooltips( m_iPad, -1, -1);
|
||||
@@ -62,6 +89,61 @@ void UIScene_ConnectingProgress::tick()
|
||||
{
|
||||
UIScene::tick();
|
||||
|
||||
#ifdef _WINDOWS64
|
||||
if (m_asyncJoinActive)
|
||||
{
|
||||
WinsockNetLayer::eJoinState state = WinsockNetLayer::GetJoinState();
|
||||
switch (state)
|
||||
{
|
||||
case WinsockNetLayer::eJoinState_Connecting:
|
||||
{
|
||||
int attempt = WinsockNetLayer::GetJoinAttempt();
|
||||
int maxAttempts = WinsockNetLayer::GetJoinMaxAttempts();
|
||||
wchar_t buf[128];
|
||||
if (attempt > 1)
|
||||
swprintf_s(buf, L"Connecting... (attempt %d/%d)", attempt, maxAttempts);
|
||||
else
|
||||
swprintf_s(buf, L"Connecting...");
|
||||
m_labelTitle.setLabel(buf);
|
||||
break;
|
||||
}
|
||||
case WinsockNetLayer::eJoinState_Success:
|
||||
m_asyncJoinActive = false;
|
||||
m_labelTitle.setLabel(L"Joining world...");
|
||||
break;
|
||||
case WinsockNetLayer::eJoinState_Cancelled:
|
||||
m_asyncJoinActive = false;
|
||||
navigateBack();
|
||||
break;
|
||||
case WinsockNetLayer::eJoinState_Rejected:
|
||||
{
|
||||
m_asyncJoinActive = false;
|
||||
DisconnectPacket::eDisconnectReason reason = WinsockNetLayer::GetJoinRejectReason();
|
||||
int reasonStringId = IDS_CONNECTION_LOST_SERVER;
|
||||
if (reason == DisconnectPacket::eDisconnect_ServerFull)
|
||||
reasonStringId = IDS_DISCONNECTED_SERVER_FULL;
|
||||
else if (reason == DisconnectPacket::eDisconnect_Kicked)
|
||||
reasonStringId = IDS_DISCONNECTED_KICKED;
|
||||
|
||||
UINT uiIDA[1];
|
||||
uiIDA[0] = IDS_CONFIRM_OK;
|
||||
ui.RequestErrorMessage(IDS_CONNECTION_FAILED, reasonStringId, uiIDA, 1, m_iPad, ConnectingProgress_OnRejectedDialogOK, nullptr);
|
||||
break;
|
||||
}
|
||||
case WinsockNetLayer::eJoinState_Failed:
|
||||
m_asyncJoinActive = false;
|
||||
m_asyncJoinFailed = true;
|
||||
m_labelTitle.setLabel(app.GetString(IDS_CONNECTION_FAILED));
|
||||
m_buttonConfirm.setVisible(true);
|
||||
m_showingButton = true;
|
||||
updateTooltips();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if( m_removeLocalPlayer )
|
||||
{
|
||||
m_removeLocalPlayer = false;
|
||||
@@ -94,6 +176,7 @@ void UIScene_ConnectingProgress::handleGainFocus(bool navBack)
|
||||
|
||||
void UIScene_ConnectingProgress::handleLoseFocus()
|
||||
{
|
||||
if (!m_runFailTimer) return;
|
||||
int millisecsLeft = getTimer(0)->targetTime - System::currentTimeMillis();
|
||||
int millisecsTaken = getTimer(0)->duration - millisecsLeft;
|
||||
app.DebugPrintf("\n");
|
||||
@@ -207,6 +290,18 @@ void UIScene_ConnectingProgress::handleInput(int iPad, int key, bool repeat, boo
|
||||
|
||||
switch(key)
|
||||
{
|
||||
#ifdef _WINDOWS64
|
||||
case ACTION_MENU_CANCEL:
|
||||
if (pressed && m_asyncJoinActive)
|
||||
{
|
||||
m_asyncJoinActive = false;
|
||||
WinsockNetLayer::CancelJoinGame();
|
||||
navigateBack();
|
||||
handled = true;
|
||||
return;
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
// 4J-PB - Removed the option to cancel join - it didn't work anyway
|
||||
// case ACTION_MENU_CANCEL:
|
||||
// {
|
||||
@@ -250,6 +345,13 @@ void UIScene_ConnectingProgress::handlePress(F64 controlId, F64 childId)
|
||||
case eControl_Confirm:
|
||||
if(m_showingButton)
|
||||
{
|
||||
#ifdef _WINDOWS64
|
||||
if (m_asyncJoinFailed)
|
||||
{
|
||||
navigateBack();
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
if( m_iPad != ProfileManager.GetPrimaryPad() && g_NetworkManager.IsInSession() )
|
||||
{
|
||||
// The connection failed if we see the button, so the temp player should be removed and the viewports updated again
|
||||
|
||||
@@ -12,6 +12,10 @@ private:
|
||||
bool m_showingButton;
|
||||
void (*m_cancelFunc)(LPVOID param);
|
||||
LPVOID m_cancelFuncParam;
|
||||
#ifdef _WINDOWS64
|
||||
bool m_asyncJoinActive;
|
||||
bool m_asyncJoinFailed;
|
||||
#endif
|
||||
|
||||
enum EControls
|
||||
{
|
||||
|
||||
@@ -29,8 +29,6 @@ UIScene_JoinMenu::UIScene_JoinMenu(int iPad, void *_initData, UILayer *parentLay
|
||||
m_editServerPhase = eEditServer_Idle;
|
||||
m_editServerButtonIndex = -1;
|
||||
m_deleteServerButtonIndex = -1;
|
||||
m_asyncJoinInProgress = false;
|
||||
m_joinLocalUsersMask = 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -64,35 +62,6 @@ void UIScene_JoinMenu::updateTooltips()
|
||||
|
||||
void UIScene_JoinMenu::tick()
|
||||
{
|
||||
#ifdef _WINDOWS64
|
||||
if (m_asyncJoinInProgress && WinsockNetLayer::IsJoinComplete())
|
||||
{
|
||||
m_asyncJoinInProgress = false;
|
||||
if (WinsockNetLayer::GetJoinResult())
|
||||
{
|
||||
int result = g_NetworkManager.FinishJoinGame(m_selectedSession);
|
||||
app.SetLiveLinkRequired(false);
|
||||
if (result != CGameNetworkManager::JOINGAME_SUCCESS)
|
||||
{
|
||||
m_bIgnoreInput = false;
|
||||
m_buttonJoinGame.setLabel(app.GetString(IDS_JOIN_GAME));
|
||||
updateTooltips();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
app.SetLiveLinkRequired(false);
|
||||
m_bIgnoreInput = false;
|
||||
m_buttonJoinGame.setLabel(app.GetString(IDS_JOIN_GAME));
|
||||
updateTooltips();
|
||||
|
||||
UINT uiIDA[1];
|
||||
uiIDA[0] = IDS_CONFIRM_OK;
|
||||
ui.RequestErrorMessage(IDS_CONNECTION_FAILED, IDS_CONNECTION_LOST_SERVER, uiIDA, 1, ProfileManager.GetPrimaryPad());
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if( !m_friendInfoRequestIssued )
|
||||
{
|
||||
ui.NavigateToScene(m_iPad, eUIScene_Timer);
|
||||
@@ -316,19 +285,6 @@ wstring UIScene_JoinMenu::getMoviePath()
|
||||
|
||||
void UIScene_JoinMenu::handleInput(int iPad, int key, bool repeat, bool pressed, bool released, bool &handled)
|
||||
{
|
||||
#ifdef _WINDOWS64
|
||||
if (m_asyncJoinInProgress && key == ACTION_MENU_CANCEL && pressed)
|
||||
{
|
||||
g_NetworkManager.CancelJoinGame(nullptr);
|
||||
m_asyncJoinInProgress = false;
|
||||
m_bIgnoreInput = false;
|
||||
m_buttonJoinGame.setLabel(app.GetString(IDS_JOIN_GAME));
|
||||
updateTooltips();
|
||||
handled = true;
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
if(m_bIgnoreInput) return;
|
||||
|
||||
ui.AnimateKeyPress(m_iPad, key, repeat, pressed, released);
|
||||
@@ -625,23 +581,28 @@ void UIScene_JoinMenu::JoinGame(UIScene_JoinMenu* pClass)
|
||||
ProfileManager.DisplaySystemMessage( SCE_MSG_DIALOG_SYSMSG_TYPE_TRC_PSN_CHAT_RESTRICTION, ProfileManager.GetPrimaryPad() );
|
||||
}
|
||||
#endif
|
||||
#ifdef _WINDOWS64
|
||||
if (g_NetworkManager.BeginJoinGameAsync(pClass->m_selectedSession, dwLocalUsersMask))
|
||||
{
|
||||
pClass->m_asyncJoinInProgress = true;
|
||||
pClass->m_joinLocalUsersMask = dwLocalUsersMask;
|
||||
pClass->m_buttonJoinGame.setLabel(app.GetString(IDS_PROGRESS_CONNECTING));
|
||||
ui.SetTooltips(DEFAULT_XUI_MENU_USER, -1, IDS_TOOLTIPS_CANCEL_JOIN);
|
||||
return;
|
||||
}
|
||||
CGameNetworkManager::eJoinGameResult result = CGameNetworkManager::JOINGAME_FAIL_GENERAL;
|
||||
#else
|
||||
CGameNetworkManager::eJoinGameResult result = g_NetworkManager.JoinGame( pClass->m_selectedSession, dwLocalUsersMask );
|
||||
#endif
|
||||
|
||||
// Alert the app the we no longer want to be informed of ethernet connections
|
||||
app.SetLiveLinkRequired( false );
|
||||
|
||||
#ifdef _WINDOWS64
|
||||
if (result == CGameNetworkManager::JOINGAME_PENDING)
|
||||
{
|
||||
pClass->m_bIgnoreInput = false;
|
||||
ConnectionProgressParams *param = new ConnectionProgressParams();
|
||||
param->iPad = ProfileManager.GetPrimaryPad();
|
||||
param->stringId = IDS_PROGRESS_CONNECTING;
|
||||
param->showTooltips = true;
|
||||
param->setFailTimer = false;
|
||||
param->timerTime = 0;
|
||||
param->cancelFunc = nullptr;
|
||||
param->cancelFuncParam = nullptr;
|
||||
ui.NavigateToScene(ProfileManager.GetPrimaryPad(), eUIScene_ConnectingProgress, param);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
if( result != CGameNetworkManager::JOINGAME_SUCCESS )
|
||||
{
|
||||
int exitReasonStringId = -1;
|
||||
|
||||
@@ -70,8 +70,6 @@ private:
|
||||
wstring m_editServerPort;
|
||||
int m_editServerButtonIndex;
|
||||
int m_deleteServerButtonIndex;
|
||||
bool m_asyncJoinInProgress;
|
||||
DWORD m_joinLocalUsersMask;
|
||||
#endif
|
||||
|
||||
public:
|
||||
|
||||
Reference in New Issue
Block a user