diff --git a/Minecraft.Client/Level/MultiPlayerLevel.cpp b/Minecraft.Client/Level/MultiPlayerLevel.cpp index 9c3fee74d..1bf05b98a 100644 --- a/Minecraft.Client/Level/MultiPlayerLevel.cpp +++ b/Minecraft.Client/Level/MultiPlayerLevel.cpp @@ -929,8 +929,8 @@ void MultiPlayerLevel::removeUnusedTileEntitiesInRegion(int x0, int y0, int z0, tileEntityList[i] = tileEntityList.back(); tileEntityList.pop_back(); - // 4J Stu - Chests can create new tile entities when being - // removed, so disable this + // 4J Stu - Chests can create new tile entities when + // being removed, so disable this m_bDisableAddNewTileEntities = true; lc->removeTileEntity(te->x & 15, te->y, te->z & 15); m_bDisableAddNewTileEntities = false; diff --git a/Minecraft.Client/Level/ServerLevel.cpp b/Minecraft.Client/Level/ServerLevel.cpp index afd3315ad..2822c8350 100644 --- a/Minecraft.Client/Level/ServerLevel.cpp +++ b/Minecraft.Client/Level/ServerLevel.cpp @@ -192,15 +192,21 @@ ServerLevel::~ServerLevel() { } m_queuedSendTileUpdates.clear(); - delete this->tracker; // MGH - added, we were losing about 500K going in - // and out the menus + delete this->tracker; // MGH - added, we were losing about 500K going + // in and out the menus delete this->chunkMap; } // Make sure that the update thread isn't actually doing any updating - { std::lock_guard lock(m_updateCS[0]); } - { std::lock_guard lock(m_updateCS[1]); } - { std::lock_guard lock(m_updateCS[2]); } + { + std::lock_guard lock(m_updateCS[0]); + } + { + std::lock_guard lock(m_updateCS[1]); + } + { + std::lock_guard lock(m_updateCS[2]); + } m_updateTrigger->clearAll(); } @@ -441,8 +447,9 @@ void ServerLevel::tickTiles() { { std::lock_guard lock(m_updateCS[iLev]); - // This section processes the tiles that need to be ticked, which we worked - // out in the previous tick (or haven't yet, if this is the first frame) + // This section processes the tiles that need to be ticked, which we + // worked out in the previous tick (or haven't yet, if this is the first + // frame) /*int grassTicks = 0; int lavaTicks = 0; int otherTicks = 0;*/ @@ -452,7 +459,8 @@ void ServerLevel::tickTiles() { int z = m_updateTileZ[iLev][i]; if (hasChunkAt(x, y, z)) { int id = getTile(x, y, z); - if (Tile::tiles[id] != nullptr && Tile::tiles[id]->isTicking()) { + if (Tile::tiles[id] != nullptr && + Tile::tiles[id]->isTicking()) { /*if(id == 2) ++grassTicks; else if(id == 11) ++lavaTicks; else ++otherTicks;*/ @@ -461,7 +469,8 @@ void ServerLevel::tickTiles() { } } // printf("Total ticks - Grass: %d, Lava: %d, Other: %d, Total: %d\n", - // grassTicks, lavaTicks, otherTicks, grassTicks + lavaTicks + otherTicks); + // grassTicks, lavaTicks, otherTicks, grassTicks + lavaTicks + + // otherTicks); m_updateTileCount[iLev] = 0; m_updateChunkCount[iLev] = 0; } diff --git a/Minecraft.Client/Minecraft.cpp b/Minecraft.Client/Minecraft.cpp index de9428a74..2305f0ed9 100644 --- a/Minecraft.Client/Minecraft.cpp +++ b/Minecraft.Client/Minecraft.cpp @@ -987,356 +987,447 @@ void Minecraft::run_middle() { } #endif - { std::lock_guard lock(m_setLevelCS); + { + std::lock_guard lock(m_setLevelCS); - if (running) { - if (reloadTextures) { - reloadTextures = false; - textures->reloadAll(); - } + if (running) { + if (reloadTextures) { + reloadTextures = false; + textures->reloadAll(); + } - // while (running) - { - // try { // 4J - removed try/catch - // if (minecraftApplet != null && - // !minecraftApplet.isActive()) break; // 4J - removed + // while (running) + { + // try { // 4J - removed try/catch + // if (minecraftApplet != null && + // !minecraftApplet.isActive()) break; // 4J - + // removed - // if (parent == nullptr && Display.isCloseRequested()) { - // // 4J - removed - // stop(); - // } + // if (parent == nullptr && + // Display.isCloseRequested()) { + // // 4J - removed + // stop(); + // } - // 4J-PB - AUTOSAVE TIMER - only in the full game and if the player - // is the host - if (level != nullptr && ProfileManager.IsFullVersion() && - g_NetworkManager.IsHost()) { - /*if(!bAutosaveTimerSet) - { - // set the timer - bAutosaveTimerSet=true; + // 4J-PB - AUTOSAVE TIMER - only in the full game and if the + // player is the host + if (level != nullptr && ProfileManager.IsFullVersion() && + g_NetworkManager.IsHost()) { + /*if(!bAutosaveTimerSet) + { + // set the timer + bAutosaveTimerSet=true; - app.SetAutosaveTimerTime(); - } - else*/ - { - // if the pause menu is up for the primary player, don't - // autosave If saving isn't disabled, and the main player - // has a app action running , or has any crafting or - // containers open, don't autosave - if (!StorageManager.GetSaveDisabled() && - (app.GetXuiAction(ProfileManager.GetPrimaryPad()) == - eAppAction_Idle)) { - if (!ui.IsPauseMenuDisplayed( - ProfileManager.GetPrimaryPad()) && - !ui.IsIgnoreAutosaveMenuDisplayed( - ProfileManager.GetPrimaryPad())) { - // check if the autotimer countdown has reached zero - unsigned char ucAutosaveVal = app.GetGameSettings( - ProfileManager.GetPrimaryPad(), - eGameSetting_Autosave); - bool bTrialTexturepack = false; - if (!Minecraft::GetInstance() - ->skins->isUsingDefaultSkin()) { - TexturePack* tPack = Minecraft::GetInstance() - ->skins->getSelected(); - DLCTexturePack* pDLCTexPack = - (DLCTexturePack*)tPack; - - DLCPack* pDLCPack = - pDLCTexPack->getDLCInfoParentPack(); - - if (pDLCPack) { - if (!pDLCPack->hasPurchasedFile( - DLCManager::e_DLCType_Texture, - L"")) { - bTrialTexturepack = true; - } - } - } - - // If the autosave value is not zero, and the player - // isn't using a trial texture pack, then check - // whether we need to save this tick - if ((ucAutosaveVal != 0) && !bTrialTexturepack) { - if (app.AutosaveDue()) { - // disable the autosave countdown - ui.ShowAutosaveCountdownTimer(false); - - // Need to save now - app.DebugPrintf("+++++++++++\n"); - app.DebugPrintf("+++Autosave\n"); - app.DebugPrintf("+++++++++++\n"); - app.SetAction( + app.SetAutosaveTimerTime(); + } + else*/ + { + // if the pause menu is up for the primary player, don't + // autosave If saving isn't disabled, and the main + // player has a app action running , or has any crafting + // or containers open, don't autosave + if (!StorageManager.GetSaveDisabled() && + (app.GetXuiAction(ProfileManager.GetPrimaryPad()) == + eAppAction_Idle)) { + if (!ui.IsPauseMenuDisplayed( + ProfileManager.GetPrimaryPad()) && + !ui.IsIgnoreAutosaveMenuDisplayed( + ProfileManager.GetPrimaryPad())) { + // check if the autotimer countdown has reached + // zero + unsigned char ucAutosaveVal = + app.GetGameSettings( ProfileManager.GetPrimaryPad(), - eAppAction_AutosaveSaveGame); - // app.SetAutosaveTimerTime(); + eGameSetting_Autosave); + bool bTrialTexturepack = false; + if (!Minecraft::GetInstance() + ->skins->isUsingDefaultSkin()) { + TexturePack* tPack = + Minecraft::GetInstance() + ->skins->getSelected(); + DLCTexturePack* pDLCTexPack = + (DLCTexturePack*)tPack; + + DLCPack* pDLCPack = + pDLCTexPack->getDLCInfoParentPack(); + + if (pDLCPack) { + if (!pDLCPack->hasPurchasedFile( + DLCManager::e_DLCType_Texture, + L"")) { + bTrialTexturepack = true; + } + } + } + + // If the autosave value is not zero, and the + // player isn't using a trial texture pack, then + // check whether we need to save this tick + if ((ucAutosaveVal != 0) && + !bTrialTexturepack) { + if (app.AutosaveDue()) { + // disable the autosave countdown + ui.ShowAutosaveCountdownTimer(false); + + // Need to save now + app.DebugPrintf("+++++++++++\n"); + app.DebugPrintf("+++Autosave\n"); + app.DebugPrintf("+++++++++++\n"); + app.SetAction( + ProfileManager.GetPrimaryPad(), + eAppAction_AutosaveSaveGame); + // app.SetAutosaveTimerTime(); #if !defined(_CONTENT_PACKAGE) - { - // print the time - SYSTEMTIME UTCSysTime; - GetSystemTime(&UTCSysTime); - // char szTime[15]; + { + // print the time + SYSTEMTIME UTCSysTime; + GetSystemTime(&UTCSysTime); + // char szTime[15]; - app.DebugPrintf("%02d:%02d:%02d\n", - UTCSysTime.wHour, - UTCSysTime.wMinute, - UTCSysTime.wSecond); - } + app.DebugPrintf("%02d:%02d:%02d\n", + UTCSysTime.wHour, + UTCSysTime.wMinute, + UTCSysTime.wSecond); + } #endif - } else { - unsigned int uiTimeToAutosave = - app.SecondsToAutosave(); + } else { + unsigned int uiTimeToAutosave = + app.SecondsToAutosave(); - if (uiTimeToAutosave < 6) { - ui.ShowAutosaveCountdownTimer(true); - ui.UpdateAutosaveCountdownTimer( - uiTimeToAutosave); + if (uiTimeToAutosave < 6) { + ui.ShowAutosaveCountdownTimer(true); + ui.UpdateAutosaveCountdownTimer( + uiTimeToAutosave); + } } } - } - } else { - // disable the autosave countdown - ui.ShowAutosaveCountdownTimer(false); - } - } - } - } - - // 4J-PB - Once we're in the level, check if the players have the - // level in their banned list and ask if they want to play it - for (int i = 0; i < XUSER_MAX_COUNT; i++) { - if (localplayers[i] && (app.GetBanListCheck(i) == false) && - !Minecraft::GetInstance()->isTutorial() && - ProfileManager.IsSignedInLive(i) && - !ProfileManager.IsGuest(i)) { - // If there is a sys ui displayed, we can't display the - // message box here, so ignore until we can - if (!ProfileManager.IsSystemUIDisplayed()) { - app.SetBanListCheck(i, true); - // 4J-PB - check if the level is in the banned level - // list get the unique save name and xuid from whoever - // is the host - INetworkPlayer* pHostPlayer = - g_NetworkManager.GetHostPlayer(); - PlayerUID xuid = pHostPlayer->GetUID(); - - if (app.IsInBannedLevelList(i, xuid, - app.GetUniqueMapName())) { - // put up a message box asking if the player would - // like to unban this level - app.DebugPrintf("This level is banned\n"); - // set the app action to bring up the message box to - // give them the option to remove from the ban list - // or exit the level - app.SetAction(i, eAppAction_LevelInBanLevelList, - (void*)true); - } - } - } - } - - if (!ProfileManager.IsSystemUIDisplayed() && - app.DLCInstallProcessCompleted() && !app.DLCInstallPending() && - app.m_dlcManager.NeedsCorruptCheck()) { - app.m_dlcManager.checkForCorruptDLCAndAlert(); - } - - // When we go into the first loaded level, check if the console has - // active joypads that are not in the game, and bring up the - // quadrant display to remind them to press start (if the session - // has space) - if (level != nullptr && bFirstTimeIntoGame && - g_NetworkManager.SessionHasSpace()) { - // have a short delay before the display - if (iFirstTimeCountdown == 0) { - bFirstTimeIntoGame = false; - - if (app.IsLocalMultiplayerAvailable()) { - for (int i = 0; i < XUSER_MAX_COUNT; i++) { - if ((localplayers[i] == nullptr) && - InputManager.IsPadConnected(i)) { - if (!ui.PressStartPlaying(i)) { - ui.ShowPressStart(i); - } + } else { + // disable the autosave countdown + ui.ShowAutosaveCountdownTimer(false); } } } - } else - iFirstTimeCountdown--; - } - // 4J-PB - store any button toggles for the players, since the - // minecraft::tick may not be called if we're running fast, and a - // button press and release will be missed + } - for (int i = 0; i < XUSER_MAX_COUNT; i++) { - if (localplayers[i]) { - // 4J-PB - add these to check for coming out of idle - if (InputManager.ButtonPressed(i, MINECRAFT_ACTION_JUMP)) - localplayers[i]->ullButtonsPressed |= - 1LL << MINECRAFT_ACTION_JUMP; - if (InputManager.ButtonPressed(i, MINECRAFT_ACTION_USE)) - localplayers[i]->ullButtonsPressed |= - 1LL << MINECRAFT_ACTION_USE; + // 4J-PB - Once we're in the level, check if the players have + // the level in their banned list and ask if they want to play + // it + for (int i = 0; i < XUSER_MAX_COUNT; i++) { + if (localplayers[i] && (app.GetBanListCheck(i) == false) && + !Minecraft::GetInstance()->isTutorial() && + ProfileManager.IsSignedInLive(i) && + !ProfileManager.IsGuest(i)) { + // If there is a sys ui displayed, we can't display the + // message box here, so ignore until we can + if (!ProfileManager.IsSystemUIDisplayed()) { + app.SetBanListCheck(i, true); + // 4J-PB - check if the level is in the banned level + // list get the unique save name and xuid from + // whoever is the host + INetworkPlayer* pHostPlayer = + g_NetworkManager.GetHostPlayer(); + PlayerUID xuid = pHostPlayer->GetUID(); - if (InputManager.ButtonPressed(i, - MINECRAFT_ACTION_INVENTORY)) - localplayers[i]->ullButtonsPressed |= - 1LL << MINECRAFT_ACTION_INVENTORY; - if (InputManager.ButtonPressed(i, MINECRAFT_ACTION_ACTION)) - localplayers[i]->ullButtonsPressed |= - 1LL << MINECRAFT_ACTION_ACTION; - if (InputManager.ButtonPressed(i, - MINECRAFT_ACTION_CRAFTING)) - localplayers[i]->ullButtonsPressed |= - 1LL << MINECRAFT_ACTION_CRAFTING; - if (InputManager.ButtonPressed( - i, MINECRAFT_ACTION_PAUSEMENU)) { - localplayers[i]->ullButtonsPressed |= - 1LL << MINECRAFT_ACTION_PAUSEMENU; - app.DebugPrintf( - "PAUSE PRESSED - ipad = %d, Storing press\n", i); -#if defined(ENABLE_JAVA_GUIS) - pauseGame(); -#endif + if (app.IsInBannedLevelList( + i, xuid, app.GetUniqueMapName())) { + // put up a message box asking if the player + // would like to unban this level + app.DebugPrintf("This level is banned\n"); + // set the app action to bring up the message + // box to give them the option to remove from + // the ban list or exit the level + app.SetAction(i, eAppAction_LevelInBanLevelList, + (void*)true); + } + } } - if (InputManager.ButtonPressed(i, MINECRAFT_ACTION_DROP)) - localplayers[i]->ullButtonsPressed |= - 1LL << MINECRAFT_ACTION_DROP; + } - // 4J-PB - If we're flying, the sneak needs to be held on to - // go down - if (localplayers[i]->abilities.flying) { - if (InputManager.ButtonDown( - i, MINECRAFT_ACTION_SNEAK_TOGGLE)) + if (!ProfileManager.IsSystemUIDisplayed() && + app.DLCInstallProcessCompleted() && + !app.DLCInstallPending() && + app.m_dlcManager.NeedsCorruptCheck()) { + app.m_dlcManager.checkForCorruptDLCAndAlert(); + } + + // When we go into the first loaded level, check if the console + // has active joypads that are not in the game, and bring up the + // quadrant display to remind them to press start (if the + // session has space) + if (level != nullptr && bFirstTimeIntoGame && + g_NetworkManager.SessionHasSpace()) { + // have a short delay before the display + if (iFirstTimeCountdown == 0) { + bFirstTimeIntoGame = false; + + if (app.IsLocalMultiplayerAvailable()) { + for (int i = 0; i < XUSER_MAX_COUNT; i++) { + if ((localplayers[i] == nullptr) && + InputManager.IsPadConnected(i)) { + if (!ui.PressStartPlaying(i)) { + ui.ShowPressStart(i); + } + } + } + } + } else + iFirstTimeCountdown--; + } + // 4J-PB - store any button toggles for the players, since the + // minecraft::tick may not be called if we're running fast, and + // a button press and release will be missed + + for (int i = 0; i < XUSER_MAX_COUNT; i++) { + if (localplayers[i]) { + // 4J-PB - add these to check for coming out of idle + if (InputManager.ButtonPressed(i, + MINECRAFT_ACTION_JUMP)) localplayers[i]->ullButtonsPressed |= - 1LL << MINECRAFT_ACTION_SNEAK_TOGGLE; - } else { + 1LL << MINECRAFT_ACTION_JUMP; + if (InputManager.ButtonPressed(i, MINECRAFT_ACTION_USE)) + localplayers[i]->ullButtonsPressed |= + 1LL << MINECRAFT_ACTION_USE; + if (InputManager.ButtonPressed( - i, MINECRAFT_ACTION_SNEAK_TOGGLE)) + i, MINECRAFT_ACTION_INVENTORY)) localplayers[i]->ullButtonsPressed |= - 1LL << MINECRAFT_ACTION_SNEAK_TOGGLE; - } - if (InputManager.ButtonPressed( - i, MINECRAFT_ACTION_RENDER_THIRD_PERSON)) - localplayers[i]->ullButtonsPressed |= - 1LL << MINECRAFT_ACTION_RENDER_THIRD_PERSON; - if (InputManager.ButtonPressed(i, - MINECRAFT_ACTION_GAME_INFO)) - localplayers[i]->ullButtonsPressed |= - 1LL << MINECRAFT_ACTION_GAME_INFO; + 1LL << MINECRAFT_ACTION_INVENTORY; + if (InputManager.ButtonPressed(i, + MINECRAFT_ACTION_ACTION)) + localplayers[i]->ullButtonsPressed |= + 1LL << MINECRAFT_ACTION_ACTION; + if (InputManager.ButtonPressed( + i, MINECRAFT_ACTION_CRAFTING)) + localplayers[i]->ullButtonsPressed |= + 1LL << MINECRAFT_ACTION_CRAFTING; + if (InputManager.ButtonPressed( + i, MINECRAFT_ACTION_PAUSEMENU)) { + localplayers[i]->ullButtonsPressed |= + 1LL << MINECRAFT_ACTION_PAUSEMENU; + app.DebugPrintf( + "PAUSE PRESSED - ipad = %d, Storing press\n", + i); +#if defined(ENABLE_JAVA_GUIS) + pauseGame(); +#endif + } + if (InputManager.ButtonPressed(i, + MINECRAFT_ACTION_DROP)) + localplayers[i]->ullButtonsPressed |= + 1LL << MINECRAFT_ACTION_DROP; + + // 4J-PB - If we're flying, the sneak needs to be held + // on to go down + if (localplayers[i]->abilities.flying) { + if (InputManager.ButtonDown( + i, MINECRAFT_ACTION_SNEAK_TOGGLE)) + localplayers[i]->ullButtonsPressed |= + 1LL << MINECRAFT_ACTION_SNEAK_TOGGLE; + } else { + if (InputManager.ButtonPressed( + i, MINECRAFT_ACTION_SNEAK_TOGGLE)) + localplayers[i]->ullButtonsPressed |= + 1LL << MINECRAFT_ACTION_SNEAK_TOGGLE; + } + if (InputManager.ButtonPressed( + i, MINECRAFT_ACTION_RENDER_THIRD_PERSON)) + localplayers[i]->ullButtonsPressed |= + 1LL << MINECRAFT_ACTION_RENDER_THIRD_PERSON; + if (InputManager.ButtonPressed( + i, MINECRAFT_ACTION_GAME_INFO)) + localplayers[i]->ullButtonsPressed |= + 1LL << MINECRAFT_ACTION_GAME_INFO; #if !defined(_FINAL_BUILD) - if (app.DebugSettingsOn() && app.GetUseDPadForDebug()) { - localplayers[i]->ullDpad_last = 0; - localplayers[i]->ullDpad_this = 0; - localplayers[i]->ullDpad_filtered = 0; - if (InputManager.ButtonPressed( - i, MINECRAFT_ACTION_DPAD_RIGHT)) - localplayers[i]->ullButtonsPressed |= - 1LL << MINECRAFT_ACTION_CHANGE_SKIN; - if (InputManager.ButtonPressed( - i, MINECRAFT_ACTION_DPAD_UP)) - localplayers[i]->ullButtonsPressed |= - 1LL << MINECRAFT_ACTION_FLY_TOGGLE; - if (InputManager.ButtonPressed( - i, MINECRAFT_ACTION_DPAD_DOWN)) - localplayers[i]->ullButtonsPressed |= - 1LL << MINECRAFT_ACTION_RENDER_DEBUG; - if (InputManager.ButtonPressed( - i, MINECRAFT_ACTION_DPAD_LEFT)) - localplayers[i]->ullButtonsPressed |= - 1LL << MINECRAFT_ACTION_SPAWN_CREEPER; - } else -#endif - { - // Movement on DPAD is stored ulimately into - // ullDpad_filtered - this ignores any diagonals - // pressed, instead reporting the last single direction - // - otherwise we get loads of accidental diagonal - // movements - - localplayers[i]->ullDpad_this = 0; - int dirCount = 0; - - if (InputManager.ButtonDown( - i, MINECRAFT_ACTION_DPAD_LEFT)) { - localplayers[i]->ullDpad_this |= - 1LL << MINECRAFT_ACTION_DPAD_LEFT; - dirCount++; - } - if (InputManager.ButtonDown( - i, MINECRAFT_ACTION_DPAD_RIGHT)) { - localplayers[i]->ullDpad_this |= - 1LL << MINECRAFT_ACTION_DPAD_RIGHT; - dirCount++; - } - if (InputManager.ButtonDown(i, - MINECRAFT_ACTION_DPAD_UP)) { - localplayers[i]->ullDpad_this |= - 1LL << MINECRAFT_ACTION_DPAD_UP; - dirCount++; - } - if (InputManager.ButtonDown( - i, MINECRAFT_ACTION_DPAD_DOWN)) { - localplayers[i]->ullDpad_this |= - 1LL << MINECRAFT_ACTION_DPAD_DOWN; - dirCount++; - } - - if (dirCount <= 1) { - localplayers[i]->ullDpad_last = - localplayers[i]->ullDpad_this; - localplayers[i]->ullDpad_filtered = - localplayers[i]->ullDpad_this; - } else { - localplayers[i]->ullDpad_filtered = - localplayers[i]->ullDpad_last; - } - } - - // for the opacity timer - if (InputManager.ButtonPressed( - i, MINECRAFT_ACTION_LEFT_SCROLL) || - InputManager.ButtonPressed( - i, MINECRAFT_ACTION_RIGHT_SCROLL)) - // InputManager.ButtonPressed(i, MINECRAFT_ACTION_USE) || - // InputManager.ButtonPressed(i, MINECRAFT_ACTION_ACTION)) - { - app.SetOpacityTimer(i); - } - } else { - // 4J Stu - This doesn't make any sense with the way we - // handle XboxOne users - // did we just get input from a player who doesn't exist? - // They'll be wanting to join the game then - bool tryJoin = !pause && - !ui.IsIgnorePlayerJoinMenuDisplayed( - ProfileManager.GetPrimaryPad()) && - g_NetworkManager.SessionHasSpace() && - RenderManager.IsHiDef() && - InputManager.ButtonPressed(i); - if (tryJoin) { - if (!ui.PressStartPlaying(i)) { - ui.ShowPressStart(i); - } else { - // did we just get input from a player who doesn't - // exist? They'll be wanting to join the game then + if (app.DebugSettingsOn() && app.GetUseDPadForDebug()) { + localplayers[i]->ullDpad_last = 0; + localplayers[i]->ullDpad_this = 0; + localplayers[i]->ullDpad_filtered = 0; if (InputManager.ButtonPressed( - i, MINECRAFT_ACTION_PAUSEMENU)) { - // Let them join + i, MINECRAFT_ACTION_DPAD_RIGHT)) + localplayers[i]->ullButtonsPressed |= + 1LL << MINECRAFT_ACTION_CHANGE_SKIN; + if (InputManager.ButtonPressed( + i, MINECRAFT_ACTION_DPAD_UP)) + localplayers[i]->ullButtonsPressed |= + 1LL << MINECRAFT_ACTION_FLY_TOGGLE; + if (InputManager.ButtonPressed( + i, MINECRAFT_ACTION_DPAD_DOWN)) + localplayers[i]->ullButtonsPressed |= + 1LL << MINECRAFT_ACTION_RENDER_DEBUG; + if (InputManager.ButtonPressed( + i, MINECRAFT_ACTION_DPAD_LEFT)) + localplayers[i]->ullButtonsPressed |= + 1LL << MINECRAFT_ACTION_SPAWN_CREEPER; + } else +#endif + { + // Movement on DPAD is stored ulimately into + // ullDpad_filtered - this ignores any diagonals + // pressed, instead reporting the last single + // direction + // - otherwise we get loads of accidental diagonal + // movements - // are they signed in? - if (ProfileManager.IsSignedIn(i)) { - // if this is a local game, then the player - // just needs to be signed in - if (g_NetworkManager.IsLocalGame() || - (ProfileManager.IsSignedInLive(i) && - ProfileManager - .AllowedToPlayMultiplayer(i))) { - if (level->isClientSide) { - bool success = addLocalPlayer(i); + localplayers[i]->ullDpad_this = 0; + int dirCount = 0; - if (!success) { + if (InputManager.ButtonDown( + i, MINECRAFT_ACTION_DPAD_LEFT)) { + localplayers[i]->ullDpad_this |= + 1LL << MINECRAFT_ACTION_DPAD_LEFT; + dirCount++; + } + if (InputManager.ButtonDown( + i, MINECRAFT_ACTION_DPAD_RIGHT)) { + localplayers[i]->ullDpad_this |= + 1LL << MINECRAFT_ACTION_DPAD_RIGHT; + dirCount++; + } + if (InputManager.ButtonDown( + i, MINECRAFT_ACTION_DPAD_UP)) { + localplayers[i]->ullDpad_this |= + 1LL << MINECRAFT_ACTION_DPAD_UP; + dirCount++; + } + if (InputManager.ButtonDown( + i, MINECRAFT_ACTION_DPAD_DOWN)) { + localplayers[i]->ullDpad_this |= + 1LL << MINECRAFT_ACTION_DPAD_DOWN; + dirCount++; + } + + if (dirCount <= 1) { + localplayers[i]->ullDpad_last = + localplayers[i]->ullDpad_this; + localplayers[i]->ullDpad_filtered = + localplayers[i]->ullDpad_this; + } else { + localplayers[i]->ullDpad_filtered = + localplayers[i]->ullDpad_last; + } + } + + // for the opacity timer + if (InputManager.ButtonPressed( + i, MINECRAFT_ACTION_LEFT_SCROLL) || + InputManager.ButtonPressed( + i, MINECRAFT_ACTION_RIGHT_SCROLL)) + // InputManager.ButtonPressed(i, MINECRAFT_ACTION_USE) + // || InputManager.ButtonPressed(i, + // MINECRAFT_ACTION_ACTION)) + { + app.SetOpacityTimer(i); + } + } else { + // 4J Stu - This doesn't make any sense with the way we + // handle XboxOne users + // did we just get input from a player who doesn't + // exist? They'll be wanting to join the game then + bool tryJoin = !pause && + !ui.IsIgnorePlayerJoinMenuDisplayed( + ProfileManager.GetPrimaryPad()) && + g_NetworkManager.SessionHasSpace() && + RenderManager.IsHiDef() && + InputManager.ButtonPressed(i); + if (tryJoin) { + if (!ui.PressStartPlaying(i)) { + ui.ShowPressStart(i); + } else { + // did we just get input from a player who + // doesn't exist? They'll be wanting to join the + // game then + if (InputManager.ButtonPressed( + i, MINECRAFT_ACTION_PAUSEMENU)) { + // Let them join + + // are they signed in? + if (ProfileManager.IsSignedIn(i)) { + // if this is a local game, then the + // player just needs to be signed in + if (g_NetworkManager.IsLocalGame() || + (ProfileManager.IsSignedInLive(i) && + ProfileManager + .AllowedToPlayMultiplayer( + i))) { + if (level->isClientSide) { + bool success = + addLocalPlayer(i); + + if (!success) { + app.DebugPrintf( + "Bringing up the sign " + "in " + "ui\n"); + ProfileManager.RequestSignInUI( + false, + g_NetworkManager + .IsLocalGame(), + true, false, true, + &Minecraft:: + InGame_SignInReturned, + this, i); + } else { + } + } else { + // create the localplayer + std::shared_ptr player = + localplayers[i]; + if (player == nullptr) { + player = + createExtraLocalPlayer( + i, + (convStringToWstring( + ProfileManager + .GetGamertag( + i))) + .c_str(), + i, + level->dimension + ->id); + } + } + } else { + if (ProfileManager.IsSignedInLive( + ProfileManager + .GetPrimaryPad()) && + !ProfileManager + .AllowedToPlayMultiplayer( + i)) { + ProfileManager + .RequestConvertOfflineToGuestUI( + &Minecraft:: + InGame_SignInReturned, + this, i); + // 4J Stu - Don't allow + // converting to guests as we + // don't allow any guest sign-in + // while in the game Fix for + // #66516 - TCR #124: MPS Guest + // Support ; #001: BAS Game + // Stability: TU8: The game + // crashes when second Guest + // signs-in on console which + // takes part in Xbox LIVE + // multiplayer session. + // ProfileManager.RequestConvertOfflineToGuestUI( + // &Minecraft::InGame_SignInReturned, + // this,i); + + ui.HidePressStart(); + { + uint32_t uiIDA[1]; + uiIDA[0] = IDS_CONFIRM_OK; + ui.RequestErrorMessage( + IDS_NO_MULTIPLAYER_PRIVILEGE_TITLE, + IDS_NO_MULTIPLAYER_PRIVILEGE_JOIN_TEXT, + uiIDA, 1, i); + } + } + // else + { + // player not signed in to live + // bring up the sign in dialog app.DebugPrintf( "Bringing up the sign in " "ui\n"); @@ -1348,391 +1439,336 @@ void Minecraft::run_middle() { &Minecraft:: InGame_SignInReturned, this, i); - } else { - } - } else { - // create the localplayer - std::shared_ptr player = - localplayers[i]; - if (player == nullptr) { - player = createExtraLocalPlayer( - i, - (convStringToWstring( - ProfileManager - .GetGamertag(i))) - .c_str(), - i, level->dimension->id); } } } else { - if (ProfileManager.IsSignedInLive( - ProfileManager - .GetPrimaryPad()) && - !ProfileManager - .AllowedToPlayMultiplayer(i)) { - ProfileManager - .RequestConvertOfflineToGuestUI( - &Minecraft:: - InGame_SignInReturned, - this, i); - // 4J Stu - Don't allow converting - // to guests as we don't allow any - // guest sign-in while in the game - // Fix for #66516 - TCR #124: MPS - // Guest Support ; #001: BAS Game - // Stability: TU8: The game crashes - // when second Guest signs-in on - // console which takes part in Xbox - // LIVE multiplayer session. - // ProfileManager.RequestConvertOfflineToGuestUI( - // &Minecraft::InGame_SignInReturned, - // this,i); - - ui.HidePressStart(); - { - uint32_t uiIDA[1]; - uiIDA[0] = IDS_CONFIRM_OK; - ui.RequestErrorMessage( - IDS_NO_MULTIPLAYER_PRIVILEGE_TITLE, - IDS_NO_MULTIPLAYER_PRIVILEGE_JOIN_TEXT, - uiIDA, 1, i); - } - } - // else - { - // player not signed in to live - // bring up the sign in dialog - app.DebugPrintf( - "Bringing up the sign in ui\n"); - ProfileManager.RequestSignInUI( - false, - g_NetworkManager.IsLocalGame(), - true, false, true, - &Minecraft:: - InGame_SignInReturned, - this, i); - } + // bring up the sign in dialog + app.DebugPrintf( + "Bringing up the sign in ui\n"); + ProfileManager.RequestSignInUI( + false, + g_NetworkManager.IsLocalGame(), + true, false, true, + &Minecraft::InGame_SignInReturned, + this, i); } - } else { - // bring up the sign in dialog - app.DebugPrintf( - "Bringing up the sign in ui\n"); - ProfileManager.RequestSignInUI( - false, g_NetworkManager.IsLocalGame(), - true, false, true, - &Minecraft::InGame_SignInReturned, this, - i); } } } } } - } - if (pause && level != nullptr) { - float lastA = timer->a; - timer->advanceTime(); - timer->a = lastA; - } else { - timer->advanceTime(); - } - - // int64_t beforeTickTime = System::nanoTime(); - for (int i = 0; i < timer->ticks; i++) { - bool bLastTimerTick = (i == (timer->ticks - 1)); - // 4J-PB - the tick here can run more than once, and this is a - // problem for our input, which would see the a key press twice - // with the same time - let's tick the inputmanager again - if (i != 0) { - InputManager.Tick(); - app.HandleButtonPresses(); + if (pause && level != nullptr) { + float lastA = timer->a; + timer->advanceTime(); + timer->a = lastA; + } else { + timer->advanceTime(); } - ticks++; - // try { // 4J - try/catch removed - bool bFirst = true; - for (int idx = 0; idx < XUSER_MAX_COUNT; idx++) { - // 4J - If we are waiting for this connection to do - // something, then tick it here. This replaces many of the - // original Java scenes which would tick the connection - // while showing that scene - if (m_pendingLocalConnections[idx] != nullptr) { - m_pendingLocalConnections[idx]->tick(); + // int64_t beforeTickTime = System::nanoTime(); + for (int i = 0; i < timer->ticks; i++) { + bool bLastTimerTick = (i == (timer->ticks - 1)); + // 4J-PB - the tick here can run more than once, and this is + // a problem for our input, which would see the a key press + // twice with the same time - let's tick the inputmanager + // again + if (i != 0) { + InputManager.Tick(); + app.HandleButtonPresses(); } - // reset the player inactive tick - if (localplayers[idx] != nullptr) { - // any input received? - if ((localplayers[idx]->ullButtonsPressed != 0) || - InputManager.GetJoypadStick_LX(idx, false) != - 0.0f || - InputManager.GetJoypadStick_LY(idx, false) != - 0.0f || - InputManager.GetJoypadStick_RX(idx, false) != - 0.0f || - InputManager.GetJoypadStick_RY(idx, false) != - 0.0f) { - localplayers[idx]->ResetInactiveTicks(); - } else { - localplayers[idx]->IncrementInactiveTicks(); + ticks++; + // try { // 4J - try/catch removed + bool bFirst = true; + for (int idx = 0; idx < XUSER_MAX_COUNT; idx++) { + // 4J - If we are waiting for this connection to do + // something, then tick it here. This replaces many of + // the original Java scenes which would tick the + // connection while showing that scene + if (m_pendingLocalConnections[idx] != nullptr) { + m_pendingLocalConnections[idx]->tick(); } - if (localplayers[idx]->GetInactiveTicks() > 200) { - if (!localplayers[idx]->isIdle() && - localplayers[idx]->onGround) { - localplayers[idx]->setIsIdle(true); + // reset the player inactive tick + if (localplayers[idx] != nullptr) { + // any input received? + if ((localplayers[idx]->ullButtonsPressed != 0) || + InputManager.GetJoypadStick_LX(idx, false) != + 0.0f || + InputManager.GetJoypadStick_LY(idx, false) != + 0.0f || + InputManager.GetJoypadStick_RX(idx, false) != + 0.0f || + InputManager.GetJoypadStick_RY(idx, false) != + 0.0f) { + localplayers[idx]->ResetInactiveTicks(); + } else { + localplayers[idx]->IncrementInactiveTicks(); } - } else { - if (localplayers[idx]->isIdle()) { - localplayers[idx]->setIsIdle(false); + + if (localplayers[idx]->GetInactiveTicks() > 200) { + if (!localplayers[idx]->isIdle() && + localplayers[idx]->onGround) { + localplayers[idx]->setIsIdle(true); + } + } else { + if (localplayers[idx]->isIdle()) { + localplayers[idx]->setIsIdle(false); + } + } + } + + if (setLocalPlayerIdx(idx)) { + tick(bFirst, bLastTimerTick); + bFirst = false; + // clear the stored button downs since the tick for + // this player will now have actioned them + player->ullButtonsPressed = 0LL; + } else if (screen != nullptr) { + screen->updateEvents(); + // 4jcraft: this fixes the title screen panorama + // running faster than it should + if (!idx) { + screen->tick(); } } } - if (setLocalPlayerIdx(idx)) { - tick(bFirst, bLastTimerTick); - bFirst = false; - // clear the stored button downs since the tick for this - // player will now have actioned them - player->ullButtonsPressed = 0LL; - } else if (screen != nullptr) { - screen->updateEvents(); - // 4jcraft: this fixes the title screen panorama running - // faster than it should - if (!idx) { - screen->tick(); + ui.HandleGameTick(); + + setLocalPlayerIdx(ProfileManager.GetPrimaryPad()); + + // 4J - added - now do the equivalent of level::animateTick, + // but taking into account the positions of all our players + + for (int l = 0; l < levels.length; l++) { + if (levels[l]) { + levels[l]->animateTickDoWork(); } } + + // } catch (LevelConflictException e) { + // this.level = null; + // setLevel(null); + // setScreen(new LevelConflictScreen()); + // } + // SparseLightStorage::tick(); + // // 4J added + // CompressedTileStorage::tick(); // 4J added + // SparseDataStorage::tick(); + // // 4J added } + // int64_t tickDuraction = System::nanoTime() - beforeTickTime; + MemSect(31); + checkGlError(L"Pre render"); + MemSect(0); - ui.HandleGameTick(); + TileRenderer::fancy = options->fancyGraphics; - setLocalPlayerIdx(ProfileManager.GetPrimaryPad()); + // if (pause) timer.a = 1; - // 4J - added - now do the equivalent of level::animateTick, but - // taking into account the positions of all our players + PIXBeginNamedEvent(0, "Sound engine update"); + soundEngine->tick((std::shared_ptr*)localplayers, + timer->a); + PIXEndNamedEvent(); - for (int l = 0; l < levels.length; l++) { - if (levels[l]) { - levels[l]->animateTickDoWork(); - } - } + PIXBeginNamedEvent(0, "Light update"); - // } catch (LevelConflictException e) { - // this.level = null; - // setLevel(null); - // setScreen(new LevelConflictScreen()); - // } - // SparseLightStorage::tick(); - // // 4J added - // CompressedTileStorage::tick(); // 4J added - // SparseDataStorage::tick(); - // // 4J added - } - // int64_t tickDuraction = System::nanoTime() - beforeTickTime; - MemSect(31); - checkGlError(L"Pre render"); - MemSect(0); + // if (level != nullptr) level->updateLights(); + glEnable(GL_TEXTURE_2D); - TileRenderer::fancy = options->fancyGraphics; + PIXEndNamedEvent(); - // if (pause) timer.a = 1; + // if (!Keyboard::isKeyDown(Keyboard.KEY_F7)) + // Display.update(); // 4J - removed - PIXBeginNamedEvent(0, "Sound engine update"); - soundEngine->tick((std::shared_ptr*)localplayers, timer->a); - PIXEndNamedEvent(); + // 4J-PB - changing this to be per player + // if (player != nullptr && player->isInWall()) + // options->thirdPersonView = false; + if (player != nullptr && player->isInWall()) + player->SetThirdPersonView(0); - PIXBeginNamedEvent(0, "Light update"); + if (!noRender) { + bool bFirst = true; + int iPrimaryPad = ProfileManager.GetPrimaryPad(); + for (int i = 0; i < XUSER_MAX_COUNT; i++) { + if (setLocalPlayerIdx(i)) { + PIXBeginNamedEvent(0, "Game render player idx %d", + i); + RenderManager.StateSetViewport( + (C4JRender::eViewportType) + player->m_iScreenSection); + gameRenderer->render(timer->a, bFirst); + bFirst = false; + PIXEndNamedEvent(); - // if (level != nullptr) level->updateLights(); - glEnable(GL_TEXTURE_2D); - - PIXEndNamedEvent(); - - // if (!Keyboard::isKeyDown(Keyboard.KEY_F7)) - // Display.update(); // 4J - removed - - // 4J-PB - changing this to be per player - // if (player != nullptr && player->isInWall()) - // options->thirdPersonView = false; - if (player != nullptr && player->isInWall()) - player->SetThirdPersonView(0); - - if (!noRender) { - bool bFirst = true; - int iPrimaryPad = ProfileManager.GetPrimaryPad(); - for (int i = 0; i < XUSER_MAX_COUNT; i++) { - if (setLocalPlayerIdx(i)) { - PIXBeginNamedEvent(0, "Game render player idx %d", i); - RenderManager.StateSetViewport( - (C4JRender::eViewportType)player->m_iScreenSection); - gameRenderer->render(timer->a, bFirst); - bFirst = false; - PIXEndNamedEvent(); - - if (i == iPrimaryPad) { - // check to see if we need to capture a screenshot - // for the save game thumbnail - switch (app.GetXuiAction(i)) { - case eAppAction_ExitWorldCapturedThumbnail: - case eAppAction_SaveGameCapturedThumbnail: - case eAppAction_AutosaveSaveGameCapturedThumbnail: - // capture the save thumbnail - app.CaptureSaveThumbnail(); - break; - default: - break; + if (i == iPrimaryPad) { + // check to see if we need to capture a + // screenshot for the save game thumbnail + switch (app.GetXuiAction(i)) { + case eAppAction_ExitWorldCapturedThumbnail: + case eAppAction_SaveGameCapturedThumbnail: + case eAppAction_AutosaveSaveGameCapturedThumbnail: + // capture the save thumbnail + app.CaptureSaveThumbnail(); + break; + default: + break; + } } } } - } #if !defined(_ENABLEIGGY) - // On Linux, Iggy Flash UI is not available. If no players were - // rendered (menu / title-screen state), call GameRenderer - // directly so mc->screen draws. - if (bFirst) { - localPlayerIdx = 0; + // On Linux, Iggy Flash UI is not available. If no players + // were rendered (menu / title-screen state), call + // GameRenderer directly so mc->screen draws. + if (bFirst) { + localPlayerIdx = 0; + RenderManager.StateSetViewport( + C4JRender::VIEWPORT_TYPE_FULLSCREEN); + gameRenderer->render(timer->a, true); + } +#endif + + // If there's an unoccupied quadrant, then clear that to + // black + if (unoccupiedQuadrant > -1) { + // render a logo + RenderManager.StateSetViewport(( + C4JRender:: + eViewportType)(C4JRender:: + VIEWPORT_TYPE_QUADRANT_TOP_LEFT + + unoccupiedQuadrant)); + glClearColor(0, 0, 0, 0); + glClear(GL_COLOR_BUFFER_BIT); + + ui.SetEmptyQuadrantLogo( + C4JRender::VIEWPORT_TYPE_QUADRANT_TOP_LEFT + + unoccupiedQuadrant); + } + setLocalPlayerIdx(iPrimaryPad); RenderManager.StateSetViewport( C4JRender::VIEWPORT_TYPE_FULLSCREEN); - gameRenderer->render(timer->a, true); } -#endif + glFlush(); - // If there's an unoccupied quadrant, then clear that to black - if (unoccupiedQuadrant > -1) { - // render a logo - RenderManager.StateSetViewport(( - C4JRender:: - eViewportType)(C4JRender:: - VIEWPORT_TYPE_QUADRANT_TOP_LEFT + - unoccupiedQuadrant)); - glClearColor(0, 0, 0, 0); - glClear(GL_COLOR_BUFFER_BIT); - - ui.SetEmptyQuadrantLogo( - C4JRender::VIEWPORT_TYPE_QUADRANT_TOP_LEFT + - unoccupiedQuadrant); + /* 4J - removed + if (!Display::isActive()) + { + if (fullscreen) + { + this->toggleFullScreen(); } - setLocalPlayerIdx(iPrimaryPad); - RenderManager.StateSetViewport( - C4JRender::VIEWPORT_TYPE_FULLSCREEN); - } - glFlush(); - - /* 4J - removed - if (!Display::isActive()) - { - if (fullscreen) - { - this->toggleFullScreen(); - } - std::this_thread::sleep_for(std::chrono::milliseconds(10)); - } - */ + std::this_thread::sleep_for(std::chrono::milliseconds(10)); + } + */ #if PACKET_ENABLE_STAT_TRACKING - Packet::updatePacketStatsPIX(); + Packet::updatePacketStatsPIX(); #endif - if (options->renderDebug) { - // renderFpsMeter(tickDuraction); + if (options->renderDebug) { + // renderFpsMeter(tickDuraction); #if DEBUG_RENDER_SHOWS_PACKETS - // To show data for only one packet type - // Packet::renderPacketStats(31); + // To show data for only one packet type + // Packet::renderPacketStats(31); - // To show data for all packet types selected as being - // renderable in the Packet:static_ctor call to Packet::map - Packet::renderAllPacketStats(); + // To show data for all packet types selected as being + // renderable in the Packet:static_ctor call to Packet::map + Packet::renderAllPacketStats(); #else - // To show the size of the QNet queue in bytes and messages - g_NetworkManager.renderQueueMeter(); + // To show the size of the QNet queue in bytes and messages + g_NetworkManager.renderQueueMeter(); #endif - } else { - lastTimer = System::nanoTime(); - } + } else { + lastTimer = System::nanoTime(); + } - achievementPopup->render(); + achievementPopup->render(); - PIXBeginNamedEvent(0, "Sleeping"); - std::this_thread::yield(); // 4jcraft added now that we have - // portable thread yield. - // std::this_thread::sleep_for( - // std::chrono::milliseconds(0)); // 4J - was Thread.yield()) - PIXEndNamedEvent(); + PIXBeginNamedEvent(0, "Sleeping"); + std::this_thread::yield(); // 4jcraft added now that we have + // portable thread yield. + // std::this_thread::sleep_for( + // std::chrono::milliseconds(0)); // 4J - was + // Thread.yield()) + PIXEndNamedEvent(); - // if (Keyboard::isKeyDown(Keyboard::KEY_F7)) - // Display.update(); // 4J - removed condition - PIXBeginNamedEvent(0, "Display update"); - Display::update(); - PIXEndNamedEvent(); + // if (Keyboard::isKeyDown(Keyboard::KEY_F7)) + // Display.update(); // 4J - removed condition + PIXBeginNamedEvent(0, "Display update"); + Display::update(); + PIXEndNamedEvent(); - // checkScreenshot(); // 4J - removed + // checkScreenshot(); // 4J - removed - /* 4J - removed - if (parent != nullptr && !fullscreen) - { - if (parent.getWidth() != width || parent.getHeight() != height) - { - width = parent.getWidth(); - height = parent.getHeight(); - if (width <= 0) width = 1; - if (height <= 0) height = 1; + /* 4J - removed + if (parent != nullptr && !fullscreen) + { + if (parent.getWidth() != width || parent.getHeight() != height) + { + width = parent.getWidth(); + height = parent.getHeight(); + if (width <= 0) width = 1; + if (height <= 0) height = 1; - resize(width, height); - } - } - */ - MemSect(31); - checkGlError(L"Post render"); - MemSect(0); - frames++; - // pause = !isClientSide() && screen != nullptr && - // screen->isPauseScreen(); + resize(width, height); + } + } + */ + MemSect(31); + checkGlError(L"Post render"); + MemSect(0); + frames++; + // pause = !isClientSide() && screen != nullptr && + // screen->isPauseScreen(); #if defined(ENABLE_JAVA_GUIS) - pause = g_NetworkManager.IsLocalGame() && - g_NetworkManager.GetPlayerCount() == 1 && - screen != nullptr && screen->isPauseScreen(); + pause = g_NetworkManager.IsLocalGame() && + g_NetworkManager.GetPlayerCount() == 1 && + screen != nullptr && screen->isPauseScreen(); #else - pause = app.IsAppPaused(); + pause = app.IsAppPaused(); #endif #if !defined(_CONTENT_PACKAGE) - while (System::nanoTime() >= lastTime + 1000000000) { - MemSect(31); - fpsString = _toString(frames) + L" fps, " + - _toString(Chunk::updates) + L" chunk updates"; - MemSect(0); - Chunk::updates = 0; - lastTime += 1000000000; - frames = 0; - } + while (System::nanoTime() >= lastTime + 1000000000) { + MemSect(31); + fpsString = _toString(frames) + L" fps, " + + _toString(Chunk::updates) + + L" chunk updates"; + MemSect(0); + Chunk::updates = 0; + lastTime += 1000000000; + frames = 0; + } #endif + /* + } catch (LevelConflictException e) { + this.level = null; + setLevel(null); + setScreen(new LevelConflictScreen()); + } catch (OutOfMemoryError e) { + emergencySave(); + setScreen(new OutOfMemoryScreen()); + System.gc(); + } + */ + } /* - } catch (LevelConflictException e) { - this.level = null; - setLevel(null); - setScreen(new LevelConflictScreen()); - } catch (OutOfMemoryError e) { + } catch (StopGameException e) { + } catch (Throwable e) { emergencySave(); - setScreen(new OutOfMemoryScreen()); - System.gc(); + e.printStackTrace(); + crash(new CrashReport("Unexpected error", e)); + } finally { + destroy(); } */ } - /* - } catch (StopGameException e) { - } catch (Throwable e) { - emergencySave(); - e.printStackTrace(); - crash(new CrashReport("Unexpected error", e)); - } finally { - destroy(); - } - */ - } - } // lock_guard scope + } // lock_guard scope } void Minecraft::run_end() { destroy(); } diff --git a/Minecraft.Client/MinecraftServer.cpp b/Minecraft.Client/MinecraftServer.cpp index c5fb9936a..de1e9fda2 100644 --- a/Minecraft.Client/MinecraftServer.cpp +++ b/Minecraft.Client/MinecraftServer.cpp @@ -265,8 +265,9 @@ int MinecraftServer::runPostUpdate(void* lpParam) { { std::unique_lock lock(server->m_postProcessCS); int maxRequests = server->m_postProcessRequests.size(); - while (server->m_postProcessRequests.size() && - ShutdownManager::ShouldRun(ShutdownManager::ePostProcessThread)) { + while ( + server->m_postProcessRequests.size() && + ShutdownManager::ShouldRun(ShutdownManager::ePostProcessThread)) { MinecraftServer::postProcessRequest request = server->m_postProcessRequests.back(); server->m_postProcessRequests.pop_back(); @@ -287,9 +288,10 @@ int MinecraftServer::runPostUpdate(void* lpParam) { void MinecraftServer::addPostProcessRequest(ChunkSource* chunkSource, int x, int z) { - { std::lock_guard lock(m_postProcessCS); - m_postProcessRequests.push_back( - MinecraftServer::postProcessRequest(x, z, chunkSource)); + { + std::lock_guard lock(m_postProcessCS); + m_postProcessRequests.push_back( + MinecraftServer::postProcessRequest(x, z, chunkSource)); } } @@ -298,16 +300,17 @@ void MinecraftServer::postProcessTerminate(ProgressRenderer* mcprogress) { size_t postProcessItemCount = 0; size_t postProcessItemRemaining = 0; - { std::lock_guard lock(server->m_postProcessCS); - postProcessItemCount = server->m_postProcessRequests.size(); + { + std::lock_guard lock(server->m_postProcessCS); + postProcessItemCount = server->m_postProcessRequests.size(); } do { status = m_postUpdateThread->waitForCompletion(50); if (status == C4JThread::WaitResult::Timeout) { - { std::lock_guard lock(server->m_postProcessCS); - postProcessItemRemaining = - server->m_postProcessRequests.size(); + { + std::lock_guard lock(server->m_postProcessCS); + postProcessItemRemaining = server->m_postProcessRequests.size(); } if (postProcessItemCount) { diff --git a/Minecraft.Client/Network/MultiPlayerChunkCache.cpp b/Minecraft.Client/Network/MultiPlayerChunkCache.cpp index 984175ecb..960b231be 100644 --- a/Minecraft.Client/Network/MultiPlayerChunkCache.cpp +++ b/Minecraft.Client/Network/MultiPlayerChunkCache.cpp @@ -155,47 +155,51 @@ LevelChunk* MultiPlayerChunkCache::create(int x, int z) { LevelChunk* lastChunk = chunk; if (chunk == nullptr) { - { std::unique_lock lock(m_csLoadCreate); - - // LevelChunk *chunk; - if (g_NetworkManager.IsHost()) // force here to disable sharing of data { - // 4J-JEV: We are about to use shared data, abort if the server is - // stopped and the data is deleted. - if (MinecraftServer::getInstance()->serverHalted()) return nullptr; + std::unique_lock lock(m_csLoadCreate); - // If we're the host, then don't create the chunk, share data from - // the server's copy + // LevelChunk *chunk; + if (g_NetworkManager + .IsHost()) // force here to disable sharing of data + { + // 4J-JEV: We are about to use shared data, abort if the server + // is stopped and the data is deleted. + if (MinecraftServer::getInstance()->serverHalted()) + return nullptr; + + // If we're the host, then don't create the chunk, share data + // from the server's copy #ifdef _LARGE_WORLDS - LevelChunk* serverChunk = - MinecraftServer::getInstance() - ->getLevel(level->dimension->id) - ->cache->getChunkLoadedOrUnloaded(x, z); + LevelChunk* serverChunk = + MinecraftServer::getInstance() + ->getLevel(level->dimension->id) + ->cache->getChunkLoadedOrUnloaded(x, z); #else - LevelChunk* serverChunk = MinecraftServer::getInstance() - ->getLevel(level->dimension->id) - ->cache->getChunk(x, z); + LevelChunk* serverChunk = MinecraftServer::getInstance() + ->getLevel(level->dimension->id) + ->cache->getChunk(x, z); #endif - chunk = new LevelChunk(level, x, z, serverChunk); - // Let renderer know that this chunk has been created - it might - // have made render data from the EmptyChunk if it got to a chunk - // before the server sent it - level->setTilesDirty(x * 16, 0, z * 16, x * 16 + 15, 127, - z * 16 + 15); - hasData[idx] = true; - } else { - // Passing an empty array into the LevelChunk ctor, which it now - // detects and sets up the chunk as compressed & empty - byteArray bytes; + chunk = new LevelChunk(level, x, z, serverChunk); + // Let renderer know that this chunk has been created - it might + // have made render data from the EmptyChunk if it got to a + // chunk before the server sent it + level->setTilesDirty(x * 16, 0, z * 16, x * 16 + 15, 127, + z * 16 + 15); + hasData[idx] = true; + } else { + // Passing an empty array into the LevelChunk ctor, which it now + // detects and sets up the chunk as compressed & empty + byteArray bytes; - chunk = new LevelChunk(level, bytes, x, z); + chunk = new LevelChunk(level, bytes, x, z); - // 4J - changed to use new methods for lighting - chunk->setSkyLightDataAllBright(); - // Arrays::fill(chunk->skyLight->data, (byte) 255); - } + // 4J - changed to use new methods for lighting + chunk->setSkyLightDataAllBright(); + // Arrays::fill(chunk->skyLight->data, + //(byte) 255); + } - chunk->loaded = true; + chunk->loaded = true; } #if (defined _WIN64 || defined __LP64__) @@ -216,8 +220,9 @@ LevelChunk* MultiPlayerChunkCache::create(int x, int z) { } // Successfully updated the cache - { std::lock_guard lock(m_csLoadCreate); - loadedChunkList.push_back(chunk); + { + std::lock_guard lock(m_csLoadCreate); + loadedChunkList.push_back(chunk); } } else { // Something else must have updated the cache. Return that chunk and @@ -278,8 +283,9 @@ void MultiPlayerChunkCache::recreateLogicStructuresForChunk(int chunkX, std::wstring MultiPlayerChunkCache::gatherStats() { int size; - { std::lock_guard lock(m_csLoadCreate); - size = (int)loadedChunkList.size(); + { + std::lock_guard lock(m_csLoadCreate); + size = (int)loadedChunkList.size(); } return L"MultiplayerChunkCache: " + _toString(size); } diff --git a/Minecraft.Client/Network/PlayerConnection.cpp b/Minecraft.Client/Network/PlayerConnection.cpp index b9fec8180..eabe55c1f 100644 --- a/Minecraft.Client/Network/PlayerConnection.cpp +++ b/Minecraft.Client/Network/PlayerConnection.cpp @@ -69,9 +69,7 @@ PlayerConnection::PlayerConnection(MinecraftServer* server, app.GetGameHostOption(eGameHostOption_Gamertags) != 0 ? true : false); } -PlayerConnection::~PlayerConnection() { - delete connection; -} +PlayerConnection::~PlayerConnection() { delete connection; } void PlayerConnection::tick() { if (done) return; diff --git a/Minecraft.Client/Network/PlayerList.cpp b/Minecraft.Client/Network/PlayerList.cpp index 59a1ca273..6ad051886 100644 --- a/Minecraft.Client/Network/PlayerList.cpp +++ b/Minecraft.Client/Network/PlayerList.cpp @@ -48,7 +48,6 @@ PlayerList::PlayerList(MinecraftServer* server) { maxPlayers = server->settings->getInt(L"max-players", 20); doWhiteList = false; - } PlayerList::~PlayerList() { @@ -59,7 +58,6 @@ PlayerList::~PlayerList() { // back to this player (*it)->gameMode = nullptr; } - } void PlayerList::placeNewPlayer(Connection* connection, @@ -991,73 +989,76 @@ void PlayerList::tick() { } } - { std::lock_guard lock(m_closePlayersCS); - while (!m_smallIdsToClose.empty()) { - std::uint8_t smallId = m_smallIdsToClose.front(); - m_smallIdsToClose.pop_front(); + { + std::lock_guard lock(m_closePlayersCS); + while (!m_smallIdsToClose.empty()) { + std::uint8_t smallId = m_smallIdsToClose.front(); + m_smallIdsToClose.pop_front(); - std::shared_ptr player = nullptr; + std::shared_ptr player = nullptr; - for (unsigned int i = 0; i < players.size(); i++) { - std::shared_ptr p = players.at(i); - // 4J Stu - May be being a bit overprotective with all the nullptr - // checks, but adding late in TU7 so want to be safe - if (p != nullptr && p->connection != nullptr && - p->connection->connection != nullptr && - p->connection->connection->getSocket() != nullptr && - p->connection->connection->getSocket()->getSmallId() == - smallId) { - player = p; - break; + for (unsigned int i = 0; i < players.size(); i++) { + std::shared_ptr p = players.at(i); + // 4J Stu - May be being a bit overprotective with all the + // nullptr checks, but adding late in TU7 so want to be safe + if (p != nullptr && p->connection != nullptr && + p->connection->connection != nullptr && + p->connection->connection->getSocket() != nullptr && + p->connection->connection->getSocket()->getSmallId() == + smallId) { + player = p; + break; + } + } + + if (player != nullptr) { + player->connection->disconnect( + DisconnectPacket::eDisconnect_Closed); } } - - if (player != nullptr) { - player->connection->disconnect( - DisconnectPacket::eDisconnect_Closed); - } - } } - { std::lock_guard lock(m_kickPlayersCS); - while (!m_smallIdsToKick.empty()) { - std::uint8_t smallId = m_smallIdsToKick.front(); - m_smallIdsToKick.pop_front(); - INetworkPlayer* selectedPlayer = - g_NetworkManager.GetPlayerBySmallId(smallId); - if (selectedPlayer != nullptr) { - if (selectedPlayer->IsLocal() != true) { - // #if 0 - PlayerUID xuid = selectedPlayer->GetUID(); - // Kick this player from the game - std::shared_ptr player = nullptr; + { + std::lock_guard lock(m_kickPlayersCS); + while (!m_smallIdsToKick.empty()) { + std::uint8_t smallId = m_smallIdsToKick.front(); + m_smallIdsToKick.pop_front(); + INetworkPlayer* selectedPlayer = + g_NetworkManager.GetPlayerBySmallId(smallId); + if (selectedPlayer != nullptr) { + if (selectedPlayer->IsLocal() != true) { + // #if 0 + PlayerUID xuid = selectedPlayer->GetUID(); + // Kick this player from the game + std::shared_ptr player = nullptr; - for (unsigned int i = 0; i < players.size(); i++) { - std::shared_ptr p = players.at(i); - PlayerUID playersXuid = p->getOnlineXuid(); - if (p != nullptr && - ProfileManager.AreXUIDSEqual(playersXuid, xuid)) { - player = p; - break; + for (unsigned int i = 0; i < players.size(); i++) { + std::shared_ptr p = players.at(i); + PlayerUID playersXuid = p->getOnlineXuid(); + if (p != nullptr && + ProfileManager.AreXUIDSEqual(playersXuid, xuid)) { + player = p; + break; + } } - } - if (player != nullptr) { - m_bannedXuids.push_back(player->getOnlineXuid()); - // 4J Stu - If we have kicked a player, make sure that they - // have no privileges if they later try to join the world - // when trust players is off - player->enableAllPlayerPrivileges(false); - player->connection->setWasKicked(); - player->connection->send( - std::shared_ptr(new DisconnectPacket( - DisconnectPacket::eDisconnect_Kicked))); + if (player != nullptr) { + m_bannedXuids.push_back(player->getOnlineXuid()); + // 4J Stu - If we have kicked a player, make sure that + // they have no privileges if they later try to join the + // world when trust players is off + player->enableAllPlayerPrivileges(false); + player->connection->setWasKicked(); + player->connection->send( + std::shared_ptr( + new DisconnectPacket( + DisconnectPacket::eDisconnect_Kicked))); + } + // #endif } - // #endif } } } - } // Check our receiving players, and if they are dead see if we can replace // them @@ -1624,14 +1625,16 @@ bool PlayerList::canReceiveAllPackets(std::shared_ptr player) { } void PlayerList::kickPlayerByShortId(std::uint8_t networkSmallId) { - { std::lock_guard lock(m_kickPlayersCS); - m_smallIdsToKick.push_back(networkSmallId); + { + std::lock_guard lock(m_kickPlayersCS); + m_smallIdsToKick.push_back(networkSmallId); } } void PlayerList::closePlayerConnectionBySmallId(std::uint8_t networkSmallId) { - { std::lock_guard lock(m_closePlayersCS); - m_smallIdsToClose.push_back(networkSmallId); + { + std::lock_guard lock(m_closePlayersCS); + m_smallIdsToClose.push_back(networkSmallId); } } diff --git a/Minecraft.Client/Network/ServerChunkCache.cpp b/Minecraft.Client/Network/ServerChunkCache.cpp index 40628a484..79e5775af 100644 --- a/Minecraft.Client/Network/ServerChunkCache.cpp +++ b/Minecraft.Client/Network/ServerChunkCache.cpp @@ -38,7 +38,6 @@ ServerChunkCache::ServerChunkCache(ServerLevel* level, ChunkStorage* storage, m_unloadedCache = new LevelChunk*[XZSIZE * XZSIZE]; memset(m_unloadedCache, 0, XZSIZE * XZSIZE * sizeof(LevelChunk*)); #endif - } // 4J-PB added @@ -144,18 +143,19 @@ LevelChunk* ServerChunkCache::create( LevelChunk* lastChunk = chunk; if ((chunk == nullptr) || (chunk->x != x) || (chunk->z != z)) { - { std::lock_guard lock(m_csLoadCreate); - chunk = load(x, z); - if (chunk == nullptr) { - if (source == nullptr) { - chunk = emptyChunk; - } else { - chunk = source->getChunk(x, z); + { + std::lock_guard lock(m_csLoadCreate); + chunk = load(x, z); + if (chunk == nullptr) { + if (source == nullptr) { + chunk = emptyChunk; + } else { + chunk = source->getChunk(x, z); + } + } + if (chunk != nullptr) { + chunk->load(); } - } - if (chunk != nullptr) { - chunk->load(); - } } #if defined(_WIN64) || defined(__LP64__) @@ -649,11 +649,12 @@ bool ServerChunkCache::saveAllEntities() { PIXBeginNamedEvent(0, "Save all entities"); PIXBeginNamedEvent(0, "saving to NBT"); - { std::lock_guard lock(m_csLoadCreate); - for (auto it = m_loadedChunkList.begin(); it != m_loadedChunkList.end(); - ++it) { - storage->saveEntities(level, *it); - } + { + std::lock_guard lock(m_csLoadCreate); + for (auto it = m_loadedChunkList.begin(); it != m_loadedChunkList.end(); + ++it) { + storage->saveEntities(level, *it); + } } PIXEndNamedEvent(); @@ -860,7 +861,8 @@ int ServerChunkCache::runSaveThreadProc(void* lpParam) { // Wait for the producer thread to tell us to start params->wakeEvent->waitForSignal( - C4JThread::kInfiniteTimeout); // WaitForSingleObject(params->wakeEvent,INFINITE); + C4JThread:: + kInfiniteTimeout); // WaitForSingleObject(params->wakeEvent,INFINITE); // app.DebugPrintf("Save thread has started\n"); @@ -887,7 +889,8 @@ int ServerChunkCache::runSaveThreadProc(void* lpParam) { // Wait for the producer thread to tell us to go again params->wakeEvent->waitForSignal( - C4JThread::kInfiniteTimeout); // WaitForSingleObject(params->wakeEvent,INFINITE); + C4JThread:: + kInfiniteTimeout); // WaitForSingleObject(params->wakeEvent,INFINITE); PIXEndNamedEvent(); } diff --git a/Minecraft.Client/Network/ServerConnection.cpp b/Minecraft.Client/Network/ServerConnection.cpp index a8edd72d2..13aab0dd6 100644 --- a/Minecraft.Client/Network/ServerConnection.cpp +++ b/Minecraft.Client/Network/ServerConnection.cpp @@ -34,17 +34,19 @@ void ServerConnection::addPlayerConnection( } void ServerConnection::handleConnection(std::shared_ptr uc) { - { std::lock_guard lock(pending_cs); - pending.push_back(uc); + { + std::lock_guard lock(pending_cs); + pending.push_back(uc); } } void ServerConnection::stop() { - { std::lock_guard lock(pending_cs); - for (unsigned int i = 0; i < pending.size(); i++) { - std::shared_ptr uc = pending[i]; - uc->connection->close(DisconnectPacket::eDisconnect_Closed); - } + { + std::lock_guard lock(pending_cs); + for (unsigned int i = 0; i < pending.size(); i++) { + std::shared_ptr uc = pending[i]; + uc->connection->close(DisconnectPacket::eDisconnect_Closed); + } } for (unsigned int i = 0; i < players.size(); i++) { @@ -58,8 +60,9 @@ void ServerConnection::tick() { // MGH - changed this so that the the CS lock doesn't cover the tick // (was causing a lockup when 2 players tried to join) std::vector > tempPending; - { std::lock_guard lock(pending_cs); - tempPending = pending; + { + std::lock_guard lock(pending_cs); + tempPending = pending; } for (unsigned int i = 0; i < tempPending.size(); i++) { @@ -76,12 +79,13 @@ void ServerConnection::tick() { } // now remove from the pending list - { std::lock_guard lock(pending_cs); - for (unsigned int i = 0; i < pending.size(); i++) - if (pending[i]->done) { - pending.erase(pending.begin() + i); - i--; - } + { + std::lock_guard lock(pending_cs); + for (unsigned int i = 0; i < pending.size(); i++) + if (pending[i]->done) { + pending.erase(pending.begin() + i); + i--; + } } for (unsigned int i = 0; i < players.size(); i++) { diff --git a/Minecraft.Client/Platform/Common/Consoles_App.cpp b/Minecraft.Client/Platform/Common/Consoles_App.cpp index edc049903..e6ea0b3c5 100644 --- a/Minecraft.Client/Platform/Common/Consoles_App.cpp +++ b/Minecraft.Client/Platform/Common/Consoles_App.cpp @@ -4613,9 +4613,10 @@ bool CMinecraftApp::DefaultCapeExists() { std::wstring wTex = L"Special_Cape.png"; bool val = false; - { std::lock_guard lock(csMemFilesLock); - auto it = m_MEM_Files.find(wTex); - if (it != m_MEM_Files.end()) val = true; + { + std::lock_guard lock(csMemFilesLock); + auto it = m_MEM_Files.find(wTex); + if (it != m_MEM_Files.end()) val = true; } return val; @@ -4624,9 +4625,10 @@ bool CMinecraftApp::DefaultCapeExists() { bool CMinecraftApp::IsFileInMemoryTextures(const std::wstring& wName) { bool val = false; - { std::lock_guard lock(csMemFilesLock); - auto it = m_MEM_Files.find(wName); - if (it != m_MEM_Files.end()) val = true; + { + std::lock_guard lock(csMemFilesLock); + auto it = m_MEM_Files.find(wName); + if (it != m_MEM_Files.end()) val = true; } return val; @@ -4678,9 +4680,10 @@ int CMinecraftApp::GetTPConfigVal(wchar_t* pwchDataFile) { return -1; } bool CMinecraftApp::IsFileInTPD(int iConfig) { bool val = false; - { std::lock_guard lock(csMemTPDLock); - auto it = m_MEM_TPD.find(iConfig); - if (it != m_MEM_TPD.end()) val = true; + { + std::lock_guard lock(csMemTPDLock); + auto it = m_MEM_TPD.find(iConfig); + if (it != m_MEM_TPD.end()) val = true; } return val; @@ -6607,41 +6610,42 @@ std::uint32_t CMinecraftApp::m_dwContentTypeA[e_Marketplace_MAX] = { unsigned int CMinecraftApp::AddDLCRequest(eDLCMarketplaceType eType, bool bPromote) { // lock access - { std::lock_guard lock(csDLCDownloadQueue); + { + std::lock_guard lock(csDLCDownloadQueue); - // If it's already in there, promote it to the top of the list - int iPosition = 0; - for (auto it = m_DLCDownloadQueue.begin(); it != m_DLCDownloadQueue.end(); - ++it) { - DLCRequest* pCurrent = *it; + // If it's already in there, promote it to the top of the list + int iPosition = 0; + for (auto it = m_DLCDownloadQueue.begin(); + it != m_DLCDownloadQueue.end(); ++it) { + DLCRequest* pCurrent = *it; - if (pCurrent->dwType == m_dwContentTypeA[eType]) { - // already got this in the list - if (pCurrent->eState == e_DLC_ContentState_Retrieving || - pCurrent->eState == e_DLC_ContentState_Retrieved) { - // already retrieved this - return 0; - } else { - // promote - if (bPromote) { - m_DLCDownloadQueue.erase(m_DLCDownloadQueue.begin() + - iPosition); - m_DLCDownloadQueue.insert(m_DLCDownloadQueue.begin(), - pCurrent); + if (pCurrent->dwType == m_dwContentTypeA[eType]) { + // already got this in the list + if (pCurrent->eState == e_DLC_ContentState_Retrieving || + pCurrent->eState == e_DLC_ContentState_Retrieved) { + // already retrieved this + return 0; + } else { + // promote + if (bPromote) { + m_DLCDownloadQueue.erase(m_DLCDownloadQueue.begin() + + iPosition); + m_DLCDownloadQueue.insert(m_DLCDownloadQueue.begin(), + pCurrent); + } + return 0; } - return 0; } + iPosition++; } - iPosition++; - } - DLCRequest* pDLCreq = new DLCRequest; - pDLCreq->dwType = m_dwContentTypeA[eType]; - pDLCreq->eState = e_DLC_ContentState_Idle; + DLCRequest* pDLCreq = new DLCRequest; + pDLCreq->dwType = m_dwContentTypeA[eType]; + pDLCreq->eState = e_DLC_ContentState_Idle; - m_DLCDownloadQueue.push_back(pDLCreq); + m_DLCDownloadQueue.push_back(pDLCreq); - m_bAllDLCContentRetrieved = false; + m_bAllDLCContentRetrieved = false; } app.DebugPrintf("[Consoles_App] Added DLC request.\n"); @@ -6859,41 +6863,42 @@ bool CMinecraftApp::RetrieveNextDLCContent() { // online. } - { std::lock_guard lock(csDLCDownloadQueue); - for (auto it = m_DLCDownloadQueue.begin(); it != m_DLCDownloadQueue.end(); - ++it) { - DLCRequest* pCurrent = *it; + { + std::lock_guard lock(csDLCDownloadQueue); + for (auto it = m_DLCDownloadQueue.begin(); + it != m_DLCDownloadQueue.end(); ++it) { + DLCRequest* pCurrent = *it; - if (pCurrent->eState == e_DLC_ContentState_Retrieving) { - return true; + if (pCurrent->eState == e_DLC_ContentState_Retrieving) { + return true; + } } - } - // Now look for the next retrieval - for (auto it = m_DLCDownloadQueue.begin(); it != m_DLCDownloadQueue.end(); - ++it) { - DLCRequest* pCurrent = *it; + // Now look for the next retrieval + for (auto it = m_DLCDownloadQueue.begin(); + it != m_DLCDownloadQueue.end(); ++it) { + DLCRequest* pCurrent = *it; - if (pCurrent->eState == e_DLC_ContentState_Idle) { + if (pCurrent->eState == e_DLC_ContentState_Idle) { #if defined(_DEBUG) - app.DebugPrintf("RetrieveNextDLCContent - type = %d\n", - pCurrent->dwType); + app.DebugPrintf("RetrieveNextDLCContent - type = %d\n", + pCurrent->dwType); #endif - C4JStorage::EDLCStatus status = StorageManager.GetDLCOffers( - ProfileManager.GetPrimaryPad(), - &CMinecraftApp::DLCOffersReturned, this, pCurrent->dwType); - if (status == C4JStorage::EDLC_Pending) { - pCurrent->eState = e_DLC_ContentState_Retrieving; - } else { - // no content of this type, or some other problem - app.DebugPrintf("RetrieveNextDLCContent - PROBLEM\n"); - pCurrent->eState = e_DLC_ContentState_Retrieved; + C4JStorage::EDLCStatus status = StorageManager.GetDLCOffers( + ProfileManager.GetPrimaryPad(), + &CMinecraftApp::DLCOffersReturned, this, pCurrent->dwType); + if (status == C4JStorage::EDLC_Pending) { + pCurrent->eState = e_DLC_ContentState_Retrieving; + } else { + // no content of this type, or some other problem + app.DebugPrintf("RetrieveNextDLCContent - PROBLEM\n"); + pCurrent->eState = e_DLC_ContentState_Retrieved; + } + return true; } - return true; } } - } app.DebugPrintf("[Consoles_App] Finished downloading dlc content.\n"); return false; @@ -6905,46 +6910,48 @@ int CMinecraftApp::TMSPPFileReturned(void* pParam, int iPad, int iUserData, CMinecraftApp* pClass = (CMinecraftApp*)pParam; // find the right one in the vector - { std::lock_guard lock(pClass->csTMSPPDownloadQueue); - for (auto it = pClass->m_TMSPPDownloadQueue.begin(); - it != pClass->m_TMSPPDownloadQueue.end(); ++it) { - TMSPPRequest* pCurrent = *it; + { + std::lock_guard lock(pClass->csTMSPPDownloadQueue); + for (auto it = pClass->m_TMSPPDownloadQueue.begin(); + it != pClass->m_TMSPPDownloadQueue.end(); ++it) { + TMSPPRequest* pCurrent = *it; #if defined(_WINDOWS64) - char szFile[MAX_TMSFILENAME_SIZE]; - wcstombs(szFile, pCurrent->wchFilename, MAX_TMSFILENAME_SIZE); + char szFile[MAX_TMSFILENAME_SIZE]; + wcstombs(szFile, pCurrent->wchFilename, MAX_TMSFILENAME_SIZE); - if (strcmp(szFilename, szFile) == 0) + if (strcmp(szFilename, szFile) == 0) #endif - { - // set this to retrieved whether it found it or not - pCurrent->eState = e_TMS_ContentState_Retrieved; + { + // set this to retrieved whether it found it or not + pCurrent->eState = e_TMS_ContentState_Retrieved; - if (pFileData != nullptr) { - switch (pCurrent->eType) { - case e_DLC_TexturePackData: { - app.DebugPrintf("--- Got texturepack data %ls\n", - pCurrent->wchFilename); - // get the config value for the texture pack - int iConfig = app.GetTPConfigVal(pCurrent->wchFilename); - app.AddMemoryTPDFile(iConfig, pFileData->pbData, - pFileData->size); - } break; - default: - app.DebugPrintf("--- Got image data - %ls\n", - pCurrent->wchFilename); - app.AddMemoryTextureFile(pCurrent->wchFilename, - pFileData->pbData, + if (pFileData != nullptr) { + switch (pCurrent->eType) { + case e_DLC_TexturePackData: { + app.DebugPrintf("--- Got texturepack data %ls\n", + pCurrent->wchFilename); + // get the config value for the texture pack + int iConfig = + app.GetTPConfigVal(pCurrent->wchFilename); + app.AddMemoryTPDFile(iConfig, pFileData->pbData, pFileData->size); - break; + } break; + default: + app.DebugPrintf("--- Got image data - %ls\n", + pCurrent->wchFilename); + app.AddMemoryTextureFile(pCurrent->wchFilename, + pFileData->pbData, + pFileData->size); + break; + } + } else { + app.DebugPrintf("TMSImageReturned failed (%s)...\n", + szFilename); } - } else { - app.DebugPrintf("TMSImageReturned failed (%s)...\n", - szFilename); + break; } - break; } } - } return 0; } @@ -6963,16 +6970,17 @@ void CMinecraftApp::ClearAndResetDLCDownloadQueue() { app.DebugPrintf("[Consoles_App] Clear and reset download queue.\n"); int iPosition = 0; - { std::lock_guard lock(csTMSPPDownloadQueue); - for (auto it = m_DLCDownloadQueue.begin(); it != m_DLCDownloadQueue.end(); - ++it) { - DLCRequest* pCurrent = *it; + { + std::lock_guard lock(csTMSPPDownloadQueue); + for (auto it = m_DLCDownloadQueue.begin(); + it != m_DLCDownloadQueue.end(); ++it) { + DLCRequest* pCurrent = *it; - delete pCurrent; - iPosition++; - } - m_DLCDownloadQueue.clear(); - m_bAllDLCContentRetrieved = true; + delete pCurrent; + iPosition++; + } + m_DLCDownloadQueue.clear(); + m_bAllDLCContentRetrieved = true; } } @@ -6985,16 +6993,17 @@ void CMinecraftApp::TickTMSPPFilesRetrieved() { } void CMinecraftApp::ClearTMSPPFilesRetrieved() { int iPosition = 0; - { std::lock_guard lock(csTMSPPDownloadQueue); - for (auto it = m_TMSPPDownloadQueue.begin(); - it != m_TMSPPDownloadQueue.end(); ++it) { - TMSPPRequest* pCurrent = *it; + { + std::lock_guard lock(csTMSPPDownloadQueue); + for (auto it = m_TMSPPDownloadQueue.begin(); + it != m_TMSPPDownloadQueue.end(); ++it) { + TMSPPRequest* pCurrent = *it; - delete pCurrent; - iPosition++; - } - m_TMSPPDownloadQueue.clear(); - m_bAllTMSContentRetrieved = true; + delete pCurrent; + iPosition++; + } + m_TMSPPDownloadQueue.clear(); + m_bAllTMSContentRetrieved = true; } } @@ -7003,24 +7012,25 @@ int CMinecraftApp::DLCOffersReturned(void* pParam, int iOfferC, CMinecraftApp* pClass = (CMinecraftApp*)pParam; // find the right one in the vector - { std::lock_guard lock(pClass->csTMSPPDownloadQueue); - for (auto it = pClass->m_DLCDownloadQueue.begin(); - it != pClass->m_DLCDownloadQueue.end(); ++it) { - DLCRequest* pCurrent = *it; + { + std::lock_guard lock(pClass->csTMSPPDownloadQueue); + for (auto it = pClass->m_DLCDownloadQueue.begin(); + it != pClass->m_DLCDownloadQueue.end(); ++it) { + DLCRequest* pCurrent = *it; - // avatar items are coming back as type Content, so we can't trust the - // type setting - if (pCurrent->dwType == static_cast(dwType)) { - pClass->m_iDLCOfferC = iOfferC; - app.DebugPrintf( - "DLCOffersReturned - type %u, count %d - setting to " - "retrieved\n", - dwType, iOfferC); - pCurrent->eState = e_DLC_ContentState_Retrieved; - break; + // avatar items are coming back as type Content, so we can't trust + // the type setting + if (pCurrent->dwType == static_cast(dwType)) { + pClass->m_iDLCOfferC = iOfferC; + app.DebugPrintf( + "DLCOffersReturned - type %u, count %d - setting to " + "retrieved\n", + dwType, iOfferC); + pCurrent->eState = e_DLC_ContentState_Retrieved; + break; + } } } - } return 0; } @@ -7057,29 +7067,32 @@ void CMinecraftApp::SetAdditionalSkinBoxes(std::uint32_t dwSkinID, std::vector* pvModelPart = new std::vector; std::vector* pvSkinBoxes = new std::vector; - { std::lock_guard lock_mp(csAdditionalModelParts); - std::lock_guard lock_sb(csAdditionalSkinBoxes); + { + std::lock_guard lock_mp(csAdditionalModelParts); + std::lock_guard lock_sb(csAdditionalSkinBoxes); - app.DebugPrintf( - "*** SetAdditionalSkinBoxes - Inserting model parts for skin %d from " - "array of Skin Boxes\n", - dwSkinID & 0x0FFFFFFF); + app.DebugPrintf( + "*** SetAdditionalSkinBoxes - Inserting model parts for skin %d " + "from " + "array of Skin Boxes\n", + dwSkinID & 0x0FFFFFFF); - // convert the skin boxes into model parts, and add to the humanoid model - for (unsigned int i = 0; i < dwSkinBoxC; i++) { - if (pModel) { - ModelPart* pModelPart = pModel->AddOrRetrievePart(&SkinBoxA[i]); - pvModelPart->push_back(pModelPart); - pvSkinBoxes->push_back(&SkinBoxA[i]); + // convert the skin boxes into model parts, and add to the humanoid + // model + for (unsigned int i = 0; i < dwSkinBoxC; i++) { + if (pModel) { + ModelPart* pModelPart = pModel->AddOrRetrievePart(&SkinBoxA[i]); + pvModelPart->push_back(pModelPart); + pvSkinBoxes->push_back(&SkinBoxA[i]); + } } - } - m_AdditionalModelParts.insert( - std::pair*>(dwSkinID, - pvModelPart)); - m_AdditionalSkinBoxes.insert( - std::pair*>(dwSkinID, - pvSkinBoxes)); + m_AdditionalModelParts.insert( + std::pair*>(dwSkinID, + pvModelPart)); + m_AdditionalSkinBoxes.insert( + std::pair*>(dwSkinID, + pvSkinBoxes)); } } @@ -7090,27 +7103,30 @@ std::vector* CMinecraftApp::SetAdditionalSkinBoxes( Model* pModel = renderer->getModel(); std::vector* pvModelPart = new std::vector; - { std::lock_guard lock_mp(csAdditionalModelParts); - std::lock_guard lock_sb(csAdditionalSkinBoxes); - app.DebugPrintf( - "*** SetAdditionalSkinBoxes - Inserting model parts for skin %d from " - "array of Skin Boxes\n", - dwSkinID & 0x0FFFFFFF); + { + std::lock_guard lock_mp(csAdditionalModelParts); + std::lock_guard lock_sb(csAdditionalSkinBoxes); + app.DebugPrintf( + "*** SetAdditionalSkinBoxes - Inserting model parts for skin %d " + "from " + "array of Skin Boxes\n", + dwSkinID & 0x0FFFFFFF); - // convert the skin boxes into model parts, and add to the humanoid model - for (auto it = pvSkinBoxA->begin(); it != pvSkinBoxA->end(); ++it) { - if (pModel) { - ModelPart* pModelPart = pModel->AddOrRetrievePart(*it); - pvModelPart->push_back(pModelPart); + // convert the skin boxes into model parts, and add to the humanoid + // model + for (auto it = pvSkinBoxA->begin(); it != pvSkinBoxA->end(); ++it) { + if (pModel) { + ModelPart* pModelPart = pModel->AddOrRetrievePart(*it); + pvModelPart->push_back(pModelPart); + } } - } - m_AdditionalModelParts.insert( - std::pair*>(dwSkinID, - pvModelPart)); - m_AdditionalSkinBoxes.insert( - std::pair*>(dwSkinID, - pvSkinBoxA)); + m_AdditionalModelParts.insert( + std::pair*>(dwSkinID, + pvModelPart)); + m_AdditionalSkinBoxes.insert( + std::pair*>(dwSkinID, + pvSkinBoxA)); } return pvModelPart; } diff --git a/Minecraft.Client/Platform/Common/Leaderboards/SonyLeaderboardManager.cpp b/Minecraft.Client/Platform/Common/Leaderboards/SonyLeaderboardManager.cpp index 600a3e3f3..7397abb93 100644 --- a/Minecraft.Client/Platform/Common/Leaderboards/SonyLeaderboardManager.cpp +++ b/Minecraft.Client/Platform/Common/Leaderboards/SonyLeaderboardManager.cpp @@ -33,7 +33,6 @@ SonyLeaderboardManager::SonyLeaderboardManager() { m_openSessions = 0; - m_running = false; m_threadScoreboard = nullptr; } @@ -49,7 +48,6 @@ SonyLeaderboardManager::~SonyLeaderboardManager() { } delete m_threadScoreboard; - } int SonyLeaderboardManager::scoreboardThreadEntry(void* lpParam) { @@ -66,8 +64,9 @@ int SonyLeaderboardManager::scoreboardThreadEntry(void* lpParam) { self->scoreboardThreadInternal(); } - { std::lock_guard lock(self->m_csViewsLock); - needsWriting = self->m_views.size() > 0; + { + std::lock_guard lock(self->m_csViewsLock); + needsWriting = self->m_views.size() > 0; } // 4J Stu - We can't write while we aren't signed in to live @@ -165,8 +164,9 @@ void SonyLeaderboardManager::scoreboardThreadInternal() { // we'll manage the write queue seperately. bool hasWork; - { std::lock_guard lock(m_csViewsLock); - hasWork = !m_views.empty(); + { + std::lock_guard lock(m_csViewsLock); + hasWork = !m_views.empty(); } if (hasWork) { @@ -493,9 +493,10 @@ bool SonyLeaderboardManager::setScore() { // Get next job. RegisterScore rscore; - { std::lock_guard lock(m_csViewsLock); - rscore = m_views.front(); - m_views.pop(); + { + std::lock_guard lock(m_csViewsLock); + rscore = m_views.front(); + m_views.pop(); } if (ProfileManager.IsGuest(rscore.m_iPad)) { @@ -641,7 +642,8 @@ bool SonyLeaderboardManager::OpenSession() { m_threadScoreboard = new C4JThread(&scoreboardThreadEntry, this, "4JScoreboard"); m_threadScoreboard->setProcessor(CPU_CORE_LEADERBOARDS); - m_threadScoreboard->setPriority(C4JThread::ThreadPriority::BelowNormal); + m_threadScoreboard->setPriority( + C4JThread::ThreadPriority::BelowNormal); m_threadScoreboard->run(); } @@ -682,16 +684,18 @@ bool SonyLeaderboardManager::WriteStats(unsigned int viewCount, ViewIn views) { // Write relevant parameters. // RegisterScore *regScore = reinterpret_cast(views); - { std::lock_guard lock(m_csViewsLock); - for (int i = 0; i < viewCount; i++) { - app.DebugPrintf( - "[SonyLeaderboardManager] WriteStats(), starting. difficulty=%i, " - "statsType=%i, score=%i\n", - views[i].m_difficulty, views[i].m_commentData.m_statsType, - views[i].m_score); + { + std::lock_guard lock(m_csViewsLock); + for (int i = 0; i < viewCount; i++) { + app.DebugPrintf( + "[SonyLeaderboardManager] WriteStats(), starting. " + "difficulty=%i, " + "statsType=%i, score=%i\n", + views[i].m_difficulty, views[i].m_commentData.m_statsType, + views[i].m_score); - m_views.push(views[i]); - } + m_views.push(views[i]); + } } delete[] views; //*regScore; diff --git a/Minecraft.Client/Platform/Common/UI/UIController.cpp b/Minecraft.Client/Platform/Common/UI/UIController.cpp index dcff5c66f..341b9d78e 100644 --- a/Minecraft.Client/Platform/Common/UI/UIController.cpp +++ b/Minecraft.Client/Platform/Common/UI/UIController.cpp @@ -616,8 +616,9 @@ void UIController::StartReloadSkinThread() { int UIController::reloadSkinThreadProc(void* lpParam) { { - std::lock_guard lock(ms_reloadSkinCS); // MGH - added to prevent crash loading Iggy movies - // while the skins were being reloaded + std::lock_guard lock( + ms_reloadSkinCS); // MGH - added to prevent crash loading Iggy + // movies while the skins were being reloaded UIController* controller = (UIController*)lpParam; // Load new skin controller->loadSkins(); @@ -1400,9 +1401,7 @@ UIScene* UIController::GetSceneFromCallbackId(size_t id) { return scene; } -void UIController::lockCallbackScenes() { - m_registeredCallbackScenesCS.lock(); -} +void UIController::lockCallbackScenes() { m_registeredCallbackScenesCS.lock(); } void UIController::unlockCallbackScenes() { m_registeredCallbackScenesCS.unlock(); diff --git a/Minecraft.Client/Platform/Common/UI/UIScene.cpp b/Minecraft.Client/Platform/Common/UI/UIScene.cpp index fe1b1df1e..632273c6b 100644 --- a/Minecraft.Client/Platform/Common/UI/UIScene.cpp +++ b/Minecraft.Client/Platform/Common/UI/UIScene.cpp @@ -247,8 +247,8 @@ bool UIScene::mapElementsAndNames() { extern std::mutex s_loadSkinCS; void UIScene::loadMovie() { UIController::ms_reloadSkinCS.lock(); // MGH - added to prevent crash - // loading Iggy movies while the skins - // were being reloaded + // loading Iggy movies while the + // skins were being reloaded std::wstring moviePath = getMoviePath(); #if defined(_WINDOWS64) diff --git a/Minecraft.Client/Rendering/Chunk.cpp b/Minecraft.Client/Rendering/Chunk.cpp index 9b3681b46..091f45ddc 100644 --- a/Minecraft.Client/Rendering/Chunk.cpp +++ b/Minecraft.Client/Rendering/Chunk.cpp @@ -93,8 +93,8 @@ void Chunk::reconcileRenderableTileEntities( // TODO - 4J see how input entity vector is set up and decide what way is best // to pass this to the function Chunk::Chunk(Level* level, LevelRenderer::rteMap& globalRenderableTileEntities, - std::mutex& globalRenderableTileEntities_cs, int x, int y, - int z, ClipChunk* clipChunk) + std::mutex& globalRenderableTileEntities_cs, int x, int y, int z, + ClipChunk* clipChunk) : globalRenderableTileEntities(&globalRenderableTileEntities), globalRenderableTileEntities_cs(&globalRenderableTileEntities_cs) { clipChunk->visible = false; @@ -151,25 +151,27 @@ void Chunk::setPos(int x, int y, int z) { assigned = true; { - std::lock_guard lock(levelRenderer->m_csDirtyChunks); + std::lock_guard lock( + levelRenderer->m_csDirtyChunks); unsigned char refCount = levelRenderer->incGlobalChunkRefCount(x, y, z, level); // printf("\t\t [inc] refcount %d at %d, %d, %d\n",refCount,x,y,z); // int idx = levelRenderer->getGlobalIndexForChunk(x, y, z, level); - // If we're the first thing to be referencing this, mark it up as dirty to - // get rebuilt + // If we're the first thing to be referencing this, mark it up as dirty + // to get rebuilt if (refCount == 1) { // printf("Setting %d %d %d dirty [%d]\n",x,y,z, idx); - // Chunks being made dirty in this way can be very numerous (eg the full - // visible area of the world at start up, or a whole edge of the world - // when moving). On account of this, don't want to stick them into our - // lock free queue that we would normally use for letting the render - // update thread know about this chunk. Instead, just set the flag to - // say this is dirty, and then pass a special value of 1 through to the - // lock free stack which lets that thread know that at least one chunk - // other than the ones in the stack itself have been made dirty. + // Chunks being made dirty in this way can be very numerous (eg the + // full visible area of the world at start up, or a whole edge of + // the world when moving). On account of this, don't want to stick + // them into our lock free queue that we would normally use for + // letting the render update thread know about this chunk. Instead, + // just set the flag to say this is dirty, and then pass a special + // value of 1 through to the lock free stack which lets that thread + // know that at least one chunk other than the ones in the stack + // itself have been made dirty. levelRenderer->setGlobalChunkFlag(x, y, z, level, LevelRenderer::CHUNK_FLAG_DIRTY); PIXSetMarkerDeprecated(0, "Non-stack event pushed"); @@ -722,7 +724,8 @@ void Chunk::reset() { bool retireRenderableTileEntities = false; { - std::lock_guard lock(levelRenderer->m_csDirtyChunks); + std::lock_guard lock( + levelRenderer->m_csDirtyChunks); oldKey = levelRenderer->getGlobalIndexForChunk(x, y, z, level); unsigned char refCount = levelRenderer->decGlobalChunkRefCount(x, y, z, level); @@ -735,8 +738,8 @@ void Chunk::reset() { if (lists >= 0) { lists += levelRenderer->chunkLists; for (int i = 0; i < 2; i++) { - // 4J - added - clear any renderer data associated with this - // unused list + // 4J - added - clear any renderer data associated with + // this unused list RenderManager.CBuffClear(lists + i); } levelRenderer->setGlobalChunkFlags(x, y, z, level, 0); diff --git a/Minecraft.Client/Rendering/Chunk.h b/Minecraft.Client/Rendering/Chunk.h index 0aacdb2c8..90c5004fb 100644 --- a/Minecraft.Client/Rendering/Chunk.h +++ b/Minecraft.Client/Rendering/Chunk.h @@ -61,8 +61,8 @@ private: public: Chunk(Level* level, LevelRenderer::rteMap& globalRenderableTileEntities, - std::mutex& globalRenderableTileEntities_cs, int x, int y, - int z, ClipChunk* clipChunk); + std::mutex& globalRenderableTileEntities_cs, int x, int y, int z, + ClipChunk* clipChunk); Chunk(); void setPos(int x, int y, int z); diff --git a/Minecraft.Client/Rendering/EntityRenderers/ProgressRenderer.cpp b/Minecraft.Client/Rendering/EntityRenderers/ProgressRenderer.cpp index 795daf8fb..68ed3dbad 100644 --- a/Minecraft.Client/Rendering/EntityRenderers/ProgressRenderer.cpp +++ b/Minecraft.Client/Rendering/EntityRenderers/ProgressRenderer.cpp @@ -34,7 +34,8 @@ void ProgressRenderer::_progressStart(int title) { } { - std::lock_guard lock(ProgressRenderer::s_progress); + std::lock_guard lock( + ProgressRenderer::s_progress); lastPercent = 0; this->title = title; } @@ -48,7 +49,8 @@ void ProgressRenderer::progressStage(int status) { lastTime = 0; { - std::lock_guard lock(ProgressRenderer::s_progress); + std::lock_guard lock( + ProgressRenderer::s_progress); m_eType = eProgressStringType_ID; this->status = status; } @@ -60,7 +62,8 @@ void ProgressRenderer::progressStagePercentage(int i) { // 4J Stu - Removing all progressRenderer rendering. This will be replaced // on the xbox { - std::lock_guard lock(ProgressRenderer::s_progress); + std::lock_guard lock( + ProgressRenderer::s_progress); lastPercent = i; } } @@ -68,7 +71,8 @@ void ProgressRenderer::progressStagePercentage(int i) { int ProgressRenderer::getCurrentPercent() { int returnValue = 0; { - std::lock_guard lock(ProgressRenderer::s_progress); + std::lock_guard lock( + ProgressRenderer::s_progress); returnValue = lastPercent; } return returnValue; @@ -77,7 +81,8 @@ int ProgressRenderer::getCurrentPercent() { int ProgressRenderer::getCurrentTitle() { int returnValue; { - std::lock_guard lock(ProgressRenderer::s_progress); + std::lock_guard lock( + ProgressRenderer::s_progress); returnValue = title; } return returnValue; @@ -86,7 +91,8 @@ int ProgressRenderer::getCurrentTitle() { int ProgressRenderer::getCurrentStatus() { int returnValue; { - std::lock_guard lock(ProgressRenderer::s_progress); + std::lock_guard lock( + ProgressRenderer::s_progress); returnValue = status; } return returnValue; @@ -95,7 +101,8 @@ int ProgressRenderer::getCurrentStatus() { ProgressRenderer::eProgressStringType ProgressRenderer::getType() { eProgressStringType returnValue; { - std::lock_guard lock(ProgressRenderer::s_progress); + std::lock_guard lock( + ProgressRenderer::s_progress); returnValue = m_eType; } return returnValue; diff --git a/Minecraft.Client/Rendering/GameRenderer.cpp b/Minecraft.Client/Rendering/GameRenderer.cpp index b74a05259..b3f1b9458 100644 --- a/Minecraft.Client/Rendering/GameRenderer.cpp +++ b/Minecraft.Client/Rendering/GameRenderer.cpp @@ -1062,9 +1062,7 @@ void GameRenderer::AddForDelete(SparseDataStorage* deleteThis) { m_deleteStackSparseDataStorage.push_back(deleteThis); } -void GameRenderer::FinishedReassigning() { - m_csDeleteStack.unlock(); -} +void GameRenderer::FinishedReassigning() { m_csDeleteStack.unlock(); } int GameRenderer::runUpdate(void* lpParam) { Minecraft* minecraft = Minecraft::GetInstance(); @@ -1135,8 +1133,8 @@ int GameRenderer::runUpdate(void* lpParam) { i < m_deleteStackCompressedTileStorage.size(); i++) delete m_deleteStackCompressedTileStorage[i]; m_deleteStackCompressedTileStorage.clear(); - for (unsigned int i = 0; - i < m_deleteStackSparseDataStorage.size(); i++) + for (unsigned int i = 0; i < m_deleteStackSparseDataStorage.size(); + i++) delete m_deleteStackSparseDataStorage[i]; m_deleteStackSparseDataStorage.clear(); } @@ -1175,7 +1173,8 @@ void GameRenderer::DisableUpdateThread() { "------------------DisableUpdateThread--------------------\n"); updateRunning = false; m_updateEvents->clear(eUpdateCanRun); - m_updateEvents->waitForSingle(eUpdateEventIsFinished, C4JThread::kInfiniteTimeout); + m_updateEvents->waitForSingle(eUpdateEventIsFinished, + C4JThread::kInfiniteTimeout); #endif } diff --git a/Minecraft.Client/Rendering/LevelRenderer.cpp b/Minecraft.Client/Rendering/LevelRenderer.cpp index 434f1134e..57ac3f6f6 100644 --- a/Minecraft.Client/Rendering/LevelRenderer.cpp +++ b/Minecraft.Client/Rendering/LevelRenderer.cpp @@ -513,7 +513,6 @@ void LevelRenderer::allChanged(int playerIndex) { noEntityRenderFrames = 2; Minecraft::GetInstance()->gameRenderer->EnableUpdateThread(); - } void LevelRenderer::renderEntities(Vec3* cam, Culler* culler, float a) { @@ -620,7 +619,8 @@ void LevelRenderer::renderEntities(Vec3* cam, Culler* culler, float a) { it != renderableTileEntities.end(); it++) { int idx = it->first; // Don't render if it isn't in the same dimension as this player - if (!isGlobalIndexInSameDimension(idx, level[playerIndex])) continue; + if (!isGlobalIndexInSameDimension(idx, level[playerIndex])) + continue; for (auto it2 = it->second.tiles.begin(); it2 != it->second.tiles.end(); it2++) { @@ -3973,7 +3973,6 @@ void LevelRenderer::DestroyedTileManager::addAABBs(Level* level, AABB* box, } } } - } void LevelRenderer::DestroyedTileManager::tick() { diff --git a/Minecraft.World/IO/Files/ConsoleSaveFileOriginal.cpp b/Minecraft.World/IO/Files/ConsoleSaveFileOriginal.cpp index 30185c309..38d550b8e 100644 --- a/Minecraft.World/IO/Files/ConsoleSaveFileOriginal.cpp +++ b/Minecraft.World/IO/Files/ConsoleSaveFileOriginal.cpp @@ -774,13 +774,9 @@ int ConsoleSaveFileOriginal::getOriginalSaveVersion() { return header.getOriginalSaveVersion(); } -void ConsoleSaveFileOriginal::LockSaveAccess() { - m_lock.lock(); -} +void ConsoleSaveFileOriginal::LockSaveAccess() { m_lock.lock(); } -void ConsoleSaveFileOriginal::ReleaseSaveAccess() { - m_lock.unlock(); -} +void ConsoleSaveFileOriginal::ReleaseSaveAccess() { m_lock.unlock(); } ESavePlatform ConsoleSaveFileOriginal::getSavePlatform() { return header.getSavePlatform(); diff --git a/Minecraft.World/IO/Files/ConsoleSaveFileSplit.cpp b/Minecraft.World/IO/Files/ConsoleSaveFileSplit.cpp index 0b7e17f2f..28c00eacd 100644 --- a/Minecraft.World/IO/Files/ConsoleSaveFileSplit.cpp +++ b/Minecraft.World/IO/Files/ConsoleSaveFileSplit.cpp @@ -396,7 +396,6 @@ ConsoleSaveFileSplit::ConsoleSaveFileSplit(ConsoleSaveFile* sourceSave, void ConsoleSaveFileSplit::_init(const std::wstring& fileName, void* pvSaveData, unsigned int fileSize, ESavePlatform plat) { - m_lastTickTime = 0; // One time initialise of static stuff required for our storage @@ -1504,9 +1503,7 @@ int ConsoleSaveFileSplit::getOriginalSaveVersion() { void ConsoleSaveFileSplit::LockSaveAccess() { m_lock.lock(); } -void ConsoleSaveFileSplit::ReleaseSaveAccess() { - m_lock.unlock(); -} +void ConsoleSaveFileSplit::ReleaseSaveAccess() { m_lock.unlock(); } ESavePlatform ConsoleSaveFileSplit::getSavePlatform() { return header.getSavePlatform(); diff --git a/Minecraft.World/IO/Streams/Compression.cpp b/Minecraft.World/IO/Streams/Compression.cpp index 0f3d31e3f..91c840fa3 100644 --- a/Minecraft.World/IO/Streams/Compression.cpp +++ b/Minecraft.World/IO/Streams/Compression.cpp @@ -92,44 +92,46 @@ int32_t Compression::CompressLZXRLE(void* pDestination, unsigned int* pDestSize, int32_t Compression::CompressRLE(void* pDestination, unsigned int* pDestSize, void* pSource, unsigned int SrcSize) { unsigned int rleSize; - { std::lock_guard lock(rleCompressLock); - // static unsigned char rleBuf[1024*100]; + { + std::lock_guard lock(rleCompressLock); + // static unsigned char rleBuf[1024*100]; - unsigned char* pucIn = (unsigned char*)pSource; - unsigned char* pucEnd = pucIn + SrcSize; - unsigned char* pucOut = (unsigned char*)rleCompressBuf; + unsigned char* pucIn = (unsigned char*)pSource; + unsigned char* pucEnd = pucIn + SrcSize; + unsigned char* pucOut = (unsigned char*)rleCompressBuf; - // Compress with RLE first: - // 0 - 254 - encodes a single byte - // 255 followed by 0, 1, 2 - encodes a 1, 2, or 3 255s - // 255 followed by 3-255, followed by a byte - encodes a run of n + 1 bytes - PIXBeginNamedEvent(0, "RLE compression"); - do { - unsigned char thisOne = *pucIn++; + // Compress with RLE first: + // 0 - 254 - encodes a single byte + // 255 followed by 0, 1, 2 - encodes a 1, 2, or 3 255s + // 255 followed by 3-255, followed by a byte - encodes a run of n + 1 + // bytes + PIXBeginNamedEvent(0, "RLE compression"); + do { + unsigned char thisOne = *pucIn++; - unsigned int count = 1; - while ((pucIn != pucEnd) && (*pucIn == thisOne) && (count < 256)) { - pucIn++; - count++; - } + unsigned int count = 1; + while ((pucIn != pucEnd) && (*pucIn == thisOne) && (count < 256)) { + pucIn++; + count++; + } - if (count <= 3) { - if (thisOne == 255) { + if (count <= 3) { + if (thisOne == 255) { + *pucOut++ = 255; + *pucOut++ = count - 1; + } else { + for (unsigned int i = 0; i < count; i++) { + *pucOut++ = thisOne; + } + } + } else { *pucOut++ = 255; *pucOut++ = count - 1; - } else { - for (unsigned int i = 0; i < count; i++) { - *pucOut++ = thisOne; - } + *pucOut++ = thisOne; } - } else { - *pucOut++ = 255; - *pucOut++ = count - 1; - *pucOut++ = thisOne; - } - } while (pucIn != pucEnd); - rleSize = (unsigned int)(pucOut - rleCompressBuf); - PIXEndNamedEvent(); + } while (pucIn != pucEnd); + rleSize = (unsigned int)(pucOut - rleCompressBuf); + PIXEndNamedEvent(); } // Return diff --git a/Minecraft.World/Level/Level.cpp b/Minecraft.World/Level/Level.cpp index b4c8d017f..98bf3d669 100644 --- a/Minecraft.World/Level/Level.cpp +++ b/Minecraft.World/Level/Level.cpp @@ -1615,10 +1615,11 @@ bool Level::addEntity(std::shared_ptr e) { MemSect(42); getChunk(xc, zc)->addEntity(e); MemSect(0); - { std::lock_guard lock(m_entitiesCS); - MemSect(43); - entities.push_back(e); - MemSect(0); + { + std::lock_guard lock(m_entitiesCS); + MemSect(43); + entities.push_back(e); + MemSect(0); } MemSect(44); entityAdded(e); @@ -1700,14 +1701,15 @@ void Level::removeEntityImmediately(std::shared_ptr e) { getChunk(xc, zc)->removeEntity(e); } - { std::lock_guard lock(m_entitiesCS); - std::vector >::iterator it = entities.begin(); - std::vector >::iterator endIt = entities.end(); - while (it != endIt && *it != e) it++; + { + std::lock_guard lock(m_entitiesCS); + std::vector >::iterator it = entities.begin(); + std::vector >::iterator endIt = entities.end(); + while (it != endIt && *it != e) it++; - if (it != endIt) { - entities.erase(it); - } + if (it != endIt) { + entities.erase(it); + } } entityRemoved(e); } @@ -2076,23 +2078,24 @@ void Level::tickEntities() { } } - { std::lock_guard lock(m_entitiesCS); + { + std::lock_guard lock(m_entitiesCS); - for (auto it = entities.begin(); it != entities.end();) { - bool found = false; - for (auto it2 = entitiesToRemove.begin(); it2 != entitiesToRemove.end(); - it2++) { - if ((*it) == (*it2)) { - found = true; - break; + for (auto it = entities.begin(); it != entities.end();) { + bool found = false; + for (auto it2 = entitiesToRemove.begin(); + it2 != entitiesToRemove.end(); it2++) { + if ((*it) == (*it2)) { + found = true; + break; + } + } + if (found) { + it = entities.erase(it); + } else { + it++; } } - if (found) { - it = entities.erase(it); - } else { - it++; - } - } } auto itETREnd = entitiesToRemove.end(); @@ -2117,138 +2120,144 @@ void Level::tickEntities() { /* 4J Jev, using an iterator causes problems here as * the vector is modified from inside this loop. */ - { std::lock_guard lock(m_entitiesCS); + { + std::lock_guard lock(m_entitiesCS); - for (unsigned int i = 0; i < entities.size();) { - std::shared_ptr e = entities.at(i); + for (unsigned int i = 0; i < entities.size();) { + std::shared_ptr e = entities.at(i); - if (e->riding != nullptr) { - if (e->riding->removed || e->riding->rider.lock() != e) { - e->riding->rider = std::weak_ptr(); - e->riding = nullptr; - } else { - i++; - continue; + if (e->riding != nullptr) { + if (e->riding->removed || e->riding->rider.lock() != e) { + e->riding->rider = std::weak_ptr(); + e->riding = nullptr; + } else { + i++; + continue; + } } - } - if (!e->removed) { + if (!e->removed) { #if !defined(_FINAL_BUILD) - if (!(app.DebugSettingsOn() && app.GetMobsDontTickEnabled() && - e->instanceof(eTYPE_MOB) && !e->instanceof(eTYPE_PLAYER))) -#endif - { - tick(e); - } - } - - if (e->removed) { - int xc = e->xChunk; - int zc = e->zChunk; - if (e->inChunk && hasChunk(xc, zc)) { - getChunk(xc, zc)->removeEntity(e); - } - // entities.remove(i--); - // itE = entities.erase( itE ); - - // 4J Find the entity again before deleting, as things might have - // moved in the entity array eg from the explosion created by tnt - auto it = find(entities.begin(), entities.end(), e); - if (it != entities.end()) { - entities.erase(it); - } - - entityRemoved(e); - } else { - i++; - } - } - } - - { std::lock_guard lock(m_tileEntityListCS); - - updatingTileEntities = true; - for (auto it = tileEntityList.begin(); it != tileEntityList.end();) { - std::shared_ptr te = - *it; // tilevector >.at(i); - if (!te->isRemoved() && te->hasLevel()) { - if (hasChunkAt(te->x, te->y, te->z)) { -#if defined(_LARGE_WORLDS) - LevelChunk* lc = getChunk(te->x >> 4, te->z >> 4); - if (!isClientSide || !lc->isUnloaded()) + if (!(app.DebugSettingsOn() && app.GetMobsDontTickEnabled() && + e->instanceof(eTYPE_MOB) && !e->instanceof(eTYPE_PLAYER))) #endif { - te->tick(); + tick(e); } } - } - if (te->isRemoved()) { - it = tileEntityList.erase(it); - if (hasChunk(te->x >> 4, te->z >> 4)) { - LevelChunk* lc = getChunk(te->x >> 4, te->z >> 4); - if (lc != nullptr) - lc->removeTileEntity(te->x & 15, te->y, te->z & 15); + if (e->removed) { + int xc = e->xChunk; + int zc = e->zChunk; + if (e->inChunk && hasChunk(xc, zc)) { + getChunk(xc, zc)->removeEntity(e); + } + // entities.remove(i--); + // itE = entities.erase( itE ); + + // 4J Find the entity again before deleting, as things might + // have moved in the entity array eg from the explosion created + // by tnt + auto it = find(entities.begin(), entities.end(), e); + if (it != entities.end()) { + entities.erase(it); + } + + entityRemoved(e); + } else { + i++; } - } else { - it++; } } - updatingTileEntities = false; - // 4J-PB - Stuart - check this is correct here - - if (!tileEntitiesToUnload.empty()) { - FRAME_PROFILE_SCOPE(TileEntityUnloadCleanup); + { + std::lock_guard lock(m_tileEntityListCS); + updatingTileEntities = true; for (auto it = tileEntityList.begin(); it != tileEntityList.end();) { - if (tileEntitiesToUnload.find(*it) != tileEntitiesToUnload.end()) { - if (isClientSide) { - __debugbreak(); + std::shared_ptr te = + *it; // tilevector >.at(i); + if (!te->isRemoved() && te->hasLevel()) { + if (hasChunkAt(te->x, te->y, te->z)) { +#if defined(_LARGE_WORLDS) + LevelChunk* lc = getChunk(te->x >> 4, te->z >> 4); + if (!isClientSide || !lc->isUnloaded()) +#endif + { + te->tick(); + } } + } + + if (te->isRemoved()) { it = tileEntityList.erase(it); + if (hasChunk(te->x >> 4, te->z >> 4)) { + LevelChunk* lc = getChunk(te->x >> 4, te->z >> 4); + if (lc != nullptr) + lc->removeTileEntity(te->x & 15, te->y, te->z & 15); + } } else { it++; } } - tileEntitiesToUnload.clear(); - } + updatingTileEntities = false; - if (!pendingTileEntities.empty()) { - for (auto it = pendingTileEntities.begin(); - it != pendingTileEntities.end(); it++) { - std::shared_ptr e = *it; - if (!e->isRemoved()) { - if (find(tileEntityList.begin(), tileEntityList.end(), e) == - tileEntityList.end()) { - tileEntityList.push_back(e); - } - if (hasChunk(e->x >> 4, e->z >> 4)) { - LevelChunk* lc = getChunk(e->x >> 4, e->z >> 4); - if (lc != nullptr) - lc->setTileEntity(e->x & 15, e->y, e->z & 15, e); - } + // 4J-PB - Stuart - check this is correct here - sendTileUpdated(e->x, e->y, e->z); + if (!tileEntitiesToUnload.empty()) { + FRAME_PROFILE_SCOPE(TileEntityUnloadCleanup); + + for (auto it = tileEntityList.begin(); + it != tileEntityList.end();) { + if (tileEntitiesToUnload.find(*it) != + tileEntitiesToUnload.end()) { + if (isClientSide) { + __debugbreak(); + } + it = tileEntityList.erase(it); + } else { + it++; + } } + tileEntitiesToUnload.clear(); + } + + if (!pendingTileEntities.empty()) { + for (auto it = pendingTileEntities.begin(); + it != pendingTileEntities.end(); it++) { + std::shared_ptr e = *it; + if (!e->isRemoved()) { + if (find(tileEntityList.begin(), tileEntityList.end(), e) == + tileEntityList.end()) { + tileEntityList.push_back(e); + } + if (hasChunk(e->x >> 4, e->z >> 4)) { + LevelChunk* lc = getChunk(e->x >> 4, e->z >> 4); + if (lc != nullptr) + lc->setTileEntity(e->x & 15, e->y, e->z & 15, e); + } + + sendTileUpdated(e->x, e->y, e->z); + } + } + pendingTileEntities.clear(); } - pendingTileEntities.clear(); - } } } void Level::addAllPendingTileEntities( std::vector >& entities) { - { std::lock_guard lock(m_tileEntityListCS); - if (updatingTileEntities) { - for (auto it = entities.begin(); it != entities.end(); it++) { - pendingTileEntities.push_back(*it); + { + std::lock_guard lock(m_tileEntityListCS); + if (updatingTileEntities) { + for (auto it = entities.begin(); it != entities.end(); it++) { + pendingTileEntities.push_back(*it); + } + } else { + for (auto it = entities.begin(); it != entities.end(); it++) { + tileEntityList.push_back(*it); + } } - } else { - for (auto it = entities.begin(); it != entities.end(); it++) { - tileEntityList.push_back(*it); - } - } } } @@ -2587,8 +2596,9 @@ return shared_ptr(); std::wstring Level::gatherStats() { wchar_t buf[64]; - { std::lock_guard lock(m_entitiesCS); - swprintf(buf, 64, L"All:%d", entities.size()); + { + std::lock_guard lock(m_entitiesCS); + swprintf(buf, 64, L"All:%d", entities.size()); } return std::wstring(buf); } @@ -2604,15 +2614,16 @@ std::shared_ptr Level::getTileEntity(int x, int y, int z) { std::shared_ptr tileEntity = nullptr; if (updatingTileEntities) { - { std::lock_guard lock(m_tileEntityListCS); - for (int i = 0; i < pendingTileEntities.size(); i++) { - std::shared_ptr e = pendingTileEntities.at(i); - if (!e->isRemoved() && e->x == x && e->y == y && e->z == z) { - tileEntity = e; - break; + { + std::lock_guard lock(m_tileEntityListCS); + for (int i = 0; i < pendingTileEntities.size(); i++) { + std::shared_ptr e = pendingTileEntities.at(i); + if (!e->isRemoved() && e->x == x && e->y == y && e->z == z) { + tileEntity = e; + break; + } } } - } } if (tileEntity == nullptr) { @@ -2623,17 +2634,18 @@ std::shared_ptr Level::getTileEntity(int x, int y, int z) { } if (tileEntity == nullptr) { - { std::lock_guard lock(m_tileEntityListCS); - for (auto it = pendingTileEntities.begin(); - it != pendingTileEntities.end(); it++) { - std::shared_ptr e = *it; + { + std::lock_guard lock(m_tileEntityListCS); + for (auto it = pendingTileEntities.begin(); + it != pendingTileEntities.end(); it++) { + std::shared_ptr e = *it; - if (!e->isRemoved() && e->x == x && e->y == y && e->z == z) { - tileEntity = e; - break; + if (!e->isRemoved() && e->x == x && e->y == y && e->z == z) { + tileEntity = e; + break; + } } } - } } return tileEntity; } @@ -2641,66 +2653,71 @@ std::shared_ptr Level::getTileEntity(int x, int y, int z) { void Level::setTileEntity(int x, int y, int z, std::shared_ptr tileEntity) { if (tileEntity != nullptr && !tileEntity->isRemoved()) { - { std::lock_guard lock(m_tileEntityListCS); - if (updatingTileEntities) { - tileEntity->x = x; - tileEntity->y = y; - tileEntity->z = z; + { + std::lock_guard lock(m_tileEntityListCS); + if (updatingTileEntities) { + tileEntity->x = x; + tileEntity->y = y; + tileEntity->z = z; - // avoid adding duplicates - for (auto it = pendingTileEntities.begin(); - it != pendingTileEntities.end();) { - std::shared_ptr next = *it; - if (next->x == x && next->y == y && next->z == z) { - next->setRemoved(); - it = pendingTileEntities.erase(it); - } else { - ++it; + // avoid adding duplicates + for (auto it = pendingTileEntities.begin(); + it != pendingTileEntities.end();) { + std::shared_ptr next = *it; + if (next->x == x && next->y == y && next->z == z) { + next->setRemoved(); + it = pendingTileEntities.erase(it); + } else { + ++it; + } } + + pendingTileEntities.push_back(tileEntity); + } else { + tileEntityList.push_back(tileEntity); + + LevelChunk* lc = getChunk(x >> 4, z >> 4); + if (lc != nullptr) + lc->setTileEntity(x & 15, y, z & 15, tileEntity); } - - pendingTileEntities.push_back(tileEntity); - } else { - tileEntityList.push_back(tileEntity); - - LevelChunk* lc = getChunk(x >> 4, z >> 4); - if (lc != nullptr) lc->setTileEntity(x & 15, y, z & 15, tileEntity); - } } } } void Level::removeTileEntity(int x, int y, int z) { - { std::lock_guard lock(m_tileEntityListCS); - std::shared_ptr te = getTileEntity(x, y, z); - if (te != nullptr && updatingTileEntities) { - te->setRemoved(); - auto it = - find(pendingTileEntities.begin(), pendingTileEntities.end(), te); - if (it != pendingTileEntities.end()) { - pendingTileEntities.erase(it); - } - } else { - if (te != nullptr) { + { + std::lock_guard lock(m_tileEntityListCS); + std::shared_ptr te = getTileEntity(x, y, z); + if (te != nullptr && updatingTileEntities) { + te->setRemoved(); auto it = find(pendingTileEntities.begin(), pendingTileEntities.end(), te); if (it != pendingTileEntities.end()) { pendingTileEntities.erase(it); } - auto it2 = find(tileEntityList.begin(), tileEntityList.end(), te); - if (it2 != tileEntityList.end()) { - tileEntityList.erase(it2); + } else { + if (te != nullptr) { + auto it = find(pendingTileEntities.begin(), + pendingTileEntities.end(), te); + if (it != pendingTileEntities.end()) { + pendingTileEntities.erase(it); + } + auto it2 = + find(tileEntityList.begin(), tileEntityList.end(), te); + if (it2 != tileEntityList.end()) { + tileEntityList.erase(it2); + } } + LevelChunk* lc = getChunk(x >> 4, z >> 4); + if (lc != nullptr) lc->removeTileEntity(x & 15, y, z & 15); } - LevelChunk* lc = getChunk(x >> 4, z >> 4); - if (lc != nullptr) lc->removeTileEntity(x & 15, y, z & 15); - } } } void Level::markForRemoval(std::shared_ptr entity) { - { std::lock_guard lock(m_tileEntityListCS); - tileEntitiesToUnload.insert(entity); + { + std::lock_guard lock(m_tileEntityListCS); + tileEntitiesToUnload.insert(entity); } } @@ -3097,234 +3114,248 @@ void Level::checkLight(LightLayer::variety layer, int xc, int yc, int zc, if (!hasChunksAt(xc, yc, zc, 17)) return; } - { std::lock_guard lock(m_checkLightCS); - - initCachePartial(cache, xc, yc, zc); - - // If we're in cached mode, then use memory allocated after the cached data - // itself for the toCheck array, in an attempt to make both that & the other - // cached data sit on the CPU L2 cache better. - - int* toCheck; - if (cache == nullptr) { - toCheck = toCheckLevel; - } else { - toCheck = (int*)(cache + (16 * 16 * 16)); - } - - int checkedPosition = 0; - int toCheckCount = 0; - // int darktcc = 0; - - // 4J - added - int minXZ = -(dimension->getXZSize() * 16) / 2; - int maxXZ = (dimension->getXZSize() * 16) / 2 - 1; - if ((xc > maxXZ) || (xc < minXZ) || (zc > maxXZ) || (zc < minXZ)) { - return; - } - - // Lock 128K of cache (containing all the lighting cache + first 112K of - // toCheck array) on L2 to try and stop any cached data getting knocked out - // of L2 by other non-cached reads (or vice-versa) - // if( cache ) XLockL2(XLOCKL2_INDEX_TITLE, cache, 128 * 1024, - // XLOCKL2_LOCK_SIZE_1_WAY, 0 ); - { - int centerCurrent = getBrightnessCached(cache, layer, xc, yc, zc); - int centerExpected = getExpectedLight(cache, xc, yc, zc, layer, false); + std::lock_guard lock(m_checkLightCS); - if (centerExpected != centerCurrent && cache) { - initCacheComplete(cache, xc, yc, zc); + initCachePartial(cache, xc, yc, zc); + + // If we're in cached mode, then use memory allocated after the cached + // data itself for the toCheck array, in an attempt to make both that & + // the other cached data sit on the CPU L2 cache better. + + int* toCheck; + if (cache == nullptr) { + toCheck = toCheckLevel; + } else { + toCheck = (int*)(cache + (16 * 16 * 16)); } - if (centerExpected > centerCurrent) { - toCheck[toCheckCount++] = 32 | (32 << 6) | (32 << 12); - } else if (centerExpected < centerCurrent) { - // 4J - added tcn. This is the code that is run when checkLight has - // been called for a light source that has got darker / turned off. - // In the original version, after zeroing tiles brightnesses that - // are deemed to come from this light source, all the zeroed tiles - // are then passed to the next stage of the function to potentially - // have their brightnesses put back up again. We shouldn't need to - // consider All these tiles as starting points for this process, now - // just considering the edge tiles (defined as a tile where we have - // a neighbour that is brightner than can be explained by the - // original light source we are turning off) - int tcn = 0; - if (layer == LightLayer::Block || true) { - toCheck[toCheckCount++] = - 32 | (32 << 6) | (32 << 12) | (centerCurrent << 18); - while (checkedPosition < toCheckCount) { - int p = toCheck[checkedPosition++]; - int x = ((p) & 63) - 32 + xc; - int y = ((p >> 6) & 63) - 32 + yc; - int z = ((p >> 12) & 63) - 32 + zc; - int expected = ((p >> 18) & 15); - int current = getBrightnessCached(cache, layer, x, y, z); - if (current == expected) { - setBrightnessCached(cache, &cacheUse, layer, x, y, z, - 0); - // cexp--; // 4J - removed, change - // from 1.2.3 - if (expected > 0) { - int xd = Mth::abs(x - xc); - int yd = Mth::abs(y - yc); - int zd = Mth::abs(z - zc); - if (xd + yd + zd < 17) { - bool edge = false; - for (int face = 0; face < 6; face++) { - int xx = x + Facing::STEP_X[face]; - int yy = y + Facing::STEP_Y[face]; - int zz = z + Facing::STEP_Z[face]; + int checkedPosition = 0; + int toCheckCount = 0; + // int darktcc = 0; - // 4J - added - don't let this lighting - // creep out of the normal fixed world and - // into the infinite water chunks beyond - if ((xx > maxXZ) || (xx < minXZ) || - (zz > maxXZ) || (zz < minXZ)) - continue; - if ((yy < 0) || (yy >= maxBuildHeight)) - continue; + // 4J - added + int minXZ = -(dimension->getXZSize() * 16) / 2; + int maxXZ = (dimension->getXZSize() * 16) / 2 - 1; + if ((xc > maxXZ) || (xc < minXZ) || (zc > maxXZ) || (zc < minXZ)) { + return; + } - // 4J - some changes here brought forward - // from 1.2.3 - int block = std::max( - 1, - getBlockingCached(cache, layer, nullptr, - xx, yy, zz)); - current = getBrightnessCached(cache, layer, - xx, yy, zz); - if ((current == expected - block) && - (toCheckCount < - (32 * 32 * 32))) // 4J - 32 * 32 * 32 - // was toCheck.length - { - toCheck[toCheckCount++] = - (xx - xc + 32) | - ((yy - yc + 32) << 6) | - ((zz - zc + 32) << 12) | - ((expected - block) << 18); - } else { - // 4J - added - keep track of which - // tiles form the edge of the region we - // are zeroing - if (current > (expected - block)) { - edge = true; + // Lock 128K of cache (containing all the lighting cache + first 112K of + // toCheck array) on L2 to try and stop any cached data getting knocked + // out of L2 by other non-cached reads (or vice-versa) + // if( cache ) XLockL2(XLOCKL2_INDEX_TITLE, cache, 128 * 1024, + // XLOCKL2_LOCK_SIZE_1_WAY, 0 ); + + { + int centerCurrent = getBrightnessCached(cache, layer, xc, yc, zc); + int centerExpected = + getExpectedLight(cache, xc, yc, zc, layer, false); + + if (centerExpected != centerCurrent && cache) { + initCacheComplete(cache, xc, yc, zc); + } + + if (centerExpected > centerCurrent) { + toCheck[toCheckCount++] = 32 | (32 << 6) | (32 << 12); + } else if (centerExpected < centerCurrent) { + // 4J - added tcn. This is the code that is run when checkLight + // has been called for a light source that has got darker / + // turned off. In the original version, after zeroing tiles + // brightnesses that are deemed to come from this light source, + // all the zeroed tiles are then passed to the next stage of the + // function to potentially have their brightnesses put back up + // again. We shouldn't need to consider All these tiles as + // starting points for this process, now just considering the + // edge tiles (defined as a tile where we have a neighbour that + // is brightner than can be explained by the original light + // source we are turning off) + int tcn = 0; + if (layer == LightLayer::Block || true) { + toCheck[toCheckCount++] = + 32 | (32 << 6) | (32 << 12) | (centerCurrent << 18); + while (checkedPosition < toCheckCount) { + int p = toCheck[checkedPosition++]; + int x = ((p) & 63) - 32 + xc; + int y = ((p >> 6) & 63) - 32 + yc; + int z = ((p >> 12) & 63) - 32 + zc; + int expected = ((p >> 18) & 15); + int current = + getBrightnessCached(cache, layer, x, y, z); + if (current == expected) { + setBrightnessCached(cache, &cacheUse, layer, x, y, + z, 0); + // cexp--; // 4J - removed, change + // from 1.2.3 + if (expected > 0) { + int xd = Mth::abs(x - xc); + int yd = Mth::abs(y - yc); + int zd = Mth::abs(z - zc); + if (xd + yd + zd < 17) { + bool edge = false; + for (int face = 0; face < 6; face++) { + int xx = x + Facing::STEP_X[face]; + int yy = y + Facing::STEP_Y[face]; + int zz = z + Facing::STEP_Z[face]; + + // 4J - added - don't let this lighting + // creep out of the normal fixed world + // and into the infinite water chunks + // beyond + if ((xx > maxXZ) || (xx < minXZ) || + (zz > maxXZ) || (zz < minXZ)) + continue; + if ((yy < 0) || (yy >= maxBuildHeight)) + continue; + + // 4J - some changes here brought + // forward from 1.2.3 + int block = std::max( + 1, getBlockingCached(cache, layer, + nullptr, xx, + yy, zz)); + current = getBrightnessCached( + cache, layer, xx, yy, zz); + if ((current == expected - block) && + (toCheckCount < + (32 * 32 * + 32))) // 4J - 32 * 32 * 32 + // was toCheck.length + { + toCheck[toCheckCount++] = + (xx - xc + 32) | + ((yy - yc + 32) << 6) | + ((zz - zc + 32) << 12) | + ((expected - block) << 18); + } else { + // 4J - added - keep track of which + // tiles form the edge of the region + // we are zeroing + if (current > (expected - block)) { + edge = true; + } } } - } - // 4J - added - keep track of which tiles form - // the edge of the region we are zeroing - can - // store over the original elements in the array - // because tcn must be <= tcp - if (edge == true) { - toCheck[tcn++] = p; + // 4J - added - keep track of which tiles + // form the edge of the region we are + // zeroing - can store over the original + // elements in the array because tcn must be + // <= tcp + if (edge == true) { + toCheck[tcn++] = p; + } } } } } } - } - checkedPosition = 0; - // darktcc = tcc; - ///////////////////////////////////////////////////// - toCheckCount = tcn; // 4J added - we've moved all the edge tiles to - // the start of the array, so only need to - // process these now. The original processes - // all tcc tiles again in the next section - } - } - - while (checkedPosition < toCheckCount) { - int p = toCheck[checkedPosition++]; - int x = ((p) & 63) - 32 + xc; - int y = ((p >> 6) & 63) - 32 + yc; - int z = ((p >> 12) & 63) - 32 + zc; - - // If force is set, then this is being used to in a special mode to try - // and light lava tiles as chunks are being loaded in. In this case, we - // don't want a lighting update to drag in any neighbouring chunks that - // aren't loaded yet. - if (force) { - if (!hasChunkAt(x, y, z)) { - continue; + checkedPosition = 0; + // darktcc = tcc; + ///////////////////////////////////////////////////// + toCheckCount = + tcn; // 4J added - we've moved all the edge tiles to + // the start of the array, so only need to + // process these now. The original processes + // all tcc tiles again in the next section } } - int current = getBrightnessCached(cache, layer, x, y, z); - // If rootOnlyEmissive flag is set, then only consider the starting tile - // to be possibly emissive. - bool propagatedOnly = false; - if (layer == LightLayer::Block) { - if (rootOnlyEmissive) { - propagatedOnly = (x != xc) || (y != yc) || (z != zc); + while (checkedPosition < toCheckCount) { + int p = toCheck[checkedPosition++]; + int x = ((p) & 63) - 32 + xc; + int y = ((p >> 6) & 63) - 32 + yc; + int z = ((p >> 12) & 63) - 32 + zc; + + // If force is set, then this is being used to in a special mode to + // try and light lava tiles as chunks are being loaded in. In this + // case, we don't want a lighting update to drag in any neighbouring + // chunks that aren't loaded yet. + if (force) { + if (!hasChunkAt(x, y, z)) { + continue; + } } - } - int expected = getExpectedLight(cache, x, y, z, layer, propagatedOnly); + int current = getBrightnessCached(cache, layer, x, y, z); - if (expected != current) { - setBrightnessCached(cache, &cacheUse, layer, x, y, z, expected); + // If rootOnlyEmissive flag is set, then only consider the starting + // tile to be possibly emissive. + bool propagatedOnly = false; + if (layer == LightLayer::Block) { + if (rootOnlyEmissive) { + propagatedOnly = (x != xc) || (y != yc) || (z != zc); + } + } + int expected = + getExpectedLight(cache, x, y, z, layer, propagatedOnly); - if (expected > current) { - int xd = abs(x - xc); - int yd = abs(y - yc); - int zd = abs(z - zc); - bool withinBounds = - toCheckCount < - (32 * 32 * 32) - 6; // 4J - 32 * 32 * 32 was toCheck.length - if (xd + yd + zd < 17 && withinBounds) { - // 4J - added extra checks here to stop lighting updates - // moving out of the actual fixed world and into the - // infinite water chunks - if ((x - 1) >= minXZ) { - if (getBrightnessCached(cache, layer, x - 1, y, z) < - expected) - toCheck[toCheckCount++] = (((x - 1 - xc) + 32)) + - (((y - yc) + 32) << 6) + - (((z - zc) + 32) << 12); - } - if ((x + 1) <= maxXZ) { - if (getBrightnessCached(cache, layer, x + 1, y, z) < - expected) - toCheck[toCheckCount++] = (((x + 1 - xc) + 32)) + - (((y - yc) + 32) << 6) + - (((z - zc) + 32) << 12); - } - if ((y - 1) >= 0) { - if (getBrightnessCached(cache, layer, x, y - 1, z) < - expected) - toCheck[toCheckCount++] = - (((x - xc) + 32)) + (((y - 1 - yc) + 32) << 6) + - (((z - zc) + 32) << 12); - } - if ((y + 1) < maxBuildHeight) { - if (getBrightnessCached(cache, layer, x, y + 1, z) < - expected) - toCheck[toCheckCount++] = - (((x - xc) + 32)) + (((y + 1 - yc) + 32) << 6) + - (((z - zc) + 32) << 12); - } - if ((z - 1) >= minXZ) { - if (getBrightnessCached(cache, layer, x, y, z - 1) < - expected) - toCheck[toCheckCount++] = - (((x - xc) + 32)) + (((y - yc) + 32) << 6) + - (((z - 1 - zc) + 32) << 12); - } - if ((z + 1) <= maxXZ) { - if (getBrightnessCached(cache, layer, x, y, z + 1) < - expected) - toCheck[toCheckCount++] = - (((x - xc) + 32)) + (((y - yc) + 32) << 6) + - (((z + 1 - zc) + 32) << 12); + if (expected != current) { + setBrightnessCached(cache, &cacheUse, layer, x, y, z, expected); + + if (expected > current) { + int xd = abs(x - xc); + int yd = abs(y - yc); + int zd = abs(z - zc); + bool withinBounds = + toCheckCount < + (32 * 32 * 32) - + 6; // 4J - 32 * 32 * 32 was toCheck.length + if (xd + yd + zd < 17 && withinBounds) { + // 4J - added extra checks here to stop lighting updates + // moving out of the actual fixed world and into the + // infinite water chunks + if ((x - 1) >= minXZ) { + if (getBrightnessCached(cache, layer, x - 1, y, z) < + expected) + toCheck[toCheckCount++] = + (((x - 1 - xc) + 32)) + + (((y - yc) + 32) << 6) + + (((z - zc) + 32) << 12); + } + if ((x + 1) <= maxXZ) { + if (getBrightnessCached(cache, layer, x + 1, y, z) < + expected) + toCheck[toCheckCount++] = + (((x + 1 - xc) + 32)) + + (((y - yc) + 32) << 6) + + (((z - zc) + 32) << 12); + } + if ((y - 1) >= 0) { + if (getBrightnessCached(cache, layer, x, y - 1, z) < + expected) + toCheck[toCheckCount++] = + (((x - xc) + 32)) + + (((y - 1 - yc) + 32) << 6) + + (((z - zc) + 32) << 12); + } + if ((y + 1) < maxBuildHeight) { + if (getBrightnessCached(cache, layer, x, y + 1, z) < + expected) + toCheck[toCheckCount++] = + (((x - xc) + 32)) + + (((y + 1 - yc) + 32) << 6) + + (((z - zc) + 32) << 12); + } + if ((z - 1) >= minXZ) { + if (getBrightnessCached(cache, layer, x, y, z - 1) < + expected) + toCheck[toCheckCount++] = + (((x - xc) + 32)) + (((y - yc) + 32) << 6) + + (((z - 1 - zc) + 32) << 12); + } + if ((z + 1) <= maxXZ) { + if (getBrightnessCached(cache, layer, x, y, z + 1) < + expected) + toCheck[toCheckCount++] = + (((x - xc) + 32)) + (((y - yc) + 32) << 6) + + (((z + 1 - zc) + 32) << 12); + } } } } } - } - // if( cache ) XUnlockL2(XLOCKL2_INDEX_TITLE); + // if( cache ) XUnlockL2(XLOCKL2_INDEX_TITLE); - flushCache(cache, cacheUse, layer); + flushCache(cache, cacheUse, layer); } } @@ -3429,27 +3460,28 @@ unsigned int Level::countInstanceOf( unsigned int count = 0; if (protectedCount) *protectedCount = 0; if (couldWanderCount) *couldWanderCount = 0; - { std::lock_guard lock(m_entitiesCS); - auto itEnd = entities.end(); - for (auto it = entities.begin(); it != itEnd; it++) { - std::shared_ptr e = *it; // entities.at(i); - if (singleType) { - if (e->GetType() == clas) { - if (protectedCount && e->isDespawnProtected()) { - (*protectedCount)++; - } + { + std::lock_guard lock(m_entitiesCS); + auto itEnd = entities.end(); + for (auto it = entities.begin(); it != itEnd; it++) { + std::shared_ptr e = *it; // entities.at(i); + if (singleType) { + if (e->GetType() == clas) { + if (protectedCount && e->isDespawnProtected()) { + (*protectedCount)++; + } - if (couldWanderCount && e->couldWander()) { - (*couldWanderCount)++; - } + if (couldWanderCount && e->couldWander()) { + (*couldWanderCount)++; + } - count++; + count++; + } + } else { + if (e->instanceof(clas)) count++; } - } else { - if (e->instanceof(clas)) count++; } } - } return count; } @@ -3457,60 +3489,62 @@ unsigned int Level::countInstanceOf( unsigned int Level::countInstanceOfInRange(eINSTANCEOF clas, bool singleType, int range, int x, int y, int z) { unsigned int count = 0; - { std::lock_guard lock(m_entitiesCS); - auto itEnd = entities.end(); - for (auto it = entities.begin(); it != itEnd; it++) { - std::shared_ptr e = *it; // entities.at(i); + { + std::lock_guard lock(m_entitiesCS); + auto itEnd = entities.end(); + for (auto it = entities.begin(); it != itEnd; it++) { + std::shared_ptr e = *it; // entities.at(i); - float sd = e->distanceTo(x, y, z); - if (sd * sd > range * range) { - continue; - } - - if (singleType) { - if (e->GetType() == clas) { - count++; + float sd = e->distanceTo(x, y, z); + if (sd * sd > range * range) { + continue; + } + + if (singleType) { + if (e->GetType() == clas) { + count++; + } + } else { + if (e->instanceof(clas)) count++; } - } else { - if (e->instanceof(clas)) count++; } } - } return count; } void Level::addEntities(std::vector >* list) { // entities.addAll(list); - { std::lock_guard lock(m_entitiesCS); - entities.insert(entities.end(), list->begin(), list->end()); - auto itEnd = list->end(); - bool deleteDragons = false; - for (auto it = list->begin(); it != itEnd; it++) { - entityAdded(*it); + { + std::lock_guard lock(m_entitiesCS); + entities.insert(entities.end(), list->begin(), list->end()); + auto itEnd = list->end(); + bool deleteDragons = false; + for (auto it = list->begin(); it != itEnd; it++) { + entityAdded(*it); - // 4J Stu - Special change to remove duplicate enderdragons that a - // previous bug might have produced - if ((*it)->GetType() == eTYPE_ENDERDRAGON) { - deleteDragons = true; - } - } - - if (deleteDragons) { - deleteDragons = false; - for (auto it = entities.begin(); it != entities.end(); ++it) { // 4J Stu - Special change to remove duplicate enderdragons that a // previous bug might have produced if ((*it)->GetType() == eTYPE_ENDERDRAGON) { - if (deleteDragons) { - (*it)->remove(); - } else { - deleteDragons = true; + deleteDragons = true; + } + } + + if (deleteDragons) { + deleteDragons = false; + for (auto it = entities.begin(); it != entities.end(); ++it) { + // 4J Stu - Special change to remove duplicate enderdragons that + // a previous bug might have produced + if ((*it)->GetType() == eTYPE_ENDERDRAGON) { + if (deleteDragons) { + (*it)->remove(); + } else { + deleteDragons = true; + } } } } } - } } void Level::removeEntities(std::vector >* list) { @@ -3925,10 +3959,11 @@ void Level::ensureAdded(std::shared_ptr entity) { } // if (!entities.contains(entity)) - { std::lock_guard lock(m_entitiesCS); - if (find(entities.begin(), entities.end(), entity) == entities.end()) { - entities.push_back(entity); - } + { + std::lock_guard lock(m_entitiesCS); + if (find(entities.begin(), entities.end(), entity) == entities.end()) { + entities.push_back(entity); + } } } diff --git a/Minecraft.World/Level/Level.h b/Minecraft.World/Level/Level.h index c0950a638..9503e1d2d 100644 --- a/Minecraft.World/Level/Level.h +++ b/Minecraft.World/Level/Level.h @@ -109,8 +109,8 @@ protected: std::vector > entitiesToRemove; public: - bool hasEntitiesToRemove(); // 4J added - bool m_bDisableAddNewTileEntities; // 4J Added + bool hasEntitiesToRemove(); // 4J added + bool m_bDisableAddNewTileEntities; // 4J Added std::recursive_mutex m_tileEntityListCS; // 4J added std::vector > tileEntityList; diff --git a/Minecraft.World/Level/LevelChunk.cpp b/Minecraft.World/Level/LevelChunk.cpp index 97fe9d7bb..69d4a9ebc 100644 --- a/Minecraft.World/Level/LevelChunk.cpp +++ b/Minecraft.World/Level/LevelChunk.cpp @@ -28,17 +28,17 @@ std::recursive_mutex LevelChunk::m_csEntities; std::recursive_mutex LevelChunk::m_csTileEntities; bool LevelChunk::touchedSky = false; -void LevelChunk::staticCtor() { -} +void LevelChunk::staticCtor() {} void LevelChunk::init(Level* level, int x, int z) { biomes = byteArray(16 * 16); for (int i = 0; i < 16 * 16; i++) { biomes[i] = 0xff; } - { std::lock_guard lock(m_csEntities); - entityBlocks = - new std::vector >*[ENTITY_BLOCKS_LENGTH]; + { + std::lock_guard lock(m_csEntities); + entityBlocks = + new std::vector >*[ENTITY_BLOCKS_LENGTH]; } terrainPopulated = 0; @@ -59,10 +59,11 @@ void LevelChunk::init(Level* level, int x, int z) { this->z = z; MemSect(1); heightmap = byteArray(16 * 16); - { std::lock_guard lock(m_csEntities); - for (int i = 0; i < ENTITY_BLOCKS_LENGTH; i++) { - entityBlocks[i] = new std::vector >(); - } + { + std::lock_guard lock(m_csEntities); + for (int i = 0; i < ENTITY_BLOCKS_LENGTH; i++) { + entityBlocks[i] = new std::vector >(); + } } MemSect(0); @@ -224,61 +225,63 @@ void LevelChunk::setUnsaved(bool unsaved) { void LevelChunk::stopSharingTilesAndData() { #if defined(SHARING_ENABLED) - { std::lock_guard lock(m_csSharing); - lastUnsharedTime = System::currentTimeMillis(); - if (!sharingTilesAndData) { - return; - } + { + std::lock_guard lock(m_csSharing); + lastUnsharedTime = System::currentTimeMillis(); + if (!sharingTilesAndData) { + return; + } - // If we've got a reference to a server chunk's terrainPopulated flag that - // this LevelChunk is sharing with, then don't consider unsharing if it - // hasn't been set. This is because post-processing things that update the - // server chunks won't actually cause the server to send any updates to the - // tiles that they alter, so they completely depend on the data not being - // shared for it to get from the server to here - if ((serverTerrainPopulated) && - (((*serverTerrainPopulated) & sTerrainPopulatedAllAffecting) != - sTerrainPopulatedAllAffecting)) { - return; - } + // If we've got a reference to a server chunk's terrainPopulated flag + // that this LevelChunk is sharing with, then don't consider unsharing + // if it hasn't been set. This is because post-processing things that + // update the server chunks won't actually cause the server to send any + // updates to the tiles that they alter, so they completely depend on + // the data not being shared for it to get from the server to here + if ((serverTerrainPopulated) && + (((*serverTerrainPopulated) & sTerrainPopulatedAllAffecting) != + sTerrainPopulatedAllAffecting)) { + return; + } - // If this is the empty chunk, then it will have a x & z of 0,0 - if we - // don't drop out here we'll end up unsharing the chunk at this location for - // no reason - if (isEmpty()) { - return; - } + // If this is the empty chunk, then it will have a x & z of 0,0 - if we + // don't drop out here we'll end up unsharing the chunk at this location + // for no reason + if (isEmpty()) { + return; + } - MemSect(47); + MemSect(47); - // Changed to used compressed storage - these CTORs make deep copies of the - // storage passed as a parameter - lowerBlocks = new CompressedTileStorage(lowerBlocks); + // Changed to used compressed storage - these CTORs make deep copies of + // the storage passed as a parameter + lowerBlocks = new CompressedTileStorage(lowerBlocks); - // Changed to use new sparse data storage - this CTOR makes a deep copy of - // the storage passed as a parameter - lowerData = new SparseDataStorage(lowerData); + // Changed to use new sparse data storage - this CTOR makes a deep copy + // of the storage passed as a parameter + lowerData = new SparseDataStorage(lowerData); - if (Level::maxBuildHeight > Level::COMPRESSED_CHUNK_SECTION_HEIGHT) { - upperBlocks = new CompressedTileStorage(upperBlocks); - upperData = new SparseDataStorage(upperData); - } else { - upperBlocks = nullptr; - upperData = nullptr; - } + if (Level::maxBuildHeight > Level::COMPRESSED_CHUNK_SECTION_HEIGHT) { + upperBlocks = new CompressedTileStorage(upperBlocks); + upperData = new SparseDataStorage(upperData); + } else { + upperBlocks = nullptr; + upperData = nullptr; + } - /* - newDataLayer = new DataLayer(skyLight->data.length*2, level->depthBits); - XMemCpy(newDataLayer->data.data, skyLight->data.data, - skyLight->data.length); skyLight = newDataLayer; + /* + newDataLayer = new DataLayer(skyLight->data.length*2, level->depthBits); + XMemCpy(newDataLayer->data.data, skyLight->data.data, + skyLight->data.length); skyLight = newDataLayer; - newDataLayer = new DataLayer(blockLight->data.length*2, level->depthBits); - XMemCpy(newDataLayer->data.data, blockLight->data.data, - blockLight->data.length); blockLight = newDataLayer; - */ + newDataLayer = new DataLayer(blockLight->data.length*2, + level->depthBits); XMemCpy(newDataLayer->data.data, + blockLight->data.data, blockLight->data.length); blockLight = + newDataLayer; + */ - sharingTilesAndData = false; - MemSect(0); + sharingTilesAndData = false; + MemSect(0); } #endif } @@ -290,108 +293,110 @@ void LevelChunk::stopSharingTilesAndData() { // not sharing void LevelChunk::reSyncLighting() { #if defined(SHARING_ENABLED) - { std::lock_guard lock(m_csSharing); + { + std::lock_guard lock(m_csSharing); - if (isEmpty()) { - return; - } + if (isEmpty()) { + return; + } #if defined(_LARGE_WORLDS) - LevelChunk* lc = MinecraftServer::getInstance() - ->getLevel(level->dimension->id) - ->cache->getChunkLoadedOrUnloaded(x, z); + LevelChunk* lc = MinecraftServer::getInstance() + ->getLevel(level->dimension->id) + ->cache->getChunkLoadedOrUnloaded(x, z); #else - LevelChunk* lc = MinecraftServer::getInstance() - ->getLevel(level->dimension->id) - ->cache->getChunk(x, z); + LevelChunk* lc = MinecraftServer::getInstance() + ->getLevel(level->dimension->id) + ->cache->getChunk(x, z); #endif - GameRenderer::AddForDelete(lowerSkyLight); - lowerSkyLight = new SparseLightStorage(lc->lowerSkyLight); - GameRenderer::FinishedReassigning(); - GameRenderer::AddForDelete(lowerBlockLight); - lowerBlockLight = new SparseLightStorage(lc->lowerBlockLight); - GameRenderer::FinishedReassigning(); + GameRenderer::AddForDelete(lowerSkyLight); + lowerSkyLight = new SparseLightStorage(lc->lowerSkyLight); + GameRenderer::FinishedReassigning(); + GameRenderer::AddForDelete(lowerBlockLight); + lowerBlockLight = new SparseLightStorage(lc->lowerBlockLight); + GameRenderer::FinishedReassigning(); - if (Level::maxBuildHeight > Level::COMPRESSED_CHUNK_SECTION_HEIGHT) { - GameRenderer::AddForDelete(upperSkyLight); - upperSkyLight = new SparseLightStorage(lc->upperSkyLight); - GameRenderer::FinishedReassigning(); - GameRenderer::AddForDelete(upperBlockLight); - upperBlockLight = new SparseLightStorage(lc->upperBlockLight); - GameRenderer::FinishedReassigning(); - } + if (Level::maxBuildHeight > Level::COMPRESSED_CHUNK_SECTION_HEIGHT) { + GameRenderer::AddForDelete(upperSkyLight); + upperSkyLight = new SparseLightStorage(lc->upperSkyLight); + GameRenderer::FinishedReassigning(); + GameRenderer::AddForDelete(upperBlockLight); + upperBlockLight = new SparseLightStorage(lc->upperBlockLight); + GameRenderer::FinishedReassigning(); + } } #endif } void LevelChunk::startSharingTilesAndData(int forceMs) { #if defined(SHARING_ENABLED) - { std::lock_guard lock(m_csSharing); - if (sharingTilesAndData) { - return; - } + { + std::lock_guard lock(m_csSharing); + if (sharingTilesAndData) { + return; + } - // If this is the empty chunk, then it will have a x & z of 0,0 - we'll end - // up potentially loading the 0,0 block if we proceed. And it obviously - // doesn't make sense to go resharing the 0,0 block on behalf of an empty - // chunk either - if (isEmpty()) { - return; - } + // If this is the empty chunk, then it will have a x & z of 0,0 - we'll + // end up potentially loading the 0,0 block if we proceed. And it + // obviously doesn't make sense to go resharing the 0,0 block on behalf + // of an empty chunk either + if (isEmpty()) { + return; + } #if defined(_LARGE_WORLDS) - LevelChunk* lc = MinecraftServer::getInstance() - ->getLevel(level->dimension->id) - ->cache->getChunkLoadedOrUnloaded(x, z); + LevelChunk* lc = MinecraftServer::getInstance() + ->getLevel(level->dimension->id) + ->cache->getChunkLoadedOrUnloaded(x, z); #else - LevelChunk* lc = MinecraftServer::getInstance() - ->getLevel(level->dimension->id) - ->cache->getChunk(x, z); + LevelChunk* lc = MinecraftServer::getInstance() + ->getLevel(level->dimension->id) + ->cache->getChunk(x, z); #endif - // In normal usage, chunks should only reshare if their local data matched - // that on the server. The forceMs parameter though can be used to force a - // share if resharing hasn't happened after a period of time - if (forceMs == 0) { - // Normal behaviour - just check that the data matches, and don't start - // sharing data if it doesn't (yet) - if (!lowerBlocks->isSameAs(lc->lowerBlocks) || - (upperBlocks && lc->upperBlocks && - !upperBlocks->isSameAs(lc->upperBlocks))) { - return; + // In normal usage, chunks should only reshare if their local data + // matched that on the server. The forceMs parameter though can be used + // to force a share if resharing hasn't happened after a period of time + if (forceMs == 0) { + // Normal behaviour - just check that the data matches, and don't + // start sharing data if it doesn't (yet) + if (!lowerBlocks->isSameAs(lc->lowerBlocks) || + (upperBlocks && lc->upperBlocks && + !upperBlocks->isSameAs(lc->upperBlocks))) { + return; + } + } else { + // Only force if it has been more than forceMs milliseconds since we + // last wanted to unshare this chunk + int64_t timenow = System::currentTimeMillis(); + if ((timenow - lastUnsharedTime) < forceMs) { + return; + } } - } else { - // Only force if it has been more than forceMs milliseconds since we - // last wanted to unshare this chunk - int64_t timenow = System::currentTimeMillis(); - if ((timenow - lastUnsharedTime) < forceMs) { - return; - } - } - // Note - data that was shared isn't directly deleted here, as it might - // still be in use in the game render update thread. Let that thread delete - // it when it is safe to do so instead. - GameRenderer::AddForDelete(lowerBlocks); - lowerBlocks = lc->lowerBlocks; - GameRenderer::FinishedReassigning(); - - GameRenderer::AddForDelete(lowerData); - lowerData = lc->lowerData; - GameRenderer::FinishedReassigning(); - - if (Level::maxBuildHeight > Level::COMPRESSED_CHUNK_SECTION_HEIGHT) { - GameRenderer::AddForDelete(upperBlocks); - upperBlocks = lc->upperBlocks; + // Note - data that was shared isn't directly deleted here, as it might + // still be in use in the game render update thread. Let that thread + // delete it when it is safe to do so instead. + GameRenderer::AddForDelete(lowerBlocks); + lowerBlocks = lc->lowerBlocks; GameRenderer::FinishedReassigning(); - GameRenderer::AddForDelete(upperData); - upperData = lc->upperData; + GameRenderer::AddForDelete(lowerData); + lowerData = lc->lowerData; GameRenderer::FinishedReassigning(); - } - sharingTilesAndData = true; + if (Level::maxBuildHeight > Level::COMPRESSED_CHUNK_SECTION_HEIGHT) { + GameRenderer::AddForDelete(upperBlocks); + upperBlocks = lc->upperBlocks; + GameRenderer::FinishedReassigning(); + + GameRenderer::AddForDelete(upperData); + upperData = lc->upperData; + GameRenderer::FinishedReassigning(); + } + + sharingTilesAndData = true; } #endif } @@ -1150,8 +1155,9 @@ void LevelChunk::addEntity(std::shared_ptr e) { e->yChunk = yc; e->zChunk = z; - { std::lock_guard lock(m_csEntities); - entityBlocks[yc]->push_back(e); + { + std::lock_guard lock(m_csEntities); + entityBlocks[yc]->push_back(e); } } @@ -1163,19 +1169,19 @@ void LevelChunk::removeEntity(std::shared_ptr e, int yc) { if (yc < 0) yc = 0; if (yc >= ENTITY_BLOCKS_LENGTH) yc = ENTITY_BLOCKS_LENGTH - 1; - { std::lock_guard lock(m_csEntities); - - // 4J - was entityBlocks[yc]->remove(e); - auto it = find(entityBlocks[yc]->begin(), entityBlocks[yc]->end(), e); - if (it != entityBlocks[yc]->end()) { - entityBlocks[yc]->erase(it); - // 4J - we don't want storage creeping up here as thinkgs move round the - // world accumulating up spare space - MemSect(31); - entityBlocks[yc]->shrink_to_fit(); - MemSect(0); - } + { + std::lock_guard lock(m_csEntities); + // 4J - was entityBlocks[yc]->remove(e); + auto it = find(entityBlocks[yc]->begin(), entityBlocks[yc]->end(), e); + if (it != entityBlocks[yc]->end()) { + entityBlocks[yc]->erase(it); + // 4J - we don't want storage creeping up here as thinkgs move round + // the world accumulating up spare space + MemSect(31); + entityBlocks[yc]->shrink_to_fit(); + MemSect(0); + } } } @@ -1201,50 +1207,56 @@ std::shared_ptr LevelChunk::getTileEntity(int x, int y, int z) { // insert when we don't want one) // shared_ptr tileEntity = tileEntities[pos]; std::shared_ptr tileEntity = nullptr; - { std::unique_lock lock(m_csTileEntities); - auto it = tileEntities.find(pos); + { + std::unique_lock lock(m_csTileEntities); + auto it = tileEntities.find(pos); - if (it == tileEntities.end()) { - lock.unlock(); // Note: don't assume iterator is valid for - // tileEntities after this point + if (it == tileEntities.end()) { + lock.unlock(); // Note: don't assume iterator is valid for + // tileEntities after this point - // Fix for #48450 - All: Code Defect: Hang: Game hangs in tutorial, when - // player arrive at the particular coordinate 4J Stu - Chests try to get - // their neighbours when being destroyed, which then causes new tile - // entities to be created if the neighbour has already been destroyed - if (level->m_bDisableAddNewTileEntities) return nullptr; + // Fix for #48450 - All: Code Defect: Hang: Game hangs in tutorial, + // when player arrive at the particular coordinate 4J Stu - Chests + // try to get their neighbours when being destroyed, which then + // causes new tile entities to be created if the neighbour has + // already been destroyed + if (level->m_bDisableAddNewTileEntities) return nullptr; - int t = getTile(x, y, z); - if (t <= 0 || !Tile::tiles[t]->isEntityTile()) return nullptr; + int t = getTile(x, y, z); + if (t <= 0 || !Tile::tiles[t]->isEntityTile()) return nullptr; - // 4J-PB changed from this in 1.7.3 - // EntityTile *et = (EntityTile *) Tile::tiles[t]; - // et->onPlace(level, this->x * 16 + x, y, this->z * 16 + z); + // 4J-PB changed from this in 1.7.3 + // EntityTile *et = (EntityTile *) Tile::tiles[t]; + // et->onPlace(level, this->x * 16 + x, y, this->z * 16 + z); - // if (tileEntity == nullptr) - //{ - tileEntity = - dynamic_cast(Tile::tiles[t])->newTileEntity(level); - level->setTileEntity(this->x * 16 + x, y, this->z * 16 + z, tileEntity); - //} + // if (tileEntity == nullptr) + //{ + tileEntity = + dynamic_cast(Tile::tiles[t])->newTileEntity(level); + level->setTileEntity(this->x * 16 + x, y, this->z * 16 + z, + tileEntity); + //} - // tileEntity = tileEntities[pos]; // 4J - TODO - this - // doesn't seem right - assignment wrong way? Check + // tileEntity = tileEntities[pos]; // 4J - TODO - this + // doesn't seem right - assignment wrong way? Check - // 4J Stu - It should have been inserted by now, but check to be sure - { std::lock_guard lock2(m_csTileEntities); - auto newIt = tileEntities.find(pos); - if (newIt != tileEntities.end()) { - tileEntity = newIt->second; + // 4J Stu - It should have been inserted by now, but check to be + // sure + { + std::lock_guard lock2(m_csTileEntities); + auto newIt = tileEntities.find(pos); + if (newIt != tileEntities.end()) { + tileEntity = newIt->second; + } + } + } else { + tileEntity = it->second; } - } - } else { - tileEntity = it->second; - } } if (tileEntity != nullptr && tileEntity->isRemoved()) { - { std::lock_guard lock(m_csTileEntities); - tileEntities.erase(pos); + { + std::lock_guard lock(m_csTileEntities); + tileEntities.erase(pos); } return nullptr; } @@ -1259,7 +1271,8 @@ void LevelChunk::addTileEntity(std::shared_ptr te) { setTileEntity(xx, yy, zz, te); if (loaded) { { - std::lock_guard lock(level->m_tileEntityListCS); + std::lock_guard lock( + level->m_tileEntityListCS); level->tileEntityList.push_back(te); } } @@ -1289,8 +1302,9 @@ void LevelChunk::setTileEntity(int x, int y, int z, tileEntity->clearRemoved(); - { std::lock_guard lock(m_csTileEntities); - tileEntities[pos] = tileEntity; + { + std::lock_guard lock(m_csTileEntities); + tileEntities[pos] = tileEntity; } } @@ -1303,20 +1317,21 @@ void LevelChunk::removeTileEntity(int x, int y, int z) { // if (removeThis != null) { // removeThis.setRemoved(); // } - { std::lock_guard lock(m_csTileEntities); - auto it = tileEntities.find(pos); - if (it != tileEntities.end()) { - std::shared_ptr te = tileEntities[pos]; - tileEntities.erase(pos); - if (te != nullptr) { - if (level->isClientSide) { - app.DebugPrintf("Removing tile entity of type %d\n", - te->GetType()); + { + std::lock_guard lock(m_csTileEntities); + auto it = tileEntities.find(pos); + if (it != tileEntities.end()) { + std::shared_ptr te = tileEntities[pos]; + tileEntities.erase(pos); + if (te != nullptr) { + if (level->isClientSide) { + app.DebugPrintf("Removing tile entity of type %d\n", + te->GetType()); + } + te->setRemoved(); } - te->setRemoved(); } } - } } } @@ -1361,17 +1376,20 @@ void LevelChunk::load() { #endif std::vector > values; - { std::lock_guard lock(m_csTileEntities); - for (auto it = tileEntities.begin(); it != tileEntities.end(); it++) { - values.push_back(it->second); - } + { + std::lock_guard lock(m_csTileEntities); + for (auto it = tileEntities.begin(); it != tileEntities.end(); + it++) { + values.push_back(it->second); + } } level->addAllPendingTileEntities(values); - { std::lock_guard lock(m_csEntities); - for (int i = 0; i < ENTITY_BLOCKS_LENGTH; i++) { - level->addEntities(entityBlocks[i]); - } + { + std::lock_guard lock(m_csEntities); + for (int i = 0; i < ENTITY_BLOCKS_LENGTH; i++) { + level->addEntities(entityBlocks[i]); + } } } else { #if defined(_LARGE_WORLDS) @@ -1385,10 +1403,12 @@ void LevelChunk::unload(bool unloadTileEntities) // 4J - added parameter loaded = false; if (unloadTileEntities) { std::vector > tileEntitiesToRemove; - { std::lock_guard lock(m_csTileEntities); - for (auto it = tileEntities.begin(); it != tileEntities.end(); it++) { - tileEntitiesToRemove.push_back(it->second); - } + { + std::lock_guard lock(m_csTileEntities); + for (auto it = tileEntities.begin(); it != tileEntities.end(); + it++) { + tileEntitiesToRemove.push_back(it->second); + } } auto itEnd = tileEntitiesToRemove.end(); @@ -1398,10 +1418,11 @@ void LevelChunk::unload(bool unloadTileEntities) // 4J - added parameter } } - { std::lock_guard lock(m_csEntities); - for (int i = 0; i < ENTITY_BLOCKS_LENGTH; i++) { - level->removeEntities(entityBlocks[i]); - } + { + std::lock_guard lock(m_csEntities); + for (int i = 0; i < ENTITY_BLOCKS_LENGTH; i++) { + level->removeEntities(entityBlocks[i]); + } } // app.DebugPrintf("Unloaded chunk %d, %d\n", x, z); @@ -1418,22 +1439,23 @@ void LevelChunk::unload(bool unloadTileEntities) // 4J - added parameter PIXBeginNamedEvent(0, "Saving entities"); ListTag* entityTags = new ListTag(); - { std::lock_guard lock(m_csEntities); - for (int i = 0; i < ENTITY_BLOCKS_LENGTH; i++) { - auto itEnd = entityBlocks[i]->end(); - for (std::vector >::iterator it = - entityBlocks[i]->begin(); - it != itEnd; it++) { - std::shared_ptr e = *it; - CompoundTag* teTag = new CompoundTag(); - if (e->save(teTag)) { - entityTags->add(teTag); + { + std::lock_guard lock(m_csEntities); + for (int i = 0; i < ENTITY_BLOCKS_LENGTH; i++) { + auto itEnd = entityBlocks[i]->end(); + for (std::vector >::iterator it = + entityBlocks[i]->begin(); + it != itEnd; it++) { + std::shared_ptr e = *it; + CompoundTag* teTag = new CompoundTag(); + if (e->save(teTag)) { + entityTags->add(teTag); + } } - } - // Clear out this list - entityBlocks[i]->clear(); - } + // Clear out this list + entityBlocks[i]->clear(); + } } m_unloadedEntitiesTag->put(L"Entities", entityTags); @@ -1463,16 +1485,17 @@ void LevelChunk::unload(bool unloadTileEntities) // 4J - added parameter } bool LevelChunk::containsPlayer() { - { std::lock_guard lock(m_csEntities); - for (int i = 0; i < ENTITY_BLOCKS_LENGTH; i++) { - std::vector >* vecEntity = entityBlocks[i]; - for (int j = 0; j < vecEntity->size(); j++) { - if (vecEntity->at(j)->GetType() == eTYPE_SERVERPLAYER) { - return true; + { + std::lock_guard lock(m_csEntities); + for (int i = 0; i < ENTITY_BLOCKS_LENGTH; i++) { + std::vector >* vecEntity = entityBlocks[i]; + for (int j = 0; j < vecEntity->size(); j++) { + if (vecEntity->at(j)->GetType() == eTYPE_SERVERPLAYER) { + return true; + } } } } - } return false; } @@ -1492,31 +1515,32 @@ void LevelChunk::getEntities(std::shared_ptr except, AABB* bb, // AP - locking is expensive so enter once in // Level::getEntities - { std::lock_guard lock(m_csEntities); - for (int yc = yc0; yc <= yc1; yc++) { - std::vector >* entities = entityBlocks[yc]; + { + std::lock_guard lock(m_csEntities); + for (int yc = yc0; yc <= yc1; yc++) { + std::vector >* entities = entityBlocks[yc]; - auto itEnd = entities->end(); - for (auto it = entities->begin(); it != itEnd; it++) { - std::shared_ptr e = *it; // entities->at(i); - if (e != except && e->bb.intersects(*bb) && - (selector == nullptr || selector->matches(e))) { - es.push_back(e); - std::vector >* subs = - e->getSubEntities(); - if (subs != nullptr) { - for (int j = 0; j < subs->size(); j++) { - e = subs->at(j); - if (e != except && e->bb.intersects(*bb) && - (selector == nullptr || selector->matches(e))) { - es.push_back(e); + auto itEnd = entities->end(); + for (auto it = entities->begin(); it != itEnd; it++) { + std::shared_ptr e = *it; // entities->at(i); + if (e != except && e->bb.intersects(*bb) && + (selector == nullptr || selector->matches(e))) { + es.push_back(e); + std::vector >* subs = + e->getSubEntities(); + if (subs != nullptr) { + for (int j = 0; j < subs->size(); j++) { + e = subs->at(j); + if (e != except && e->bb.intersects(*bb) && + (selector == nullptr || selector->matches(e))) { + es.push_back(e); + } } } } } } } - } } void LevelChunk::getEntitiesOfClass(const std::type_info& ec, AABB* bb, @@ -1538,55 +1562,57 @@ void LevelChunk::getEntitiesOfClass(const std::type_info& ec, AABB* bb, // AP - locking is expensive so enter once in // Level::getEntitiesOfClass - { std::lock_guard lock(m_csEntities); - for (int yc = yc0; yc <= yc1; yc++) { - std::vector >* entities = entityBlocks[yc]; + { + std::lock_guard lock(m_csEntities); + for (int yc = yc0; yc <= yc1; yc++) { + std::vector >* entities = entityBlocks[yc]; - auto itEnd = entities->end(); - for (auto it = entities->begin(); it != itEnd; it++) { - std::shared_ptr e = *it; // entities->at(i); + auto itEnd = entities->end(); + for (auto it = entities->begin(); it != itEnd; it++) { + std::shared_ptr e = *it; // entities->at(i); - bool isAssignableFrom = false; - // Some special cases where the base class is a general type that - // our class may be derived from, otherwise do a direct comparison - // of type_info - if (ec == typeid(Player)) - isAssignableFrom = e->instanceof(eTYPE_PLAYER); - else if (ec == typeid(Entity)) - isAssignableFrom = e->instanceof(eTYPE_ENTITY); - else if (ec == typeid(Mob)) - isAssignableFrom = e->instanceof(eTYPE_MOB); - else if (ec == typeid(LivingEntity)) - isAssignableFrom = e->instanceof(eTYPE_LIVINGENTITY); - else if (ec == typeid(ItemEntity)) - isAssignableFrom = e->instanceof(eTYPE_ITEMENTITY); - else if (ec == typeid(Minecart)) - isAssignableFrom = e->instanceof(eTYPE_MINECART); - else if (ec == typeid(Monster)) - isAssignableFrom = e->instanceof(eTYPE_MONSTER); - else if (ec == typeid(Zombie)) - isAssignableFrom = e->instanceof(eTYPE_ZOMBIE); - else if (Entity* entity = e.get(); - entity != nullptr && ec == typeid(*entity)) - isAssignableFrom = true; - if (isAssignableFrom && e->bb.intersects(*bb)) { - if (selector == nullptr || selector->matches(e)) { - es.push_back(e); + bool isAssignableFrom = false; + // Some special cases where the base class is a general type + // that our class may be derived from, otherwise do a direct + // comparison of type_info + if (ec == typeid(Player)) + isAssignableFrom = e->instanceof(eTYPE_PLAYER); + else if (ec == typeid(Entity)) + isAssignableFrom = e->instanceof(eTYPE_ENTITY); + else if (ec == typeid(Mob)) + isAssignableFrom = e->instanceof(eTYPE_MOB); + else if (ec == typeid(LivingEntity)) + isAssignableFrom = e->instanceof(eTYPE_LIVINGENTITY); + else if (ec == typeid(ItemEntity)) + isAssignableFrom = e->instanceof(eTYPE_ITEMENTITY); + else if (ec == typeid(Minecart)) + isAssignableFrom = e->instanceof(eTYPE_MINECART); + else if (ec == typeid(Monster)) + isAssignableFrom = e->instanceof(eTYPE_MONSTER); + else if (ec == typeid(Zombie)) + isAssignableFrom = e->instanceof(eTYPE_ZOMBIE); + else if (Entity* entity = e.get(); + entity != nullptr && ec == typeid(*entity)) + isAssignableFrom = true; + if (isAssignableFrom && e->bb.intersects(*bb)) { + if (selector == nullptr || selector->matches(e)) { + es.push_back(e); + } } + // 4J - note needs to be equivalent to + // baseClass.isAssignableFrom(e.getClass()) } - // 4J - note needs to be equivalent to - // baseClass.isAssignableFrom(e.getClass()) } } - } } int LevelChunk::countEntities() { int entityCount = 0; - { std::lock_guard lock(m_csEntities); - for (int yc = 0; yc < ENTITY_BLOCKS_LENGTH; yc++) { - entityCount += (int)entityBlocks[yc]->size(); - } + { + std::lock_guard lock(m_csEntities); + for (int yc = 0; yc < ENTITY_BLOCKS_LENGTH; yc++) { + entityCount += (int)entityBlocks[yc]->size(); + } } return entityCount; } @@ -2131,11 +2157,12 @@ void LevelChunk::compressBlocks() { // Note - only the extraction of the pointers needs to be done in the // lock, since even if the data is unshared whilst we are // processing this data is still valid (for the server) - { std::lock_guard lock(m_csSharing); - if (sharingTilesAndData) { - blocksToCompressLower = lowerBlocks; - blocksToCompressUpper = upperBlocks; - } + { + std::lock_guard lock(m_csSharing); + if (sharingTilesAndData) { + blocksToCompressLower = lowerBlocks; + blocksToCompressUpper = upperBlocks; + } } } else { // Not the host, simple case @@ -2230,11 +2257,12 @@ void LevelChunk::compressData() { // Note - only the extraction of the pointers needs to be done in the // lock, since even if the data is unshared whilst we are // processing this data is still valid (for the server) - { std::lock_guard lock(m_csSharing); - if (sharingTilesAndData) { - dataToCompressLower = lowerData; - dataToCompressUpper = upperData; - } + { + std::lock_guard lock(m_csSharing); + if (sharingTilesAndData) { + dataToCompressLower = lowerData; + dataToCompressUpper = upperData; + } } } else { // Not the host, simple case diff --git a/Minecraft.World/Level/Storage/CompressedTileStorage.cpp b/Minecraft.World/Level/Storage/CompressedTileStorage.cpp index 46c1da9eb..a2b3f921c 100644 --- a/Minecraft.World/Level/Storage/CompressedTileStorage.cpp +++ b/Minecraft.World/Level/Storage/CompressedTileStorage.cpp @@ -33,16 +33,17 @@ CompressedTileStorage::CompressedTileStorage() { } CompressedTileStorage::CompressedTileStorage(CompressedTileStorage* copyFrom) { - { std::lock_guard lock(cs_write); - allocatedSize = copyFrom->allocatedSize; - if (allocatedSize > 0) { - indicesAndData = (unsigned char*)XPhysicalAlloc( - allocatedSize, MAXULONG_PTR, 4096, - PAGE_READWRITE); //(unsigned char *)malloc(allocatedSize); - XMemCpy(indicesAndData, copyFrom->indicesAndData, allocatedSize); - } else { - indicesAndData = nullptr; - } + { + std::lock_guard lock(cs_write); + allocatedSize = copyFrom->allocatedSize; + if (allocatedSize > 0) { + indicesAndData = (unsigned char*)XPhysicalAlloc( + allocatedSize, MAXULONG_PTR, 4096, + PAGE_READWRITE); //(unsigned char *)malloc(allocatedSize); + XMemCpy(indicesAndData, copyFrom->indicesAndData, allocatedSize); + } else { + indicesAndData = nullptr; + } } #if defined(PSVITA_PRECOMPUTED_TABLE) diff --git a/Minecraft.World/Level/Storage/McRegionChunkStorage.cpp b/Minecraft.World/Level/Storage/McRegionChunkStorage.cpp index bba7b774a..27808d7af 100644 --- a/Minecraft.World/Level/Storage/McRegionChunkStorage.cpp +++ b/Minecraft.World/Level/Storage/McRegionChunkStorage.cpp @@ -184,8 +184,9 @@ void McRegionChunkStorage::save(Level* level, LevelChunk* levelChunk) { // Note - have added use of a mutex round sections of code that // do a lot of memory alloc/free operations. This is because when we are - // running saves on multiple threads these sections have a lot of contention. - // Better to let each thread have its turn at a higher level of granularity. + // running saves on multiple threads these sections have a lot of + // contention. Better to let each thread have its turn at a higher level of + // granularity. MemSect(30); PIXBeginNamedEvent(0, "Getting output stream\n"); DataOutputStream* output = RegionFileCache::getChunkDataOutputStream( @@ -199,22 +200,24 @@ void McRegionChunkStorage::save(Level* level, LevelChunk* levelChunk) { PIXEndNamedEvent(); PIXBeginNamedEvent(0, "Updating chunk queue"); - { std::lock_guard lock(cs_memory); - s_chunkDataQueue.push_back(output); + { + std::lock_guard lock(cs_memory); + s_chunkDataQueue.push_back(output); } PIXEndNamedEvent(); } else { CompoundTag* tag; - { std::lock_guard lock(cs_memory); - PIXBeginNamedEvent(0, "Creating tags\n"); - tag = new CompoundTag(); - CompoundTag* levelData = new CompoundTag(); - tag->put(L"Level", levelData); - OldChunkStorage::save(levelChunk, level, levelData); - PIXEndNamedEvent(); - PIXBeginNamedEvent(0, "NbtIo writing\n"); - NbtIo::write(tag, output); - PIXEndNamedEvent(); + { + std::lock_guard lock(cs_memory); + PIXBeginNamedEvent(0, "Creating tags\n"); + tag = new CompoundTag(); + CompoundTag* levelData = new CompoundTag(); + tag->put(L"Level", levelData); + OldChunkStorage::save(levelChunk, level, levelData); + PIXEndNamedEvent(); + PIXBeginNamedEvent(0, "NbtIo writing\n"); + NbtIo::write(tag, output); + PIXEndNamedEvent(); } PIXBeginNamedEvent(0, "Output closing\n"); output->close(); @@ -223,11 +226,12 @@ void McRegionChunkStorage::save(Level* level, LevelChunk* levelChunk) { // 4J Stu - getChunkDataOutputStream makes a new DataOutputStream that // points to a new ChunkBuffer( ByteArrayOutputStream ) We should clean // these up when we are done - { std::lock_guard lock(cs_memory); - PIXBeginNamedEvent(0, "Cleaning up\n"); - output->deleteChildStream(); - delete output; - delete tag; + { + std::lock_guard lock(cs_memory); + PIXBeginNamedEvent(0, "Cleaning up\n"); + output->deleteChildStream(); + delete output; + delete tag; } PIXEndNamedEvent(); } @@ -355,32 +359,34 @@ int McRegionChunkStorage::runSaveThreadProc(void* lpParam) { DataOutputStream* dos = nullptr; while (running) { - { std::unique_lock lock(cs_memory, std::try_to_lock); - if (lock.owns_lock()) { - lastQueueSize = s_chunkDataQueue.size(); - if (lastQueueSize > 0) { - dos = s_chunkDataQueue.front(); - s_chunkDataQueue.pop_front(); - } - s_runningThreadCount++; - lock.unlock(); + { + std::unique_lock lock(cs_memory, std::try_to_lock); + if (lock.owns_lock()) { + lastQueueSize = s_chunkDataQueue.size(); + if (lastQueueSize > 0) { + dos = s_chunkDataQueue.front(); + s_chunkDataQueue.pop_front(); + } + s_runningThreadCount++; + lock.unlock(); - if (dos) { - PIXBeginNamedEvent(0, "Saving chunk"); - // app.DebugPrintf("Compressing chunk data (%d left)\n", - // lastQueueSize - 1); - dos->close(); - dos->deleteChildStream(); - PIXEndNamedEvent(); - } - delete dos; - dos = nullptr; + if (dos) { + PIXBeginNamedEvent(0, "Saving chunk"); + // app.DebugPrintf("Compressing chunk data (%d left)\n", + // lastQueueSize - 1); + dos->close(); + dos->deleteChildStream(); + PIXEndNamedEvent(); + } + delete dos; + dos = nullptr; - { std::lock_guard lock2(cs_memory); - s_runningThreadCount--; + { + std::lock_guard lock2(cs_memory); + s_runningThreadCount--; + } } } - } // If there was more than one thing in the queue last time we checked, // then we want to spin round again soon Otherwise wait a bit longer @@ -404,30 +410,34 @@ void McRegionChunkStorage::WaitIfTooManyQueuedChunks() { WaitForSaves(); } void McRegionChunkStorage::WaitForAllSaves() { // Wait for there to be no more tasks to be processed... size_t queueSize; - { std::lock_guard lock(cs_memory); - queueSize = s_chunkDataQueue.size(); + { + std::lock_guard lock(cs_memory); + queueSize = s_chunkDataQueue.size(); } while (queueSize > 0) { std::this_thread::sleep_for(std::chrono::milliseconds(10)); - { std::lock_guard lock(cs_memory); - queueSize = s_chunkDataQueue.size(); + { + std::lock_guard lock(cs_memory); + queueSize = s_chunkDataQueue.size(); } } // And then wait for there to be no running threads that are processing // these tasks int runningThreadCount; - { std::lock_guard lock(cs_memory); - runningThreadCount = s_runningThreadCount; + { + std::lock_guard lock(cs_memory); + runningThreadCount = s_runningThreadCount; } while (runningThreadCount > 0) { std::this_thread::sleep_for(std::chrono::milliseconds(10)); - { std::lock_guard lock(cs_memory); - runningThreadCount = s_runningThreadCount; + { + std::lock_guard lock(cs_memory); + runningThreadCount = s_runningThreadCount; } } } @@ -439,16 +449,18 @@ void McRegionChunkStorage::WaitForSaves() { // Wait for the queue to reduce to a level where we should add more elements size_t queueSize; - { std::lock_guard lock(cs_memory); - queueSize = s_chunkDataQueue.size(); + { + std::lock_guard lock(cs_memory); + queueSize = s_chunkDataQueue.size(); } if (queueSize > MAX_QUEUE_SIZE) { while (queueSize > DESIRED_QUEUE_SIZE) { std::this_thread::sleep_for(std::chrono::milliseconds(10)); - { std::lock_guard lock(cs_memory); - queueSize = s_chunkDataQueue.size(); + { + std::lock_guard lock(cs_memory); + queueSize = s_chunkDataQueue.size(); } } } diff --git a/Minecraft.World/Level/Storage/ZonedChunkStorage.cpp b/Minecraft.World/Level/Storage/ZonedChunkStorage.cpp index c1b151104..92b41eb56 100644 --- a/Minecraft.World/Level/Storage/ZonedChunkStorage.cpp +++ b/Minecraft.World/Level/Storage/ZonedChunkStorage.cpp @@ -218,7 +218,8 @@ void ZonedChunkStorage::saveEntities(Level* level, LevelChunk* lc) { { std::lock_guard lock(lc->m_csEntities); for (int i = 0; i < LevelChunk::ENTITY_BLOCKS_LENGTH; i++) { - std::vector >* entities = lc->entityBlocks[i]; + std::vector >* entities = + lc->entityBlocks[i]; auto itEndTags = entities->end(); for (auto it = entities->begin(); it != itEndTags; it++) { diff --git a/Minecraft.World/Network/Connection.cpp b/Minecraft.World/Network/Connection.cpp index 6b5849d20..871560dc2 100644 --- a/Minecraft.World/Network/Connection.cpp +++ b/Minecraft.World/Network/Connection.cpp @@ -462,7 +462,8 @@ void Connection::tick() { { std::lock_guard lock(incoming_cs); while (!disconnected && !g_NetworkManager.IsLeavingGame() && - g_NetworkManager.IsInSession() && !incoming.empty() && max-- >= 0) { + g_NetworkManager.IsInSession() && !incoming.empty() && + max-- >= 0) { std::shared_ptr packet = incoming.front(); packetsToHandle.push_back(packet); incoming.pop(); diff --git a/Minecraft.World/Network/Connection.h b/Minecraft.World/Network/Connection.h index 4cf68a8b1..7759e6c1f 100644 --- a/Minecraft.World/Network/Connection.h +++ b/Minecraft.World/Network/Connection.h @@ -55,7 +55,7 @@ private: bool running; std::queue > - incoming; // 4J - was using synchronizedList... + incoming; // 4J - was using synchronizedList... std::mutex incoming_cs; // ... now has this mutex std::queue > outgoing; // 4J - was using synchronizedList - but don't think it is diff --git a/Minecraft.World/Network/Socket.cpp b/Minecraft.World/Network/Socket.cpp index c0d16bd82..120cd5700 100644 --- a/Minecraft.World/Network/Socket.cpp +++ b/Minecraft.World/Network/Socket.cpp @@ -47,7 +47,8 @@ void Socket::Initialise(ServerConnection* serverConnection) { // Streams already exist – just reset queue state and re-open streams. for (int i = 0; i < 2; i++) { { - std::unique_lock lock(s_hostQueueLock[i], std::try_to_lock); + std::unique_lock lock(s_hostQueueLock[i], + std::try_to_lock); if (lock.owns_lock()) { // Clear the queue std::queue empty; @@ -246,7 +247,8 @@ int Socket::SocketInputStreamLocal::read() { while (m_streamOpen && ShutdownManager::ShouldRun( ShutdownManager::eConnectionReadThreads)) { { - std::unique_lock lock(s_hostQueueLock[m_queueIdx], std::try_to_lock); + std::unique_lock lock(s_hostQueueLock[m_queueIdx], + std::try_to_lock); if (lock.owns_lock()) { if (s_hostQueue[m_queueIdx].size()) { std::uint8_t retval = s_hostQueue[m_queueIdx].front(); @@ -272,7 +274,8 @@ int Socket::SocketInputStreamLocal::read(byteArray b, unsigned int offset, unsigned int length) { while (m_streamOpen) { { - std::unique_lock lock(s_hostQueueLock[m_queueIdx], std::try_to_lock); + std::unique_lock lock(s_hostQueueLock[m_queueIdx], + std::try_to_lock); if (lock.owns_lock()) { if (s_hostQueue[m_queueIdx].size() >= length) { for (unsigned int i = 0; i < length; i++) { @@ -356,7 +359,8 @@ int Socket::SocketInputStreamNetwork::read() { while (m_streamOpen && ShutdownManager::ShouldRun( ShutdownManager::eConnectionReadThreads)) { { - std::unique_lock lock(m_socket->m_queueLockNetwork[m_queueIdx], std::try_to_lock); + std::unique_lock lock( + m_socket->m_queueLockNetwork[m_queueIdx], std::try_to_lock); if (lock.owns_lock()) { if (m_socket->m_queueNetwork[m_queueIdx].size()) { std::uint8_t retval = @@ -383,7 +387,8 @@ int Socket::SocketInputStreamNetwork::read(byteArray b, unsigned int offset, unsigned int length) { while (m_streamOpen) { { - std::unique_lock lock(m_socket->m_queueLockNetwork[m_queueIdx], std::try_to_lock); + std::unique_lock lock( + m_socket->m_queueLockNetwork[m_queueIdx], std::try_to_lock); if (lock.owns_lock()) { if (m_socket->m_queueNetwork[m_queueIdx].size() >= length) { for (unsigned int i = 0; i < length; i++) { @@ -449,7 +454,8 @@ void Socket::SocketOutputStreamNetwork::writeWithFlags(byteArray b, queueIdx = SOCKET_CLIENT_END; { - std::lock_guard lock(m_socket->m_queueLockNetwork[queueIdx]); + std::lock_guard lock( + m_socket->m_queueLockNetwork[queueIdx]); for (unsigned int i = 0; i < length; i++) { m_socket->m_queueNetwork[queueIdx].push(b[offset + i]); } diff --git a/Minecraft.World/Network/Socket.h b/Minecraft.World/Network/Socket.h index 18719598a..6a26e1001 100644 --- a/Minecraft.World/Network/Socket.h +++ b/Minecraft.World/Network/Socket.h @@ -115,7 +115,7 @@ private: // For network connections std::queue m_queueNetwork[2]; // For input data - std::mutex m_queueLockNetwork[2]; // For input data + std::mutex m_queueLockNetwork[2]; // For input data SocketInputStreamNetwork* m_inputStream[2]; SocketOutputStreamNetwork* m_outputStream[2]; bool m_endClosed[2]; diff --git a/Minecraft.World/Util/C4JThread.cpp b/Minecraft.World/Util/C4JThread.cpp index f3ba46fc8..56b620e6d 100644 --- a/Minecraft.World/Util/C4JThread.cpp +++ b/Minecraft.World/Util/C4JThread.cpp @@ -215,14 +215,30 @@ void setPriorityPlatform(std::thread& threadHandle, bool isSelf, using enum C4JThread::ThreadPriority; int niceValue = 0; switch (priority) { - case TimeCritical: niceValue = -15; break; - case Highest: niceValue = -10; break; - case AboveNormal: niceValue = -5; break; - case Normal: niceValue = 0; break; - case BelowNormal: niceValue = 5; break; - case Lowest: niceValue = 10; break; - case Idle: niceValue = 19; break; - default: niceValue = 0; break; + case TimeCritical: + niceValue = -15; + break; + case Highest: + niceValue = -10; + break; + case AboveNormal: + niceValue = -5; + break; + case Normal: + niceValue = 0; + break; + case BelowNormal: + niceValue = 5; + break; + case Lowest: + niceValue = 10; + break; + case Idle: + niceValue = 19; + break; + default: + niceValue = 0; + break; } errno = 0; @@ -401,8 +417,8 @@ bool C4JThread::isMainThread() noexcept { } void C4JThread::setThreadName(std::uint32_t threadId, const char* threadName) { - const char* safe = (threadName && threadName[0] != '\0') ? threadName - : "(4J) Unnamed"; + const char* safe = + (threadName && threadName[0] != '\0') ? threadName : "(4J) Unnamed"; setThreadNamePlatform(threadId, safe); } @@ -477,10 +493,9 @@ std::uint32_t C4JThread::EventArray::waitForSingle(int index, int timeoutMs) { const std::uint32_t bitMask = 1U << static_cast(index); std::unique_lock lock(m_mutex); - if (!waitForCondition(m_condition, lock, timeoutMs, - [this, bitMask] { - return (m_signaledMask & bitMask) != 0U; - })) { + if (!waitForCondition(m_condition, lock, timeoutMs, [this, bitMask] { + return (m_signaledMask & bitMask) != 0U; + })) { return WaitResult::Timeout; } if (m_mode == Mode::AutoClear) m_signaledMask &= ~bitMask; @@ -491,10 +506,9 @@ std::uint32_t C4JThread::EventArray::waitForAll(int timeoutMs) { const std::uint32_t bitMask = buildMaskForSize(m_size); std::unique_lock lock(m_mutex); - if (!waitForCondition(m_condition, lock, timeoutMs, - [this, bitMask] { - return (m_signaledMask & bitMask) == bitMask; - })) { + if (!waitForCondition(m_condition, lock, timeoutMs, [this, bitMask] { + return (m_signaledMask & bitMask) == bitMask; + })) { return WaitResult::Timeout; } if (m_mode == Mode::AutoClear) m_signaledMask &= ~bitMask; @@ -505,15 +519,13 @@ std::uint32_t C4JThread::EventArray::waitForAny(int timeoutMs) { const std::uint32_t bitMask = buildMaskForSize(m_size); std::unique_lock lock(m_mutex); - if (!waitForCondition(m_condition, lock, timeoutMs, - [this, bitMask] { - return (m_signaledMask & bitMask) != 0U; - })) { + if (!waitForCondition(m_condition, lock, timeoutMs, [this, bitMask] { + return (m_signaledMask & bitMask) != 0U; + })) { return WaitResult::Timeout; } - const std::uint32_t readyIndex = - firstSetBitIndex(m_signaledMask & bitMask); + const std::uint32_t readyIndex = firstSetBitIndex(m_signaledMask & bitMask); if (m_mode == Mode::AutoClear) m_signaledMask &= ~(1U << readyIndex); return WaitResult::Signaled + readyIndex; }