From 00f6df96053472c4825e6acc18e4ade562dd5314 Mon Sep 17 00:00:00 2001 From: NOTPIES Date: Sun, 8 Mar 2026 22:13:19 -0300 Subject: [PATCH] prepare code for dedicated server support --- .gitignore | 3 + Minecraft.Client/Common/Consoles_App.cpp | 24 ++++++++ .../Common/Network/GameNetworkManager.cpp | 3 + Minecraft.Client/CreativeMode.cpp | 6 +- Minecraft.Client/Minecraft.cpp | 8 +++ Minecraft.Client/MinecraftServer.cpp | 60 ++++++++++++++----- Minecraft.Client/PendingConnection.cpp | 2 + Minecraft.Client/PlayerConnection.cpp | 8 ++- Minecraft.Client/PlayerList.cpp | 4 ++ Minecraft.Client/ServerLevel.cpp | 2 + .../Windows64/Network/WinsockNetLayer.cpp | 51 +++++++++++++++- .../Windows64/Network/WinsockNetLayer.h | 4 ++ Minecraft.World/Level.cpp | 3 +- Minecraft.World/StrongholdPieces.cpp | 6 +- 14 files changed, 161 insertions(+), 23 deletions(-) diff --git a/.gitignore b/.gitignore index 405bb60..2bb6ade 100644 --- a/.gitignore +++ b/.gitignore @@ -205,3 +205,6 @@ Minecraft.Client/PS3/PS3Extras/HeapInspector/ # Sony remote storage libs Minecraft.Client/Common/Network/Sony/ + +Minecraft.Server/ +build_dedicated/ \ No newline at end of file diff --git a/Minecraft.Client/Common/Consoles_App.cpp b/Minecraft.Client/Common/Consoles_App.cpp index 4971b69..e72757b 100644 --- a/Minecraft.Client/Common/Consoles_App.cpp +++ b/Minecraft.Client/Common/Consoles_App.cpp @@ -1,6 +1,7 @@  #include "stdafx.h" +#include #include "..\..\Minecraft.World\Recipy.h" #include "..\..\Minecraft.Client\Options.h" #include "..\..\Minecraft.World\AABB.h" @@ -241,6 +242,26 @@ void CMinecraftApp::DebugPrintf(const char *szFormat, ...) vsnprintf(buf, sizeof(buf), szFormat, ap); va_end(ap); OutputDebugStringA(buf); +#ifdef _DEDICATED_SERVER + bool hasContent = false; + for (const char *p = buf; *p; p++) { + if (*p != ' ' && *p != '\t' && *p != '\n' && *p != '\r' && *p != '=') { + hasContent = true; + break; + } + } + if (hasContent) + { + size_t len = strlen(buf); + while (len > 0 && (buf[len-1] == '\n' || buf[len-1] == '\r')) + buf[--len] = '\0'; + + time_t now = time(NULL); + struct tm t; + localtime_s(&t, &now); + printf("[%02d:%02d:%02d] [Server thread/INFO]: %s\n", t.tm_hour, t.tm_min, t.tm_sec, buf); + } +#endif #endif } @@ -303,6 +324,9 @@ LPCWSTR CMinecraftApp::GetString(int iID) { //return L"Değişiklikler ve Yenilikler"; //return L"ÕÕÕÕÖÖÖÖ"; +#ifdef _DEDICATED_SERVER + if (!app.m_stringTable) return L""; +#endif return app.m_stringTable->getString(iID); } diff --git a/Minecraft.Client/Common/Network/GameNetworkManager.cpp b/Minecraft.Client/Common/Network/GameNetworkManager.cpp index a633359..ce1802c 100644 --- a/Minecraft.Client/Common/Network/GameNetworkManager.cpp +++ b/Minecraft.Client/Common/Network/GameNetworkManager.cpp @@ -790,10 +790,12 @@ int CGameNetworkManager::JoinFromInvite_SignInReturned(void *pParam,bool bContin void CGameNetworkManager::UpdateAndSetGameSessionData(INetworkPlayer *pNetworkPlayerLeaving) { +#ifndef _DEDICATED_SERVER Minecraft *pMinecraft = Minecraft::GetInstance(); TexturePack *tPack = pMinecraft->skins->getSelected(); s_pPlatformNetworkManager->SetSessionTexturePackParentId( tPack->getDLCParentPackId() ); s_pPlatformNetworkManager->SetSessionSubTexturePackId( tPack->getDLCSubPackId() ); +#endif s_pPlatformNetworkManager->UpdateAndSetGameSessionData( pNetworkPlayerLeaving ); } @@ -1421,6 +1423,7 @@ void CGameNetworkManager::CreateSocket( INetworkPlayer *pNetworkPlayer, bool loc // Add this user to the game server if the game is started already if( g_NetworkManager.IsHost() && g_NetworkManager.IsInGameplay() ) { + app.DebugPrintf("Adding incoming socket for smallId=%d\n", pNetworkPlayer->GetSmallId()); Socket::addIncomingSocket(socket); } diff --git a/Minecraft.Client/CreativeMode.cpp b/Minecraft.Client/CreativeMode.cpp index 48342eb..e5e6a79 100644 --- a/Minecraft.Client/CreativeMode.cpp +++ b/Minecraft.Client/CreativeMode.cpp @@ -1,5 +1,7 @@ #include "stdafx.h" #include "CreativeMode.h" +#include "MultiPlayerLevel.h" +#include "MultiPlayerLocalPlayer.h" #include "User.h" #include "LocalPlayer.h" #include "..\Minecraft.World\\net.minecraft.world.entity.player.h" @@ -66,12 +68,12 @@ bool CreativeMode::useItemOn(shared_ptr player, Level *level, shared_ptr int t = level->getTile(x, y, z); if (t > 0) { - if (Tile::tiles[t]->use(level, x, y, z, player)) return true; + if (Tile::tiles[t]->use(level, x, y, z, player, face, 0.0f, 0.0f, 0.0f)) return true; } if (item == NULL) return false; int aux = item->getAuxValue(); int count = item->count; - bool success = item->useOn(player, level, x, y, z, face); + bool success = item->useOn(player, level, x, y, z, face, 0.0f, 0.0f, 0.0f); item->setAuxValue(aux); item->count = count; return success; diff --git a/Minecraft.Client/Minecraft.cpp b/Minecraft.Client/Minecraft.cpp index feb42d6..b3b077a 100644 --- a/Minecraft.Client/Minecraft.cpp +++ b/Minecraft.Client/Minecraft.cpp @@ -5046,11 +5046,18 @@ void Minecraft::handleClientTextureReceived(const wstring &textureName) unsigned int Minecraft::getCurrentTexturePackId() { +#ifdef _DEDICATED_SERVER + return 0; +#else return skins->getSelected()->getId(); +#endif } ColourTable *Minecraft::getColourTable() { +#ifdef _DEDICATED_SERVER + return NULL; +#else TexturePack *selected = skins->getSelected(); ColourTable *colours = selected->getColourTable(); @@ -5061,6 +5068,7 @@ ColourTable *Minecraft::getColourTable() } return colours; +#endif } #if defined __ORBIS__ diff --git a/Minecraft.Client/MinecraftServer.cpp b/Minecraft.Client/MinecraftServer.cpp index 6dce63d..e267596 100644 --- a/Minecraft.Client/MinecraftServer.cpp +++ b/Minecraft.Client/MinecraftServer.cpp @@ -33,7 +33,11 @@ #include "..\Minecraft.World\net.minecraft.world.entity.h" #include "ProgressRenderer.h" #include "ServerPlayer.h" +#include "PlayerConnection.h" #include "GameRenderer.h" +#ifdef _WINDOWS64 +#include "Windows64\Network\WinsockNetLayer.h" +#endif #include "..\Minecraft.World\ThreadName.h" #include "..\Minecraft.World\IntCache.h" #include "..\Minecraft.World\CompressedTileStorage.h" @@ -45,6 +49,11 @@ #endif #include "PS3\PS3Extras\ShutdownManager.h" #include "ServerCommandDispatcher.h" + +#ifdef _DEDICATED_SERVER +#include "..\Minecraft.Server\ServerCommands.h" +#endif + #include "..\Minecraft.World\BiomeSource.h" #include "PlayerChunkMap.h" #include "Common\Telemetry\TelemetryManager.h" @@ -134,13 +143,11 @@ bool MinecraftServer::initServer(__int64 seed, NetworkGameInitData *initData, DW #endif settings = new Settings(new File(L"server.properties")); - app.DebugPrintf("\n*** SERVER SETTINGS ***\n"); - app.DebugPrintf("ServerSettings: host-friends-only is %s\n",(app.GetGameHostOption(eGameHostOption_FriendsOfFriends)>0)?"on":"off"); - app.DebugPrintf("ServerSettings: game-type is %s\n",(app.GetGameHostOption(eGameHostOption_GameType)==0)?"Survival Mode":"Creative Mode"); - app.DebugPrintf("ServerSettings: pvp is %s\n",(app.GetGameHostOption(eGameHostOption_PvP)>0)?"on":"off"); - app.DebugPrintf("ServerSettings: fire spreads is %s\n",(app.GetGameHostOption(eGameHostOption_FireSpreads)>0)?"on":"off"); - app.DebugPrintf("ServerSettings: tnt explodes is %s\n",(app.GetGameHostOption(eGameHostOption_TNT)>0)?"on":"off"); - app.DebugPrintf("\n"); + app.DebugPrintf("host-friends-only is %s",(app.GetGameHostOption(eGameHostOption_FriendsOfFriends)>0)?"on":"off"); + app.DebugPrintf("game-type is %s",(app.GetGameHostOption(eGameHostOption_GameType)==0)?"Survival Mode":"Creative Mode"); + app.DebugPrintf("pvp is %s",(app.GetGameHostOption(eGameHostOption_PvP)>0)?"on":"off"); + app.DebugPrintf("fire-spreads is %s",(app.GetGameHostOption(eGameHostOption_FireSpreads)>0)?"on":"off"); + app.DebugPrintf("tnt-explodes is %s",(app.GetGameHostOption(eGameHostOption_TNT)>0)?"on":"off"); // TODO 4J Stu - Init a load of settings based on data passed as params //settings->setBooleanAndSave( L"host-friends-only", (app.GetGameHostOption(eGameHostOption_FriendsOfFriends)>0) ); @@ -267,6 +274,14 @@ bool MinecraftServer::initServer(__int64 seed, NetworkGameInitData *initData, DW } g_NetworkManager.ServerReady(); // 4J added + +#ifdef _DEDICATED_SERVER + { + extern QNET_STATE _iQNetStubState; + _iQNetStubState = QNET_STATE_GAME_PLAY; + } +#endif + return m_bLoaded; } @@ -389,7 +404,7 @@ bool MinecraftServer::loadLevel(LevelStorageSource *storageSource, const wstring int gameTypeId = settings->getInt(L"gamemode", app.GetGameHostOption(eGameHostOption_GameType));//LevelSettings::GAMETYPE_SURVIVAL); GameType *gameType = LevelSettings::validateGameType(gameTypeId); - app.DebugPrintf("Default game type: %d\n" , gameTypeId); + app.DebugPrintf("Default game type: %d" , gameTypeId); LevelSettings *levelSettings = new LevelSettings(levelSeed, gameType, app.GetGameHostOption(eGameHostOption_Structures)>0?true:false, isHardcore(), true, pLevelType, initData->xzSize, initData->hellScale); if( app.GetGameHostOption(eGameHostOption_BonusChest ) ) levelSettings->enableStartingBonusItems(); @@ -481,7 +496,7 @@ bool MinecraftServer::loadLevel(LevelStorageSource *storageSource, const wstring Minecraft *pMinecraft = Minecraft::GetInstance(); // m_lastSentDifficulty = pMinecraft->options->difficulty; levels[i]->difficulty = app.GetGameHostOption(eGameHostOption_Difficulty); //pMinecraft->options->difficulty; - app.DebugPrintf("MinecraftServer::loadLevel - Difficulty = %d\n",levels[i]->difficulty); + app.DebugPrintf("MinecraftServer::loadLevel - Difficulty = %d",levels[i]->difficulty); #if DEBUG_SERVER_DONT_SPAWN_MOBS levels[i]->setSpawnSettings(false, false); @@ -659,8 +674,6 @@ bool MinecraftServer::loadLevel(LevelStorageSource *storageSource, const wstring if(levels[0]->dimension->id==0) { - app.DebugPrintf("===================================\n"); - if(!levels[0]->getLevelData()->getHasStronghold()) { int x,z; @@ -670,20 +683,19 @@ bool MinecraftServer::loadLevel(LevelStorageSource *storageSource, const wstring levels[0]->getLevelData()->setZStronghold(z); levels[0]->getLevelData()->setHasStronghold(); - app.DebugPrintf("=== FOUND stronghold in terrain features list\n"); + app.DebugPrintf("Found stronghold in terrain features list"); } else { // can't find the stronghold position in the terrain feature list. Do we have to run a post-process? - app.DebugPrintf("=== Can't find stronghold in terrain features list\n"); + app.DebugPrintf("Can't find stronghold in terrain features list"); } } else { - app.DebugPrintf("=== Leveldata has stronghold position\n"); + app.DebugPrintf("Leveldata has stronghold position"); } - app.DebugPrintf("===================================\n"); } // printf("Post processing complete at %dms\n",System::currentTimeMillis() - startTime); @@ -1075,6 +1087,13 @@ void MinecraftServer::run(__int64 seed, void *lpParameter) } } +#ifdef _DEDICATED_SERVER + { + __int64 doneTime = System::currentTimeMillis(); + app.DebugPrintf("Done! For help, type \"help\" or \"?\""); + } +#endif + __int64 lastTime = System::currentTimeMillis(); __int64 unprocessedTime = 0; while (running && !s_bServerHalted) @@ -1527,6 +1546,11 @@ void MinecraftServer::tick() } Entity::tickExtraWandering(); // 4J added +#ifdef _DEDICATED_SERVER + g_NetworkManager.DoWork(); + WinsockNetLayer::FlushPendingData(); +#endif + PIXBeginNamedEvent(0,"Connection tick"); connection->tick(); PIXEndNamedEvent(); @@ -1560,7 +1584,13 @@ void MinecraftServer::handleConsoleInputs() AUTO_VAR(it, consoleInput.begin()); ConsoleInput *input = *it; consoleInput.erase(it); +#ifdef _DEDICATED_SERVER + HandleServerCommand(input->msg, input->source, this); + delete input; +#else // commands->handleCommand(input); // 4J - removed - TODO - do we want equivalent of console commands? + delete input; +#endif } } diff --git a/Minecraft.Client/PendingConnection.cpp b/Minecraft.Client/PendingConnection.cpp index 2bb5106..a00907c 100644 --- a/Minecraft.Client/PendingConnection.cpp +++ b/Minecraft.Client/PendingConnection.cpp @@ -89,6 +89,7 @@ void PendingConnection::handlePreLogin(shared_ptr packet) return; } // printf("Server: handlePreLogin\n"); + app.DebugPrintf("PreLogin received from \"%ls\"\n", packet->loginKey.c_str()); name = packet->loginKey; // 4J Stu - Change from the login packet as we know better on client end during the pre-login packet sendPreLoginResponse(); } @@ -143,6 +144,7 @@ void PendingConnection::sendPreLoginResponse() void PendingConnection::handleLogin(shared_ptr packet) { + app.DebugPrintf("Login received from \"%ls\" (protocol %d)\n", name.c_str(), packet->clientVersion); // printf("Server: handleLogin\n"); //name = packet->userName; if (packet->clientVersion != SharedConstants::NETWORK_PROTOCOL_VERSION) diff --git a/Minecraft.Client/PlayerConnection.cpp b/Minecraft.Client/PlayerConnection.cpp index 45ff8cd..76e3264 100644 --- a/Minecraft.Client/PlayerConnection.cpp +++ b/Minecraft.Client/PlayerConnection.cpp @@ -118,7 +118,7 @@ void PlayerConnection::disconnect(DisconnectPacket::eDisconnectReason reason) return; } - app.DebugPrintf("PlayerConnection disconect reason: %d\n", reason ); + app.DebugPrintf("PlayerConnection disconnect reason: %d", reason ); player->disconnect(); // 4J Stu - Need to remove the player from the receiving list before their socket is NULLed so that we can find another player on their system @@ -130,10 +130,16 @@ void PlayerConnection::disconnect(DisconnectPacket::eDisconnectReason reason) if(getWasKicked()) { server->getPlayers()->broadcastAll( shared_ptr( new ChatPacket(player->name, ChatPacket::e_ChatPlayerKickedFromGame) ) ); +#ifdef _DEDICATED_SERVER + app.DebugPrintf("%ls was kicked from the game", player->name.c_str()); +#endif } else { server->getPlayers()->broadcastAll( shared_ptr( new ChatPacket(player->name, ChatPacket::e_ChatPlayerLeftGame) ) ); +#ifdef _DEDICATED_SERVER + app.DebugPrintf("%ls left the game", player->name.c_str()); +#endif } server->getPlayers()->remove(player); diff --git a/Minecraft.Client/PlayerList.cpp b/Minecraft.Client/PlayerList.cpp index de1479c..527a3f3 100644 --- a/Minecraft.Client/PlayerList.cpp +++ b/Minecraft.Client/PlayerList.cpp @@ -236,6 +236,10 @@ void PlayerList::placeNewPlayer(Connection *connection, shared_ptr //server->players->broadcastAll( shared_ptr( new ChatPacket(L"�e" + playerEntity->name + L" joined the game.") ) ); broadcastAll( shared_ptr( new ChatPacket(player->name, ChatPacket::e_ChatPlayerJoinedGame) ) ); +#ifdef _DEDICATED_SERVER + app.DebugPrintf("%ls joined the game", player->name.c_str()); +#endif + MemSect(14); add(player); MemSect(0); diff --git a/Minecraft.Client/ServerLevel.cpp b/Minecraft.Client/ServerLevel.cpp index ed7c116..39ca415 100644 --- a/Minecraft.Client/ServerLevel.cpp +++ b/Minecraft.Client/ServerLevel.cpp @@ -922,6 +922,7 @@ void ServerLevel::saveToDisc(ProgressListener *progressListener, bool autosave) // 4J-PB - check that saves are enabled if(StorageManager.GetSaveDisabled()) return; +#ifndef _DEDICATED_SERVER // Check if we are using a trial version of a texture pack (which will be the case for going into the mash-up pack world with a trial version) if(!Minecraft::GetInstance()->skins->isUsingDefaultSkin()) { @@ -935,6 +936,7 @@ void ServerLevel::saveToDisc(ProgressListener *progressListener, bool autosave) return; } } +#endif if (progressListener != NULL) progressListener->progressStage(IDS_PROGRESS_SAVING_TO_DISC); levelStorage->flushSaveFile(autosave); diff --git a/Minecraft.Client/Windows64/Network/WinsockNetLayer.cpp b/Minecraft.Client/Windows64/Network/WinsockNetLayer.cpp index ebadc73..86ba460 100644 --- a/Minecraft.Client/Windows64/Network/WinsockNetLayer.cpp +++ b/Minecraft.Client/Windows64/Network/WinsockNetLayer.cpp @@ -49,6 +49,9 @@ std::vector WinsockNetLayer::s_pendingJoinSmallIds; CRITICAL_SECTION WinsockNetLayer::s_freeSmallIdLock; std::vector WinsockNetLayer::s_freeSmallIds; +CRITICAL_SECTION WinsockNetLayer::s_earlyDataLock; +std::vector WinsockNetLayer::s_earlyDataBuffers[WIN64_NET_MAX_CLIENTS + 1]; + bool g_Win64MultiplayerHost = false; bool g_Win64MultiplayerJoin = false; int g_Win64MultiplayerPort = WIN64_NET_DEFAULT_PORT; @@ -73,6 +76,7 @@ bool WinsockNetLayer::Initialize() InitializeCriticalSection(&s_disconnectLock); InitializeCriticalSection(&s_pendingJoinLock); InitializeCriticalSection(&s_freeSmallIdLock); + InitializeCriticalSection(&s_earlyDataLock); for (int i = 0; i < WIN64_NET_MAX_CLIENTS + 1; i++) { @@ -356,6 +360,9 @@ bool WinsockNetLayer::JoinGame(const char *ip, int port) } s_localSmallId = assignedSmallId; + DWORD noTimeout = 0; + setsockopt(s_hostConnectionSocket, SOL_SOCKET, SO_RCVTIMEO, (const char *)&noTimeout, sizeof(noTimeout)); + app.DebugPrintf("Win64 LAN: Connected to %s:%d, assigned smallId=%d\n", ip, port, s_localSmallId); s_active = true; @@ -458,13 +465,30 @@ void WinsockNetLayer::HandleDataReceived(BYTE fromSmallId, BYTE toSmallId, unsig INetworkPlayer *pPlayerFrom = g_NetworkManager.GetPlayerBySmallId(fromSmallId); INetworkPlayer *pPlayerTo = g_NetworkManager.GetPlayerBySmallId(toSmallId); - if (pPlayerFrom == NULL || pPlayerTo == NULL) return; + if (pPlayerFrom == NULL || pPlayerTo == NULL) + { + if (s_isHost && fromSmallId > 0 && fromSmallId < WIN64_NET_MAX_CLIENTS + 1) + { + EnterCriticalSection(&s_earlyDataLock); + s_earlyDataBuffers[fromSmallId].insert( + s_earlyDataBuffers[fromSmallId].end(), data, data + dataSize); + LeaveCriticalSection(&s_earlyDataLock); + } + return; + } if (s_isHost) { ::Socket *pSocket = pPlayerFrom->GetSocket(); if (pSocket != NULL) pSocket->pushDataToQueue(data, dataSize, false); + else + { + EnterCriticalSection(&s_earlyDataLock); + s_earlyDataBuffers[fromSmallId].insert( + s_earlyDataBuffers[fromSmallId].end(), data, data + dataSize); + LeaveCriticalSection(&s_earlyDataLock); + } } else { @@ -474,6 +498,26 @@ void WinsockNetLayer::HandleDataReceived(BYTE fromSmallId, BYTE toSmallId, unsig } } +void WinsockNetLayer::FlushPendingData() +{ + EnterCriticalSection(&s_earlyDataLock); + for (int i = 1; i < WIN64_NET_MAX_CLIENTS + 1; i++) + { + if (s_earlyDataBuffers[i].empty()) continue; + + INetworkPlayer *pPlayer = g_NetworkManager.GetPlayerBySmallId((BYTE)i); + if (pPlayer == NULL) continue; + + ::Socket *pSocket = pPlayer->GetSocket(); + if (pSocket == NULL) continue; + + pSocket->pushDataToQueue(s_earlyDataBuffers[i].data(), + (DWORD)s_earlyDataBuffers[i].size(), false); + s_earlyDataBuffers[i].clear(); + } + LeaveCriticalSection(&s_earlyDataLock); +} + DWORD WINAPI WinsockNetLayer::AcceptThreadProc(LPVOID param) { while (s_active) @@ -686,6 +730,11 @@ void WinsockNetLayer::CloseConnectionBySmallId(BYTE smallId) app.DebugPrintf("Win64 LAN: Force-closed TCP connection for smallId=%d\n", smallId); } LeaveCriticalSection(&s_connectionsLock); + + EnterCriticalSection(&s_earlyDataLock); + if (smallId < WIN64_NET_MAX_CLIENTS + 1) + s_earlyDataBuffers[smallId].clear(); + LeaveCriticalSection(&s_earlyDataLock); } DWORD WINAPI WinsockNetLayer::ClientRecvThreadProc(LPVOID param) diff --git a/Minecraft.Client/Windows64/Network/WinsockNetLayer.h b/Minecraft.Client/Windows64/Network/WinsockNetLayer.h index afebabe..fa4f95f 100644 --- a/Minecraft.Client/Windows64/Network/WinsockNetLayer.h +++ b/Minecraft.Client/Windows64/Network/WinsockNetLayer.h @@ -83,6 +83,7 @@ public: static SOCKET GetSocketForSmallId(BYTE smallId); static void HandleDataReceived(BYTE fromSmallId, BYTE toSmallId, unsigned char *data, unsigned int dataSize); + static void FlushPendingData(); static bool PopDisconnectedSmallId(BYTE *outSmallId); static void PushFreeSmallId(BYTE smallId); @@ -151,6 +152,9 @@ private: static CRITICAL_SECTION s_freeSmallIdLock; static std::vector s_freeSmallIds; + + static CRITICAL_SECTION s_earlyDataLock; + static std::vector s_earlyDataBuffers[WIN64_NET_MAX_CLIENTS + 1]; }; extern bool g_Win64MultiplayerHost; diff --git a/Minecraft.World/Level.cpp b/Minecraft.World/Level.cpp index 4b6a64f..44ea16b 100644 --- a/Minecraft.World/Level.cpp +++ b/Minecraft.World/Level.cpp @@ -1889,7 +1889,8 @@ AABBList *Level::getCubes(shared_ptr source, AABB *box, bool noEntities, // 4J - now add in collision for any blocks which have actually been removed, but haven't had their render data updated to reflect this yet. This is to stop the player // being able to move the view position inside a tile which is (visually) still there, and see out of the world. This is particularly a problem when moving upwards in // creative mode as the player can get very close to the edge of tiles whilst looking upwards and can therefore very quickly move inside one. - Minecraft::GetInstance()->levelRenderer->destroyedTileManager->addAABBs( this, box, &boxes); + if(Minecraft::GetInstance()->levelRenderer != NULL) + Minecraft::GetInstance()->levelRenderer->destroyedTileManager->addAABBs( this, box, &boxes); // 4J - added if( noEntities ) return &boxes; diff --git a/Minecraft.World/StrongholdPieces.cpp b/Minecraft.World/StrongholdPieces.cpp index 0168b2b..105e9a1 100644 --- a/Minecraft.World/StrongholdPieces.cpp +++ b/Minecraft.World/StrongholdPieces.cpp @@ -192,7 +192,7 @@ StructurePiece *StrongholdPieces::generateAndAddPiece(StartPiece *startPiece, li { return NULL; } - if (abs(footX - startPiece->getBoundingBox()->x0) > 3 * 16 || abs(footZ - startPiece->getBoundingBox()->z0) > 3 * 16) + if (abs(footX - startPiece->getBoundingBox()->x0) > 3 * 16 || abs(footZ - startPiece->getBoundingBox()->z0) > 3 * 16) { // Force attempt at spawning a portal room if(startPiece->m_level->getOriginalSaveVersion() >= SAVE_FILE_VERSION_MOVED_STRONGHOLD && !startPiece->m_level->getLevelData()->getHasStrongholdEndPortal()) @@ -204,7 +204,7 @@ StructurePiece *StrongholdPieces::generateAndAddPiece(StartPiece *startPiece, li if(piece->pieceClass != EPieceClass_PortalRoom) continue; #ifndef _CONTENT_PACKAGE - printf("Portal room forcing attempt\n"); + app.DebugPrintf("Portal room forcing attempt\n"); #endif StrongholdPiece *strongholdPiece = PortalRoom::createPiece(pieces, random, footX, footY, footZ, direction, depth); if (strongholdPiece != NULL) @@ -217,7 +217,7 @@ StructurePiece *StrongholdPieces::generateAndAddPiece(StartPiece *startPiece, li currentPieces.remove(piece); } #ifndef _CONTENT_PACKAGE - printf("Success\n"); + app.DebugPrintf("Success\n"); #endif return strongholdPiece; }