aboutsummaryrefslogtreecommitdiff
path: root/Minecraft.Client/Common/UI
diff options
context:
space:
mode:
authorSylvessa <225480449+sylvessa@users.noreply.github.com>2026-03-26 09:15:11 -0500
committerGitHub <noreply@github.com>2026-03-26 10:15:11 -0400
commit1a50770647c582c5ce194e5741e3014bb1c1e8b2 (patch)
tree8160994034f5f58b222032b73f8cda8c42e92479 /Minecraft.Client/Common/UI
parentdee559bd16e5fc4fb1d8cdd16e7e3924666b01c9 (diff)
Add asynchronous server joining (#1408)
Diffstat (limited to 'Minecraft.Client/Common/UI')
-rw-r--r--Minecraft.Client/Common/UI/UIScene_ConnectingProgress.cpp127
-rw-r--r--Minecraft.Client/Common/UI/UIScene_ConnectingProgress.h5
-rw-r--r--Minecraft.Client/Common/UI/UIScene_JoinMenu.cpp18
3 files changed, 150 insertions, 0 deletions
diff --git a/Minecraft.Client/Common/UI/UIScene_ConnectingProgress.cpp b/Minecraft.Client/Common/UI/UIScene_ConnectingProgress.cpp
index e10a5a62..40557cd5 100644
--- a/Minecraft.Client/Common/UI/UIScene_ConnectingProgress.cpp
+++ b/Minecraft.Client/Common/UI/UIScene_ConnectingProgress.cpp
@@ -2,6 +2,16 @@
#include "UI.h"
#include "UIScene_ConnectingProgress.h"
#include "..\..\Minecraft.h"
+#ifdef _WINDOWS64
+#include "..\..\Windows64\Network\WinsockNetLayer.h"
+#include "..\..\..\Minecraft.World\DisconnectPacket.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 +53,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_Idle && initState != WinsockNetLayer::eJoinState_Cancelled);
+ m_asyncJoinFailed = false;
+#endif
}
UIScene_ConnectingProgress::~UIScene_ConnectingProgress()
@@ -53,6 +69,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 +90,85 @@ void UIScene_ConnectingProgress::tick()
{
UIScene::tick();
+#ifdef _WINDOWS64
+ if (m_asyncJoinActive)
+ {
+ WinsockNetLayer::eJoinState state = WinsockNetLayer::GetJoinState();
+ if (state == WinsockNetLayer::eJoinState_Connecting)
+ {
+ // connecting.............
+ int attempt = WinsockNetLayer::GetJoinAttempt();
+ int maxAttempts = WinsockNetLayer::GetJoinMaxAttempts();
+ char buf[128];
+ if (attempt <= 1)
+ sprintf_s(buf, "Connecting...");
+ else
+ sprintf_s(buf, "Connecting failed, trying again (%d/%d)", attempt, maxAttempts);
+ wchar_t wbuf[128];
+ mbstowcs(wbuf, buf, 128);
+ m_labelTitle.setLabel(wstring(wbuf));
+ }
+ else if (state == WinsockNetLayer::eJoinState_Success)
+ {
+ m_asyncJoinActive = false;
+ // go go go
+ }
+ else if (state == WinsockNetLayer::eJoinState_Cancelled)
+ {
+ // cancel
+ m_asyncJoinActive = false;
+ navigateBack();
+ }
+ else if (state == WinsockNetLayer::eJoinState_Rejected)
+ {
+ // server full and banned are passed differently compared to other disconnects it seems
+ m_asyncJoinActive = false;
+ DisconnectPacket::eDisconnectReason reason = WinsockNetLayer::GetJoinRejectReason();
+ int exitReasonStringId;
+ switch (reason)
+ {
+ case DisconnectPacket::eDisconnect_ServerFull:
+ exitReasonStringId = IDS_DISCONNECTED_SERVER_FULL;
+ break;
+ case DisconnectPacket::eDisconnect_Banned:
+ exitReasonStringId = IDS_DISCONNECTED_KICKED;
+ break;
+ default:
+ exitReasonStringId = IDS_CONNECTION_LOST_SERVER;
+ break;
+ }
+ UINT uiIDA[1];
+ uiIDA[0] = IDS_CONFIRM_OK;
+ ui.RequestErrorMessage(IDS_CONNECTION_FAILED, exitReasonStringId, uiIDA, 1, ProfileManager.GetPrimaryPad(), ConnectingProgress_OnRejectedDialogOK, nullptr, nullptr);
+ }
+ else if (state == WinsockNetLayer::eJoinState_Failed)
+ {
+ // FAIL
+ m_asyncJoinActive = false;
+ m_asyncJoinFailed = true;
+
+ int maxAttempts = WinsockNetLayer::GetJoinMaxAttempts();
+ char buf[256];
+ sprintf_s(buf, "Failed to connect after %d attempts. The server may be unavailable.", maxAttempts);
+ wchar_t wbuf[256];
+ mbstowcs(wbuf, buf, 256);
+
+ // TIL that these exist
+ // not going to use a actual popup due to it requiring messing with strings which can really mess things up
+ // i dont trust myself with that
+ // these need to be touched up later as teh button is a bit offset
+ m_labelTitle.setLabel(L"Unable to connect to server");
+ m_progressBar.setLabel(wstring(wbuf));
+ m_progressBar.showBar(false);
+ m_progressBar.setVisible(true);
+ m_buttonConfirm.setVisible(true);
+ m_showingButton = true;
+ m_controlTimer.setVisible(false);
+ }
+ return;
+ }
+#endif
+
if( m_removeLocalPlayer )
{
m_removeLocalPlayer = false;
@@ -94,6 +201,8 @@ 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");
@@ -208,6 +317,17 @@ void UIScene_ConnectingProgress::handleInput(int iPad, int key, bool repeat, boo
switch(key)
{
// 4J-PB - Removed the option to cancel join - it didn't work anyway
+#ifdef _WINDOWS64
+ case ACTION_MENU_CANCEL:
+ if (pressed && m_asyncJoinActive)
+ {
+ m_asyncJoinActive = false;
+ WinsockNetLayer::CancelJoinGame();
+ navigateBack();
+ handled = true;
+ }
+ break;
+#endif
// case ACTION_MENU_CANCEL:
// {
// if(m_cancelFunc != nullptr)
@@ -250,6 +370,13 @@ void UIScene_ConnectingProgress::handlePress(F64 controlId, F64 childId)
case eControl_Confirm:
if(m_showingButton)
{
+#ifdef _WINDOWS64
+ if (m_asyncJoinFailed)
+ {
+ navigateBack();
+ }
+ else
+#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
diff --git a/Minecraft.Client/Common/UI/UIScene_ConnectingProgress.h b/Minecraft.Client/Common/UI/UIScene_ConnectingProgress.h
index 2c52284c..eaaea7f6 100644
--- a/Minecraft.Client/Common/UI/UIScene_ConnectingProgress.h
+++ b/Minecraft.Client/Common/UI/UIScene_ConnectingProgress.h
@@ -13,6 +13,11 @@ private:
void (*m_cancelFunc)(LPVOID param);
LPVOID m_cancelFuncParam;
+#ifdef _WINDOWS64
+ bool m_asyncJoinActive;
+ bool m_asyncJoinFailed;
+#endif
+
enum EControls
{
eControl_Confirm
diff --git a/Minecraft.Client/Common/UI/UIScene_JoinMenu.cpp b/Minecraft.Client/Common/UI/UIScene_JoinMenu.cpp
index 417c1700..5b83ea7c 100644
--- a/Minecraft.Client/Common/UI/UIScene_JoinMenu.cpp
+++ b/Minecraft.Client/Common/UI/UIScene_JoinMenu.cpp
@@ -583,6 +583,24 @@ void UIScene_JoinMenu::JoinGame(UIScene_JoinMenu* pClass)
// 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 = -1;
+ 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;