3 Commits

Author SHA1 Message Date
itsRevela 17ed3d2b9a Fix Ender Dragon damage, End portal transition, and End Poem crash
Dragon melee damage: reassign sub-entity IDs to be sequential from
the parent entity ID in ServerLevel::entityAdded(), so the client's
offset-based ID calculation matches the server. Previously the server's
smallId pool allocated non-sequential IDs, causing melee attacks to
target entity IDs the server didn't recognize.

End portal transition: ensure the player entity is always added to the
new level when transitioning from The End, not just for non-End
dimensions. The addEntity call was previously gated behind a
lastDimension != 1 check that also excluded it from End exits.

End Poem crash: bounds-check the WIN_GAME event's player index before
accessing localplayers[], with a fallback to prevent null dereference
when the server sends an out-of-range index.
2026-03-26 22:25:14 -05:00
666uvu 73d713878c fix redstone tick persistence on chunk unload (#1423) 2026-03-26 16:55:56 -05:00
Revela 4f370c45e3 Fix pistons permanently breaking server-wide on dedicated servers (#1420)
triggerEvent() set ignoreUpdate to true at the start but three early
return paths skipped the reset at the end. Once any of these paths was
hit, the TLS flag stayed true permanently, blocking all piston neighbor
updates for the rest of the server session.
2026-03-26 15:16:15 -05:00
6 changed files with 24 additions and 23 deletions
@@ -50,13 +50,18 @@ UIScene_EndPoem::UIScene_EndPoem(int iPad, void *initData, UILayer *parentLayer)
Minecraft *pMinecraft = Minecraft::GetInstance();
wstring playerName = L"";
if(pMinecraft->localplayers[ui.GetWinUserIndex()] != nullptr)
unsigned int winIdx = ui.GetWinUserIndex();
if(winIdx < XUSER_MAX_COUNT && pMinecraft->localplayers[winIdx] != nullptr)
{
playerName = escapeXML( pMinecraft->localplayers[ui.GetWinUserIndex()]->getDisplayName() );
playerName = escapeXML( pMinecraft->localplayers[winIdx]->getDisplayName() );
}
else if(pMinecraft->localplayers[ProfileManager.GetPrimaryPad()] != nullptr)
{
playerName = escapeXML( pMinecraft->localplayers[ProfileManager.GetPrimaryPad()]->getDisplayName() );
}
else
{
playerName = escapeXML( pMinecraft->localplayers[ProfileManager.GetPrimaryPad()]->getDisplayName() );
playerName = L"Player";
}
noNoiseString = replaceAll(noNoiseString,L"{*PLAYER*}",playerName);
+1
View File
@@ -1795,6 +1795,7 @@ void MinecraftServer::run(int64_t seed, void *lpParameter)
chunkPacketManagement_PostTick();
}
lastTime = getCurrentTimeMillis();
// int64_t afterall = System::currentTimeMillis();
// PIXReportCounter(L"Server time all",(float)(afterall-beforeall));
// PIXReportCounter(L"Server ticks",(float)tickcount);
-2
View File
@@ -816,8 +816,6 @@ void PlayerConnection::handleInteract(shared_ptr<InteractPacket> packet)
{
if ((target->GetType() == eTYPE_ITEMENTITY) || (target->GetType() == eTYPE_EXPERIENCEORB) || (target->GetType() == eTYPE_ARROW) || target == player)
{
//disconnect("Attempting to attack an invalid entity");
//server.warn("Player " + player.getName() + " tried to attack an invalid entity");
return;
}
player->attack(target);
+3 -2
View File
@@ -951,8 +951,6 @@ void PlayerList::repositionAcrossDimension(shared_ptr<Entity> entity, int lastDi
addPlayerToReceiving(player);
}
if (lastDimension != 1)
{
xt = static_cast<double>(Mth::clamp(static_cast<int>(xt), -Level::MAX_LEVEL_SIZE + 128, Level::MAX_LEVEL_SIZE - 128));
zt = static_cast<double>(Mth::clamp(static_cast<int>(zt), -Level::MAX_LEVEL_SIZE + 128, Level::MAX_LEVEL_SIZE - 128));
if (entity->isAlive())
@@ -960,6 +958,9 @@ void PlayerList::repositionAcrossDimension(shared_ptr<Entity> entity, int lastDi
newLevel->addEntity(entity);
entity->moveTo(xt, entity->y, zt, entity->yRot, entity->xRot);
newLevel->tick(entity, false);
// Portal forcing only for non-End exits (End exits go to spawn, not a portal)
if (lastDimension != 1)
{
newLevel->cache->autoCreate = true;
newLevel->getPortalForcer()->force(entity, xOriginal, yOriginal, zOriginal, yRotOriginal);
newLevel->cache->autoCreate = false;
+6 -1
View File
@@ -678,7 +678,7 @@ bool ServerLevel::tickPendingTicks(bool force)
}
else
{
addToTickNextTick(td.x, td.y, td.z, td.tileId, 0);
forceAddTileTick(td.x, td.y, td.z, td.tileId, 0, td.priorityTilt);
}
}
@@ -1052,9 +1052,14 @@ void ServerLevel::entityAdded(shared_ptr<Entity> e)
vector<shared_ptr<Entity> > *es = e->getSubEntities();
if (es)
{
// Reassign sub-entity IDs to be sequential from the parent's ID.
// The client assumes this layout when it applies an offset in handleAddMob.
int offset = 1;
for(auto& i : *es)
{
i->entityId = e->entityId + offset;
entitiesById.emplace(i->entityId, i);
offset++;
}
}
entityAddedExtra(e); // 4J added
-9
View File
@@ -1118,15 +1118,6 @@ bool EnderDragon::hurt(shared_ptr<MultiEntityMobPart> MultiEntityMobPart, Damage
damage = damage / 4 + 1;
}
//float rot1 = yRot * PI / 180;
//float ss1 = sin(rot1);
//float cc1 = cos(rot1);
//xTarget = x + ss1 * 5 + (random->nextFloat() - 0.5f) * 2;
//yTarget = y + random->nextFloat() * 3 + 1;
//zTarget = z - cc1 * 5 + (random->nextFloat() - 0.5f) * 2;
//attackTarget = nullptr;
if ( source->getEntity() != nullptr && source->getEntity()->instanceof(eTYPE_PLAYER) || source->isExplosion() )
{
int healthBefore = getHealth();