Added "game in progress" message for players trying to join late. Improved "unknown host" packet logging to only log when truly unknown. Correctly abort network window so game can process fatal errors instead of hanging on waiting to connect. Unexpected disconnects in lobby now correctly update the state of the game.
158 lines
3.7 KiB
C++
158 lines
3.7 KiB
C++
|
|
#include "netstartwindow.h"
|
|
#include "version.h"
|
|
#include "engineerrors.h"
|
|
#include "gstrings.h"
|
|
#include <zwidget/core/timer.h>
|
|
#include <zwidget/widgets/textlabel/textlabel.h>
|
|
#include <zwidget/widgets/pushbutton/pushbutton.h>
|
|
|
|
NetStartWindow* NetStartWindow::Instance = nullptr;
|
|
|
|
void NetStartWindow::ShowNetStartPane(const char* message, int maxpos)
|
|
{
|
|
Size screenSize = GetScreenSize();
|
|
double windowWidth = 300.0;
|
|
double windowHeight = 150.0;
|
|
|
|
if (!Instance)
|
|
{
|
|
Instance = new NetStartWindow();
|
|
Instance->SetFrameGeometry((screenSize.width - windowWidth) * 0.5, (screenSize.height - windowHeight) * 0.5, windowWidth, windowHeight);
|
|
Instance->Show();
|
|
}
|
|
|
|
Instance->SetMessage(message, maxpos);
|
|
}
|
|
|
|
void NetStartWindow::HideNetStartPane()
|
|
{
|
|
delete Instance;
|
|
Instance = nullptr;
|
|
}
|
|
|
|
void NetStartWindow::SetNetStartProgress(int pos)
|
|
{
|
|
if (Instance)
|
|
Instance->SetProgress(pos);
|
|
}
|
|
|
|
bool NetStartWindow::RunMessageLoop(bool (*newtimer_callback)(void*), void* newuserdata)
|
|
{
|
|
if (!Instance)
|
|
return false;
|
|
|
|
Instance->timer_callback = newtimer_callback;
|
|
Instance->userdata = newuserdata;
|
|
Instance->CallbackException = {};
|
|
|
|
DisplayWindow::RunLoop();
|
|
|
|
Instance->timer_callback = nullptr;
|
|
Instance->userdata = nullptr;
|
|
|
|
if (Instance->CallbackException)
|
|
std::rethrow_exception(Instance->CallbackException);
|
|
|
|
// Even though the comment in FBasicStartupScreen::NetLoop says we should return false, the old code actually throws an exception!
|
|
// This effectively also means the function always returns true...
|
|
if (!Instance->exitreason)
|
|
{
|
|
throw CExitEvent(0);
|
|
}
|
|
|
|
return Instance->exitreason;
|
|
}
|
|
|
|
void NetStartWindow::NetClose()
|
|
{
|
|
if (Instance != nullptr)
|
|
Instance->OnClose();
|
|
}
|
|
|
|
NetStartWindow::NetStartWindow() : Widget(nullptr, WidgetType::Window)
|
|
{
|
|
SetWindowBackground(Colorf::fromRgba8(51, 51, 51));
|
|
SetWindowBorderColor(Colorf::fromRgba8(51, 51, 51));
|
|
SetWindowCaptionColor(Colorf::fromRgba8(33, 33, 33));
|
|
SetWindowCaptionTextColor(Colorf::fromRgba8(226, 223, 219));
|
|
SetWindowTitle(GAMENAME);
|
|
|
|
MessageLabel = new TextLabel(this);
|
|
ProgressLabel = new TextLabel(this);
|
|
AbortButton = new PushButton(this);
|
|
|
|
MessageLabel->SetTextAlignment(TextLabelAlignment::Center);
|
|
ProgressLabel->SetTextAlignment(TextLabelAlignment::Center);
|
|
|
|
AbortButton->OnClick = [=]() { OnClose(); };
|
|
|
|
AbortButton->SetText("Abort Network Game");
|
|
|
|
CallbackTimer = new Timer(this);
|
|
CallbackTimer->FuncExpired = [=]() { OnCallbackTimerExpired(); };
|
|
CallbackTimer->Start(500);
|
|
}
|
|
|
|
void NetStartWindow::SetMessage(const std::string& message, int newmaxpos)
|
|
{
|
|
MessageLabel->SetText(message);
|
|
maxpos = newmaxpos;
|
|
}
|
|
|
|
void NetStartWindow::SetProgress(int newpos)
|
|
{
|
|
if (pos != newpos && maxpos > 1)
|
|
{
|
|
pos = newpos;
|
|
FString message;
|
|
message.Format("%d/%d", pos, maxpos);
|
|
ProgressLabel->SetText(message.GetChars());
|
|
}
|
|
}
|
|
|
|
void NetStartWindow::OnClose()
|
|
{
|
|
exitreason = false;
|
|
DisplayWindow::ExitLoop();
|
|
}
|
|
|
|
void NetStartWindow::OnGeometryChanged()
|
|
{
|
|
double w = GetWidth();
|
|
double h = GetHeight();
|
|
|
|
double y = 15.0;
|
|
double labelheight = MessageLabel->GetPreferredHeight();
|
|
MessageLabel->SetFrameGeometry(Rect::xywh(5.0, y, w - 10.0, labelheight));
|
|
y += labelheight;
|
|
|
|
labelheight = ProgressLabel->GetPreferredHeight();
|
|
ProgressLabel->SetFrameGeometry(Rect::xywh(5.0, y, w - 10.0, labelheight));
|
|
y += labelheight;
|
|
|
|
y = GetHeight() - 15.0 - AbortButton->GetPreferredHeight();
|
|
AbortButton->SetFrameGeometry((w - 200.0) * 0.5, y, 200.0, AbortButton->GetPreferredHeight());
|
|
}
|
|
|
|
void NetStartWindow::OnCallbackTimerExpired()
|
|
{
|
|
if (timer_callback)
|
|
{
|
|
bool result = false;
|
|
try
|
|
{
|
|
result = timer_callback(userdata);
|
|
}
|
|
catch (...)
|
|
{
|
|
CallbackException = std::current_exception();
|
|
}
|
|
|
|
if (result)
|
|
{
|
|
exitreason = true;
|
|
DisplayWindow::ExitLoop();
|
|
}
|
|
}
|
|
}
|