* Improve the DirectConnectScreen, among other things.

This commit is contained in:
iProgramInCpp
2023-08-06 13:50:17 +03:00
parent bc407fda47
commit 6d8693ada5
6 changed files with 140 additions and 40 deletions

View File

@@ -506,8 +506,7 @@ void Minecraft::sendMessage(const std::string& message)
if (isOnlineClient())
{
// send the server a message packet
MessagePacket mp(message);
m_pRakNetInstance->send(&mp);
m_pRakNetInstance->send(new MessagePacket(message));
}
else
{

View File

@@ -13,33 +13,29 @@
DirectConnectScreen::DirectConnectScreen() :
m_textAddress(1, 0, 0, 0, 0, "Server address"),
m_btnJoin(2, "Join Game"),
m_btnJoin(2, "Connect"),
m_btnQuit(3, "Cancel")
{}
void DirectConnectScreen::init()
{
const int CONTAINER_PADDING = 5;
const int BUTTON_CONTAINER_PADDING = 5;
const int BUTTON_CONTAINER_WIDTH = 200;
m_textAddress.m_width = 200;
m_textAddress.m_height = 20;
m_btnJoin.m_width = (BUTTON_CONTAINER_WIDTH / 2) - (BUTTON_CONTAINER_PADDING / 2);
m_btnJoin.m_width = 200;
m_btnJoin.m_height = 20;
m_btnQuit.m_width = (BUTTON_CONTAINER_WIDTH / 2) - (BUTTON_CONTAINER_PADDING / 2);
m_btnQuit.m_width = 200;
m_btnQuit.m_height = 20;
m_textAddress.m_xPos = (m_width / 2) - (m_textAddress.m_width / 2);
m_textAddress.m_yPos = (m_height / 2) - m_btnJoin.m_height - CONTAINER_PADDING;
m_textAddress.m_yPos = m_height / 2 - 20;
m_btnJoin.m_xPos = (m_width / 2) - (m_btnJoin.m_width) - (BUTTON_CONTAINER_PADDING / 2);
m_btnJoin.m_yPos = (m_height / 2) + CONTAINER_PADDING + m_textAddress.m_height;
m_btnJoin.m_xPos = (m_width / 2) - (m_btnJoin.m_width / 2);
m_btnJoin.m_yPos = m_height - 55;
m_btnQuit.m_xPos = (m_width / 2) + (BUTTON_CONTAINER_PADDING / 2);
m_btnQuit.m_yPos = (m_height / 2) + CONTAINER_PADDING + m_textAddress.m_height;
m_btnQuit.m_xPos = (m_width / 2) - (m_btnQuit.m_width / 2);
m_btnQuit.m_yPos = m_height - 30;
m_textInputs.push_back(&m_textAddress);
m_buttons.push_back(&m_btnQuit);
@@ -53,28 +49,33 @@ void DirectConnectScreen::render(int x, int y, float f)
renderBackground();
Screen::render(x, y, f);
drawCenteredString(m_pFont, "Direct Connect", m_width / 2, 30, 0xFFFFFF);
drawString(m_pFont, "Server address", m_textAddress.m_xPos, m_textAddress.m_yPos - 10, 0xDDDDDD);
drawCenteredString(m_pFont, "Play Multiplayer", m_width / 2, 30, 0xFFFFFF);
drawCenteredString(m_pFont, "Enter the IP address of a server to connect to it:", m_width / 2, m_textAddress.m_yPos - 20, 0x999999);
}
void DirectConnectScreen::buttonClicked(Button* pButton)
{
if (pButton->m_buttonId == m_btnJoin.m_buttonId)
{
if (!m_textAddress.m_text.empty())
{
PingedCompatibleServer newPgs;
RakNet::SystemAddress sysAddress;
if (m_textAddress.m_text.empty())
return;
sysAddress.FromString(m_textAddress.m_text.c_str());
newPgs.m_address = sysAddress;
PingedCompatibleServer newPgs;
RakNet::SystemAddress sysAddress;
m_pMinecraft->joinMultiplayer(newPgs);
m_pMinecraft->setScreen(new ProgressScreen);
if (!sysAddress.FromString(m_textAddress.m_text.c_str()))
return;
m_btnJoin.m_bEnabled = false;
m_textAddress.m_bEnabled = false;
}
if (sysAddress.GetPort() == 0)
sysAddress.SetPortHostOrder(C_DEFAULT_PORT);
newPgs.m_address = sysAddress;
m_pMinecraft->joinMultiplayer(newPgs);
m_pMinecraft->setScreen(new ProgressScreen);
m_btnJoin.m_bEnabled = false;
m_textAddress.m_bEnabled = false;
}
else if (pButton->m_buttonId == m_btnQuit.m_buttonId)
{

View File

@@ -63,7 +63,7 @@ bool JoinGameScreen::handleBackEvent(bool b)
void JoinGameScreen::init()
{
const int BUTTON_WIDTH = 120;
const int BUTTON_WIDTH = 100;
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;
@@ -72,7 +72,7 @@ void JoinGameScreen::init()
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_btnDirectConnect.m_width = BUTTON_WIDTH;
m_buttons.push_back(&m_btnJoin);
m_buttons.push_back(&m_btnDirectConnect);

View File

@@ -8,6 +8,7 @@
#include <RakPeer.h>
#include "ClientSideNetworkHandler.hpp"
#include "client/gui/screens/StartMenuScreen.hpp"
// This lets you make the client shut up and not log events in the debug console.
#define VERBOSE_CLIENT
@@ -49,6 +50,16 @@ void ClientSideNetworkHandler::onConnect(const RakNet::RakNetGUID& rakGuid) // s
void ClientSideNetworkHandler::onUnableToConnect()
{
puts_ignorable("onUnableToConnect");
// get rid of the prepare-thread to stop preparation immediately
if (m_pMinecraft->m_pPrepThread)
{
delete m_pMinecraft->m_pPrepThread;
m_pMinecraft->m_pPrepThread = nullptr;
}
// throw to the start menu for now
m_pMinecraft->setScreen(new StartMenuScreen);
}
void ClientSideNetworkHandler::onDisconnect(const RakNet::RakNetGUID& rakGuid)

View File

@@ -31,6 +31,11 @@ ServerSideNetworkHandler::~ServerSideNetworkHandler()
{
if (m_pLevel)
m_pLevel->removeListener(this);
for (auto plrKVP : m_onlinePlayers)
delete plrKVP.second;
m_onlinePlayers.clear();
}
void ServerSideNetworkHandler::levelGenerated(Level* level)
@@ -45,6 +50,8 @@ void ServerSideNetworkHandler::levelGenerated(Level* level)
level->addListener(this);
allowIncomingConnections(m_pMinecraft->m_options.m_bServerVisibleDefault);
m_onlinePlayers.insert_or_assign(m_pMinecraft->m_pLocalPlayer->m_guid, new OnlinePlayer(m_pMinecraft->m_pLocalPlayer));
}
void ServerSideNetworkHandler::onNewClient(const RakNet::RakNetGUID& guid)
@@ -56,17 +63,25 @@ void ServerSideNetworkHandler::onDisconnect(const RakNet::RakNetGUID& guid)
{
puts_ignorable("onDisconnect");
for (Player* pPlayer : m_pLevel->m_players)
{
if (pPlayer->m_guid != guid)
continue;
OnlinePlayer* pOnlinePlayer = getPlayerByGUID(guid);
displayGameMessage(pPlayer->m_name + " disconnected from the game");
if (!pOnlinePlayer)
return;
m_pRakNetInstance->send(new RemoveEntityPacket(pPlayer->m_EntityID));
Player* pPlayer = pOnlinePlayer->m_pPlayer;
m_pLevel->removeEntity(pPlayer);
}
// erase it from the map
m_onlinePlayers.erase(m_onlinePlayers.find(guid)); // it better be in our map
// tell everyone that they left the game
displayGameMessage(pPlayer->m_name + " disconnected from the game");
m_pRakNetInstance->send(new RemoveEntityPacket(pPlayer->m_EntityID));
// remove it from our world
m_pLevel->removeEntity(pPlayer);
// delete the online player's entry.
delete pOnlinePlayer;
}
void ServerSideNetworkHandler::handle(const RakNet::RakNetGUID& guid, LoginPacket* packet)
@@ -76,10 +91,19 @@ void ServerSideNetworkHandler::handle(const RakNet::RakNetGUID& guid, LoginPacke
puts_ignorable("LoginPacket");
// if they're already online, fail
if (getPlayerByGUID(guid))
{
printf("That player is already in the world!\n");
return;
}
Player* pPlayer = new Player(m_pLevel);
pPlayer->m_guid = guid;
pPlayer->m_name = std::string(packet->m_str.C_String());
m_onlinePlayers.insert_or_assign(guid, new OnlinePlayer(pPlayer));
StartGamePacket sgp;
sgp.field_4 = m_pLevel->getSeed();
sgp.field_8 = m_pLevel->getLevelData()->field_20;
@@ -113,9 +137,33 @@ void ServerSideNetworkHandler::handle(const RakNet::RakNetGUID& guid, LoginPacke
m_pRakNetPeer->Send(&appbs, HIGH_PRIORITY, RELIABLE_ORDERED, 0, guid, true);
}
void ServerSideNetworkHandler::handle(const RakNet::RakNetGUID&, MessagePacket* packet)
void ServerSideNetworkHandler::handle(const RakNet::RakNetGUID& guid, MessagePacket* packet)
{
// TODO
OnlinePlayer* pOP = getPlayerByGUID(guid);
if (!pOP)
{
printf("MessagePacket: That jerk %s doesn't actually exist\n", guid.ToString());
return;
}
// don't let players send empty messages
std::string msg(packet->m_str.C_String());
if (msg.empty())
return;
if (msg[0] == '/')
{
printf("CMD: %s: %s\n", pOP->m_pPlayer->m_name.c_str(), msg.c_str());
// TODO: Commands
sendMessage(guid, "Commands haven't been implemented yet!");
return;
}
printf("MSG: <%s> %s\n", pOP->m_pPlayer->m_name.c_str(), msg.c_str());
// send everyone the message
std::string gameMessage = "<" + pOP->m_pPlayer->m_name + "> " + msg;
displayGameMessage(gameMessage);
}
void ServerSideNetworkHandler::handle(const RakNet::RakNetGUID& guid, MovePlayerPacket* packet)
@@ -276,6 +324,17 @@ void ServerSideNetworkHandler::displayGameMessage(const std::string& msg)
m_pRakNetInstance->send(new MessagePacket(msg));
}
void ServerSideNetworkHandler::sendMessage(const RakNet::RakNetGUID& guid, const std::string& msg)
{
if (m_pRakNetPeer->GetMyGUID() == guid)
{
m_pMinecraft->m_gui.addMessage(msg);
return;
}
m_pRakNetInstance->send(guid, new MessagePacket(msg));
}
void ServerSideNetworkHandler::redistributePacket(Packet* packet, const RakNet::RakNetGUID& source)
{
RakNet::BitStream bs;
@@ -283,3 +342,12 @@ void ServerSideNetworkHandler::redistributePacket(Packet* packet, const RakNet::
m_pRakNetPeer->Send(&bs, HIGH_PRIORITY, RELIABLE_ORDERED, 0, source, true);
}
OnlinePlayer* ServerSideNetworkHandler::getPlayerByGUID(const RakNet::RakNetGUID& guid)
{
auto iter = m_onlinePlayers.find(guid);
if (iter == m_onlinePlayers.end())
return nullptr;
return iter->second;
}

View File

@@ -8,6 +8,7 @@
#pragma once
#include <unordered_map>
#include "NetEventCallback.hpp"
#include "Minecraft.hpp"
#include "RakNetInstance.hpp"
@@ -15,6 +16,21 @@
class Minecraft;
struct OnlinePlayer
{
Player* m_pPlayer; // The player avatar this online player controls
OnlinePlayer(Player* p) : m_pPlayer(p) {}
};
struct RakNetGUIDHasher
{
size_t operator()(const RakNet::RakNetGUID& guid) const
{
return size_t(guid.g);
}
};
class ServerSideNetworkHandler : public NetEventCallback, public LevelListener
{
public:
@@ -39,13 +55,18 @@ public:
void allowIncomingConnections(bool b);
void displayGameMessage(const std::string&);
void sendMessage(const RakNet::RakNetGUID& guid, const std::string&);
void redistributePacket(Packet* packet, const RakNet::RakNetGUID& source);
OnlinePlayer* getPlayerByGUID(const RakNet::RakNetGUID& guid);
public:
Minecraft* m_pMinecraft = nullptr;
Level* m_pLevel = nullptr;
RakNetInstance* m_pRakNetInstance = nullptr;
RakNet::RakPeerInterface* m_pRakNetPeer = nullptr;
bool m_bAllowIncoming = false;
bool m_bAllowIncoming = false;
std::unordered_map<RakNet::RakNetGUID, OnlinePlayer*, RakNetGUIDHasher> m_onlinePlayers;
};