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:
2026-08-29 14:01:24 +03:00
parent a1541c590d
commit 4b962fcb21
146 changed files with 32837 additions and 272 deletions
+143 -1
View File
@@ -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
}