Files
mcpe/source/client/gui/screens/JoinGameScreen.cpp
2023-08-06 12:59:46 +03:00

179 lines
4.6 KiB
C++

/********************************************************************
Minecraft: Pocket Edition - Decompilation Project
Copyright (C) 2023 iProgramInCpp
The following code is licensed under the BSD 1 clause license.
SPDX-License-Identifier: BSD-1-Clause
********************************************************************/
#include "JoinGameScreen.hpp"
#include "DirectConnectScreen.hpp"
#include "ProgressScreen.hpp"
#include "StartMenuScreen.hpp"
JoinGameScreen::JoinGameScreen() :
m_btnJoin(2, "Join Game"),
m_btnDirectConnect(3, "Direct Connect"),
m_btnBack(4, "Back")
{
}
JoinGameScreen::~JoinGameScreen()
{
if (m_pAvailableGamesList)
delete m_pAvailableGamesList;
}
void JoinGameScreen::buttonClicked(Button* pButton)
{
if (pButton->m_buttonId == m_btnJoin.m_buttonId)
{
if (isIndexValid(m_pAvailableGamesList->m_selectedIndex))
{
m_pMinecraft->joinMultiplayer(m_pAvailableGamesList->m_games[m_pAvailableGamesList->m_selectedIndex]);
m_pMinecraft->setScreen(new ProgressScreen);
m_btnJoin.m_bEnabled = false;
m_btnDirectConnect.m_bEnabled = false;
m_btnBack.m_bEnabled = false;
}
}
if (pButton->m_buttonId == m_btnDirectConnect.m_buttonId)
{
m_pMinecraft->setScreen(new DirectConnectScreen);
}
if (pButton->m_buttonId == m_btnBack.m_buttonId)
{
m_pMinecraft->setScreen(new StartMenuScreen);
}
}
bool JoinGameScreen::handleBackEvent(bool b)
{
if (!b)
{
m_pMinecraft->cancelLocateMultiplayer();
m_pMinecraft->setScreen(new StartMenuScreen);
}
return true;
}
void JoinGameScreen::init()
{
const int BUTTON_WIDTH = 120;
m_btnBack.m_yPos = m_btnJoin.m_yPos = m_btnDirectConnect.m_yPos = m_height - 27;
m_btnBack.m_width = m_btnJoin.m_width = BUTTON_WIDTH;
m_btnJoin.m_xPos = m_width / 2 - (BUTTON_WIDTH + (BUTTON_WIDTH / 2)) - 4;
m_btnDirectConnect.m_xPos = (m_width / 2) - (BUTTON_WIDTH / 2);
m_btnBack.m_xPos = m_width / 2 + 4 + (BUTTON_WIDTH / 2);
m_btnDirectConnect.m_width = 120;
m_buttons.push_back(&m_btnJoin);
m_buttons.push_back(&m_btnDirectConnect);
m_buttons.push_back(&m_btnBack);
m_pMinecraft->m_pRakNetInstance->clearServerList();
m_pAvailableGamesList = new AvailableGamesList(m_pMinecraft, m_width, m_height, 24, m_height - 30, 28);
m_buttonTabList.push_back(&m_btnJoin);
m_buttonTabList.push_back(&m_btnDirectConnect);
m_buttonTabList.push_back(&m_btnBack);
}
bool JoinGameScreen::isInGameScreen()
{
return false;
}
void JoinGameScreen::render(int mouseX, int mouseY, float f)
{
renderBackground();
m_pAvailableGamesList->render(mouseX, mouseY, f);
Screen::render(mouseX, mouseY, f);
drawCenteredString(m_pMinecraft->m_pFont, "Scanning for Games...", m_width / 2, 8, 0xFFFFFFFF);
}
void JoinGameScreen::tick()
{
std::vector<PingedCompatibleServer> *serverList, serverListFiltered;
serverList = m_pMinecraft->m_pRakNetInstance->getServerList();
for (const PingedCompatibleServer& pcs : *serverList)
{
if (pcs.m_name.GetLength())
serverListFiltered.push_back(pcs);
}
if (serverListFiltered.size() != m_pAvailableGamesList->m_games.size())
{
PingedCompatibleServer selectedItem;
if (isIndexValid(m_pAvailableGamesList->m_selectedIndex))
{
selectedItem = m_pAvailableGamesList->m_games[m_pAvailableGamesList->m_selectedIndex];
m_pAvailableGamesList->m_games = serverListFiltered;
m_pAvailableGamesList->selectItem(-1, false);
// relocate the new list item, if possible
for (int i = 0; i < int(serverListFiltered.size()); i++)
{
if (serverListFiltered[i].m_address == selectedItem.m_address)
{
m_pAvailableGamesList->selectItem(i, false);
break;
}
}
}
else
{
m_pAvailableGamesList->m_games = serverListFiltered;
m_pAvailableGamesList->selectItem(-1, false);
}
}
else if (!serverListFiltered.empty())
{
// Update the names of the items already in the available games list.
// @BUG: What would happen if the filtered server list removes an IP and adds another all in the same tick?
std::vector<PingedCompatibleServer>* pGames = &m_pAvailableGamesList->m_games;
for (int i = int(pGames->size() - 1); i >= 0; i--)
{
int j = 0;
for (; j < int(serverListFiltered.size()); j++)
{
if (serverListFiltered[j].m_address == (*pGames)[i].m_address)
break;
}
if (j == serverListFiltered.size())
continue;
(*pGames)[i].m_name = serverListFiltered[j].m_name;
}
}
m_btnJoin.m_bEnabled = isIndexValid(m_pAvailableGamesList->m_selectedIndex);
}
bool JoinGameScreen::isIndexValid(int idx)
{
if (!m_pAvailableGamesList)
return false;
if (idx < 0)
return false;
if (idx >= m_pAvailableGamesList->getNumberOfItems())
return false;
return true;
}