forked from cafeberry/cafeberry
feat: add smartcmd dedicated server
major bug: when connecting to the server a second time, it gets softlocked and keeps repeating ticking connection A\n in debug logs until it times out.
This commit is contained in:
@@ -14,12 +14,37 @@
|
||||
#include "..\Minecraft.World\net.minecraft.world.item.h"
|
||||
#include "..\Minecraft.World\SharedConstants.h"
|
||||
#include "Settings.h"
|
||||
|
||||
#if defined(_WINDOWS64) && defined(MINECRAFT_SERVER_BUILD)
|
||||
#include "../Minecraft.Server/ServerLogManager.h"
|
||||
#include "../Minecraft.Server/Access/Access.h"
|
||||
#include "../Minecraft.World/Socket.h"
|
||||
#include <Common/Network/NetworkSocketLayer.h>
|
||||
#endif
|
||||
// #ifdef __PS3__
|
||||
// #include "PS3\Network\NetworkPlayerSony.h"
|
||||
// #endif
|
||||
|
||||
Random *PendingConnection::random = new Random();
|
||||
|
||||
#if defined(_WINDOWS64) && defined(MINECRAFT_SERVER_BUILD)
|
||||
namespace
|
||||
{
|
||||
static unsigned char GetPendingConnectionSmallId(Connection *connection)
|
||||
{
|
||||
if (connection != nullptr)
|
||||
{
|
||||
Socket *socket = connection->getSocket();
|
||||
if (socket != nullptr)
|
||||
{
|
||||
return socket->getSmallId();
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
PendingConnection::PendingConnection(MinecraftServer *server, Socket *socket, const wstring& id)
|
||||
{
|
||||
// 4J - added initialisers
|
||||
@@ -159,12 +184,123 @@ void PendingConnection::handleLogin(shared_ptr<LoginPacket> packet)
|
||||
bool sentDisconnect = false;
|
||||
bool nameTaken = false;
|
||||
|
||||
#if defined(_WINDOWS64) && defined(MINECRAFT_SERVER_BUILD)
|
||||
{
|
||||
std::string connectionIp = "";
|
||||
int connectionPort = 0;
|
||||
|
||||
if (!connection || !connection->getSocket()) {
|
||||
disconnect(DisconnectPacket::eDisconnect_EndOfStream);
|
||||
return;
|
||||
}
|
||||
|
||||
unsigned char smallId = connection->getSocket()->getSmallId();
|
||||
if (smallId == 0) {
|
||||
disconnect(DisconnectPacket::eDisconnect_EndOfStream);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!ServerRuntime::ServerLogManager::TryGetConnectionRemoteIp(smallId, &connectionIp))
|
||||
{
|
||||
SOCKET sock = NetworkSocketLayer::GetSocketForSmallId(smallId);
|
||||
if (sock != INVALID_SOCKET)
|
||||
{
|
||||
sockaddr_in addr;
|
||||
int addrLen = sizeof(addr);
|
||||
if (getpeername(sock, (sockaddr*)&addr, &addrLen) == 0)
|
||||
{
|
||||
char ipBuf[64] = {};
|
||||
if (inet_ntop(AF_INET, &addr.sin_addr, ipBuf, sizeof(ipBuf)))
|
||||
{
|
||||
connectionIp = ipBuf;
|
||||
connectionPort = (int)ntohs(addr.sin_port);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (connectionIp.empty()) {
|
||||
disconnect(DisconnectPacket::eDisconnect_EndOfStream);
|
||||
return;
|
||||
}
|
||||
}
|
||||
else {
|
||||
SOCKET sock = NetworkSocketLayer::GetSocketForSmallId(smallId);
|
||||
if (sock != INVALID_SOCKET)
|
||||
{
|
||||
sockaddr_in addr;
|
||||
int addrLen = sizeof(addr);
|
||||
if (getpeername(sock, (sockaddr*)&addr, &addrLen) == 0)
|
||||
connectionPort = (int)ntohs(addr.sin_port);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// Use the same Xuid choice as handleAcceptedLogin (offline first, online fallback).
|
||||
PlayerUID loginXuid = packet->m_offlineXuid;
|
||||
if (loginXuid == INVALID_XUID) loginXuid = packet->m_onlineXuid;
|
||||
|
||||
bool duplicateXuid = false;
|
||||
if (loginXuid != INVALID_XUID && server->getPlayers()->getPlayer(loginXuid) != nullptr)
|
||||
{
|
||||
duplicateXuid = true;
|
||||
}
|
||||
else if (packet->m_onlineXuid != INVALID_XUID &&
|
||||
packet->m_onlineXuid != loginXuid &&
|
||||
server->getPlayers()->getPlayer(packet->m_onlineXuid) != nullptr)
|
||||
{
|
||||
duplicateXuid = true;
|
||||
}
|
||||
|
||||
bool bannedXuid = false;
|
||||
if (packet->m_offlineXuid != INVALID_XUID)
|
||||
{
|
||||
bannedXuid = server->getPlayers()->isXuidBanned(packet->m_offlineXuid);
|
||||
}
|
||||
if (!bannedXuid && packet->m_onlineXuid != INVALID_XUID && packet->m_onlineXuid != packet->m_offlineXuid)
|
||||
{
|
||||
bannedXuid = server->getPlayers()->isXuidBanned(packet->m_onlineXuid);
|
||||
}
|
||||
|
||||
bool whitelistSatisfied = true;
|
||||
#if defined(_WINDOWS64) && defined(MINECRAFT_SERVER_BUILD)
|
||||
if (ServerRuntime::Access::IsWhitelistEnabled())
|
||||
{
|
||||
whitelistSatisfied = false;
|
||||
if (loginXuid != INVALID_XUID)
|
||||
{
|
||||
whitelistSatisfied = ServerRuntime::Access::IsPlayerWhitelisted(loginXuid);
|
||||
}
|
||||
if (!whitelistSatisfied && packet->m_onlineXuid != INVALID_XUID && packet->m_onlineXuid != loginXuid)
|
||||
{
|
||||
whitelistSatisfied = ServerRuntime::Access::IsPlayerWhitelisted(packet->m_onlineXuid);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if( sentDisconnect )
|
||||
{
|
||||
// Do nothing
|
||||
}
|
||||
else if( server->getPlayers()->isXuidBanned( packet->m_onlineXuid ) )
|
||||
else if (bannedXuid)
|
||||
{
|
||||
#if defined(_WINDOWS64) && defined(MINECRAFT_SERVER_BUILD)
|
||||
ServerRuntime::ServerLogManager::OnRejectedPlayerLogin(GetPendingConnectionSmallId(connection), name, ServerRuntime::ServerLogManager::eLoginRejectReason_BannedXuid);
|
||||
#endif
|
||||
disconnect(DisconnectPacket::eDisconnect_Banned);
|
||||
}
|
||||
else if (!whitelistSatisfied)
|
||||
{
|
||||
#if defined(_WINDOWS64) && defined(MINECRAFT_SERVER_BUILD)
|
||||
ServerRuntime::ServerLogManager::OnRejectedPlayerLogin(GetPendingConnectionSmallId(connection), name, ServerRuntime::ServerLogManager::eLoginRejectReason_NotWhitelisted);
|
||||
#endif
|
||||
disconnect(DisconnectPacket::eDisconnect_Banned);
|
||||
}
|
||||
else if (duplicateXuid)
|
||||
{
|
||||
// Reject the incoming connection — a player with this UID is already
|
||||
// on the server. Allowing duplicates causes invisible players and
|
||||
// other undefined behaviour.
|
||||
app.DebugPrintf("LOGIN: Rejecting duplicate xuid for name: %ls\n", name.c_str());
|
||||
disconnect(DisconnectPacket::eDisconnect_Banned);
|
||||
}
|
||||
else
|
||||
@@ -182,6 +318,9 @@ void PendingConnection::handleLogin(shared_ptr<LoginPacket> packet)
|
||||
|
||||
if (nameTaken)
|
||||
{
|
||||
#if defined(_WINDOWS64) && defined(MINECRAFT_SERVER_BUILD)
|
||||
ServerRuntime::ServerLogManager::OnRejectedPlayerLogin(GetPendingConnectionSmallId(connection), name, ServerRuntime::ServerLogManager::eLoginRejectReason_DuplicateName);
|
||||
#endif
|
||||
app.DebugPrintf("Rejecting duplicate name: %ls\n", name.c_str());
|
||||
|
||||
// to do: replace this with a dedicated duplicate name
|
||||
@@ -237,6 +376,9 @@ void PendingConnection::handleAcceptedLogin(shared_ptr<LoginPacket> packet)
|
||||
shared_ptr<ServerPlayer> playerEntity = server->getPlayers()->getPlayerForLogin(this, name, playerXuid,packet->m_onlineXuid);
|
||||
if (playerEntity != NULL)
|
||||
{
|
||||
#if defined(_WINDOWS64) && defined(MINECRAFT_SERVER_BUILD)
|
||||
ServerRuntime::ServerLogManager::OnAcceptedPlayerLogin(GetPendingConnectionSmallId(connection), name);
|
||||
#endif
|
||||
server->getPlayers()->placeNewPlayer(connection, playerEntity, packet);
|
||||
connection = NULL; // We've moved responsibility for this over to the new PlayerConnection, NULL so we don't delete our reference to it here in our dtor
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user