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:
@@ -32,6 +32,22 @@
|
||||
// 4J Added
|
||||
#include "..\Minecraft.World\net.minecraft.world.item.crafting.h"
|
||||
#include "Options.h"
|
||||
#if defined(_WINDOWS64) && defined(MINECRAFT_SERVER_BUILD)
|
||||
#include "..\Minecraft.Server\ServerLogManager.h"
|
||||
#endif
|
||||
|
||||
namespace
|
||||
{
|
||||
// Anti-cheat thresholds. Keep server-side checks authoritative even in host mode.
|
||||
// Base max squared displacement allowed per move packet before speed flags trigger.
|
||||
const double kMoveBaseAllowanceSq = 100.0;
|
||||
// Extra squared displacement allowance derived from current server-side velocity.
|
||||
const double kMoveVelocityAllowanceScale = 100.0;
|
||||
// Max squared distance for interact/attack when the target is visible (normal reach).
|
||||
const double kInteractReachSq = 6.0 * 6.0;
|
||||
// Stricter max squared distance used when LOS is blocked to reduce wall-hit abuse.
|
||||
const double kInteractBlockedReachSq = 3.0 * 3.0;
|
||||
}
|
||||
|
||||
Random PlayerConnection::random;
|
||||
|
||||
@@ -64,6 +80,13 @@ PlayerConnection::PlayerConnection(MinecraftServer *server, Connection *connecti
|
||||
m_offlineXUID = INVALID_XUID;
|
||||
m_onlineXUID = INVALID_XUID;
|
||||
m_bHasClientTickedOnce = false;
|
||||
m_logSmallId = 0;
|
||||
|
||||
// Cache the first valid transport smallId because disconnect teardown can clear it before the server logger runs.
|
||||
if (this->connection != NULL && this->connection->getSocket() != NULL)
|
||||
{
|
||||
m_logSmallId = this->connection->getSocket()->getSmallId();
|
||||
}
|
||||
|
||||
setShowOnMaps(app.GetGameHostOption(eGameHostOption_Gamertags)!=0?true:false);
|
||||
}
|
||||
@@ -74,6 +97,17 @@ PlayerConnection::~PlayerConnection()
|
||||
DeleteCriticalSection(&done_cs);
|
||||
}
|
||||
|
||||
unsigned char PlayerConnection::getLogSmallId()
|
||||
{
|
||||
// Fall back to the live socket only while the cached value is still empty.
|
||||
if (m_logSmallId == 0 && connection != NULL && connection->getSocket() != NULL)
|
||||
{
|
||||
m_logSmallId = connection->getSocket()->getSmallId();
|
||||
}
|
||||
|
||||
return m_logSmallId;
|
||||
}
|
||||
|
||||
void PlayerConnection::tick()
|
||||
{
|
||||
if( done ) return;
|
||||
@@ -116,6 +150,14 @@ void PlayerConnection::disconnect(DisconnectPacket::eDisconnectReason reason)
|
||||
return;
|
||||
}
|
||||
|
||||
#if defined(_WINDOWS64) && defined(MINECRAFT_SERVER_BUILD)
|
||||
ServerRuntime::ServerLogManager::OnPlayerDisconnected(
|
||||
getLogSmallId(),
|
||||
(player != NULL) ? player->name : std::wstring(),
|
||||
reason,
|
||||
true);
|
||||
#endif
|
||||
|
||||
app.DebugPrintf("PlayerConnection disconect reason: %d\n", reason );
|
||||
player->disconnect();
|
||||
|
||||
@@ -280,6 +322,20 @@ void PlayerConnection::handleMovePlayer(shared_ptr<MovePlayerPacket> packet)
|
||||
}
|
||||
*/
|
||||
|
||||
// Anti-cheat: reject movement packets that exceed server-authoritative bounds.
|
||||
double velocitySq = player->xd * player->xd + player->yd * player->yd + player->zd * player->zd;
|
||||
double maxAllowedSq = kMoveBaseAllowanceSq + (velocitySq * kMoveVelocityAllowanceScale);
|
||||
if (player->isAllowedToFly() || player->gameMode->isCreative())
|
||||
{
|
||||
// Creative / flight-allowed players can move farther legitimately per tick.
|
||||
maxAllowedSq *= 1.5;
|
||||
}
|
||||
if (dist > maxAllowedSq)
|
||||
{
|
||||
disconnect(DisconnectPacket::eDisconnect_MovedTooQuickly);
|
||||
return;
|
||||
}
|
||||
|
||||
float r = 1 / 16.0f;
|
||||
bool oldOk = level->getCubes(player, player->bb->copy()->shrink(r, r, r))->empty();
|
||||
|
||||
@@ -306,8 +362,8 @@ void PlayerConnection::handleMovePlayer(shared_ptr<MovePlayerPacket> packet)
|
||||
xDist = xt - player->x;
|
||||
yDist = yt - player->y;
|
||||
|
||||
// 4J-PB - line below will always be true!
|
||||
if (yDist > -0.5 || yDist < 0.5)
|
||||
// Clamp tiny Y drift noise to reduce false positives.
|
||||
if (yDist > -0.5 && yDist < 0.5)
|
||||
{
|
||||
yDist = 0;
|
||||
}
|
||||
@@ -428,7 +484,8 @@ void PlayerConnection::handlePlayerAction(shared_ptr<PlayerActionPacket> packet)
|
||||
|
||||
if (packet->action == PlayerActionPacket::START_DESTROY_BLOCK)
|
||||
{
|
||||
if (true) player->gameMode->startDestroyBlock(x, y, z, packet->face); // 4J - condition was !server->isUnderSpawnProtection(level, x, y, z, player) (from Java 1.6.4) but putting back to old behaviour
|
||||
// Anti-cheat: validate spawn protection on the server for mining start.
|
||||
if (!server->isUnderSpawnProtection(level, x, y, z, player)) player->gameMode->startDestroyBlock(x, y, z, packet->face);
|
||||
else player->connection->send( shared_ptr<TileUpdatePacket>( new TileUpdatePacket(x, y, z, level) ) );
|
||||
|
||||
}
|
||||
@@ -456,8 +513,6 @@ void PlayerConnection::handleUseItem(shared_ptr<UseItemPacket> packet)
|
||||
int face = packet->getFace();
|
||||
player->resetLastActionTime();
|
||||
|
||||
// 4J Stu - We don't have ops, so just use the levels setting
|
||||
bool canEditSpawn = level->canEditSpawn; // = level->dimension->id != 0 || server->players->isOp(player->name);
|
||||
if (packet->getFace() == 255)
|
||||
{
|
||||
if (item == NULL) return;
|
||||
@@ -467,7 +522,8 @@ void PlayerConnection::handleUseItem(shared_ptr<UseItemPacket> packet)
|
||||
{
|
||||
if (synched && player->distanceToSqr(x + 0.5, y + 0.5, z + 0.5) < 8 * 8)
|
||||
{
|
||||
if (true) // 4J - condition was !server->isUnderSpawnProtection(level, x, y, z, player) (from java 1.6.4) but putting back to old behaviour
|
||||
// Anti-cheat: block placement/use must pass server-side spawn protection.
|
||||
if (!server->isUnderSpawnProtection(level, x, y, z, player))
|
||||
{
|
||||
player->gameMode->useItemOn(player, level, item, x, y, z, face, packet->getClickX(), packet->getClickY(), packet->getClickZ());
|
||||
}
|
||||
@@ -536,7 +592,18 @@ void PlayerConnection::handleUseItem(shared_ptr<UseItemPacket> packet)
|
||||
void PlayerConnection::onDisconnect(DisconnectPacket::eDisconnectReason reason, void *reasonObjects)
|
||||
{
|
||||
EnterCriticalSection(&done_cs);
|
||||
if( done ) return;
|
||||
if( done )
|
||||
{
|
||||
LeaveCriticalSection(&done_cs);
|
||||
return;
|
||||
}
|
||||
#if defined(_WINDOWS64) && defined(MINECRAFT_SERVER_BUILD)
|
||||
ServerRuntime::ServerLogManager::OnPlayerDisconnected(
|
||||
getLogSmallId(),
|
||||
(player != NULL) ? player->name : std::wstring(),
|
||||
reason,
|
||||
false);
|
||||
#endif
|
||||
// logger.info(player.name + " lost connection: " + reason);
|
||||
// 4J-PB - removed, since it needs to be localised in the language the client is in
|
||||
//server->players->broadcastAll( shared_ptr<ChatPacket>( new ChatPacket(L"§e" + player->name + L" left the game.") ) );
|
||||
@@ -754,12 +821,13 @@ void PlayerConnection::handleInteract(shared_ptr<InteractPacket> packet)
|
||||
// even though the ray is blocked.
|
||||
if (target != NULL) // && player->canSee(target) && player->distanceToSqr(target) < 6 * 6)
|
||||
{
|
||||
//boole canSee = player->canSee(target);
|
||||
//double maxDist = 6 * 6;
|
||||
//if (!canSee)
|
||||
//{
|
||||
// maxDist = 3 * 3;
|
||||
//}
|
||||
// Anti-cheat: enforce reach and LOS on the server to reject forged hits.
|
||||
bool canSeeTarget = player->canSee(target);
|
||||
double maxDistSq = canSeeTarget ? kInteractReachSq : kInteractBlockedReachSq;
|
||||
if (player->distanceToSqr(target) > maxDistSq)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//if (player->distanceToSqr(target) < maxDist)
|
||||
//{
|
||||
|
||||
Reference in New Issue
Block a user